Commit 242a0053 by kimvde Committed by Oliver Woodman

Add method to read more than 32 bits in ParsableBitArray

PiperOrigin-RevId: 277766372
parent 32dcd80b
...@@ -163,7 +163,7 @@ public final class ParsableBitArray { ...@@ -163,7 +163,7 @@ public final class ParsableBitArray {
* Reads up to 32 bits. * Reads up to 32 bits.
* *
* @param numBits The number of bits to read. * @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) { public int readBits(int numBits) {
if (numBits == 0) { if (numBits == 0) {
...@@ -186,11 +186,24 @@ public final class ParsableBitArray { ...@@ -186,11 +186,24 @@ public final class ParsableBitArray {
} }
/** /**
* 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}. * Reads {@code numBits} bits into {@code buffer}.
* *
* @param buffer The array into which the read data should be written. The trailing * @param buffer The array into which the read data should be written. The trailing {@code numBits
* {@code numBits % 8} bits are written into the most significant bits of the last modified * % 8} bits are written into the most significant bits of the last modified {@code buffer}
* {@code buffer} byte. The remaining ones are unmodified. * byte. The remaining ones are unmodified.
* @param offset The offset in {@code buffer} at which the read data should be written. * @param offset The offset in {@code buffer} at which the read data should be written.
* @param numBits The number of bits to read. * @param numBits The number of bits to read.
*/ */
......
...@@ -146,7 +146,7 @@ public final class Util { ...@@ -146,7 +146,7 @@ public final class Util {
* Converts the entirety of an {@link InputStream} to a byte array. * 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 * @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. * @return a byte array containing all of the inputStream's bytes.
* @throws IOException if an error occurs reading from the stream. * @throws IOException if an error occurs reading from the stream.
*/ */
...@@ -366,7 +366,6 @@ public final class Util { ...@@ -366,7 +366,6 @@ public final class Util {
/* length= */ second.length); /* length= */ second.length);
return concatenation; return concatenation;
} }
/** /**
* Creates a {@link Handler} with the specified {@link Handler.Callback} on the current {@link * 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 * Looper} thread. The method accepts partially initialized objects as callback under the
...@@ -1193,6 +1192,17 @@ public final class Util { ...@@ -1193,6 +1192,17 @@ public final class Util {
} }
/** /**
* 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. * Returns a byte array containing values parsed from the hex string provided.
* *
* @param hexString The hex string to convert to bytes. * @param hexString The hex string to convert to bytes.
......
...@@ -108,6 +108,50 @@ public final class ParsableBitArrayTest { ...@@ -108,6 +108,50 @@ public final class ParsableBitArrayTest {
} }
@Test @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() { public void testReadBitsToByteArray() {
byte[] testData = TestUtil.createByteArray(0x3C, 0xD2, 0x5F, 0x01, 0xFF, 0x14, 0x60, 0x99); byte[] testData = TestUtil.createByteArray(0x3C, 0xD2, 0x5F, 0x01, 0xFF, 0x14, 0x60, 0x99);
ParsableBitArray testArray = new ParsableBitArray(testData); ParsableBitArray testArray = new ParsableBitArray(testData);
......
...@@ -218,6 +218,24 @@ public class UtilTest { ...@@ -218,6 +218,24 @@ public class UtilTest {
} }
@Test @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() { public void testGetCodecsOfType() {
assertThat(getCodecsOfType(null, C.TRACK_TYPE_VIDEO)).isNull(); assertThat(getCodecsOfType(null, C.TRACK_TYPE_VIDEO)).isNull();
assertThat(getCodecsOfType("avc1.64001e,vp9.63.1", C.TRACK_TYPE_AUDIO)).isNull(); assertThat(getCodecsOfType("avc1.64001e,vp9.63.1", C.TRACK_TYPE_AUDIO)).isNull();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment