cbored/
reader.rs

1use super::context::*;
2use super::decode::*;
3use super::header::*;
4use super::prim::*;
5use super::state::*;
6use super::types::*;
7use crate::lowlevel::lead::*;
8
9/// Possible error when reading CBOR from a data stream
10#[derive(Debug, Clone)]
11pub enum ReaderError {
12    /// The element header was invalid
13    LeadError(LeadError),
14    /// Trying to read more data than was available in the buffer.
15    /// This can be used to fill more data in the buffer, as it return the number
16    /// of byte missing
17    DataMissing(CborDataMissing),
18    /// When trying to get element, the overall CBOR state machine represent
19    /// an invalid transition, for example a break in a non indefinite structure
20    StateError(StateError),
21    /// Wrong expected type, the user is asking for a specific expected type, but
22    /// got some other type.
23    WrongExpectedType { expected: Type, got: Type },
24    /// Wrong expected types, the user is asking for a specific set of expected types, but
25    /// got some other type. This is similar to `WrongExpectedType` but works with a list of
26    /// multiple types
27    WrongExpectedTypes {
28        expected: &'static [Type],
29        got: Type,
30    },
31    /// Wrong expected tags, the user is asking for a specific expected tag, but
32    /// got some other type.
33    WrongExpectedTag { expected: u64, got: u64 },
34    /// Wrong expected tags, the user is asking for a specific set of expected tags, but
35    /// got some other tag. This is similar to `WrongExpectedTag` but works with a list of
36    /// multiple tags
37    WrongExpectedTags { expected: &'static [u64], got: u64 },
38    /// Length expected is not met
39    WrongExpectedLength { expected: usize, got: usize },
40    /// Unexpected break type
41    UnexpectedBreakType,
42    /// Text is not a valid UTF8 string
43    TextUTF8Error(std::str::Utf8Error),
44    /// Indefinite text into another indefinite text
45    TextChunksInTextChunks,
46    /// Indefinite bytes into another indefinite bytes
47    BytesChunksInBytesChunks,
48    /// Unexpected type received in an indefinite Text where only definite Text chunk are allowed
49    WrongExpectedTypeInText { got: Type },
50    /// Unexpected type received in an indefinite Bytes where only definite Bytes chunk are allowed
51    WrongExpectedTypeInBytes { got: Type },
52    /// Expected termination, but still some trailing data available
53    NotTerminated {
54        at: usize,
55        remaining_bytes: usize,
56        next_byte: u8,
57    },
58}
59
60impl From<LeadError> for ReaderError {
61    fn from(e: LeadError) -> Self {
62        ReaderError::LeadError(e)
63    }
64}
65
66impl From<StateError> for ReaderError {
67    fn from(e: StateError) -> Self {
68        ReaderError::StateError(e)
69    }
70}
71
72impl From<CborDataMissing> for ReaderError {
73    fn from(e: CborDataMissing) -> Self {
74        ReaderError::DataMissing(e)
75    }
76}
77
78/// CBOR Data structure to read CBOR elements from a slice of byte
79pub struct Reader<'a> {
80    reader: CborDataReader<'a>,
81}
82
83macro_rules! matches_type {
84    ($hdr:ident, $ty:path, $hdrty:path) => {
85        match $hdr {
86            $hdrty(content) => Ok(content),
87            _ => Err(ReaderError::WrongExpectedType {
88                expected: $ty,
89                got: $hdr.to_type(),
90            }),
91        }
92    };
93}
94
95fn state_process_header(state: &mut State, header: Header) -> Result<(), ReaderError> {
96    match header {
97        Header::Positive(_) => state.simple()?,
98        Header::Negative(_) => state.simple()?,
99        Header::Bytes(c) => state.bytes(c)?,
100        Header::Text(c) => state.text(c)?,
101        Header::Array(c) => state.array(c)?,
102        Header::Map(c) => state.map(c)?,
103        Header::Tag(_) => state.tag()?,
104        Header::Constant(_) => state.simple()?,
105        Header::Byte(_) => state.simple()?,
106        Header::Float(_) => state.simple()?,
107        Header::Break => state.brk()?,
108    };
109    Ok(())
110}
111
112impl<'a> Reader<'a> {
113    /// Return the number of bytes remaining to be processed by the reader
114    pub fn remaining_bytes(&self) -> usize {
115        self.reader.remaining_bytes()
116    }
117
118    /// Return the number of bytes consumed since the start of the Reader
119    pub fn consumed_bytes(&self) -> usize {
120        self.reader.index
121    }
122
123    /// Return if all the bytes have been consumed by the reader
124    pub fn is_finished(&self) -> bool {
125        self.remaining_bytes() == 0
126    }
127
128    /// Assume the reader is finished (no more bytes to process), or
129    /// otherwise return a `ReaderError::NotTerminated`
130    pub fn expect_finished(&self) -> Result<(), ReaderError> {
131        if !self.is_finished() {
132            return Err(ReaderError::NotTerminated {
133                at: self.consumed_bytes(),
134                remaining_bytes: self.remaining_bytes(),
135                next_byte: self.reader.peek_byte(),
136            });
137        }
138        Ok(())
139    }
140
141    // internal call to expect some bytes
142    fn expect(&mut self, context: CborDataContext, n: usize) -> Result<&'a [u8], ReaderError> {
143        self.reader.consume(context, n).map_err(|e| e.into())
144    }
145
146    fn peek_at(
147        &self,
148        context: CborDataContext,
149        offset: usize,
150        n: usize,
151    ) -> Result<&'a [u8], ReaderError> {
152        self.reader.peek(context, offset, n).map_err(|e| e.into())
153    }
154
155    pub fn new(data: &'a [u8]) -> Self {
156        assert!(data.len() > 0);
157        let reader = CborDataReader::new(data);
158        Self { reader }
159    }
160
161    /// read the byte header
162    fn lead(&self) -> Result<Lead, ReaderError> {
163        let hdr = self.peek_at(CborDataContext::Header, 0, 1)?;
164        let header = Lead::from_byte(hdr[0])?;
165        Ok(header)
166    }
167
168    /// get the indirect content (1, 2, 4 or 8 bytes)
169    ///
170    /// always get data from self.index+1
171    fn resolve_indirect(&self, indirect_len: IndirectLen) -> Result<IndirectValue, ReaderError> {
172        match indirect_len {
173            IndirectLen::I1 => {
174                let len_slice = self.peek_at(CborDataContext::IndirectLen, 1, 1)?;
175                Ok(IndirectValue::U8(len_slice[0]))
176            }
177            IndirectLen::I2 => {
178                let mut data = [0u8; 2];
179                data.copy_from_slice(self.peek_at(CborDataContext::IndirectLen, 1, 2)?);
180                Ok(IndirectValue::U16(u16::from_be_bytes(data)))
181            }
182            IndirectLen::I4 => {
183                let mut data = [0u8; 4];
184                data.copy_from_slice(self.peek_at(CborDataContext::IndirectLen, 1, 4)?);
185                Ok(IndirectValue::U32(u32::from_be_bytes(data)))
186            }
187            IndirectLen::I8 => {
188                let mut data = [0u8; 8];
189                data.copy_from_slice(self.peek_at(CborDataContext::IndirectLen, 1, 8)?);
190                Ok(IndirectValue::U64(u64::from_be_bytes(data)))
191            }
192        }
193    }
194
195    /// peek the data type
196    fn header_parts(&self) -> Result<(Lead, usize, Option<IndirectValue>), ReaderError> {
197        let lead = self.lead()?;
198        let maybe_indirect = lead.expected_extra();
199        let (advance, indirect) = match maybe_indirect {
200            None => (1, None),
201            Some(v) => (1 + v.len_bytes(), Some(self.resolve_indirect(v)?)),
202        };
203        Ok((lead, advance, indirect))
204    }
205
206    fn header(&self) -> Result<(Header, usize), ReaderError> {
207        let (ld, advance, ival) = self.header_parts()?;
208        let header = Header::from_parts(ld, ival);
209        Ok((header, advance))
210    }
211
212    fn advance_data(&mut self, header: &Header) -> Result<(), ReaderError> {
213        match header {
214            Header::Bytes(c) | Header::Text(c) => match c {
215                None => {}
216                Some(b) => {
217                    let sz = b.to_size();
218                    let _data = self.expect(CborDataContext::Content, sz)?;
219                }
220            },
221            _ => (),
222        }
223        Ok(())
224    }
225
226    /// Peek at the next type in the buffer
227    ///
228    /// Note that it can still return error if there's no data available (end of buffer),
229    /// or that the CBOR lead byte is not well-formed
230    pub fn peek_type(&self) -> Result<Type, ReaderError> {
231        let lead = self.lead()?;
232        Ok(Type::from_lead(lead))
233    }
234
235    pub fn positive(&mut self) -> Result<Positive, ReaderError> {
236        let (hdr, advance) = self.header()?;
237        let content = matches_type!(hdr, Type::Positive, Header::Positive)?;
238        self.reader.advance(advance);
239        Ok(content)
240    }
241
242    pub fn negative(&mut self) -> Result<Negative, ReaderError> {
243        let (hdr, advance) = self.header()?;
244        let content = matches_type!(hdr, Type::Negative, Header::Negative)?;
245        self.reader.advance(advance);
246        Ok(content)
247    }
248
249    pub fn scalar(&mut self) -> Result<Scalar, ReaderError> {
250        let (hdr, advance) = self.header()?;
251        let content = match hdr {
252            Header::Positive(pos) => Ok(Scalar::Positive(pos)),
253            Header::Negative(neg) => Ok(Scalar::Negative(neg)),
254            _ => Err(ReaderError::WrongExpectedTypes {
255                expected: &[Type::Positive, Type::Negative],
256                got: hdr.to_type(),
257            }),
258        }?;
259        self.reader.advance(advance);
260        Ok(content)
261    }
262
263    pub fn byte(&mut self) -> Result<Byte, ReaderError> {
264        let (hdr, advance) = self.header()?;
265        let content = matches_type!(hdr, Type::Byte, Header::Byte)?;
266        self.reader.advance(advance);
267        Ok(content)
268    }
269
270    pub fn float(&mut self) -> Result<Float, ReaderError> {
271        let (hdr, advance) = self.header()?;
272        let content = matches_type!(hdr, Type::Float, Header::Float)?;
273        self.reader.advance(advance);
274        Ok(content)
275    }
276
277    pub fn constant(&mut self) -> Result<Constant, ReaderError> {
278        let (hdr, advance) = self.header()?;
279        let content = match hdr {
280            Header::Constant(constant) => Ok(constant),
281            _ => Err(ReaderError::WrongExpectedTypes {
282                expected: &[Type::False, Type::True, Type::Null, Type::Undefined],
283                got: hdr.to_type(),
284            }),
285        }?;
286        self.reader.advance(advance);
287        Ok(content)
288    }
289
290    pub fn null(&mut self) -> Result<(), ReaderError> {
291        let (hdr, advance) = self.header()?;
292        let _content = matches_type!(hdr, Type::Null, Header::Constant)?;
293        self.reader.advance(advance);
294        Ok(())
295    }
296
297    pub fn undefined(&mut self) -> Result<(), ReaderError> {
298        let (hdr, advance) = self.header()?;
299        let _content = matches_type!(hdr, Type::Undefined, Header::Constant)?;
300        self.reader.advance(advance);
301        Ok(())
302    }
303
304    pub fn bool(&mut self) -> Result<bool, ReaderError> {
305        let (hdr, advance) = self.header()?;
306        let content = match hdr {
307            Header::Constant(Constant::True) => Ok(true),
308            Header::Constant(Constant::False) => Ok(false),
309            _ => Err(ReaderError::WrongExpectedTypes {
310                expected: &[Type::False, Type::True],
311                got: hdr.to_type(),
312            }),
313        }?;
314        self.reader.advance(advance);
315        Ok(content)
316    }
317
318    pub fn bytes(&mut self) -> Result<Bytes<'a>, ReaderError> {
319        let (hdr, advance) = self.header()?;
320        let content = matches_type!(hdr, Type::Bytes, Header::Bytes)?;
321        self.reader.advance(advance);
322        match content {
323            // indefinite bytes
324            None => {
325                let mut out = Vec::new();
326                loop {
327                    let (hdr, advance) = self.header()?;
328                    self.reader.advance(advance);
329                    match hdr {
330                        Header::Break => {
331                            break;
332                        }
333                        Header::Bytes(t) => match t {
334                            None => return Err(ReaderError::BytesChunksInBytesChunks),
335                            Some(b) => {
336                                let sz = b.to_size();
337                                let data = self.expect(CborDataContext::Content, sz)?;
338                                out.push(BytesData(b, data));
339                            }
340                        },
341                        _ => {
342                            return Err(ReaderError::WrongExpectedTypeInBytes {
343                                got: hdr.to_type(),
344                            });
345                        }
346                    }
347                }
348                Ok(Bytes::Chunks(out))
349            }
350            // immediate bytes
351            Some(b) => {
352                let sz = b.to_size();
353                let data = self.expect(CborDataContext::Content, sz)?;
354                Ok(Bytes::Imm(BytesData(b, data)))
355            }
356        }
357    }
358
359    fn text_data(&mut self, b: HeaderValue) -> Result<TextData<'a>, ReaderError> {
360        let sz = b.to_size();
361        let data = self.expect(CborDataContext::Content, sz)?;
362        let data_str = std::str::from_utf8(data).map_err(|err| ReaderError::TextUTF8Error(err))?;
363        Ok(TextData(b, data_str))
364    }
365
366    pub fn text(&mut self) -> Result<Text<'a>, ReaderError> {
367        let (hdr, advance) = self.header()?;
368        let content = matches_type!(hdr, Type::Text, Header::Text)?;
369
370        self.reader.advance(advance);
371        match content {
372            // indefinite UTF8 string
373            None => {
374                let mut out = Vec::new();
375                loop {
376                    let (hdr, advance) = self.header()?;
377                    self.reader.advance(advance);
378                    match hdr {
379                        Header::Break => {
380                            break;
381                        }
382                        Header::Text(t) => match t {
383                            None => return Err(ReaderError::TextChunksInTextChunks),
384                            Some(b) => {
385                                let textdata = self.text_data(b)?;
386                                out.push(textdata)
387                            }
388                        },
389                        _ => {
390                            return Err(ReaderError::WrongExpectedTypeInText {
391                                got: hdr.to_type(),
392                            });
393                        }
394                    }
395                }
396                Ok(Text::Chunks(out))
397            }
398            // immediate UTF8 string
399            Some(b) => {
400                let textdata = self.text_data(b)?;
401                Ok(Text::Imm(textdata))
402            }
403        }
404    }
405
406    /// return the slice of data of one next element (whatever it is)
407    fn cbor_slice_neutral(&mut self) -> Result<&'a CborSlice, ReaderError> {
408        let start = self.reader.index;
409        let mut state = State::new();
410        loop {
411            let (header, advance) = self.header()?;
412            self.reader.advance(advance);
413
414            self.advance_data(&header)?;
415            state_process_header(&mut state, header)?;
416            if state.acceptable() {
417                break;
418            }
419        }
420        let data = self.reader.slice_from(start);
421        Ok(data)
422    }
423
424    pub fn array(&mut self) -> Result<Array<'a>, ReaderError> {
425        let (hdr, advance) = self.header()?;
426        let content = matches_type!(hdr, Type::Array, Header::Array)?;
427
428        self.reader.advance(advance);
429
430        let mut elements = Vec::new();
431        match content {
432            // indefinite Array
433            None => {
434                // loop for cbor slices until we find a cbor break
435                while self.peek_type()? != Type::Break {
436                    let data = self.cbor_slice_neutral()?;
437                    elements.push(data);
438                }
439                // skip the break now that we found it
440                self.reader.advance(1);
441
442                Ok(Array {
443                    len_encoding: content.into(),
444                    elements,
445                })
446            }
447            // definite Array
448            Some(len) => {
449                let sz = len.to_size();
450                for _ in 0..sz {
451                    let data = self.cbor_slice_neutral()?;
452                    elements.push(data);
453                }
454
455                Ok(Array {
456                    len_encoding: content.into(),
457                    elements,
458                })
459            }
460        }
461    }
462
463    pub fn map(&mut self) -> Result<Map<'a>, ReaderError> {
464        let (hdr, advance) = self.header()?;
465        let content = matches_type!(hdr, Type::Map, Header::Map)?;
466
467        self.reader.advance(advance);
468
469        let mut elements = Vec::new();
470        match content {
471            // indefinite Map
472            None => {
473                // loop for cbor key/value slices until we find a cbor break
474                while self.peek_type()? != Type::Break {
475                    let key = self.cbor_slice_neutral()?;
476                    let value = self.cbor_slice_neutral()?;
477                    elements.push((key, value));
478                }
479
480                // skip the break now that we found it
481                self.reader.advance(1);
482
483                Ok(Map {
484                    len_encoding: content.into(),
485                    elements,
486                })
487            }
488            // definite Map
489            Some(len) => {
490                let sz = len.to_size();
491                for _ in 0..sz {
492                    let key = self.cbor_slice_neutral()?;
493                    let value = self.cbor_slice_neutral()?;
494                    elements.push((key, value));
495                }
496
497                Ok(Map {
498                    len_encoding: content.into(),
499                    elements,
500                })
501            }
502        }
503    }
504
505    pub fn tag(&mut self) -> Result<Tag<'a>, ReaderError> {
506        let (hdr, advance) = self.header()?;
507        let tag_val = TagValue(matches_type!(hdr, Type::Tag, Header::Tag)?);
508
509        self.reader.advance(advance);
510        let data = self.cbor_slice_neutral()?;
511
512        Ok(Tag { tag_val, data })
513    }
514
515    pub fn data(&mut self) -> Result<Data<'a>, ReaderError> {
516        let ty = self.peek_type()?;
517        match ty {
518            Type::Positive => self.positive().map(Data::Positive),
519            Type::Negative => self.negative().map(Data::Negative),
520            Type::Bytes => self.bytes().map(Data::Bytes),
521            Type::Text => self.text().map(Data::Text),
522            Type::Array => self.array().map(Data::Array),
523            Type::Map => self.map().map(Data::Map),
524            Type::Tag => self.tag().map(Data::Tag),
525            Type::False => self.constant().map(|_| Data::False),
526            Type::True => self.constant().map(|_| Data::True),
527            Type::Null => self.constant().map(|_| Data::Null),
528            Type::Undefined => self.constant().map(|_| Data::Undefined),
529            Type::Float => self.float().map(Data::Float),
530            Type::Byte => self.byte().map(Data::Byte),
531            Type::Break => Err(ReaderError::UnexpectedBreakType),
532        }
533    }
534
535    pub fn decode<T: Decode>(&mut self) -> Result<T, DecodeError> {
536        <T>::decode(self)
537    }
538
539    pub fn decode_one<T: Decode>(&mut self) -> Result<T, DecodeError> {
540        let t = <T>::decode(self)?;
541        let remaining_bytes = self.remaining_bytes();
542        if remaining_bytes == 0 {
543            Ok(t)
544        } else {
545            Err(DecodeErrorKind::ReaderNotTerminated { remaining_bytes }.context::<T>())
546        }
547    }
548
549    pub fn exact_decodable_slice<T: Decode>(&mut self) -> Result<&'a CborSliceOf<T>, DecodeError> {
550        let slice = self
551            .cbor_slice_neutral()
552            .map_err(DecodeErrorKind::ReaderError)
553            .map_err(|e| e.context::<&'a CborSliceOf<T>>())?;
554        slice.validate_as()
555    }
556
557    pub fn exact_decodable_data<T: Decode>(&mut self) -> Result<CborDataOf<T>, DecodeError> {
558        let slice = self
559            .cbor_slice_neutral()
560            .map_err(DecodeErrorKind::ReaderError)
561            .map_err(|e| e.context::<CborDataOf<T>>())?;
562        slice.validate_as().map(|slice| slice.to_owned())
563    }
564}