ntcip/dms/
oer.rs

1// oer.rs
2//
3// Copyright (C) 2023  Minnesota Department of Transportation
4//
5//! OER encoding
6
7/// OER encoder
8pub struct Oer(Vec<u8>);
9
10impl From<Vec<u8>> for Oer {
11    fn from(vec: Vec<u8>) -> Self {
12        Oer(vec)
13    }
14}
15
16impl From<Oer> for Vec<u8> {
17    fn from(oer: Oer) -> Self {
18        oer.0
19    }
20}
21
22impl Oer {
23    /// Integer constrained to 0 - 255
24    pub fn u8(&mut self, v: u8) {
25        self.0.push(v);
26    }
27
28    /// Integer constrained to 0 - 65_535
29    pub fn u16(&mut self, v: u16) {
30        self.0.push((v >> 8) as u8);
31        self.0.push(v as u8);
32    }
33
34    // idk, is this even a thing?
35    fn u24(&mut self, v: u32) {
36        self.0.push((v >> 16) as u8);
37        self.0.push((v >> 8) as u8);
38        self.0.push(v as u8);
39    }
40
41    /// Integer constrained to 0 - 4_294_967_295
42    pub fn u32(&mut self, v: u32) {
43        self.0.push((v >> 24) as u8);
44        self.0.push((v >> 16) as u8);
45        self.0.push((v >> 8) as u8);
46        self.0.push(v as u8);
47    }
48
49    /// Encode a length prefix
50    fn length_prefix(&mut self, len: u32) {
51        if len <= 0x7F {
52            self.0.push(len as u8);
53        } else if len <= 0xFF {
54            self.0.push(128 | 1);
55            self.u8(len as u8);
56        } else if len <= 0xFFFF {
57            self.0.push(128 | 2);
58            self.u16(len as u16);
59        } else if len <= 0xFFFFFF {
60            self.0.push(128 | 3);
61            self.u24(len);
62        } else {
63            self.0.push(128 | 4);
64            self.u32(len);
65        }
66    }
67
68    // Unsigned integer (unconstrained)
69    pub fn uint(&mut self, v: u32) {
70        if v <= 0xFF {
71            self.length_prefix(1);
72            self.u8(v as u8);
73        } else if v <= 0xFFFF {
74            self.length_prefix(2);
75            self.u16(v as u16);
76        } else if v <= 0xFFFFFF {
77            self.length_prefix(3);
78            self.u24(v);
79        } else {
80            self.length_prefix(4);
81            self.u32(v);
82        }
83    }
84
85    /// Octet string (unconstrained)
86    pub fn octet_string(&mut self, octets: &[u8]) {
87        self.length_prefix(octets.len() as u32);
88        self.0.extend(octets);
89    }
90
91    /// Octet string (constrained)
92    pub fn octet_str(&mut self, octets: &[u8]) {
93        self.0.extend(octets);
94    }
95}