lc3_codec/encoder/
buffer_writer.rs

1#[allow(unused_imports)]
2use num_traits::real::Real;
3
4#[derive(Default)]
5pub struct BufferWriter {
6    pub bp: usize,
7    bp_side: u16,
8    mask_side: u8,
9}
10
11impl BufferWriter {
12    pub fn new(buf_len: usize) -> Self {
13        Self {
14            bp: 0,
15            bp_side: buf_len as u16 - 1,
16            mask_side: 1,
17        }
18    }
19    pub fn write_uint_backward(&mut self, buf: &mut [u8], mut val: usize, num_bits: usize) {
20        for _ in 0..num_bits {
21            let bit = (val as u16 & 1) as u8;
22            self.write_bool_backward(buf, bit != 0);
23            val >>= 1;
24        }
25    }
26
27    pub fn write_bool_backward(&mut self, buf: &mut [u8], bit: bool) {
28        if !bit {
29            buf[self.bp_side as usize] &= !self.mask_side;
30        } else {
31            buf[self.bp_side as usize] |= self.mask_side;
32        }
33
34        if self.mask_side == 0x80 {
35            self.mask_side = 1;
36            self.bp_side -= 1
37        } else {
38            self.mask_side <<= 1;
39        }
40    }
41
42    pub fn write_uint_forward(&mut self, buf: &mut [u8], val: u16, num_bits: usize) {
43        let mut mask: u8 = 0x80;
44        for _ in 0..num_bits {
45            let bit = val as u8 & mask; // TODO: check this!!!
46            if bit == 0 {
47                buf[self.bp] &= !mask;
48            } else {
49                buf[self.bp] |= mask;
50            }
51            mask >>= 1;
52        }
53    }
54
55    pub fn write_byte_forward(&mut self, buf: &mut [u8], val: u8) {
56        buf[self.bp] = val;
57        self.bp += 1;
58    }
59
60    pub fn nbits_side_written(&self, nbits: usize) -> usize {
61        let value = nbits as i32 - (8 * self.bp_side as i32 + 8 - (self.mask_side as f64).log2() as i32);
62        if value < 0 {
63            panic!("nbits_side_written is negative: {}", value);
64        }
65        value as usize
66    }
67}
68
69#[cfg(test)]
70mod tests {
71    extern crate std;
72    use super::*;
73
74    #[test]
75    fn buffer_writer_forward_and_backwards() {
76        let mut writer = BufferWriter::new(10);
77        let mut buf = [0; 10];
78
79        writer.write_bool_backward(&mut buf, true);
80        writer.write_byte_forward(&mut buf, 123);
81        writer.write_uint_backward(&mut buf, 22, 6);
82        writer.write_bool_backward(&mut buf, false);
83        // TODO: this implementation looks wrong, fix it!!
84        // writer.write_uint_forward(&mut buf, 2, 4);
85
86        assert_eq!(buf, [123, 0, 0, 0, 0, 0, 0, 0, 0, 45]);
87    }
88
89    #[test]
90    fn nbits_written_calc() {
91        let mut writer = BufferWriter::new(150);
92        writer.bp_side = 140;
93        writer.mask_side = 4;
94
95        let nbits_side_written = writer.nbits_side_written(1200);
96
97        assert_eq!(nbits_side_written, 74);
98    }
99}