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