bits_io/buf/
bits.rs

1use std::ops::{Deref, Range};
2
3use crate::prelude::*;
4use bytes::{Bytes, BytesMut};
5
6use super::util::bytes_needed;
7
8// TODO: Need to determine if advancing here needs to be reflected in the underlying Bytes
9// instances.  For BitsMut it's critical, since the starting point for writing is important for
10// certain operations.  I suspect that may be the same for reading, but need to look into
11// it/verify.
12
13/// A cheaply cloneable chunk of contiugous memory, built on top of `[bytes::Bytes`] but providing
14/// bit-level operations.  
15#[derive(Clone, Debug, PartialEq, Eq)]
16pub struct Bits {
17    pub(crate) inner: Bytes,
18    /// The start of this instance's view of the underlying storage
19    pub(crate) bit_start: usize,
20    /// How many bits, from bit_start, are part of this view
21    pub(crate) bit_len: usize,
22}
23
24impl Bits {
25    /// Creates a new empty [`Bits`] from an instance of [`Bytes`]
26    pub fn from_bytes(bytes: Bytes) -> Self {
27        let bit_len = bytes.len() * 8;
28        Self {
29            inner: bytes,
30            bit_start: 0,
31            bit_len,
32        }
33    }
34
35    pub fn from_static_bytes(bytes: &'static [u8]) -> Self {
36        let inner = Bytes::from_static(bytes);
37        let bit_len = inner.len() * 8;
38        Self {
39            inner,
40            bit_start: 0,
41            bit_len,
42        }
43    }
44
45    pub fn from_owner_bytes<T>(owner: T) -> Self
46    where
47        T: AsRef<[u8]> + Send + 'static,
48    {
49        let inner = Bytes::from_owner(owner);
50        let bit_len = inner.len() * 8;
51        Self {
52            inner,
53            bit_start: 0,
54            bit_len,
55        }
56    }
57
58    /// Creates a new [`Bits`] instance from the given `BitSlice` by copying it.
59    pub fn copy_from_bit_slice(bits: &BitSlice) -> Self {
60        let bytes_needed = bytes_needed(bits.len());
61        let mut bytes = BytesMut::with_capacity(bytes_needed);
62        bytes.resize(bytes_needed, 0);
63
64        let target = BitSlice::from_slice_mut(&mut bytes);
65        target[..bits.len()].clone_from_bitslice(bits);
66
67        Self {
68            inner: bytes.freeze(),
69            bit_start: 0,
70            bit_len: bits.len(),
71        }
72    }
73
74    /// Creates a new `Bits` instance from the given u8 slice by copying it.
75    pub fn copy_from_bytes(bytes: &[u8]) -> Self {
76        let mut target = BytesMut::with_capacity(bytes.len());
77        target.resize(bytes.len(), 0);
78        target.copy_from_slice(bytes);
79
80        Self {
81            inner: target.freeze(),
82            bit_start: 0,
83            bit_len: bytes.len() * 8,
84        }
85    }
86
87    /// Create a slice corresponding to the given range, which is given in bits.  The given range
88    /// is relative to the start of the buffer, not the current position.
89    pub fn slice_bits(&self, range: Range<usize>) -> Self {
90        assert!(
91            range.end <= self.bit_start + self.bit_len,
92            "Range beyond Bits length"
93        );
94        Self {
95            inner: self.inner.clone(),
96            bit_start: self.bit_start + range.start,
97            bit_len: range.end - range.start,
98        }
99    }
100
101    /// Create a slice corresponding to the given range, which is given in bytes.  The given range
102    /// is relative to the start of the buffer, not the current position.  Note that the 'start' of
103    /// this view may not correspond to a byte boundary on the underlying storage.
104    pub fn slice_bytes(&self, range: Range<usize>) -> Self {
105        assert!(
106            range.end * 8 <= self.bit_start + self.bit_len,
107            "Range beyond Bits length"
108        );
109        let bit_range_start = range.start * 8;
110        let bit_range_end = range.end * 8;
111        self.slice_bits(bit_range_start..bit_range_end)
112    }
113
114    /// Splits the bits into two at the given bit index.
115    ///
116    /// Afterwards self contains elements [at, len), and the returned Bits contains elements [0,
117    /// at).
118    pub fn split_to_bits(&mut self, at: usize) -> Self {
119        assert!(
120            at <= self.bit_len,
121            "split_to out of bounds: {:?} must be <= {:?}",
122            at,
123            self.len_bits()
124        );
125        let mut ret = self.clone();
126        self.inc_start_bits(at);
127        ret.bit_len = at;
128        ret
129    }
130
131    /// Splits the bits into two at the given byte index.  Note that this byte index is relative to
132    /// the start of this view, and may not fall on a byte boundary in the underlying storage.
133    ///
134    /// Afterwards self contains elements [at, len), and the returned Bits contains elements [0,
135    /// at).
136    pub fn split_to_bytes(&mut self, at: usize) -> Self {
137        self.split_to_bits(at * 8)
138    }
139
140    /// Splits the bits into two at the given index.
141    ///
142    /// Afterwards self contains elements [0, at), and the returned Bits contains elements [at,
143    /// len).
144    pub fn split_off_bits(&mut self, at: usize) -> Self {
145        assert!(
146            at <= self.bit_len,
147            "split_off out of bounds: {:?} must be <= {:?}",
148            at,
149            self.len_bits()
150        );
151        let mut ret = self.clone();
152        self.bit_len = at;
153        ret.inc_start_bits(at);
154        ret
155    }
156
157    /// Splits the bits into two at the given byte index.  Note that this byte index is relative to
158    /// the start of this view, and may not fall on a byte boundary in the underlying storage.
159    ///
160    /// Afterwards self contains elements [0, at), and the returned Bits contains elements [at,
161    /// len).
162    pub fn split_off_bytes(&mut self, at: usize) -> Self {
163        self.split_off_bits(at * 8)
164    }
165
166    /// Shortens the buffer, keeping the first len bits and dropping the rest.
167    ///
168    /// If len is greater than the buffer’s current length, this has no effect.
169    ///
170    /// The split_off method can emulate truncate, but this causes the excess bits to be returned
171    /// instead of dropped.
172    pub fn truncate_bits(&mut self, len: usize) {
173        if len < self.bit_len {
174            self.bit_len = len;
175        }
176    }
177
178    /// Shortens the buffer, keeping the first len bytes and dropping the rest.
179    ///
180    /// If len is greater than the buffer’s current length, this has no effect.
181    ///
182    /// The split_off method can emulate truncate, but this causes the excess bits to be returned
183    /// instead of dropped.
184    pub fn truncate_bytes(&mut self, len: usize) {
185        if len * 8 < self.bit_len {
186            self.bit_len = len * 8;
187        }
188    }
189
190    /// Clears the buffer, removing all data.
191    pub fn clear(&mut self) {
192        self.truncate_bits(0);
193    }
194
195    /// Returns the number of bits contained in this `Bits`
196    pub fn len_bits(&self) -> usize {
197        self.bit_len
198    }
199
200    /// Returns the number of _complete_ bytes contained in this `Bits`.  Note that this `Bits` may
201    /// contain a number of bits that does not evenly divide into bytes: this method returns the
202    /// number of _complete_ bytes, i.e. it does a truncating divide on the number of bits.
203    pub fn len_bytes(&self) -> usize {
204        self.bit_len / 8
205    }
206
207    /// Returns true if the `Bits` has a length of 0.
208    pub fn is_empty(&self) -> bool {
209        self.bit_len == 0
210    }
211
212    /// Move the start point of this view forward by `by` bits.
213    pub(crate) fn inc_start_bits(&mut self, by: usize) {
214        self.bit_len -= by;
215        self.bit_start += by;
216    }
217}
218
219impl Deref for Bits {
220    type Target = BitSlice;
221
222    fn deref(&self) -> &Self::Target {
223        BitSlice::from_slice(&self.inner)[self.bit_start..self.bit_start + self.bit_len].as_ref()
224    }
225}
226
227impl From<BitVec> for Bits {
228    fn from(bv: BitVec) -> Self {
229        // As far as I can tell, the bitvec crate does not give any way to get access to the
230        // underlying bytes _and_ give the offset at which the bitslice/bitvec starts (since it may
231        // not be at the beginning of that underlying storage).  This means we first need to
232        // 'left-align' the data that we get here, and the only way to do that is to copy the bits
233        // into a new bitvec.
234        let bit_len = bv.len();
235        let aligned: BitVec = bv.iter().by_vals().collect();
236        let bytes = aligned.into_vec();
237
238        Self {
239            inner: Bytes::from(bytes),
240            bit_start: 0,
241            bit_len,
242        }
243    }
244}
245
246impl From<&BitSlice> for Bits {
247    fn from(value: &BitSlice) -> Self {
248        Bits::from(value.to_bitvec())
249    }
250}
251
252#[cfg(test)]
253mod tests {
254    use super::*;
255
256    #[test]
257    fn test_copy_from_slice() {
258        // Mutable so we can alter it below to make sure a copy was made
259        let src = bits![mut 1, 0, 1, 1, 0, 1, 0, 0, 1, 1];
260
261        let bits = Bits::copy_from_bit_slice(src);
262
263        assert_eq!(bits.len_bits(), src.len());
264        assert_eq!(src, bits[..]);
265
266        // Ensure the data was copied (not shared)
267        src.set(0, false);
268
269        // Original `bits` should not be affected
270        assert!(bits[0]);
271    }
272
273    #[test]
274    fn test_from_bitslice() {
275        let slice = bits![1, 1, 0, 1, 1, 0];
276        let bits = Bits::from(slice);
277        assert_eq!(bits.len_bits(), 6);
278        assert_eq!(bits[..], bits![1, 1, 0, 1, 1, 0]);
279
280        // Now make sure a slice that came from a non-byte boundary still works
281        let unaligned_slice = &slice[2..];
282        let bits = Bits::from(unaligned_slice);
283        assert_eq!(bits.len_bits(), 4);
284        assert_eq!(bits[..], bits![0, 1, 1, 0]);
285    }
286
287    #[test]
288    fn test_slice() {
289        let bits = Bits::from_static_bytes(&[0b1010_1010, 0b1111_0000]);
290
291        let head = bits.slice_bits(0..4);
292        assert_eq!(head.len_bits(), 4);
293        assert_eq!(head[..], bits!(1, 0, 1, 0));
294
295        let mid = bits.slice_bits(4..12);
296        assert_eq!(mid.len_bits(), 8);
297        assert_eq!(mid[..], bits!(1, 0, 1, 0, 1, 1, 1, 1));
298
299        let tail = bits.slice_bits(12..16);
300        assert_eq!(tail.len_bits(), 4);
301        assert_eq!(tail[..], bits!(0, 0, 0, 0));
302
303        // A slice which overlaps two existing slices
304        let overlapping = bits.slice_bits(10..14);
305        assert_eq!(overlapping.len_bits(), 4);
306        assert_eq!(overlapping[..], bits!(1, 1, 0, 0));
307
308        // A slice taken from an existing slice who's starting point isn't at a byte boundary
309        let slice_of_slice = overlapping.slice_bits(0..2);
310        assert_eq!(slice_of_slice.len_bits(), 2);
311        assert_eq!(slice_of_slice[..], bits!(1, 1));
312    }
313
314    #[test]
315    fn test_slice_bytes() {
316        #[rustfmt::skip]
317        let bits = Bits::from_static_bytes(&[
318            0b1010_1010,
319            0b1100_1100,
320            0b1110_0011,
321            0b1111_0000,
322        ]);
323
324        let head = bits.slice_bytes(0..2);
325        assert_eq!(head.len_bits(), 16);
326        assert_eq!(
327            head[..],
328            bits!(1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0)
329        );
330
331        let mid = bits.slice_bytes(1..3);
332        assert_eq!(head.len_bits(), 16);
333        assert_eq!(
334            mid[..],
335            bits!(1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1)
336        );
337
338        // Grab a bitslice that starts at a non-byte boundary and make sure a byte slice from that
339        // works correctly
340        let bitslice = bits.slice_bits(4..32);
341        let byte_slice_from_bitslice = bitslice.slice_bytes(0..1);
342        assert_eq!(byte_slice_from_bitslice.len_bits(), 8);
343        assert_eq!(byte_slice_from_bitslice[..], bits!(1, 0, 1, 0, 1, 1, 0, 0));
344    }
345
346    #[test]
347    fn test_split_to() {
348        let mut bits = Bits::from_static_bytes(&[0b1010_1010, 0b1111_0000]);
349
350        let head = bits.split_to_bits(7);
351        assert_eq!(head.len_bits(), 7);
352        assert_eq!(bits.len_bits(), 9);
353        assert_eq!(head[..], bits!(1, 0, 1, 0, 1, 0, 1));
354        assert_eq!(bits[..], bits!(0, 1, 1, 1, 1, 0, 0, 0, 0));
355
356        // Split again from what was left over
357        let head = bits.split_to_bits(3);
358        assert_eq!(head.len_bits(), 3);
359        assert_eq!(bits.len_bits(), 6);
360        assert_eq!(head[..], bits!(0, 1, 1));
361        assert_eq!(bits[..], bits!(1, 1, 0, 0, 0, 0));
362    }
363
364    #[test]
365    fn test_split_to_bytes() {
366        #[rustfmt::skip]
367        let mut bits = Bits::from_static_bytes(&[
368            0b1010_1010,
369            0b1100_1100,
370            0b1110_0011,
371            0b1111_0000,
372        ]);
373
374        let head = bits.split_to_bytes(1);
375        assert_eq!(head.len_bits(), 8);
376        assert_eq!(bits.len_bits(), 24);
377        assert_eq!(head[..], bits!(1, 0, 1, 0, 1, 0, 1, 0));
378        assert_eq!(
379            bits[..],
380            bits!(1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0)
381        );
382
383        // Now split on a non-byte boundary
384        let _head = bits.split_to_bits(4);
385        // Then split_bytes on that and make sure it works
386        let head = bits.split_to_bytes(1);
387        assert_eq!(head.len_bits(), 8);
388        assert_eq!(bits.len_bits(), 12);
389        assert_eq!(head[..], bits!(1, 1, 0, 0, 1, 1, 1, 0));
390        assert_eq!(bits[..], bits!(0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0));
391    }
392
393    #[test]
394    fn test_split_off() {
395        let mut bits = Bits::from_static_bytes(&[0b1010_1010, 0b1111_0000]);
396
397        let tail = bits.split_off_bits(7);
398        assert_eq!(bits.len_bits(), 7);
399        assert_eq!(tail.len_bits(), 9);
400        assert_eq!(bits[..], bits!(1, 0, 1, 0, 1, 0, 1));
401        assert_eq!(tail[..], bits!(0, 1, 1, 1, 1, 0, 0, 0, 0));
402
403        // Split again from what was left over
404        let tail = bits.split_off_bits(3);
405        assert_eq!(bits.len_bits(), 3);
406        assert_eq!(tail.len_bits(), 4);
407        assert_eq!(bits[..], bits!(1, 0, 1));
408        assert_eq!(tail[..], bits!(0, 1, 0, 1));
409    }
410
411    #[test]
412    fn test_split_off_bytes() {
413        #[rustfmt::skip]
414        let mut bits = Bits::from_static_bytes(&[
415            0b1010_1010,
416            0b1100_1100,
417            0b1110_0011,
418            0b1111_0000,
419        ]);
420
421        let tail = bits.split_off_bytes(3);
422        // 'tail' is now bits [24, 32), 'bits' is [0, 24)
423        assert_eq!(bits.len_bits(), 24);
424        assert_eq!(tail.len_bits(), 8);
425        assert_eq!(
426            bits[..],
427            bits!(1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1)
428        );
429        assert_eq!(tail[..], bits!(1, 1, 1, 1, 0, 0, 0, 0));
430
431        // Now split on a non-byte boundary
432        let mut tail = bits.split_off_bits(6);
433        // 'tail' is now bits [6, 24), 'bits' is now [0, 6)
434        assert_eq!(bits.len_bits(), 6);
435        assert_eq!(bits[..], bits!(1, 0, 1, 0, 1, 0));
436
437        // Now split_off_bytes on 'tail' to make sure it works
438        let tail_tail = tail.split_off_bytes(1);
439        // 'tail_tail' is now bits [14, 24), 'tail' is [6, 14)
440        assert_eq!(tail_tail.len_bits(), 10);
441        assert_eq!(tail.len_bits(), 8);
442        assert_eq!(tail_tail[..], bits!(0, 0, 1, 1, 1, 0, 0, 0, 1, 1));
443        assert_eq!(tail[..], bits!(1, 0, 1, 1, 0, 0, 1, 1));
444    }
445
446    #[test]
447    fn test_truncate() {
448        #[rustfmt::skip]
449        let mut bits = Bits::from_static_bytes(&[
450            0b1010_1010,
451            0b1100_1100,
452            0b1110_0011,
453            0b1111_0000,
454        ]);
455
456        bits.truncate_bits(10);
457        assert_eq!(bits.len_bits(), 10);
458        assert_eq!(bits[..], bits![1, 0, 1, 0, 1, 0, 1, 0, 1, 1]);
459    }
460
461    #[test]
462    fn test_truncate_bytes() {
463        #[rustfmt::skip]
464        let mut bits = Bits::from_static_bytes(&[
465            0b1010_1010,
466            0b1100_1100,
467            0b1110_0011,
468            0b1111_0000,
469        ]);
470
471        bits.truncate_bytes(2);
472        assert_eq!(bits.len_bits(), 16);
473        assert_eq!(
474            bits[..],
475            bits![1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0]
476        );
477    }
478}