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
use DecodeError;
use bigint::BigUint;
pub struct AsciiDecoder;
pub struct Utf8Decoder;
macro_rules! decode {
($alpha:ident, $input:ident, $iter:ident, $c:pat => $carry:expr) => ({
if $input.len() == 0 {
return Ok(Vec::new());
}
let base = $alpha.len() as u32;
let mut big = BigUint::with_capacity(4);
for $c in $input.$iter() {
big.mul_add(base, $carry as u32);
}
let mut bytes = big.into_bytes_be();
let leader = $alpha[0];
let leaders = $input
.$iter()
.take_while(|byte| *byte == leader)
.count();
for _ in 0..leaders {
bytes.insert(0, 0);
}
Ok(bytes)
})
}
impl AsciiDecoder {
#[inline(always)]
pub fn decode(alphabet: &[u8], lookup: [u8; 256], input: &str) -> Result<Vec<u8>, DecodeError> {
decode!(
alphabet,
input,
bytes,
c => match lookup[c as usize] {
0xFF => return Err(DecodeError),
index => index
}
)
}
}
impl Utf8Decoder {
#[inline(always)]
pub fn decode(alphabet: &[char], input: &str) -> Result<Vec<u8>, DecodeError> {
decode!(
alphabet,
input,
chars,
c => alphabet
.iter()
.enumerate()
.find(|&(_, ch)| *ch == c)
.map(|(i, _)| i)
.ok_or(DecodeError)?
)
}
}