1use super::common::Utils;
4use crate::errors::ByteArrayError;
5use crate::errors::ByteArrayError::{InvalidBinaryChar, InvalidHexChar};
6use alloc::vec;
7use alloc::vec::Vec;
8use core::cmp::PartialEq;
9use core::ops::{Index, IndexMut, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo};
10
11#[derive(Default, PartialEq, Eq, Clone)] pub struct ByteArray {
14 pub(crate) bytes: Vec<u8>,
15}
16
17impl ByteArray {
18 pub fn new() -> Self {
21 ByteArray { bytes: vec![] }
22 }
23
24 pub fn with_capacity(size_in_bytes: usize) -> Self {
26 Self {
27 bytes: Vec::with_capacity(size_in_bytes),
28 }
29 }
30
31 #[deprecated(
57 since = "0.3.3",
58 note = "This will be renamed to with_zeros at a future version"
59 )]
60 pub fn fill_zeros(self) -> Self {
61 if self.bytes.capacity() == 0 {
62 self
63 } else {
64 ByteArray {
65 bytes: vec![0u8; self.bytes.capacity()],
66 }
67 }
68 }
69
70 #[deprecated(
98 since = "0.3.3",
99 note = "This will be renamed to with_value at a future version"
100 )]
101 pub fn fill_with(self, value: u8) -> Self {
102 if self.bytes.capacity() == 0 {
103 self
104 } else {
105 ByteArray {
106 bytes: vec![value; self.bytes.capacity()],
107 }
108 }
109 }
110
111 pub fn from_hex(hex_str: &str) -> Result<Self, ByteArrayError> {
121 if hex_str.is_empty() {
122 return Err(ByteArrayError::EmptyInput);
123 }
124
125 let bytes: Vec<u8> = hex_str.bytes().filter(|&b| b != b'_').collect();
127
128 if let Some(&invalid) = bytes.iter().find(|&&b| !b.is_ascii_hexdigit()) {
130 return Err(InvalidHexChar(invalid as char));
131 }
132
133 let hex_count = bytes.len();
134 let byte_count = hex_count / 2 + hex_count % 2;
135 let mut ret = ByteArray::with_capacity(byte_count);
136
137 let mut start = 0;
138
139 if hex_count % 2 == 1 {
141 ret.bytes
142 .push(Utils::hex_char_to_nibble_unchecked(bytes[0]));
143 start = 1;
144 }
145
146 for i in (start..hex_count).step_by(2) {
148 let byte_val = Utils::hex_char_to_nibble_unchecked(bytes[i]) << 4
149 | Utils::hex_char_to_nibble_unchecked(bytes[i + 1]);
150 ret.bytes.push(byte_val);
151 }
152
153 Ok(ret)
154 }
155
156 pub fn from_bin(bin_str: &str) -> Result<Self, ByteArrayError> {
166 if bin_str.is_empty() {
167 return Err(ByteArrayError::EmptyInput);
168 }
169
170 let bytes: Vec<u8> = bin_str.bytes().filter(|&b| b != b'_').collect();
172
173 if let Some(&invalid) = bytes.iter().find(|&&b| b != b'0' && b != b'1') {
175 return Err(InvalidBinaryChar(invalid as char));
176 }
177
178 let bit_count = bytes.len();
179 let byte_count = bit_count.div_ceil(8);
180 let mut ret = ByteArray::with_capacity(byte_count);
181
182 let rem = bit_count % 8;
183
184 let start = if rem != 0 {
186 let mut byte = 0u8;
187 #[allow(clippy::needless_range_loop)] for i in 0..rem {
189 let bit_value = bytes[i] - b'0';
190 byte |= bit_value << (rem - 1 - i);
191 }
192 ret.bytes.push(byte);
193 rem
194 } else {
195 0
196 };
197
198 for i in (start..bit_count).step_by(8) {
200 let mut byte = 0u8;
201
202 for j in 0..8 {
203 let bit_value = bytes[i + j] - b'0';
204 byte |= bit_value << (7 - j);
205 }
206
207 ret.bytes.push(byte);
208 }
209
210 Ok(ret)
211 }
212
213 pub fn init_zeros(count: usize) -> Self {
217 ByteArray {
218 bytes: vec![0u8; count],
219 }
220 }
221
222 pub fn init_value(value: u8, count: usize) -> Self {
226 ByteArray {
227 bytes: vec![value; count],
228 }
229 }
230
231 pub fn as_bytes(&self) -> &[u8] {
250 &self.bytes
251 }
252
253 #[cfg(feature = "experimental")]
254 pub fn resize(&mut self, new_capacity: usize, value: u8) {
255 unimplemented!(
256 "this is insecure and must find a way on how to handle this in a more secure fashion"
257 );
258 self.bytes.resize(new_capacity, value);
259 }
260
261 #[cfg(feature = "experimental")]
276 pub fn try_push(&mut self, value: u8) {
277 self.bytes.push(value);
278 }
279}
280
281impl Index<usize> for ByteArray {
284 type Output = u8;
285
286 fn index(&self, index: usize) -> &Self::Output {
290 &self.bytes[index]
291 }
292}
293
294impl IndexMut<usize> for ByteArray {
295 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
299 &mut self.bytes[index]
300 }
301}
302
303impl Index<Range<usize>> for ByteArray {
304 type Output = [u8];
305
306 fn index(&self, range: Range<usize>) -> &Self::Output {
307 &self.bytes[range]
308 }
309}
310
311impl Index<RangeFrom<usize>> for ByteArray {
312 type Output = [u8];
313
314 fn index(&self, range: RangeFrom<usize>) -> &Self::Output {
315 &self.bytes[range] }
317}
318impl Index<RangeTo<usize>> for ByteArray {
319 type Output = [u8];
320
321 fn index(&self, range: RangeTo<usize>) -> &Self::Output {
322 &self.bytes[range] }
324}
325impl Index<RangeInclusive<usize>> for ByteArray {
326 type Output = [u8];
327
328 fn index(&self, range: RangeInclusive<usize>) -> &Self::Output {
329 &self.bytes[range] }
331}
332impl Index<RangeFull> for ByteArray {
333 type Output = [u8];
334
335 fn index(&self, range: RangeFull) -> &Self::Output {
336 &self.bytes[range] }
338}
339
340impl IndexMut<Range<usize>> for ByteArray {
341 fn index_mut(&mut self, range: Range<usize>) -> &mut Self::Output {
342 &mut self.bytes[range]
343 }
344}
345
346impl IndexMut<RangeFrom<usize>> for ByteArray {
347 fn index_mut(&mut self, range: RangeFrom<usize>) -> &mut Self::Output {
348 &mut self.bytes[range]
349 }
350}
351impl IndexMut<RangeTo<usize>> for ByteArray {
352 fn index_mut(&mut self, range: RangeTo<usize>) -> &mut Self::Output {
353 &mut self.bytes[range]
354 }
355}
356impl IndexMut<RangeInclusive<usize>> for ByteArray {
357 fn index_mut(&mut self, range: RangeInclusive<usize>) -> &mut Self::Output {
358 &mut self.bytes[range] }
360}
361impl IndexMut<RangeFull> for ByteArray {
362 fn index_mut(&mut self, range: RangeFull) -> &mut Self::Output {
363 &mut self.bytes[range] }
365}
366
367impl AsRef<[u8]> for ByteArray {
368 fn as_ref(&self) -> &[u8] {
369 self.as_bytes()
370 }
371}
372
373impl AsMut<[u8]> for ByteArray {
374 fn as_mut(&mut self) -> &mut [u8] {
375 &mut self.bytes
376 }
377}
378
379#[cfg(test)]
380mod tests {
381 use super::*;
382 use crate::try_hex;
383 use alloc::vec;
384 use core::str::FromStr;
385
386 fn is_normal<T: Sized + Send + Sync + Unpin>() {}
387
388 #[test]
389 fn test_thread_safety_autotraits() {
390 is_normal::<ByteArray>();
391 }
392
393 #[test]
394 fn test_hex_string_constructor() {
395 let b1: ByteArray = "0xfe81eabd5".parse().unwrap();
396
397 assert_eq!(b1.len(), 5);
398 assert_eq!(b1.bytes, vec![0x0f, 0xe8, 0x1e, 0xab, 0xd5]);
399 }
400
401 #[test]
402 fn test_ba_with_capacity() {
403 let arr = ByteArray::with_capacity(10);
404
405 assert_eq!(arr.bytes.capacity(), 10);
406 assert!(ByteArray::try_from(arr).is_ok());
407 }
408
409 #[test]
410 fn test_with_hex() {
411 let arr = ByteArray::from_hex("ffabc");
412
413 assert_eq!(arr.unwrap().bytes, vec![0x0f, 0xfa, 0xbc]);
414 }
415
416 #[test]
417 fn test_with_bin_less_than_8() {
418 let arr = ByteArray::from_bin("1101111").unwrap();
419 assert_eq!(arr.bytes, vec![0x6f]);
420 }
421
422 #[test]
423 fn test_with_bin_more_than_8() {
424 let arr = ByteArray::from_bin("110111010110111").unwrap();
425 assert_eq!(arr.bytes, vec![0x6e, 0xb7]);
426 }
427
428 #[test]
429 fn test_equality_derives() {
430 let arr: ByteArray = "0xffab12345ffaf".parse().unwrap();
431 let arr_2 = ByteArray::from_hex("ffab12345ffafdeadbeef").unwrap();
432 let arr_3 = arr.clone();
433
434 assert_ne!(arr.bytes, arr_2.bytes);
435 assert_eq!(arr.bytes, arr_3.bytes);
436 }
437
438 #[test]
439 fn test_init_zeros() {
440 let arr = ByteArray::init_zeros(8);
441
442 assert_eq!(arr.bytes, [0u8, 0, 0, 0, 0, 0, 0, 0]);
443 }
444
445 #[test]
446 fn test_init_value() {
447 let arr = ByteArray::init_value(254, 8);
448
449 assert_eq!(arr.bytes, [254, 254, 254, 254, 254, 254, 254, 254]);
450 }
451
452 #[test]
453 fn test_mutable_idx_accessor() {
454 let mut arr: ByteArray = "0xffab1245".parse().unwrap();
455
456 arr[3] = 0xbe;
457 arr[1] = 0xfa;
458
459 assert_eq!(arr.bytes, ByteArray::from_str("0xfffa12be").unwrap().bytes);
460 }
461
462 #[test]
463 #[allow(deprecated)]
464 fn test_fill_zeros() {
465 let arr = ByteArray::default().fill_zeros();
466 assert!(arr.as_bytes().is_empty());
467
468 let arr = ByteArray::with_capacity(5).fill_zeros();
469 assert_eq!(arr.as_bytes(), [0u8, 0, 0, 0, 0]);
470
471 let arr = ByteArray::with_capacity(7).fill_zeros();
472
473 assert_eq!(arr.as_bytes(), [0u8, 0, 0, 0, 0, 0, 0])
474 }
475
476 #[test]
477 #[allow(deprecated)]
478 fn test_fill_with() {
479 let arr = ByteArray::default().fill_zeros();
480 assert!(arr.as_bytes().is_empty());
481
482 let arr = ByteArray::with_capacity(5).fill_with(126);
483 assert_eq!(arr.as_bytes(), [126u8, 126, 126, 126, 126]);
484
485 let arr = ByteArray::with_capacity(7).fill_with(5);
486
487 assert_eq!(arr.as_bytes(), [5u8, 5, 5, 5, 5, 5, 5]);
488 }
489
490 #[test]
491 #[cfg(feature = "experimental")]
492 fn test_push_element() {
493 let mut arr: ByteArray = vec![1, 2].into();
494
495 arr.try_push(0xab);
496
497 assert_eq!(arr.as_bytes(), [1, 2, 0xab]);
498 }
499
500 #[test]
501 fn test_hex_with_underscores() {
502 let arr = ByteArray::from_hex("de_ad_be_ef").unwrap();
503 assert_eq!(arr.as_bytes(), [0xde, 0xad, 0xbe, 0xef]);
504 }
505
506 #[test]
507 fn test_bin_with_underscores() {
508 let arr = ByteArray::from_bin("1010_0101").unwrap();
509 assert_eq!(arr.as_bytes(), [0xa5]);
510 }
511
512 #[test]
513 fn test_bin_with_underscores_odd_length() {
514 let arr = ByteArray::from_bin("110_1111").unwrap();
515 assert_eq!(arr.as_bytes(), [0x6f]);
516 }
517
518 #[test]
519 #[should_panic]
520 fn test_as_mut_empty() {
521 let mut bytes = ByteArray::default();
522
523 let mut_ref = bytes.as_mut();
524
525 mut_ref[0] = 0x00;
526 }
527
528 #[test]
529 fn test_ranges() {
530 let bytes = try_hex!("ff_aa_fa_b8_ca_12_15_5a_5c_6f").unwrap();
531
532 assert_eq!(bytes[1..2], [0xaa]);
533 assert_eq!(bytes[0..=2], [0xff, 0xaa, 0xfa]);
534 assert_eq!(bytes[6..], [0x15, 0x5a, 0x5c, 0x6f]);
535 assert_eq!(bytes[..3], [0xff, 0xaa, 0xfa]);
536 assert_eq!(
537 bytes[..],
538 [0xff, 0xaa, 0xfa, 0xb8, 0xca, 0x12, 0x15, 0x5a, 0x5c, 0x6f]
539 );
540 }
541
542 #[test]
543 fn test_ranges_mut() {
544 let mut bytes = try_hex!("ff_aa_fa_b8_ca_12_15_5a_5c_6f").unwrap();
545
546 let slice = &mut bytes[1..3];
547 slice[0] = 0x00;
548 slice[1] = 0x01;
549 let expected: ByteArray = "0xff_00_01_b8_ca_12_15_5a_5c_6f".parse().unwrap();
550
551 assert_eq!(bytes, expected);
552
553 let slice = &mut bytes[0..=2];
554 slice[0] = 0x12;
555 slice[1] = 0xab;
556 slice[2] = 0xbc;
557
558 let expected: ByteArray = "0x12_ab_bc_b8_ca_12_15_5a_5c_6f".parse().unwrap();
559
560 assert_eq!(bytes, expected);
561
562 let slice = &mut bytes[6..];
563 slice[0] = 0x01;
564 slice[1] = 0x02;
565 slice[2] = 0x03;
566 slice[3] = 0x04;
567
568 let expected: ByteArray = "0x12_ab_bc_b8_ca_12_01_02_03_04".parse().unwrap();
569
570 assert_eq!(bytes, expected);
571
572 let slice = &mut bytes[..3];
573 slice[0] = 0x00;
574 slice[1] = 0x02;
575 slice[2] = 0x03;
576
577 let expected: ByteArray = "0x00_02_03_b8_ca_12_01_02_03_04".parse().unwrap();
578
579 assert_eq!(bytes, expected);
580
581 let slice = &mut bytes[..];
582
583 slice.iter_mut().for_each(|e| *e = 0x01);
584
585 let expected: ByteArray = "0x01_01_01_01_01_01_01_01_01_01".parse().unwrap();
586
587 assert_eq!(bytes, expected);
588 }
589
590 #[test]
591 fn test_as_ref() {
592 let bytes: ByteArray = "0x01_02_03_04_05_06_07_08".parse().unwrap();
593 let bytes_ref = bytes.as_ref();
594
595 assert_eq!(bytes.as_bytes(), bytes_ref);
596 }
597
598 #[test]
599 fn test_as_mut() {
600 let mut bytes: ByteArray = "0x01_02_03_04_05_06_07_08".parse().unwrap();
601
602 let mut_ref = bytes.as_mut();
603
604 mut_ref[0] = 0xFF;
605 mut_ref[5] = 0xab;
606 mut_ref[7] = 0x1a;
607
608 assert_eq!(
609 bytes.as_bytes(),
610 [0xff, 0x02, 0x03, 0x04, 0x05, 0xab, 0x07, 0x1a]
611 )
612 }
613}