lilliput_core/decoder/
bytes.rs

1use crate::{
2    error::Result,
3    header::BytesHeader,
4    io::{Read, Reference},
5    marker::Marker,
6    value::BytesValue,
7};
8
9use super::Decoder;
10
11impl<'de, R> Decoder<R>
12where
13    R: Read<'de>,
14{
15    // MARK: - Value
16
17    /// Decodes a byte array value, as a slice reference.
18    #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))]
19    pub fn decode_bytes<'s>(
20        &'s mut self,
21        scratch: &'s mut Vec<u8>,
22    ) -> Result<Reference<'de, 's, [u8]>> {
23        let header = self.decode_bytes_header()?;
24
25        self.decode_bytes_of(header, scratch)
26    }
27
28    /// Decodes a byte array value, as an owned buffer.
29    #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))]
30    pub fn decode_bytes_buf(&mut self) -> Result<Vec<u8>> {
31        let header = self.decode_bytes_header()?;
32
33        self.decode_bytes_buf_of(header)
34    }
35
36    /// Decodes a byte array value, as a `BytesValue`.
37    #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))]
38    pub fn decode_bytes_value(&mut self) -> Result<BytesValue> {
39        self.decode_bytes_buf().map(From::from)
40    }
41
42    // MARK: - Header
43
44    /// Decodes a byte array value's header.
45    #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))]
46    pub fn decode_bytes_header(&mut self) -> Result<BytesHeader> {
47        let byte = self.pull_byte_expecting(Marker::Bytes)?;
48
49        let len_width_exponent = byte & BytesHeader::LEN_WIDTH_EXPONENT_BITS;
50
51        let len_width: u8 = 1 << len_width_exponent;
52        let len = self.pull_len_bytes(len_width)?;
53
54        #[cfg(feature = "tracing")]
55        tracing::debug!(byte = crate::binary::fmt_byte(byte), len = len);
56
57        Ok(BytesHeader::for_len(len))
58    }
59
60    // MARK: - Skip
61
62    /// Skips the byte array value for a given `header`.
63    #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))]
64    pub fn skip_bytes_value_of(&mut self, header: BytesHeader) -> Result<()>
65    where
66        R: Read<'de>,
67    {
68        self.reader.skip(header.len())
69    }
70
71    // MARK: - Body
72
73    /// Decodes byte array value for a given `header`, as a `BytesValue`.
74    #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))]
75    pub fn decode_bytes_value_of(&mut self, header: BytesHeader) -> Result<BytesValue> {
76        self.decode_bytes_buf_of(header).map(From::from)
77    }
78
79    // MARK: - Private
80
81    /// Decodes byte array value for a given `header`, using a scratch buffer.
82    #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))]
83    fn decode_bytes_of<'s>(
84        &'s mut self,
85        header: BytesHeader,
86        scratch: &'s mut Vec<u8>,
87    ) -> Result<Reference<'de, 's, [u8]>> {
88        self.pull_bytes(header.len(), scratch)
89    }
90
91    /// Decodes byte array value for a given `header`, returning an owned buffer.
92    #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))]
93    fn decode_bytes_buf_of(&mut self, header: BytesHeader) -> Result<Vec<u8>> {
94        let mut buf = Vec::new();
95
96        match self.decode_bytes_of(header, &mut buf)? {
97            Reference::Borrowed(slice) => {
98                debug_assert_eq!(buf.len(), 0);
99                buf.extend_from_slice(slice);
100            }
101            Reference::Copied(slice) => {
102                debug_assert_eq!(slice.len(), buf.len());
103            }
104        }
105
106        Ok(buf)
107    }
108}