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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use {
alloc::string::String,
super::{Debt64, PAD_CHAR},
};
fn add_char(s: &mut String, chr: &char, max_line_len: &usize, line_separators: &Option<&[char]>, line_column: &mut usize) {
s.push(*chr);
if *max_line_len == 0 {
return;
}
if let Some(line_separators) = line_separators {
*line_column = (*line_column).saturating_add(1);
if *line_column >= *max_line_len {
for chr in line_separators.iter() {
s.push(*chr);
}
*line_column = 0;
}
}
}
pub (super) fn encode<B>(bytes: B, debt64: &Debt64) -> String where B: AsRef<[u8]> {
let bytes = bytes.as_ref();
let mut result = String::with_capacity(debt64.estimate_encoding_capacity(bytes));
let max_line_len = debt64.max_line_len().unwrap_or(0);
let line_separators = debt64.line_separators();
let mut line_column = 0;
let must_use_pad = debt64.must_use_pad();
let last_chars = debt64.last_chars();
let len = bytes.len();
let mut index = 0;
loop {
let byte = if index < len { bytes[index] } else { break; };
add_char(&mut result, Debt64::get_char((byte >> 2) as usize, last_chars), &max_line_len, &line_separators, &mut line_column);
index += 1;
let bits = (byte << 6) >> 2;
if index < len {
let byte = bytes[index];
index += 1;
add_char(
&mut result, Debt64::get_char((bits | (byte >> 4)) as usize, last_chars), &max_line_len, &line_separators, &mut line_column
);
let bits = (byte << 4) >> 2;
if index < len {
let byte = bytes[index];
index += 1;
add_char(
&mut result, Debt64::get_char((bits | (byte >> 6)) as usize, last_chars), &max_line_len, &line_separators,
&mut line_column
);
add_char(
&mut result, Debt64::get_char(((byte << 2) >> 2) as usize, last_chars), &max_line_len, &line_separators,
&mut line_column
);
} else {
add_char(&mut result, Debt64::get_char(bits as usize, last_chars), &max_line_len, &line_separators, &mut line_column);
if must_use_pad {
result.push(PAD_CHAR);
}
break;
}
} else {
add_char(&mut result, Debt64::get_char(bits as usize, last_chars), &max_line_len, &line_separators, &mut line_column);
if must_use_pad {
for _ in 0..2 {
add_char(&mut result, &PAD_CHAR, &max_line_len, &line_separators, &mut line_column);
}
}
break;
}
}
result
}