1use crate::prelude::*;
2use core::{convert::TryInto, fmt::Write, iter::FromIterator};
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 slice = &buffer[*index..*index + 1];
17 *index += 1;
18 i8::from_le_bytes(slice.try_into().unwrap())
19}
20
21pub fn read_u16(buffer: &[u8], index: &mut usize) -> u16 {
22 let slice = &buffer[*index..*index + 2];
23 *index += 2;
24 u16::from_be_bytes(slice.try_into().unwrap())
25}
26pub fn read_i16(buffer: &[u8], index: &mut usize) -> i16 {
27 let slice = &buffer[*index..*index + 2];
28 *index += 2;
29 i16::from_be_bytes(slice.try_into().unwrap())
30}
31
32pub fn read_i32(buffer: &[u8], index: &mut usize) -> i32 {
33 let slice = &buffer[*index..*index + 4];
34 *index += 4;
35 i32::from_be_bytes(slice.try_into().unwrap())
36}
37pub fn read_u32(buffer: &[u8], index: &mut usize) -> u32 {
38 let slice = &buffer[*index..*index + 4];
39 *index += 4;
40 u32::from_be_bytes(slice.try_into().unwrap())
41}
42
43pub fn read_u64(buffer: &[u8], index: &mut usize) -> u64 {
44 let slice = &buffer[*index..*index + 8];
45 *index += 8;
46 u64::from_be_bytes(slice.try_into().unwrap())
47}
48pub fn read_i64(buffer: &[u8], index: &mut usize) -> i64 {
49 let slice = &buffer[*index..*index + 8];
50 *index += 8;
51 i64::from_be_bytes(slice.try_into().unwrap())
52}
53
54pub fn read_f64(buffer: &[u8], index: &mut usize) -> f64 {
55 let slice = &buffer[*index..*index + 8];
56 *index += 8;
57 f64::from_be_bytes(slice.try_into().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 core::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 core::write!(s, "x{zero_count:01X}")
286 .expect("could not parse buffer");
287 } else {
288 i = initial_i;
289 core::write!(s, "{byte:02X}").expect("could not parse buffer");
290 }
291 }
292 else {
294 core::write!(s, "{byte:02X}").expect("could not parse buffer");
295 }
296
297 if !seperator.is_empty() && i < n {
299 s += seperator;
300 }
301 }
302
303 s
304}
305
306pub fn hex_to_buffer(hex: String) -> Vec<u8> {
307 let mut buffer = Vec::<u8>::new();
308
309 for chunk in &hex.chars().chunks(2) {
310 buffer.push(
311 u8::from_str_radix(&String::from_iter(chunk), 16)
312 .expect("invalid hex buffer"),
313 );
314 }
315
316 buffer
317}
318
319pub fn hex_to_buffer_advanced(hex: String, seperator: &str) -> Vec<u8> {
320 let mut buffer = Vec::<u8>::new();
321
322 let raw_hex = hex.replace(seperator, "");
323
324 for chunk in &raw_hex.chars().chunks(2) {
325 let part = &String::from_iter(chunk);
326 if part.starts_with("x") {
327 let count = u8::from_str_radix(part.split_at(1).1, 16)
328 .expect("invalid x shortcut");
329 for _i in 0..count {
330 buffer.push(0);
331 }
332 } else {
333 buffer.push(
334 u8::from_str_radix(part, 16).expect("invalid hex buffer"),
335 );
336 }
337 }
338
339 buffer
340}
341
342#[cfg(test)]
343mod tests {
344 use super::{
345 buffer_to_hex, buffer_to_hex_advanced, hex_to_buffer,
346 hex_to_buffer_advanced,
347 };
348 use crate::prelude::*;
349
350 #[test]
354 pub fn buffer_to_hex_tests() {
355 assert_eq!(buffer_to_hex_advanced(vec![], "_", 0, true), "");
356 assert_eq!(
357 buffer_to_hex_advanced(vec![0x00, 0x00, 0x00], "", 0, true),
358 "x3"
359 );
360 assert_eq!(
361 buffer_to_hex_advanced(
362 vec![
363 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
364 0x00, 0x00, 0x00, 0x00, 0x00
365 ],
366 "",
367 0,
368 true
369 ),
370 "xF"
371 );
372 assert_eq!(
373 buffer_to_hex_advanced(
374 vec![
375 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
376 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa
377 ],
378 "",
379 0,
380 true
381 ),
382 "00xFAA"
383 );
384 assert_eq!(buffer_to_hex(vec![0xaa, 0xbb, 0xcc, 0x00]), "AABBCC00");
385 assert_eq!(
386 buffer_to_hex_advanced(vec![0xaa, 0xbb, 0xcc, 0x00], "-", 0, false),
387 "AA-BB-CC-00"
388 );
389 assert_eq!(
390 buffer_to_hex_advanced(
391 vec![0xaa, 0xbb, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x01],
392 "_",
393 0,
394 false
395 ),
396 "AA_BB_CC_00_00_00_00_01"
397 );
398 assert_eq!(
399 buffer_to_hex_advanced(
400 vec![0xaa, 0xbb, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x01],
401 "_",
402 0,
403 true
404 ),
405 "AA_BB_CC_x4_01"
406 );
407
408 assert_eq!(
409 buffer_to_hex_advanced(vec![0xaa, 0xbb], "-", 4, true),
410 "AA-BB-x2"
411 );
412 assert_eq!(
413 buffer_to_hex_advanced(vec![0xaa, 0xbb, 0xcc], "-", 6, false),
414 "AA-BB-CC-00-00-00"
415 );
416 assert_eq!(
417 buffer_to_hex_advanced(vec![0xaa, 0xbb, 0xcc, 0xdd], "-", 2, false),
418 "AA-BB"
419 );
420 }
421
422 #[test]
426 pub fn hex_to_buffer_tests() {
427 assert_eq!(hex_to_buffer(buffer_to_hex(vec![0x1])), vec![0x1]);
428 assert_eq!(
429 hex_to_buffer(buffer_to_hex(vec![0xaa, 0xbb, 0xcc, 0x00])),
430 vec![0xaa, 0xbb, 0xcc, 0x00]
431 );
432
433 assert_eq!(buffer_to_hex(hex_to_buffer("".to_string())), "");
434 assert_eq!(
435 buffer_to_hex(hex_to_buffer("AABB1122".to_string())),
436 "AABB1122"
437 );
438 assert_eq!(
439 buffer_to_hex(hex_to_buffer_advanced(
440 "AA-BB-11-22".to_string(),
441 "-"
442 )),
443 "AABB1122"
444 );
445 assert_eq!(
446 buffer_to_hex_advanced(
447 hex_to_buffer_advanced("AA-BB-11-22".to_string(), "-"),
448 "-",
449 0,
450 false
451 ),
452 "AA-BB-11-22"
453 );
454
455 assert_eq!(
456 hex_to_buffer_advanced("AA-BB-11-22".to_string(), "-"),
457 vec![0xAA, 0xBB, 0x11, 0x22]
458 );
459 assert_eq!(
460 hex_to_buffer_advanced("AABB1122".to_string(), ""),
461 vec![0xAA, 0xBB, 0x11, 0x22]
462 );
463 }
464}