pub struct ForwardBitWriter {
output: Vec<u8>,
current_byte: u8,
bits_in_current: u8,
}
impl ForwardBitWriter {
pub fn new() -> Self {
Self {
output: Vec::new(),
current_byte: 0,
bits_in_current: 0,
}
}
pub fn with_capacity(byte_capacity: usize) -> Self {
Self {
output: Vec::with_capacity(byte_capacity),
current_byte: 0,
bits_in_current: 0,
}
}
pub fn write_bits(&mut self, value: u32, num_bits: u8) {
debug_assert!(
num_bits <= 25,
"ForwardBitWriter supports up to 25 bits per call"
);
if num_bits == 0 {
return;
}
let mask = if num_bits >= 32 {
u32::MAX
} else {
(1u32 << num_bits) - 1
};
let masked_value = value & mask;
let mut remaining_bits = num_bits;
let mut bits_to_write = masked_value;
while remaining_bits > 0 {
let space_in_current = 8 - self.bits_in_current;
let take = remaining_bits.min(space_in_current);
let take_mask = if take >= 32 {
u32::MAX
} else {
(1u32 << take) - 1
};
let chunk = (bits_to_write & take_mask) as u8;
self.current_byte |= chunk << self.bits_in_current;
self.bits_in_current += take;
bits_to_write >>= take;
remaining_bits -= take;
if self.bits_in_current == 8 {
self.output.push(self.current_byte);
self.current_byte = 0;
self.bits_in_current = 0;
}
}
}
pub fn write_bit(&mut self, bit: bool) {
self.write_bits(if bit { 1 } else { 0 }, 1);
}
pub fn finish(mut self) -> Vec<u8> {
if self.bits_in_current > 0 {
self.output.push(self.current_byte);
}
self.output
}
pub fn bit_position(&self) -> usize {
self.output.len() * 8 + self.bits_in_current as usize
}
pub fn byte_len(&self) -> usize {
self.output.len()
}
pub fn is_empty(&self) -> bool {
self.output.is_empty() && self.bits_in_current == 0
}
pub fn as_bytes(&self) -> &[u8] {
&self.output
}
}
impl Default for ForwardBitWriter {
fn default() -> Self {
Self::new()
}
}
pub struct BackwardBitWriter {
data_bits: Vec<u8>,
total_bits: usize,
}
impl BackwardBitWriter {
pub fn new() -> Self {
Self {
data_bits: Vec::new(),
total_bits: 0,
}
}
pub fn with_capacity(byte_capacity: usize) -> Self {
Self {
data_bits: Vec::with_capacity(byte_capacity * 8),
total_bits: 0,
}
}
pub fn write_bits(&mut self, value: u64, num_bits: u8) {
if num_bits == 0 {
return;
}
for i in 0..num_bits {
let bit = ((value >> i) & 1) as u8;
self.data_bits.push(bit);
}
self.total_bits += num_bits as usize;
}
pub fn write_bit(&mut self, bit: bool) {
self.data_bits.push(if bit { 1 } else { 0 });
self.total_bits += 1;
}
pub fn finish(self) -> Vec<u8> {
if self.data_bits.is_empty() {
return vec![0x01];
}
let n = self.data_bits.len();
let sentinel_data_bits = n % 8;
let full_bytes = n / 8;
let mut output = Vec::with_capacity(full_bytes + 1);
for byte_idx in 0..full_bytes {
let start = sentinel_data_bits + (full_bytes - 1 - byte_idx) * 8;
let mut byte_val = 0u8;
for bit in 0..8 {
if self.data_bits[start + bit] != 0 {
byte_val |= 1 << bit;
}
}
output.push(byte_val);
}
let mut sentinel_byte = 0u8;
for bit in 0..sentinel_data_bits {
if self.data_bits[bit] != 0 {
sentinel_byte |= 1 << bit;
}
}
sentinel_byte |= 1 << sentinel_data_bits; output.push(sentinel_byte);
output
}
pub fn len(&self) -> usize {
self.total_bits
}
pub fn is_empty(&self) -> bool {
self.total_bits == 0
}
}
impl Default for BackwardBitWriter {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_forward_empty() {
let writer = ForwardBitWriter::new();
assert!(writer.is_empty());
assert_eq!(writer.bit_position(), 0);
let output = writer.finish();
assert!(output.is_empty());
}
#[test]
fn test_forward_single_byte() {
let mut writer = ForwardBitWriter::new();
writer.write_bits(0xAB, 8);
assert_eq!(writer.bit_position(), 8);
let output = writer.finish();
assert_eq!(output, vec![0xAB]);
}
#[test]
fn test_forward_partial_byte() {
let mut writer = ForwardBitWriter::new();
writer.write_bits(5, 3);
assert_eq!(writer.bit_position(), 3);
let output = writer.finish();
assert_eq!(output, vec![0x05]);
}
#[test]
fn test_forward_multi_byte() {
let mut writer = ForwardBitWriter::new();
writer.write_bits(0xABC, 12);
let output = writer.finish();
assert_eq!(output, vec![0xBC, 0x0A]);
}
#[test]
fn test_forward_cross_byte_boundary() {
let mut writer = ForwardBitWriter::new();
writer.write_bits(0x07, 3); writer.write_bits(0x1F, 5); let output = writer.finish();
assert_eq!(output, vec![0xFF]);
}
#[test]
fn test_forward_multiple_writes() {
let mut writer = ForwardBitWriter::new();
writer.write_bits(1, 1); writer.write_bits(0, 1); writer.write_bits(1, 1); writer.write_bits(0, 1); writer.write_bits(1, 1); writer.write_bits(0, 1); writer.write_bits(1, 1); writer.write_bits(0, 1); let output = writer.finish();
assert_eq!(output, vec![0x55]);
}
#[test]
fn test_forward_write_bit() {
let mut writer = ForwardBitWriter::new();
for _ in 0..8 {
writer.write_bit(true);
}
let output = writer.finish();
assert_eq!(output, vec![0xFF]);
}
#[test]
fn test_forward_zero_bits() {
let mut writer = ForwardBitWriter::new();
writer.write_bits(0xFF, 0); assert!(writer.is_empty());
let output = writer.finish();
assert!(output.is_empty());
}
#[test]
fn test_forward_25_bits() {
let mut writer = ForwardBitWriter::new();
let val = (1u32 << 25) - 1; writer.write_bits(val, 25);
assert_eq!(writer.bit_position(), 25);
let output = writer.finish();
assert_eq!(output.len(), 4);
assert_eq!(output[0], 0xFF);
assert_eq!(output[1], 0xFF);
assert_eq!(output[2], 0xFF);
assert_eq!(output[3], 0x01); }
#[test]
fn test_backward_empty() {
let writer = BackwardBitWriter::new();
assert!(writer.is_empty());
assert_eq!(writer.len(), 0);
let output = writer.finish();
assert_eq!(output, vec![0x01]);
}
#[test]
fn test_backward_single_bit() {
let mut writer = BackwardBitWriter::new();
writer.write_bit(true);
let output = writer.finish();
assert_eq!(output, vec![0x03]);
}
#[test]
fn test_backward_single_byte_data() {
let mut writer = BackwardBitWriter::new();
writer.write_bits(0xAB, 8);
let output = writer.finish();
assert_eq!(output, vec![0xAB, 0x01]);
}
#[test]
fn test_backward_partial_bits() {
let mut writer = BackwardBitWriter::new();
writer.write_bits(22, 5);
let output = writer.finish();
assert_eq!(output, vec![0x36]);
}
#[test]
fn test_backward_multi_byte() {
let mut writer = BackwardBitWriter::new();
writer.write_bits(0xFF, 8);
writer.write_bits(0xAA, 8);
let output = writer.finish();
assert_eq!(output, vec![0xAA, 0xFF, 0x01]);
}
#[test]
fn test_backward_len() {
let mut writer = BackwardBitWriter::new();
writer.write_bits(0, 3);
assert_eq!(writer.len(), 3);
writer.write_bits(0, 10);
assert_eq!(writer.len(), 13);
}
#[test]
fn test_backward_zero_bits() {
let mut writer = BackwardBitWriter::new();
writer.write_bits(0xFF, 0); assert!(writer.is_empty());
}
#[test]
fn test_forward_with_capacity() {
let writer = ForwardBitWriter::with_capacity(128);
assert!(writer.is_empty());
let output = writer.finish();
assert!(output.is_empty());
}
#[test]
fn test_backward_with_capacity() {
let writer = BackwardBitWriter::with_capacity(128);
assert!(writer.is_empty());
}
}