untrusted/
reader.rs

1// Copyright 2015-2021 Brian Smith.
2//
3// Permission to use, copy, modify, and/or distribute this software for any
4// purpose with or without fee is hereby granted, provided that the above
5// copyright notice and this permission notice appear in all copies.
6//
7// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
8// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
10// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15use crate::{no_panic, Input};
16
17/// A read-only, forward-only cursor into the data in an `Input`.
18///
19/// Using `Reader` to parse input helps to ensure that no byte of the input
20/// will be accidentally processed more than once. Using `Reader` in
21/// conjunction with `read_all` and `read_all_optional` helps ensure that no
22/// byte of the input is accidentally left unprocessed. The methods of `Reader`
23/// never panic, so `Reader` also assists the writing of panic-free code.
24///
25/// Intentionally avoids implementing `PartialEq` and `Eq` to avoid implicit
26/// non-constant-time comparisons.
27pub struct Reader<'a> {
28    input: no_panic::Slice<'a>,
29    i: usize,
30}
31
32/// Avoids writing the value or position to avoid creating a side channel,
33/// though `Reader` can't avoid leaking the position via timing.
34impl core::fmt::Debug for Reader<'_> {
35    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
36        f.debug_struct("Reader").finish()
37    }
38}
39
40impl<'a> Reader<'a> {
41    /// Construct a new Reader for the given input. Use `read_all` or
42    /// `read_all_optional` instead of `Reader::new` whenever possible.
43    #[inline]
44    pub fn new(input: Input<'a>) -> Self {
45        Self {
46            input: input.into_value(),
47            i: 0,
48        }
49    }
50
51    /// Returns `true` if the reader is at the end of the input, and `false`
52    /// otherwise.
53    #[inline]
54    pub fn at_end(&self) -> bool {
55        self.i == self.input.len()
56    }
57
58    /// Returns `true` if there is at least one more byte in the input and that
59    /// byte is equal to `b`, and false otherwise.
60    #[inline]
61    pub fn peek(&self, b: u8) -> bool {
62        match self.input.get(self.i) {
63            Some(actual_b) => b == *actual_b,
64            None => false,
65        }
66    }
67
68    /// Reads the next input byte.
69    ///
70    /// Returns `Ok(b)` where `b` is the next input byte, or `Err(EndOfInput)`
71    /// if the `Reader` is at the end of the input.
72    #[inline]
73    pub fn read_byte(&mut self) -> Result<u8, EndOfInput> {
74        match self.input.get(self.i) {
75            Some(b) => {
76                self.i += 1; // safe from overflow; see Input::from().
77                Ok(*b)
78            }
79            None => Err(EndOfInput),
80        }
81    }
82
83    /// Skips `num_bytes` of the input, returning the skipped input as an
84    /// `Input`.
85    ///
86    /// Returns `Ok(i)` if there are at least `num_bytes` of input remaining,
87    /// and `Err(EndOfInput)` otherwise.
88    #[inline]
89    pub fn read_bytes(&mut self, num_bytes: usize) -> Result<Input<'a>, EndOfInput> {
90        let new_i = self.i.checked_add(num_bytes).ok_or(EndOfInput)?;
91        let ret = self
92            .input
93            .subslice(self.i..new_i)
94            .map(From::from)
95            .ok_or(EndOfInput)?;
96        self.i = new_i;
97        Ok(ret)
98    }
99
100    /// Skips the reader to the end of the input, returning the skipped input
101    /// as an `Input`.
102    #[inline]
103    pub fn read_bytes_to_end(&mut self) -> Input<'a> {
104        let to_skip = self.input.len() - self.i;
105        self.read_bytes(to_skip).unwrap()
106    }
107
108    /// Calls `read()` with the given input as a `Reader`. On success, returns a
109    /// pair `(bytes_read, r)` where `bytes_read` is what `read()` consumed and
110    /// `r` is `read()`'s return value.
111    pub fn read_partial<F, R, E>(&mut self, read: F) -> Result<(Input<'a>, R), E>
112    where
113        F: FnOnce(&mut Reader<'a>) -> Result<R, E>,
114    {
115        let start = self.i;
116        let r = read(self)?;
117        let bytes_read = self.input.subslice(start..self.i).unwrap().into();
118        Ok((bytes_read, r))
119    }
120
121    /// Skips `num_bytes` of the input.
122    ///
123    /// Returns `Ok(i)` if there are at least `num_bytes` of input remaining,
124    /// and `Err(EndOfInput)` otherwise.
125    #[inline]
126    pub fn skip(&mut self, num_bytes: usize) -> Result<(), EndOfInput> {
127        self.read_bytes(num_bytes).map(|_| ())
128    }
129
130    /// Skips the reader to the end of the input.
131    #[inline]
132    pub fn skip_to_end(&mut self) {
133        let _ = self.read_bytes_to_end();
134    }
135}
136
137/// The error type used to indicate the end of the input was reached before the
138/// operation could be completed.
139#[derive(Clone, Copy, Debug, Eq, PartialEq)]
140pub struct EndOfInput;