1use crate::common;
2pub use encoding_asn1_derive::Marshal;
3
4pub trait Encoder {
5 fn len(&self) -> usize {
6 self.encode().len()
7 }
8 fn encode(&self) -> Vec<u8>;
9}
10
11pub struct TaggedEncoder<E1: Encoder, E2: Encoder> {
12 pub tag: E1,
13 pub body: E2,
14}
15
16impl<E1, E2> Encoder for TaggedEncoder<E1, E2>
17where
18 E1: Encoder,
19 E2: Encoder,
20{
21 fn encode(&self) -> Vec<u8> {
22 let mut v = self.tag.encode();
23 v.append(&mut self.body.encode());
24 v
25 }
26}
27
28fn base128_int_length(mut n: i64) -> i32 {
29 if n == 0 {
30 return 1;
31 }
32
33 let mut l = 0;
34 while n > 0 {
35 l += 1;
36 n >>= 7;
37 }
38
39 return l;
40}
41
42fn encode_int_using_base128(n: i64) -> Vec<u8> {
43 let mut v = vec![];
44
45 let l = base128_int_length(n);
46
47 for i in (0..l).rev() {
48 let mut o = (n >> ((i * 7) as u32)) as u8;
49 o &= 0x7f;
50 if i != 0 {
51 o |= 0x80;
52 }
53
54 v.push(o);
55 }
56
57 v
58}
59
60fn length_length(mut i: i32) -> i32 {
61 let mut num_bytes = 1;
62 while i > 255 {
63 num_bytes += 1;
64 i >>= 8;
65 }
66 num_bytes
67}
68
69fn encode_length(i: i32) -> Vec<u8> {
70 let mut v = vec![];
71 let mut n = length_length(i);
72
73 while n > 0 {
74 v.push((i >> ((n - 1) * 8)) as u8);
75 n -= 1;
76 }
77 v
78}
79
80impl Encoder for common::TagAndLength {
81 fn encode(&self) -> Vec<u8> {
82 let mut v = vec![];
83
84 let mut b = (self.class as u8) << 6;
85 if self.is_compound {
86 b |= 0x20;
87 }
88 if self.tag >= 31 {
89 b |= 0x1f;
90 v.push(b);
91 v.append(&mut encode_int_using_base128(self.tag as i64));
92 } else {
93 b |= self.tag as u8;
94 v.push(b);
95 }
96
97 if self.length >= 128 {
98 let l = length_length(self.length as i32);
99 v.push(0x80 | l as u8);
100 v.append(&mut encode_length(self.length as i32));
101 } else {
102 v.push(self.length as u8);
103 }
104
105 v
106 }
107}
108
109impl Encoder for i32 {
110 fn len(&self) -> usize {
111 let mut i = *self;
112 let mut n = 1;
113
114 while i > 127 {
115 n += 1;
116 i >>= 8;
117 }
118
119 while i < -128 {
120 n += 1;
121 i >>= 8;
122 }
123
124 return n;
125 }
126
127 fn encode(&self) -> Vec<u8> {
128 let mut v = vec![];
129 let n = self.len();
130 let i = *self;
131
132 for j in 0..n {
133 v.push((i >> ((n - 1 - j) * 8)) as u8);
134 }
135
136 v
137 }
138}
139
140impl Encoder for Vec<u8> {
141 fn len(&self) -> usize {
142 self.len()
143 }
144
145 fn encode(&self) -> Vec<u8> {
146 self.to_vec()
147 }
148}
149
150pub trait Marshaler {
151 fn marshal(&self) -> Vec<u8> {
152 self.marshal_with_params(&common::FieldParameters::default())
153 }
154 fn marshal_with_params(&self, params: &common::FieldParameters) -> Vec<u8>;
155}
156
157impl Marshaler for i32 {
158 fn marshal_with_params(&self, params: &common::FieldParameters) -> Vec<u8> {
159 let mut class = common::CLASS_UNIVERSAL;
160 let mut tag = common::TAG_INTEGER;
161 if let Some(v) = params.tag {
162 if params.application {
163 class = common::CLASS_APPLICATION;
164 } else if params.private {
165 class = common::CLASS_PRIVATE
166 } else {
167 class = common::CLASS_CONTEXT_SPECIFIC
168 }
169
170 if params.explicit {
171 let mut t = TaggedEncoder {
172 tag: common::TagAndLength {
173 class: class,
174 is_compound: true,
175 length: 0,
176 tag: v,
177 },
178 body: TaggedEncoder {
179 tag: common::TagAndLength {
180 class: 0,
181 is_compound: false,
182 length: self.len(),
183 tag: common::TAG_INTEGER,
184 },
185 body: self.encode(),
186 },
187 };
188
189 t.tag.length = t.body.len();
190
191 return t.encode();
192 }
193
194 tag = v;
196 }
197
198 let t = TaggedEncoder {
199 tag: common::TagAndLength {
200 class: class,
201 is_compound: false,
202 length: self.len(),
203 tag: tag,
204 },
205 body: self.encode(),
206 };
207
208 t.encode()
209 }
210}
211
212impl Marshaler for Vec<u8> {
213 fn marshal_with_params(&self, _params: &common::FieldParameters) -> Vec<u8> {
214 let t = TaggedEncoder {
215 tag: common::TagAndLength {
216 class: 0,
217 is_compound: false,
218 length: self.len(),
219 tag: common::TAG_OCTET_STRING,
220 },
221 body: self.encode(),
222 };
223
224 t.encode()
225 }
226}
227
228pub fn marshal<M: Marshaler>(m: &M) -> Vec<u8> {
229 m.marshal()
230}
231
232pub fn marshal_with_params<M: Marshaler>(m: &M, params: &common::FieldParameters) -> Vec<u8> {
233 m.marshal_with_params(params)
234}
235
236#[cfg(test)]
237mod tests {
238 use super::*;
239
240 #[derive(Marshal)]
241 struct IntStruct {
242 a: i32,
243 }
244
245 #[derive(Marshal)]
246 struct TwoIntStruct {
247 a: i32,
248 b: i32,
249 }
250
251 #[derive(Marshal)]
252 struct NestedStruct {
253 a: IntStruct,
254 }
255
256 #[derive(Marshal)]
257 struct ImplicitTagTest {
258 #[asn1(implicit, tag = 5)]
259 a: i32,
260 }
261
262 #[derive(Marshal)]
263 struct ExplicitTagTest {
264 #[asn1(explicit, tag = 5)]
265 a: i32,
266 }
267
268 #[test]
269 fn it_works() {
270 assert_eq!(marshal(&10), vec![0x02, 0x01, 0x0a]);
271 assert_eq!(marshal(&127), vec![0x02, 0x01, 0x7f]);
272 assert_eq!(marshal(&128), vec![0x02, 0x02, 0x00, 0x80]);
273 assert_eq!(marshal(&-128), vec![0x02, 0x01, 0x80]);
274 assert_eq!(marshal(&-129), vec![0x02, 0x02, 0xff, 0x7f]);
275 assert_eq!(
276 marshal(&IntStruct { a: 64 }),
277 vec![0x30, 0x03, 0x02, 0x01, 0x40]
278 );
279 assert_eq!(
280 marshal(&TwoIntStruct { a: 64, b: 65 }),
281 vec![0x30, 0x06, 0x02, 0x01, 0x40, 0x02, 0x01, 0x41]
282 );
283 assert_eq!(
284 marshal(&NestedStruct {
285 a: IntStruct { a: 127 }
286 }),
287 vec![0x30, 0x05, 0x30, 0x03, 0x02, 0x01, 0x7f]
288 );
289 assert_eq!(marshal(&vec![1, 2, 3]), vec![0x04, 0x03, 0x01, 0x02, 0x03]);
290 assert_eq!(
291 marshal(&ImplicitTagTest { a: 64 }),
292 vec![0x30, 0x03, 0x85, 0x01, 0x40]
293 );
294 assert_eq!(
295 marshal(&ExplicitTagTest { a: 64 }),
296 vec![0x30, 0x05, 0xa5, 0x03, 0x02, 0x01, 0x40]
297 );
298 assert_eq!(
299 marshal(&crate::types::RawValue {
300 tag: 1,
301 class: 2,
302 is_compound: false,
303 bytes: vec![0x01, 0x02, 0x03],
304 full_bytes: vec![],
305 }),
306 vec![0x81, 0x03, 0x01, 0x02, 0x03]
307 );
308 }
309}