bit_cursor/
bit_read.rs

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