1use crate::alphabet::{Alphabet, ZBASE32, EncodeOrder};
3
4#[cfg(any(feature = "alloc", feature = "std", test))]
5use core::fmt;
6#[cfg(any(feature = "std", test))]
7use std::error;
8
9#[derive(Clone, Debug, PartialEq, Eq)]
11pub enum DecodeError {
12 InvalidByte(usize, u8),
14 InvalidLength(usize),
16}
17
18impl fmt::Display for DecodeError {
19 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
20 match *self {
21 DecodeError::InvalidByte(index, byte) => {
22 write!(f, "Invalid byte {}, offset {}.", byte, index)
23 }
24 DecodeError::InvalidLength(sz) => write!(f, "Encoded text cannot have a 5-bit remainder: length = {}", sz),
25 }
26 }
27}
28
29#[cfg(any(feature = "std", test))]
30impl error::Error for DecodeError {
31 fn description(&self) -> &str {
32 match *self {
33 DecodeError::InvalidByte(_, _) => "invalid byte",
34 DecodeError::InvalidLength(_) => "invalid length",
35 }
36 }
37
38 fn cause(&self) -> Option<&dyn error::Error> {
39 None
40 }
41}
42
43#[cfg(any(feature = "alloc", feature = "std", test))]
58pub fn decode<T: AsRef<[u8]>>(input: T) -> Result<Vec<u8>, DecodeError> {
59 decode_alphabet(input, &ZBASE32)
60}
61
62#[cfg(any(feature = "alloc", feature = "std", test))]
80pub fn decode_alphabet<T: AsRef<[u8]>>(
81 input: T,
82 alphabet: &Alphabet,
83) -> Result<Vec<u8>, DecodeError> {
84 let mut buffer = Vec::<u8>::with_capacity(
85 decoded_len(input.as_ref().len()).expect("integer multiplication overflow"));
86
87 decode_alphabet_vec(input, &mut buffer, &alphabet).map(|_| buffer)
88}
89
90#[cfg(any(feature = "alloc", feature = "std", test))]
112pub fn decode_alphabet_vec<T: AsRef<[u8]>>(
113 input: T,
114 buffer: &mut Vec<u8>,
115 alphabet: &Alphabet,
116) -> Result<(), DecodeError> {
117 let input_bytes = input.as_ref();
118
119 let estimate = decoded_len(input_bytes.len()).expect("integer multiplication overflow");
120 buffer.resize(estimate, 0);
121
122 let mut processed_bits = 0;
123 let mut acc = 0_u32;
124 let mut o = 0_usize;
125 let mut i = o;
126
127 if alphabet.encode_order == EncodeOrder::OrderInversed {
128 for c in input_bytes {
129 if processed_bits >= 8 {
130 processed_bits -= 8;
132 buffer[o] = (acc & 0xFF) as u8;
133 o = o + 1;
134 acc = acc >> 8;
135 }
136 let decoded = alphabet.decode_bytes[*c as usize];
137 if decoded == 0xff {
138 return Err(DecodeError::InvalidByte(i, *c));
139 }
140
141 acc = ((decoded as u32) << processed_bits) | acc;
142 processed_bits = processed_bits + 5;
143 i = i + 1;
144 }
145 if processed_bits > 0 {
146 buffer[o] = (acc & 0xFF) as u8;
147 o = o + 1;
148 }
149 }
150 else {
151 for c in input_bytes {
152 let decoded = alphabet.decode_bytes[*c as usize];
153 if decoded == 0xff {
154 return Err(DecodeError::InvalidByte(i, *c));
155 }
156
157 acc = (acc << 5) | decoded as u32;
158 processed_bits = processed_bits + 5;
159
160 if processed_bits >= 8 {
161 processed_bits = processed_bits - 8;
162 buffer[o] = ((acc >> processed_bits) & 0xFF) as u8;
164 o = o + 1;
165 acc = acc & ((1 << processed_bits) - 1);
166 }
167
168 i = i + 1;
169 }
170 }
171
172 buffer.resize(o, 0);
173
174 Ok(())
175}
176
177fn decoded_len(bytes_len : usize) -> Option<usize> {
178 let full_chunks = bytes_len / 8;
179 let remainder = bytes_len % 8;
180 full_chunks.checked_mul(5).and_then(|c| c.checked_add(remainder))
181}
182
183#[cfg(test)]
184mod tests {
185 use crate::encode::*;
186 use crate::decode::*;
187 use crate::alphabet::*;
188
189 #[test]
190 fn simple_decode_zbase() {
191 assert_eq!(
192 "test123".as_bytes(),
193 decode("wm3g84fg13cy").expect("undecoded!"),
194 );
195 assert_eq!(
196 "hello".as_bytes(),
197 decode("em3ags7p").expect("undecoded"),
198 );
199 }
200
201 #[test]
202 fn simple_encode_decode_zbase() {
203 assert_eq!("test123".as_bytes(),
204 decode(encode("test123")).expect("undecoded"));
205 }
206
207 #[test]
208 fn simple_decode_rfc() {
209 assert_eq!(
210 "test123".as_bytes(),
211 decode_alphabet("ORSXG5BRGIZQ", &RFC).expect("undecoded!"),
212 );
213 assert_eq!(
214 "hello".as_bytes(),
215 decode_alphabet("NBSWY3DP", &RFC).expect("undecoded"),
216 );
217 }
218
219 #[test]
220 fn simple_encode_decode_rfc() {
221 assert_eq!("test123".as_bytes(),
222 decode_alphabet(encode_alphabet("test123", &RFC),
223 &RFC).expect("undecoded"));
224 }
225}