rcnb_rs/
encode.rs

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}