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