1use crate::types::{Int8u, Int16u, Int32u, Int64u};
10
11const MASK: [u32; 33] = [
12 0x0000_0000,
13 0x0000_0001,
14 0x0000_0003,
15 0x0000_0007,
16 0x0000_000f,
17 0x0000_001f,
18 0x0000_003f,
19 0x0000_007f,
20 0x0000_00ff,
21 0x0000_01ff,
22 0x0000_03ff,
23 0x0000_07ff,
24 0x0000_0fff,
25 0x0000_1fff,
26 0x0000_3fff,
27 0x0000_7fff,
28 0x0000_ffff,
29 0x0001_ffff,
30 0x0003_ffff,
31 0x0007_ffff,
32 0x000f_ffff,
33 0x001f_ffff,
34 0x003f_ffff,
35 0x007f_ffff,
36 0x00ff_ffff,
37 0x01ff_ffff,
38 0x03ff_ffff,
39 0x07ff_ffff,
40 0x0fff_ffff,
41 0x1fff_ffff,
42 0x3fff_ffff,
43 0x7fff_ffff,
44 0xffff_ffff,
45];
46
47#[derive(Clone, Copy)]
48struct Snapshot {
49 pos: usize,
50 buffer_size: usize,
51 last_byte: usize,
52 last_byte_size: usize,
53 buffer_under_run: bool,
54}
55
56pub struct BitStream<'a> {
57 buffer: &'a [u8],
58 pos: usize,
59 buffer_size: usize,
60 buffer_size_init: usize,
61 buffer_size_before_last_call: usize,
62 last_byte: usize,
63 last_byte_size: usize,
64 buffer_under_run: bool,
65 bookmark: Option<Snapshot>,
66}
67
68impl<'a> BitStream<'a> {
69 pub fn new(buffer: &'a [u8]) -> Self {
70 let bits = buffer.len() * 8;
71 BitStream {
72 buffer,
73 pos: 0,
74 buffer_size: bits,
75 buffer_size_init: bits,
76 buffer_size_before_last_call: bits,
77 last_byte: 0,
78 last_byte_size: 0,
79 buffer_under_run: buffer.is_empty(),
80 bookmark: None,
81 }
82 }
83
84 pub fn attach(&mut self, buffer: &'a [u8]) {
85 if std::ptr::eq(buffer.as_ptr(), self.buffer.as_ptr()) && buffer.len() == self.buffer.len()
86 {
87 return;
88 }
89 let bits = buffer.len() * 8;
90 self.buffer = buffer;
91 self.pos = 0;
92 self.buffer_size = bits;
93 self.buffer_size_init = bits;
94 self.buffer_size_before_last_call = bits;
95 self.last_byte_size = 0;
96 self.buffer_under_run = buffer.is_empty();
97 self.bookmark = None;
98 }
99
100 pub fn get(&mut self, how_many: usize) -> Int32u {
101 let to_return: usize;
102 if how_many == 0 || how_many > 32 {
103 return 0;
104 }
105 if how_many > self.buffer_size + self.last_byte_size {
106 self.buffer_size = 0;
107 self.last_byte_size = 0;
108 self.buffer_under_run = true;
109 return 0;
110 }
111
112 self.buffer_size_before_last_call = self.buffer_size + self.last_byte_size;
113
114 if how_many <= self.last_byte_size {
115 self.last_byte_size -= how_many;
116 to_return = self.last_byte >> self.last_byte_size;
117 } else {
118 let mut new_bits = how_many - self.last_byte_size;
119 let mut acc: usize = if new_bits == 32 { 0 } else { self.last_byte << new_bits };
120 let mut tier = (new_bits - 1) / 8;
123 while tier >= 1 {
124 new_bits -= 8;
125 acc |= (self.buffer[self.pos] as usize) << new_bits;
126 self.pos += 1;
127 self.buffer_size -= 8;
128 tier -= 1;
129 }
130 self.last_byte = self.buffer[self.pos] as usize;
132 self.pos += 1;
133 self.last_byte_size = self.buffer_size.min(8) - new_bits;
134 self.buffer_size -= self.buffer_size.min(8);
135 acc |= (self.last_byte >> self.last_byte_size) & MASK[new_bits] as usize;
136 to_return = acc;
137 }
138 (to_return as u32) & MASK[how_many]
139 }
140
141 pub fn getb(&mut self) -> bool {
142 self.get(1) != 0
143 }
144
145 pub fn get1(&mut self, how_many: usize) -> Int8u {
146 self.get(how_many) as Int8u
147 }
148
149 pub fn get2(&mut self, how_many: usize) -> Int16u {
150 self.get(how_many) as Int16u
151 }
152
153 pub fn get4(&mut self, how_many: usize) -> Int32u {
154 self.get(how_many)
155 }
156
157 pub fn get8(&mut self, how_many: usize) -> Int64u {
158 if how_many > 64 {
159 return 0;
160 }
161 let how_many1 = how_many.saturating_sub(32);
162 let how_many2 = how_many - how_many1;
163 let value1 = self.get(how_many1) as Int64u;
164 let value2 = self.get(how_many2) as Int64u;
165 if self.buffer_under_run {
166 return 0;
167 }
168 value1 * 0x1_0000_0000 + value2
169 }
170
171 pub fn skip(&mut self, mut how_many: usize) {
172 if how_many == 0 {
173 return;
174 }
175 if how_many > 32 {
176 while how_many > 32 {
177 self.skip(32);
178 how_many -= 32;
179 }
180 if how_many > 0 {
181 self.skip(how_many);
182 }
183 return;
184 }
185 if how_many > self.buffer_size + self.last_byte_size {
186 self.buffer_size = 0;
187 self.last_byte_size = 0;
188 self.buffer_under_run = true;
189 return;
190 }
191 self.buffer_size_before_last_call = self.buffer_size + self.last_byte_size;
192
193 if how_many <= self.last_byte_size {
194 self.last_byte_size -= how_many;
195 } else {
196 let mut new_bits = how_many - self.last_byte_size;
197 let mut tier = (new_bits - 1) / 8;
198 while tier >= 1 {
199 new_bits -= 8;
200 self.pos += 1;
201 self.buffer_size -= 8;
202 tier -= 1;
203 }
204 self.last_byte = self.buffer[self.pos] as usize;
205 self.pos += 1;
206 self.last_byte_size = self.buffer_size.min(8) - new_bits;
207 self.buffer_size -= self.buffer_size.min(8);
208 }
209 }
210
211 pub fn skipb(&mut self) {
212 self.skip(1)
213 }
214 pub fn skip1(&mut self, how_many: usize) {
215 self.skip(how_many)
216 }
217 pub fn skip2(&mut self, how_many: usize) {
218 self.skip(how_many)
219 }
220 pub fn skip4(&mut self, how_many: usize) {
221 self.skip(how_many)
222 }
223
224 pub fn skip8(&mut self, how_many: usize) {
225 if how_many > 64 {
226 return;
227 }
228 let how_many1 = how_many.saturating_sub(32);
229 let how_many2 = how_many - how_many1;
230 self.skip(how_many1);
231 self.skip(how_many2);
232 }
233
234 pub fn peek(&mut self, how_many: usize) -> Int32u {
235 self.bookmark_pos(true);
236 let v = self.get(how_many);
237 self.bookmark_pos(false);
238 v
239 }
240
241 pub fn peekb(&mut self) -> bool {
242 self.peek(1) != 0
243 }
244 pub fn peek1(&mut self, how_many: usize) -> Int8u {
245 self.peek(how_many) as Int8u
246 }
247 pub fn peek2(&mut self, how_many: usize) -> Int16u {
248 self.peek(how_many) as Int16u
249 }
250 pub fn peek3(&mut self, how_many: usize) -> Int32u {
251 self.peek(how_many)
252 }
253 pub fn peek4(&mut self, how_many: usize) -> Int32u {
254 self.peek(how_many)
255 }
256 pub fn peek8(&mut self, how_many: usize) -> Int64u {
257 self.peek(how_many) as Int64u
258 }
259
260 pub fn bookmark_pos(&mut self, set: bool) {
261 if set {
262 self.bookmark = Some(Snapshot {
263 pos: self.pos,
264 buffer_size: self.buffer_size,
265 last_byte: self.last_byte,
266 last_byte_size: self.last_byte_size,
267 buffer_under_run: self.buffer_under_run,
268 });
269 } else if let Some(s) = self.bookmark.take() {
270 self.pos = s.pos;
271 self.buffer_size = s.buffer_size;
272 self.last_byte = s.last_byte;
273 self.last_byte_size = s.last_byte_size;
274 self.buffer_under_run = s.buffer_under_run;
275 }
276 }
277
278 pub fn remain(&self) -> Int32u {
279 (self.buffer_size + self.last_byte_size) as Int32u
280 }
281
282 pub fn byte_align(&mut self) {
283 self.get(self.last_byte_size);
284 }
285
286 pub fn offset_get(&self) -> usize {
287 if self.buffer_under_run {
288 return 0;
289 }
290 (self.buffer_size_init - self.buffer_size) / 8
291 }
292
293 pub fn bit_offset_get(&self) -> usize {
294 if self.buffer_under_run {
295 return 0;
296 }
297 self.last_byte_size
298 }
299
300 pub fn offset_before_last_call_get(&self) -> usize {
301 if self.buffer_under_run {
302 return 0;
303 }
304 (self.buffer_size_init - self.buffer_size_before_last_call) / 8
305 }
306
307 pub fn buffer_under_run(&self) -> bool {
308 self.buffer_under_run
309 }
310}
311
312#[cfg(test)]
313mod tests {
314 use super::*;
315
316 #[test]
317 fn read_single_bits_msb_first() {
318 let mut bs = BitStream::new(&[0xAC]);
320 assert!(bs.getb());
321 assert!(!bs.getb());
322 assert!(bs.getb());
323 assert!(!bs.getb());
324 assert!(bs.getb());
325 assert!(bs.getb());
326 assert!(!bs.getb());
327 assert!(!bs.getb());
328 }
329
330 #[test]
331 fn read_nibbles_across_bytes() {
332 let mut bs = BitStream::new(&[0xAB, 0xCD, 0xEF]);
333 assert_eq!(bs.get(4), 0xA);
334 assert_eq!(bs.get(4), 0xB);
335 assert_eq!(bs.get(4), 0xC);
336 assert_eq!(bs.get(4), 0xD);
337 assert_eq!(bs.get(4), 0xE);
338 assert_eq!(bs.get(4), 0xF);
339 assert!(!bs.buffer_under_run());
340 }
341
342 #[test]
343 fn read_32_bits_aligned() {
344 let mut bs = BitStream::new(&[0xDE, 0xAD, 0xBE, 0xEF]);
345 assert_eq!(bs.get(32), 0xDEAD_BEEF);
346 }
347
348 #[test]
349 fn read_64_bits_via_get8() {
350 let mut bs = BitStream::new(&[0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE, 0xBA, 0xBE]);
351 assert_eq!(bs.get8(64), 0xDEAD_BEEF_CAFE_BABE);
352 }
353
354 #[test]
355 fn read_unaligned_3_bits_then_5() {
356 let mut bs = BitStream::new(&[0xDA]);
358 assert_eq!(bs.get(3), 6);
359 assert_eq!(bs.get(5), 26);
360 }
361
362 #[test]
363 fn underrun_zeros_result_and_flags() {
364 let mut bs = BitStream::new(&[0xFF]);
365 assert_eq!(bs.get(16), 0);
366 assert!(bs.buffer_under_run());
367 assert_eq!(bs.remain(), 0);
368 }
369
370 #[test]
371 fn peek_does_not_advance() {
372 let mut bs = BitStream::new(&[0xAB, 0xCD]);
373 assert_eq!(bs.peek(8), 0xAB);
374 assert_eq!(bs.peek(8), 0xAB);
375 assert_eq!(bs.get(8), 0xAB);
376 assert_eq!(bs.get(8), 0xCD);
377 }
378
379 #[test]
380 fn skip_then_read() {
381 let mut bs = BitStream::new(&[0xAB, 0xCD, 0xEF]);
382 bs.skip(12);
383 assert_eq!(bs.get(12), 0xDEF);
384 }
385
386 #[test]
387 fn skip_more_than_32() {
388 let mut bs = BitStream::new(&[0; 8]);
389 bs.skip(40);
390 assert_eq!(bs.remain(), 24);
391 }
392
393 #[test]
394 fn byte_align_consumes_partial_byte() {
395 let mut bs = BitStream::new(&[0xAB, 0xCD]);
396 assert_eq!(bs.get(3), 0b101);
397 assert_eq!(bs.bit_offset_get(), 5);
398 bs.byte_align();
399 assert_eq!(bs.bit_offset_get(), 0);
400 assert_eq!(bs.get(8), 0xCD);
401 }
402
403 #[test]
404 fn offset_tracking() {
405 let mut bs = BitStream::new(&[0x00, 0x00, 0x00, 0x00]);
406 assert_eq!(bs.offset_get(), 0);
407 bs.get(16);
408 assert_eq!(bs.offset_get(), 2);
409 }
410}