cbored/
context.rs

1use super::prim::CborSlice;
2
3#[derive(Debug, Clone, Copy)]
4pub enum CborDataContext {
5    Header,
6    IndirectLen,
7    Content,
8}
9
10/// Trying to read data from a buffer, but missing bytes
11#[derive(Debug, Clone)]
12pub struct CborDataMissing {
13    /// The number of bytes that try to be read
14    pub expecting_bytes: usize,
15    /// The number of bytes available
16    pub got_bytes: usize,
17    /// The CBOR context which trigger this error
18    pub context: CborDataContext,
19}
20
21#[derive(Clone)]
22pub struct CborDataReader<'a> {
23    data: &'a [u8],
24    pub index: usize,
25}
26
27impl<'a> CborDataReader<'a> {
28    pub fn new(data: &'a [u8]) -> Self {
29        Self { data, index: 0 }
30    }
31
32    /// Return the number of bytes to read in the Data Reader
33    pub fn remaining_bytes(&self) -> usize {
34        self.data.len() - self.index
35    }
36
37    pub fn peek(
38        &self,
39        context: CborDataContext,
40        offset: usize,
41        n: usize,
42    ) -> Result<&'a [u8], CborDataMissing> {
43        if n == 0 {
44            return Ok(&[]);
45        }
46        let rem = self.remaining_bytes();
47        // if offset is more than remaining bytes, that might be
48        // an internal error as previous peeking should have verify
49        // the previous byte(s) are in the buffer already;
50        // only rem == offset could genuinely happen
51        if rem <= offset {
52            return Err(CborDataMissing {
53                expecting_bytes: n,
54                got_bytes: 0,
55                context,
56            });
57        }
58        let offseted_rem = rem - offset;
59        let start = self.index + offset;
60        let end = start + n;
61        if n > offseted_rem {
62            Err(CborDataMissing {
63                expecting_bytes: n,
64                got_bytes: rem - offset,
65                context,
66            })
67        } else {
68            Ok(&self.data[start..end])
69        }
70    }
71
72    /// return the next byte that would be consumed. assume there is a byte to consume,
73    /// not public
74    pub(crate) fn peek_byte(&self) -> u8 {
75        self.data[self.index]
76    }
77
78    pub fn advance(&mut self, n: usize) {
79        self.index += n;
80    }
81
82    pub fn consume(
83        &mut self,
84        context: CborDataContext,
85        n: usize,
86    ) -> Result<&'a [u8], CborDataMissing> {
87        let dat = self.peek(context, 0, n)?;
88        self.index += n;
89        Ok(dat)
90    }
91
92    // no check to see if that the slice is valid CBOR
93    pub fn slice_from(&self, start: usize) -> &'a CborSlice {
94        let slice = &self.data[start..self.index];
95        unsafe { &*(slice as *const [u8] as *const CborSlice) }
96    }
97}