1use super::length::encode_length;
7use super::tag;
8use bytes::Bytes;
9
10pub struct EncodeBuf {
15 buf: Vec<u8>,
16}
17
18impl EncodeBuf {
19 pub fn new() -> Self {
21 Self::with_capacity(512)
22 }
23
24 pub fn with_capacity(capacity: usize) -> Self {
26 Self {
27 buf: Vec::with_capacity(capacity),
28 }
29 }
30
31 pub fn push_byte(&mut self, byte: u8) {
33 self.buf.push(byte);
34 }
35
36 pub fn push_bytes(&mut self, bytes: &[u8]) {
38 self.buf.extend(bytes.iter().rev());
39 }
40
41 pub fn push_bytes_raw(&mut self, bytes: &[u8]) {
43 self.buf.extend(bytes.iter().rev());
44 }
45
46 pub fn push_length(&mut self, len: usize) {
48 let (bytes, count) = encode_length(len);
49 for byte in bytes.iter().take(count) {
51 self.buf.push(*byte);
52 }
53 }
54
55 pub fn push_tag(&mut self, tag: u8) {
57 self.buf.push(tag);
58 }
59
60 pub fn len(&self) -> usize {
62 self.buf.len()
63 }
64
65 pub fn is_empty(&self) -> bool {
67 self.buf.is_empty()
68 }
69
70 pub fn push_constructed<F>(&mut self, tag: u8, f: F)
74 where
75 F: FnOnce(&mut Self),
76 {
77 let start_len = self.len();
78 f(self);
79 let content_len = self.len() - start_len;
80 self.push_length(content_len);
81 self.push_tag(tag);
82 }
83
84 pub fn push_sequence<F>(&mut self, f: F)
86 where
87 F: FnOnce(&mut Self),
88 {
89 self.push_constructed(tag::universal::SEQUENCE, f);
90 }
91
92 pub fn push_integer(&mut self, value: i32) {
94 let (arr, len) = encode_integer_stack(value);
95 self.push_bytes(&arr[4 - len..]);
97 self.push_length(len);
98 self.push_tag(tag::universal::INTEGER);
99 }
100
101 pub fn push_integer64(&mut self, value: u64) {
103 let (arr, len) = encode_integer64_stack(value);
104 self.push_bytes(&arr[9 - len..]);
106 self.push_length(len);
107 self.push_tag(tag::application::COUNTER64);
108 }
109
110 pub fn push_unsigned32(&mut self, tag: u8, value: u32) {
112 let (arr, len) = encode_unsigned32_stack(value);
113 self.push_bytes(&arr[5 - len..]);
115 self.push_length(len);
116 self.push_tag(tag);
117 }
118
119 pub fn push_octet_string(&mut self, data: &[u8]) {
121 self.push_bytes(data);
122 self.push_length(data.len());
123 self.push_tag(tag::universal::OCTET_STRING);
124 }
125
126 pub fn push_null(&mut self) {
128 self.push_length(0);
129 self.push_tag(tag::universal::NULL);
130 }
131
132 pub fn push_oid(&mut self, oid: &crate::oid::Oid) {
134 let ber = oid.to_ber_smallvec();
135 self.push_bytes(&ber);
136 self.push_length(ber.len());
137 self.push_tag(tag::universal::OBJECT_IDENTIFIER);
138 }
139
140 pub fn push_ip_address(&mut self, addr: [u8; 4]) {
142 self.push_bytes(&addr);
143 self.push_length(4);
144 self.push_tag(tag::application::IP_ADDRESS);
145 }
146
147 pub fn finish(mut self) -> Bytes {
151 self.buf.reverse();
152 Bytes::from(self.buf)
153 }
154
155 pub fn finish_vec(mut self) -> Vec<u8> {
157 self.buf.reverse();
158 self.buf
159 }
160}
161
162impl Default for EncodeBuf {
163 fn default() -> Self {
164 Self::new()
165 }
166}
167
168#[inline]
173fn encode_integer_stack(value: i32) -> ([u8; 4], usize) {
174 let bytes = value.to_be_bytes();
175
176 let mut start = 0;
178 if value >= 0 {
179 while start < 3 && bytes[start] == 0 && bytes[start + 1] & 0x80 == 0 {
181 start += 1;
182 }
183 } else {
184 while start < 3 && bytes[start] == 0xFF && bytes[start + 1] & 0x80 != 0 {
186 start += 1;
187 }
188 }
189
190 (bytes, 4 - start)
191}
192
193#[inline]
198fn encode_unsigned32_stack(value: u32) -> ([u8; 5], usize) {
199 if value == 0 {
200 return ([0, 0, 0, 0, 0], 1);
201 }
202
203 let bytes = value.to_be_bytes();
204 let mut start = 0;
205
206 while start < 3 && bytes[start] == 0 {
208 start += 1;
209 }
210
211 if bytes[start] & 0x80 != 0 {
212 let mut result = [0u8; 5];
214 result[1..].copy_from_slice(&bytes);
215 (result, 5 - start)
216 } else {
217 let mut result = [0u8; 5];
218 result[1..].copy_from_slice(&bytes);
219 (result, 4 - start)
220 }
221}
222
223#[inline]
228fn encode_integer64_stack(value: u64) -> ([u8; 9], usize) {
229 if value == 0 {
230 return ([0; 9], 1);
231 }
232
233 let bytes = value.to_be_bytes();
234 let mut start = 0;
235
236 while start < 7 && bytes[start] == 0 {
238 start += 1;
239 }
240
241 if bytes[start] & 0x80 != 0 {
242 let mut result = [0u8; 9];
244 result[1..].copy_from_slice(&bytes);
245 (result, 9 - start)
246 } else {
247 let mut result = [0u8; 9];
248 result[1..].copy_from_slice(&bytes);
249 (result, 8 - start)
250 }
251}
252
253#[cfg(test)]
254mod tests {
255 use super::*;
256
257 fn encode_integer(value: i32) -> Vec<u8> {
259 let (arr, len) = encode_integer_stack(value);
260 arr[4 - len..].to_vec()
261 }
262
263 fn encode_unsigned32(value: u32) -> Vec<u8> {
265 let (arr, len) = encode_unsigned32_stack(value);
266 arr[5 - len..].to_vec()
267 }
268
269 #[test]
270 fn test_encode_integer() {
271 assert_eq!(encode_integer(0), vec![0]);
272 assert_eq!(encode_integer(1), vec![1]);
273 assert_eq!(encode_integer(127), vec![127]);
274 assert_eq!(encode_integer(128), vec![0, 128]);
275 assert_eq!(encode_integer(-1), vec![0xFF]);
276 assert_eq!(encode_integer(-128), vec![0x80]);
277 assert_eq!(encode_integer(-129), vec![0xFF, 0x7F]);
278 }
279
280 #[test]
281 fn test_encode_unsigned32() {
282 assert_eq!(encode_unsigned32(0), vec![0]);
283 assert_eq!(encode_unsigned32(127), vec![127]);
284 assert_eq!(encode_unsigned32(128), vec![0, 128]);
285 assert_eq!(encode_unsigned32(255), vec![0, 255]);
286 assert_eq!(encode_unsigned32(256), vec![1, 0]);
287 }
288
289 #[test]
290 fn test_encode_null() {
291 let mut buf = EncodeBuf::new();
292 buf.push_null();
293 let bytes = buf.finish();
294 assert_eq!(&bytes[..], &[0x05, 0x00]);
295 }
296
297 #[test]
298 fn test_encode_integer_value() {
299 let mut buf = EncodeBuf::new();
300 buf.push_integer(42);
301 let bytes = buf.finish();
302 assert_eq!(&bytes[..], &[0x02, 0x01, 0x2A]);
303 }
304
305 #[test]
306 fn test_encode_sequence() {
307 let mut buf = EncodeBuf::new();
308 buf.push_sequence(|buf| {
309 buf.push_integer(2);
311 buf.push_integer(1);
312 });
313 let bytes = buf.finish();
314 assert_eq!(
316 &bytes[..],
317 &[0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02]
318 );
319 }
320}