binary_codec/
serializers.rs

1use crate::{encodings::ZigZag, DeserializationError, SerializationError};
2
3pub fn read_small_dynamic_unsigned(
4    bytes: &[u8],
5    pos: &mut usize,
6    bits: &mut u8,
7    bit_count: u8,
8) -> Result<u8, DeserializationError> {
9    read_small_dynamic(bytes, pos, bits, bit_count)
10}
11
12pub fn read_small_dynamic_signed(
13    bytes: &[u8],
14    pos: &mut usize,
15    bits: &mut u8,
16    bit_count: u8,
17) -> Result<i8, DeserializationError> {
18    let val = read_small_dynamic(bytes, pos, bits, bit_count)?;
19    Ok(ZigZag::to_signed(val))
20}
21
22pub fn write_small_dynamic_unsigned(
23    val: u8,
24    bytes: &mut Vec<u8>,
25    pos: &mut usize,
26    bits: &mut u8,
27    bit_count: u8,
28) -> Result<(), SerializationError> {
29    let max = (1u8 << bit_count) - 1;
30
31    if val > max {
32        return Err(SerializationError::ValueOutOfBounds(val as i32, 0, max as i32));
33    }
34
35    write_small_dynamic(val, bytes, pos, bits, bit_count)
36}
37
38pub fn write_small_dynamic_signed(
39    val: i8,
40    bytes: &mut Vec<u8>,
41    pos: &mut usize,
42    bits: &mut u8,
43    bit_count: u8,
44) -> Result<(), SerializationError> {
45    let min = -(1i8 << (bit_count - 1));
46    let max = (1i8 << (bit_count - 1)) - 1;
47
48    if val < min || val > max {
49        return Err(SerializationError::ValueOutOfBounds(val as i32, min as i32, max as i32));
50    }
51
52    write_small_dynamic(val.to_unsigned(), bytes, pos, bits, bit_count)
53}
54
55pub fn write_bool(
56    val: bool,
57    bytes: &mut Vec<u8>,
58    pos: &mut usize,
59    bits: &mut u8
60) -> Result<(), SerializationError> {
61    let val_u8 = if val { 1 } else { 0 };
62    write_small_dynamic(val_u8, bytes, pos, bits, 1)
63}
64
65pub fn read_bool(
66    bytes: &[u8],
67    pos: &mut usize,
68    bits: &mut u8
69) -> Result<bool, DeserializationError> {
70    let val = read_small_dynamic(bytes, pos, bits, 1)?;
71    Ok(val != 0)
72}
73
74fn create_mask(bits: &u8, bit_count: u8) -> u8 {
75    let mask = (1u8 << bit_count) - 1u8;
76    return mask << *bits;
77}
78
79// returns (bits, next_bits, next_byte)
80fn next_bits_and_byte(bits: u8, bits_needed: u8) -> (u8, u8, bool) {
81    let next_bits = bits + bits_needed;
82    if next_bits > 8 {
83        (0, bits_needed, true)
84    } else if next_bits < 8 {
85        (bits, next_bits, bits == 0)
86    } else {
87        (bits, 0, false)
88    }
89}
90
91fn read_small_dynamic(
92    bytes: &[u8],
93    pos: &mut usize,
94    bits: &mut u8,
95    bit_count: u8
96) -> Result<u8, DeserializationError>
97{
98    let (current_bits, next_bits, next_byte) = next_bits_and_byte(*bits, bit_count);
99    let mask = create_mask(&current_bits, bit_count);
100
101    if next_byte {
102        *pos += 1;
103    }
104
105    let read_pos = if *pos == 0 { 0 } else { *pos - 1 };
106
107    let val = bytes[read_pos];
108    let result = (val & mask) >> current_bits;
109
110    *bits = next_bits;
111    Ok(result)
112}
113
114fn write_small_dynamic(
115    val: u8,
116    bytes: &mut Vec<u8>,
117    pos: &mut usize,
118    bits: &mut u8,
119    bit_count: u8
120) -> Result<(), SerializationError>
121{
122    let (current_bits, next_bits, next_byte) = next_bits_and_byte(*bits, bit_count);
123    let mask = create_mask(&current_bits, bit_count);
124
125    if next_byte {
126        bytes.push(0u8);
127        *pos += 1;
128    }
129
130    bytes[*pos - 1] &= !mask;
131    bytes[*pos - 1] |= (val << current_bits) & mask;
132
133    *bits = next_bits;
134    Ok(())
135}
136
137#[cfg(test)]
138mod tests {
139    use super::*;
140
141    #[test]
142    fn test_write_read_small_dynamic_unsigned() {
143        let mut bytes = Vec::new();
144        let mut pos = 0;
145        let mut bits = 0;
146        let bit_count = 4;
147        let val: u8 = 0b1010;
148        write_small_dynamic_unsigned(val, &mut bytes, &mut pos, &mut bits, bit_count).unwrap();
149        pos = 0;
150        bits = 0;
151        let result = read_small_dynamic_unsigned(&bytes, &mut pos, &mut bits, bit_count).unwrap();
152        assert_eq!(result, val);
153    }
154
155    #[test]
156    fn test_write_read_small_dynamic_signed() {
157        let mut bytes = Vec::new();
158        let mut pos = 0;
159        let mut bits = 0;
160        let bit_count = 4;
161        let val: i8 = -3;
162        write_small_dynamic_signed(val, &mut bytes, &mut pos, &mut bits, bit_count).unwrap();
163        pos = 0;
164        bits = 0;
165        let result = read_small_dynamic_signed(&bytes, &mut pos, &mut bits, bit_count).unwrap();
166        assert_eq!(result, val);
167    }
168
169    #[test]
170    fn test_write_read_small_dynamic_unsigned_existing_byte() {
171        let mut bytes = vec![0b0000_0111]; // 7
172        let mut pos = 1;
173        let mut bits = 4;
174        let bit_count = 4;
175        let val: u8 = 5;
176        write_small_dynamic_unsigned(val, &mut bytes, &mut pos, &mut bits, bit_count).unwrap();
177        assert_eq!(bytes, vec![0b0101_0111]);
178        pos = 0;
179        bits = 0;
180        let result = read_small_dynamic_unsigned(&bytes, &mut pos, &mut bits, bit_count).unwrap();
181        assert_eq!(result, 7); // first 4 bits
182        let result = read_small_dynamic_unsigned(&bytes, &mut pos, &mut bits, bit_count).unwrap();
183        assert_eq!(result, 5); // last 4 bits
184    }
185
186    #[test]
187    fn test_write_small_dynamic_unsigned_out_of_bounds() {
188        let mut bytes = Vec::new();
189        let mut pos = 0;
190        let mut bits = 0;
191        let bit_count = 3;
192        let val: u8 = 0b1000; // 8, out of bounds for 3 bits
193        let result = write_small_dynamic_unsigned(val, &mut bytes, &mut pos, &mut bits, bit_count);
194        assert!(result.is_err());
195    }
196
197    #[test]
198    fn test_write_small_dynamic_signed_out_of_bounds() {
199        let mut bytes = Vec::new();
200        let mut pos = 0;
201        let mut bits = 0;
202        let bit_count = 3;
203        let val: i8 = 5; // out of bounds for 3 bits signed
204        let result = write_small_dynamic_signed(val, &mut bytes, &mut pos, &mut bits, bit_count);
205        assert!(result.is_err());
206    }
207
208    #[test]
209    fn test_write_read_bool_true() {
210        let mut bytes = Vec::new();
211        let mut pos = 0;
212        let mut bits = 0;
213        write_bool(true, &mut bytes, &mut pos, &mut bits).unwrap();
214        pos = 0;
215        bits = 0;
216        let result = read_bool(&bytes, &mut pos, &mut bits).unwrap();
217        assert_eq!(result, true);
218    }
219
220    #[test]
221    fn test_write_read_bool_false() {
222        let mut bytes = Vec::new();
223        let mut pos = 0;
224        let mut bits = 0;
225        write_bool(false, &mut bytes, &mut pos, &mut bits).unwrap();
226        pos = 0;
227        bits = 0;
228        let result = read_bool(&bytes, &mut pos, &mut bits).unwrap();
229        assert_eq!(result, false);
230    }
231
232    #[test]
233    fn test_create_mask_3() {
234        let bits = 2u8;
235        let bit_count = 3u8;
236        let mask = create_mask(&bits, bit_count);
237        assert_eq!(mask, 0b0001_1100);
238    }
239
240    #[test]
241    fn test_create_mask_2() {
242        let bits = 3u8;
243        let bit_count = 2u8;
244        let mask = create_mask(&bits, bit_count);
245        assert_eq!(mask, 0b0001_1000);
246    }
247
248    #[test]
249    fn test_next_bits_and_byte() {
250        let (bits, next_bits, next_byte) = next_bits_and_byte(6, 3);
251        assert_eq!((bits, next_bits, next_byte), (0, 3, true));
252        let (bits, next_bits, next_byte) = next_bits_and_byte(0, 3);
253        assert_eq!((bits, next_bits, next_byte), (0, 3, true));
254           let (bits, next_bits, next_byte) = next_bits_and_byte(8, 1);
255        assert_eq!((bits, next_bits, next_byte), (0, 1, true));
256        let (bits, next_bits, next_byte) = next_bits_and_byte(4, 4);
257        assert_eq!((bits, next_bits, next_byte), (4, 0, false));
258    }
259}