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