Skip to main content

bit_buf/
buf.rs

1use crate::{Storage, StorageMut};
2
3/// The main structure
4///
5/// Keeps track of the data storage and a cursor for automatic operations
6#[derive(Debug)]
7pub struct BitBuf<S> {
8  data: S,
9  cursor: usize,
10}
11
12impl<S> BitBuf<S> {
13  /// Construct from provided data storage
14  pub const fn from(data: S) -> Self {
15    Self { data, cursor: 0 }
16  }
17
18  /// Get the underlying bytes from the storage
19  #[inline(always)]
20  pub fn bytes(&self) -> &[u8]
21  where
22    S: Storage,
23  {
24    self.data.as_bytes()
25  }
26
27  /// Get the underlying bytes from the storage
28  #[inline(always)]
29  pub fn bytes_mut(&mut self) -> &mut [u8]
30  where
31    S: StorageMut,
32  {
33    self.data.as_bytes_mut()
34  }
35
36  /// Get the internal cursor for automatic operations
37  ///
38  /// <div class="warning">
39  ///
40  /// The cursor may not be within storage bounds
41  ///
42  /// </div>
43  #[inline(always)]
44  pub fn pos(&self) -> usize {
45    self.cursor
46  }
47
48  /// Get the byte-aligned position of the internal cursor for automatic operations
49  ///
50  /// <div class="warning">
51  ///
52  /// The cursor may not be within storage bounds
53  ///
54  /// </div>
55  #[inline(always)]
56  pub fn byte_pos(&self) -> usize {
57    self.cursor / 8
58  }
59
60  /// Advance the internal cursor for automatic operations
61  ///
62  /// <div class="warning">
63  ///
64  /// This does not enforce that the cursor stay within storage bounds
65  ///
66  /// </div>
67  #[inline(always)]
68  pub fn advance(&mut self, bits: usize) -> &mut Self {
69    self.cursor += bits;
70    self
71  }
72
73  /// Advance the internal cursor for automatic operations by a number of bytes
74  ///
75  /// <div class="warning">
76  ///
77  /// This does not enforce that the cursor stay within storage bounds
78  ///
79  /// </div>
80  #[inline(always)]
81  pub fn advance_bytes(&mut self, bytes: usize) -> &mut Self {
82    self.advance(bytes * 8)
83  }
84
85  /// Set the internal cursor for automatic operations
86  ///
87  /// <div class="warning">
88  ///
89  /// This does not enforce that the cursor stay within storage bounds
90  ///
91  /// </div>
92  #[inline(always)]
93  pub fn seek(&mut self, offset: usize) -> &mut Self {
94    self.cursor = offset;
95    self
96  }
97
98  /// Set the internal cursor for automatic operations to a byte position
99  ///
100  /// This sets the cursor to `offset * 8` bits.
101  ///
102  /// <div class="warning">
103  ///
104  /// This does not enforce that the cursor stay within storage bounds
105  ///
106  /// </div>
107  #[inline(always)]
108  pub fn seek_byte(&mut self, byte: usize) -> &mut Self {
109    self.seek(byte * 8)
110  }
111
112  /// Checks if the internal cursor for automatic operations is aligned on the start of a byte
113  ///
114  /// <div class="warning">
115  ///
116  /// This does not care whether the cursor is outside storage bounds
117  ///
118  /// </div>
119  #[inline(always)]
120  pub fn is_aligned(&self) -> bool {
121    self.cursor.is_multiple_of(8)
122  }
123}