1use super::position::Position;
4use crate::{BytesRef, Decode, EncodingRules, Error, ErrorKind, Length, Reader};
5
6#[derive(Clone, Debug)]
8pub struct SliceReader<'a> {
9 bytes: &'a BytesRef,
11
12 encoding_rules: EncodingRules,
14
15 failed: bool,
17
18 position: Position,
20}
21
22impl<'a> SliceReader<'a> {
23 pub fn new(bytes: &'a [u8]) -> Result<Self, Error> {
28 Self::new_with_encoding_rules(bytes, EncodingRules::default())
29 }
30
31 pub fn new_with_encoding_rules(
36 bytes: &'a [u8],
37 encoding_rules: EncodingRules,
38 ) -> Result<Self, Error> {
39 Ok(Self {
40 bytes: BytesRef::new(bytes)?,
41 encoding_rules,
42 failed: false,
43 position: Position::new(bytes.len().try_into()?),
44 })
45 }
46
47 pub fn error(&mut self, kind: ErrorKind) -> Error {
50 self.failed = true;
51 self.position.error(kind)
52 }
53
54 #[must_use]
56 pub fn is_failed(&self) -> bool {
57 self.failed
58 }
59
60 pub(crate) fn remaining(&self) -> Result<&'a [u8], Error> {
62 if self.is_failed() {
63 Err(ErrorKind::Failed.at(self.position.current()))
64 } else {
65 self.bytes
66 .as_slice()
67 .get(self.position.current().try_into()?..)
68 .ok_or_else(|| Error::incomplete(self.input_len()))
69 }
70 }
71}
72
73impl<'a> Reader<'a> for SliceReader<'a> {
74 const CAN_READ_SLICE: bool = true;
75
76 fn encoding_rules(&self) -> EncodingRules {
77 self.encoding_rules
78 }
79
80 fn input_len(&self) -> Length {
81 self.bytes.len()
82 }
83
84 fn position(&self) -> Length {
85 self.position.current()
86 }
87
88 #[inline]
90 fn read_nested<T, F, E>(&mut self, len: Length, f: F) -> Result<T, E>
91 where
92 F: FnOnce(&mut Self) -> Result<T, E>,
93 E: From<Error>,
94 {
95 let bytes = self.bytes;
97 let prefix_len = (self.position.current() + len)?;
98 self.bytes = self.bytes.prefix(prefix_len)?;
99
100 let resumption = self.position.split_nested(len)?;
101 let ret = f(self);
102 self.bytes = bytes;
103 self.position.resume_nested(resumption);
104 ret
105 }
106
107 fn read_slice(&mut self, len: Length) -> Result<&'a [u8], Error> {
108 if self.is_failed() {
109 return Err(self.error(ErrorKind::Failed));
110 }
111
112 match self.remaining()?.get(..len.try_into()?) {
113 Some(result) => {
114 self.position.advance(len)?;
115 Ok(result)
116 }
117 None => Err(self.error(ErrorKind::Incomplete {
118 expected_len: (self.position.current() + len)?,
119 actual_len: self.input_len(),
120 })),
121 }
122 }
123
124 fn decode<T: Decode<'a>>(&mut self) -> Result<T, T::Error> {
125 if self.is_failed() {
126 return Err(self.error(ErrorKind::Failed).into());
127 }
128
129 T::decode(self).inspect_err(|_| {
130 self.failed = true;
131 })
132 }
133
134 fn error(&mut self, kind: ErrorKind) -> Error {
135 self.error(kind)
136 }
137
138 fn finish(mut self) -> Result<(), Error> {
139 if self.is_failed() {
140 Err(ErrorKind::Failed.at(self.position.current()))
141 } else if !self.is_finished() {
142 let decoded = self.position.current();
143 let remaining = self.remaining_len();
144 Err(self.error(ErrorKind::TrailingData { decoded, remaining }))
145 } else {
146 Ok(())
147 }
148 }
149
150 fn remaining_len(&self) -> Length {
151 self.position.remaining_len()
152 }
153}
154
155#[cfg(test)]
156#[allow(clippy::unwrap_used, clippy::panic)]
157mod tests {
158 use super::SliceReader;
159 use crate::{Decode, ErrorKind, Length, Reader};
160 use hex_literal::hex;
161
162 const EXAMPLE_MSG: &[u8] = &hex!("02012A00");
164
165 #[test]
166 fn empty_message() {
167 let mut reader = SliceReader::new(&[]).unwrap();
168 let err = bool::decode(&mut reader).err().unwrap();
169 assert_eq!(Some(Length::ZERO), err.position());
170
171 match err.kind() {
172 ErrorKind::Incomplete {
173 expected_len,
174 actual_len,
175 } => {
176 assert_eq!(actual_len, 0u8.into());
177 assert_eq!(expected_len, 1u8.into());
178 }
179 other => panic!("unexpected error kind: {:?}", other),
180 }
181 }
182
183 #[test]
184 fn invalid_field_length() {
185 const MSG_LEN: usize = 2;
186
187 let mut reader = SliceReader::new(&EXAMPLE_MSG[..MSG_LEN]).unwrap();
188 let err = i8::decode(&mut reader).err().unwrap();
189 assert_eq!(Some(Length::from(2u8)), err.position());
190
191 match err.kind() {
192 ErrorKind::Incomplete {
193 expected_len,
194 actual_len,
195 } => {
196 assert_eq!(actual_len, MSG_LEN.try_into().unwrap());
197 assert_eq!(expected_len, (MSG_LEN + 1).try_into().unwrap());
198 }
199 other => panic!("unexpected error kind: {:?}", other),
200 }
201 }
202
203 #[test]
204 fn trailing_data() {
205 let mut reader = SliceReader::new(EXAMPLE_MSG).unwrap();
206 let x = i8::decode(&mut reader).unwrap();
207 assert_eq!(42i8, x);
208
209 let err = reader.finish().err().unwrap();
210 assert_eq!(Some(Length::from(3u8)), err.position());
211
212 assert_eq!(
213 ErrorKind::TrailingData {
214 decoded: 3u8.into(),
215 remaining: 1u8.into(),
216 },
217 err.kind()
218 );
219 }
220}