Skip to main content

serde_cbor/
read.rs

1#[cfg(feature = "alloc")]
2use alloc::{vec, vec::Vec};
3#[cfg(feature = "std")]
4use core::cmp;
5use core::mem;
6
7#[cfg(feature = "std")]
8use std::io::{self, Read as StdRead};
9
10use crate::error::{Error, ErrorCode, Result};
11
12#[cfg(not(feature = "unsealed_read_write"))]
13/// Trait used by the deserializer for iterating over input.
14///
15/// This trait is sealed by default, enabling the `unsealed_read_write` feature removes this bound
16/// to allow objects outside of this crate to implement this trait.
17pub trait Read<'de>: private::Sealed {
18    #[doc(hidden)]
19    /// Read n bytes from the input.
20    ///
21    /// Implementations that can are asked to return a slice with a Long lifetime that outlives the
22    /// decoder, but others (eg. ones that need to allocate the data into a temporary buffer) can
23    /// return it with a Short lifetime that just lives for the time of read's mutable borrow of
24    /// the reader.
25    ///
26    /// This may, as a side effect, clear the reader's scratch buffer (as the provided
27    /// implementation does).
28
29    // A more appropriate lifetime setup for this (that would allow the Deserializer::convert_str
30    // to stay a function) would be something like `fn read<'a, 'r: 'a>(&'a mut 'r immut self, ...) -> ...
31    // EitherLifetime<'r, 'de>>`, which borrows self mutably for the duration of the function and
32    // downgrates that reference to an immutable one that outlives the result (protecting the
33    // scratch buffer from changes), but alas, that can't be expressed (yet?).
34    fn read<'a>(&'a mut self, n: usize) -> Result<EitherLifetime<'a, 'de>> {
35        self.clear_buffer();
36        self.read_to_buffer(n)?;
37
38        Ok(self.take_buffer())
39    }
40
41    #[doc(hidden)]
42    fn next(&mut self) -> Result<Option<u8>>;
43
44    #[doc(hidden)]
45    fn peek(&mut self) -> Result<Option<u8>>;
46
47    #[doc(hidden)]
48    fn clear_buffer(&mut self);
49
50    #[doc(hidden)]
51    fn read_to_buffer(&mut self, n: usize) -> Result<()>;
52
53    #[doc(hidden)]
54    fn take_buffer<'a>(&'a mut self) -> EitherLifetime<'a, 'de>;
55
56    #[doc(hidden)]
57    fn read_into(&mut self, buf: &mut [u8]) -> Result<()>;
58
59    #[doc(hidden)]
60    fn discard(&mut self);
61
62    #[doc(hidden)]
63    fn offset(&self) -> u64;
64}
65
66#[cfg(feature = "unsealed_read_write")]
67/// Trait used by the deserializer for iterating over input.
68pub trait Read<'de> {
69    /// Read n bytes from the input.
70    ///
71    /// Implementations that can are asked to return a slice with a Long lifetime that outlives the
72    /// decoder, but others (eg. ones that need to allocate the data into a temporary buffer) can
73    /// return it with a Short lifetime that just lives for the time of read's mutable borrow of
74    /// the reader.
75    ///
76    /// This may, as a side effect, clear the reader's scratch buffer (as the provided
77    /// implementation does).
78
79    // A more appropriate lifetime setup for this (that would allow the Deserializer::convert_str
80    // to stay a function) would be something like `fn read<'a, 'r: 'a>(&'a mut 'r immut self, ...) -> ...
81    // EitherLifetime<'r, 'de>>`, which borrows self mutably for the duration of the function and
82    // downgrates that reference to an immutable one that outlives the result (protecting the
83    // scratch buffer from changes), but alas, that can't be expressed (yet?).
84    fn read<'a>(&'a mut self, n: usize) -> Result<EitherLifetime<'a, 'de>> {
85        self.clear_buffer();
86        self.read_to_buffer(n)?;
87
88        Ok(self.take_buffer())
89    }
90
91    /// Read the next byte from the input, if any.
92    fn next(&mut self) -> Result<Option<u8>>;
93
94    /// Peek at the next byte of the input, if any. This does not advance the reader, so the result
95    /// of this function will remain the same until a read or clear occurs.
96    fn peek(&mut self) -> Result<Option<u8>>;
97
98    /// Clear the underlying scratch buffer
99    fn clear_buffer(&mut self);
100
101    /// Append n bytes from the reader to the reader's scratch buffer (without clearing it)
102    fn read_to_buffer(&mut self, n: usize) -> Result<()>;
103
104    /// Read out everything accumulated in the reader's scratch buffer. This may, as a side effect,
105    /// clear it.
106    fn take_buffer<'a>(&'a mut self) -> EitherLifetime<'a, 'de>;
107
108    /// Read from the input until `buf` is full or end of input is encountered.
109    fn read_into(&mut self, buf: &mut [u8]) -> Result<()>;
110
111    /// Discard any data read by `peek`.
112    fn discard(&mut self);
113
114    /// Returns the offset from the start of the reader.
115    fn offset(&self) -> u64;
116}
117
118/// Represents a reader that can return its current position
119pub trait Offset {
120    fn byte_offset(&self) -> usize;
121}
122
123/// Represents a buffer with one of two lifetimes.
124pub enum EitherLifetime<'short, 'long> {
125    /// The short lifetime
126    Short(&'short [u8]),
127    /// The long lifetime
128    Long(&'long [u8]),
129}
130
131#[cfg(not(feature = "unsealed_read_write"))]
132mod private {
133    pub trait Sealed {}
134}
135
136/// CBOR input source that reads from a std::io input stream.
137#[cfg(feature = "std")]
138#[derive(Debug)]
139pub struct IoRead<R>
140where
141    R: io::Read,
142{
143    reader: OffsetReader<R>,
144    scratch: Vec<u8>,
145    ch: Option<u8>,
146}
147
148#[cfg(feature = "std")]
149impl<R> IoRead<R>
150where
151    R: io::Read,
152{
153    /// Creates a new CBOR input source to read from a std::io input stream.
154    pub fn new(reader: R) -> IoRead<R> {
155        IoRead {
156            reader: OffsetReader { reader, offset: 0 },
157            scratch: vec![],
158            ch: None,
159        }
160    }
161
162    #[inline]
163    fn next_inner(&mut self) -> Result<Option<u8>> {
164        let mut buf = [0; 1];
165        loop {
166            match self.reader.read(&mut buf) {
167                Ok(0) => return Ok(None),
168                Ok(_) => return Ok(Some(buf[0])),
169                Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
170                Err(e) => return Err(Error::io(e)),
171            }
172        }
173    }
174}
175
176#[cfg(all(feature = "std", not(feature = "unsealed_read_write")))]
177impl<R> private::Sealed for IoRead<R> where R: io::Read {}
178
179#[cfg(feature = "std")]
180impl<'de, R> Read<'de> for IoRead<R>
181where
182    R: io::Read,
183{
184    #[inline]
185    fn next(&mut self) -> Result<Option<u8>> {
186        match self.ch.take() {
187            Some(ch) => Ok(Some(ch)),
188            None => self.next_inner(),
189        }
190    }
191
192    #[inline]
193    fn peek(&mut self) -> Result<Option<u8>> {
194        match self.ch {
195            Some(ch) => Ok(Some(ch)),
196            None => {
197                self.ch = self.next_inner()?;
198                Ok(self.ch)
199            }
200        }
201    }
202
203    fn read_to_buffer(&mut self, mut n: usize) -> Result<()> {
204        // defend against malicious input pretending to be huge strings by limiting growth
205        self.scratch.reserve(cmp::min(n, 16 * 1024));
206
207        if n == 0 {
208            return Ok(());
209        }
210
211        if let Some(ch) = self.ch.take() {
212            self.scratch.push(ch);
213            n -= 1;
214        }
215
216        // n == 0 is OK here and needs no further special treatment
217
218        let transfer_result = {
219            // Prepare for take() (which consumes its reader) by creating a reference adaptor
220            // that'll only live in this block
221            let reference = self.reader.by_ref();
222            // Append the first n bytes of the reader to the scratch vector (or up to
223            // an error or EOF indicated by a shorter read)
224            let mut taken = reference.take(n as u64);
225            taken.read_to_end(&mut self.scratch)
226        };
227
228        match transfer_result {
229            Ok(r) if r == n => Ok(()),
230            Ok(_) => Err(Error::syntax(
231                ErrorCode::EofWhileParsingValue,
232                self.offset(),
233            )),
234            Err(e) => Err(Error::io(e)),
235        }
236    }
237
238    fn clear_buffer(&mut self) {
239        self.scratch.clear();
240    }
241
242    fn take_buffer<'a>(&'a mut self) -> EitherLifetime<'a, 'de> {
243        EitherLifetime::Short(&self.scratch)
244    }
245
246    fn read_into(&mut self, buf: &mut [u8]) -> Result<()> {
247        self.reader.read_exact(buf).map_err(|e| {
248            if e.kind() == io::ErrorKind::UnexpectedEof {
249                Error::syntax(ErrorCode::EofWhileParsingValue, self.offset())
250            } else {
251                Error::io(e)
252            }
253        })
254    }
255
256    #[inline]
257    fn discard(&mut self) {
258        self.ch = None;
259    }
260
261    fn offset(&self) -> u64 {
262        self.reader.offset
263    }
264}
265
266#[cfg(feature = "std")]
267impl<R> Offset for IoRead<R>
268where
269    R: std::io::Read,
270{
271    fn byte_offset(&self) -> usize {
272        self.offset() as usize
273    }
274}
275
276#[cfg(feature = "std")]
277#[derive(Debug)]
278struct OffsetReader<R> {
279    reader: R,
280    offset: u64,
281}
282
283#[cfg(feature = "std")]
284impl<R> io::Read for OffsetReader<R>
285where
286    R: io::Read,
287{
288    #[inline]
289    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
290        let r = self.reader.read(buf);
291        if let Ok(count) = r {
292            self.offset += count as u64;
293        }
294        r
295    }
296}
297
298/// A CBOR input source that reads from a slice of bytes.
299#[cfg(any(feature = "std", feature = "alloc"))]
300#[derive(Debug)]
301pub struct SliceRead<'a> {
302    slice: &'a [u8],
303    scratch: Vec<u8>,
304    index: usize,
305}
306
307#[cfg(any(feature = "std", feature = "alloc"))]
308impl<'a> SliceRead<'a> {
309    /// Creates a CBOR input source to read from a slice of bytes.
310    pub fn new(slice: &'a [u8]) -> SliceRead<'a> {
311        SliceRead {
312            slice,
313            scratch: vec![],
314            index: 0,
315        }
316    }
317
318    fn end(&self, n: usize) -> Result<usize> {
319        match self.index.checked_add(n) {
320            Some(end) if end <= self.slice.len() => Ok(end),
321            _ => Err(Error::syntax(
322                ErrorCode::EofWhileParsingValue,
323                self.slice.len() as u64,
324            )),
325        }
326    }
327}
328
329#[cfg(any(feature = "std", feature = "alloc"))]
330impl<'a> Offset for SliceRead<'a> {
331    #[inline]
332    fn byte_offset(&self) -> usize {
333        self.index
334    }
335}
336
337#[cfg(all(
338    any(feature = "std", feature = "alloc"),
339    not(feature = "unsealed_read_write")
340))]
341impl<'a> private::Sealed for SliceRead<'a> {}
342
343#[cfg(any(feature = "std", feature = "alloc"))]
344impl<'a> Read<'a> for SliceRead<'a> {
345    #[inline]
346    fn next(&mut self) -> Result<Option<u8>> {
347        Ok(if self.index < self.slice.len() {
348            let ch = self.slice[self.index];
349            self.index += 1;
350            Some(ch)
351        } else {
352            None
353        })
354    }
355
356    #[inline]
357    fn peek(&mut self) -> Result<Option<u8>> {
358        Ok(if self.index < self.slice.len() {
359            Some(self.slice[self.index])
360        } else {
361            None
362        })
363    }
364
365    fn clear_buffer(&mut self) {
366        self.scratch.clear();
367    }
368
369    fn read_to_buffer(&mut self, n: usize) -> Result<()> {
370        let end = self.end(n)?;
371        let slice = &self.slice[self.index..end];
372        self.scratch.extend_from_slice(slice);
373        self.index = end;
374
375        Ok(())
376    }
377
378    #[inline]
379    fn read<'b>(&'b mut self, n: usize) -> Result<EitherLifetime<'b, 'a>> {
380        let end = self.end(n)?;
381        let slice = &self.slice[self.index..end];
382        self.index = end;
383        Ok(EitherLifetime::Long(slice))
384    }
385
386    fn take_buffer<'b>(&'b mut self) -> EitherLifetime<'b, 'a> {
387        EitherLifetime::Short(&self.scratch)
388    }
389
390    #[inline]
391    fn read_into(&mut self, buf: &mut [u8]) -> Result<()> {
392        let end = self.end(buf.len())?;
393        buf.copy_from_slice(&self.slice[self.index..end]);
394        self.index = end;
395        Ok(())
396    }
397
398    #[inline]
399    fn discard(&mut self) {
400        self.index += 1;
401    }
402
403    fn offset(&self) -> u64 {
404        self.index as u64
405    }
406}
407
408/// A CBOR input source that reads from a slice of bytes using a fixed size scratch buffer.
409///
410/// [`SliceRead`](struct.SliceRead.html) and [`MutSliceRead`](struct.MutSliceRead.html) are usually
411/// preferred over this, as they can handle indefinite length items.
412#[derive(Debug)]
413pub struct SliceReadFixed<'a, 'b> {
414    slice: &'a [u8],
415    scratch: &'b mut [u8],
416    index: usize,
417    scratch_index: usize,
418}
419
420impl<'a, 'b> SliceReadFixed<'a, 'b> {
421    /// Creates a CBOR input source to read from a slice of bytes, backed by a scratch buffer.
422    pub fn new(slice: &'a [u8], scratch: &'b mut [u8]) -> SliceReadFixed<'a, 'b> {
423        SliceReadFixed {
424            slice,
425            scratch,
426            index: 0,
427            scratch_index: 0,
428        }
429    }
430
431    fn end(&self, n: usize) -> Result<usize> {
432        match self.index.checked_add(n) {
433            Some(end) if end <= self.slice.len() => Ok(end),
434            _ => Err(Error::syntax(
435                ErrorCode::EofWhileParsingValue,
436                self.slice.len() as u64,
437            )),
438        }
439    }
440
441    fn scratch_end(&self, n: usize) -> Result<usize> {
442        match self.scratch_index.checked_add(n) {
443            Some(end) if end <= self.scratch.len() => Ok(end),
444            _ => Err(Error::scratch_too_small(self.index as u64)),
445        }
446    }
447}
448
449#[cfg(not(feature = "unsealed_read_write"))]
450impl<'a, 'b> private::Sealed for SliceReadFixed<'a, 'b> {}
451
452impl<'a, 'b> Read<'a> for SliceReadFixed<'a, 'b> {
453    #[inline]
454    fn next(&mut self) -> Result<Option<u8>> {
455        Ok(if self.index < self.slice.len() {
456            let ch = self.slice[self.index];
457            self.index += 1;
458            Some(ch)
459        } else {
460            None
461        })
462    }
463
464    #[inline]
465    fn peek(&mut self) -> Result<Option<u8>> {
466        Ok(if self.index < self.slice.len() {
467            Some(self.slice[self.index])
468        } else {
469            None
470        })
471    }
472
473    fn clear_buffer(&mut self) {
474        self.scratch_index = 0;
475    }
476
477    fn read_to_buffer(&mut self, n: usize) -> Result<()> {
478        let end = self.end(n)?;
479        let scratch_end = self.scratch_end(n)?;
480        let slice = &self.slice[self.index..end];
481        self.scratch[self.scratch_index..scratch_end].copy_from_slice(&slice);
482        self.index = end;
483        self.scratch_index = scratch_end;
484
485        Ok(())
486    }
487
488    fn read<'c>(&'c mut self, n: usize) -> Result<EitherLifetime<'c, 'a>> {
489        let end = self.end(n)?;
490        let slice = &self.slice[self.index..end];
491        self.index = end;
492        Ok(EitherLifetime::Long(slice))
493    }
494
495    fn take_buffer<'c>(&'c mut self) -> EitherLifetime<'c, 'a> {
496        EitherLifetime::Short(&self.scratch[0..self.scratch_index])
497    }
498
499    #[inline]
500    fn read_into(&mut self, buf: &mut [u8]) -> Result<()> {
501        let end = self.end(buf.len())?;
502        buf.copy_from_slice(&self.slice[self.index..end]);
503        self.index = end;
504        Ok(())
505    }
506
507    #[inline]
508    fn discard(&mut self) {
509        self.index += 1;
510    }
511
512    fn offset(&self) -> u64 {
513        self.index as u64
514    }
515}
516
517#[cfg(any(feature = "std", feature = "alloc"))]
518impl<'a, 'b> Offset for SliceReadFixed<'a, 'b> {
519    #[inline]
520    fn byte_offset(&self) -> usize {
521        self.index
522    }
523}
524
525/// A CBOR input source that reads from a slice of bytes, and can move data around internally to
526/// reassemble indefinite strings without the need of an allocated scratch buffer.
527#[derive(Debug)]
528pub struct MutSliceRead<'a> {
529    /// A complete view of the reader's data. It is promised that bytes before buffer_end are not
530    /// mutated any more.
531    slice: &'a mut [u8],
532    /// Read cursor position in slice
533    index: usize,
534    /// Number of bytes already discarded from the slice
535    before: usize,
536    /// End of the buffer area that contains all bytes read_into_buffer. This is always <= index.
537    buffer_end: usize,
538}
539
540impl<'a> MutSliceRead<'a> {
541    /// Creates a CBOR input source to read from a slice of bytes.
542    pub fn new(slice: &'a mut [u8]) -> MutSliceRead<'a> {
543        MutSliceRead {
544            slice,
545            index: 0,
546            before: 0,
547            buffer_end: 0,
548        }
549    }
550
551    fn end(&self, n: usize) -> Result<usize> {
552        match self.index.checked_add(n) {
553            Some(end) if end <= self.slice.len() => Ok(end),
554            _ => Err(Error::syntax(
555                ErrorCode::EofWhileParsingValue,
556                self.slice.len() as u64,
557            )),
558        }
559    }
560}
561
562#[cfg(not(feature = "unsealed_read_write"))]
563impl<'a> private::Sealed for MutSliceRead<'a> {}
564
565impl<'a> Read<'a> for MutSliceRead<'a> {
566    #[inline]
567    fn next(&mut self) -> Result<Option<u8>> {
568        // This is duplicated from SliceRead, can that be eased?
569        Ok(if self.index < self.slice.len() {
570            let ch = self.slice[self.index];
571            self.index += 1;
572            Some(ch)
573        } else {
574            None
575        })
576    }
577
578    #[inline]
579    fn peek(&mut self) -> Result<Option<u8>> {
580        // This is duplicated from SliceRead, can that be eased?
581        Ok(if self.index < self.slice.len() {
582            Some(self.slice[self.index])
583        } else {
584            None
585        })
586    }
587
588    fn clear_buffer(&mut self) {
589        self.slice = &mut mem::replace(&mut self.slice, &mut [])[self.index..];
590        self.before += self.index;
591        self.index = 0;
592        self.buffer_end = 0;
593    }
594
595    fn read_to_buffer(&mut self, n: usize) -> Result<()> {
596        let end = self.end(n)?;
597        debug_assert!(
598            self.buffer_end <= self.index,
599            "MutSliceRead invariant violated: scratch buffer exceeds index"
600        );
601        self.slice[self.buffer_end..end].rotate_left(self.index - self.buffer_end);
602        self.buffer_end += n;
603        self.index = end;
604
605        Ok(())
606    }
607
608    fn take_buffer<'b>(&'b mut self) -> EitherLifetime<'b, 'a> {
609        let (left, right) = mem::replace(&mut self.slice, &mut []).split_at_mut(self.index);
610        self.slice = right;
611        self.before += self.index;
612        self.index = 0;
613
614        let left = &left[..self.buffer_end];
615        self.buffer_end = 0;
616
617        EitherLifetime::Long(left)
618    }
619
620    #[inline]
621    fn read_into(&mut self, buf: &mut [u8]) -> Result<()> {
622        // This is duplicated from SliceRead, can that be eased?
623        let end = self.end(buf.len())?;
624        buf.copy_from_slice(&self.slice[self.index..end]);
625        self.index = end;
626        Ok(())
627    }
628
629    #[inline]
630    fn discard(&mut self) {
631        self.index += 1;
632    }
633
634    fn offset(&self) -> u64 {
635        (self.before + self.index) as u64
636    }
637}