1#[cfg(feature = "io")]
3use std::io::Read;
4
5use alloc::vec::Vec;
6#[cfg(feature = "io")]
7use deser_core::de::DeserializeOwned;
8use deser_core::de::{self, DeserializeDriver, Frame, Progress};
9use deser_core::{Error, ErrorKind, State};
10
11use crate::de::{Deserializer, DeserializerConfig};
12use crate::head::{Head, HeadError, decode_head};
13use crate::parser::{Copying, Discard, Parser, Progress as ParseProgress};
14
15#[derive(Default)]
17struct StreamState {
18 pos: usize,
20 stack: Vec<u64>,
22 failed: bool,
24 parser: Parser,
26 started: bool,
28 skipping: Option<usize>,
31 feed_failed: bool,
33 ended: bool,
35}
36
37impl core::fmt::Debug for StreamState {
38 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
39 f.debug_struct("StreamState").finish_non_exhaustive()
40 }
41}
42
43enum Scan {
45 Complete(usize),
47 Incomplete,
49 Malformed(usize),
51}
52
53impl StreamState {
54 fn scan(&mut self, input: &[u8]) -> Scan {
56 loop {
57 let head_start = self.pos;
58 let (head, len) = match decode_head(&input[head_start..]) {
59 Ok(rv) => rv,
60 Err(HeadError::Incomplete) => return Scan::Incomplete,
61 Err(HeadError::Reserved) => return Scan::Malformed(head_start),
62 };
63 let mut pos = head_start + len;
64 let items = match head {
65 Head::Str(len) | Head::Bin(len) | Head::Ext(_, len) => {
66 match pos.checked_add(len as usize) {
67 Some(end) if end <= input.len() => pos = end,
68 _ => return Scan::Incomplete,
69 }
70 0
71 }
72 Head::Array(len) => u64::from(len),
73 Head::Map(len) => u64::from(len) * 2,
74 _ => 0,
75 };
76 self.pos = pos;
77
78 if items > 0 {
79 self.stack.push(items);
80 continue;
81 }
82 loop {
84 match self.stack.last_mut() {
85 None => return Scan::Complete(pos),
86 Some(remaining) => {
87 *remaining -= 1;
88 if *remaining > 0 {
89 break;
90 }
91 self.stack.pop();
92 }
93 }
94 }
95 }
96 }
97}
98
99#[derive(Debug)]
126pub struct StreamDeserializer {
127 config: DeserializerConfig,
128 state: StreamState,
129}
130
131impl Default for StreamDeserializer {
132 fn default() -> StreamDeserializer {
133 StreamDeserializer::new()
134 }
135}
136
137impl StreamDeserializer {
138 pub fn new() -> StreamDeserializer {
140 StreamDeserializer::with_config(&DeserializerConfig::new())
141 }
142
143 pub fn with_config(config: &DeserializerConfig) -> StreamDeserializer {
145 StreamDeserializer {
146 config: config.clone(),
147 state: StreamState::default(),
148 }
149 }
150
151 pub fn config(&self) -> &DeserializerConfig {
153 &self.config
154 }
155
156 fn skip_to_item(
161 &mut self,
162 input: &[u8],
163 offset: usize,
164 eof: bool,
165 ) -> Result<Result<usize, Progress>, Error> {
166 let state = &mut self.state;
167 if state.ended {
168 return Ok(Err(Progress::End));
169 }
170 if state.feed_failed {
171 return Err(Error::new(
172 ErrorKind::Unexpected,
173 "cannot continue after an error",
174 ));
175 }
176
177 let mut pos = 0;
179 if let Some(skip) = state.skipping {
180 let mut discard = Discard(State::new());
181 match state.parser.parse(input, skip, eof, offset, &mut discard) {
182 Ok(ParseProgress::Done(end)) => {
183 state.skipping = None;
184 pos = end;
185 }
186 Ok(ParseProgress::NeedMore(consumed)) => {
187 state.skipping = Some(0);
188 return Ok(Err(Progress::NeedMore { consumed }));
189 }
190 Err(err) => {
191 state.skipping = None;
192 return Err(fail(state, err, eof));
193 }
194 }
195 }
196
197 if !state.started && pos == input.len() {
198 return Ok(Err(if eof {
199 Progress::End
200 } else {
201 Progress::NeedMore { consumed: pos }
202 }));
203 }
204 Ok(Ok(pos))
205 }
206}
207
208impl de::StreamDeserializer for StreamDeserializer {
209 fn frame(&mut self, input: &[u8], eof: bool) -> Result<Frame, Error> {
210 let state = &mut self.state;
211 if state.failed {
212 return Err(Error::new(
213 ErrorKind::Unexpected,
214 "cannot continue after an item that is not well-formed",
215 ));
216 }
217 if input.is_empty() && eof {
218 return Ok(Frame::End);
219 }
220 let end = match state.scan(input) {
221 Scan::Complete(end) => end,
222 Scan::Incomplete if !eof => return Ok(Frame::Incomplete { consumed: 0 }),
223 Scan::Incomplete => input.len(),
225 Scan::Malformed(offset) => {
226 state.failed = true;
227 offset + 1
228 }
229 };
230 state.pos = 0;
231 state.stack.clear();
232 Ok(Frame::Value {
233 start: 0,
234 end,
235 consumed: end,
236 })
237 }
238
239 fn drive_frame<'de>(
240 &mut self,
241 frame: &'de [u8],
242 driver: &mut DeserializeDriver<'_, 'de>,
243 ) -> Result<(), Error> {
244 let mut de = Deserializer::from_slice_with_config(frame, &self.config);
245 de.drive(driver)?;
246 de.end()
247 }
248
249 fn supports_feed(&self) -> bool {
250 true
251 }
252
253 fn feed(
254 &mut self,
255 input: &[u8],
256 offset: usize,
257 eof: bool,
258 driver: &mut DeserializeDriver<'_, '_>,
259 ) -> Result<Progress, Error> {
260 let pos = match self.skip_to_item(input, offset, eof)? {
261 Ok(pos) => pos,
262 Err(progress) => return Ok(progress),
263 };
264 let state = &mut self.state;
265 state.started = true;
266 match state
267 .parser
268 .parse(input, pos, eof, offset, &mut Copying(driver))
269 {
270 Ok(ParseProgress::Done(end)) => {
271 state.started = false;
272 Ok(Progress::Done { consumed: end })
273 }
274 Ok(ParseProgress::NeedMore(consumed)) => Ok(Progress::NeedMore { consumed }),
275 Err(err) => {
276 state.started = false;
277 match state.parser.recoverable() {
278 Some(resume) => {
281 state.skipping = Some(resume);
282 Err(err)
283 }
284 None => Err(fail(state, err, eof)),
285 }
286 }
287 }
288 }
289
290 fn peek(&mut self, input: &[u8], eof: bool) -> Result<Option<Progress>, Error> {
291 Ok(Some(match self.skip_to_item(input, 0, eof)? {
292 Ok(pos) => Progress::Done { consumed: pos },
293 Err(progress) => progress,
294 }))
295 }
296}
297
298#[cfg(feature = "io")]
299impl DeserializerConfig {
300 pub fn reader<R: Read>(&self, reader: R) -> deser_core::io::Reader<R, StreamDeserializer> {
305 deser_core::io::Reader::new(reader, StreamDeserializer::with_config(self))
306 }
307
308 pub fn from_reader<T: DeserializeOwned, R: Read>(&self, reader: R) -> Result<T, Error> {
312 deser_core::io::from_reader(reader, StreamDeserializer::with_config(self))
313 }
314}
315
316#[cfg(feature = "io")]
327pub fn from_reader<T: DeserializeOwned, R: Read>(reader: R) -> Result<T, Error> {
328 DeserializerConfig::new().from_reader(reader)
329}
330
331fn fail(state: &mut StreamState, err: Error, eof: bool) -> Error {
333 state.parser.reset();
334 state.feed_failed = true;
335 state.ended = eof && err.kind() == ErrorKind::EndOfFile;
337 err
338}