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}