1use common_traits::*;
10
11use crate::codes::params::{DefaultReadParams, ReadParams};
12use crate::traits::*;
13use core::convert::Infallible;
14use core::error::Error;
15use core::{mem, ptr};
16#[cfg(feature = "mem_dbg")]
17use mem_dbg::{MemDbg, MemSize};
18
19type BB<WR> = <<WR as WordRead>::Word as DoubleType>::DoubleType;
22
23#[derive(Debug)]
53#[cfg_attr(feature = "mem_dbg", derive(MemDbg, MemSize))]
54pub struct BufBitReader<E: Endianness, WR: WordRead, RP: ReadParams = DefaultReadParams>
55where
56 WR::Word: DoubleType,
57{
58 backend: WR,
60 buffer: BB<WR>,
64 bits_in_buffer: usize,
67 _marker: core::marker::PhantomData<(E, RP)>,
68}
69
70#[cfg(feature = "std")]
82pub fn from_path<E: Endianness, W: Word + DoubleType>(
83 path: impl AsRef<std::path::Path>,
84) -> anyhow::Result<
85 BufBitReader<E, super::WordAdapter<W, std::io::BufReader<std::fs::File>>, DefaultReadParams>,
86> {
87 Ok(from_file::<E, W>(std::fs::File::open(path)?))
88}
89
90#[cfg(feature = "std")]
96pub fn from_file<E: Endianness, W: Word + DoubleType>(
97 file: std::fs::File,
98) -> BufBitReader<E, super::WordAdapter<W, std::io::BufReader<std::fs::File>>, DefaultReadParams> {
99 BufBitReader::new(super::WordAdapter::new(std::io::BufReader::new(file)))
100}
101
102impl<E: Endianness, WR: WordRead + Clone, RP: ReadParams> core::clone::Clone
103 for BufBitReader<E, WR, RP>
104where
105 WR::Word: DoubleType,
106{
107 fn clone(&self) -> Self {
108 Self {
109 backend: self.backend.clone(),
110 buffer: self.buffer,
111 bits_in_buffer: self.bits_in_buffer,
112 _marker: core::marker::PhantomData,
113 }
114 }
115}
116
117impl<E: Endianness, WR: WordRead, RP: ReadParams> BufBitReader<E, WR, RP>
118where
119 WR::Word: DoubleType,
120{
121 #[must_use]
131 pub fn new(backend: WR) -> Self {
132 #[cfg(feature = "std")]
133 check_tables(WR::Word::BITS + 1);
134 Self {
135 backend,
136 buffer: BB::<WR>::ZERO,
137 bits_in_buffer: 0,
138 _marker: core::marker::PhantomData,
139 }
140 }
141
142 pub fn into_inner(self) -> Result<WR, Infallible> {
144 let backend = unsafe { ptr::read(&self.backend) };
146 mem::forget(self);
147 Ok(backend)
148 }
149}
150
151impl<WR: WordRead, RP: ReadParams> BufBitReader<BE, WR, RP>
156where
157 WR::Word: DoubleType,
158{
159 #[inline(always)]
163 fn refill(&mut self) -> Result<(), <WR as WordRead>::Error> {
164 debug_assert!(BB::<WR>::BITS - self.bits_in_buffer >= WR::Word::BITS);
165
166 let new_word: BB<WR> = self.backend.read_word()?.to_be().upcast();
167 self.bits_in_buffer += WR::Word::BITS;
168 self.buffer |= new_word << (BB::<WR>::BITS - self.bits_in_buffer);
169 Ok(())
170 }
171}
172
173impl<WR: WordRead, RP: ReadParams> BitRead<BE> for BufBitReader<BE, WR, RP>
174where
175 WR::Word: DoubleType + UpcastableInto<u64>,
176 BB<WR>: CastableInto<u64>,
177{
178 type Error = <WR as WordRead>::Error;
179 type PeekWord = BB<WR>;
180
181 #[inline(always)]
182 fn peek_bits(&mut self, n_bits: usize) -> Result<Self::PeekWord, Self::Error> {
183 debug_assert!(n_bits > 0);
184 debug_assert!(n_bits <= Self::PeekWord::BITS);
185
186 if n_bits > self.bits_in_buffer {
188 self.refill()?;
189 }
190
191 debug_assert!(n_bits <= self.bits_in_buffer);
192
193 Ok(self.buffer >> (BB::<WR>::BITS - n_bits))
195 }
196
197 #[inline(always)]
198 fn skip_bits_after_peek(&mut self, n_bits: usize) {
199 self.bits_in_buffer -= n_bits;
200 self.buffer <<= n_bits;
201 }
202
203 #[inline]
204 fn read_bits(&mut self, mut n_bits: usize) -> Result<u64, Self::Error> {
205 debug_assert!(n_bits <= 64);
206 debug_assert!(self.bits_in_buffer < BB::<WR>::BITS);
207
208 if n_bits <= self.bits_in_buffer {
210 let result: u64 = (self.buffer >> (BB::<WR>::BITS - n_bits - 1) >> 1_u32).cast();
212 self.bits_in_buffer -= n_bits;
213 self.buffer <<= n_bits;
214 return Ok(result);
215 }
216
217 let mut result: u64 =
218 (self.buffer >> (BB::<WR>::BITS - 1 - self.bits_in_buffer) >> 1_u8).cast();
219 n_bits -= self.bits_in_buffer;
220
221 while n_bits > WR::Word::BITS {
223 let new_word: u64 = self.backend.read_word()?.to_be().upcast();
224 result = (result << WR::Word::BITS) | new_word;
225 n_bits -= WR::Word::BITS;
226 }
227
228 debug_assert!(n_bits > 0);
229 debug_assert!(n_bits <= WR::Word::BITS);
230
231 let new_word = self.backend.read_word()?.to_be();
233 self.bits_in_buffer = WR::Word::BITS - n_bits;
234 let upcasted: u64 = new_word.upcast();
236 let final_bits: u64 = (upcasted >> self.bits_in_buffer).downcast();
237 result = (result << (n_bits - 1) << 1) | final_bits;
238 self.buffer = (UpcastableInto::<BB<WR>>::upcast(new_word)
240 << (BB::<WR>::BITS - self.bits_in_buffer - 1))
241 << 1;
242
243 Ok(result)
244 }
245
246 #[inline]
247 fn read_unary(&mut self) -> Result<u64, Self::Error> {
248 debug_assert!(self.bits_in_buffer < BB::<WR>::BITS);
249
250 let zeros: usize = self.buffer.leading_zeros() as _;
252
253 if zeros < self.bits_in_buffer {
255 self.buffer = self.buffer << zeros << 1;
256 self.bits_in_buffer -= zeros + 1;
257 return Ok(zeros as u64);
258 }
259
260 let mut result: u64 = self.bits_in_buffer as _;
261
262 loop {
263 let new_word = self.backend.read_word()?.to_be();
264
265 if new_word != WR::Word::ZERO {
266 let zeros: usize = new_word.leading_zeros() as _;
267 self.buffer =
268 UpcastableInto::<BB<WR>>::upcast(new_word) << (WR::Word::BITS + zeros) << 1;
269 self.bits_in_buffer = WR::Word::BITS - zeros - 1;
270 return Ok(result + zeros as u64);
271 }
272 result += WR::Word::BITS as u64;
273 }
274 }
275
276 #[inline]
277 fn skip_bits(&mut self, mut n_bits: usize) -> Result<(), Self::Error> {
278 debug_assert!(self.bits_in_buffer < BB::<WR>::BITS);
279 if n_bits <= self.bits_in_buffer {
281 self.bits_in_buffer -= n_bits;
282 self.buffer <<= n_bits;
283 return Ok(());
284 }
285
286 n_bits -= self.bits_in_buffer;
287
288 while n_bits > WR::Word::BITS {
290 let _ = self.backend.read_word()?;
291 n_bits -= WR::Word::BITS;
292 }
293
294 let new_word = self.backend.read_word()?.to_be();
296 self.bits_in_buffer = WR::Word::BITS - n_bits;
297
298 self.buffer = UpcastableInto::<BB<WR>>::upcast(new_word)
299 << (BB::<WR>::BITS - 1 - self.bits_in_buffer)
300 << 1;
301
302 Ok(())
303 }
304
305 #[cfg(not(feature = "no_copy_impls"))]
306 fn copy_to<F: Endianness, W: BitWrite<F>>(
307 &mut self,
308 bit_write: &mut W,
309 mut n: u64,
310 ) -> Result<(), CopyError<Self::Error, W::Error>> {
311 let from_buffer = Ord::min(n, self.bits_in_buffer as _);
312 self.buffer = self.buffer.rotate_left(from_buffer as _);
313
314 #[allow(unused_mut)]
315 let mut self_buffer_u64: u64 = self.buffer.cast();
316
317 #[cfg(feature = "checks")]
318 {
319 if n < 64 {
321 self_buffer_u64 &= (1_u64 << n) - 1;
322 }
323 }
324
325 bit_write
326 .write_bits(self_buffer_u64, from_buffer as usize)
327 .map_err(CopyError::WriteError)?;
328 n -= from_buffer;
329
330 if n == 0 {
331 self.bits_in_buffer -= from_buffer as usize;
332 return Ok(());
333 }
334
335 while n > WR::Word::BITS as u64 {
336 bit_write
337 .write_bits(
338 self.backend
339 .read_word()
340 .map_err(CopyError::ReadError)?
341 .to_be()
342 .upcast(),
343 WR::Word::BITS,
344 )
345 .map_err(CopyError::WriteError)?;
346 n -= WR::Word::BITS as u64;
347 }
348
349 assert!(n > 0);
350 let new_word = self
351 .backend
352 .read_word()
353 .map_err(CopyError::ReadError)?
354 .to_be();
355 self.bits_in_buffer = WR::Word::BITS - n as usize;
356 bit_write
357 .write_bits((new_word >> self.bits_in_buffer).upcast(), n as usize)
358 .map_err(CopyError::WriteError)?;
359 self.buffer = UpcastableInto::<BB<WR>>::upcast(new_word)
360 .rotate_right(WR::Word::BITS as u32 - n as u32);
361
362 Ok(())
363 }
364}
365
366impl<
367 E: Error + Send + Sync + 'static,
368 WR: WordRead<Error = E> + WordSeek<Error = E>,
369 RP: ReadParams,
370> BitSeek for BufBitReader<BE, WR, RP>
371where
372 WR::Word: DoubleType,
373{
374 type Error = <WR as WordSeek>::Error;
375
376 #[inline]
377 fn bit_pos(&mut self) -> Result<u64, Self::Error> {
378 Ok(self.backend.word_pos()? * WR::Word::BITS as u64 - self.bits_in_buffer as u64)
379 }
380
381 #[inline]
382 fn set_bit_pos(&mut self, bit_index: u64) -> Result<(), Self::Error> {
383 self.backend
384 .set_word_pos(bit_index / WR::Word::BITS as u64)?;
385 let bit_offset = (bit_index % WR::Word::BITS as u64) as usize;
386 self.buffer = BB::<WR>::ZERO;
387 self.bits_in_buffer = 0;
388 if bit_offset != 0 {
389 let new_word: BB<WR> = self.backend.read_word()?.to_be().upcast();
390 self.bits_in_buffer = WR::Word::BITS - bit_offset;
391 self.buffer = new_word << (BB::<WR>::BITS - self.bits_in_buffer);
392 }
393 Ok(())
394 }
395}
396
397impl<WR: WordRead, RP: ReadParams> BufBitReader<LE, WR, RP>
402where
403 WR::Word: DoubleType,
404{
405 #[inline(always)]
409 fn refill(&mut self) -> Result<(), <WR as WordRead>::Error> {
410 debug_assert!(BB::<WR>::BITS - self.bits_in_buffer >= WR::Word::BITS);
411
412 let new_word: BB<WR> = self.backend.read_word()?.to_le().upcast();
413 self.buffer |= new_word << self.bits_in_buffer;
414 self.bits_in_buffer += WR::Word::BITS;
415 Ok(())
416 }
417}
418
419impl<WR: WordRead, RP: ReadParams> BitRead<LE> for BufBitReader<LE, WR, RP>
420where
421 WR::Word: DoubleType + UpcastableInto<u64>,
422 BB<WR>: CastableInto<u64>,
423{
424 type Error = <WR as WordRead>::Error;
425 type PeekWord = BB<WR>;
426
427 #[inline(always)]
428 fn peek_bits(&mut self, n_bits: usize) -> Result<Self::PeekWord, Self::Error> {
429 debug_assert!(n_bits > 0);
430 debug_assert!(n_bits <= Self::PeekWord::BITS);
431
432 if n_bits > self.bits_in_buffer {
434 self.refill()?;
435 }
436
437 debug_assert!(n_bits <= self.bits_in_buffer);
438
439 let shamt = BB::<WR>::BITS - n_bits;
441 Ok((self.buffer << shamt) >> shamt)
442 }
443
444 #[inline(always)]
445 fn skip_bits_after_peek(&mut self, n_bits: usize) {
446 self.bits_in_buffer -= n_bits;
447 self.buffer >>= n_bits;
448 }
449
450 #[inline]
451 fn read_bits(&mut self, mut n_bits: usize) -> Result<u64, Self::Error> {
452 debug_assert!(n_bits <= 64);
453 debug_assert!(self.bits_in_buffer < BB::<WR>::BITS);
454
455 if n_bits <= self.bits_in_buffer {
457 let result: u64 = (self.buffer & ((BB::<WR>::ONE << n_bits) - BB::<WR>::ONE)).cast();
458 self.bits_in_buffer -= n_bits;
459 self.buffer >>= n_bits;
460 return Ok(result);
461 }
462
463 let mut result: u64 = self.buffer.cast();
464 let mut bits_in_res = self.bits_in_buffer;
465
466 while n_bits > WR::Word::BITS + bits_in_res {
468 let new_word: u64 = self.backend.read_word()?.to_le().upcast();
469 result |= new_word << bits_in_res;
470 bits_in_res += WR::Word::BITS;
471 }
472
473 n_bits -= bits_in_res;
474
475 debug_assert!(n_bits > 0);
476 debug_assert!(n_bits <= WR::Word::BITS);
477
478 let new_word = self.backend.read_word()?.to_le();
480 self.bits_in_buffer = WR::Word::BITS - n_bits;
481 let shamt = 64 - n_bits;
483 let upcasted: u64 = new_word.upcast();
484 let final_bits: u64 = ((upcasted << shamt) >> shamt).downcast();
485 result |= final_bits << bits_in_res;
486 self.buffer = UpcastableInto::<BB<WR>>::upcast(new_word) >> n_bits;
488
489 Ok(result)
490 }
491
492 #[inline]
493 fn read_unary(&mut self) -> Result<u64, Self::Error> {
494 debug_assert!(self.bits_in_buffer < BB::<WR>::BITS);
495
496 let zeros: usize = self.buffer.trailing_zeros() as usize;
498
499 if zeros < self.bits_in_buffer {
501 self.buffer = self.buffer >> zeros >> 1;
502 self.bits_in_buffer -= zeros + 1;
503 return Ok(zeros as u64);
504 }
505
506 let mut result: u64 = self.bits_in_buffer as _;
507
508 loop {
509 let new_word = self.backend.read_word()?.to_le();
510
511 if new_word != WR::Word::ZERO {
512 let zeros: usize = new_word.trailing_zeros() as _;
513 self.buffer = UpcastableInto::<BB<WR>>::upcast(new_word) >> zeros >> 1;
514 self.bits_in_buffer = WR::Word::BITS - zeros - 1;
515 return Ok(result + zeros as u64);
516 }
517 result += WR::Word::BITS as u64;
518 }
519 }
520
521 #[inline]
522 fn skip_bits(&mut self, mut n_bits: usize) -> Result<(), Self::Error> {
523 debug_assert!(self.bits_in_buffer < BB::<WR>::BITS);
524 if n_bits <= self.bits_in_buffer {
526 self.bits_in_buffer -= n_bits;
527 self.buffer >>= n_bits;
528 return Ok(());
529 }
530
531 n_bits -= self.bits_in_buffer;
532
533 while n_bits > WR::Word::BITS {
535 let _ = self.backend.read_word()?;
536 n_bits -= WR::Word::BITS;
537 }
538
539 let new_word = self.backend.read_word()?.to_le();
541 self.bits_in_buffer = WR::Word::BITS - n_bits;
542 self.buffer = UpcastableInto::<BB<WR>>::upcast(new_word) >> n_bits;
543
544 Ok(())
545 }
546
547 #[cfg(not(feature = "no_copy_impls"))]
548 fn copy_to<F: Endianness, W: BitWrite<F>>(
549 &mut self,
550 bit_write: &mut W,
551 mut n: u64,
552 ) -> Result<(), CopyError<Self::Error, W::Error>> {
553 let from_buffer = Ord::min(n, self.bits_in_buffer as _);
554
555 #[allow(unused_mut)]
556 let mut self_buffer_u64: u64 = self.buffer.cast();
557
558 #[cfg(feature = "checks")]
559 {
560 if n < 64 {
562 self_buffer_u64 &= (1_u64 << n) - 1;
563 }
564 }
565
566 bit_write
567 .write_bits(self_buffer_u64, from_buffer as usize)
568 .map_err(CopyError::WriteError)?;
569
570 self.buffer >>= from_buffer;
571 n -= from_buffer;
572
573 if n == 0 {
574 self.bits_in_buffer -= from_buffer as usize;
575 return Ok(());
576 }
577
578 while n > WR::Word::BITS as u64 {
579 bit_write
580 .write_bits(
581 self.backend
582 .read_word()
583 .map_err(CopyError::ReadError)?
584 .to_le()
585 .upcast(),
586 WR::Word::BITS,
587 )
588 .map_err(CopyError::WriteError)?;
589 n -= WR::Word::BITS as u64;
590 }
591
592 assert!(n > 0);
593 let new_word = self
594 .backend
595 .read_word()
596 .map_err(CopyError::ReadError)?
597 .to_le();
598 self.bits_in_buffer = WR::Word::BITS - n as usize;
599
600 #[allow(unused_mut)]
601 let mut new_word_u64: u64 = new_word.upcast();
602
603 #[cfg(feature = "checks")]
604 {
605 if n < 64 {
607 new_word_u64 &= (1_u64 << n) - 1;
608 }
609 }
610
611 bit_write
612 .write_bits(new_word_u64, n as usize)
613 .map_err(CopyError::WriteError)?;
614 self.buffer = UpcastableInto::<BB<WR>>::upcast(new_word) >> n;
615 Ok(())
616 }
617}
618
619impl<
620 E: Error + Send + Sync + 'static,
621 WR: WordRead<Error = E> + WordSeek<Error = E>,
622 RP: ReadParams,
623> BitSeek for BufBitReader<LE, WR, RP>
624where
625 WR::Word: DoubleType,
626{
627 type Error = <WR as WordSeek>::Error;
628
629 #[inline]
630 fn bit_pos(&mut self) -> Result<u64, Self::Error> {
631 Ok(self.backend.word_pos()? * WR::Word::BITS as u64 - self.bits_in_buffer as u64)
632 }
633
634 #[inline]
635 fn set_bit_pos(&mut self, bit_index: u64) -> Result<(), Self::Error> {
636 self.backend
637 .set_word_pos(bit_index / WR::Word::BITS as u64)?;
638
639 let bit_offset = (bit_index % WR::Word::BITS as u64) as usize;
640 self.buffer = BB::<WR>::ZERO;
641 self.bits_in_buffer = 0;
642 if bit_offset != 0 {
643 let new_word: BB<WR> = self.backend.read_word()?.to_le().upcast();
644 self.bits_in_buffer = WR::Word::BITS - bit_offset;
645 self.buffer = new_word >> bit_offset;
646 }
647 Ok(())
648 }
649}
650
651#[cfg(feature = "std")]
652impl<WR: WordRead, RP: ReadParams> std::io::Read for BufBitReader<LE, WR, RP>
653where
654 WR::Word: DoubleType + UpcastableInto<u64>,
655 BB<WR>: CastableInto<u64>,
656{
657 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
658 let mut iter = buf.chunks_exact_mut(8);
659
660 for chunk in &mut iter {
661 let word = self
662 .read_bits(64)
663 .map_err(|_| std::io::ErrorKind::UnexpectedEof)?;
664 chunk.copy_from_slice(&word.to_le_bytes());
665 }
666
667 let rem = iter.into_remainder();
668 if !rem.is_empty() {
669 let word = self
670 .read_bits(rem.len() * 8)
671 .map_err(|_| std::io::ErrorKind::UnexpectedEof)?;
672 rem.copy_from_slice(&word.to_le_bytes()[..rem.len()]);
673 }
674
675 Ok(buf.len())
676 }
677}
678
679#[cfg(feature = "std")]
680impl<WR: WordRead, RP: ReadParams> std::io::Read for BufBitReader<BE, WR, RP>
681where
682 WR::Word: DoubleType + UpcastableInto<u64>,
683 BB<WR>: CastableInto<u64>,
684{
685 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
686 let mut iter = buf.chunks_exact_mut(8);
687
688 for chunk in &mut iter {
689 let word = self
690 .read_bits(64)
691 .map_err(|_| std::io::ErrorKind::UnexpectedEof)?;
692 chunk.copy_from_slice(&word.to_be_bytes());
693 }
694
695 let rem = iter.into_remainder();
696 if !rem.is_empty() {
697 let word = self
698 .read_bits(rem.len() * 8)
699 .map_err(|_| std::io::ErrorKind::UnexpectedEof)?;
700 rem.copy_from_slice(&word.to_be_bytes()[8 - rem.len()..]);
701 }
702
703 Ok(buf.len())
704 }
705}
706
707#[cfg(test)]
708#[cfg(feature = "std")]
709mod test {
710 use super::*;
711 use crate::prelude::{MemWordReader, MemWordWriterVec};
712 use std::io::Read;
713
714 #[test]
715 fn test_read() {
716 let data = [
717 0x90, 0x2d, 0xd0, 0x26, 0xdf, 0x89, 0xbb, 0x7e, 0x3a, 0xd6, 0xc6, 0x96, 0x73, 0xe9,
718 0x9d, 0xc9, 0x2a, 0x77, 0x82, 0xa9, 0xe6, 0x4b, 0x53, 0xcc, 0x83, 0x80, 0x4a, 0xf3,
719 0xcd, 0xe3, 0x50, 0x4e, 0x45, 0x4a, 0x3a, 0x42, 0x00, 0x4b, 0x4d, 0xbe, 0x4c, 0x88,
720 0x24, 0xf2, 0x4b, 0x6b, 0xbd, 0x79, 0xeb, 0x74, 0xbc, 0xe8, 0x7d, 0xff, 0x4b, 0x3d,
721 0xa7, 0xd6, 0x0d, 0xef, 0x9c, 0x5b, 0xb3, 0xec, 0x94, 0x97, 0xcc, 0x8b, 0x41, 0xe1,
722 0x9c, 0xcc, 0x1a, 0x03, 0x58, 0xc4, 0xfb, 0xd0, 0xc0, 0x10, 0xe2, 0xa0, 0xc9, 0xac,
723 0xa7, 0xbb, 0x50, 0xf6, 0x5c, 0x87, 0x68, 0x0f, 0x42, 0x93, 0x3f, 0x2e, 0x28, 0x28,
724 0x76, 0x83, 0x9b, 0xeb, 0x12, 0xe0, 0x4f, 0xc5, 0xb0, 0x8d, 0x14, 0xda, 0x3b, 0xdf,
725 0xd3, 0x4b, 0x80, 0xd1, 0xfc, 0x87, 0x85, 0xae, 0x54, 0xc7, 0x45, 0xc9, 0x38, 0x43,
726 0xa7, 0x9f, 0xdd, 0xa9, 0x71, 0xa7, 0x52, 0x36, 0x82, 0xff, 0x49, 0x55, 0xdb, 0x84,
727 0xc2, 0x95, 0xad, 0x45, 0x80, 0xc6, 0x02, 0x80, 0xf8, 0xfc, 0x86, 0x79, 0xae, 0xb9,
728 0x57, 0xe7, 0x3b, 0x33, 0x64, 0xa8,
729 ];
730 let data_u32 = unsafe { data.align_to::<u32>().1 };
731
732 for i in 0..data.len() {
733 let mut reader = BufBitReader::<LE, _>::new(MemWordReader::new(&data_u32));
734 let mut buffer = vec![0; i];
735 assert_eq!(reader.read(&mut buffer).unwrap(), i);
736 assert_eq!(&buffer, &data[..i]);
737
738 let mut reader = BufBitReader::<BE, _>::new(MemWordReader::new(&data_u32));
739 let mut buffer = vec![0; i];
740 assert_eq!(reader.read(&mut buffer).unwrap(), i);
741 assert_eq!(&buffer, &data[..i]);
742 }
743 }
744
745 macro_rules! test_buf_bit_reader {
746 ($f: ident, $word:ty) => {
747 #[test]
748 fn $f() -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
749 #[allow(unused_imports)]
750 use crate::{
751 codes::{GammaRead, GammaWrite},
752 prelude::{
753 BufBitWriter, DeltaRead, DeltaWrite, MemWordReader, len_delta, len_gamma,
754 },
755 };
756 use rand::Rng;
757 use rand::{SeedableRng, rngs::SmallRng};
758
759 let mut buffer_be: Vec<$word> = vec![];
760 let mut buffer_le: Vec<$word> = vec![];
761 let mut big = BufBitWriter::<BE, _>::new(MemWordWriterVec::new(&mut buffer_be));
762 let mut little = BufBitWriter::<LE, _>::new(MemWordWriterVec::new(&mut buffer_le));
763
764 let mut r = SmallRng::seed_from_u64(0);
765 const ITER: usize = 1_000_000;
766
767 for _ in 0..ITER {
768 let value = r.random_range(0..128);
769 assert_eq!(big.write_gamma(value)?, len_gamma(value));
770 let value = r.random_range(0..128);
771 assert_eq!(little.write_gamma(value)?, len_gamma(value));
772 let value = r.random_range(0..128);
773 assert_eq!(big.write_gamma(value)?, len_gamma(value));
774 let value = r.random_range(0..128);
775 assert_eq!(little.write_gamma(value)?, len_gamma(value));
776 let value = r.random_range(0..128);
777 assert_eq!(big.write_delta(value)?, len_delta(value));
778 let value = r.random_range(0..128);
779 assert_eq!(little.write_delta(value)?, len_delta(value));
780 let value = r.random_range(0..128);
781 assert_eq!(big.write_delta(value)?, len_delta(value));
782 let value = r.random_range(0..128);
783 assert_eq!(little.write_delta(value)?, len_delta(value));
784 let n_bits = r.random_range(0..=64);
785 if n_bits == 0 {
786 big.write_bits(0, 0)?;
787 } else {
788 big.write_bits(1, n_bits)?;
789 }
790 let n_bits = r.random_range(0..=64);
791 if n_bits == 0 {
792 little.write_bits(0, 0)?;
793 } else {
794 little.write_bits(1, n_bits)?;
795 }
796 let value = r.random_range(0..128);
797 assert_eq!(big.write_unary(value)?, value as usize + 1);
798 let value = r.random_range(0..128);
799 assert_eq!(little.write_unary(value)?, value as usize + 1);
800 }
801
802 drop(big);
803 drop(little);
804
805 type ReadWord = $word;
806
807 #[allow(clippy::size_of_in_element_count)] let be_trans: &[ReadWord] = unsafe {
809 core::slice::from_raw_parts(
810 buffer_be.as_ptr() as *const ReadWord,
811 buffer_be.len()
812 * (core::mem::size_of::<$word>() / core::mem::size_of::<ReadWord>()),
813 )
814 };
815
816 #[allow(clippy::size_of_in_element_count)] let le_trans: &[ReadWord] = unsafe {
818 core::slice::from_raw_parts(
819 buffer_le.as_ptr() as *const ReadWord,
820 buffer_le.len()
821 * (core::mem::size_of::<$word>() / core::mem::size_of::<ReadWord>()),
822 )
823 };
824
825 let mut big_buff = BufBitReader::<BE, _>::new(MemWordReader::new(be_trans));
826 let mut little_buff = BufBitReader::<LE, _>::new(MemWordReader::new(le_trans));
827
828 let mut r = SmallRng::seed_from_u64(0);
829
830 for _ in 0..ITER {
831 assert_eq!(big_buff.read_gamma()?, r.random_range(0..128));
832 assert_eq!(little_buff.read_gamma()?, r.random_range(0..128));
833 assert_eq!(big_buff.read_gamma()?, r.random_range(0..128));
834 assert_eq!(little_buff.read_gamma()?, r.random_range(0..128));
835 assert_eq!(big_buff.read_delta()?, r.random_range(0..128));
836 assert_eq!(little_buff.read_delta()?, r.random_range(0..128));
837 assert_eq!(big_buff.read_delta()?, r.random_range(0..128));
838 assert_eq!(little_buff.read_delta()?, r.random_range(0..128));
839 let n_bits = r.random_range(0..=64);
840 if n_bits == 0 {
841 assert_eq!(big_buff.read_bits(0)?, 0);
842 } else {
843 assert_eq!(big_buff.read_bits(n_bits)?, 1);
844 }
845 let n_bits = r.random_range(0..=64);
846 if n_bits == 0 {
847 assert_eq!(little_buff.read_bits(0)?, 0);
848 } else {
849 assert_eq!(little_buff.read_bits(n_bits)?, 1);
850 }
851
852 assert_eq!(big_buff.read_unary()?, r.random_range(0..128));
853 assert_eq!(little_buff.read_unary()?, r.random_range(0..128));
854 }
855
856 Ok(())
857 }
858 };
859 }
860
861 test_buf_bit_reader!(test_u64, u64);
862 test_buf_bit_reader!(test_u32, u32);
863
864 test_buf_bit_reader!(test_u16, u16);
865}