use crate::Error;
#[derive(Debug)]
pub struct BitStream<'a> {
data: &'a [u8],
bit_offset: usize,
}
impl<'a> BitStream<'a> {
pub const fn new(data: &'a [u8]) -> Self {
Self {
data,
bit_offset: 0,
}
}
pub fn read_bits(&mut self, count: usize) -> Result<u32, Error> {
let mut value = 0u32;
for _ in 0..count {
value = (value << 1) | u32::from(self.read_bit()?);
}
Ok(value)
}
fn read_bit(&mut self) -> Result<u8, Error> {
let byte_index = self.bit_offset / 8;
let bit_index = self.bit_offset % 8;
let byte = *self.data.get(byte_index).ok_or_else(Error::truncated)?;
let shift = 7usize
.checked_sub(bit_index)
.ok_or_else(Error::compression_error)?;
self.bit_offset = self
.bit_offset
.checked_add(1)
.ok_or_else(Error::compression_error)?;
Ok((byte >> shift) & 1)
}
}