1use crate::operators::DictionaryValue;
12use std::collections::HashMap;
13
14#[derive(Debug)]
16pub struct FastEncoder {
17 buffer: Vec<u8>,
19 global_dict: HashMap<String, DictionaryValue>,
21 template_dicts: HashMap<u32, HashMap<String, DictionaryValue>>,
23}
24
25impl FastEncoder {
26 #[must_use]
28 pub fn new() -> Self {
29 Self {
30 buffer: Vec::new(),
31 global_dict: HashMap::new(),
32 template_dicts: HashMap::new(),
33 }
34 }
35
36 #[must_use]
38 pub fn with_capacity(capacity: usize) -> Self {
39 Self {
40 buffer: Vec::with_capacity(capacity),
41 global_dict: HashMap::new(),
42 template_dicts: HashMap::new(),
43 }
44 }
45
46 pub fn encode_uint(&mut self, value: u64) {
51 if value == 0 {
52 self.buffer.push(0x80);
53 return;
54 }
55
56 let mut bytes = Vec::new();
57 let mut v = value;
58
59 while v > 0 {
60 bytes.push((v & 0x7F) as u8);
61 v >>= 7;
62 }
63
64 bytes.reverse();
65
66 if let Some(last) = bytes.last_mut() {
68 *last |= 0x80;
69 }
70
71 self.buffer.extend(bytes);
72 }
73
74 pub fn encode_int(&mut self, value: i64) {
79 if (0..64).contains(&value) {
80 self.buffer.push((value as u8) | 0x80);
81 return;
82 }
83
84 if (-64..0).contains(&value) {
85 self.buffer.push((value as u8) | 0x80);
86 return;
87 }
88
89 let mut bytes = Vec::new();
90 let mut v = value;
91 let negative = value < 0;
92
93 loop {
94 bytes.push((v & 0x7F) as u8);
95 v >>= 7;
96
97 if (negative && v == -1 && (bytes.last().unwrap() & 0x40) != 0)
98 || (!negative && v == 0 && (bytes.last().unwrap() & 0x40) == 0)
99 {
100 break;
101 }
102
103 if v == 0 && !negative {
104 break;
105 }
106 if v == -1 && negative {
107 break;
108 }
109 }
110
111 bytes.reverse();
112
113 if let Some(last) = bytes.last_mut() {
114 *last |= 0x80;
115 }
116
117 self.buffer.extend(bytes);
118 }
119
120 pub fn encode_ascii(&mut self, value: &str) {
125 let bytes = value.as_bytes();
126
127 if bytes.is_empty() {
128 self.buffer.push(0x80);
129 return;
130 }
131
132 for (i, &b) in bytes.iter().enumerate() {
133 if i == bytes.len() - 1 {
134 self.buffer.push(b | 0x80);
135 } else {
136 self.buffer.push(b & 0x7F);
137 }
138 }
139 }
140
141 pub fn encode_bytes(&mut self, value: &[u8]) {
146 self.encode_uint(value.len() as u64);
147 self.buffer.extend_from_slice(value);
148 }
149
150 pub fn encode_nullable_uint(&mut self, value: Option<u64>) {
155 match value {
156 Some(v) => self.encode_uint(v + 1),
157 None => self.buffer.push(0x80),
158 }
159 }
160
161 #[must_use]
163 pub fn finish(self) -> Vec<u8> {
164 self.buffer
165 }
166
167 #[must_use]
169 pub fn as_bytes(&self) -> &[u8] {
170 &self.buffer
171 }
172
173 #[must_use]
175 pub fn len(&self) -> usize {
176 self.buffer.len()
177 }
178
179 #[must_use]
181 pub fn is_empty(&self) -> bool {
182 self.buffer.is_empty()
183 }
184
185 pub fn clear(&mut self) {
187 self.buffer.clear();
188 }
189
190 pub fn reset(&mut self) {
192 self.buffer.clear();
193 self.global_dict.clear();
194 self.template_dicts.clear();
195 }
196
197 #[must_use]
199 pub fn get_global(&self, key: &str) -> Option<&DictionaryValue> {
200 self.global_dict.get(key)
201 }
202
203 pub fn set_global(&mut self, key: impl Into<String>, value: DictionaryValue) {
205 self.global_dict.insert(key.into(), value);
206 }
207}
208
209impl Default for FastEncoder {
210 fn default() -> Self {
211 Self::new()
212 }
213}
214
215#[cfg(test)]
216mod tests {
217 use super::*;
218
219 #[test]
220 fn test_encode_uint_zero() {
221 let mut encoder = FastEncoder::new();
222 encoder.encode_uint(0);
223 assert_eq!(encoder.finish(), vec![0x80]);
224 }
225
226 #[test]
227 fn test_encode_uint_one() {
228 let mut encoder = FastEncoder::new();
229 encoder.encode_uint(1);
230 assert_eq!(encoder.finish(), vec![0x81]);
231 }
232
233 #[test]
234 fn test_encode_uint_larger() {
235 let mut encoder = FastEncoder::new();
236 encoder.encode_uint(942);
237 let bytes = encoder.finish();
238 assert_eq!(bytes, vec![0x07, 0xAE]);
240 }
241
242 #[test]
243 fn test_encode_ascii() {
244 let mut encoder = FastEncoder::new();
245 encoder.encode_ascii("Hi!");
246 let bytes = encoder.finish();
247 assert_eq!(bytes, vec![b'H', b'i', b'!' | 0x80]);
248 }
249
250 #[test]
251 fn test_encode_ascii_empty() {
252 let mut encoder = FastEncoder::new();
253 encoder.encode_ascii("");
254 assert_eq!(encoder.finish(), vec![0x80]);
255 }
256
257 #[test]
258 fn test_encode_bytes() {
259 let mut encoder = FastEncoder::new();
260 encoder.encode_bytes(&[1, 2, 3]);
261 let bytes = encoder.finish();
262 assert_eq!(bytes, vec![0x83, 1, 2, 3]);
263 }
264
265 #[test]
266 fn test_encoder_clear() {
267 let mut encoder = FastEncoder::new();
268 encoder.encode_uint(42);
269 assert!(!encoder.is_empty());
270
271 encoder.clear();
272 assert!(encoder.is_empty());
273 }
274}