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