bits_io/buf/
take.rs

1use crate::prelude::*;
2
3/// A `BitBuf` adaptor which limits the bits read from an underlying buffer.
4pub struct Take<T> {
5    inner: T,
6    limit: usize,
7}
8
9impl<T> Take<T> {
10    pub fn new(inner: T, limit: usize) -> Take<T> {
11        Self { inner, limit }
12    }
13}
14
15impl<T> Take<T> {
16    pub fn into_inner(self) -> T {
17        self.inner
18    }
19
20    pub fn get_ref(&self) -> &T {
21        &self.inner
22    }
23
24    pub fn get_mut(&mut self) -> &mut T {
25        &mut self.inner
26    }
27
28    pub fn limit(&self) -> usize {
29        self.limit
30    }
31
32    pub fn set_limit(&mut self, limit: usize) {
33        self.limit = limit;
34    }
35}
36
37impl<T: BitBuf> BitBuf for Take<T> {
38    fn advance_bits(&mut self, count: usize) {
39        assert!(count <= self.limit);
40        self.inner.advance_bits(count);
41        self.limit -= count;
42    }
43
44    fn remaining_bits(&self) -> usize {
45        std::cmp::min(self.inner.remaining_bits(), self.limit)
46    }
47
48    fn chunk_bits(&self) -> &BitSlice {
49        let chunk = self.inner.chunk_bits();
50        let end = std::cmp::min(chunk.len(), self.limit);
51        &chunk[..end]
52    }
53
54    fn chunk_bytes(&self) -> &[u8] {
55        assert!(self.byte_aligned());
56        let chunk = self.inner.chunk_bytes();
57        let byte_limit = self.limit / 8;
58        let end = std::cmp::min(chunk.len(), byte_limit);
59        &chunk[..end]
60    }
61
62    fn byte_aligned(&self) -> bool {
63        // TODO: need to verify that this is right/it's possible to reliably implement this for
64        // BitTake
65        self.inner.byte_aligned() && self.limit % 8 == 0
66    }
67}