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