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 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 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); 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 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 bs.append(&[6]);
110 assert!(bs.buffer.len() == 2);
111
112 let result = bs.extract(14).unwrap();
115 assert_eq!(result, 385);
116 }
117}