1#[derive(Debug, Clone, PartialEq, Eq)]
8pub enum DecodeError {
9 Truncated,
11 Invalid(&'static str),
13}
14
15impl core::fmt::Display for DecodeError {
16 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
17 match self {
18 DecodeError::Truncated => write!(f, "bitstream truncated"),
19 DecodeError::Invalid(what) => write!(f, "invalid bitstream: {what}"),
20 }
21 }
22}
23
24impl std::error::Error for DecodeError {}
25
26#[derive(Default, Debug, Clone)]
28pub struct ByteWriter {
29 pub buf: Vec<u8>,
31}
32
33impl ByteWriter {
34 pub fn new() -> Self {
36 Self::default()
37 }
38 pub fn u8(&mut self, v: u8) {
40 self.buf.push(v);
41 }
42 pub fn varint(&mut self, mut v: u64) {
44 loop {
45 let b = (v & 0x7f) as u8;
46 v >>= 7;
47 if v == 0 {
48 self.buf.push(b);
49 return;
50 }
51 self.buf.push(b | 0x80);
52 }
53 }
54 pub fn svarint(&mut self, v: i64) {
56 self.varint(zigzag(v));
57 }
58 pub fn f64(&mut self, v: f64) {
60 self.buf.extend_from_slice(&v.to_le_bytes());
61 }
62 pub fn block(&mut self, bytes: &[u8]) {
64 self.varint(bytes.len() as u64);
65 self.buf.extend_from_slice(bytes);
66 }
67 pub fn bytes(&mut self, bytes: &[u8]) {
69 self.buf.extend_from_slice(bytes);
70 }
71}
72
73#[derive(Debug, Clone)]
75pub struct ByteReader<'a> {
76 buf: &'a [u8],
77 pos: usize,
78}
79
80impl<'a> ByteReader<'a> {
81 pub fn new(buf: &'a [u8]) -> Self {
83 Self { buf, pos: 0 }
84 }
85 pub fn position(&self) -> usize {
87 self.pos
88 }
89 pub fn u8(&mut self) -> Result<u8, DecodeError> {
91 let b = *self.buf.get(self.pos).ok_or(DecodeError::Truncated)?;
92 self.pos += 1;
93 Ok(b)
94 }
95 pub fn varint(&mut self) -> Result<u64, DecodeError> {
97 let mut v = 0u64;
98 let mut shift = 0;
99 loop {
100 let b = self.u8()?;
101 if shift >= 64 {
102 return Err(DecodeError::Invalid("varint overflow"));
103 }
104 v |= ((b & 0x7f) as u64) << shift;
105 if b & 0x80 == 0 {
106 return Ok(v);
107 }
108 shift += 7;
109 }
110 }
111 pub fn svarint(&mut self) -> Result<i64, DecodeError> {
113 Ok(unzigzag(self.varint()?))
114 }
115 pub fn f64(&mut self) -> Result<f64, DecodeError> {
117 let b = self.take(8)?;
118 Ok(f64::from_le_bytes(b.try_into().unwrap()))
119 }
120 pub fn take(&mut self, n: usize) -> Result<&'a [u8], DecodeError> {
122 let end = self.pos.checked_add(n).ok_or(DecodeError::Truncated)?;
123 let s = self.buf.get(self.pos..end).ok_or(DecodeError::Truncated)?;
124 self.pos = end;
125 Ok(s)
126 }
127 pub fn block(&mut self) -> Result<&'a [u8], DecodeError> {
129 let n = self.varint()? as usize;
130 self.take(n)
131 }
132}
133
134pub fn zigzag(v: i64) -> u64 {
136 ((v << 1) ^ (v >> 63)) as u64
137}
138
139pub fn unzigzag(u: u64) -> i64 {
141 ((u >> 1) as i64) ^ -((u & 1) as i64)
142}
143
144#[derive(Default, Debug, Clone)]
146pub struct BitWriter {
147 buf: Vec<u8>,
148 acc: u64,
149 n: u32,
150}
151
152impl BitWriter {
153 pub fn new() -> Self {
155 Self::default()
156 }
157 pub fn put(&mut self, v: u64, nbits: u32) {
159 debug_assert!(nbits <= 57);
160 if nbits == 0 {
161 return;
162 }
163 self.acc |= (v & ((1u64 << nbits) - 1)) << self.n;
164 self.n += nbits;
165 while self.n >= 8 {
166 self.buf.push(self.acc as u8);
167 self.acc >>= 8;
168 self.n -= 8;
169 }
170 }
171 pub fn finish(mut self) -> Vec<u8> {
173 if self.n > 0 {
174 self.buf.push(self.acc as u8);
175 }
176 self.buf
177 }
178}
179
180#[derive(Debug, Clone)]
182pub struct BitReader<'a> {
183 buf: &'a [u8],
184 pos: usize,
185 acc: u64,
186 n: u32,
187}
188
189impl<'a> BitReader<'a> {
190 pub fn new(buf: &'a [u8]) -> Self {
192 Self {
193 buf,
194 pos: 0,
195 acc: 0,
196 n: 0,
197 }
198 }
199 pub fn get(&mut self, nbits: u32) -> Result<u64, DecodeError> {
201 if nbits == 0 {
202 return Ok(0);
203 }
204 while self.n < nbits {
205 let b = *self.buf.get(self.pos).ok_or(DecodeError::Truncated)?;
206 self.pos += 1;
207 self.acc |= (b as u64) << self.n;
208 self.n += 8;
209 }
210 let v = self.acc & ((1u64 << nbits) - 1);
211 self.acc >>= nbits;
212 self.n -= nbits;
213 Ok(v)
214 }
215}
216
217#[cfg(test)]
218mod tests {
219 use super::*;
220
221 #[test]
222 fn varint_and_zigzag_roundtrip() {
223 let mut w = ByteWriter::new();
224 let vals = [0i64, -1, 1, 63, -64, 1 << 40, i64::MIN + 1, i64::MAX];
225 for &v in &vals {
226 w.svarint(v);
227 }
228 w.f64(-3.25);
229 let mut r = ByteReader::new(&w.buf);
230 for &v in &vals {
231 assert_eq!(r.svarint().unwrap(), v);
232 }
233 assert_eq!(r.f64().unwrap(), -3.25);
234 assert_eq!(r.u8(), Err(DecodeError::Truncated));
235 }
236
237 #[test]
238 fn bits_roundtrip() {
239 let mut w = BitWriter::new();
240 for i in 0..200u64 {
241 w.put(i * 7919, (i % 30) as u32);
242 }
243 let buf = w.finish();
244 let mut r = BitReader::new(&buf);
245 for i in 0..200u64 {
246 let nb = (i % 30) as u32;
247 let mask = if nb == 0 { 0 } else { (1u64 << nb) - 1 };
248 assert_eq!(r.get(nb).unwrap(), (i * 7919) & mask);
249 }
250 }
251}