1use crate::error::*;
2use crate::{Decoder, Encoder};
3
4pub struct Hex;
5
6impl Encoder for Hex {
7 #[inline]
8 fn encoded_len(bin_len: usize) -> Result<usize, Error> {
9 bin_len.checked_mul(2).ok_or(Error::Overflow)
10 }
11
12 fn encode<IN: AsRef<[u8]>>(hex: &mut [u8], bin: IN) -> Result<&[u8], Error> {
13 let bin = bin.as_ref();
14 let bin_len = bin.len();
15 let hex_maxlen = hex.len();
16 if hex_maxlen < bin_len.checked_shl(1).ok_or(Error::Overflow)? {
17 return Err(Error::Overflow);
18 }
19 for (i, v) in bin.iter().enumerate() {
20 let (b, c) = ((v >> 4) as u16, (v & 0xf) as u16);
21 let x = (((87 + c + (((c.wrapping_sub(10)) >> 8) & !38)) as u8) as u16) << 8
22 | ((87 + b + (((b.wrapping_sub(10)) >> 8) & !38)) as u8) as u16;
23 hex[i * 2] = x as u8;
24 hex[i * 2 + 1] = (x >> 8) as u8;
25 }
26 Ok(&hex[..bin_len * 2])
27 }
28}
29
30impl Decoder for Hex {
31 fn decode<'t, IN: AsRef<[u8]>>(
32 bin: &'t mut [u8],
33 hex: IN,
34 ignore: Option<&[u8]>,
35 ) -> Result<&'t [u8], Error> {
36 let hex = hex.as_ref();
37 let bin_maxlen = bin.len();
38 let mut bin_pos = 0;
39 let mut state = false;
40 let mut c_acc = 0;
41 for &c in hex {
42 let c_num = c ^ 48;
43 let c_num0 = ((c_num as u16).wrapping_sub(10) >> 8) as u8;
44 let c_alpha = (c & !32).wrapping_sub(55);
45 let c_alpha0 = (((c_alpha as u16).wrapping_sub(10)
46 ^ ((c_alpha as u16).wrapping_sub(16)))
47 >> 8) as u8;
48 if (c_num0 | c_alpha0) == 0 {
49 match ignore {
50 Some(ignore) if ignore.contains(&c) => continue,
51 _ => return Err(Error::InvalidInput),
52 };
53 }
54 let c_val = (c_num0 & c_num) | (c_alpha0 & c_alpha);
55 if bin_pos >= bin_maxlen {
56 return Err(Error::Overflow);
57 }
58 if !state {
59 c_acc = c_val << 4;
60 } else {
61 bin[bin_pos] = c_acc | c_val;
62 bin_pos += 1;
63 }
64 state = !state;
65 }
66 if state {
67 return Err(Error::InvalidInput);
68 }
69 Ok(&bin[..bin_pos])
70 }
71}
72
73#[cfg(feature = "std")]
74#[test]
75fn test_hex() {
76 let bin = [1u8, 5, 11, 15, 19, 131];
77 let hex = Hex::encode_to_string(bin).unwrap();
78 let expected = "01050b0f1383";
79 assert_eq!(hex, expected);
80 let bin2 = Hex::decode_to_vec(&hex, None).unwrap();
81 assert_eq!(bin, &bin2[..]);
82}
83
84#[test]
85fn test_hex_no_std() {
86 let bin = [1u8, 5, 11, 15, 19, 131];
87 let expected = "01050b0f1383";
88 let mut hex = [0u8; 12];
89 let hex = Hex::encode_to_str(&mut hex, bin).unwrap();
90 assert_eq!(&hex, &expected);
91 let mut bin2 = [0u8; 6];
92 let bin2 = Hex::decode(&mut bin2, hex, None).unwrap();
93 assert_eq!(bin, bin2);
94}