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::parser::{Copying, Discard, Parser, Progress as ParseProgress};
13
14const MAJOR_BYTES: u8 = 2;
15const MAJOR_TEXT: u8 = 3;
16const MAJOR_ARRAY: u8 = 4;
17const MAJOR_MAP: u8 = 5;
18const MAJOR_TAG: u8 = 6;
19const MAJOR_SIMPLE: u8 = 7;
20const INDEFINITE: u8 = 31;
21
22#[derive(Default)]
24struct StreamState {
25 pos: usize,
27 stack: Vec<Option<u64>>,
30 failed: bool,
32 parser: Parser,
34 started: bool,
36 skipping: Option<usize>,
39 partial_failed: bool,
41 ended: bool,
43}
44
45impl core::fmt::Debug for StreamState {
46 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
47 f.debug_struct("StreamState").finish_non_exhaustive()
48 }
49}
50
51enum Scan {
53 Complete(usize),
55 Incomplete,
57 Malformed(usize),
59}
60
61impl StreamState {
62 fn scan(&mut self, input: &[u8]) -> Scan {
64 loop {
65 let head_start = self.pos;
66 let Some(&initial) = input.get(head_start) else {
67 return Scan::Incomplete;
68 };
69 let major = initial >> 5;
70 let info = initial & 0x1f;
71 let arg_len = match info {
72 0..=23 => 0,
73 24 => 1,
74 25 => 2,
75 26 => 4,
76 27 => 8,
77 INDEFINITE => 0,
78 _ => return Scan::Malformed(head_start),
79 };
80 let Some(arg_bytes) = input.get(head_start + 1..head_start + 1 + arg_len) else {
81 return Scan::Incomplete;
82 };
83 let arg = if info < 24 {
84 u64::from(info)
85 } else {
86 arg_bytes
87 .iter()
88 .fold(0u64, |acc, &b| (acc << 8) | u64::from(b))
89 };
90 let mut pos = head_start + 1 + arg_len;
91
92 let item_done = if info == INDEFINITE {
93 match major {
94 MAJOR_BYTES | MAJOR_TEXT | MAJOR_ARRAY | MAJOR_MAP => {
95 self.stack.push(None);
96 false
97 }
98 MAJOR_SIMPLE => match self.stack.pop() {
100 Some(None) => true,
101 _ => return Scan::Malformed(head_start),
102 },
103 _ => return Scan::Malformed(head_start),
104 }
105 } else {
106 match major {
107 MAJOR_BYTES | MAJOR_TEXT => {
108 let end = usize::try_from(arg)
109 .ok()
110 .and_then(|len| pos.checked_add(len));
111 match end {
112 Some(end) if end <= input.len() => pos = end,
113 Some(_) => return Scan::Incomplete,
114 None => return Scan::Malformed(head_start),
115 }
116 true
117 }
118 MAJOR_ARRAY | MAJOR_MAP | MAJOR_TAG => {
119 let items = match major {
120 MAJOR_MAP => match arg.checked_mul(2) {
121 Some(items) => items,
122 None => return Scan::Malformed(head_start),
123 },
124 MAJOR_TAG => 1,
125 _ => arg,
126 };
127 if items == 0 {
128 true
129 } else {
130 self.stack.push(Some(items));
131 false
132 }
133 }
134 _ => true,
135 }
136 };
137 self.pos = pos;
138
139 if item_done {
140 loop {
142 match self.stack.last_mut() {
143 None => return Scan::Complete(pos),
144 Some(None) => break,
145 Some(Some(remaining)) => {
146 *remaining -= 1;
147 if *remaining > 0 {
148 break;
149 }
150 self.stack.pop();
151 }
152 }
153 }
154 }
155 }
156 }
157}
158
159#[derive(Debug)]
187pub struct StreamDeserializer {
188 config: DeserializerConfig,
189 state: StreamState,
190}
191
192impl Default for StreamDeserializer {
193 fn default() -> StreamDeserializer {
194 StreamDeserializer::new()
195 }
196}
197
198impl StreamDeserializer {
199 pub fn new() -> StreamDeserializer {
201 StreamDeserializer::with_config(DeserializerConfig::new())
202 }
203
204 pub fn with_config(config: DeserializerConfig) -> StreamDeserializer {
206 StreamDeserializer {
207 config,
208 state: StreamState::default(),
209 }
210 }
211
212 pub fn config(&self) -> &DeserializerConfig {
214 &self.config
215 }
216
217 fn skip_to_item(
222 &mut self,
223 input: &[u8],
224 offset: usize,
225 eof: bool,
226 ) -> Result<Result<usize, Progress>, Error> {
227 let state = &mut self.state;
228 if state.ended {
229 return Ok(Err(Progress::End));
230 }
231 if state.partial_failed {
232 return Err(Error::new(
233 ErrorKind::InvalidState,
234 "cannot continue after an error",
235 ));
236 }
237
238 let mut pos = 0;
240 if let Some(skip) = state.skipping {
241 let mut discard = Discard(State::new());
242 match state.parser.parse(input, skip, eof, offset, &mut discard) {
243 Ok(ParseProgress::Done(end)) => {
244 state.skipping = None;
245 pos = end;
246 }
247 Ok(ParseProgress::NeedMore(consumed)) => {
248 state.skipping = Some(0);
249 return Ok(Err(Progress::NeedMore { consumed }));
250 }
251 Err(err) => {
252 state.skipping = None;
253 return Err(fail(state, err, eof));
254 }
255 }
256 }
257
258 if !state.started && pos == input.len() {
259 return Ok(Err(if eof {
260 Progress::End
261 } else {
262 Progress::NeedMore { consumed: pos }
263 }));
264 }
265 Ok(Ok(pos))
266 }
267}
268
269impl de::StreamDeserializer for StreamDeserializer {
270 fn context(&self) -> deser_core::Context {
271 self.config.context().clone()
272 }
273
274 fn frame(&mut self, input: &[u8], eof: bool) -> Result<Frame, Error> {
275 let state = &mut self.state;
276 if state.failed {
277 return Err(Error::new(
278 ErrorKind::InvalidState,
279 "cannot continue after an item that is not well-formed",
280 ));
281 }
282 if input.is_empty() && eof {
283 return Ok(Frame::End);
284 }
285 let end = match state.scan(input) {
286 Scan::Complete(end) => end,
287 Scan::Incomplete if !eof => return Ok(Frame::Incomplete { consumed: 0 }),
288 Scan::Incomplete => input.len(),
290 Scan::Malformed(offset) => {
291 state.failed = true;
292 offset + 1
293 }
294 };
295 state.pos = 0;
296 state.stack.clear();
297 Ok(Frame::Value {
298 start: 0,
299 end,
300 consumed: end,
301 })
302 }
303
304 fn drive_frame<'de>(
305 &mut self,
306 frame: &'de [u8],
307 driver: &mut DeserializeDriver<'_, 'de>,
308 ) -> Result<(), Error> {
309 let mut de = Deserializer::from_slice_with_config(frame, self.config.without_context());
310 de.drive(driver)?;
311 de.end()
312 }
313
314 fn supports_partial(&self) -> bool {
315 true
316 }
317
318 fn drive_partial(
319 &mut self,
320 input: &[u8],
321 offset: usize,
322 eof: bool,
323 driver: &mut DeserializeDriver<'_, '_>,
324 ) -> Result<Progress, Error> {
325 let pos = match self.skip_to_item(input, offset, eof)? {
326 Ok(pos) => pos,
327 Err(progress) => return Ok(progress),
328 };
329 let state = &mut self.state;
330 state.started = true;
331 match state
332 .parser
333 .parse(input, pos, eof, offset, &mut Copying(driver))
334 {
335 Ok(ParseProgress::Done(end)) => {
336 state.started = false;
337 Ok(Progress::Done { consumed: end })
338 }
339 Ok(ParseProgress::NeedMore(consumed)) => Ok(Progress::NeedMore { consumed }),
340 Err(err) => {
341 state.started = false;
342 match state.parser.recoverable() {
343 Some(resume) => {
346 state.skipping = Some(resume);
347 Err(err)
348 }
349 None => Err(fail(state, err, eof)),
350 }
351 }
352 }
353 }
354
355 fn peek(&mut self, input: &[u8], eof: bool) -> Result<Option<Progress>, Error> {
356 Ok(Some(match self.skip_to_item(input, 0, eof)? {
357 Ok(pos) => Progress::Done { consumed: pos },
358 Err(progress) => progress,
359 }))
360 }
361}
362
363#[cfg(feature = "io")]
364impl DeserializerConfig {
365 pub fn reader<R: Read>(&self, reader: R) -> deser_core::io::Reader<R, StreamDeserializer> {
370 deser_core::io::Reader::new(reader, StreamDeserializer::with_config(self.clone()))
371 }
372
373 pub fn from_reader<T: DeserializeOwned, R: Read>(&self, reader: R) -> Result<T, Error> {
377 deser_core::io::from_reader(reader, StreamDeserializer::with_config(self.clone()))
378 }
379}
380
381#[cfg(feature = "io")]
393pub fn from_reader<T: DeserializeOwned, R: Read>(reader: R) -> Result<T, Error> {
394 DeserializerConfig::new().from_reader(reader)
395}
396
397fn fail(state: &mut StreamState, err: Error, eof: bool) -> Error {
399 state.parser.reset();
400 state.partial_failed = true;
401 state.ended = eof && err.kind() == ErrorKind::EndOfFile;
403 err
404}