pub struct BitWriter {
buffer: Vec<u8>,
current: u8,
bits_used: u8,
}
impl Default for BitWriter {
fn default() -> Self {
Self::new()
}
}
impl BitWriter {
#[must_use]
pub const fn new() -> Self {
Self {
buffer: Vec::new(),
current: 0,
bits_used: 0,
}
}
pub fn write_bits(&mut self, code: u64, length: u8) {
for i in (0..length).rev() {
let bit = ((code >> i) & 1) as u8;
self.current = (self.current << 1) | bit;
self.bits_used += 1;
if self.bits_used == 8 {
self.buffer.push(self.current);
self.current = 0;
self.bits_used = 0;
}
}
}
#[must_use]
pub fn finish(mut self) -> Vec<u8> {
if self.bits_used > 0 {
self.current <<= 8 - self.bits_used;
self.buffer.push(self.current);
}
self.buffer
}
#[must_use]
pub const fn padding_bits(&self) -> u8 {
if self.bits_used == 0 {
0
} else {
8 - self.bits_used
}
}
}
pub struct BitReader<'a> {
data: &'a [u8],
byte_pos: usize,
bit_pos: u8,
padding: u8,
}
impl<'a> BitReader<'a> {
#[must_use]
pub const fn new(data: &'a [u8], padding: u8) -> Self {
Self {
data,
byte_pos: 0,
bit_pos: 0,
padding,
}
}
pub fn read_bit(&mut self) -> Option<u8> {
let is_last_byte = self.byte_pos == self.data.len() - 1;
if is_last_byte && self.bit_pos >= (8 - self.padding) {
return None;
}
if self.byte_pos >= self.data.len() {
return None;
}
let bit = (self.data[self.byte_pos] >> (7 - self.bit_pos)) & 1;
self.bit_pos += 1;
if self.bit_pos == 8 {
self.bit_pos = 0;
self.byte_pos += 1;
}
Some(bit)
}
}