1 //! Reader type for consuming nested TLV records within a DER document.
2 
3 use crate::{reader::Reader, Error, ErrorKind, Header, Length, Result};
4 
5 /// Reader type used by [`Reader::read_nested`].
6 pub struct NestedReader<'i, R> {
7     /// Inner reader type.
8     inner: &'i mut R,
9 
10     /// Nested input length.
11     input_len: Length,
12 
13     /// Position within the nested input.
14     position: Length,
15 }
16 
17 impl<'i, 'r, R: Reader<'r>> NestedReader<'i, R> {
18     /// Create a new nested reader which can read the given [`Length`].
new(inner: &'i mut R, len: Length) -> Result<Self>19     pub(crate) fn new(inner: &'i mut R, len: Length) -> Result<Self> {
20         if len <= inner.remaining_len() {
21             Ok(Self {
22                 inner,
23                 input_len: len,
24                 position: Length::ZERO,
25             })
26         } else {
27             Err(ErrorKind::Incomplete {
28                 expected_len: (inner.offset() + len)?,
29                 actual_len: (inner.offset() + inner.remaining_len())?,
30             }
31             .at(inner.offset()))
32         }
33     }
34 
35     /// Move the position cursor the given length, returning an error if there
36     /// isn't enough remaining data in the nested input.
advance_position(&mut self, len: Length) -> Result<()>37     fn advance_position(&mut self, len: Length) -> Result<()> {
38         let new_position = (self.position + len)?;
39 
40         if new_position <= self.input_len {
41             self.position = new_position;
42             Ok(())
43         } else {
44             Err(ErrorKind::Incomplete {
45                 expected_len: (self.inner.offset() + len)?,
46                 actual_len: (self.inner.offset() + self.remaining_len())?,
47             }
48             .at(self.inner.offset()))
49         }
50     }
51 }
52 
53 impl<'i, 'r, R: Reader<'r>> Reader<'r> for NestedReader<'i, R> {
input_len(&self) -> Length54     fn input_len(&self) -> Length {
55         self.input_len
56     }
57 
peek_byte(&self) -> Option<u8>58     fn peek_byte(&self) -> Option<u8> {
59         if self.is_finished() {
60             None
61         } else {
62             self.inner.peek_byte()
63         }
64     }
65 
peek_header(&self) -> Result<Header>66     fn peek_header(&self) -> Result<Header> {
67         if self.is_finished() {
68             Err(Error::incomplete(self.offset()))
69         } else {
70             // TODO(tarcieri): handle peeking past nested length
71             self.inner.peek_header()
72         }
73     }
74 
position(&self) -> Length75     fn position(&self) -> Length {
76         self.position
77     }
78 
read_slice(&mut self, len: Length) -> Result<&'r [u8]>79     fn read_slice(&mut self, len: Length) -> Result<&'r [u8]> {
80         self.advance_position(len)?;
81         self.inner.read_slice(len)
82     }
83 
error(&mut self, kind: ErrorKind) -> Error84     fn error(&mut self, kind: ErrorKind) -> Error {
85         self.inner.error(kind)
86     }
87 
offset(&self) -> Length88     fn offset(&self) -> Length {
89         self.inner.offset()
90     }
91 
read_into<'o>(&mut self, out: &'o mut [u8]) -> Result<&'o [u8]>92     fn read_into<'o>(&mut self, out: &'o mut [u8]) -> Result<&'o [u8]> {
93         self.advance_position(Length::try_from(out.len())?)?;
94         self.inner.read_into(out)
95     }
96 }
97