bits_io/io/
bit_read.rs

1use crate::prelude::*;
2
3/// The BitRead trait allows for reading bits from a source.
4pub trait BitRead: std::io::Read {
5    /// Pull some bits from this source into the specified buffer, returning how many bits were
6    /// read.
7    fn read_bits<O: BitStore>(&mut self, dest: &mut BitSlice<O>) -> std::io::Result<usize>;
8
9    /// Read the exact number of bits required to fill buf.
10    fn read_bits_exact<O: BitStore>(&mut self, dest: &mut BitSlice<O>) -> std::io::Result<()> {
11        // TODO: double-check this impl
12        read_bits_exact_helper(self, dest)
13    }
14}
15
16// TODO: do we need this helper?
17fn read_bits_exact_helper<R: BitRead + ?Sized, O: BitStore>(
18    this: &mut R,
19    mut dest: &mut BitSlice<O>,
20) -> std::io::Result<()> {
21    while !dest.is_empty() {
22        // Note: unlike std::io::Read, we don't have a special case for an 'interrupted'
23        // error, since we don't have access to all the error data it uses.
24        // TODO: look into if we can replicate the is_interrupted logic here somehow.
25        match this.read_bits(dest) {
26            Ok(0) => break,
27            Ok(n) => dest = &mut dest[n..],
28            Err(e) => return Err(e),
29        }
30    }
31    if !dest.is_empty() {
32        Err(std::io::Error::new(
33            std::io::ErrorKind::UnexpectedEof,
34            "failed to fill whole buffer",
35        ))
36    } else {
37        Ok(())
38    }
39}