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