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