binary_codec/
dynamics.rs

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