1use crate::{CN, SB, SC, CR, CC, CB, SNB, SCNB};
2
3fn encode_byte(i: u16) -> [char;2] {
4 if i > 0xFF {
5 panic!("rc/nb overflow")
6 }
7
8 if i > 0x7F {
9 let i = i & 0x7F;
10 [CN[(i / SB) as usize], CB[(i % SB) as usize]]
11 } else {
12 [CR[(i / SC) as usize], CC[(i % SC) as usize]]
13 }
14}
15
16fn encode_short(i: u16) -> [char;4] {
17 let mut reverse = false;
18 let mut i = i;
19 if i > 0x7FFF {
20 reverse = true;
21 i = i & 0x7FFF
22 }
23 let chars = [
24 CR[(i / SCNB) as usize],
25 CC[(i % SCNB / SNB) as usize],
26 CN[(i % SNB / SB) as usize],
27 CB[(i % SB) as usize],
28 ];
29 if reverse {
30 [chars[2], chars[3], chars[0], chars[1]]
31 } else {
32 chars
33 }
34}
35
36pub fn encode<T: AsRef<[u8]>>(data: T) -> String {
37 let data = data.as_ref();
38 let len = data.len();
39 let mut vc = Vec::with_capacity(len * 2);
40
41 let mut i = 0;
42 while i < (len >> 1) {
43 vc.extend_from_slice(&encode_short(((data[i * 2] as u16) << 8) | data[i * 2 + 1] as u16));
44 i += 1;
45 }
46
47 if (data.len() & 1) != 0 {
48 vc.extend_from_slice(&encode_byte(data[len - 1] as u16))
49 }
50
51 vc.iter().collect::<String>()
52}