asn1_rs/to_ber/
encoder.rs1use std::io::{self, Write};
2
3use crate::{Class, Length, Tag};
4
5pub trait BerEncoder {
10 fn new() -> Self;
12
13 fn write_tag_info<W: Write>(
16 &mut self,
17 class: Class,
18 constructed: bool,
19 tag: Tag,
20 target: &mut W,
21 ) -> Result<usize, io::Error> {
22 self.write_tag_generic(class, constructed, tag, target)
23 }
24
25 fn write_tag_generic<W: Write>(
29 &mut self,
30 class: Class,
31 constructed: bool,
32 tag: Tag,
33 target: &mut W,
34 ) -> Result<usize, io::Error> {
35 let class = class as u8;
36
37 const CONSTRUCTED_BIT: u8 = 0b0010_0000;
38 let cs = if constructed { CONSTRUCTED_BIT } else { 0 };
39
40 if tag.0 < 31 {
42 let b0 = (class << 6) | cs | (tag.0 as u8);
44 target.write(&[b0])
45 } else {
46 let b0 = (class << 6) | cs | 0b1_1111;
50 let mut sz = target.write(&[b0])?;
51
52 let mut val = tag.0;
54
55 const BUF_SZ: usize = 8;
56 let mut buffer = [0u8; BUF_SZ];
57 let mut current_index = BUF_SZ - 1;
58
59 buffer[current_index] = (val & 0x7f) as u8;
61 val >>= 7;
62
63 while val > 0 {
64 current_index -= 1;
65 if current_index == 0 {
66 return Err(io::Error::new(io::ErrorKind::InvalidData, "tag too long"));
68 }
69 buffer[current_index] = (val & 0x7f) as u8 | 0x80;
70 val >>= 7;
71 }
72
73 sz += target.write(&buffer[current_index..])?;
74 Ok(sz)
75 }
76 }
77
78 fn write_length<W: Write>(
80 &mut self,
81 length: Length,
82 target: &mut W,
83 ) -> Result<usize, io::Error> {
84 const INDEFINITE: u8 = 0b1000_0000;
85 match length {
86 Length::Indefinite => target.write(&[INDEFINITE]),
87 Length::Definite(n) => {
88 if n <= 127 {
89 target.write(&[n as u8])
91 } else {
92 let b = n.to_be_bytes();
94 let mut idx = 0;
97 while b[idx] == 0 {
98 idx += 1;
99 }
100 let b = &b[idx..];
101 let b0 = 0x80 | (b.len() as u8);
103 let sz = target.write(&[b0])?;
104 let sz = sz + target.write(b)?;
105 Ok(sz)
106 }
107 }
108 }
109 }
110}
111
112#[cfg(test)]
113mod tests {
114 use hex_literal::hex;
115
116 use crate::{BerEncoder, Length, Primitive};
117
118 #[test]
119 fn tober_write_length() {
120 let mut encoder = Primitive::<0>::new();
121 let mut v: Vec<u8> = Vec::new();
122
123 v.clear();
125 encoder
126 .write_length(Length::Indefinite, &mut v)
127 .expect("serialization failed");
128 assert_eq!(&v, &hex!("80"));
129
130 v.clear();
132 encoder
133 .write_length(Length::Definite(2), &mut v)
134 .expect("serialization failed");
135 assert_eq!(&v, &hex!("02"));
136
137 v.clear();
139 encoder
140 .write_length(Length::Definite(300), &mut v)
141 .expect("serialization failed");
142 assert_eq!(&v, &hex!("82 01 2c"));
143 }
144}