e57/
bs_read.rs

1#[derive(Clone)]
2pub struct ByteStreamReadBuffer {
3    buffer: Vec<u8>,
4    tmp: Vec<u8>,
5    offset: usize,
6}
7
8impl ByteStreamReadBuffer {
9    pub fn new() -> Self {
10        Self {
11            buffer: Vec::new(),
12            tmp: Vec::new(),
13            offset: 0,
14        }
15    }
16
17    /// Append a fresh slice of bytes to the end of the stream
18    pub fn append(&mut self, data: &[u8]) {
19        let consumed_bytes = self.offset / 8;
20        let remaining_bytes = self.buffer.len() - consumed_bytes;
21        self.offset -= consumed_bytes * 8;
22        self.tmp.reserve(remaining_bytes + data.len());
23        self.tmp.extend_from_slice(&self.buffer[consumed_bytes..]);
24        self.tmp.extend_from_slice(data);
25        self.buffer.clear();
26        std::mem::swap(&mut self.buffer, &mut self.tmp);
27    }
28
29    /// Extract 64 bits or less from the byte stream and return them as u64.
30    /// The returned u64 might contain more than the requested number of bits.
31    /// Please make sure to ignore/mask the additional bits!
32    /// Returns None if the request cannot be satisfied.
33    pub fn extract(&mut self, bits: usize) -> Option<u64> {
34        if self.available() < bits {
35            return None;
36        }
37
38        let start_offset = self.offset / 8;
39        let end_offset = (self.offset + bits).div_ceil(8); // Integer division with rounding up
40        let offset = self.offset % 8;
41
42        let mut data = [0; 16];
43        let data_len = end_offset - start_offset;
44        let dst = &mut data[..data_len];
45        let src = &self.buffer[start_offset..end_offset];
46        dst.copy_from_slice(src);
47
48        self.offset += bits;
49        let data = u128::from_le_bytes(data) >> offset;
50        Some(data as u64)
51    }
52
53    /// Returns the number of available bits in the stream
54    pub fn available(&self) -> usize {
55        (self.buffer.len() * 8) - self.offset
56    }
57}
58
59#[cfg(test)]
60mod tests {
61    use super::*;
62
63    #[test]
64    fn empty() {
65        let mut bs = ByteStreamReadBuffer::new();
66        assert_eq!(bs.available(), 0);
67        let result = bs.extract(0).unwrap();
68        assert_eq!(result, 0);
69        assert_eq!(bs.available(), 0);
70        assert!(bs.extract(1).is_none());
71    }
72
73    #[test]
74    fn append_and_extract_bits() {
75        let mut bs = ByteStreamReadBuffer::new();
76        bs.append(&[255]);
77
78        assert_eq!(bs.available(), 8);
79        let result = bs.extract(2).unwrap();
80        assert_eq!(result, 255);
81
82        assert_eq!(bs.available(), 6);
83        let result = bs.extract(6).unwrap();
84        assert_eq!(result, 63);
85
86        assert_eq!(bs.available(), 0);
87        assert!(bs.extract(1).is_none());
88    }
89
90    #[test]
91    fn append_and_extract_bytes() {
92        let mut bs = ByteStreamReadBuffer::new();
93        bs.append(&[23, 42, 13]);
94        bs.extract(2).unwrap();
95
96        assert_eq!(bs.available(), 22);
97        let result = bs.extract(22).unwrap();
98        assert_eq!(result, 215685);
99    }
100
101    #[test]
102    fn remove_consume_when_appending() {
103        let mut bs = ByteStreamReadBuffer::new();
104        bs.append(&[1, 2, 3, 4, 5]);
105        bs.extract(4 * 8 + 2).unwrap();
106
107        // We append one byte and the buffer should become smaller
108        // because all fully consumed bytes are removed.
109        bs.append(&[6]);
110        assert!(bs.buffer.len() == 2);
111
112        // Offsets are updated correctly appended
113        // data can be extracted as expected.
114        let result = bs.extract(14).unwrap();
115        assert_eq!(result, 385);
116    }
117}