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(name:"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;
141