We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
I noticed the parser pops data from the array, effectively consuming it. This blocks #9 and in turn #8.
I suggest rewriting it to a bit-container with random-access and a walking 'current pointer'.
Here's my implementation in Java that you should be able to cannibalize.
public final class BitContainer { private final byte[] buffer; private final int bitCapacity; private int pointer = 0; // byte pointer private int remainingBits = 8; // Always in the range [1, 8] private BitContainer(byte[] buffer, int bitCapacity) { this.buffer = requireNonNull(buffer, "buffer"); this.bitCapacity = bitCapacity; } public static BitContainer allocate(int bitCapacity) { requireAtLeast(1, bitCapacity, "bitCapacity"); int capacity = (bitCapacity + 7) / 8; byte[] buffer = new byte[capacity]; return new BitContainer(buffer, bitCapacity); } public int bitCapacity() { return bitCapacity; } public int capacity() { return (bitCapacity + 7) / 8; } public int remainingBits() { return bitCapacity - buffer.position() * 8 + remainingBits - 8; } public void setPointer(int bitPosition) { pointer = bitPosition / 8; remainingBits = 8 - (bitPosition & 7); } public byte[] getArray(int numBits) { requireThat((numBits & 7) == 0, "numBits not an integral number of bytes: " + numBits); if (numBits > remainingBits()) throw new IndexOutOfBoundsException(numBits + " > " + remainingBits()); byte[] array = new byte[numBits / 8]; // Use more efficient method for byte-aligned bytes if (remainingBits == 8) { for (int i = 0; i < array.length; i++) array[i] = buffer[pointer++]; } else { for (int i = 0; i < array.length; i++) array[i] = (byte)getBits(8); } return array; } public void putArray(byte[] array) { requireNonNull(array, "array"); if (array.length * 8 > remainingBits()) throw new IndexOutOfBoundsException(array.length * 8 + " > " + remainingBits()); // Use more efficient method for byte-aligned bytes if (remainingBits == 8) { for (byte element : array) buffer[pointer++] = element; } else { for (byte element : array) putBits(8, element); } } public int getBits(int numBits) { requireRange(1, 32, numBits, "numBits"); if (numBits > remainingBits()) throw new IndexOutOfBoundsException(numBits + " > " + remainingBits()); if (numBits < remainingBits) { // Get middle bits of this byte and don't advance byte pointer byte value = buffer[pointer]; int result = extractBits(value, remainingBits - numBits, numBits); remainingBits -= numBits; return result; } int result; if (remainingBits != 8) { // Get all remaining bits of this byte and advance byte pointer byte value = buffer[pointer++]; result = extractBits(value, 0, remainingBits); numBits -= remainingBits; } else { result = 0; } // Get middle bytes and advance byte pointer while (numBits >= 8) { result <<= 8; result |= buffer[pointer++] & 0xFF; numBits -= 8; } if (numBits > 0) { // Get remaining bits of this byte and don't advance byte pointer byte value = buffer[pointer]; result <<= numBits; result |= extractBits(value, 8 - numBits, numBits); } remainingBits = 8 - numBits; return result; } public void putBits(int numBits, int bits) { requireRange(1, 32, numBits, "numBits"); if (numBits > remainingBits()) throw new IndexOutOfBoundsException(numBits + " > " + remainingBits()); if (numBits < remainingBits) { // Put all bits in the middle of this byte and don't advance byte pointer byte value = buffer[pointer]; byte result = injectBits(bits, value, remainingBits - numBits, numBits); buffer[pointer] = result; remainingBits -= numBits; return; } if (remainingBits != 8) { // Fill remaining bits of this byte and advance byte pointer byte value = buffer[pointer]; int highBits = extractBits(bits, numBits - remainingBits, remainingBits); byte result = injectBits(highBits, value, 0, remainingBits); numBits -= remainingBits; buffer[pointer++] = result; } // Fill middle bytes and advance byte pointer while (numBits >= 8) { int value = extractBits(bits, numBits - 8, 8); buffer[pointer++] = (byte)value; numBits -= 8; } if (numBits > 0) { // Put remaining bits in this byte and don't advance byte pointer byte value = buffer[pointer]; int lowBits = extractBits(bits, 0, numBits); byte result = injectBits(lowBits, value, 8 - numBits, numBits); buffer[pointer] = result; } remainingBits = 8 - numBits; } private static int extractBits(byte value, int firstBit, int numBits) { int mask = (1 << numBits) - 1; return value >> firstBit & mask; } private static int extractBits(int value, int firstBit, int numBits) { int mask = (1 << numBits) - 1; return value >> firstBit & mask; } private static byte injectBits(int bits, byte value, int firstBit, int numBits) { int mask = ((1 << numBits) - 1) << firstBit; return (byte)((value & ~mask) | (bits << firstBit & mask)); } }
The text was updated successfully, but these errors were encountered:
Yes, I'll split out all the helpers to a proper bitbuffer and then put something like this on top.
Sorry, something went wrong.
Bug fixed in setPointer(). And remember in Java / doesn't promote a type to float, it truncates.
setPointer()
/
Good thing I posted it here; I keep finding previously unnoticed bugs. (first post updated)
No branches or pull requests
I noticed the parser pops data from the array, effectively consuming it. This blocks #9 and in turn #8.
I suggest rewriting it to a bit-container with random-access and a walking 'current pointer'.
Here's my implementation in Java that you should be able to cannibalize.
The text was updated successfully, but these errors were encountered: