1#![cfg(feature = "std")]
2
3use std::io::Write;
4
5use crate::{Class, Header, InnerError, Length, SerializeResult, Tag};
6
7mod constructed;
8mod constructed_indefinite;
9mod encoder;
10mod generic;
11mod primitive;
12
13pub use constructed::*;
14pub use constructed_indefinite::*;
15pub use encoder::*;
16pub use generic::*;
17pub use primitive::*;
18
19pub trait ToBer {
24 type Encoder: BerEncoder;
25
26 fn ber_content_len(&self) -> Length;
30
31 fn ber_total_len(&self) -> Length {
33 let (_, _, tag) = self.ber_tag_info();
34 let content_length = self.ber_content_len();
35 ber_total_length(tag, content_length)
36 }
37
38 fn ber_tag_info(&self) -> (Class, bool, Tag);
40
41 fn ber_write_content<W: Write>(&self, target: &mut W) -> SerializeResult<usize>;
45
46 fn ber_write_header<W: Write>(&self, target: &mut W) -> SerializeResult<usize> {
50 let mut encoder = Self::Encoder::new();
51
52 let mut sz = 0;
53 let (class, constructed, tag) = self.ber_tag_info();
54 sz += encoder.write_tag_info(class, constructed, tag, target)?;
55
56 let length = self.ber_content_len();
58 sz += encoder.write_length(length, target)?;
59
60 Ok(sz)
61 }
62
63 fn ber_encode<W: Write>(&self, target: &mut W) -> SerializeResult<usize> {
67 let sz = self.ber_write_header(target)? + self.ber_write_content(target)?;
68
69 Ok(sz)
70 }
71
72 fn ber_encode_tagged_explicit<W: Write>(
78 &self,
79 class: Class,
80 tag_number: u32,
81 target: &mut W,
82 ) -> SerializeResult<usize> {
83 let length = self.ber_total_len();
84 let tagged_header = Header::new(class, true, Tag(tag_number), length);
85 let sz = tagged_header.ber_write_header(target)?
86 + self.ber_write_header(target)?
87 + self.ber_write_content(target)?;
88
89 Ok(sz)
90 }
91
92 fn ber_encode_tagged_implicit<W: Write>(
98 &self,
99 class: Class,
100 tag_number: u32,
101 target: &mut W,
102 ) -> SerializeResult<usize> {
103 let length = self.ber_content_len();
104 let (_, constructed, _) = self.ber_tag_info();
105 let tagged_header = Header::new(class, constructed, Tag(tag_number), length);
106 let sz = tagged_header.ber_write_header(target)? + self.ber_write_content(target)?;
107
108 Ok(sz)
109 }
110
111 fn to_ber_vec(&self) -> SerializeResult<Vec<u8>> {
113 let mut v = Vec::new();
114 self.ber_encode(&mut v)?;
115 Ok(v)
116 }
117
118 fn write_ber<W: Write>(&self, writer: &mut W) -> SerializeResult<usize> {
122 self.ber_encode(writer)
123 }
124}
125
126impl<E, T: ToBer> ToBer for &'_ T
129where
130 T: ToBer<Encoder = E>,
131 E: BerEncoder,
132{
133 type Encoder = <T as ToBer>::Encoder;
134
135 fn ber_content_len(&self) -> Length {
136 (*self).ber_content_len()
137 }
138
139 fn ber_tag_info(&self) -> (Class, bool, Tag) {
140 (*self).ber_tag_info()
141 }
142
143 fn ber_write_content<W: Write>(&self, target: &mut W) -> SerializeResult<usize> {
144 (*self).ber_write_content(target)
145 }
146}
147
148pub fn ber_tag_length(tag: Tag) -> usize {
152 match tag.0 {
153 0..=30 => 1,
154 t => {
155 let mut sz = 1;
156 let mut val = t;
157 loop {
158 if val <= 127 {
159 return sz + 1;
160 } else {
161 val >>= 7;
162 sz += 1;
163 }
164 }
165 }
166 }
167}
168
169pub fn ber_length_length(length: Length) -> Result<usize, InnerError> {
171 match length {
172 Length::Indefinite => Ok(1),
173 Length::Definite(l) => match l {
174 0..=0x7f => Ok(1),
175 0x80..=0xff => Ok(2),
176 0x100..=0xffff => Ok(3),
177 0x1_0000..=0xffff_ffff => Ok(4),
178 _ => Err(InnerError::InvalidLength),
179 },
180 }
181}
182
183pub fn ber_total_length(tag: Tag, content_length: Length) -> Length {
187 let header_len = ber_header_length(tag, content_length).unwrap_or(0);
188 content_length + header_len
189}
190
191pub fn ber_header_length(tag: Tag, length: Length) -> Result<usize, InnerError> {
195 let sz = ber_tag_length(tag);
196 let sz = sz + ber_length_length(length)?;
197 Ok(sz)
198}
199
200pub fn ber_length_constructed_items<'a, T, IT>(iter: IT) -> Length
207where
208 T: ToBer + 'a,
209 IT: Iterator<Item = &'a T>,
210{
211 iter.map(|t| t.ber_total_len()).sum()
212}