bcder/decode/
source.rs

1//! The source for decoding data.
2//!
3//! This is an internal module. Its public types are re-exported by the
4//! parent.
5
6use std::{error, fmt, mem, ops};
7use std::cmp::min;
8use std::convert::Infallible;
9use bytes::Bytes;
10use super::error::{ContentError, DecodeError};
11
12
13//------------ Source --------------------------------------------------------
14
15/// A view into a sequence of octets.
16///
17/// Sources form that foundation of decoding. They provide the raw octets to
18/// decoders.
19///
20/// A source can only progress forward over time. It provides the ability to
21/// access the next few bytes as a slice or a [`Bytes`] value, and advance
22/// forward.
23///
24/// _Please note:_ This trait may change as we gain more experience with
25/// decoding in different circumstances. If you implement it for your own
26/// types, we would appreciate feedback what worked well and what didn’t.
27pub trait Source {
28    /// The error produced when the source failed to read more data.
29    type Error: error::Error;
30
31    /// Returns the current logical postion within the sequence of data.
32    fn pos(&self) -> Pos;
33
34    /// Request at least `len` bytes to be available.
35    ///
36    /// The method returns the number of bytes that are actually available.
37    /// This may only be smaller than `len` if the source ends with less
38    /// bytes available. It may be larger than `len` but less than the total
39    /// number of bytes still left in the source.
40    ///
41    /// The method can be called multiple times without advancing in between.
42    /// If in this case `len` is larger than when last called, the source
43    /// should try and make the additional data available.
44    ///
45    /// The method should only return an error if the source somehow fails
46    /// to get more data such as an IO error or reset connection.
47    fn request(&mut self, len: usize) -> Result<usize, Self::Error>;
48
49    /// Returns a bytes slice with the available data.
50    ///
51    /// The slice will be at least as long as the value returned by the last
52    /// successful [`request`] call. It may be longer if more data is
53    /// available.
54    ///
55    /// [`request`]: #tymethod.request
56    fn slice(&self) -> &[u8];
57
58    /// Produces a `Bytes` value from part of the data.
59    ///
60    /// The method returns a [`Bytes`] value of the range `start..end` from
61    /// the beginning of the current view of the source. Both indexes must
62    /// not be greater than the value returned by the last successful call
63    /// to [`request`][Self::request].
64    ///
65    /// # Panics
66    ///
67    /// The method panics if `start` or `end` are larger than the result of
68    /// the last successful call to [`request`][Self::request].
69    fn bytes(&self, start: usize, end: usize) -> Bytes;
70
71    /// Advance the source by `len` bytes.
72    ///
73    /// The method advances the start of the view provided by the source by
74    /// `len` bytes. This value must not be greater than the value returned
75    /// by the last successful call to [`request`][Self::request].
76    ///
77    /// # Panics
78    ///
79    /// The method panics if `len` is larger than the result of the last
80    /// successful call to [`request`][Self::request].
81    fn advance(&mut self, len: usize);
82
83    /// Skip over the next `len` bytes.
84    ///
85    /// The method attempts to advance the source by `len` bytes or by
86    /// however many bytes are still available if this number is smaller,
87    /// without making these bytes available.
88    ///
89    /// Returns the number of bytes skipped over. This value may only differ
90    /// from len if the remainder of the source contains less than `len`
91    /// bytes.
92    ///
93    /// The default implementation uses `request` and `advance`. However, for
94    /// some sources it may be significantly cheaper to provide a specialised
95    /// implementation.
96    fn skip(&mut self, len: usize) -> Result<usize, Self::Error> {
97        let res = min(self.request(len)?, len);
98        self.advance(res);
99        Ok(res)
100    }
101
102
103    //--- Advanced access
104
105    /// Takes a single octet from the source.
106    ///
107    /// If there aren’t any more octets available from the source, returns
108    /// a content error.
109    fn take_u8(&mut self) -> Result<u8, DecodeError<Self::Error>> {
110        if self.request(1)? < 1 {
111            return Err(self.content_err("unexpected end of data"))
112        }
113        let res = self.slice()[0];
114        self.advance(1);
115        Ok(res)
116    }
117
118    /// Takes an optional octet from the source.
119    ///
120    /// If there aren’t any more octets available from the source, returns
121    /// `Ok(None)`.
122    fn take_opt_u8(&mut self) -> Result<Option<u8>, Self::Error> {
123        if self.request(1)? < 1 {
124            return Ok(None)
125        }
126        let res = self.slice()[0];
127        self.advance(1);
128        Ok(Some(res))
129    }
130
131    /// Returns a content error at the current position of the source.
132    fn content_err(
133        &self, err: impl Into<ContentError>
134    ) -> DecodeError<Self::Error> {
135        DecodeError::content(err.into(), self.pos())
136    }
137}
138
139impl<T: Source> Source for &'_ mut T {
140    type Error = T::Error;
141
142    fn request(&mut self, len: usize) -> Result<usize, Self::Error> {
143        Source::request(*self, len)
144    }
145    
146    fn advance(&mut self, len: usize) {
147        Source::advance(*self, len)
148    }
149
150    fn slice(&self) -> &[u8] {
151        Source::slice(*self)
152    }
153
154    fn bytes(&self, start: usize, end: usize) -> Bytes {
155        Source::bytes(*self, start, end)
156    }
157
158    fn pos(&self) -> Pos {
159        Source::pos(*self)
160    }
161}
162
163
164//------------ IntoSource ----------------------------------------------------
165
166/// A type that can be converted into a source.
167pub trait IntoSource {
168    type Source: Source;
169
170    fn into_source(self) -> Self::Source;
171}
172
173impl<T: Source> IntoSource for T {
174    type Source = Self;
175
176    fn into_source(self) -> Self::Source {
177        self
178    }
179}
180
181
182//------------ Pos -----------------------------------------------------------
183
184/// The logical position within a source.
185///
186/// Values of this type can only be used for diagnostics. They can not be used
187/// to determine how far a source has been advanced since it was created. This
188/// is why we used a newtype.
189#[derive(Clone, Copy, Debug, Default)]
190pub struct Pos(usize);
191
192impl From<usize> for Pos {
193    fn from(pos: usize) -> Pos {
194        Pos(pos)
195    }
196}
197
198impl ops::Add for Pos {
199    type Output = Self;
200
201    fn add(self, rhs: Self) -> Self {
202        Pos(self.0 + rhs.0)
203    }
204}
205
206impl fmt::Display for Pos {
207    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
208        self.0.fmt(f)
209    }
210}
211
212
213//------------ BytesSource ---------------------------------------------------
214
215/// A source for a bytes value.
216#[derive(Clone, Debug)]
217pub struct BytesSource {
218    /// The bytes.
219    data: Bytes,
220
221    /// The current read position in the data.
222    pos: usize,
223
224    /// The offset for the reported position.
225    ///
226    /// This is the value reported by `Source::pos` when `self.pos` is zero.
227    offset: Pos,
228}
229
230impl BytesSource {
231    /// Creates a new bytes source from a bytes values.
232    pub fn new(data: Bytes) -> Self {
233        BytesSource { data, pos: 0, offset: 0.into() }
234    }
235
236    /// Creates a new bytes source with an explicit offset.
237    ///
238    /// When this function is used to create a bytes source, `Source::pos`
239    /// will report a value increates by `offset`.
240    pub fn with_offset(data: Bytes, offset: Pos) -> Self {
241        BytesSource { data, pos: 0, offset }
242    }
243
244    /// Returns the remaining length of data.
245    pub fn len(&self) -> usize {
246        self.data.len()
247    }
248
249    /// Returns whether there is any data remaining.
250    pub fn is_empty(&self) -> bool {
251        self.data.is_empty()
252    }
253
254    /// Splits the first `len` bytes off the source and returns them.
255    ///
256    /// # Panics
257    ///
258    /// This method panics of `len` is larger than `self.len()`.
259    pub fn split_to(&mut self, len: usize) -> Bytes {
260        let res = self.data.split_to(len);
261        self.pos += len;
262        res
263    }
264
265    /// Converts the source into the remaining bytes.
266    pub fn into_bytes(self) -> Bytes {
267        self.data
268    }
269}
270
271impl Source for BytesSource {
272    type Error = Infallible;
273
274    fn pos(&self) -> Pos {
275        self.offset + self.pos.into()
276    }
277
278    fn request(&mut self, _len: usize) -> Result<usize, Self::Error> {
279        Ok(self.data.len())
280    }
281
282    fn slice(&self) -> &[u8] {
283        self.data.as_ref()
284    }
285
286    fn bytes(&self, start: usize, end: usize) -> Bytes {
287        self.data.slice(start..end)
288    }
289
290    fn advance(&mut self, len: usize) {
291        assert!(len <= self.data.len());
292        bytes::Buf::advance(&mut self.data, len);
293        self.pos += len;
294    }
295}
296
297impl IntoSource for Bytes {
298    type Source = BytesSource;
299
300    fn into_source(self) -> Self::Source {
301        BytesSource::new(self)
302    }
303}
304
305
306//------------ SliceSource ---------------------------------------------------
307
308#[derive(Clone, Copy, Debug)]
309pub struct SliceSource<'a> {
310    data: &'a [u8],
311    pos: usize
312}
313
314impl<'a> SliceSource<'a> {
315    /// Creates a new bytes source from a slice.
316    pub fn new(data: &'a [u8]) -> Self {
317        SliceSource { data, pos: 0 }
318    }
319
320    /// Returns the remaining length of data.
321    pub fn len(&self) -> usize {
322        self.data.len()
323    }
324
325    /// Returns whether there is any data remaining.
326    pub fn is_empty(&self) -> bool {
327        self.data.is_empty()
328    }
329
330    /// Splits the first `len` bytes off the source and returns them.
331    ///
332    /// # Panics
333    ///
334    /// This method panics of `len` is larger than `self.len()`.
335    pub fn split_to(&mut self, len: usize) -> &'a [u8] {
336        let (left, right) = self.data.split_at(len);
337        self.data = right;
338        self.pos += len;
339        left
340    }
341}
342
343impl Source for SliceSource<'_> {
344    type Error = Infallible;
345
346    fn pos(&self) -> Pos {
347        self.pos.into()
348    }
349
350    fn request(&mut self, _len: usize) -> Result<usize, Self::Error> {
351        Ok(self.data.len())
352    }
353
354    fn advance(&mut self, len: usize) {
355        assert!(len <= self.data.len());
356        self.data = &self.data[len..];
357        self.pos += len;
358    }
359
360    fn slice(&self) -> &[u8] {
361        self.data
362    }
363
364    fn bytes(&self, start: usize, end: usize) -> Bytes {
365        Bytes::copy_from_slice(&self.data[start..end])
366    }
367}
368
369impl<'a> IntoSource for &'a [u8] {
370    type Source = SliceSource<'a>;
371
372    fn into_source(self) -> Self::Source {
373        SliceSource::new(self)
374    }
375}
376
377
378//------------ LimitedSource -------------------------------------------------
379
380/// A source that can be limited to a certain number of octets.
381///
382/// This type wraps another source and allows access to be limited to a
383/// certain number of octets. It will never provide access to more than
384/// that number of octets. Any attempt to advance over more octets will
385/// fail with a malformed error.
386///
387/// The limit is, however, independent of the underlying source. It can
388/// be larger than the number of octets actually available in the source.
389///
390/// The limit can be changed or even removed at any time.
391#[derive(Clone, Debug)]
392pub struct LimitedSource<S> {
393    /// The source this value wraps.
394    source: S,
395
396    /// The current limit.
397    ///
398    /// If `limit` is `None`, there is no limit. If there is a limit, it
399    /// will be decreased by calls to `advance` accordingly. I.e., this is
400    /// the current limit, not the original limit.
401    limit: Option<usize>,
402}
403
404/// # General Management
405///
406impl<S> LimitedSource<S> {
407    /// Creates a new limited source for the given source.
408    ///
409    /// The return limited source will have no limit just yet.
410    pub fn new(source: S) -> Self {
411        LimitedSource {
412            source,
413            limit: None
414        }
415    }
416
417    /// Unwraps the value and returns the source it was created from.
418    pub fn unwrap(self) -> S {
419        self.source
420    }
421
422    /// Returns the current limit.
423    ///
424    /// Returns `None` if there is no limit. Otherwise, the number returned
425    /// is the number of remaining octets before the limit is reached. This
426    /// does not necessarily mean that that many octets are actually
427    /// available in the underlying source.
428    pub fn limit(&self) -> Option<usize> {
429        self.limit
430    }
431
432    /// Sets a more strict limit.
433    ///
434    /// The method will panic (!) if you are trying to set a new limit that
435    /// is larger than the current limit or if you are trying to remove
436    /// the limit by passing `None` if there currently is a limit set.
437    ///
438    /// Returns the old limit.
439    pub fn limit_further(&mut self, limit: Option<usize>) -> Option<usize> {
440        if let Some(cur) = self.limit {
441            match limit {
442                Some(limit) => assert!(limit <= cur),
443                None => panic!("relimiting to unlimited"),
444            }
445        }
446        mem::replace(&mut self.limit, limit)
447    }
448
449    /// Unconditionally sets a new limit.
450    ///
451    /// If you pass `None`, the limit will be removed.
452    pub fn set_limit(&mut self, limit: Option<usize>) {
453        self.limit = limit
454    }
455}
456
457/// # Advanced Access
458///
459impl<S: Source> LimitedSource<S> {
460    /// Skip over all remaining octets until the current limit is reached.
461    ///
462    /// If there currently is no limit, the method will panic. Otherwise it
463    /// will simply advance to the end of the limit which may be something
464    /// the underlying source doesn’t like and thus produce an error.
465    pub fn skip_all(&mut self) -> Result<(), DecodeError<S::Error>> {
466        let limit = self.limit.unwrap();
467        if self.request(limit)? < limit {
468            return Err(self.content_err("unexpected end of data"))
469        }
470        self.advance(limit);
471        Ok(())
472    }
473
474    /// Returns a bytes value containing all octets until the current limit.
475    ///
476    /// If there currently is no limit, the method will panic. Otherwise it
477    /// tries to acquire a bytes value for the octets from the current
478    /// position to the end of the limit and advance to the end of the limit.
479    ///
480    /// This will result in a source error if the underlying source returns
481    /// an error. It will result in a content error if the underlying source
482    /// ends before the limit is reached.
483    pub fn take_all(&mut self) -> Result<Bytes, DecodeError<S::Error>> {
484        let limit = self.limit.unwrap();
485        if self.request(limit)? < limit {
486            return Err(self.content_err("unexpected end of data"))
487        }
488        let res = self.bytes(0, limit);
489        self.advance(limit);
490        Ok(res)
491    }
492
493    /// Checks whether the end of the limit has been reached.
494    ///
495    /// If a limit is currently set, the method will return a malformed
496    /// error if it is larger than zero, i.e., if there are octets left to
497    /// advance over before reaching the limit.
498    ///
499    /// If there is no limit set, the method will try to access one single
500    /// octet and return a malformed error if that is actually possible, i.e.,
501    /// if there are octets left in the underlying source.
502    ///
503    /// Any source errors are passed through. If there the data is not
504    /// exhausted as described above, a content error is created.
505    pub fn exhausted(&mut self) -> Result<(), DecodeError<S::Error>> {
506        match self.limit {
507            Some(0) => Ok(()),
508            Some(_limit) => Err(self.content_err("trailing data")),
509            None => {
510                if self.source.request(1)? == 0 {
511                    Ok(())
512                }
513                else {
514                    Err(self.content_err("trailing data"))
515                }
516            }
517        }
518    }
519}
520
521impl<S: Source> Source for LimitedSource<S> {
522    type Error = S::Error;
523
524    fn pos(&self) -> Pos {
525        self.source.pos()
526    }
527
528    fn request(&mut self, len: usize) -> Result<usize, Self::Error> {
529        if let Some(limit) = self.limit {
530            Ok(min(limit, self.source.request(min(limit, len))?))
531        }
532        else {
533            self.source.request(len)
534        }
535    }
536
537    fn advance(&mut self, len: usize) {
538        if let Some(limit) = self.limit {
539            assert!(
540                len <= limit,
541                "advanced past end of limit"
542            );
543            self.limit = Some(limit - len);
544        }
545        self.source.advance(len)
546    }
547
548    fn slice(&self) -> &[u8] {
549        let res = self.source.slice();
550        if let Some(limit) = self.limit {
551            if res.len() > limit {
552                return &res[..limit]
553            }
554        }
555        res
556    }
557
558    fn bytes(&self, start: usize, end: usize) -> Bytes {
559        if let Some(limit) = self.limit {
560            assert!(start <= limit);
561            assert!(end <= limit);
562        }
563        self.source.bytes(start, end)
564    }
565}
566
567
568//------------ CaptureSource -------------------------------------------------
569
570/// A source that captures what has been advanced over.
571///
572/// A capture source wraps a mutable reference to some other source and
573/// provides the usual source access. However, instead of dropping octets
574/// that have been advanced over, it keeps them around and allows taking
575/// them out as a bytes value.
576///
577/// This type is used by [`Constructed::capture`].
578///
579/// [`Constructed::capture`]: struct.Constructed.html#method.capture
580pub struct CaptureSource<'a, S: 'a> {
581    /// The wrapped real source.
582    source: &'a mut S,
583
584    /// The number of bytes the source has promised to have for us.
585    len: usize,
586
587    /// The position in the source our view starts at.
588    pos: usize,
589}
590
591impl<'a, S: Source> CaptureSource<'a, S> {
592    /// Creates a new capture source using a reference to some other source.
593    pub fn new(source: &'a mut S) -> Self {
594        CaptureSource {
595            source,
596            len: 0,
597            pos: 0,
598        }
599    }
600
601    /// Converts the capture source into the captured bytes.
602    pub fn into_bytes(self) -> Bytes {
603        let res = self.source.bytes(0, self.pos);
604        self.skip();
605        res
606    }
607
608    /// Drops the captured bytes.
609    ///
610    /// Advances the underlying source to the end of the captured bytes.
611    pub fn skip(self) {
612        self.source.advance(self.pos)
613    }
614}
615
616impl<'a, S: Source + 'a> Source for CaptureSource<'a, S> {
617    type Error = S::Error;
618
619    fn pos(&self) -> Pos {
620        self.source.pos() + self.pos.into()
621    }
622
623    fn request(&mut self, len: usize) -> Result<usize, Self::Error> {
624        self.len = self.source.request(self.pos + len)?;
625        Ok(self.len - self.pos)
626    }
627
628    fn slice(&self) -> &[u8] {
629        &self.source.slice()[self.pos..]
630    }
631
632    fn bytes(&self, start: usize, end: usize) -> Bytes {
633        let start = start + self.pos;
634        let end = end + self.pos;
635        assert!(
636            self.len >= start,
637            "start past the end of data"
638        );
639        assert!(
640            self.len >= end,
641            "end past the end of data"
642        );
643        self.source.bytes(start, end)
644    }
645
646    fn advance(&mut self, len: usize) {
647        assert!(
648            self.len >= self.pos + len,
649            "advanced past the end of data"
650        );
651        self.pos += len;
652    }
653}
654
655
656//============ Tests =========================================================
657
658#[cfg(test)]
659mod test {
660    use super::*;
661
662    #[test]
663    fn take_u8() {
664        let mut source = b"123".into_source();
665        assert_eq!(source.take_u8().unwrap(), b'1');
666        assert_eq!(source.take_u8().unwrap(), b'2');
667        assert_eq!(source.take_u8().unwrap(), b'3');
668        assert!(source.take_u8().is_err())
669    }
670
671    #[test]
672    fn take_opt_u8() {
673        let mut source = b"123".into_source();
674        assert_eq!(source.take_opt_u8().unwrap(), Some(b'1'));
675        assert_eq!(source.take_opt_u8().unwrap(), Some(b'2'));
676        assert_eq!(source.take_opt_u8().unwrap(), Some(b'3'));
677        assert_eq!(source.take_opt_u8().unwrap(), None);
678    }
679
680    #[test]
681    fn bytes_impl() {
682        let mut bytes = Bytes::from_static(b"1234567890").into_source();
683        assert!(bytes.request(4).unwrap() >= 4);
684        assert!(&Source::slice(&bytes)[..4] == b"1234");
685        assert_eq!(bytes.bytes(2, 4), Bytes::from_static(b"34"));
686        Source::advance(&mut bytes, 4);
687        assert!(bytes.request(4).unwrap() >= 4);
688        assert!(&Source::slice(&bytes)[..4] == b"5678");
689        Source::advance(&mut bytes, 4);
690        assert_eq!(bytes.request(4).unwrap(), 2);
691        assert!(&Source::slice(&bytes) == b"90");
692        bytes.advance(2);
693        assert_eq!(bytes.request(4).unwrap(), 0);
694    }
695
696    #[test]
697    fn slice_impl() {
698        let mut bytes = b"1234567890".into_source();
699        assert!(bytes.request(4).unwrap() >= 4);
700        assert!(&bytes.slice()[..4] == b"1234");
701        assert_eq!(bytes.bytes(2, 4), Bytes::from_static(b"34"));
702        bytes.advance(4);
703        assert!(bytes.request(4).unwrap() >= 4);
704        assert!(&bytes.slice()[..4] == b"5678");
705        bytes.advance(4);
706        assert_eq!(bytes.request(4).unwrap(), 2);
707        assert!(&bytes.slice() == b"90");
708        bytes.advance(2);
709        assert_eq!(bytes.request(4).unwrap(), 0);
710    }
711
712    #[test]
713    fn limited_source() {
714        let mut the_source = LimitedSource::new(
715            b"12345678".into_source()
716        );
717        the_source.set_limit(Some(4));
718
719        let mut source = the_source.clone();
720        assert!(source.exhausted().is_err());
721        assert_eq!(source.request(6).unwrap(), 4);
722        source.advance(2);
723        assert!(source.exhausted().is_err());
724        assert_eq!(source.request(6).unwrap(), 2);
725        source.advance(2);
726        source.exhausted().unwrap();
727        assert_eq!(source.request(6).unwrap(), 0);
728
729        let mut source = the_source.clone();
730        source.skip_all().unwrap();
731        let source = source.unwrap();
732        assert_eq!(source.slice(), b"5678");
733
734        let mut source = the_source.clone();
735        assert_eq!(source.take_all().unwrap(), Bytes::from_static(b"1234"));
736        source.exhausted().unwrap();
737        let source = source.unwrap();
738        assert_eq!(source.slice(), b"5678");
739    }
740
741    #[test]
742    #[should_panic]
743    fn limited_source_far_advance() {
744        let mut source = LimitedSource::new(
745            b"12345678".into_source()
746        );
747        source.set_limit(Some(4));
748        assert_eq!(source.request(6).unwrap(), 4);
749        source.advance(4);
750        assert_eq!(source.request(6).unwrap(), 0);
751        source.advance(6); // panics
752    }
753
754    #[test]
755    #[should_panic]
756    fn limit_further() {
757        let mut source = LimitedSource::new(b"12345".into_source());
758        source.set_limit(Some(4));
759        source.limit_further(Some(5)); // panics
760    }
761
762    #[test]
763    fn capture_source() {
764        let mut source = b"1234567890".into_source();
765        {
766            let mut capture = CaptureSource::new(&mut source);
767            assert_eq!(capture.request(4).unwrap(), 10);
768            capture.advance(4);
769            assert_eq!(capture.into_bytes(), Bytes::from_static(b"1234"));
770        }
771        assert_eq!(source.data, b"567890");
772
773        let mut source = b"1234567890".into_source();
774        {
775            let mut capture = CaptureSource::new(&mut source);
776            assert_eq!(capture.request(4).unwrap(), 10);
777            capture.advance(4);
778            capture.skip();
779        }
780        assert_eq!(source.data, b"567890");
781    }
782}
783