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