lilliput_core/decoder/
bytes.rs1use 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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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}