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