Bug 1716518 - Upgrade bitreader to v0.3.4. r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D117764
This commit is contained in:
Mike Hommey 2021-06-15 20:39:49 +00:00
parent 702b706639
commit 2558543ffd
5 changed files with 121 additions and 6 deletions

6
Cargo.lock generated
View File

@ -319,11 +319,11 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]] [[package]]
name = "bitreader" name = "bitreader"
version = "0.3.2" version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fa7f0adf37cd5472c978a1ff4be89c1880a923d10df4cfef6a10855a666e09b" checksum = "9178181a7d44239c6c8eaafa8688558a2ab5fa04b8855381f2681e9591fb941b"
dependencies = [ dependencies = [
"cfg-if 0.1.10", "cfg-if 1.0.0",
] ]
[[package]] [[package]]

View File

@ -1 +1 @@
{"files":{"Cargo.toml":"27cfa3fe44cc78bce30786d727dedef7967e399c0cdec1282e8dafc9c38a6c10","LICENSE-APACHE":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","LICENSE-MIT":"8583712ee2b062ff3d4d6d3e16f19ff0f92bc3a0a4beeec11a81ef00146fbd4f","README.md":"28986de2e8d457e76ae3303d80094697e6ef4ad8da06a4a3178bb1b52bff63d5","src/lib.rs":"6947e329a2f20dca35ea14b6f483c23b4812ae55b6851a276355c31fb7dd65e9","src/tests.rs":"b3ed3ae22daa348dc786219b6e2c4f2b1d3ba35d7d4401ea05f773773fdf8807"},"package":"5fa7f0adf37cd5472c978a1ff4be89c1880a923d10df4cfef6a10855a666e09b"} {"files":{"Cargo.toml":"1da2771067c7bb47f182c75624cec456ef99daf6882314633a2a68aefc2616ad","LICENSE-APACHE":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","LICENSE-MIT":"8583712ee2b062ff3d4d6d3e16f19ff0f92bc3a0a4beeec11a81ef00146fbd4f","README.md":"28986de2e8d457e76ae3303d80094697e6ef4ad8da06a4a3178bb1b52bff63d5","src/lib.rs":"6dcb62a9279ecad8cdcfe37f383282089753e28adc0f2785ca73d50040bc89e7","src/tests.rs":"f67d17aa8faed5e3838322de9b98bb0cdc58d35fe5870e3f5c65ef1ef788966e"},"package":"9178181a7d44239c6c8eaafa8688558a2ab5fa04b8855381f2681e9591fb941b"}

View File

@ -12,7 +12,7 @@
[package] [package]
name = "bitreader" name = "bitreader"
version = "0.3.2" version = "0.3.4"
authors = ["Ilkka Rauta <ilkka.rauta@gmail.com>"] authors = ["Ilkka Rauta <ilkka.rauta@gmail.com>"]
description = "BitReader helps reading individual bits from a slice of bytes.\n\nYou can read \"unusual\" numbers of bits from the byte slice, for example 13 bits\nat once. The reader internally keeps track of position within the buffer.\n" description = "BitReader helps reading individual bits from a slice of bytes.\n\nYou can read \"unusual\" numbers of bits from the byte slice, for example 13 bits\nat once. The reader internally keeps track of position within the buffer.\n"
homepage = "https://github.com/irauta/bitreader" homepage = "https://github.com/irauta/bitreader"
@ -21,7 +21,7 @@ keywords = ["bit", "bits", "bitstream"]
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
repository = "https://github.com/irauta/bitreader" repository = "https://github.com/irauta/bitreader"
[dependencies.cfg-if] [dependencies.cfg-if]
version = "0.1.9" version = "1"
[features] [features]
default = ["std"] default = ["std"]

View File

@ -118,6 +118,11 @@ impl<'a> BitReader<'a> {
Ok((value & 0xff) as u8) Ok((value & 0xff) as u8)
} }
/// Read at most 8 bits into a u8, but without moving the cursor forward.
pub fn peek_u8(&self, bit_count: u8) -> Result<u8> {
self.relative_reader().read_u8(bit_count)
}
/// Fills the entire `output_bytes` slice. If there aren't enough bits remaining /// Fills the entire `output_bytes` slice. If there aren't enough bits remaining
/// after the internal cursor's current position, the cursor won't be moved forward /// after the internal cursor's current position, the cursor won't be moved forward
/// and the contents of `output_bytes` won't be modified. /// and the contents of `output_bytes` won't be modified.
@ -143,18 +148,33 @@ impl<'a> BitReader<'a> {
Ok((value & 0xffff) as u16) Ok((value & 0xffff) as u16)
} }
/// Read at most 16 bits into a u16, but without moving the cursor forward.
pub fn peek_u16(&self, bit_count: u8) -> Result<u16> {
self.relative_reader().read_u16(bit_count)
}
/// Read at most 32 bits into a u32. /// Read at most 32 bits into a u32.
pub fn read_u32(&mut self, bit_count: u8) -> Result<u32> { pub fn read_u32(&mut self, bit_count: u8) -> Result<u32> {
let value = self.read_value(bit_count, 32)?; let value = self.read_value(bit_count, 32)?;
Ok((value & 0xffffffff) as u32) Ok((value & 0xffffffff) as u32)
} }
/// Read at most 32 bits into a u32, but without moving the cursor forward.
pub fn peek_u32(&self, bit_count: u8) -> Result<u32> {
self.relative_reader().read_u32(bit_count)
}
/// Read at most 64 bits into a u64. /// Read at most 64 bits into a u64.
pub fn read_u64(&mut self, bit_count: u8) -> Result<u64> { pub fn read_u64(&mut self, bit_count: u8) -> Result<u64> {
let value = self.read_value(bit_count, 64)?; let value = self.read_value(bit_count, 64)?;
Ok(value) Ok(value)
} }
/// Read at most 64 bits into a u64, but without moving the cursor forward.
pub fn peek_u64(&self, bit_count: u8) -> Result<u64> {
self.relative_reader().read_u64(bit_count)
}
/// Read at most 8 bits into a i8. /// Read at most 8 bits into a i8.
/// Assumes the bits are stored in two's complement format. /// Assumes the bits are stored in two's complement format.
pub fn read_i8(&mut self, bit_count: u8) -> Result<i8> { pub fn read_i8(&mut self, bit_count: u8) -> Result<i8> {
@ -192,6 +212,12 @@ impl<'a> BitReader<'a> {
} }
} }
/// Read a single bit as a boolean value, but without moving the cursor forward.
/// Interprets 1 as true and 0 as false.
pub fn peek_bool(&self) -> Result<bool> {
self.relative_reader().read_bool()
}
/// Skip arbitrary number of bits. However, you can skip at most to the end of the byte slice. /// Skip arbitrary number of bits. However, you can skip at most to the end of the byte slice.
pub fn skip(&mut self, bit_count: u64) -> Result<()> { pub fn skip(&mut self, bit_count: u64) -> Result<()> {
let end_position = self.position + bit_count; let end_position = self.position + bit_count;
@ -231,6 +257,18 @@ impl<'a> BitReader<'a> {
self.position % (alignment_bytes as u64 * 8) == 0 self.position % (alignment_bytes as u64 * 8) == 0
} }
/// Helper to move the "bit cursor" to exactly the beginning of a byte, or to a specific
/// multi-byte alignment position.
///
/// That is, `reader.align(n)` moves the cursor to the next position that
/// is a multiple of n * 8 bits, if it's not correctly aligned already.
pub fn align(&mut self, alignment_bytes: u32) -> Result<()> {
let alignment_bits = alignment_bytes as u64 * 8;
let cur_alignment = self.position % alignment_bits;
let bits_to_skip = (alignment_bits - cur_alignment) % alignment_bits;
self.skip(bits_to_skip)
}
fn read_signed_value(&mut self, bit_count: u8, maximum_count: u8) -> Result<i64> { fn read_signed_value(&mut self, bit_count: u8, maximum_count: u8) -> Result<i64> {
let unsigned = self.read_value(bit_count, maximum_count)?; let unsigned = self.read_value(bit_count, maximum_count)?;
// Fill the bits above the requested bits with all ones or all zeros, // Fill the bits above the requested bits with all ones or all zeros,

View File

@ -18,17 +18,32 @@ fn read_buffer() {
let mut reader = BitReader::new(bytes); let mut reader = BitReader::new(bytes);
assert_eq!(reader.read_u8(1).unwrap(), 0b1); assert_eq!(reader.read_u8(1).unwrap(), 0b1);
assert_eq!(reader.peek_u8(3).unwrap(), 0b011);
assert_eq!(reader.read_u8(1).unwrap(), 0b0); assert_eq!(reader.read_u8(1).unwrap(), 0b0);
assert_eq!(reader.read_u8(2).unwrap(), 0b11); assert_eq!(reader.read_u8(2).unwrap(), 0b11);
assert!(!reader.is_aligned(1));
assert!(!reader.is_aligned(2));
assert!(!reader.is_aligned(4));
assert_eq!(reader.position(), 4); assert_eq!(reader.position(), 4);
assert_eq!(reader.remaining(), 60); assert_eq!(reader.remaining(), 60);
assert_eq!(reader.read_u8(4).unwrap(), 0b0101); assert_eq!(reader.read_u8(4).unwrap(), 0b0101);
assert!(reader.is_aligned(1)); assert!(reader.is_aligned(1));
assert!(!reader.is_aligned(2));
assert!(!reader.is_aligned(4));
assert_eq!(reader.align(1), Ok(())); // shouldn't do anything if already aligned
assert_eq!(reader.peek_u64(16).unwrap(), 0b110_1010_1010_1100);
assert_eq!(reader.read_u8(3).unwrap(), 0b11); assert_eq!(reader.read_u8(3).unwrap(), 0b11);
assert_eq!(reader.peek_u16(13).unwrap(), 0b1010_1010_1100);
assert_eq!(reader.peek_u32(13).unwrap(), 0b1010_1010_1100);
assert_eq!(reader.peek_u64(13).unwrap(), 0b1010_1010_1100);
assert_eq!(reader.peek_u16(10).unwrap(), 0b01_0101_0101);
assert_eq!(reader.peek_u8(8).unwrap(), 0b0101_0101);
assert_eq!(reader.read_u16(10).unwrap(), 0b01_0101_0101); assert_eq!(reader.read_u16(10).unwrap(), 0b01_0101_0101);
assert_eq!(reader.read_u8(3).unwrap(), 0b100); assert_eq!(reader.read_u8(3).unwrap(), 0b100);
@ -39,12 +54,74 @@ fn read_buffer() {
assert_eq!(reader.read_u32(32).unwrap(), 0b1001_1001_1001_1001_1001_1001_1001_1001); assert_eq!(reader.read_u32(32).unwrap(), 0b1001_1001_1001_1001_1001_1001_1001_1001);
assert_eq!(reader.peek_bool().unwrap(), true);
assert_eq!(reader.read_u8(4).unwrap(), 0b1110); assert_eq!(reader.read_u8(4).unwrap(), 0b1110);
assert_eq!(reader.peek_bool().unwrap(), false);
assert_eq!(reader.read_u8(3).unwrap(), 0b011); assert_eq!(reader.read_u8(3).unwrap(), 0b011);
assert_eq!(reader.peek_bool().unwrap(), true);
assert_eq!(reader.read_bool().unwrap(), true); assert_eq!(reader.read_bool().unwrap(), true);
// Could also be 8 at this point! // Could also be 8 at this point!
assert!(reader.is_aligned(4)); assert!(reader.is_aligned(4));
// shouldn't do anything if already aligned
assert_eq!(reader.align(1), Ok(()));
assert_eq!(reader.align(2), Ok(()));
assert_eq!(reader.align(4), Ok(()));
assert_eq!(reader.align(8), Ok(()));
// Start over to test align()
let mut reader = BitReader::new(bytes);
// shouldn't do anything if already aligned
assert_eq!(reader.align(1), Ok(()));
assert_eq!(reader.align(2), Ok(()));
assert_eq!(reader.align(4), Ok(()));
assert_eq!(reader.align(8), Ok(()));
assert_eq!(reader.position(), 0);
assert_eq!(reader.read_u8(1).unwrap(), 0b1);
assert_eq!(reader.align(1), Ok(()));
assert_eq!(reader.position(), 8);
assert!(reader.is_aligned(1));
assert!(!reader.is_aligned(2));
assert!(!reader.is_aligned(4));
assert_eq!(reader.align(2), Ok(()));
assert_eq!(reader.position(), 16);
assert!(reader.is_aligned(1));
assert!(reader.is_aligned(2));
assert!(!reader.is_aligned(4));
assert_eq!(reader.read_u8(7).unwrap(), 0b0101_0110);
assert_eq!(reader.align(4), Ok(()));
assert_eq!(reader.position(), 32);
assert!(reader.is_aligned(1));
assert!(reader.is_aligned(2));
assert!(reader.is_aligned(4));
let mut reader = BitReader::new(bytes);
assert_eq!(reader.position(), 0);
assert_eq!(reader.skip(1), Ok(()));
assert_eq!(reader.align(4), Ok(()));
assert_eq!(reader.position(), 32);
assert_eq!(reader.skip(7), Ok(()));
assert_eq!(reader.align(1), Ok(()));
assert_eq!(reader.position(), 40);
assert_eq!(reader.align(2), Ok(()));
assert_eq!(reader.position(), 48);
assert_eq!(reader.skip(5), Ok(()));
assert_eq!(reader.align(2), Ok(()));
assert_eq!(reader.position(), 64);
let mut reader = BitReader::new(bytes);
assert_eq!(reader.skip(1), Ok(()));
assert_eq!(reader.align(3), Ok(()));
assert_eq!(reader.position(), 24);
assert!(!reader.align(128).is_ok());
} }
#[test] #[test]