asn1_codecs/per/aper/encode/
mod.rs

1//! ASN.1 Aper Encoder module.
2
3use bitvec::prelude::*;
4
5use crate::per::PerCodecData;
6
7#[allow(unused)]
8use crate::per::common::encode::*;
9
10use crate::PerCodecError;
11
12/// Encode a Choice Index
13///
14/// During Encoding a 'CHOICE' Type to help decoding, the 'CHOICE' Index is encoded first, followed
15/// by the actual encoding of the 'CHOICE' variant.
16pub fn encode_choice_idx(
17    data: &mut PerCodecData,
18    lb: i128,
19    ub: i128,
20    is_extensible: bool,
21    idx: i128,
22    extended: bool,
23) -> Result<(), PerCodecError> {
24    log::trace!(
25        "encode_choice_idx: lb: {}, ub: {}, is_extensible: {}, idx: {}, extended: {}",
26        lb,
27        ub,
28        is_extensible,
29        idx,
30        extended
31    );
32
33    encode_choice_idx_common(data, lb, ub, is_extensible, idx, extended, true)
34}
35
36/// Encode sequence header
37pub fn encode_sequence_header(
38    data: &mut PerCodecData,
39    is_extensible: bool,
40    optionals: &BitSlice<u8, Msb0>,
41    extended: bool,
42) -> Result<(), PerCodecError> {
43    log::trace!(
44        "encode_sequence_header: is_extensible: {}, optional_fields: {:?}, extended: {}",
45        is_extensible,
46        optionals,
47        extended
48    );
49
50    encode_sequence_header_common(data, is_extensible, optionals, extended, true)
51}
52
53/// Encode an INTEGER
54///
55/// This API is also used by other `encode` functions to encode an integer value.
56///
57/// Note: The maximum (and minimum) value to be decoded is limited to an `i128` value. For the
58/// protocols that are currently supported this limit is acceptable.
59pub fn encode_integer(
60    data: &mut PerCodecData,
61    lb: Option<i128>,
62    ub: Option<i128>,
63    is_extensible: bool,
64    value: i128,
65    extended: bool,
66) -> Result<(), PerCodecError> {
67    log::trace!(
68        "encode_integer: lb: {:?}, ub: {:?}, is_extensible: {}, value: {}, extended: {}",
69        lb,
70        ub,
71        is_extensible,
72        value,
73        extended
74    );
75
76    encode_integer_common(data, lb, ub, is_extensible, value, extended, true)
77}
78
79/// Encode a BOOLEAN Value
80///
81/// Encodes a boolean value into the passed `PerCodecData` structure.
82pub fn encode_bool(data: &mut PerCodecData, value: bool) -> Result<(), PerCodecError> {
83    log::trace!("encode_bool: {}", value);
84
85    encode_bool_common(data, value, true)
86}
87
88/// Encode a REAL Value
89///
90/// Encodes a boolean value into the passed `PerCodecData` structure.
91pub fn encode_real(data: &mut PerCodecData, value: f64) -> Result<(), PerCodecError> {
92    log::trace!("encode_real: {}", value);
93    encode_real_common(data, value, true)
94}
95
96/// Encode an ENUMERATED Value
97pub fn encode_enumerated(
98    data: &mut PerCodecData,
99    lb: Option<i128>,
100    ub: Option<i128>,
101    is_extensible: bool,
102    value: i128,
103    extended: bool,
104) -> Result<(), PerCodecError> {
105    log::trace!(
106        "encode_enumerated: lb: {:?}, ub: {:?}, is_extensible: {}, value: {}, extended: {}",
107        lb,
108        ub,
109        is_extensible,
110        value,
111        extended
112    );
113
114    encode_enumerated_common(data, lb, ub, is_extensible, value, extended, true)
115}
116
117/// Encode a Bit String
118pub fn encode_bitstring(
119    data: &mut PerCodecData,
120    lb: Option<i128>,
121    ub: Option<i128>,
122    is_extensible: bool,
123    bit_string: &BitSlice<u8, Msb0>,
124    extended: bool,
125) -> Result<(), PerCodecError> {
126    log::trace!(
127        "encode_bitstring: lb: {:?}, ub: {:?}, is_extensible: {}, bits: {:?}, extended: {}",
128        lb,
129        ub,
130        is_extensible,
131        bit_string,
132        extended
133    );
134
135    encode_bitstring_common(data, lb, ub, is_extensible, bit_string, extended, true)
136}
137
138/// Encode an OCTET STRING
139pub fn encode_octetstring(
140    data: &mut PerCodecData,
141    lb: Option<i128>,
142    ub: Option<i128>,
143    is_extensible: bool,
144    octet_string: &Vec<u8>,
145    extended: bool,
146) -> Result<(), PerCodecError> {
147    log::trace!(
148        "encode_octetstring: lb: {:?}, ub: {:?}, is_extensible: {}, bytes: {:?}, extended: {}",
149        lb,
150        ub,
151        is_extensible,
152        octet_string,
153        extended
154    );
155
156    encode_octet_string_common(data, lb, ub, is_extensible, octet_string, extended, true)
157}
158
159// Encode a Length Determinent
160pub fn encode_length_determinent(
161    data: &mut PerCodecData,
162    lb: Option<i128>,
163    ub: Option<i128>,
164    normally_small: bool,
165    value: usize,
166) -> Result<(), PerCodecError> {
167    log::trace!(
168        "encode_length_determinent: lb: {:?}, ub: {:?}, normally_small: {}, value: {}",
169        lb,
170        ub,
171        normally_small,
172        value
173    );
174
175    encode_length_determinent_common(data, lb, ub, normally_small, value, true)
176}
177
178/// Encode a VisibleString CharacterString Type.
179pub fn encode_visible_string(
180    data: &mut PerCodecData,
181    lb: Option<i128>,
182    ub: Option<i128>,
183    is_extensible: bool,
184    value: &String,
185    extended: bool,
186) -> Result<(), PerCodecError> {
187    log::trace!(
188        "encode_visible_string: lb: {:?}, ub: {:?}, is_extensible: {}, value: {}, extended: {}",
189        lb,
190        ub,
191        is_extensible,
192        value,
193        extended
194    );
195
196    encode_string_common(data, lb, ub, is_extensible, value, extended, true)
197}
198
199/// Encode a PrintableString CharacterString Type.
200pub fn encode_printable_string(
201    data: &mut PerCodecData,
202    lb: Option<i128>,
203    ub: Option<i128>,
204    is_extensible: bool,
205    value: &String,
206    extended: bool,
207) -> Result<(), PerCodecError> {
208    log::trace!(
209        "encode_printable_string: lb: {:?}, ub: {:?}, is_extensible: {}, value: {}, extended: {}",
210        lb,
211        ub,
212        is_extensible,
213        value,
214        extended
215    );
216
217    encode_string_common(data, lb, ub, is_extensible, value, extended, true)
218}
219
220/// Encode a UTF8String CharacterString Type.
221pub fn encode_utf8_string(
222    data: &mut PerCodecData,
223    lb: Option<i128>,
224    ub: Option<i128>,
225    is_extensible: bool,
226    value: &String,
227    extended: bool,
228) -> Result<(), PerCodecError> {
229    log::trace!(
230        "encode_utf8_string: lb: {:?}, ub: {:?}, is_extensible: {}, value: {}, extended: {}",
231        lb,
232        ub,
233        is_extensible,
234        value,
235        extended
236    );
237
238    encode_string_common(data, lb, ub, is_extensible, value, extended, true)
239}
240
241/// Encode a UTCTime CharacterString Type.
242pub fn encode_utc_time(
243    data: &mut PerCodecData,
244    lb: Option<i128>,
245    ub: Option<i128>,
246    is_extensible: bool,
247    value: &String,
248    extended: bool,
249) -> Result<(), PerCodecError> {
250    log::trace!(
251        "encode_utc_time: lb: {:?}, ub: {:?}, is_extensible: {}, value: {}, extended: {}",
252        lb,
253        ub,
254        is_extensible,
255        value,
256        extended
257    );
258
259    encode_string_common(data, lb, ub, is_extensible, value, extended, true)
260}
261
262#[cfg(test)]
263mod tests {
264
265    use super::*;
266
267    #[test]
268    fn encode_bool_always_success() {
269        let mut data = PerCodecData::new_aper();
270
271        let result = encode_bool(&mut data, true);
272        assert!(result.is_ok());
273        assert_eq!(data.bits.len(), 1);
274        assert_eq!(data.bits[0], true);
275    }
276
277    #[test]
278    fn int_too_small() {
279        assert!(encode_integer(
280            &mut PerCodecData::new_aper(),
281            Some(1),
282            None,
283            false,
284            0,
285            false
286        )
287        .is_err());
288    }
289
290    #[test]
291    fn int_too_big() {
292        assert!(encode_integer(
293            &mut PerCodecData::new_aper(),
294            Some(-1),
295            Some(0),
296            false,
297            1,
298            false
299        )
300        .is_err());
301    }
302
303    #[test]
304    fn octetstring_too_small() {
305        assert!(encode_octetstring(
306            &mut PerCodecData::new_aper(),
307            Some(2),
308            None,
309            false,
310            &vec![0],
311            false
312        )
313        .is_err());
314    }
315    #[test]
316    fn octetstring_too_big() {
317        assert!(encode_octetstring(
318            &mut PerCodecData::new_aper(),
319            None,
320            Some(1),
321            false,
322            &vec![0, 0],
323            false
324        )
325        .is_err());
326    }
327
328    #[test]
329    fn string_too_small() {
330        assert!(encode_visible_string(
331            &mut PerCodecData::new_aper(),
332            Some(2),
333            None,
334            false,
335            &"a".to_string(),
336            false
337        )
338        .is_err());
339    }
340
341    #[test]
342    fn string_too_big() {
343        assert!(encode_visible_string(
344            &mut PerCodecData::new_aper(),
345            None,
346            Some(1),
347            false,
348            &"aa".to_string(),
349            false
350        )
351        .is_err());
352    }
353
354    #[test]
355    fn length_too_small() {
356        assert!(
357            encode_length_determinent(&mut PerCodecData::new_aper(), Some(2), None, false, 1,)
358                .is_err()
359        );
360    }
361    #[test]
362    fn length_too_big() {
363        assert!(
364            encode_length_determinent(&mut PerCodecData::new_aper(), None, Some(1), false, 2,)
365                .is_err()
366        );
367    }
368
369    #[test]
370    fn big_length_too_big() {
371        assert!(encode_length_determinent(
372            &mut PerCodecData::new_aper(),
373            None,
374            Some(65536),
375            false,
376            65537,
377        )
378        .is_err());
379    }
380
381    #[test]
382    fn bitstring_too_small() {
383        assert!(encode_bitstring(
384            &mut PerCodecData::new_aper(),
385            Some(2),
386            None,
387            false,
388            bits![u8, Msb0; 0],
389            false
390        )
391        .is_err());
392    }
393
394    #[test]
395    fn bitstring_too_big() {
396        assert!(encode_bitstring(
397            &mut PerCodecData::new_aper(),
398            None,
399            Some(1),
400            false,
401            bits![u8, Msb0; 0, 0],
402            false
403        )
404        .is_err());
405    }
406}