questdb/egress/wire/
bit_reader.rs1use crate::error::{Result, fmt};
32
33pub struct BitReader<'a> {
35 bytes: &'a [u8],
36 byte_pos: usize,
38 window: u64,
40 bits_in_window: u32,
41 bits_read: u64,
43 bits_total: u64,
45}
46
47impl<'a> BitReader<'a> {
48 pub fn new(bytes: &'a [u8]) -> Self {
49 Self {
50 bytes,
51 byte_pos: 0,
52 window: 0,
53 bits_in_window: 0,
54 bits_read: 0,
55 bits_total: (bytes.len() as u64) * 8,
56 }
57 }
58
59 pub fn bit_position(&self) -> u64 {
61 self.bits_read
62 }
63
64 pub fn bytes_consumed(&self) -> usize {
67 self.bits_read.div_ceil(8) as usize
68 }
69
70 #[inline]
72 pub fn read_bit(&mut self) -> Result<u8> {
73 if self.bits_read >= self.bits_total {
74 return Err(fmt!(ProtocolError, "BitReader: read past end"));
75 }
76 if !self.ensure_bits(1) {
77 return Err(fmt!(ProtocolError, "BitReader: read past end"));
78 }
79 let bit = (self.window & 1) as u8;
80 self.window >>= 1;
81 self.bits_in_window -= 1;
82 self.bits_read += 1;
83 Ok(bit)
84 }
85
86 #[inline]
88 pub fn read_bits(&mut self, n: u32) -> Result<u64> {
89 if n == 0 {
90 return Ok(0);
91 }
92 if n > 64 {
93 return Err(fmt!(
94 ProtocolError,
95 "BitReader: cannot read {} bits into u64",
96 n
97 ));
98 }
99 if self.bits_read + n as u64 > self.bits_total {
100 return Err(fmt!(ProtocolError, "BitReader: read past end"));
101 }
102
103 let mut result: u64 = 0;
104 let mut remaining = n;
105 let mut shift: u32 = 0;
106 while remaining > 0 {
107 if self.bits_in_window == 0 {
108 let want = remaining.min(64);
109 if !self.ensure_bits(want) {
110 return Err(fmt!(ProtocolError, "BitReader: read past end"));
111 }
112 }
113 let take = remaining.min(self.bits_in_window);
114 let mask = if take == 64 {
115 u64::MAX
116 } else {
117 (1u64 << take) - 1
118 };
119 result |= (self.window & mask) << shift;
120 if take == 64 {
122 self.window = 0;
123 } else {
124 self.window >>= take;
125 }
126 self.bits_in_window -= take;
127 remaining -= take;
128 shift += take;
129 }
130 self.bits_read += n as u64;
131 Ok(result)
132 }
133
134 #[inline]
136 pub fn read_signed(&mut self, n: u32) -> Result<i64> {
137 let unsigned = self.read_bits(n)?;
138 if n == 0 || n == 64 {
139 return Ok(unsigned as i64);
140 }
141 let sign_bit = 1u64 << (n - 1);
142 let extended = if unsigned & sign_bit != 0 {
143 unsigned | (u64::MAX << n)
144 } else {
145 unsigned
146 };
147 Ok(extended as i64)
148 }
149
150 #[inline]
153 fn ensure_bits(&mut self, want: u32) -> bool {
154 while self.bits_in_window < want
155 && self.bits_in_window <= 56
156 && self.byte_pos < self.bytes.len()
157 {
158 let b = self.bytes[self.byte_pos] as u64;
159 self.byte_pos += 1;
160 self.window |= b << self.bits_in_window;
161 self.bits_in_window += 8;
162 }
163 self.bits_in_window >= want
164 }
165}
166
167#[cfg(test)]
168mod tests {
169 use super::*;
170 use crate::error::ErrorCode;
171
172 #[test]
173 fn single_bits_lsb_first() {
174 let bytes = [0b1010_0001u8];
176 let mut r = BitReader::new(&bytes);
177 let order = [1, 0, 0, 0, 0, 1, 0, 1];
178 for (i, expected) in order.iter().enumerate() {
179 assert_eq!(r.read_bit().unwrap(), *expected, "bit {}", i);
180 }
181 assert_eq!(r.read_bit().unwrap_err().code(), ErrorCode::ProtocolError);
183 }
184
185 #[test]
186 fn read_bits_groups_lsb_first() {
187 let bytes = [0xAC, 0x02];
190 let mut r = BitReader::new(&bytes);
191 assert_eq!(r.read_bits(8).unwrap(), 0xAC);
192 assert_eq!(r.read_bits(4).unwrap(), 0x02);
193 }
194
195 #[test]
196 fn read_bits_spans_byte_boundary() {
197 let bytes = [0xFF, 0x01];
199 let mut r = BitReader::new(&bytes);
200 assert_eq!(r.read_bits(12).unwrap(), 0x1FF);
201 }
202
203 #[test]
204 fn read_signed_sign_extends() {
205 let bytes = [0x40];
207 let mut r = BitReader::new(&bytes);
208 assert_eq!(r.read_signed(7).unwrap(), -64);
209
210 let bytes = [0b0011_1111];
212 let mut r = BitReader::new(&bytes);
213 assert_eq!(r.read_signed(7).unwrap(), 63);
214 }
215
216 #[test]
217 fn read_64_bits_works() {
218 let bytes = 0x0102_0304_0506_0708u64.to_le_bytes();
219 let mut r = BitReader::new(&bytes);
220 assert_eq!(r.read_bits(64).unwrap(), 0x0102_0304_0506_0708);
221 assert!(r.read_bit().is_err()); }
223
224 #[test]
225 fn bit_position_and_bytes_consumed() {
226 let bytes = [0xFFu8, 0xFF, 0xFF];
227 let mut r = BitReader::new(&bytes);
228 let _ = r.read_bits(13).unwrap();
229 assert_eq!(r.bit_position(), 13);
230 assert_eq!(r.bytes_consumed(), 2); }
232
233 #[test]
234 fn n_zero_returns_zero() {
235 let bytes = [0u8; 0];
236 let mut r = BitReader::new(&bytes);
237 assert_eq!(r.read_bits(0).unwrap(), 0);
238 assert_eq!(r.bit_position(), 0);
239 }
240
241 #[test]
242 fn over_64_bits_rejected() {
243 let bytes = [0u8; 16];
244 let mut r = BitReader::new(&bytes);
245 assert_eq!(
246 r.read_bits(65).unwrap_err().code(),
247 ErrorCode::ProtocolError
248 );
249 }
250
251 #[test]
252 fn read_past_end_in_read_bits_errors() {
253 let bytes = [0xFFu8];
254 let mut r = BitReader::new(&bytes);
255 let _ = r.read_bits(7).unwrap();
256 assert!(r.read_bits(2).is_err()); }
258}