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
79fn 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(¤t_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(¤t_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]; 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); let result = read_small_dynamic_unsigned(&bytes, &mut pos, &mut bits, bit_count).unwrap();
183 assert_eq!(result, 5); }
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; 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; 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}