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_length(&mut self, len: usize) {
43 let (bytes, count) = encode_length(len);
44 for byte in bytes.iter().take(count) {
46 self.buf.push(*byte);
47 }
48 }
49
50 pub fn push_tag(&mut self, tag: u8) {
52 self.buf.push(tag);
53 }
54
55 pub fn len(&self) -> usize {
57 self.buf.len()
58 }
59
60 pub fn is_empty(&self) -> bool {
62 self.buf.is_empty()
63 }
64
65 pub fn push_constructed<F>(&mut self, tag: u8, f: F)
69 where
70 F: FnOnce(&mut Self),
71 {
72 let start_len = self.len();
73 f(self);
74 let content_len = self.len() - start_len;
75 self.push_length(content_len);
76 self.push_tag(tag);
77 }
78
79 pub fn push_sequence<F>(&mut self, f: F)
81 where
82 F: FnOnce(&mut Self),
83 {
84 self.push_constructed(tag::universal::SEQUENCE, f);
85 }
86
87 pub fn push_integer(&mut self, value: i32) {
89 let (arr, len) = encode_integer_stack(value);
90 self.push_bytes(&arr[4 - len..]);
92 self.push_length(len);
93 self.push_tag(tag::universal::INTEGER);
94 }
95
96 pub fn push_integer64(&mut self, value: u64) {
98 let (arr, len) = encode_integer64_stack(value);
99 self.push_bytes(&arr[9 - len..]);
101 self.push_length(len);
102 self.push_tag(tag::application::COUNTER64);
103 }
104
105 pub fn push_unsigned32(&mut self, tag: u8, value: u32) {
107 let (arr, len) = encode_unsigned32_stack(value);
108 self.push_bytes(&arr[5 - len..]);
110 self.push_length(len);
111 self.push_tag(tag);
112 }
113
114 pub fn push_octet_string(&mut self, data: &[u8]) {
116 self.push_bytes(data);
117 self.push_length(data.len());
118 self.push_tag(tag::universal::OCTET_STRING);
119 }
120
121 pub fn push_null(&mut self) {
123 self.push_length(0);
124 self.push_tag(tag::universal::NULL);
125 }
126
127 pub fn push_oid(&mut self, oid: &crate::oid::Oid) {
129 let ber = oid.to_ber_smallvec();
130 self.push_bytes(&ber);
131 self.push_length(ber.len());
132 self.push_tag(tag::universal::OBJECT_IDENTIFIER);
133 }
134
135 pub fn push_ip_address(&mut self, addr: [u8; 4]) {
137 self.push_bytes(&addr);
138 self.push_length(4);
139 self.push_tag(tag::application::IP_ADDRESS);
140 }
141
142 pub fn finish(mut self) -> Bytes {
146 self.buf.reverse();
147 Bytes::from(self.buf)
148 }
149
150 pub fn finish_vec(mut self) -> Vec<u8> {
152 self.buf.reverse();
153 self.buf
154 }
155}
156
157impl Default for EncodeBuf {
158 fn default() -> Self {
159 Self::new()
160 }
161}
162
163#[inline]
168fn encode_integer_stack(value: i32) -> ([u8; 4], usize) {
169 let bytes = value.to_be_bytes();
170
171 let mut start = 0;
173 if value >= 0 {
174 while start < 3 && bytes[start] == 0 && bytes[start + 1] & 0x80 == 0 {
176 start += 1;
177 }
178 } else {
179 while start < 3 && bytes[start] == 0xFF && bytes[start + 1] & 0x80 != 0 {
181 start += 1;
182 }
183 }
184
185 (bytes, 4 - start)
186}
187
188#[inline]
193fn encode_unsigned32_stack(value: u32) -> ([u8; 5], usize) {
194 if value == 0 {
195 return ([0, 0, 0, 0, 0], 1);
196 }
197
198 let bytes = value.to_be_bytes();
199 let mut start = 0;
200
201 while start < 3 && bytes[start] == 0 {
203 start += 1;
204 }
205
206 if bytes[start] & 0x80 != 0 {
207 let mut result = [0u8; 5];
209 result[1..].copy_from_slice(&bytes);
210 (result, 5 - start)
211 } else {
212 let mut result = [0u8; 5];
213 result[1..].copy_from_slice(&bytes);
214 (result, 4 - start)
215 }
216}
217
218#[inline]
223fn encode_integer64_stack(value: u64) -> ([u8; 9], usize) {
224 if value == 0 {
225 return ([0; 9], 1);
226 }
227
228 let bytes = value.to_be_bytes();
229 let mut start = 0;
230
231 while start < 7 && bytes[start] == 0 {
233 start += 1;
234 }
235
236 if bytes[start] & 0x80 != 0 {
237 let mut result = [0u8; 9];
239 result[1..].copy_from_slice(&bytes);
240 (result, 9 - start)
241 } else {
242 let mut result = [0u8; 9];
243 result[1..].copy_from_slice(&bytes);
244 (result, 8 - start)
245 }
246}
247
248#[cfg(test)]
249mod tests {
250 use super::*;
251
252 fn encode_integer(value: i32) -> Vec<u8> {
254 let (arr, len) = encode_integer_stack(value);
255 arr[4 - len..].to_vec()
256 }
257
258 fn encode_unsigned32(value: u32) -> Vec<u8> {
260 let (arr, len) = encode_unsigned32_stack(value);
261 arr[5 - len..].to_vec()
262 }
263
264 #[test]
265 fn test_encode_integer() {
266 assert_eq!(encode_integer(0), vec![0]);
267 assert_eq!(encode_integer(1), vec![1]);
268 assert_eq!(encode_integer(127), vec![127]);
269 assert_eq!(encode_integer(128), vec![0, 128]);
270 assert_eq!(encode_integer(-1), vec![0xFF]);
271 assert_eq!(encode_integer(-128), vec![0x80]);
272 assert_eq!(encode_integer(-129), vec![0xFF, 0x7F]);
273 }
274
275 #[test]
276 fn test_encode_unsigned32() {
277 assert_eq!(encode_unsigned32(0), vec![0]);
278 assert_eq!(encode_unsigned32(127), vec![127]);
279 assert_eq!(encode_unsigned32(128), vec![0, 128]);
280 assert_eq!(encode_unsigned32(255), vec![0, 255]);
281 assert_eq!(encode_unsigned32(256), vec![1, 0]);
282 }
283
284 #[test]
285 fn test_encode_null() {
286 let mut buf = EncodeBuf::new();
287 buf.push_null();
288 let bytes = buf.finish();
289 assert_eq!(&bytes[..], &[0x05, 0x00]);
290 }
291
292 #[test]
293 fn test_encode_integer_value() {
294 let mut buf = EncodeBuf::new();
295 buf.push_integer(42);
296 let bytes = buf.finish();
297 assert_eq!(&bytes[..], &[0x02, 0x01, 0x2A]);
298 }
299
300 #[test]
301 fn test_encode_sequence() {
302 let mut buf = EncodeBuf::new();
303 buf.push_sequence(|buf| {
304 buf.push_integer(2);
306 buf.push_integer(1);
307 });
308 let bytes = buf.finish();
309 assert_eq!(
311 &bytes[..],
312 &[0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02]
313 );
314 }
315}