1use crate::error::{BitError, BitResult};
4
5#[derive(Debug)]
10pub struct BitReader<'a> {
11 data: &'a [u8],
12 bit_pos: usize,
13}
14
15impl<'a> BitReader<'a> {
16 #[must_use]
18 pub const fn new(data: &'a [u8]) -> Self {
19 Self { data, bit_pos: 0 }
20 }
21
22 #[must_use]
24 pub const fn bits_remaining(&self) -> usize {
25 self.data
26 .len()
27 .saturating_mul(8)
28 .saturating_sub(self.bit_pos)
29 }
30
31 #[must_use]
33 pub const fn is_empty(&self) -> bool {
34 self.bits_remaining() == 0
35 }
36
37 #[must_use]
39 pub const fn bit_position(&self) -> usize {
40 self.bit_pos
41 }
42
43 pub fn read_bit(&mut self) -> BitResult<bool> {
45 if self.bits_remaining() == 0 {
46 return Err(BitError::UnexpectedEof {
47 requested: 1,
48 available: 0,
49 });
50 }
51 let byte_idx = self.bit_pos / 8;
52 let bit_idx = self.bit_pos % 8;
53 let bit = (self.data[byte_idx] >> (7 - bit_idx)) & 1;
54 self.bit_pos += 1;
55 Ok(bit == 1)
56 }
57
58 pub fn read_bits(&mut self, bits: u8) -> BitResult<u64> {
60 if bits > 64 {
61 return Err(BitError::InvalidBitCount { bits, max_bits: 64 });
62 }
63 if bits == 0 {
64 return Ok(0);
65 }
66 if bits as usize > self.bits_remaining() {
67 return Err(BitError::UnexpectedEof {
68 requested: bits as usize,
69 available: self.bits_remaining(),
70 });
71 }
72
73 let mut value = 0u64;
74 for _ in 0..bits {
75 value = (value << 1) | u64::from(self.read_bit()?);
76 }
77 Ok(value)
78 }
79
80 pub fn align_to_byte(&mut self) -> BitResult<()> {
82 let rem = self.bit_pos % 8;
83 if rem == 0 {
84 return Ok(());
85 }
86 let skip = 8 - rem;
87 if skip > self.bits_remaining() {
88 return Err(BitError::UnexpectedEof {
89 requested: skip,
90 available: self.bits_remaining(),
91 });
92 }
93 self.bit_pos += skip;
94 Ok(())
95 }
96
97 pub fn read_u8_aligned(&mut self) -> BitResult<u8> {
99 self.ensure_aligned()?;
100 self.ensure_bits(8)?;
101 let idx = self.bit_pos / 8;
102 let value = self.data[idx];
103 self.bit_pos += 8;
104 Ok(value)
105 }
106
107 pub fn read_u16_aligned(&mut self) -> BitResult<u16> {
109 let bytes = self.read_aligned_bytes::<2>()?;
110 Ok(u16::from_le_bytes(bytes))
111 }
112
113 pub fn read_u32_aligned(&mut self) -> BitResult<u32> {
115 let bytes = self.read_aligned_bytes::<4>()?;
116 Ok(u32::from_le_bytes(bytes))
117 }
118
119 pub fn read_u64_aligned(&mut self) -> BitResult<u64> {
121 let bytes = self.read_aligned_bytes::<8>()?;
122 Ok(u64::from_le_bytes(bytes))
123 }
124
125 pub fn read_varu32(&mut self) -> BitResult<u32> {
127 self.ensure_aligned()?;
128 let mut result = 0u32;
129 for shift in (0..35).step_by(7) {
130 let byte = self.read_u8_aligned()?;
131 result |= u32::from(byte & 0x7F) << shift;
132 if byte & 0x80 == 0 {
133 return Ok(result);
134 }
135 }
136 Err(BitError::InvalidVarint)
137 }
138
139 pub fn read_vars32(&mut self) -> BitResult<i32> {
141 let value = self.read_varu32()?;
142 let decoded = ((value >> 1) as i32) ^ (-((value & 1) as i32));
143 Ok(decoded)
144 }
145
146 fn ensure_aligned(&self) -> BitResult<()> {
147 if self.bit_pos % 8 != 0 {
148 return Err(BitError::MisalignedAccess {
149 bit_position: self.bit_pos,
150 });
151 }
152 Ok(())
153 }
154
155 fn ensure_bits(&self, bits: usize) -> BitResult<()> {
156 let available = self.bits_remaining();
157 if bits > available {
158 return Err(BitError::UnexpectedEof {
159 requested: bits,
160 available,
161 });
162 }
163 Ok(())
164 }
165
166 fn read_aligned_bytes<const N: usize>(&mut self) -> BitResult<[u8; N]> {
167 self.ensure_aligned()?;
168 self.ensure_bits(N * 8)?;
169 let idx = self.bit_pos / 8;
170 let mut out = [0u8; N];
171 out.copy_from_slice(&self.data[idx..idx + N]);
172 self.bit_pos += N * 8;
173 Ok(out)
174 }
175}
176
177#[cfg(test)]
178mod tests {
179 use super::*;
180
181 #[test]
182 fn empty_reader() {
183 let reader = BitReader::new(&[]);
184 assert!(reader.is_empty());
185 assert_eq!(reader.bits_remaining(), 0);
186 assert_eq!(reader.bit_position(), 0);
187 }
188
189 #[test]
190 fn read_from_empty_fails() {
191 let mut reader = BitReader::new(&[]);
192 let result = reader.read_bit();
193 assert!(matches!(result, Err(BitError::UnexpectedEof { .. })));
194 }
195
196 #[test]
197 fn read_bits_across_bytes() {
198 let mut reader = BitReader::new(&[0b1111_0000, 0b0000_1111]);
199 assert_eq!(reader.read_bits(12).unwrap(), 0b1111_0000_0000);
200 assert_eq!(reader.bits_remaining(), 4);
201 }
202
203 #[test]
204 fn read_aligned_u32() {
205 let mut reader = BitReader::new(&[0x78, 0x56, 0x34, 0x12]);
206 assert_eq!(reader.read_u32_aligned().unwrap(), 0x1234_5678);
207 }
208
209 #[test]
210 fn read_misaligned_fails() {
211 let mut reader = BitReader::new(&[0xFF, 0xFF]);
212 reader.read_bits(1).unwrap();
213 let err = reader.read_u8_aligned().unwrap_err();
214 assert!(matches!(err, BitError::MisalignedAccess { .. }));
215 }
216
217 #[test]
218 fn read_varu32() {
219 let mut reader = BitReader::new(&[0xAC, 0x02]);
220 assert_eq!(reader.read_varu32().unwrap(), 300);
221 }
222
223 #[test]
224 fn read_vars32() {
225 let mut reader = BitReader::new(&[0x01]);
226 assert_eq!(reader.read_vars32().unwrap(), -1);
227 }
228
229 #[test]
230 fn read_varu32_invalid() {
231 let mut reader = BitReader::new(&[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01]);
232 let err = reader.read_varu32().unwrap_err();
233 assert!(matches!(err, BitError::InvalidVarint));
234 }
235}