bcder/captured.rs
1//! Captured BER-encoded data.
2//!
3//! This is a private module. Its public items are re-exported by the parent.
4
5use std::{fmt, io, mem, ops};
6use bytes::{Bytes, BytesMut};
7use crate::{decode, encode};
8use crate::decode::{BytesSource, DecodeError, IntoSource, Pos};
9use crate::mode::Mode;
10
11
12//------------ Captured ------------------------------------------------------
13
14/// A wrapper for BER encoded data.
15///
16/// This types keeps a sequence of BER-encoded data in a [`Bytes`] value. It
17/// allows for delayed processing of this data and therefore zero-allocation
18/// handling of sequences and similar types by implementing iterators and
19/// helper types that work directly on the the still-encoded data.
20///
21/// You usually acquire a value of this type trough the [`capture`] family of
22/// methods on constructed BER content. Alternatively, you can also construct
23/// a new value via the [`CapturedBuilder`].
24///
25/// Once you have a captured value, you can use the [`decode`] method to
26/// decode the entire captured value or [`decode_partial`] to decode some
27/// values at the start of the captured value. The latter manipulates the
28/// captured content by moving past the captured values and is therefore
29/// perfect for an iterator.
30///
31/// The value also remembers what [`Mode`] the original data was decoded in
32/// and will automatically use this encoding in those methods.
33///
34/// [`Bytes`]: ../../bytes/struct.Bytes.html
35/// [`capture`]: ../decode/struct.Constructed.html
36/// [`from_values`]: #method.from_values
37/// [`empty`]: #method.empty
38/// [`decode`]: #method.decode
39/// [`decode_partial`]: #method.decode
40/// [`Mode`]: ../enum.Mode.html
41#[derive(Clone)]
42pub struct Captured {
43 /// The captured data.
44 bytes: Bytes,
45
46 /// The encoding mode of the captured data.
47 mode: Mode,
48
49 /// The start position of the data in the original source.
50 start: Pos,
51}
52
53impl Captured {
54 /// Creates a new captured value from bytes and a mode.
55 ///
56 /// Because we can’t guarantee that the bytes are properly encoded, we
57 /// keep this function crate public. The type, however, doesn’t rely on
58 /// content being properly encoded so this method isn’t unsafe.
59 pub(crate) fn new(bytes: Bytes, mode: Mode, start: Pos) -> Self {
60 Captured { bytes, mode, start }
61 }
62
63 /// Creates a captured value by encoding data.
64 ///
65 /// The function takes a value encoder, encodes it into a bytes value
66 /// with the given mode, and returns the resulting data as a captured
67 /// value.
68 pub fn from_values<V: encode::Values>(mode: Mode, values: V) -> Self {
69 let mut builder = Self::builder(mode);
70 builder.extend(values);
71 builder.freeze()
72 }
73
74 /// Creates a new empty captured value in the given mode.
75 pub fn empty(mode: Mode) -> Self {
76 Captured {
77 bytes: Bytes::new(),
78 mode,
79 start: Pos::default(),
80 }
81 }
82
83 /// Creates a builder for a captured value in the given mode.
84 pub fn builder(mode: Mode) -> CapturedBuilder {
85 CapturedBuilder::new(mode)
86 }
87
88 /// Converts the captured values into a builder in order to add new values.
89 ///
90 /// Because the captured values might be shared, this requires copying the
91 /// underlying data.
92 pub fn into_builder(self) -> CapturedBuilder {
93 self.into()
94 }
95
96 /// Decodes the full content using the provided function argument.
97 ///
98 /// The method consumes the value. If you want to keep it around, simply
99 /// clone it first. Since bytes values are cheap to clone, this is
100 /// relatively cheap.
101 pub fn decode<F, T>(
102 self, op: F
103 ) -> Result<T, DecodeError<<BytesSource as decode::Source>::Error>>
104 where
105 F: FnOnce(
106 &mut decode::Constructed<BytesSource>
107 ) -> Result<T, DecodeError<<BytesSource as decode::Source>::Error>>
108 {
109 self.mode.decode(self.bytes, op)
110 }
111
112 /// Decodes the beginning of the content of the captured value.
113 ///
114 /// The method calls `op` to parse a number of values from the beginning
115 /// of the value and then advances the content of the captured value until
116 /// after the end of these decoded values.
117 pub fn decode_partial<F, T>(
118 &mut self, op: F
119 ) -> Result<T, DecodeError<<BytesSource as decode::Source>::Error>>
120 where
121 F: FnOnce(
122 &mut decode::Constructed<&mut BytesSource>
123 ) -> Result<T, DecodeError<<BytesSource as decode::Source>::Error>>
124 {
125 let mut source = mem::replace(
126 &mut self.bytes, Bytes::new()
127 ).into_source();
128 let res = self.mode.decode(&mut source, op);
129 self.bytes = source.into_bytes();
130 res
131 }
132
133 /// Trades the value for a bytes value with the raw data.
134 pub fn into_bytes(self) -> Bytes {
135 self.bytes
136 }
137
138 /// Returns a bytes slice with the raw data of the captured value.
139 pub fn as_slice(&self) -> &[u8] {
140 self.bytes.as_ref()
141 }
142}
143
144
145//--- Deref and AsRef
146
147impl ops::Deref for Captured {
148 type Target = Bytes;
149
150 fn deref(&self) -> &Bytes {
151 &self.bytes
152 }
153}
154
155impl AsRef<Bytes> for Captured {
156 fn as_ref(&self) -> &Bytes {
157 &self.bytes
158 }
159}
160
161impl AsRef<[u8]> for Captured {
162 fn as_ref(&self) -> &[u8] {
163 self.bytes.as_ref()
164 }
165}
166
167
168//--- IntoSource
169
170impl IntoSource for Captured {
171 type Source = BytesSource;
172
173 fn into_source(self) -> Self::Source {
174 BytesSource::with_offset(self.bytes, self.start)
175 }
176}
177
178
179//--- encode::Values
180
181impl encode::Values for Captured {
182 fn encoded_len(&self, mode: Mode) -> usize {
183 assert!(
184 !(self.mode != mode && mode != Mode::Ber),
185 "Trying to encode a captured value with incompatible mode"
186 );
187 self.bytes.len()
188 }
189
190 fn write_encoded<W: io::Write>(
191 &self,
192 mode: Mode,
193 target: &mut W
194 ) -> Result<(), io::Error> {
195 assert!(
196 !(self.mode != mode && mode != Mode::Ber),
197 "Trying to encode a captured value with incompatible mode"
198 );
199 target.write_all(self.bytes.as_ref())
200 }
201}
202
203
204//--- Debug
205
206impl fmt::Debug for Captured {
207 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
208 write!(f, "[ ")?;
209 for (i, &v) in self.bytes.iter().enumerate() {
210 write!(f, "{:02x} ", v)?;
211 if i % 4 == 3 {
212 write!(f, " ")?;
213 }
214 }
215 write!(f, "]")
216 }
217}
218
219
220//------------ CapturedBuilder -----------------------------------------------
221
222pub struct CapturedBuilder {
223 bytes: BytesMut,
224 mode: Mode,
225}
226
227impl CapturedBuilder {
228 pub fn new(mode: Mode) -> Self {
229 CapturedBuilder {
230 bytes: BytesMut::new(),
231 mode
232 }
233 }
234
235 pub fn with_capacity(capacity: usize, mode: Mode) -> Self {
236 CapturedBuilder {
237 bytes: BytesMut::with_capacity(capacity),
238 mode
239 }
240 }
241
242 /// Extends the captured value by encoding the given values.
243 ///
244 /// The function encodes the given values in the captured value’s own mode
245 /// and places the encoded content at the end of the captured value.
246 pub fn extend<V: encode::Values>(&mut self, values: V) {
247 values.write_encoded(
248 self.mode,
249 &mut CapturedWriter(&mut self.bytes)
250 ).unwrap()
251 }
252
253 pub fn freeze(self) -> Captured {
254 Captured::new(self.bytes.freeze(), self.mode, Pos::default())
255 }
256}
257
258impl From<Captured> for CapturedBuilder {
259 fn from(src: Captured) -> Self {
260 CapturedBuilder {
261 bytes: src.bytes.as_ref().into(),
262 mode: src.mode
263 }
264 }
265}
266
267
268//------------ CapturedWriter ------------------------------------------------
269
270struct CapturedWriter<'a>(&'a mut BytesMut);
271
272impl io::Write for CapturedWriter<'_> {
273 fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
274 self.0.extend_from_slice(buf);
275 Ok(buf.len())
276 }
277
278 fn flush(&mut self) -> Result<(), io::Error> {
279 Ok(())
280 }
281}
282