Coverage Report

Created: 2025-10-10 06:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/der-0.7.10/src/reader/nested.rs
Line
Count
Source
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`].
19
0
    pub(crate) fn new(inner: &'i mut R, len: Length) -> Result<Self> {
20
0
        if len <= inner.remaining_len() {
21
0
            Ok(Self {
22
0
                inner,
23
0
                input_len: len,
24
0
                position: Length::ZERO,
25
0
            })
26
        } else {
27
            Err(ErrorKind::Incomplete {
28
0
                expected_len: (inner.offset() + len)?,
29
0
                actual_len: (inner.offset() + inner.remaining_len())?,
30
            }
31
0
            .at(inner.offset()))
32
        }
33
0
    }
34
35
    /// Move the position cursor the given length, returning an error if there
36
    /// isn't enough remaining data in the nested input.
37
0
    fn advance_position(&mut self, len: Length) -> Result<()> {
38
0
        let new_position = (self.position + len)?;
39
40
0
        if new_position <= self.input_len {
41
0
            self.position = new_position;
42
0
            Ok(())
43
        } else {
44
            Err(ErrorKind::Incomplete {
45
0
                expected_len: (self.inner.offset() + len)?,
46
0
                actual_len: (self.inner.offset() + self.remaining_len())?,
47
            }
48
0
            .at(self.inner.offset()))
49
        }
50
0
    }
51
}
52
53
impl<'i, 'r, R: Reader<'r>> Reader<'r> for NestedReader<'i, R> {
54
0
    fn input_len(&self) -> Length {
55
0
        self.input_len
56
0
    }
57
58
0
    fn peek_byte(&self) -> Option<u8> {
59
0
        if self.is_finished() {
60
0
            None
61
        } else {
62
0
            self.inner.peek_byte()
63
        }
64
0
    }
65
66
0
    fn peek_header(&self) -> Result<Header> {
67
0
        if self.is_finished() {
68
0
            Err(Error::incomplete(self.offset()))
69
        } else {
70
            // TODO(tarcieri): handle peeking past nested length
71
0
            self.inner.peek_header()
72
        }
73
0
    }
74
75
0
    fn position(&self) -> Length {
76
0
        self.position
77
0
    }
78
79
0
    fn read_slice(&mut self, len: Length) -> Result<&'r [u8]> {
80
0
        self.advance_position(len)?;
81
0
        self.inner.read_slice(len)
82
0
    }
83
84
0
    fn error(&mut self, kind: ErrorKind) -> Error {
85
0
        self.inner.error(kind)
86
0
    }
87
88
0
    fn offset(&self) -> Length {
89
0
        self.inner.offset()
90
0
    }
91
92
0
    fn read_into<'o>(&mut self, out: &'o mut [u8]) -> Result<&'o [u8]> {
93
0
        self.advance_position(Length::try_from(out.len())?)?;
94
0
        self.inner.read_into(out)
95
0
    }
96
}