Add method to read more than 32 bits in ParsableBitArray

PiperOrigin-RevId: 277766372
This commit is contained in:
kimvde 2019-10-31 18:34:34 +00:00 committed by Oliver Woodman
parent 32dcd80b4a
commit 242a0053c9
4 changed files with 91 additions and 6 deletions

View file

@ -163,7 +163,7 @@ public final class ParsableBitArray {
* Reads up to 32 bits.
*
* @param numBits The number of bits to read.
* @return An integer whose bottom n bits hold the read data.
* @return An integer whose bottom {@code numBits} bits hold the read data.
*/
public int readBits(int numBits) {
if (numBits == 0) {
@ -185,12 +185,25 @@ public final class ParsableBitArray {
return returnValue;
}
/**
* Reads up to 64 bits.
*
* @param numBits The number of bits to read.
* @return A long whose bottom {@code numBits} bits hold the read data.
*/
public long readBitsToLong(int numBits) {
if (numBits <= 32) {
return Util.toUnsignedLong(readBits(numBits));
}
return Util.toUnsignedLong(readBits(numBits - 32)) << 32 | Util.toUnsignedLong(readBits(32));
}
/**
* Reads {@code numBits} bits into {@code buffer}.
*
* @param buffer The array into which the read data should be written. The trailing
* {@code numBits % 8} bits are written into the most significant bits of the last modified
* {@code buffer} byte. The remaining ones are unmodified.
* @param buffer The array into which the read data should be written. The trailing {@code numBits
* % 8} bits are written into the most significant bits of the last modified {@code buffer}
* byte. The remaining ones are unmodified.
* @param offset The offset in {@code buffer} at which the read data should be written.
* @param numBits The number of bits to read.
*/

View file

@ -146,7 +146,7 @@ public final class Util {
* Converts the entirety of an {@link InputStream} to a byte array.
*
* @param inputStream the {@link InputStream} to be read. The input stream is not closed by this
* method.
* method.
* @return a byte array containing all of the inputStream's bytes.
* @throws IOException if an error occurs reading from the stream.
*/
@ -366,7 +366,6 @@ public final class Util {
/* length= */ second.length);
return concatenation;
}
/**
* Creates a {@link Handler} with the specified {@link Handler.Callback} on the current {@link
* Looper} thread. The method accepts partially initialized objects as callback under the
@ -1192,6 +1191,17 @@ public final class Util {
return result;
}
/**
* Converts an integer to a long by unsigned conversion.
*
* <p>This method is equivalent to {@link Integer#toUnsignedLong(int)} for API 26+.
*/
public static long toUnsignedLong(int x) {
// x is implicitly casted to a long before the bit operation is executed but this does not
// impact the method correctness.
return x & 0xFFFFFFFFL;
}
/**
* Returns a byte array containing values parsed from the hex string provided.
*

View file

@ -107,6 +107,50 @@ public final class ParsableBitArrayTest {
assertThat(result).isEqualTo(0xF0000000);
}
@Test
public void testReadBitsToLong0Bits() {
byte[] testData = TestUtil.createByteArray(0x3C);
ParsableBitArray testArray = new ParsableBitArray(testData);
long result = testArray.readBitsToLong(0);
assertThat(result).isEqualTo(0);
}
@Test
public void testReadBitsToLongByteAligned() {
byte[] testData = TestUtil.createByteArray(0x3C, 0xD2, 0x5F, 0x01, 0xFF, 0x14, 0x60);
ParsableBitArray testArray = new ParsableBitArray(testData);
testArray.readBits(8);
long result = testArray.readBitsToLong(45);
assertThat(result).isEqualTo(0xD25F01FF14L << 5 | 0x60 >> 3);
assertThat(testArray.getPosition()).isEqualTo(53);
}
@Test
public void testReadBitsToLongNonByteAligned() {
byte[] testData = TestUtil.createByteArray(0x3C, 0xD2, 0x5F, 0x01, 0xFF, 0x14, 0x60);
ParsableBitArray testArray = new ParsableBitArray(testData);
testArray.readBits(3);
long result = testArray.readBitsToLong(53);
assertThat(result).isEqualTo((0x3CL & 0b11111) << 48 | 0xD25F01FF1460L);
assertThat(testArray.getPosition()).isEqualTo(56);
}
@Test
public void testReadBitsToLongNegativeValue() {
byte[] testData = TestUtil.createByteArray(0xF0, 0, 0, 0, 0, 0, 0, 0);
ParsableBitArray testArray = new ParsableBitArray(testData);
long result = testArray.readBitsToLong(64);
assertThat(result).isEqualTo(0xF000000000000000L);
}
@Test
public void testReadBitsToByteArray() {
byte[] testData = TestUtil.createByteArray(0x3C, 0xD2, 0x5F, 0x01, 0xFF, 0x14, 0x60, 0x99);

View file

@ -217,6 +217,24 @@ public class UtilTest {
assertThat(parseXsDateTime("2014-09-19T13:18:55.000-800")).isEqualTo(1411161535000L);
}
@Test
public void testToUnsignedLongPositiveValue() {
int x = 0x05D67F23;
long result = Util.toUnsignedLong(x);
assertThat(result).isEqualTo(0x05D67F23L);
}
@Test
public void testToUnsignedLongNegativeValue() {
int x = 0xF5D67F23;
long result = Util.toUnsignedLong(x);
assertThat(result).isEqualTo(0xF5D67F23L);
}
@Test
public void testGetCodecsOfType() {
assertThat(getCodecsOfType(null, C.TRACK_TYPE_VIDEO)).isNull();