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 common_traits::*;
10
11use crate::codes::params::{DefaultReadParams, ReadParams};
12use crate::traits::*;
13use core::convert::Infallible;
14use core::error::Error;
15use core::{mem, ptr};
16#[cfg(feature = "mem_dbg")]
17use mem_dbg::{MemDbg, MemSize};
18
19/// An internal shortcut to the double type of the word of a
20/// [`WordRead`].
21type BB<WR> = <<WR as WordRead>::Word as DoubleType>::DoubleType;
22
23/// An implementation of [`BitRead`] and [`BitSeek`] for a [`WordRead`] and a
24/// [`WordSeek`].
25///
26/// This implementation uses a bit buffer to store bits that are not yet read.
27/// The buffer is sized as twice the word size of the underlying [`WordRead`].
28/// Typically, the best choice is to have a buffer that is sized as `usize`,
29/// which means that the word of the underlying [`WordRead`] should be half of
30/// that (i.e., `u32` for a 64-bit architecture). However, results will vary
31/// depending on the CPU.
32///
33/// The peek word is equal to the bit buffer. The value returned
34/// by [`peek_bits`](crate::traits::BitRead::peek_bits) contains at least as
35/// many bits as the word size plus one (extended with zeros beyond end of
36/// stream).
37///
38/// The convenience methods [`from_path`] and [`from_file`] create a
39/// [`BufBitReader`] around a buffered file reader.
40///
41/// This implementation is usually faster than
42/// [`BitReader`](crate::impls::BitReader).
43///
44/// The additional type parameter `RP` is used to select the parameters for the
45/// instantaneous codes, but the casual user should be happy with the default
46/// value. See [`ReadParams`] for more details.
47///
48/// For additional flexibility, this structures implements [`std::io::Read`].
49/// Note that because of coherence rules it is not possible to implement
50/// [`std::io::Read`] for a generic [`BitRead`].
51
52#[derive(Debug)]
53#[cfg_attr(feature = "mem_dbg", derive(MemDbg, MemSize))]
54pub struct BufBitReader<E: Endianness, WR: WordRead, RP: ReadParams = DefaultReadParams>
55where
56    WR::Word: DoubleType,
57{
58    /// The [`WordRead`] used to fill the buffer.
59    backend: WR,
60    /// The 2-word bit buffer that is used to read the codes. It is never full,
61    /// but it may be empty. Only the upper (BE) or lower (LE)
62    /// `bits_in_buffer` bits are valid; the other bits are always zeroes.
63    buffer: BB<WR>,
64    /// Number of valid upper (BE) or lower (LE) bits in the buffer.
65    /// It is always smaller than `BB::<WR>::BITS`.
66    bits_in_buffer: usize,
67    _marker: core::marker::PhantomData<(E, RP)>,
68}
69
70/// Creates a new [`BufBitReader`] with [default read
71/// parameters](`DefaultReadParams`) from a file path using the provided
72/// endianness and read word.
73///
74/// # Examples
75///
76/// ```no_run
77/// use dsi_bitstream::prelude::*;
78/// let mut reader = buf_bit_reader::from_path::<LE, u32>("data.bin")?;
79/// # Ok::<(), Box<dyn std::error::Error>>(())
80/// ```
81#[cfg(feature = "std")]
82pub fn from_path<E: Endianness, W: Word + DoubleType>(
83    path: impl AsRef<std::path::Path>,
84) -> anyhow::Result<
85    BufBitReader<E, super::WordAdapter<W, std::io::BufReader<std::fs::File>>, DefaultReadParams>,
86> {
87    Ok(from_file::<E, W>(std::fs::File::open(path)?))
88}
89
90/// Creates a new [`BufBitReader`] with [default read
91/// parameters](`DefaultReadParams`) from a file path using the provided
92/// endianness and read word.
93///
94/// See also [`from_path`] for a version that takes a path.
95#[cfg(feature = "std")]
96pub fn from_file<E: Endianness, W: Word + DoubleType>(
97    file: std::fs::File,
98) -> BufBitReader<E, super::WordAdapter<W, std::io::BufReader<std::fs::File>>, DefaultReadParams> {
99    BufBitReader::new(super::WordAdapter::new(std::io::BufReader::new(file)))
100}
101
102impl<E: Endianness, WR: WordRead + Clone, RP: ReadParams> core::clone::Clone
103    for BufBitReader<E, WR, RP>
104where
105    WR::Word: DoubleType,
106{
107    fn clone(&self) -> Self {
108        Self {
109            backend: self.backend.clone(),
110            buffer: self.buffer,
111            bits_in_buffer: self.bits_in_buffer,
112            _marker: core::marker::PhantomData,
113        }
114    }
115}
116
117impl<E: Endianness, WR: WordRead, RP: ReadParams> BufBitReader<E, WR, RP>
118where
119    WR::Word: DoubleType,
120{
121    /// Creates a new [`BufBitReader`] around a [`WordRead`].
122    ///
123    /// # Example
124    /// ```
125    /// use dsi_bitstream::prelude::*;
126    /// let words: [u32; 2] = [0x0043b59f, 0xccf16077];
127    /// let word_reader = MemWordReader::new(&words);
128    /// let mut buf_bit_reader = <BufBitReader<BE, _>>::new(word_reader);
129    /// ```
130    #[must_use]
131    pub fn new(backend: WR) -> Self {
132        #[cfg(feature = "std")]
133        check_tables(WR::Word::BITS + 1);
134        Self {
135            backend,
136            buffer: BB::<WR>::ZERO,
137            bits_in_buffer: 0,
138            _marker: core::marker::PhantomData,
139        }
140    }
141
142    ///  Return the backend, consuming this reader.
143    pub fn into_inner(self) -> Result<WR, Infallible> {
144        // SAFETY: forget(self) prevents double dropping backend
145        let backend = unsafe { ptr::read(&self.backend) };
146        mem::forget(self);
147        Ok(backend)
148    }
149}
150
151//
152// Big-endian implementation
153//
154
155impl<WR: WordRead, RP: ReadParams> BufBitReader<BE, WR, RP>
156where
157    WR::Word: DoubleType,
158{
159    /// Ensure that in the buffer there are at least `WR::Word::BITS` bits to read.
160    /// This method can be called only if there are at least
161    /// `WR::Word::BITS` free bits in the buffer.
162    #[inline(always)]
163    fn refill(&mut self) -> Result<(), <WR as WordRead>::Error> {
164        debug_assert!(BB::<WR>::BITS - self.bits_in_buffer >= WR::Word::BITS);
165
166        let new_word: BB<WR> = self.backend.read_word()?.to_be().upcast();
167        self.bits_in_buffer += WR::Word::BITS;
168        self.buffer |= new_word << (BB::<WR>::BITS - self.bits_in_buffer);
169        Ok(())
170    }
171}
172
173impl<WR: WordRead, RP: ReadParams> BitRead<BE> for BufBitReader<BE, WR, RP>
174where
175    WR::Word: DoubleType + UpcastableInto<u64>,
176    BB<WR>: CastableInto<u64>,
177{
178    type Error = <WR as WordRead>::Error;
179    type PeekWord = BB<WR>;
180
181    #[inline(always)]
182    fn peek_bits(&mut self, n_bits: usize) -> Result<Self::PeekWord, Self::Error> {
183        debug_assert!(n_bits > 0);
184        debug_assert!(n_bits <= Self::PeekWord::BITS);
185
186        // A peek can do at most one refill, otherwise we might lose data
187        if n_bits > self.bits_in_buffer {
188            self.refill()?;
189        }
190
191        debug_assert!(n_bits <= self.bits_in_buffer);
192
193        // Move the n_bits highest bits of the buffer to the lowest
194        Ok(self.buffer >> (BB::<WR>::BITS - n_bits))
195    }
196
197    #[inline(always)]
198    fn skip_bits_after_peek(&mut self, n_bits: usize) {
199        self.bits_in_buffer -= n_bits;
200        self.buffer <<= n_bits;
201    }
202
203    #[inline]
204    fn read_bits(&mut self, mut n_bits: usize) -> Result<u64, Self::Error> {
205        debug_assert!(n_bits <= 64);
206        debug_assert!(self.bits_in_buffer < BB::<WR>::BITS);
207
208        // most common path, we just read the buffer
209        if n_bits <= self.bits_in_buffer {
210            // Valid right shift of BB::<WR>::BITS - n_bits, even when n_bits is zero
211            let result: u64 = (self.buffer >> (BB::<WR>::BITS - n_bits - 1) >> 1_u32).cast();
212            self.bits_in_buffer -= n_bits;
213            self.buffer <<= n_bits;
214            return Ok(result);
215        }
216
217        let mut result: u64 =
218            (self.buffer >> (BB::<WR>::BITS - 1 - self.bits_in_buffer) >> 1_u8).cast();
219        n_bits -= self.bits_in_buffer;
220
221        // Directly read to the result without updating the buffer
222        while n_bits > WR::Word::BITS {
223            let new_word: u64 = self.backend.read_word()?.to_be().upcast();
224            result = (result << WR::Word::BITS) | new_word;
225            n_bits -= WR::Word::BITS;
226        }
227
228        debug_assert!(n_bits > 0);
229        debug_assert!(n_bits <= WR::Word::BITS);
230
231        // get the final word
232        let new_word = self.backend.read_word()?.to_be();
233        self.bits_in_buffer = WR::Word::BITS - n_bits;
234        // compose the remaining bits
235        let upcasted: u64 = new_word.upcast();
236        let final_bits: u64 = (upcasted >> self.bits_in_buffer).downcast();
237        result = (result << (n_bits - 1) << 1) | final_bits;
238        // and put the rest in the buffer
239        self.buffer = (UpcastableInto::<BB<WR>>::upcast(new_word)
240            << (BB::<WR>::BITS - self.bits_in_buffer - 1))
241            << 1;
242
243        Ok(result)
244    }
245
246    #[inline]
247    fn read_unary(&mut self) -> Result<u64, Self::Error> {
248        debug_assert!(self.bits_in_buffer < BB::<WR>::BITS);
249
250        // count the zeros from the left
251        let zeros: usize = self.buffer.leading_zeros() as _;
252
253        // if we encountered an 1 in the bits_in_buffer we can return
254        if zeros < self.bits_in_buffer {
255            self.buffer = self.buffer << zeros << 1;
256            self.bits_in_buffer -= zeros + 1;
257            return Ok(zeros as u64);
258        }
259
260        let mut result: u64 = self.bits_in_buffer as _;
261
262        loop {
263            let new_word = self.backend.read_word()?.to_be();
264
265            if new_word != WR::Word::ZERO {
266                let zeros: usize = new_word.leading_zeros() as _;
267                self.buffer =
268                    UpcastableInto::<BB<WR>>::upcast(new_word) << (WR::Word::BITS + zeros) << 1;
269                self.bits_in_buffer = WR::Word::BITS - zeros - 1;
270                return Ok(result + zeros as u64);
271            }
272            result += WR::Word::BITS as u64;
273        }
274    }
275
276    #[inline]
277    fn skip_bits(&mut self, mut n_bits: usize) -> Result<(), Self::Error> {
278        debug_assert!(self.bits_in_buffer < BB::<WR>::BITS);
279        // happy case, just shift the buffer
280        if n_bits <= self.bits_in_buffer {
281            self.bits_in_buffer -= n_bits;
282            self.buffer <<= n_bits;
283            return Ok(());
284        }
285
286        n_bits -= self.bits_in_buffer;
287
288        // skip words as needed
289        while n_bits > WR::Word::BITS {
290            let _ = self.backend.read_word()?;
291            n_bits -= WR::Word::BITS;
292        }
293
294        // get the final word
295        let new_word = self.backend.read_word()?.to_be();
296        self.bits_in_buffer = WR::Word::BITS - n_bits;
297
298        self.buffer = UpcastableInto::<BB<WR>>::upcast(new_word)
299            << (BB::<WR>::BITS - 1 - self.bits_in_buffer)
300            << 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.cast();
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 > WR::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                        .upcast(),
343                    WR::Word::BITS,
344                )
345                .map_err(CopyError::WriteError)?;
346            n -= WR::Word::BITS as u64;
347        }
348
349        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 = WR::Word::BITS - n as usize;
356        bit_write
357            .write_bits((new_word >> self.bits_in_buffer).upcast(), n as usize)
358            .map_err(CopyError::WriteError)?;
359        self.buffer = UpcastableInto::<BB<WR>>::upcast(new_word)
360            .rotate_right(WR::Word::BITS as u32 - n as u32);
361
362        Ok(())
363    }
364}
365
366impl<
367    E: Error + Send + Sync + 'static,
368    WR: WordRead<Error = E> + WordSeek<Error = E>,
369    RP: ReadParams,
370> BitSeek for BufBitReader<BE, WR, RP>
371where
372    WR::Word: DoubleType,
373{
374    type Error = <WR as WordSeek>::Error;
375
376    #[inline]
377    fn bit_pos(&mut self) -> Result<u64, Self::Error> {
378        Ok(self.backend.word_pos()? * WR::Word::BITS as u64 - self.bits_in_buffer as u64)
379    }
380
381    #[inline]
382    fn set_bit_pos(&mut self, bit_index: u64) -> Result<(), Self::Error> {
383        self.backend
384            .set_word_pos(bit_index / WR::Word::BITS as u64)?;
385        let bit_offset = (bit_index % WR::Word::BITS as u64) as usize;
386        self.buffer = BB::<WR>::ZERO;
387        self.bits_in_buffer = 0;
388        if bit_offset != 0 {
389            let new_word: BB<WR> = self.backend.read_word()?.to_be().upcast();
390            self.bits_in_buffer = WR::Word::BITS - bit_offset;
391            self.buffer = new_word << (BB::<WR>::BITS - self.bits_in_buffer);
392        }
393        Ok(())
394    }
395}
396
397//
398// Little-endian implementation
399//
400
401impl<WR: WordRead, RP: ReadParams> BufBitReader<LE, WR, RP>
402where
403    WR::Word: DoubleType,
404{
405    /// Ensure that in the buffer there are at least `WR::Word::BITS` bits to read.
406    /// This method can be called only if there are at least
407    /// `WR::Word::BITS` free bits in the buffer.
408    #[inline(always)]
409    fn refill(&mut self) -> Result<(), <WR as WordRead>::Error> {
410        debug_assert!(BB::<WR>::BITS - self.bits_in_buffer >= WR::Word::BITS);
411
412        let new_word: BB<WR> = self.backend.read_word()?.to_le().upcast();
413        self.buffer |= new_word << self.bits_in_buffer;
414        self.bits_in_buffer += WR::Word::BITS;
415        Ok(())
416    }
417}
418
419impl<WR: WordRead, RP: ReadParams> BitRead<LE> for BufBitReader<LE, WR, RP>
420where
421    WR::Word: DoubleType + UpcastableInto<u64>,
422    BB<WR>: CastableInto<u64>,
423{
424    type Error = <WR as WordRead>::Error;
425    type PeekWord = BB<WR>;
426
427    #[inline(always)]
428    fn peek_bits(&mut self, n_bits: usize) -> Result<Self::PeekWord, Self::Error> {
429        debug_assert!(n_bits > 0);
430        debug_assert!(n_bits <= Self::PeekWord::BITS);
431
432        // A peek can do at most one refill, otherwise we might lose data
433        if n_bits > self.bits_in_buffer {
434            self.refill()?;
435        }
436
437        debug_assert!(n_bits <= self.bits_in_buffer);
438
439        // Keep the n_bits lowest bits of the buffer
440        let shamt = BB::<WR>::BITS - n_bits;
441        Ok((self.buffer << shamt) >> shamt)
442    }
443
444    #[inline(always)]
445    fn skip_bits_after_peek(&mut self, n_bits: usize) {
446        self.bits_in_buffer -= n_bits;
447        self.buffer >>= n_bits;
448    }
449
450    #[inline]
451    fn read_bits(&mut self, mut n_bits: usize) -> Result<u64, Self::Error> {
452        debug_assert!(n_bits <= 64);
453        debug_assert!(self.bits_in_buffer < BB::<WR>::BITS);
454
455        // most common path, we just read the buffer
456        if n_bits <= self.bits_in_buffer {
457            let result: u64 = (self.buffer & ((BB::<WR>::ONE << n_bits) - BB::<WR>::ONE)).cast();
458            self.bits_in_buffer -= n_bits;
459            self.buffer >>= n_bits;
460            return Ok(result);
461        }
462
463        let mut result: u64 = self.buffer.cast();
464        let mut bits_in_res = self.bits_in_buffer;
465
466        // Directly read to the result without updating the buffer
467        while n_bits > WR::Word::BITS + bits_in_res {
468            let new_word: u64 = self.backend.read_word()?.to_le().upcast();
469            result |= new_word << bits_in_res;
470            bits_in_res += WR::Word::BITS;
471        }
472
473        n_bits -= bits_in_res;
474
475        debug_assert!(n_bits > 0);
476        debug_assert!(n_bits <= WR::Word::BITS);
477
478        // get the final word
479        let new_word = self.backend.read_word()?.to_le();
480        self.bits_in_buffer = WR::Word::BITS - n_bits;
481        // compose the remaining bits
482        let shamt = 64 - n_bits;
483        let upcasted: u64 = new_word.upcast();
484        let final_bits: u64 = ((upcasted << shamt) >> shamt).downcast();
485        result |= final_bits << bits_in_res;
486        // and put the rest in the buffer
487        self.buffer = UpcastableInto::<BB<WR>>::upcast(new_word) >> n_bits;
488
489        Ok(result)
490    }
491
492    #[inline]
493    fn read_unary(&mut self) -> Result<u64, Self::Error> {
494        debug_assert!(self.bits_in_buffer < BB::<WR>::BITS);
495
496        // count the zeros from the right
497        let zeros: usize = self.buffer.trailing_zeros() as usize;
498
499        // if we encountered an 1 in the bits_in_buffer we can return
500        if zeros < self.bits_in_buffer {
501            self.buffer = self.buffer >> zeros >> 1;
502            self.bits_in_buffer -= zeros + 1;
503            return Ok(zeros as u64);
504        }
505
506        let mut result: u64 = self.bits_in_buffer as _;
507
508        loop {
509            let new_word = self.backend.read_word()?.to_le();
510
511            if new_word != WR::Word::ZERO {
512                let zeros: usize = new_word.trailing_zeros() as _;
513                self.buffer = UpcastableInto::<BB<WR>>::upcast(new_word) >> zeros >> 1;
514                self.bits_in_buffer = WR::Word::BITS - zeros - 1;
515                return Ok(result + zeros as u64);
516            }
517            result += WR::Word::BITS as u64;
518        }
519    }
520
521    #[inline]
522    fn skip_bits(&mut self, mut n_bits: usize) -> Result<(), Self::Error> {
523        debug_assert!(self.bits_in_buffer < BB::<WR>::BITS);
524        // happy case, just shift the buffer
525        if n_bits <= self.bits_in_buffer {
526            self.bits_in_buffer -= n_bits;
527            self.buffer >>= n_bits;
528            return Ok(());
529        }
530
531        n_bits -= self.bits_in_buffer;
532
533        // skip words as needed
534        while n_bits > WR::Word::BITS {
535            let _ = self.backend.read_word()?;
536            n_bits -= WR::Word::BITS;
537        }
538
539        // get the final word
540        let new_word = self.backend.read_word()?.to_le();
541        self.bits_in_buffer = WR::Word::BITS - n_bits;
542        self.buffer = UpcastableInto::<BB<WR>>::upcast(new_word) >> n_bits;
543
544        Ok(())
545    }
546
547    #[cfg(not(feature = "no_copy_impls"))]
548    fn copy_to<F: Endianness, W: BitWrite<F>>(
549        &mut self,
550        bit_write: &mut W,
551        mut n: u64,
552    ) -> Result<(), CopyError<Self::Error, W::Error>> {
553        let from_buffer = Ord::min(n, self.bits_in_buffer as _);
554
555        #[allow(unused_mut)]
556        let mut self_buffer_u64: u64 = self.buffer.cast();
557
558        #[cfg(feature = "checks")]
559        {
560            // Clean up in case checks are enabled
561            if n < 64 {
562                self_buffer_u64 &= (1_u64 << n) - 1;
563            }
564        }
565
566        bit_write
567            .write_bits(self_buffer_u64, from_buffer as usize)
568            .map_err(CopyError::WriteError)?;
569
570        self.buffer >>= from_buffer;
571        n -= from_buffer;
572
573        if n == 0 {
574            self.bits_in_buffer -= from_buffer as usize;
575            return Ok(());
576        }
577
578        while n > WR::Word::BITS as u64 {
579            bit_write
580                .write_bits(
581                    self.backend
582                        .read_word()
583                        .map_err(CopyError::ReadError)?
584                        .to_le()
585                        .upcast(),
586                    WR::Word::BITS,
587                )
588                .map_err(CopyError::WriteError)?;
589            n -= WR::Word::BITS as u64;
590        }
591
592        assert!(n > 0);
593        let new_word = self
594            .backend
595            .read_word()
596            .map_err(CopyError::ReadError)?
597            .to_le();
598        self.bits_in_buffer = WR::Word::BITS - n as usize;
599
600        #[allow(unused_mut)]
601        let mut new_word_u64: u64 = new_word.upcast();
602
603        #[cfg(feature = "checks")]
604        {
605            // Clean up in case checks are enabled
606            if n < 64 {
607                new_word_u64 &= (1_u64 << n) - 1;
608            }
609        }
610
611        bit_write
612            .write_bits(new_word_u64, n as usize)
613            .map_err(CopyError::WriteError)?;
614        self.buffer = UpcastableInto::<BB<WR>>::upcast(new_word) >> n;
615        Ok(())
616    }
617}
618
619impl<
620    E: Error + Send + Sync + 'static,
621    WR: WordRead<Error = E> + WordSeek<Error = E>,
622    RP: ReadParams,
623> BitSeek for BufBitReader<LE, WR, RP>
624where
625    WR::Word: DoubleType,
626{
627    type Error = <WR as WordSeek>::Error;
628
629    #[inline]
630    fn bit_pos(&mut self) -> Result<u64, Self::Error> {
631        Ok(self.backend.word_pos()? * WR::Word::BITS as u64 - self.bits_in_buffer as u64)
632    }
633
634    #[inline]
635    fn set_bit_pos(&mut self, bit_index: u64) -> Result<(), Self::Error> {
636        self.backend
637            .set_word_pos(bit_index / WR::Word::BITS as u64)?;
638
639        let bit_offset = (bit_index % WR::Word::BITS as u64) as usize;
640        self.buffer = BB::<WR>::ZERO;
641        self.bits_in_buffer = 0;
642        if bit_offset != 0 {
643            let new_word: BB<WR> = self.backend.read_word()?.to_le().upcast();
644            self.bits_in_buffer = WR::Word::BITS - bit_offset;
645            self.buffer = new_word >> bit_offset;
646        }
647        Ok(())
648    }
649}
650
651#[cfg(feature = "std")]
652impl<WR: WordRead, RP: ReadParams> std::io::Read for BufBitReader<LE, WR, RP>
653where
654    WR::Word: DoubleType + UpcastableInto<u64>,
655    BB<WR>: CastableInto<u64>,
656{
657    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
658        let mut iter = buf.chunks_exact_mut(8);
659
660        for chunk in &mut iter {
661            let word = self
662                .read_bits(64)
663                .map_err(|_| std::io::ErrorKind::UnexpectedEof)?;
664            chunk.copy_from_slice(&word.to_le_bytes());
665        }
666
667        let rem = iter.into_remainder();
668        if !rem.is_empty() {
669            let word = self
670                .read_bits(rem.len() * 8)
671                .map_err(|_| std::io::ErrorKind::UnexpectedEof)?;
672            rem.copy_from_slice(&word.to_le_bytes()[..rem.len()]);
673        }
674
675        Ok(buf.len())
676    }
677}
678
679#[cfg(feature = "std")]
680impl<WR: WordRead, RP: ReadParams> std::io::Read for BufBitReader<BE, WR, RP>
681where
682    WR::Word: DoubleType + UpcastableInto<u64>,
683    BB<WR>: CastableInto<u64>,
684{
685    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
686        let mut iter = buf.chunks_exact_mut(8);
687
688        for chunk in &mut iter {
689            let word = self
690                .read_bits(64)
691                .map_err(|_| std::io::ErrorKind::UnexpectedEof)?;
692            chunk.copy_from_slice(&word.to_be_bytes());
693        }
694
695        let rem = iter.into_remainder();
696        if !rem.is_empty() {
697            let word = self
698                .read_bits(rem.len() * 8)
699                .map_err(|_| std::io::ErrorKind::UnexpectedEof)?;
700            rem.copy_from_slice(&word.to_be_bytes()[8 - rem.len()..]);
701        }
702
703        Ok(buf.len())
704    }
705}
706
707#[cfg(test)]
708#[cfg(feature = "std")]
709mod test {
710    use super::*;
711    use crate::prelude::{MemWordReader, MemWordWriterVec};
712    use std::io::Read;
713
714    #[test]
715    fn test_read() {
716        let data = [
717            0x90, 0x2d, 0xd0, 0x26, 0xdf, 0x89, 0xbb, 0x7e, 0x3a, 0xd6, 0xc6, 0x96, 0x73, 0xe9,
718            0x9d, 0xc9, 0x2a, 0x77, 0x82, 0xa9, 0xe6, 0x4b, 0x53, 0xcc, 0x83, 0x80, 0x4a, 0xf3,
719            0xcd, 0xe3, 0x50, 0x4e, 0x45, 0x4a, 0x3a, 0x42, 0x00, 0x4b, 0x4d, 0xbe, 0x4c, 0x88,
720            0x24, 0xf2, 0x4b, 0x6b, 0xbd, 0x79, 0xeb, 0x74, 0xbc, 0xe8, 0x7d, 0xff, 0x4b, 0x3d,
721            0xa7, 0xd6, 0x0d, 0xef, 0x9c, 0x5b, 0xb3, 0xec, 0x94, 0x97, 0xcc, 0x8b, 0x41, 0xe1,
722            0x9c, 0xcc, 0x1a, 0x03, 0x58, 0xc4, 0xfb, 0xd0, 0xc0, 0x10, 0xe2, 0xa0, 0xc9, 0xac,
723            0xa7, 0xbb, 0x50, 0xf6, 0x5c, 0x87, 0x68, 0x0f, 0x42, 0x93, 0x3f, 0x2e, 0x28, 0x28,
724            0x76, 0x83, 0x9b, 0xeb, 0x12, 0xe0, 0x4f, 0xc5, 0xb0, 0x8d, 0x14, 0xda, 0x3b, 0xdf,
725            0xd3, 0x4b, 0x80, 0xd1, 0xfc, 0x87, 0x85, 0xae, 0x54, 0xc7, 0x45, 0xc9, 0x38, 0x43,
726            0xa7, 0x9f, 0xdd, 0xa9, 0x71, 0xa7, 0x52, 0x36, 0x82, 0xff, 0x49, 0x55, 0xdb, 0x84,
727            0xc2, 0x95, 0xad, 0x45, 0x80, 0xc6, 0x02, 0x80, 0xf8, 0xfc, 0x86, 0x79, 0xae, 0xb9,
728            0x57, 0xe7, 0x3b, 0x33, 0x64, 0xa8,
729        ];
730        let data_u32 = unsafe { data.align_to::<u32>().1 };
731
732        for i in 0..data.len() {
733            let mut reader = BufBitReader::<LE, _>::new(MemWordReader::new(&data_u32));
734            let mut buffer = vec![0; i];
735            assert_eq!(reader.read(&mut buffer).unwrap(), i);
736            assert_eq!(&buffer, &data[..i]);
737
738            let mut reader = BufBitReader::<BE, _>::new(MemWordReader::new(&data_u32));
739            let mut buffer = vec![0; i];
740            assert_eq!(reader.read(&mut buffer).unwrap(), i);
741            assert_eq!(&buffer, &data[..i]);
742        }
743    }
744
745    macro_rules! test_buf_bit_reader {
746        ($f: ident, $word:ty) => {
747            #[test]
748            fn $f() -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
749                #[allow(unused_imports)]
750                use crate::{
751                    codes::{GammaRead, GammaWrite},
752                    prelude::{
753                        BufBitWriter, DeltaRead, DeltaWrite, MemWordReader, len_delta, len_gamma,
754                    },
755                };
756                use rand::Rng;
757                use rand::{SeedableRng, rngs::SmallRng};
758
759                let mut buffer_be: Vec<$word> = vec![];
760                let mut buffer_le: Vec<$word> = vec![];
761                let mut big = BufBitWriter::<BE, _>::new(MemWordWriterVec::new(&mut buffer_be));
762                let mut little = BufBitWriter::<LE, _>::new(MemWordWriterVec::new(&mut buffer_le));
763
764                let mut r = SmallRng::seed_from_u64(0);
765                const ITER: usize = 1_000_000;
766
767                for _ in 0..ITER {
768                    let value = r.random_range(0..128);
769                    assert_eq!(big.write_gamma(value)?, len_gamma(value));
770                    let value = r.random_range(0..128);
771                    assert_eq!(little.write_gamma(value)?, len_gamma(value));
772                    let value = r.random_range(0..128);
773                    assert_eq!(big.write_gamma(value)?, len_gamma(value));
774                    let value = r.random_range(0..128);
775                    assert_eq!(little.write_gamma(value)?, len_gamma(value));
776                    let value = r.random_range(0..128);
777                    assert_eq!(big.write_delta(value)?, len_delta(value));
778                    let value = r.random_range(0..128);
779                    assert_eq!(little.write_delta(value)?, len_delta(value));
780                    let value = r.random_range(0..128);
781                    assert_eq!(big.write_delta(value)?, len_delta(value));
782                    let value = r.random_range(0..128);
783                    assert_eq!(little.write_delta(value)?, len_delta(value));
784                    let n_bits = r.random_range(0..=64);
785                    if n_bits == 0 {
786                        big.write_bits(0, 0)?;
787                    } else {
788                        big.write_bits(1, n_bits)?;
789                    }
790                    let n_bits = r.random_range(0..=64);
791                    if n_bits == 0 {
792                        little.write_bits(0, 0)?;
793                    } else {
794                        little.write_bits(1, n_bits)?;
795                    }
796                    let value = r.random_range(0..128);
797                    assert_eq!(big.write_unary(value)?, value as usize + 1);
798                    let value = r.random_range(0..128);
799                    assert_eq!(little.write_unary(value)?, value as usize + 1);
800                }
801
802                drop(big);
803                drop(little);
804
805                type ReadWord = $word;
806
807                #[allow(clippy::size_of_in_element_count)] // false positive
808                let be_trans: &[ReadWord] = unsafe {
809                    core::slice::from_raw_parts(
810                        buffer_be.as_ptr() as *const ReadWord,
811                        buffer_be.len()
812                            * (core::mem::size_of::<$word>() / core::mem::size_of::<ReadWord>()),
813                    )
814                };
815
816                #[allow(clippy::size_of_in_element_count)] // false positive
817                let le_trans: &[ReadWord] = unsafe {
818                    core::slice::from_raw_parts(
819                        buffer_le.as_ptr() as *const ReadWord,
820                        buffer_le.len()
821                            * (core::mem::size_of::<$word>() / core::mem::size_of::<ReadWord>()),
822                    )
823                };
824
825                let mut big_buff = BufBitReader::<BE, _>::new(MemWordReader::new(be_trans));
826                let mut little_buff = BufBitReader::<LE, _>::new(MemWordReader::new(le_trans));
827
828                let mut r = SmallRng::seed_from_u64(0);
829
830                for _ in 0..ITER {
831                    assert_eq!(big_buff.read_gamma()?, r.random_range(0..128));
832                    assert_eq!(little_buff.read_gamma()?, r.random_range(0..128));
833                    assert_eq!(big_buff.read_gamma()?, r.random_range(0..128));
834                    assert_eq!(little_buff.read_gamma()?, r.random_range(0..128));
835                    assert_eq!(big_buff.read_delta()?, r.random_range(0..128));
836                    assert_eq!(little_buff.read_delta()?, r.random_range(0..128));
837                    assert_eq!(big_buff.read_delta()?, r.random_range(0..128));
838                    assert_eq!(little_buff.read_delta()?, r.random_range(0..128));
839                    let n_bits = r.random_range(0..=64);
840                    if n_bits == 0 {
841                        assert_eq!(big_buff.read_bits(0)?, 0);
842                    } else {
843                        assert_eq!(big_buff.read_bits(n_bits)?, 1);
844                    }
845                    let n_bits = r.random_range(0..=64);
846                    if n_bits == 0 {
847                        assert_eq!(little_buff.read_bits(0)?, 0);
848                    } else {
849                        assert_eq!(little_buff.read_bits(n_bits)?, 1);
850                    }
851
852                    assert_eq!(big_buff.read_unary()?, r.random_range(0..128));
853                    assert_eq!(little_buff.read_unary()?, r.random_range(0..128));
854                }
855
856                Ok(())
857            }
858        };
859    }
860
861    test_buf_bit_reader!(test_u64, u64);
862    test_buf_bit_reader!(test_u32, u32);
863
864    test_buf_bit_reader!(test_u16, u16);
865}