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