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
70
71
72
73
74
75
76
77
78
79
80
81
use crate::info;
use crate::mode::Mode;
use crate::version::Version;
use bitvec::prelude::*;
use std::cmp;
pub fn encode(s: &str, version: Version) -> (Mode, BitVec<Lsb0, u8>) {
let mode = Mode::from_str(s);
let encoded = encode_with_mode(s, mode, version);
(mode, encoded)
}
pub fn encode_with_mode(s: &str, mode: Mode, version: Version) -> BitVec<Lsb0, u8> {
let total_capacity = info::total_bits();
let mut bv = mode.to_bitvec();
bv.reserve(total_capacity);
bv.append(&mut bitvec_char_count(s.len(), mode, version));
bv.append(&mut bitvec_data(s, mode));
assert!(bv.len() <= total_capacity);
let zero_bits = cmp::min(total_capacity - bv.len(), 4);
append(&mut bv, 0, zero_bits);
assert!(bv.len() <= total_capacity);
let zero_bits = (total_capacity - bv.len()) % 8;
append(&mut bv, 0, zero_bits);
assert!(bv.len() % 8 == 0);
for pad in [0xEC, 0x11].iter().cycle() {
if bv.len() >= total_capacity {
break;
}
append(&mut bv, *pad, 8);
}
assert_eq!(bv.len(), total_capacity);
bv
}
pub fn append(bv: &mut BitVec<Lsb0, u8>, v: u32, len: usize) {
bv.extend((0..len).rev().map(|i| (v >> i) & 1 != 0));
}
fn bitvec_char_count(len: usize, mode: Mode, v: Version) -> BitVec<Lsb0, u8> {
let mut bv = BitVec::<Lsb0, u8>::new();
append(&mut bv, len as u32, v.char_count_len(mode));
bv
}
fn bitvec_data(s: &str, mode: Mode) -> BitVec<Lsb0, u8> {
let bytes = string_to_bytes(s, mode);
match mode {
Mode::Byte => encode_byte_data(&bytes),
}
}
fn encode_byte_data(v: &Vec<u8>) -> BitVec<Lsb0, u8> {
BitVec::<Lsb0, u8>::from_slice(&v[..])
}
fn string_to_bytes(s: &str, mode: Mode) -> Vec<u8> {
match mode {
Mode::Byte => s.bytes().collect(),
}
}