package org.eclipse.tracecompass.ctf.core.event.io;
+import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.tracecompass.ctf.core.trace.CTFReaderException;
+import org.eclipse.tracecompass.ctf.core.CTFException;
/**
* <b><u>BitBuffer</u></b>
* <p>
* A bitwise buffer capable of accessing fields with bit offsets.
- *
- * @since 2.0
*/
public final class BitBuffer {
// ------------------------------------------------------------------------
/* default bit width */
- /** 8 bits to a char */
- public static final int BIT_CHAR = 8;
- /** 16 bits to a short */
- public static final int BIT_SHORT = 16;
- /** 32 bits to an int */
- public static final int BIT_INT = 32;
- /** 32 bits to a float */
- public static final int BIT_FLOAT = 32;
- /** 64 bits to a long */
- public static final int BIT_LONG = 64;
+ private static final int BIT_CHAR = Byte.SIZE; // yum
+ private static final int BYTE_MASK = (1 << BIT_CHAR) - 1;
+ private static final int BIT_SHORT = Short.SIZE;
+ private static final int SHORT_MASK = (1 << BIT_SHORT) - 1;
+ private static final int BIT_INT = Integer.SIZE;
+ private static final long INT_MASK = (1L << BIT_INT) - 1;
+ private static final int BIT_LONG = Long.SIZE;
// ------------------------------------------------------------------------
// Attributes
/**
* Default constructor, makes a big-endian buffer
*/
- @SuppressWarnings("null")
public BitBuffer() {
- this(ByteBuffer.allocateDirect(0), ByteOrder.BIG_ENDIAN);
+ this(checkNotNull(ByteBuffer.allocateDirect(0)), ByteOrder.BIG_ENDIAN);
}
/**
fBuffer = buf;
setByteOrder(order);
resetPosition();
- fBitCapacity = fBuffer.capacity() * BIT_CHAR;
+ fBitCapacity = (long) fBuffer.capacity() * BIT_CHAR;
}
private void resetPosition() {
* byte order.
*
* @return The int value (signed) read from the buffer
- * @throws CTFReaderException
+ * @throws CTFException
* An error occurred reading the long. This exception can be
* raised if the buffer tries to read out of bounds
*/
- public int getInt() throws CTFReaderException {
+ public int getInt() throws CTFException {
return getInt(BIT_INT, true);
}
* byte order.
*
* @return The long value (signed) read from the buffer
- * @throws CTFReaderException
+ * @throws CTFException
* An error occurred reading the long. This exception can be
* raised if the buffer tries to read out of bounds
- * @since 3.0
*/
- public long getLong() throws CTFReaderException {
+ public long getLong() throws CTFException {
return get(BIT_LONG, true);
}
* @param signed
* The sign extended flag
* @return The long value read from the buffer
- * @throws CTFReaderException
+ * @throws CTFException
* An error occurred reading the data. If more than 64 bits at a
* time are read, or the buffer is read beyond its end, this
* exception will be raised.
- * @since 3.0
*/
- public long get(int length, boolean signed) throws CTFReaderException {
+ public long get(int length, boolean signed) throws CTFException {
if (length > BIT_LONG) {
- throw new CTFReaderException("Cannot read a long longer than 64 bits. Rquested: " + length); //$NON-NLS-1$
+ throw new CTFException("Cannot read a long longer than 64 bits. Rquested: " + length); //$NON-NLS-1$
}
if (length > BIT_INT) {
final int highShift = length - BIT_INT;
long b = getInt(highShift, false);
long retVal;
/* Cast the signed-extended int into a unsigned int. */
- a &= 0xFFFFFFFFL;
+ a &= INT_MASK;
b &= (1L << highShift) - 1L;
retVal = (fByteOrder == ByteOrder.BIG_ENDIAN) ? ((a << highShift) | b) : ((b << BIT_INT) | a);
return retVal;
}
long retVal = getInt(length, signed);
- return (signed ? retVal : (retVal & 0xFFFFFFFFL));
+ return (signed ? retVal : (retVal & INT_MASK));
}
/**
* @throws BufferUnderflowException
* - If there are fewer than length bytes remaining in this
* buffer
- * @since 3.1
*/
public void get(@NonNull byte[] dst) {
- fBuffer.position((int) (fPosition / 8));
+ fBuffer.position((int) (fPosition / BIT_CHAR));
fBuffer.get(dst);
- fPosition += dst.length * 8;
+ fPosition += dst.length * BIT_CHAR;
}
/**
* @param signed
* The sign extended flag
* @return The int value read from the buffer
- * @throws CTFReaderException
+ * @throws CTFException
* An error occurred reading the data. When the buffer is read
* beyond its end, this exception will be raised.
*/
- private int getInt(int length, boolean signed) throws CTFReaderException {
+ private int getInt(int length, boolean signed) throws CTFException {
/* Nothing to read. */
if (length == 0) {
/* Validate that the buffer has enough bits. */
if (!canRead(length)) {
- throw new CTFReaderException("Cannot read the integer, " + //$NON-NLS-1$
+ throw new CTFException("Cannot read the integer, " + //$NON-NLS-1$
"the buffer does not have enough remaining space. " + //$NON-NLS-1$
"Requested:" + length); //$NON-NLS-1$
}
switch (length) {
case BitBuffer.BIT_CHAR:
// Byte
- val = fBuffer.get((int) (fPosition / 8));
+ val = fBuffer.get((int) (fPosition / BIT_CHAR));
if (!signed) {
- val = val & 0xff;
+ val = val & BYTE_MASK;
}
gotIt = true;
break;
case BitBuffer.BIT_SHORT:
// Word
- val = fBuffer.getShort((int) (fPosition / 8));
+ val = fBuffer.getShort((int) (fPosition / BIT_CHAR));
if (!signed) {
- val = val & 0xffff;
+ val = val & SHORT_MASK;
}
gotIt = true;
break;
case BitBuffer.BIT_INT:
// Double word
- val = fBuffer.getInt((int) (fPosition / 8));
+ val = fBuffer.getInt((int) (fPosition / BIT_CHAR));
gotIt = true;
break;
int value = 0;
currByte = startByte;
- cache = fBuffer.get(currByte) & 0xFF;
+ cache = fBuffer.get(currByte) & BYTE_MASK;
boolean isNeg = (cache & (1 << (BIT_CHAR - (index % BIT_CHAR) - 1))) != 0;
if (signed && isNeg) {
value = ~0;
}
for (; currByte < (endByte - 1); currByte++) {
value <<= BIT_CHAR;
- value |= fBuffer.get(currByte) & 0xFF;
+ value |= fBuffer.get(currByte) & BYTE_MASK;
}
lshift = (int) (end % BIT_CHAR);
if (lshift > 0) {
mask = ~((~0) << lshift);
- cmask = fBuffer.get(currByte) & 0xFF;
+ cmask = fBuffer.get(currByte) & BYTE_MASK;
cmask >>>= BIT_CHAR - lshift;
cmask &= mask;
value <<= lshift;
value |= cmask;
} else {
value <<= BIT_CHAR;
- value |= fBuffer.get(currByte) & 0xFF;
+ value |= fBuffer.get(currByte) & BYTE_MASK;
}
return value;
}
int value = 0;
currByte = endByte - 1;
- cache = fBuffer.get(currByte) & 0xFF;
+ cache = fBuffer.get(currByte) & BYTE_MASK;
mod = (int) (end % BIT_CHAR);
lshift = (mod > 0) ? mod : BIT_CHAR;
boolean isNeg = (cache & (1 << (lshift - 1))) != 0;
}
for (; currByte >= (startByte + 1); currByte--) {
value <<= BIT_CHAR;
- value |= fBuffer.get(currByte) & 0xFF;
+ value |= fBuffer.get(currByte) & BYTE_MASK;
}
lshift = (int) (index % BIT_CHAR);
if (lshift > 0) {
mask = ~((~0) << (BIT_CHAR - lshift));
- cmask = fBuffer.get(currByte) & 0xFF;
+ cmask = fBuffer.get(currByte) & BYTE_MASK;
cmask >>>= lshift;
cmask &= mask;
value <<= (BIT_CHAR - lshift);
value |= cmask;
} else {
value <<= BIT_CHAR;
- value |= fBuffer.get(currByte) & 0xFF;
+ value |= fBuffer.get(currByte) & BYTE_MASK;
}
return value;
}
*
* @param value
* The int value to write
- * @throws CTFReaderException
+ * @throws CTFException
* An error occurred writing the data. If the buffer is written
* beyond its end, this exception will be raised.
*/
- public void putInt(int value) throws CTFReaderException {
+ public void putInt(int value) throws CTFException {
putInt(BIT_INT, value);
}
* The number of bits to write
* @param value
* The value to write
- * @throws CTFReaderException
+ * @throws CTFException
* An error occurred writing the data. If the buffer is written
* beyond its end, this exception will be raised.
*/
- public void putInt(int length, int value) throws CTFReaderException {
+ public void putInt(int length, int value) throws CTFException {
final long curPos = fPosition;
if (!canRead(length)) {
- throw new CTFReaderException("Cannot write to bitbuffer, " //$NON-NLS-1$
+ throw new CTFException("Cannot write to bitbuffer, " //$NON-NLS-1$
+ "insufficient space. Requested: " + length); //$NON-NLS-1$
}
if (length == 0) {
* already cleared
*/
cmask &= ~mask;
- int b = fBuffer.get(startByte) & 0xFF;
+ int b = fBuffer.get(startByte) & BYTE_MASK;
fBuffer.put(startByte, (byte) ((b & mask) | cmask));
return;
}
mask = ~((~0) << lshift);
cmask = correctedValue << lshift;
cmask &= ~mask;
- int b = fBuffer.get(currByte) & 0xFF;
+ int b = fBuffer.get(currByte) & BYTE_MASK;
fBuffer.put(currByte, (byte) ((b & mask) | cmask));
correctedValue >>>= cshift;
currByte--;
if ((index % BIT_CHAR) > 0) {
mask = (~0) << (BIT_CHAR - (index % BIT_CHAR));
cmask = correctedValue & ~mask;
- int b = fBuffer.get(currByte) & 0xFF;
+ int b = fBuffer.get(currByte) & BYTE_MASK;
fBuffer.put(currByte, (byte) ((b & mask) | cmask));
} else {
fBuffer.put(currByte, (byte) correctedValue);
* already cleared
*/
cmask &= ~mask;
- int b = fBuffer.get(startByte) & 0xFF;
+ int b = fBuffer.get(startByte) & BYTE_MASK;
fBuffer.put(startByte, (byte) ((b & mask) | cmask));
return;
}
mask = ~((~0) << cshift);
cmask = correctedValue << cshift;
cmask &= ~mask;
- int b = fBuffer.get(currByte) & 0xFF;
+ int b = fBuffer.get(currByte) & BYTE_MASK;
fBuffer.put(currByte, (byte) ((b & mask) | cmask));
correctedValue >>>= BIT_CHAR - cshift;
currByte++;
if ((end % BIT_CHAR) > 0) {
mask = (~0) << (end % BIT_CHAR);
cmask = correctedValue & ~mask;
- int b = fBuffer.get(currByte) & 0xFF;
+ int b = fBuffer.get(currByte) & BYTE_MASK;
fBuffer.put(currByte, (byte) ((b & mask) | cmask));
} else {
fBuffer.put(currByte, (byte) correctedValue);
*
* @param newPosition
* The new position of the buffer.
- * @throws CTFReaderException
+ * @throws CTFException
* Thrown on out of bounds exceptions
- * @since 3.0
*/
- public void position(long newPosition) throws CTFReaderException {
-
+ public void position(long newPosition) throws CTFException {
if (newPosition > fBitCapacity) {
- throw new CTFReaderException("Out of bounds exception on a position move, attempting to access position: " + newPosition); //$NON-NLS-1$
+ throw new CTFException("Out of bounds exception on a position move, attempting to access position: " + newPosition); //$NON-NLS-1$
}
fPosition = newPosition;
}
* Sets the position in the buffer.
*
* @return order The position of the buffer.
- * @since 3.0
*/
public long position() {
return fPosition;
}
- /**
- * Sets the byte buffer
- *
- * @param buf
- * the byte buffer
- */
- @Deprecated
- public void setByteBuffer(ByteBuffer buf) {
- /*
- * to avoid "The method setByteBuffer(ByteBuffer) from the type
- * BitBuffer can be declared as static"
- */
- long data = fPosition;
- fPosition = data;
- throw new UnsupportedOperationException("Bytebuffers are now final"); //$NON-NLS-1$
-
- }
-
/**
* Gets the byte buffer
*