-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-/**
- *
- */
-package org.opendaylight.controller.sal.packet;
-
-import java.util.Arrays;
-
-import org.opendaylight.controller.sal.utils.NetUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * BitBufferHelper class that provides utility methods to
- * - fetch specific bits from a serialized stream of bits
- * - convert bits to primitive data type - like short, int, long
- * - store bits in specified location in stream of bits
- * - convert primitive data types to stream of bits
- */
-public abstract class BitBufferHelper {
- protected static final Logger logger = LoggerFactory
- .getLogger(BitBufferHelper.class);
-
- public static final long ByteMask = 0xFF;
-
- // Getters
- // data: array where data are stored
- // startOffset: bit from where to start reading
- // numBits: number of bits to read
- // All this function return an exception if overflow or underflow
-
- /**
- * Returns the first byte from the byte array
- * @param byte[] data
- * @return byte value
- */
- public static byte getByte(byte[] data) {
- if ((data.length * NetUtils.NumBitsInAByte) > Byte.SIZE) {
- try {
- throw new BufferException(
- "Container is too small for the number of requested bits");
- } catch (BufferException e) {
- logger.error("", e);
- }
- }
- return (data[0]);
- }
-
- /**
- * Returns the short value for the byte array passed.
- * Size of byte array is restricted to Short.SIZE
- * @param byte[] data
- * @return short value
- */
- public static short getShort(byte[] data) {
- if (data.length > Short.SIZE) {
- try {
- throw new BufferException(
- "Container is too small for the number of requested bits");
- } catch (BufferException e) {
- logger.error("", e);
- }
- }
- return (short) toNumber(data);
- }
-
- /**
- * Returns the int value for the byte array passed.
- * Size of byte array is restricted to Integer.SIZE
- * @param byte[] data
- * @return int - the integer value of byte array
- */
- public static int getInt(byte[] data) {
- if (data.length > Integer.SIZE) {
- try {
- throw new BufferException(
- "Container is too small for the number of requested bits");
- } catch (BufferException e) {
- logger.error("", e);
- }
- }
- return (int) toNumber(data);
- }
-
- /**
- * Returns the long value for the byte array passed.
- * Size of byte array is restricted to Long.SIZE
- * @param byte[] data
- * @return long - the integer value of byte array
- */
- public static long getLong(byte[] data) {
- if (data.length > Long.SIZE) {
- try {
- throw new BufferException(
- "Container is too small for the number of requested bits");
- } catch (Exception e) {
- logger.error("", e);
- }
- }
- return (long) toNumber(data);
- }
-
- /**
- * Returns the short value for the last numBits of the byte array passed.
- * Size of numBits is restricted to Short.SIZE
- * @param byte[] data
- * @param int - numBits
- * @return short - the short value of byte array
- */
- public static short getShort(byte[] data, int numBits) {
- if (numBits > Short.SIZE) {
- try {
- throw new BufferException(
- "Container is too small for the number of requested bits");
- } catch (BufferException e) {
- logger.error("", e);
- }
- }
- int startOffset = data.length * NetUtils.NumBitsInAByte - numBits;
- byte[] bits = null;
- try {
- bits = BitBufferHelper.getBits(data, startOffset, numBits);
- } catch (BufferException e) {
- logger.error("", e);
- }
- return (short) toNumber(bits, numBits);
- }
-
- /**
- * Returns the int value for the last numBits of the byte array passed.
- * Size of numBits is restricted to Integer.SIZE
- * @param byte[] data
- * @param int - numBits
- * @return int - the integer value of byte array
- */
- public static int getInt(byte[] data, int numBits) {
- if (numBits > Integer.SIZE) {
- try {
- throw new BufferException(
- "Container is too small for the number of requested bits");
- } catch (BufferException e) {
- logger.error("", e);
- }
- }
- int startOffset = data.length * NetUtils.NumBitsInAByte - numBits;
- byte[] bits = null;
- try {
- bits = BitBufferHelper.getBits(data, startOffset, numBits);
- } catch (BufferException e) {
- logger.error("", e);
- }
- return (int) toNumber(bits, numBits);
- }
-
- /**
- * Returns the long value for the last numBits of the byte array passed.
- * Size of numBits is restricted to Long.SIZE
- * @param byte[] data
- * @param int - numBits
- * @return long - the integer value of byte array
- */
- public static long getLong(byte[] data, int numBits) {
- if (numBits > Long.SIZE) {
- try {
- throw new BufferException(
- "Container is too small for the number of requested bits");
- } catch (BufferException e) {
- logger.error("", e);
- }
- }
- if (numBits > data.length * NetUtils.NumBitsInAByte) {
- try {
- throw new BufferException(
- "Trying to read more bits than contained in the data buffer");
- } catch (BufferException e) {
- logger.error("", e);
- }
- }
- int startOffset = data.length * NetUtils.NumBitsInAByte - numBits;
- byte[] bits = null;
- try {
- bits = BitBufferHelper.getBits(data, startOffset, numBits);
- } catch (BufferException e) {
- logger.error("", e);
- }
- return (long) toNumber(bits, numBits);
- }
-
- /**
- * Reads the specified number of bits from the passed byte array
- * starting to read from the specified offset
- * The bits read are stored in a byte array which size is dictated
- * by the number of bits to be stored.
- * The bits are stored in the byte array LSB aligned.
- *
- * Ex.
- * Read 7 bits at offset 10
- * 0 9 10 16 17
- * 0101000010 | 0000101 | 1111001010010101011
- * will be returned as {0,0,0,0,0,1,0,1}
- *
- * @param byte[] data
- * @param int startOffset - offset to start fetching bits from data from
- * @param int numBits - number of bits to be fetched from data
- * @return byte [] - LSB aligned bits
- *
- * @throws BufferException
- * when the startOffset and numBits parameters are not congruent
- * with the data buffer size
- */
- public static byte[] getBits(byte[] data, int startOffset, int numBits)
- throws BufferException {
-
- int startByteOffset = 0;
- int valfromcurr, valfromnext;
- int extranumBits = numBits % NetUtils.NumBitsInAByte;
- int extraOffsetBits = startOffset % NetUtils.NumBitsInAByte;
- int numBytes = (numBits % NetUtils.NumBitsInAByte != 0) ? 1 + numBits
- / NetUtils.NumBitsInAByte : numBits / NetUtils.NumBitsInAByte;
- byte[] shiftedBytes = new byte[numBytes];
- startByteOffset = startOffset / NetUtils.NumBitsInAByte;
- byte[] bytes = new byte[numBytes];
- if (numBits == 0) {
- return bytes;
- }
-
- checkExceptions(data, startOffset, numBits);
-
- if (extraOffsetBits == 0) {
- if (extranumBits == 0) {
- System.arraycopy(data, startByteOffset, bytes, 0, numBytes);
- return bytes;
- } else {
- System.arraycopy(data, startByteOffset, bytes, 0, numBytes - 1);
- bytes[numBytes - 1] = (byte) ((int) data[startByteOffset
- + numBytes - 1] & getMSBMask(extranumBits));
- }
- } else {
- int i;
- for (i = 0; i < numBits / NetUtils.NumBitsInAByte; i++) {
- // Reading numBytes starting from offset
- valfromcurr = (data[startByteOffset + i])
- & getLSBMask(NetUtils.NumBitsInAByte - extraOffsetBits);
- valfromnext = (data[startByteOffset + i + 1])
- & getMSBMask(extraOffsetBits);
- bytes[i] = (byte) (valfromcurr << (extraOffsetBits) | (valfromnext >> (NetUtils.NumBitsInAByte - extraOffsetBits)));
- }
- // Now adding the rest of the bits if any
- if (extranumBits != 0) {
- if (extranumBits < (NetUtils.NumBitsInAByte - extraOffsetBits)) {
- valfromnext = (byte) (data[startByteOffset + i] & ((getMSBMask(extranumBits)) >> extraOffsetBits));
- bytes[i] = (byte) (valfromnext << extraOffsetBits);
- } else if (extranumBits == (NetUtils.NumBitsInAByte - extraOffsetBits)) {
- valfromcurr = (data[startByteOffset + i])
- & getLSBMask(NetUtils.NumBitsInAByte
- - extraOffsetBits);
- bytes[i] = (byte) (valfromcurr << extraOffsetBits);
- } else {
- valfromcurr = (data[startByteOffset + i])
- & getLSBMask(NetUtils.NumBitsInAByte
- - extraOffsetBits);
- valfromnext = (data[startByteOffset + i + 1])
- & (getMSBMask(extranumBits
- - (NetUtils.NumBitsInAByte - extraOffsetBits)));
- bytes[i] = (byte) (valfromcurr << (extraOffsetBits) | (valfromnext >> (NetUtils.NumBitsInAByte - extraOffsetBits)));
- }
-
- }
- }
- // Aligns the bits to LSB
- shiftedBytes = shiftBitsToLSB(bytes, numBits);
- return shiftedBytes;
- }
-
- // Setters
- // data: array where data will be stored
- // input: the data that need to be stored in the data array
- // startOffset: bit from where to start writing
- // numBits: number of bits to read
-
- /**
- * Bits are expected to be stored in the input byte array from LSB
- * @param byte[] - data to set the input byte
- * @param byte - input byte to be inserted
- * @param startOffset - offset of data[] to start inserting byte from
- * @param numBits - number of bits of input to be inserted into data[]
- *
- * @throws BufferException
- * when the input, startOffset and numBits are not congruent
- * with the data buffer size
- */
- public static void setByte(byte[] data, byte input, int startOffset,
- int numBits) throws BufferException {
- byte[] inputByteArray = new byte[1];
- Arrays.fill(inputByteArray, 0, 1, input);
- setBytes(data, inputByteArray, startOffset, numBits);
- }
-
- /**
- * Bits are expected to be stored in the input byte array from LSB
- * @param byte[] - data to set the input byte
- * @param byte[] - input bytes to be inserted
- * @param startOffset - offset of data[] to start inserting byte from
- * @param numBits - number of bits of input to be inserted into data[]
- * @return void
- * @throws BufferException
- * when the startOffset and numBits parameters are not congruent
- * with data and input buffers' size
- */
- public static void setBytes(byte[] data, byte[] input, int startOffset,
- int numBits) throws BufferException {
- checkExceptions(data, startOffset, numBits);
- insertBits(data, input, startOffset, numBits);
- }
-
- /**
- * Returns numBits 1's in the MSB position
- *
- * @param numBits
- * @return
- */
- public static int getMSBMask(int numBits) {
- int mask = 0;
- for (int i = 0; i < numBits; i++) {
- mask = mask | (1 << (7 - i));
- }
- return mask;
- }
-
- /**
- * Returns numBits 1's in the LSB position
- *
- * @param numBits
- * @return
- */
- public static int getLSBMask(int numBits) {
- int mask = 0;
- for (int i = 0; i < numBits; i++) {
- mask = mask | (1 << i);
- }
- return mask;
- }
-
- /**
- * Returns the numerical value of the byte array passed
- *
- * @param byte[] - array
- * @return long - numerical value of byte array passed
- */
- static public long toNumber(byte[] array) {
- long ret = 0;
- long length = array.length;
- int value = 0;
- for (int i = 0; i < length; i++) {
- value = array[i];
- if (value < 0)
- value += 256;
- ret = ret
- | (long) ((long) value << ((length - i - 1) * NetUtils.NumBitsInAByte));
- }
- return ret;
- }
-
- /**
- * Returns the numerical value of the last numBits (LSB bits) of the byte
- * array passed
- *
- * @param byte[] - array
- * @param int - numBits
- * @return long - numerical value of byte array passed
- */
- static public long toNumber(byte[] array, int numBits) {
- int length = numBits / NetUtils.NumBitsInAByte;
- int bitsRest = numBits % NetUtils.NumBitsInAByte;
- int startOffset = array.length - length;
- long ret = 0;
- int value = 0;
-
- value = array[startOffset - 1] & getLSBMask(bitsRest);
- value = (array[startOffset - 1] < 0) ? (array[startOffset - 1] + 256)
- : array[startOffset - 1];
- ret = ret
- | (value << ((array.length - startOffset) * NetUtils.NumBitsInAByte));
-
- for (int i = startOffset; i < array.length; i++) {
- value = array[i];
- if (value < 0)
- value += 256;
- ret = ret
- | (long) ((long) value << ((array.length - i - 1) * NetUtils.NumBitsInAByte));
- }
-
- return ret;
- }
-
- /**
- * Accepts a number as input and returns its value in byte form in LSB
- * aligned form example: input = 5000 [1001110001000] bytes = 19, -120
- * [00010011] [10001000]
- *
- * @param Number
- * @return byte[]
- *
- */
-
- public static byte[] toByteArray(Number input) {
- Class<? extends Number> dataType = input.getClass();
- short size = 0;
- long longValue = input.longValue();
-
- if (dataType == Byte.class || dataType == byte.class) {
- size = Byte.SIZE;
- } else if (dataType == Short.class || dataType == short.class) {
- size = Short.SIZE;
- } else if (dataType == Integer.class || dataType == int.class) {
- size = Integer.SIZE;
- } else if (dataType == Long.class || dataType == long.class) {
- size = Long.SIZE;
- } else {
- throw new IllegalArgumentException(
- "Parameter must one of the following: Short/Int/Long\n");
- }
-
- int length = size / NetUtils.NumBitsInAByte;
- byte bytes[] = new byte[length];
-
- // Getting the bytes from input value
- for (int i = 0; i < length; i++) {
- bytes[i] = (byte) ((longValue >> (NetUtils.NumBitsInAByte * (length
- - i - 1))) & ByteMask);
- }
- return bytes;
- }
-
- /**
- * Accepts a number as input and returns its value in byte form in MSB
- * aligned form example: input = 5000 [1001110001000] bytes = -114, 64
- * [10011100] [01000000]
- *
- * @param Number
- * input
- * @param int numBits - the number of bits to be returned
- * @return byte[]
- *
- */
- public static byte[] toByteArray(Number input, int numBits) {
- Class<? extends Number> dataType = input.getClass();
- short size = 0;
- long longValue = input.longValue();
-
- if (dataType == Short.class) {
- size = Short.SIZE;
- } else if (dataType == Integer.class) {
- size = Integer.SIZE;
- } else if (dataType == Long.class) {
- size = Long.SIZE;
- } else {
- throw new IllegalArgumentException(
- "Parameter must one of the following: Short/Int/Long\n");
- }
-
- int length = size / NetUtils.NumBitsInAByte;
- byte bytes[] = new byte[length];
- byte[] inputbytes = new byte[length];
- byte shiftedBytes[];
-
- // Getting the bytes from input value
- for (int i = 0; i < length; i++) {
- bytes[i] = (byte) ((longValue >> (NetUtils.NumBitsInAByte * (length
- - i - 1))) & ByteMask);
- }
-
- if ((bytes[0] == 0 && dataType == Long.class)
- || (bytes[0] == 0 && dataType == Integer.class)) {
- int index = 0;
- for (index = 0; index < length; ++index) {
- if (bytes[index] != 0) {
- bytes[0] = bytes[index];
- break;
- }
- }
- System.arraycopy(bytes, index, inputbytes, 0, length - index);
- Arrays.fill(bytes, length - index + 1, length - 1, (byte) 0);
- } else {
- System.arraycopy(bytes, 0, inputbytes, 0, length);
- }
-
- shiftedBytes = shiftBitsToMSB(inputbytes, numBits);
-
- return shiftedBytes;
- }
-
- /**
- * Takes an LSB aligned byte array and returned the LSB numBits in a MSB
- * aligned byte array
- *
- * @param inputbytes
- * @param numBits
- * @return
- */
- /**
- * It aligns the last numBits bits to the head of the byte array following
- * them with numBits % 8 zero bits.
- *
- * Example: For inputbytes = [00000111][01110001] and numBits = 12 it
- * returns: shiftedBytes = [01110111][00010000]
- *
- * @param byte[] inputBytes
- * @param int numBits - number of bits to be left aligned
- * @return byte[]
- */
- public static byte[] shiftBitsToMSB(byte[] inputBytes, int numBits) {
- int numBitstoShiftBy = 0, leadZeroesMSB = 8, numEndRestBits = 0;
- int size = inputBytes.length;
- byte[] shiftedBytes = new byte[size];
- int i;
-
- for (i = 0; i < Byte.SIZE; i++) {
- if (((byte) (inputBytes[0] & getMSBMask(i + 1))) != 0) {
- leadZeroesMSB = i;
- break;
- }
- }
-
- if (numBits % NetUtils.NumBitsInAByte == 0) {
- numBitstoShiftBy = 0;
- } else {
- numBitstoShiftBy = ((NetUtils.NumBitsInAByte - (numBits % NetUtils.NumBitsInAByte)) < leadZeroesMSB) ? (NetUtils.NumBitsInAByte - (numBits % NetUtils.NumBitsInAByte))
- : leadZeroesMSB;
- }
- if (numBitstoShiftBy == 0) {
- return inputBytes;
- }
-
- if (numBits < NetUtils.NumBitsInAByte) {
- // inputbytes.length = 1 OR read less than a byte
- shiftedBytes[0] = (byte) ((inputBytes[0] & getLSBMask(numBits)) << numBitstoShiftBy);
- } else {
- // # of bits to read from last byte
- numEndRestBits = NetUtils.NumBitsInAByte
- - (inputBytes.length * NetUtils.NumBitsInAByte - numBits - numBitstoShiftBy);
-
- for (i = 0; i < (size - 1); i++) {
- if ((i + 1) == (size - 1)) {
- if (numEndRestBits > numBitstoShiftBy) {
- shiftedBytes[i] = (byte) ((inputBytes[i] << numBitstoShiftBy) | ((inputBytes[i + 1] & getMSBMask(numBitstoShiftBy)) >> (numEndRestBits - numBitstoShiftBy)));
- shiftedBytes[i + 1] = (byte) ((inputBytes[i + 1] & getLSBMask(numEndRestBits
- - numBitstoShiftBy)) << numBitstoShiftBy);
- } else
- shiftedBytes[i] = (byte) ((inputBytes[i] << numBitstoShiftBy) | ((inputBytes[i + 1] & getMSBMask(numEndRestBits)) >> (NetUtils.NumBitsInAByte - numEndRestBits)));
- }
- shiftedBytes[i] = (byte) ((inputBytes[i] << numBitstoShiftBy) | (inputBytes[i + 1] & getMSBMask(numBitstoShiftBy)) >> (NetUtils.NumBitsInAByte - numBitstoShiftBy));
- }
-
- }
- return shiftedBytes;
- }
-
- /**
- * It aligns the first numBits bits to the right end of the byte array
- * preceding them with numBits % 8 zero bits.
- *
- * Example: For inputbytes = [01110111][00010000] and numBits = 12 it
- * returns: shiftedBytes = [00000111][01110001]
- *
- * @param byte[] inputBytes
- * @param int numBits - number of bits to be right aligned
- * @return byte[]
- */
- public static byte[] shiftBitsToLSB(byte[] inputBytes, int numBits) {
- int numBytes = inputBytes.length;
- int numBitstoShift = numBits % NetUtils.NumBitsInAByte;
- byte[] shiftedBytes = new byte[numBytes];
- int inputLsb = 0, inputMsb = 0;
-
- if (numBitstoShift == 0) {
- return inputBytes;
- }
-
- for (int i = 1; i < numBytes; i++) {
- inputLsb = inputBytes[i - 1]
- & getLSBMask(NetUtils.NumBitsInAByte - numBitstoShift);
- inputLsb = (inputLsb < 0) ? (inputLsb + 256) : inputLsb;
- inputMsb = inputBytes[i] & getMSBMask(numBitstoShift);
- inputMsb = (inputBytes[i] < 0) ? (inputBytes[i] + 256)
- : inputBytes[i];
- shiftedBytes[i] = (byte) ((inputLsb << numBitstoShift) | (inputMsb >> (NetUtils.NumBitsInAByte - numBitstoShift)));
- }
- inputMsb = inputBytes[0] & (getMSBMask(numBitstoShift));
- inputMsb = (inputMsb < 0) ? (inputMsb + 256) : inputMsb;
- shiftedBytes[0] = (byte) (inputMsb >> (NetUtils.NumBitsInAByte - numBitstoShift));
- return shiftedBytes;
- }
-
- /**
- * Insert in the data buffer at position dictated by the offset the number
- * of bits specified from the input data byte array. The input byte array
- * has the bits stored starting from the LSB
- *
- * @param byte[] data
- * @param byte[] inputdata
- * @param int startOffset
- * @param int numBits
- */
- public static void insertBits(byte[] data, byte[] inputdataLSB,
- int startOffset, int numBits) {
- byte[] inputdata = shiftBitsToMSB(inputdataLSB, numBits); // Align to
- // MSB the
- // passed byte
- // array
- int numBytes = numBits / NetUtils.NumBitsInAByte;
- int startByteOffset = startOffset / NetUtils.NumBitsInAByte;
- int extraOffsetBits = startOffset % NetUtils.NumBitsInAByte;
- int extranumBits = numBits % NetUtils.NumBitsInAByte;
- int RestBits = numBits % NetUtils.NumBitsInAByte;
- int InputMSBbits = 0, InputLSBbits = 0;
- int i;
-
- if (numBits == 0) {
- return;
- }
-
- if (extraOffsetBits == 0) {
- if (extranumBits == 0) {
- numBytes = numBits / NetUtils.NumBitsInAByte;
- System.arraycopy(inputdata, 0, data, startByteOffset, numBytes);
- } else {
- System.arraycopy(inputdata, 0, data, startByteOffset, numBytes);
- data[startByteOffset + numBytes] = (byte) (data[startByteOffset
- + numBytes] | (inputdata[numBytes] & getMSBMask(extranumBits)));
- }
- } else {
- for (i = 0; i < numBytes; i++) {
- if (i != 0)
- InputLSBbits = (inputdata[i - 1] & getLSBMask(extraOffsetBits));
- InputMSBbits = (byte) (inputdata[i] & (getMSBMask(NetUtils.NumBitsInAByte
- - extraOffsetBits)));
- InputMSBbits = (InputMSBbits >= 0) ? InputMSBbits
- : InputMSBbits + 256;
- data[startByteOffset + i] = (byte) (data[startByteOffset + i]
- | (InputLSBbits << (NetUtils.NumBitsInAByte - extraOffsetBits)) | (InputMSBbits >> extraOffsetBits));
- InputMSBbits = InputLSBbits = 0;
- }
- if (RestBits < (NetUtils.NumBitsInAByte - extraOffsetBits)) {
- if (numBytes != 0)
- InputLSBbits = (inputdata[i - 1] & getLSBMask(extraOffsetBits));
- InputMSBbits = (byte) (inputdata[i] & (getMSBMask(RestBits)));
- InputMSBbits = (InputMSBbits >= 0) ? InputMSBbits
- : InputMSBbits + 256;
- data[startByteOffset + i] = (byte) ((data[startByteOffset + i])
- | (InputLSBbits << (NetUtils.NumBitsInAByte - extraOffsetBits)) | (InputMSBbits >> extraOffsetBits));
- } else if (RestBits == (NetUtils.NumBitsInAByte - extraOffsetBits)) {
- if (numBytes != 0)
- InputLSBbits = (inputdata[i - 1] & getLSBMask(extraOffsetBits));
- InputMSBbits = (byte) (inputdata[i] & (getMSBMask(NetUtils.NumBitsInAByte
- - extraOffsetBits)));
- InputMSBbits = (InputMSBbits >= 0) ? InputMSBbits
- : InputMSBbits + 256;
- data[startByteOffset + i] = (byte) (data[startByteOffset + i]
- | (InputLSBbits << (NetUtils.NumBitsInAByte - extraOffsetBits)) | (InputMSBbits >> extraOffsetBits));
- } else {
- if (numBytes != 0)
- InputLSBbits = (inputdata[i - 1] & getLSBMask(extraOffsetBits));
- InputMSBbits = (byte) (inputdata[i] & (getMSBMask(NetUtils.NumBitsInAByte
- - extraOffsetBits)));
- InputMSBbits = (InputMSBbits >= 0) ? InputMSBbits
- : InputMSBbits + 256;
- data[startByteOffset + i] = (byte) (data[startByteOffset + i]
- | (InputLSBbits << (NetUtils.NumBitsInAByte - extraOffsetBits)) | (InputMSBbits >> extraOffsetBits));
-
- InputLSBbits = (inputdata[i] & (getLSBMask(RestBits
- - (NetUtils.NumBitsInAByte - extraOffsetBits)) << (NetUtils.NumBitsInAByte - RestBits)));
- data[startByteOffset + i + 1] = (byte) (data[startByteOffset
- + i + 1] | (InputLSBbits << (NetUtils.NumBitsInAByte - extraOffsetBits)));
- }
- }
- }
-
- /**
- * Checks for overflow and underflow exceptions
- * @param data
- * @param startOffset
- * @param numBits
- * @throws PacketException when the startOffset and numBits parameters
- * are not congruent with the data buffer's size
- */
- public static void checkExceptions(byte[] data, int startOffset, int numBits)
- throws BufferException {
- int endOffsetByte;
- int startByteOffset;
- endOffsetByte = startOffset
- / NetUtils.NumBitsInAByte
- + numBits
- / NetUtils.NumBitsInAByte
- + ((numBits % NetUtils.NumBitsInAByte != 0) ? 1 : ((startOffset
- % NetUtils.NumBitsInAByte != 0) ? 1 : 0));
- startByteOffset = startOffset / NetUtils.NumBitsInAByte;
-
- if (data == null) {
- throw new BufferException("data[] is null\n");
- }
-
- if ((startOffset < 0) || (startByteOffset >= data.length)
- || (endOffsetByte > data.length) || (numBits < 0)
- || (numBits > NetUtils.NumBitsInAByte * data.length)) {
- throw new BufferException(
- "Illegal arguement/out of bound exception - data.length = "
- + data.length + " startOffset = " + startOffset
- + " numBits " + numBits);
- }
- }
-}