1use std::fmt;
4use bytes::{BufMut, Bytes, BytesMut};
5use super::base64::DecodeError;
6
7
8pub fn decode_hex(s: &str) -> Result<Bytes, DecodeError> {
11 let mut decoder = Decoder::new_hex();
12 for ch in s.chars() {
13 decoder.push(ch)?;
14 }
15 decoder.finalize()
16}
17
18
19pub fn display_hex<B, W>(bytes: &B, f: &mut W) -> fmt::Result
20where B: AsRef<[u8]> + ?Sized, W: fmt::Write {
21 fn ch(i: u8) -> char {
22 ENCODE_HEX_ALPHABET[i as usize]
23 }
24
25 for chunk in bytes.as_ref().chunks(5) {
26 f.write_char(ch(chunk[0] >> 3))?; if chunk.len() == 1 {
28 f.write_char(ch((chunk[0] & 0x07) << 2))?; break;
30 }
31 f.write_char(ch((chunk[0] & 0x07) << 2 | chunk[1] >> 6))?; f.write_char(ch((chunk[1] & 0x3F) >> 1))?; if chunk.len() == 2 {
34 f.write_char(ch((chunk[1] & 0x01) << 4))?; break;
36 }
37 f.write_char(ch((chunk[1] & 0x01) << 4 | chunk[2] >> 4))?; if chunk.len() == 3 {
39 f.write_char(ch((chunk[2] & 0x0F) << 1))?; break;
41 }
42 f.write_char(ch((chunk[2] & 0x0F) << 1 | chunk[3] >> 7))?; f.write_char(ch((chunk[3] & 0x7F) >> 2))?; if chunk.len() == 4 {
45 f.write_char(ch((chunk[3] & 0x03) << 3))?; break;
47 }
48 f.write_char(ch((chunk[3] & 0x03) << 3 | chunk[4] >> 5))?; f.write_char(ch(chunk[4] & 0x1F))?; }
51 Ok(())
52}
53
54
55pub struct Decoder {
61 alphabet: &'static [u8; 128],
63
64 buf: [u8; 8],
69
70 next: usize,
72
73 target: Result<BytesMut, DecodeError>,
75}
76
77impl Decoder {
78 pub fn new_hex() -> Self {
79 Decoder {
80 alphabet: &DECODE_HEX_ALPHABET,
81 buf: [0; 8],
82 next: 0,
83 target: Ok(BytesMut::new())
84 }
85 }
86
87 pub fn finalize(mut self) -> Result<Bytes, DecodeError> {
88 if let Err(err) = self.target {
89 return Err(err)
90 }
91
92 match self.next {
93 0 => { }
94 1 | 3 | 6 => return Err(DecodeError::IncompleteInput),
95 2 => {
96 self.reserve(1);
97 self.octet_0();
98 }
99 4 => {
100 self.reserve(2);
101 self.octet_0();
102 self.octet_1();
103 }
104 5 => {
105 self.reserve(3);
106 self.octet_0();
107 self.octet_1();
108 self.octet_2();
109 }
110 7 => {
111 self.reserve(4);
112 self.octet_0();
113 self.octet_1();
114 self.octet_2();
115 self.octet_3();
116 }
117 _ => unreachable!()
118 }
119 self.target.map(BytesMut::freeze)
120 }
121
122 pub fn push(&mut self, ch: char) -> Result<(), DecodeError> {
123 if ch > (127 as char) {
124 return Err(DecodeError::IllegalChar(ch))
125 }
126 let val = self.alphabet[ch as usize];
127 if val == 0xFF {
128 return Err(DecodeError::IllegalChar(ch))
129 }
130 self.buf[self.next] = val;
131 self.next += 1;
132
133 if self.next == 8 {
134 self.reserve(5);
135 self.octet_0();
136 self.octet_1();
137 self.octet_2();
138 self.octet_3();
139 self.octet_4();
140 self.next = 0;
141 }
142 Ok(())
143 }
144}
145
146impl Decoder {
147 fn octet_0(&mut self) {
148 let ch = self.buf[0] << 3 | self.buf[1] >> 2;
149 self.append(ch)
150 }
151
152 fn octet_1(&mut self) {
153 let ch = self.buf[1] << 6 | self.buf[2] << 1 | self.buf[3] >> 4;
154 self.append(ch)
155 }
156
157 fn octet_2(&mut self) {
158 let ch = self.buf[3] << 4 | self.buf[4] >> 1;
159 self.append(ch)
160 }
161
162 fn octet_3(&mut self) {
163 let ch = self.buf[4] << 7 | self.buf[5] << 2 | self.buf[6] >> 3;
164 self.append(ch)
165 }
166
167 fn octet_4(&mut self) {
168 let ch = self.buf[6] << 5 | self.buf[7];
169 self.append(ch)
170 }
171
172 fn append(&mut self, value: u8) {
173 self.target.as_mut().unwrap().put_u8(value);
174 }
175
176 fn reserve(&mut self, len: usize) {
177 let target = self.target.as_mut().unwrap();
178 if target.remaining_mut() < len {
179 target.reserve(len)
180 }
181 }
182}
183
184
185const DECODE_HEX_ALPHABET: [u8; 128] = [
193 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, ];
217
218
219const ENCODE_HEX_ALPHABET: [char; 32] = [
220 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', ];
226
227
228#[cfg(test)]
231mod test {
232 use super::*;
233
234 #[test]
235 fn test_decode_hex() {
236 assert_eq!(decode_hex("").unwrap().as_ref(), b"");
237 assert_eq!(decode_hex("CO").unwrap().as_ref(), b"f");
238 assert_eq!(decode_hex("CPNG").unwrap().as_ref(), b"fo");
239 assert_eq!(decode_hex("CPNMU").unwrap().as_ref(), b"foo");
240 assert_eq!(decode_hex("CPNMUOG").unwrap().as_ref(), b"foob");
241 assert_eq!(decode_hex("CPNMUOJ1").unwrap().as_ref(), b"fooba");
242 assert_eq!(decode_hex("CPNMUOJ1E8").unwrap().as_ref(), b"foobar");
243 assert_eq!(decode_hex("co").unwrap().as_ref(), b"f");
244 assert_eq!(decode_hex("cpng").unwrap().as_ref(), b"fo");
245 assert_eq!(decode_hex("cpnmu").unwrap().as_ref(), b"foo");
246 assert_eq!(decode_hex("cpnmuog").unwrap().as_ref(), b"foob");
247 assert_eq!(decode_hex("cpnmuoj1").unwrap().as_ref(), b"fooba");
248 assert_eq!(decode_hex("cpnmuoj1e8").unwrap().as_ref(), b"foobar");
249 }
250
251 #[test]
252 fn test_display_hex() {
253 fn fmt(s: &[u8]) -> String {
254 let mut out = String::new();
255 display_hex(s, &mut out).unwrap();
256 out
257 }
258
259 assert_eq!(fmt(b""), "");
260 assert_eq!(fmt(b"f"), "CO");
261 assert_eq!(fmt(b"fo"), "CPNG");
262 assert_eq!(fmt(b"foo"), "CPNMU");
263 assert_eq!(fmt(b"foob"), "CPNMUOG");
264 assert_eq!(fmt(b"fooba"), "CPNMUOJ1");
265 assert_eq!(fmt(b"foobar"), "CPNMUOJ1E8");
266 }
267}
268