griffin_core/pallas_codec/flat/decode/decoder.rs
1use super::Decode;
2use super::Error;
3use crate::pallas_codec::flat::zigzag::ZigZag;
4use alloc::{string::String, vec::Vec};
5
6use num_bigint::{BigInt, BigUint};
7
8#[derive(Debug)]
9pub struct Decoder<'b> {
10 pub buffer: &'b [u8],
11 pub used_bits: i64,
12 pub pos: usize,
13}
14
15impl<'b> Decoder<'b> {
16 pub fn new(bytes: &'b [u8]) -> Decoder<'b> {
17 Decoder {
18 buffer: bytes,
19 pos: 0,
20 used_bits: 0,
21 }
22 }
23
24 /// Decode any type that implements [`Decode`].
25 pub fn decode<T: Decode<'b>>(&mut self) -> Result<T, Error> {
26 T::decode(self)
27 }
28
29 /// Decode an isize integer.
30 ///
31 /// This is byte alignment agnostic.
32 /// First we decode the next 8 bits of the buffer.
33 /// We take the 7 least significant bits as the 7 least significant bits of
34 /// the current unsigned integer. If the most significant bit of the 8
35 /// bits is 1 then we take the next 8 and repeat the process above,
36 /// filling in the next 7 least significant bits of the unsigned integer and
37 /// so on. If the most significant bit was instead 0 we stop decoding
38 /// any more bits. Finally we use zigzag to convert the unsigned integer
39 /// back to a signed integer.
40 pub fn integer(&mut self) -> Result<isize, Error> {
41 Ok(self.word()?.zigzag())
42 }
43
44 /// Decode an integer of an arbitrary size..
45 ///
46 /// This is byte alignment agnostic.
47 /// First we decode the next 8 bits of the buffer.
48 /// We take the 7 least significant bits as the 7 least significant bits of
49 /// the current unsigned integer. If the most significant bit of the 8
50 /// bits is 1 then we take the next 8 and repeat the process above,
51 /// filling in the next 7 least significant bits of the unsigned integer and
52 /// so on. If the most significant bit was instead 0 we stop decoding
53 /// any more bits. Finally we use zigzag to convert the unsigned integer
54 /// back to a signed integer.
55 pub fn big_integer(&mut self) -> Result<BigInt, Error> {
56 Ok(self.big_word()?.zigzag())
57 }
58
59 /// Decode a single bit of the buffer to get a bool.
60 /// We mask out a single bit of the buffer based on used bits.
61 /// and check if it is 0 for false or 1 for true.
62 // TODO: use bit() instead of this custom implementation.
63 pub fn bool(&mut self) -> Result<bool, Error> {
64 let current_byte = self.buffer[self.pos];
65 let b = 0 != (current_byte & (128 >> self.used_bits));
66 self.increment_buffer_by_bit();
67 Ok(b)
68 }
69
70 /// Decode a byte from the buffer.
71 /// This byte alignment agnostic.
72 /// We use the next 8 bits in the buffer and return the resulting byte.
73 pub fn u8(&mut self) -> Result<u8, Error> {
74 self.bits8(8)
75 }
76
77 /// Decode a byte array.
78 /// Decodes a filler to byte align the buffer,
79 /// then decodes the next byte to get the array length up to a max of 255.
80 /// We decode bytes equal to the array length to form the byte array.
81 /// If the following byte for array length is not 0 we decode it and repeat
82 /// above to continue decoding the byte array. We stop once we hit a
83 /// byte array length of 0. If array length is 0 for first byte array
84 /// length the we return a empty array.
85 pub fn bytes(&mut self) -> Result<Vec<u8>, Error> {
86 self.filler()?;
87 self.byte_array()
88 }
89
90 /// Decode a 32 bit char.
91 /// This is byte alignment agnostic.
92 /// First we decode the next 8 bits of the buffer.
93 /// We take the 7 least significant bits as the 7 least significant bits of
94 /// the current unsigned integer. If the most significant bit of the 8
95 /// bits is 1 then we take the next 8 and repeat the process above,
96 /// filling in the next 7 least significant bits of the unsigned integer and
97 /// so on. If the most significant bit was instead 0 we stop decoding
98 /// any more bits.
99 pub fn char(&mut self) -> Result<char, Error> {
100 let character = self.word()? as u32;
101
102 char::from_u32(character).ok_or(Error::DecodeChar(character))
103 }
104
105 // TODO: Do we need this?
106 // pub fn string(&mut self) -> Result<String, Error> {
107 // let mut s = String::new();
108 // while self.bit()? {
109 // s += &self.char()?.to_string();
110 // }
111 // Ok(s)
112 // }
113
114 /// Decode a string.
115 /// Convert to byte array and then use byte array decoding.
116 /// Decodes a filler to byte align the buffer,
117 /// then decodes the next byte to get the array length up to a max of 255.
118 /// We decode bytes equal to the array length to form the byte array.
119 /// If the following byte for array length is not 0 we decode it and repeat
120 /// above to continue decoding the byte array. We stop once we hit a
121 /// byte array length of 0. If array length is 0 for first byte array
122 /// length the we return a empty array.
123 pub fn utf8(&mut self) -> Result<String, Error> {
124 // TODO: Better Error Handling
125 String::from_utf8(Vec::<u8>::decode(self)?).map_err(Error::from)
126 }
127
128 /// Decodes a filler of max one byte size.
129 /// Decodes bits until we hit a bit that is 1.
130 /// Expects that the 1 is at the end of the current byte in the buffer.
131 pub fn filler(&mut self) -> Result<(), Error> {
132 while self.zero()? {}
133 Ok(())
134 }
135
136 /// Decode a word of any size.
137 /// This is byte alignment agnostic.
138 /// First we decode the next 8 bits of the buffer.
139 /// We take the 7 least significant bits as the 7 least significant bits of
140 /// the current unsigned integer. If the most significant bit of the 8
141 /// bits is 1 then we take the next 8 and repeat the process above,
142 /// filling in the next 7 least significant bits of the unsigned integer and
143 /// so on. If the most significant bit was instead 0 we stop decoding
144 /// any more bits.
145 pub fn word(&mut self) -> Result<usize, Error> {
146 let mut leading_bit = 1;
147 let mut final_word: usize = 0;
148 let mut shl: usize = 0;
149 // continue looping if lead bit is 1 which is 128 as a u8 otherwise exit
150 while leading_bit > 0 {
151 let word8 = self.bits8(8)?;
152 let word7 = word8 & 127;
153 final_word |= (word7 as usize) << shl;
154 shl += 7;
155 leading_bit = word8 & 128;
156 }
157 Ok(final_word)
158 }
159
160 /// Decode a word of 128 bits size.
161 /// This is byte alignment agnostic.
162 /// First we decode the next 8 bits of the buffer.
163 /// We take the 7 least significant bits as the 7 least significant bits of
164 /// the current unsigned integer. If the most significant bit of the 8
165 /// bits is 1 then we take the next 8 and repeat the process above,
166 /// filling in the next 7 least significant bits of the unsigned integer and
167 /// so on. If the most significant bit was instead 0 we stop decoding
168 /// any more bits.
169 pub fn big_word(&mut self) -> Result<BigUint, Error> {
170 let mut leading_bit = 1;
171 let mut final_word: BigUint = (0_u8).into();
172 let mut shl: u128 = 0;
173 // continue looping if lead bit is 1 which is 128 as a u8 otherwise exit
174 while leading_bit > 0 {
175 let word8 = self.bits8(8)?;
176 let word7 = word8 & 127;
177 final_word |= <u8 as Into<BigUint>>::into(word7) << shl;
178 shl += 7;
179 leading_bit = word8 & 128;
180 }
181 Ok(final_word)
182 }
183
184 /// Decode a list of items with a decoder function.
185 /// This is byte alignment agnostic.
186 /// Decode a bit from the buffer.
187 /// If 0 then stop.
188 /// Otherwise we decode an item in the list with the decoder function passed
189 /// in. Then decode the next bit in the buffer and repeat above.
190 /// Returns a list of items decoded with the decoder function.
191 pub fn decode_list_with<T, F>(&mut self, decoder_func: F) -> Result<Vec<T>, Error>
192 where
193 F: Copy + FnOnce(&mut Decoder) -> Result<T, Error>,
194 {
195 let mut vec_array: Vec<T> = Vec::new();
196 while self.bit()? {
197 vec_array.push(decoder_func(self)?)
198 }
199 Ok(vec_array)
200 }
201
202 pub fn decode_list_with_debug<T, F>(
203 &mut self,
204 decoder_func: F,
205 state_log: &mut Vec<String>,
206 ) -> Result<Vec<T>, Error>
207 where
208 F: Copy + FnOnce(&mut Decoder, &mut Vec<String>) -> Result<T, Error>,
209 {
210 let mut vec_array: Vec<T> = Vec::new();
211 while self.bit()? {
212 vec_array.push(decoder_func(self, state_log)?)
213 }
214 Ok(vec_array)
215 }
216
217 /// Decode the next bit in the buffer.
218 /// If the bit was 0 then return true.
219 /// Otherwise return false.
220 /// Throws EndOfBuffer error if used at the end of the array.
221 fn zero(&mut self) -> Result<bool, Error> {
222 let current_bit = self.bit()?;
223
224 Ok(!current_bit)
225 }
226
227 /// Decode the next bit in the buffer.
228 /// If the bit was 1 then return true.
229 /// Otherwise return false.
230 /// Throws EndOfBuffer error if used at the end of the array.
231 fn bit(&mut self) -> Result<bool, Error> {
232 if self.pos >= self.buffer.len() {
233 return Err(Error::EndOfBuffer);
234 }
235
236 let b = self.buffer[self.pos] & (128 >> self.used_bits) > 0;
237
238 self.increment_buffer_by_bit();
239
240 Ok(b)
241 }
242
243 /// Decode a byte array.
244 /// Throws a BufferNotByteAligned error if the buffer is not byte aligned
245 /// Decodes the next byte to get the array length up to a max of 255.
246 /// We decode bytes equal to the array length to form the byte array.
247 /// If the following byte for array length is not 0 we decode it and repeat
248 /// above to continue decoding the byte array. We stop once we hit a
249 /// byte array length of 0. If array length is 0 for first byte array
250 /// length the we return a empty array.
251 fn byte_array(&mut self) -> Result<Vec<u8>, Error> {
252 if self.used_bits != 0 {
253 return Err(Error::BufferNotByteAligned);
254 }
255
256 self.ensure_bytes(1)?;
257
258 let mut blk_len = self.buffer[self.pos];
259
260 self.pos += 1;
261
262 let mut blk_array: Vec<u8> = Vec::new();
263
264 while blk_len != 0 {
265 self.ensure_bytes(blk_len as usize + 1)?;
266
267 let decoded_array = &self.buffer[self.pos..self.pos + blk_len as usize];
268
269 blk_array.extend(decoded_array);
270
271 self.pos += blk_len as usize;
272
273 blk_len = self.buffer[self.pos];
274
275 self.pos += 1
276 }
277
278 Ok(blk_array)
279 }
280
281 /// Decode up to 8 bits.
282 /// This is byte alignment agnostic.
283 /// If num_bits is greater than the 8 we throw an IncorrectNumBits error.
284 /// First we decode the next num_bits of bits in the buffer.
285 /// If there are less unused bits in the current byte in the buffer than
286 /// num_bits, then we decode the remaining bits from the most
287 /// significant bits in the next byte in the buffer. Otherwise we decode
288 /// the unused bits from the current byte. Returns the decoded value up
289 /// to a byte in size.
290 pub fn bits8(&mut self, num_bits: usize) -> Result<u8, Error> {
291 if num_bits > 8 {
292 return Err(Error::IncorrectNumBits);
293 }
294
295 self.ensure_bits(num_bits)?;
296
297 let unused_bits = 8 - self.used_bits as usize;
298 let leading_zeroes = 8 - num_bits;
299 let r = (self.buffer[self.pos] << self.used_bits as usize) >> leading_zeroes;
300
301 let x = if num_bits > unused_bits {
302 r | (self.buffer[self.pos + 1] >> (unused_bits + leading_zeroes))
303 } else {
304 r
305 };
306
307 self.drop_bits(num_bits);
308
309 Ok(x)
310 }
311
312 /// Ensures the buffer has the required bytes passed in by required_bytes.
313 /// Throws a NotEnoughBytes error if there are less bytes remaining in the
314 /// buffer than required_bytes.
315 fn ensure_bytes(&mut self, required_bytes: usize) -> Result<(), Error> {
316 if required_bytes as isize > self.buffer.len() as isize - self.pos as isize {
317 Err(Error::NotEnoughBytes(required_bytes))
318 } else {
319 Ok(())
320 }
321 }
322
323 /// Ensures the buffer has the required bits passed in by required_bits.
324 /// Throws a NotEnoughBits error if there are less bits remaining in the
325 /// buffer than required_bits.
326 fn ensure_bits(&mut self, required_bits: usize) -> Result<(), Error> {
327 if required_bits as isize
328 > (self.buffer.len() as isize - self.pos as isize) * 8 - self.used_bits as isize
329 {
330 Err(Error::NotEnoughBits(required_bits))
331 } else {
332 Ok(())
333 }
334 }
335
336 /// Increment buffer by num_bits.
337 /// If num_bits + used bits is greater than 8,
338 /// then increment position by (num_bits + used bits) / 8
339 /// Use the left over remainder as the new amount of used bits.
340 fn drop_bits(&mut self, num_bits: usize) {
341 let all_used_bits = num_bits as i64 + self.used_bits;
342 self.used_bits = all_used_bits % 8;
343 self.pos += all_used_bits as usize / 8;
344 }
345
346 /// Increment used bits by 1.
347 /// If all 8 bits are used then increment buffer position by 1.
348 fn increment_buffer_by_bit(&mut self) {
349 if self.used_bits == 7 {
350 self.pos += 1;
351 self.used_bits = 0;
352 } else {
353 self.used_bits += 1;
354 }
355 }
356}