mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Add method to read more than 32 bits in ParsableBitArray
PiperOrigin-RevId: 277766372
This commit is contained in:
parent
32dcd80b4a
commit
242a0053c9
4 changed files with 91 additions and 6 deletions
|
|
@ -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) {
|
||||||
|
|
@ -185,12 +185,25 @@ public final class ParsableBitArray {
|
||||||
return returnValue;
|
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}.
|
* 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 {
|
||||||
* 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 {
|
||||||
/* 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
|
||||||
|
|
@ -1192,6 +1191,17 @@ public final class Util {
|
||||||
return result;
|
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.
|
* Returns a byte array containing values parsed from the hex string provided.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,50 @@ public final class ParsableBitArrayTest {
|
||||||
assertThat(result).isEqualTo(0xF0000000);
|
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
|
@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);
|
||||||
|
|
|
||||||
|
|
@ -217,6 +217,24 @@ public class UtilTest {
|
||||||
assertThat(parseXsDateTime("2014-09-19T13:18:55.000-800")).isEqualTo(1411161535000L);
|
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
|
@Test
|
||||||
public void testGetCodecsOfType() {
|
public void testGetCodecsOfType() {
|
||||||
assertThat(getCodecsOfType(null, C.TRACK_TYPE_VIDEO)).isNull();
|
assertThat(getCodecsOfType(null, C.TRACK_TYPE_VIDEO)).isNull();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue