use crate::{Result, error::invalid};
pub(super) struct BitReader<'a> {
input: &'a [u8],
bit: usize,
}
impl<'a> BitReader<'a> {
pub(super) const fn new(input: &'a [u8]) -> Self {
Self { input, bit: 0 }
}
pub(super) fn read(&mut self, count: u8) -> Result<u32> {
let value = self.peek(count)?;
self.bit += usize::from(count);
Ok(value)
}
pub(super) fn peek(&self, count: u8) -> Result<u32> {
if count > 24 || self.bit + usize::from(count) > self.input.len() * 8 {
return Err(invalid("truncated DEFLATE bit stream"));
}
let mut value = 0_u32;
for offset in 0..usize::from(count) {
let position = self.bit + offset;
let bit = (self.input[position / 8] >> (position % 8)) & 1;
value |= u32::from(bit) << offset;
}
Ok(value)
}
pub(super) fn consume(&mut self, count: u8) -> Result<()> {
self.read(count).map(|_| ())
}
pub(super) fn align_byte(&mut self) {
self.bit = self.bit.div_ceil(8) * 8;
}
pub(super) const fn byte_position(&self) -> usize {
self.bit.div_ceil(8)
}
}