1use byteorder::{LittleEndian, ReadBytesExt};
2use core::fmt::Write;
3use itertools::Itertools;
4
5pub fn read_u8(buffer: &[u8], index: &mut usize) -> u8 {
10 let val = buffer[*index];
11 *index += 1;
12 val
13}
14
15pub fn read_i8(buffer: &[u8], index: &mut usize) -> i8 {
16 let mut slice = &buffer[*index..*index + 1];
17 *index += 1;
18 slice.read_i8().unwrap()
19}
20
21pub fn read_u16(buffer: &[u8], index: &mut usize) -> u16 {
22 let mut slice = &buffer[*index..*index + 2];
23 *index += 2;
24 slice.read_u16::<LittleEndian>().unwrap()
25}
26pub fn read_i16(buffer: &[u8], index: &mut usize) -> i16 {
27 let mut slice = &buffer[*index..*index + 2];
28 *index += 2;
29 slice.read_i16::<LittleEndian>().unwrap()
30}
31
32pub fn read_i32(buffer: &[u8], index: &mut usize) -> i32 {
33 let mut slice = &buffer[*index..*index + 4];
34 *index += 4;
35 slice.read_i32::<LittleEndian>().unwrap()
36}
37pub fn read_u32(buffer: &[u8], index: &mut usize) -> u32 {
38 let mut slice = &buffer[*index..*index + 4];
39 *index += 4;
40 slice.read_u32::<LittleEndian>().unwrap()
41}
42
43pub fn read_u64(buffer: &[u8], index: &mut usize) -> u64 {
44 let mut slice = &buffer[*index..*index + 8];
45 *index += 8;
46 slice.read_u64::<LittleEndian>().unwrap()
47}
48pub fn read_i64(buffer: &[u8], index: &mut usize) -> i64 {
49 let mut slice = &buffer[*index..*index + 8];
50 *index += 8;
51 slice.read_i64::<LittleEndian>().unwrap()
52}
53
54pub fn read_f64(buffer: &[u8], index: &mut usize) -> f64 {
55 let mut slice = &buffer[*index..*index + 8];
56 *index += 8;
57 slice.read_f64::<LittleEndian>().unwrap()
58}
59
60pub fn read_string_utf8(
61 buffer: &[u8],
62 index: &mut usize,
63 size: usize,
64) -> String {
65 let end = if *index + size > buffer.len() {
67 buffer.len()
68 } else {
69 *index + size
70 };
71 let slice = &buffer[*index..end];
72 *index = end;
73 String::from_utf8(slice.to_vec())
74 .unwrap_or("⎣INVALID UTF8 STRING⎤".to_string())
75}
76
77pub fn read_vec_slice(
78 buffer: &[u8],
79 index: &mut usize,
80 size: usize,
81) -> Vec<u8> {
82 let slice = &buffer[*index..*index + size];
83 *index += size;
84 slice.to_vec()
85}
86
87pub fn read_slice<'a, const SIZE: usize>(
88 buffer: &'a [u8],
89 index: &mut usize,
90) -> &'a [u8; SIZE] {
91 let slice = &buffer[*index..*index + SIZE];
92 *index += SIZE;
93 slice.try_into().unwrap()
94}
95
96pub fn write_u8(buffer: &mut [u8], index: &mut usize, val: u8) {
102 buffer[*index] = val;
103 *index += 1;
104}
105pub fn append_u8(buffer: &mut Vec<u8>, val: u8) {
106 buffer.extend_from_slice(&[val]);
107}
108pub fn write_i8(buffer: &mut [u8], index: &mut usize, val: i8) {
109 let bytes = val.to_le_bytes();
110 for b in bytes {
111 buffer[*index] = b;
112 *index += 1;
113 }
114}
115pub fn append_i8(buffer: &mut Vec<u8>, val: i8) {
116 buffer.extend_from_slice(&val.to_le_bytes());
117}
118
119pub fn write_u16(buffer: &mut [u8], index: &mut usize, val: u16) {
120 let bytes = val.to_le_bytes();
121 for b in bytes {
122 buffer[*index] = b;
123 *index += 1;
124 }
125}
126pub fn write_u32(buffer: &mut [u8], index: &mut usize, val: u32) {
127 let bytes = val.to_le_bytes();
128 for b in bytes {
129 buffer[*index] = b;
130 *index += 1;
131 }
132}
133
134pub fn set_bit(buffer: &mut [u8], byte_index: usize, bit_position: u8) {
135 buffer[byte_index] |= 1 << bit_position;
136}
137
138pub fn clear_bit(buffer: &mut [u8], byte_index: usize, bit_position: u8) {
139 if byte_index < buffer.len() && bit_position < 8 {
140 buffer[byte_index] &= !(1 << bit_position);
141 }
142}
143
144pub fn toggle_bit(buffer: &mut [u8], byte_index: usize, bit_position: u8) {
145 if byte_index < buffer.len() && bit_position < 8 {
146 buffer[byte_index] ^= 1 << bit_position;
147 }
148}
149
150pub fn append_u16(buffer: &mut Vec<u8>, val: u16) {
160 buffer.extend_from_slice(&val.to_le_bytes());
161}
162pub fn write_i16(buffer: &mut [u8], index: &mut usize, val: i16) {
163 let bytes = val.to_le_bytes();
164 for b in bytes {
165 buffer[*index] = b;
166 *index += 1;
167 }
168}
169pub fn append_i16(buffer: &mut Vec<u8>, val: i16) {
170 buffer.extend_from_slice(&val.to_le_bytes());
171}
172
173pub fn append_u32(buffer: &mut Vec<u8>, val: u32) {
174 buffer.extend_from_slice(&val.to_le_bytes());
175}
176pub fn write_i32(buffer: &mut [u8], index: &mut usize, val: i32) {
177 let bytes = val.to_le_bytes();
178 for b in bytes {
179 buffer[*index] = b;
180 *index += 1;
181 }
182}
183pub fn append_i32(buffer: &mut Vec<u8>, val: i32) {
184 buffer.extend_from_slice(&val.to_le_bytes());
185}
186
187pub fn write_u64(buffer: &mut [u8], index: &mut usize, val: u64) {
188 let bytes = val.to_le_bytes();
189 for b in bytes {
190 buffer[*index] = b;
191 *index += 1;
192 }
193}
194pub fn append_u64(buffer: &mut Vec<u8>, val: u64) {
195 buffer.extend_from_slice(&val.to_le_bytes());
196}
197pub fn write_i64(buffer: &mut [u8], index: &mut usize, val: i64) {
198 let bytes = val.to_le_bytes();
199 for b in bytes {
200 buffer[*index] = b;
201 *index += 1;
202 }
203}
204pub fn append_i64(buffer: &mut Vec<u8>, val: i64) {
205 buffer.extend_from_slice(&val.to_le_bytes());
206}
207pub fn append_i128(buffer: &mut Vec<u8>, val: i128) {
208 buffer.extend_from_slice(&val.to_le_bytes());
209}
210pub fn append_u128(buffer: &mut Vec<u8>, val: u128) {
211 buffer.extend_from_slice(&val.to_le_bytes());
212}
213
214pub fn write_f64(buffer: &mut [u8], index: &mut usize, val: f64) {
215 let bytes = val.to_le_bytes();
216 for b in bytes {
217 buffer[*index] = b;
218 *index += 1;
219 }
220}
221pub fn append_f64(buffer: &mut Vec<u8>, val: f64) {
222 buffer.extend_from_slice(&val.to_le_bytes());
223}
224
225pub fn append_f32(buffer: &mut Vec<u8>, val: f32) {
226 buffer.extend_from_slice(&val.to_le_bytes());
227}
228
229pub fn append_string_utf8(buffer: &mut Vec<u8>, val: &str) {
230 buffer.extend_from_slice(val.as_bytes());
231}
232
233pub fn buffer_to_hex(buffer: Vec<u8>) -> String {
236 let n = buffer.len();
237
238 let mut s = String::with_capacity(2 * n);
239 for byte in buffer {
240 write!(s, "{byte:02X}").expect("could not parse buffer")
241 }
242 s
243}
244
245pub fn buffer_to_hex_advanced(
251 buffer: Vec<u8>,
252 seperator: &str,
253 pad_size_bytes: usize,
254 x_shorthand: bool,
255) -> String {
256 let n = if pad_size_bytes == 0 {
257 buffer.len()
258 } else {
259 pad_size_bytes
260 };
261
262 let buf_len = buffer.len();
263
264 let mut s = String::with_capacity(2 * n);
265 let mut i = 0;
266 while i < n {
267 let byte = if i < buf_len { buffer[i] } else { 0 };
269 i += 1;
270 if x_shorthand
272 && byte == 0
273 && i < n
274 && if i < buf_len { buffer[i] } else { 0 } == 0
275 {
276 let mut zero_count: u8 = 2;
277 let initial_i = i;
278 while i + 1 < n && buffer[i + 1] == 0 {
279 i += 1;
280 zero_count += 1;
281 }
282 if zero_count <= 0xf {
284 i += 1;
285 write!(s, "x{zero_count:01X}").expect("could not parse buffer");
286 } else {
287 i = initial_i;
288 write!(s, "{byte:02X}").expect("could not parse buffer");
289 }
290 }
291 else {
293 write!(s, "{byte:02X}").expect("could not parse buffer");
294 }
295
296 if !seperator.is_empty() && i < n {
298 s += seperator;
299 }
300 }
301
302 s
303}
304
305pub fn hex_to_buffer(hex: String) -> Vec<u8> {
306 let mut buffer = Vec::<u8>::new();
307
308 for chunk in &hex.chars().chunks(2) {
309 buffer.push(
310 u8::from_str_radix(&String::from_iter(chunk), 16)
311 .expect("invalid hex buffer"),
312 );
313 }
314
315 buffer
316}
317
318pub fn hex_to_buffer_advanced(hex: String, seperator: &str) -> Vec<u8> {
319 let mut buffer = Vec::<u8>::new();
320
321 let raw_hex = hex.replace(seperator, "");
322
323 for chunk in &raw_hex.chars().chunks(2) {
324 let part = &String::from_iter(chunk);
325 if part.starts_with("x") {
326 let count = u8::from_str_radix(part.split_at(1).1, 16)
327 .expect("invalid x shortcut");
328 for _i in 0..count {
329 buffer.push(0);
330 }
331 } else {
332 buffer.push(
333 u8::from_str_radix(part, 16).expect("invalid hex buffer"),
334 );
335 }
336 }
337
338 buffer
339}
340
341#[cfg(test)]
342mod tests {
343 use super::{
344 buffer_to_hex, buffer_to_hex_advanced, hex_to_buffer,
345 hex_to_buffer_advanced,
346 };
347
348 #[test]
352 pub fn buffer_to_hex_tests() {
353 assert_eq!(buffer_to_hex_advanced(vec![], "_", 0, true), "");
354 assert_eq!(
355 buffer_to_hex_advanced(vec![0x00, 0x00, 0x00], "", 0, true),
356 "x3"
357 );
358 assert_eq!(
359 buffer_to_hex_advanced(
360 vec![
361 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
362 0x00, 0x00, 0x00, 0x00, 0x00
363 ],
364 "",
365 0,
366 true
367 ),
368 "xF"
369 );
370 assert_eq!(
371 buffer_to_hex_advanced(
372 vec![
373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
374 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa
375 ],
376 "",
377 0,
378 true
379 ),
380 "00xFAA"
381 );
382 assert_eq!(buffer_to_hex(vec![0xaa, 0xbb, 0xcc, 0x00]), "AABBCC00");
383 assert_eq!(
384 buffer_to_hex_advanced(vec![0xaa, 0xbb, 0xcc, 0x00], "-", 0, false),
385 "AA-BB-CC-00"
386 );
387 assert_eq!(
388 buffer_to_hex_advanced(
389 vec![0xaa, 0xbb, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x01],
390 "_",
391 0,
392 false
393 ),
394 "AA_BB_CC_00_00_00_00_01"
395 );
396 assert_eq!(
397 buffer_to_hex_advanced(
398 vec![0xaa, 0xbb, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x01],
399 "_",
400 0,
401 true
402 ),
403 "AA_BB_CC_x4_01"
404 );
405
406 assert_eq!(
407 buffer_to_hex_advanced(vec![0xaa, 0xbb], "-", 4, true),
408 "AA-BB-x2"
409 );
410 assert_eq!(
411 buffer_to_hex_advanced(vec![0xaa, 0xbb, 0xcc], "-", 6, false),
412 "AA-BB-CC-00-00-00"
413 );
414 assert_eq!(
415 buffer_to_hex_advanced(vec![0xaa, 0xbb, 0xcc, 0xdd], "-", 2, false),
416 "AA-BB"
417 );
418 }
419
420 #[test]
424 pub fn hex_to_buffer_tests() {
425 assert_eq!(hex_to_buffer(buffer_to_hex(vec![0x1])), vec![0x1]);
426 assert_eq!(
427 hex_to_buffer(buffer_to_hex(vec![0xaa, 0xbb, 0xcc, 0x00])),
428 vec![0xaa, 0xbb, 0xcc, 0x00]
429 );
430
431 assert_eq!(buffer_to_hex(hex_to_buffer("".to_string())), "");
432 assert_eq!(
433 buffer_to_hex(hex_to_buffer("AABB1122".to_string())),
434 "AABB1122"
435 );
436 assert_eq!(
437 buffer_to_hex(hex_to_buffer_advanced(
438 "AA-BB-11-22".to_string(),
439 "-"
440 )),
441 "AABB1122"
442 );
443 assert_eq!(
444 buffer_to_hex_advanced(
445 hex_to_buffer_advanced("AA-BB-11-22".to_string(), "-"),
446 "-",
447 0,
448 false
449 ),
450 "AA-BB-11-22"
451 );
452
453 assert_eq!(
454 hex_to_buffer_advanced("AA-BB-11-22".to_string(), "-"),
455 vec![0xAA, 0xBB, 0x11, 0x22]
456 );
457 assert_eq!(
458 hex_to_buffer_advanced("AABB1122".to_string(), ""),
459 vec![0xAA, 0xBB, 0x11, 0x22]
460 );
461 }
462}