Skip to main content

dsi_bitstream/impls/
buf_bit_reader.rs

1/*
2 * SPDX-FileCopyrightText: 2023 Tommaso Fontana
3 * SPDX-FileCopyrightText: 2023 Inria
4 * SPDX-FileCopyrightText: 2023 Sebastiano Vigna
5 *
6 * SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
7 */
8
9use 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
16/// An internal shortcut to the double type of the word of a
17/// [`WordRead`].
18type BB<WR> = <<WR as WordRead>::Word as DoubleType>::DoubleType;
19
20/// An implementation of [`BitRead`] and [`BitSeek`] for a [`WordRead`] and a
21/// [`WordSeek`].
22///
23/// This implementation uses a bit buffer to store bits that are not yet read.
24/// The buffer is sized as twice the word size of the underlying [`WordRead`].
25/// Typically, the best choice is to have a buffer that is sized as `usize`,
26/// which means that the word of the underlying [`WordRead`] should be half of
27/// that (i.e., `u32` for a 64-bit architecture). However, results will vary
28/// depending on the CPU.
29///
30/// The peek word is equal to the bit buffer. The value returned
31/// by [`peek_bits`](crate::traits::BitRead::peek_bits) contains at least as
32/// many bits as the word size plus one (extended with zeros beyond end of
33/// stream).
34///
35/// The convenience functions [`from_path`] and [`from_file`] (requiring the
36/// `std` feature) create a [`BufBitReader`] around a buffered file reader.
37///
38/// This implementation is usually faster than
39/// [`BitReader`](crate::impls::BitReader).
40///
41/// The additional type parameter `RP` is used to select the parameters for the
42/// instantaneous codes, but the casual user should be happy with the default
43/// value. See [`ReadParams`] for more details.
44///
45/// For additional flexibility, when the `std` feature is enabled, this
46/// structure implements [`std::io::Read`]. Note that because of coherence
47/// rules it is not possible to implement [`std::io::Read`] for a generic
48/// [`BitRead`].
49
50#[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    /// The [`WordRead`] used to fill the buffer.
57    backend: WR,
58    /// The 2-word bit buffer that is used to read the codes. It is never full,
59    /// but it may be empty. Only the upper (BE) or lower (LE)
60    /// `bits_in_buffer` bits are valid; the other bits are always zeroes.
61    buffer: BB<WR>,
62    /// Number of valid upper (BE) or lower (LE) bits in the buffer.
63    /// It is always smaller than `BB::<WR>::BITS`.
64    bits_in_buffer: usize,
65    _marker: core::marker::PhantomData<(E, RP)>,
66}
67
68/// Creates a new [`BufBitReader`] with [default read
69/// parameters](`DefaultReadParams`) from a file path using the provided
70/// endianness and read word.
71///
72/// # Examples
73///
74/// ```no_run
75/// use dsi_bitstream::prelude::*;
76/// let mut reader = buf_bit_reader::from_path::<LE, u32>("data.bin")?;
77/// # Ok::<(), Box<dyn core::error::Error>>(())
78/// ```
79#[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/// Creates a new [`BufBitReader`] with [default read
92/// parameters](`DefaultReadParams`) from a file using the provided
93/// endianness and read word.
94///
95/// See also [`from_path`] for a version that takes a path.
96#[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    /// Creates a new [`BufBitReader`] around a [`WordRead`].
130    ///
131    /// # Examples
132    /// ```
133    /// use dsi_bitstream::prelude::*;
134    /// let words: [u32; 2] = [0x0043b59f, 0xccf16077];
135    /// let word_reader = MemWordReader::new_inf(&words);
136    /// let mut buf_bit_reader = <BufBitReader<BE, _>>::new(word_reader);
137    /// ```
138    #[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    /// Consumes this reader and returns the underlying [`WordRead`].
149    #[must_use]
150    pub fn into_inner(self) -> WR {
151        self.backend
152    }
153}
154
155//
156// Big-endian implementation
157//
158
159impl<WR: WordRead, RP: ReadParams> BufBitReader<BE, WR, RP>
160where
161    WR::Word: DoubleType,
162{
163    /// Ensures that in the buffer there are at least `Self::WORD_BITS` bits to read.
164    /// This method can be called only if there are at least
165    /// `Self::WORD_BITS` free bits in the buffer.
166    #[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        // A peek can do at most one refill, otherwise we might lose data
191        if n_bits > self.bits_in_buffer {
192            self.refill()?;
193        }
194
195        debug_assert!(n_bits <= self.bits_in_buffer);
196
197        // Move the n_bits highest bits of the buffer to the lowest
198        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        // most common path, we just read the buffer
213        if num_bits <= self.bits_in_buffer {
214            // Valid right shift of BB::<WR>::BITS - num_bits, even when num_bits is zero
215            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        // Directly read to the result without updating the buffer
226        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        // get the final word
236        let new_word = self.backend.read_word()?.to_be();
237        self.bits_in_buffer = Self::WORD_BITS - num_bits;
238        // compose the remaining bits
239        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        // and put the rest in the buffer
243        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        // count the zeros from the left
253        let zeros: usize = self.buffer.leading_zeros() as _;
254
255        // if we encountered a 1 in the bits_in_buffer we can return
256        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        // happy case, just shift the buffer
281        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        // skip words as needed
290        while n_bits > Self::WORD_BITS {
291            let _ = self.backend.read_word()?;
292            n_bits -= Self::WORD_BITS;
293        }
294
295        // get the final word
296        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            // Clean up in case checks are enabled
319            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
394//
395// Little-endian implementation
396//
397
398impl<WR: WordRead, RP: ReadParams> BufBitReader<LE, WR, RP>
399where
400    WR::Word: DoubleType,
401{
402    /// Ensures that in the buffer there are at least `Self::WORD_BITS` bits to read.
403    /// This method can be called only if there are at least
404    /// `Self::WORD_BITS` free bits in the buffer.
405    #[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        // A peek can do at most one refill, otherwise we might lose data
430        if n_bits > self.bits_in_buffer {
431            self.refill()?;
432        }
433
434        debug_assert!(n_bits <= self.bits_in_buffer);
435
436        // Keep the n_bits lowest bits of the buffer
437        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        // most common path, we just read the buffer
453        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        // Directly read to the result without updating the buffer
464        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        // get the final word
476        let new_word = self.backend.read_word()?.to_le();
477        self.bits_in_buffer = Self::WORD_BITS - num_bits;
478        // compose the remaining bits
479        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        // and put the rest in the buffer
484        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        // count the zeros from the right
494        let zeros: usize = self.buffer.trailing_zeros() as usize;
495
496        // if we encountered a 1 in the bits_in_buffer we can return
497        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        // happy case, just shift the buffer
522        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        // skip words as needed
531        while n_bits > Self::WORD_BITS {
532            let _ = self.backend.read_word()?;
533            n_bits -= Self::WORD_BITS;
534        }
535
536        // get the final word
537        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            // Clean up in case checks are enabled
558            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            // Clean up in case checks are enabled
603            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)] // false positive
801                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)] // false positive
810                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}