1use bitvec::prelude::*;
4
5use crate::{PerCodecData, PerCodecError, PerCodecErrorCause};
6
7#[allow(unused)]
8use crate::per::common::encode::*;
9
10pub fn encode_choice_idx(
15 data: &mut PerCodecData,
16 lb: i128,
17 ub: i128,
18 is_extensible: bool,
19 idx: i128,
20 extended: bool,
21) -> Result<(), PerCodecError> {
22 log::trace!(
23 "encode_choice_idx: lb: {}, ub: {}, is_extensible: {}, idx: {}, extended: {}",
24 lb,
25 ub,
26 is_extensible,
27 idx,
28 extended
29 );
30
31 encode_choice_idx_common(data, lb, ub, is_extensible, idx, extended, false)
32}
33
34pub fn encode_sequence_header(
36 data: &mut PerCodecData,
37 is_extensible: bool,
38 optionals: &BitSlice<u8, Msb0>,
39 extended: bool,
40) -> Result<(), PerCodecError> {
41 log::trace!(
42 "encode_sequence_header: is_extensible: {}, optional_fields: {:?}, extended: {}",
43 is_extensible,
44 optionals,
45 extended
46 );
47
48 encode_sequence_header_common(data, is_extensible, optionals, extended, false)
49}
50
51pub fn encode_integer(
58 data: &mut PerCodecData,
59 lb: Option<i128>,
60 ub: Option<i128>,
61 is_extensible: bool,
62 value: i128,
63 extended: bool,
64) -> Result<(), PerCodecError> {
65 log::trace!(
66 "encode_integer: lb: {:?}, ub: {:?}, is_extensible: {}, value: {}, extended: {}",
67 lb,
68 ub,
69 is_extensible,
70 value,
71 extended
72 );
73
74 encode_integer_common(data, lb, ub, is_extensible, value, extended, false)
75}
76
77pub fn encode_bool(data: &mut PerCodecData, value: bool) -> Result<(), PerCodecError> {
81 log::trace!("encode_bool: {}", value);
82
83 encode_bool_common(data, value, true)
84}
85
86pub fn encode_real(data: &mut PerCodecData, value: f64) -> Result<(), PerCodecError> {
90 log::trace!("encode_real: {}", value);
91 encode_real_common(data, value, false)
92}
93
94pub fn encode_enumerated(
96 data: &mut PerCodecData,
97 lb: Option<i128>,
98 ub: Option<i128>,
99 is_extensible: bool,
100 value: i128,
101 extended: bool,
102) -> Result<(), PerCodecError> {
103 log::trace!(
104 "encode_enumerated: lb: {:?}, ub: {:?}, is_extensible: {}, value: {}, extended: {}",
105 lb,
106 ub,
107 is_extensible,
108 value,
109 extended
110 );
111
112 encode_enumerated_common(data, lb, ub, is_extensible, value, extended, false)
113}
114
115pub fn encode_bitstring(
117 data: &mut PerCodecData,
118 lb: Option<i128>,
119 ub: Option<i128>,
120 is_extensible: bool,
121 bit_string: &BitSlice<u8, Msb0>,
122 extended: bool,
123) -> Result<(), PerCodecError> {
124 log::trace!(
125 "encode_bitstring: lb: {:?}, ub: {:?}, is_extensible: {}, bits: {:?}, extended: {}",
126 lb,
127 ub,
128 is_extensible,
129 bit_string,
130 extended
131 );
132
133 encode_bitstring_common(data, lb, ub, is_extensible, bit_string, extended, false)
134}
135
136pub fn encode_octetstring(
138 data: &mut PerCodecData,
139 lb: Option<i128>,
140 ub: Option<i128>,
141 is_extensible: bool,
142 octet_string: &Vec<u8>,
143 extended: bool,
144) -> Result<(), PerCodecError> {
145 log::trace!(
146 "encode_octetstring: lb: {:?}, ub: {:?}, is_extensible: {}, bytes: {:?}, extended: {}",
147 lb,
148 ub,
149 is_extensible,
150 octet_string,
151 extended
152 );
153
154 encode_octet_string_common(data, lb, ub, is_extensible, octet_string, extended, false)
155}
156
157pub fn encode_length_determinent(
159 data: &mut PerCodecData,
160 lb: Option<i128>,
161 ub: Option<i128>,
162 normally_small: bool,
163 value: usize,
164) -> Result<(), PerCodecError> {
165 log::trace!(
166 "encode_length_determinent: lb: {:?}, ub: {:?}, normally_small: {}, value: {}",
167 lb,
168 ub,
169 normally_small,
170 value
171 );
172
173 encode_length_determinent_common(data, lb, ub, normally_small, value, false)
174}
175
176pub fn encode_visible_string(
178 data: &mut PerCodecData,
179 lb: Option<i128>,
180 ub: Option<i128>,
181 is_extensible: bool,
182 value: &String,
183 extended: bool,
184) -> Result<(), PerCodecError> {
185 log::trace!(
186 "encode_visible_string: lb: {:?}, ub: {:?}, is_extensible: {}, value: {}, extended: {}",
187 lb,
188 ub,
189 is_extensible,
190 value,
191 extended
192 );
193
194 encode_ascii_ish_string_common(data, lb, ub, is_extensible, value, extended)
195}
196
197pub fn encode_printable_string(
199 data: &mut PerCodecData,
200 lb: Option<i128>,
201 ub: Option<i128>,
202 is_extensible: bool,
203 value: &String,
204 extended: bool,
205) -> Result<(), PerCodecError> {
206 log::trace!(
207 "encode_printable_string: lb: {:?}, ub: {:?}, is_extensible: {}, value: {}, extended: {}",
208 lb,
209 ub,
210 is_extensible,
211 value,
212 extended
213 );
214
215 encode_ascii_ish_string_common(data, lb, ub, is_extensible, value, extended)
216}
217
218pub fn encode_utf8_string(
220 data: &mut PerCodecData,
221 lb: Option<i128>,
222 ub: Option<i128>,
223 is_extensible: bool,
224 value: &String,
225 extended: bool,
226) -> Result<(), PerCodecError> {
227 log::trace!(
228 "encode_utf8_string: lb: {:?}, ub: {:?}, is_extensible: {}, value: {}, extended: {}",
229 lb,
230 ub,
231 is_extensible,
232 value,
233 extended
234 );
235
236 encode_octet_string_common(
237 data,
238 lb,
239 ub,
240 is_extensible,
241 value.as_bytes(),
242 extended,
243 false,
244 )
245}
246
247pub fn encode_utc_time(
249 data: &mut PerCodecData,
250 lb: Option<i128>,
251 ub: Option<i128>,
252 is_extensible: bool,
253 value: &String,
254 extended: bool,
255) -> Result<(), PerCodecError> {
256 log::trace!(
257 "encode_utc_time: lb: {:?}, ub: {:?}, is_extensible: {}, value: {}, extended: {}",
258 lb,
259 ub,
260 is_extensible,
261 value,
262 extended
263 );
264
265 encode_octet_string_common(
266 data,
267 lb,
268 ub,
269 is_extensible,
270 value.as_bytes(),
271 extended,
272 false,
273 )
274}
275
276fn encode_ascii_ish_string_common(
278 data: &mut PerCodecData,
279 lb: Option<i128>,
280 ub: Option<i128>,
281 is_extensible: bool,
282 value: &String,
283 extended: bool,
284) -> Result<(), PerCodecError> {
285 if extended {
286 return Err(PerCodecError::new(
287 PerCodecErrorCause::EncodeNotSupported,
288 "Encode of extended octetstring not yet implemented",
289 ));
290 }
291
292 if is_extensible {
293 data.encode_bool(extended);
294 }
295
296 encode_length_determinent_common(data, lb, ub, false, value.len(), false)?;
297
298 let bits_per_char = 7;
300 let offset = 8 - bits_per_char;
301 let chars_vec = value
302 .chars()
303 .map(|c| BitSlice::<_, Msb0>::from_element(&(c as u8))[offset..].to_bitvec())
304 .collect::<Vec<_>>()
305 .into_iter()
306 .flatten()
307 .collect::<BitVec<u8, Msb0>>();
308
309 data.append_bits(chars_vec.as_bitslice());
310
311 Ok(())
312}
313
314#[cfg(test)]
315mod tests {
316
317 use super::*;
318
319 #[test]
320 fn encode_bool_always_success() {
321 let mut data = PerCodecData::new_uper();
322
323 let result = encode_bool(&mut data, true);
324 assert!(result.is_ok());
325 assert_eq!(data.bits.len(), 1);
326 assert_eq!(data.bits[0], true);
327 }
328
329 #[test]
330 fn int_too_small() {
331 assert!(encode_integer(
332 &mut PerCodecData::new_uper(),
333 Some(1),
334 None,
335 false,
336 0,
337 false
338 )
339 .is_err());
340 }
341
342 #[test]
343 fn int_too_big() {
344 assert!(encode_integer(
345 &mut PerCodecData::new_uper(),
346 Some(-1),
347 Some(0),
348 false,
349 1,
350 false
351 )
352 .is_err());
353 }
354
355 #[test]
356 fn octetstring_too_small() {
357 assert!(encode_octetstring(
358 &mut PerCodecData::new_uper(),
359 Some(2),
360 None,
361 false,
362 &vec![0],
363 false
364 )
365 .is_err());
366 }
367 #[test]
368 fn octetstring_too_big() {
369 assert!(encode_octetstring(
370 &mut PerCodecData::new_uper(),
371 None,
372 Some(1),
373 false,
374 &vec![0, 0],
375 false
376 )
377 .is_err());
378 }
379
380 #[test]
381 fn string_too_small() {
382 assert!(encode_visible_string(
383 &mut PerCodecData::new_uper(),
384 Some(2),
385 None,
386 false,
387 &"a".to_string(),
388 false
389 )
390 .is_err());
391 }
392
393 #[test]
394 fn string_too_big() {
395 assert!(encode_visible_string(
396 &mut PerCodecData::new_uper(),
397 None,
398 Some(1),
399 false,
400 &"aa".to_string(),
401 false
402 )
403 .is_err());
404 }
405
406 #[test]
407 fn length_too_small() {
408 assert!(
409 encode_length_determinent(&mut PerCodecData::new_uper(), Some(2), None, false, 1,)
410 .is_err()
411 );
412 }
413 #[test]
414 fn length_too_big() {
415 assert!(
416 encode_length_determinent(&mut PerCodecData::new_uper(), None, Some(1), false, 2,)
417 .is_err()
418 );
419 }
420
421 #[test]
422 fn big_length_too_big() {
423 assert!(encode_length_determinent(
424 &mut PerCodecData::new_uper(),
425 None,
426 Some(65536),
427 false,
428 65537,
429 )
430 .is_err());
431 }
432
433 #[test]
434 fn bitstring_too_small() {
435 assert!(encode_bitstring(
436 &mut PerCodecData::new_uper(),
437 Some(2),
438 None,
439 false,
440 bits![u8, Msb0; 0],
441 false
442 )
443 .is_err());
444 }
445
446 #[test]
447 fn bitstring_too_big() {
448 assert!(encode_bitstring(
449 &mut PerCodecData::new_uper(),
450 None,
451 Some(1),
452 false,
453 bits![u8, Msb0; 0, 0],
454 false
455 )
456 .is_err());
457 }
458
459 #[test]
460 fn bitstring_uper_ascii_ish_string() {
461 let value = "John".to_string();
463 let mut codec_data = &mut PerCodecData::new_uper();
464 let result = encode_visible_string(&mut codec_data, None, None, false, &value, false);
465 assert!(result.is_ok(), "{:#?}", result.err().unwrap());
466 }
467}