1use std::cmp::min;
2
3use crate::encoding::fixed_int::FixedInt;
4
5pub struct BitStreamWriter<'a> {
6 buffer: &'a mut Vec<u8>,
7 bit_pos: usize,
8}
9
10impl<'a> BitStreamWriter<'a> {
11 pub fn new(buffer: &'a mut Vec<u8>) -> Self {
13 Self { buffer, bit_pos: 0 }
14 }
15
16 pub fn byte_pos(&self) -> usize {
18 self.bit_pos / 8
19 }
20
21 pub fn write_bit(&mut self, val: bool) {
23 self.write_small(val as u8, 1);
24 }
25
26 pub fn write_small(&mut self, mut val: u8, mut bits: u8) {
28 assert!(bits > 0 && bits < 8);
29
30 while bits > 0 {
31 self.ensure_byte();
32
33 let bit_offset = self.bit_pos % 8;
35
36 let bits_in_current_byte = min(8 - bit_offset as u8, bits);
38
39 let mask = ((1 << bits_in_current_byte) - 1) << bit_offset;
43
44 let shifted_val = (val & ((1 << bits_in_current_byte) - 1)) << bit_offset;
51
52 let byte_pos = self.byte_pos();
53
54 self.buffer[byte_pos] &= !mask;
56
57 self.buffer[byte_pos] |= shifted_val & mask;
59
60 bits -= bits_in_current_byte;
62
63 val >>= bits_in_current_byte;
65
66 self.bit_pos += bits_in_current_byte as usize;
67 }
68 }
69
70 pub fn write_byte(&mut self, byte: u8) {
72 self.align_byte();
73 self.ensure_byte();
74
75 let byte_pos = self.byte_pos();
76 self.buffer[byte_pos] = byte;
77 self.bit_pos += 8;
78 }
79
80 pub fn write_bytes(&mut self, data: &[u8]) {
82 self.align_byte();
83 self.buffer.extend_from_slice(data);
84 self.bit_pos += 8 * data.len();
85 }
86
87 pub fn write_dyn_int(&mut self, mut val: u128) {
90 while val > 0 {
91 let mut encoded = val % 128;
92 val /= 128;
93 if val > 0 {
94 encoded |= 128;
95 }
96 self.write_byte(encoded as u8);
97 }
98 }
99
100 pub fn write_fixed_int<const S: usize, T: FixedInt<S>>(&mut self, val: T) {
102 self.write_bytes(&val.serialize());
103 }
104
105 fn ensure_byte(&mut self) {
107 let byte_pos = self.byte_pos();
108 if byte_pos >= self.buffer.len() {
109 self.buffer.resize(byte_pos + 1, 0);
110 }
111 }
112
113 pub fn align_byte(&mut self) {
115 let rem = self.bit_pos % 8;
116 if rem != 0 {
117 self.bit_pos += 8 - rem;
118 }
119 }
120
121 pub fn reset(&mut self) {
123 self.bit_pos = 0;
124 }
125
126 pub fn len(&self) -> usize {
128 self.buffer.len()
129 }
130}
131
132#[cfg(test)]
133mod tests {
134 use super::BitStreamWriter;
135
136 fn buffer_to_bin(buffer: &[u8]) -> Vec<String> {
138 buffer.iter().map(|b| format!("{:08b}", b)).collect()
139 }
140
141 #[test]
142 fn test_write_bit() {
143 let mut buf = Vec::new();
144 let mut stream = BitStreamWriter::new(&mut buf);
145
146 stream.write_bit(true);
147 stream.write_bit(false);
148 stream.write_bit(true);
149 stream.write_bit(true); assert_eq!(buf.len(), 1);
152 assert_eq!(buf[0], 0b00001101); }
154
155 #[test]
156 fn test_write_small() {
157 let mut buf = Vec::new();
158 let mut stream = BitStreamWriter::new(&mut buf);
159
160 stream.write_small(0b101, 3); stream.write_small(0b11, 2); stream.write_small(0b111, 3); assert_eq!(buf.len(), 1);
165 assert_eq!(buf[0], 0b11111101); }
167
168 #[test]
169 fn test_write_cross_byte() {
170 let mut buf = Vec::new();
171 let mut stream = BitStreamWriter::new(&mut buf);
172
173 stream.write_small(0b00101011, 7);
175 stream.write_small(0b1101, 4);
176
177 assert_eq!(buf.len(), 2);
178 assert_eq!(buf[0], 0b10101011);
179 assert_eq!(buf[1], 0b00000110);
180 }
181
182 #[test]
183 fn test_write_byte() {
184 let mut buf = Vec::new();
185 let mut stream = BitStreamWriter::new(&mut buf);
186
187 stream.write_bit(true); stream.write_byte(0xAA); assert_eq!(buf.len(), 2);
191 assert_eq!(buf[0], 0b00000001); assert_eq!(buf[1], 0xAA); }
194
195 #[test]
196 fn test_write_bytes() {
197 let mut buf = Vec::new();
198 let mut stream = BitStreamWriter::new(&mut buf);
199
200 stream.write_bit(true); stream.write_bytes(&[0xAA, 0xBB, 0xCC]); assert_eq!(buf.len(), 4);
204 assert_eq!(buf[0], 0b00000001); assert_eq!(buf[1], 0xAA);
206 assert_eq!(buf[2], 0xBB);
207 assert_eq!(buf[3], 0xCC);
208 }
209
210 #[test]
211 fn test_alignment() {
212 let mut buf = Vec::new();
213 let mut stream = BitStreamWriter::new(&mut buf);
214
215 stream.write_small(0b11, 2); stream.align_byte();
217 stream.write_byte(0xFF);
218
219 assert_eq!(buf.len(), 2);
220 assert_eq!(buf[0], 0b00000011); assert_eq!(buf[1], 0xFF);
222 }
223
224 #[test]
225 fn test_multiple_operations() {
226 let mut buf = Vec::new();
227 let mut stream = BitStreamWriter::new(&mut buf);
228
229 stream.write_bit(true);
230 stream.write_small(0b101, 3);
231 stream.write_byte(0xAA);
232 stream.write_bytes(&[0xBB, 0xCC]);
233 stream.write_small(0b11, 2);
234
235 let bin = buffer_to_bin(&buf);
236 println!("{:?}", bin);
237
238 assert_eq!(buf.len(), 5);
239 assert_eq!(buf[0], 0b00001011); assert_eq!(buf[1], 0xAA); assert_eq!(buf[2], 0xBB);
242 assert_eq!(buf[3], 0xCC);
243 assert_eq!(buf[4], 0b00000011); }
245
246 #[test]
247 fn test_write_dyn_int() {
248 let mut buf = Vec::new();
249 let mut stream = BitStreamWriter::new(&mut buf);
250
251 stream.write_dyn_int(127);
252 assert_eq!(1, stream.len());
253
254 stream.write_dyn_int(128); assert_eq!(3, stream.len());
256
257 stream.write_dyn_int(268435455); assert_eq!(7, stream.len());
259
260 assert_eq!(vec![127, 128, 1, 255, 255, 255, 127], buf);
261 }
262
263 #[test]
264 fn test_write_fixed_int() {
265 let mut buf = Vec::new();
266 let mut stream = BitStreamWriter::new(&mut buf);
267
268 stream.write_fixed_int(1u8);
269 stream.write_fixed_int(1i8);
270 stream.write_fixed_int(2u16);
271 stream.write_fixed_int(2i16);
272 stream.write_fixed_int(3u32);
273 stream.write_fixed_int(3i32);
274 stream.write_fixed_int(4u64);
275 stream.write_fixed_int(4i64);
276 stream.write_fixed_int(5u128);
277 stream.write_fixed_int(5i128);
278
279 assert_eq!(
280 vec![
281 1, 2, 0, 2, 0, 4, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0,
282 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
283 0, 0, 0, 0, 0, 10
284 ],
285 buf
286 );
287 }
288}