gel_protocol/serialization/decode/
raw_composite.rs

1use self::inner::DecodeCompositeInner;
2use crate::errors::{self, DecodeError};
3use snafu::ensure;
4
5pub struct DecodeTupleLike<'t> {
6    inner: DecodeCompositeInner<'t>,
7}
8
9impl<'t> DecodeTupleLike<'t> {
10    fn new(buf: &'t [u8]) -> Result<Self, DecodeError> {
11        let inner = DecodeCompositeInner::read_tuple_like_header(buf)?;
12        Ok(DecodeTupleLike { inner })
13    }
14
15    pub fn new_object(buf: &'t [u8], expected_count: usize) -> Result<Self, DecodeError> {
16        let elements = Self::new(buf)?;
17        ensure!(
18            elements.inner.count() == expected_count,
19            errors::ObjectSizeMismatch
20        );
21        Ok(elements)
22    }
23
24    pub fn new_tuple(buf: &'t [u8], expected_count: usize) -> Result<Self, DecodeError> {
25        let elements = Self::new(buf)?;
26        ensure!(
27            elements.inner.count() == expected_count,
28            errors::TupleSizeMismatch
29        );
30        Ok(elements)
31    }
32
33    pub fn read(&mut self) -> Result<Option<&'t [u8]>, DecodeError> {
34        self.inner.read_object_element()
35    }
36
37    pub fn read_n(&mut self, n: usize) -> Result<Vec<Option<&'t [u8]>>, DecodeError> {
38        let mut bufs = Vec::with_capacity(n);
39        for _ in 0..n {
40            bufs.push(self.read()?);
41        }
42        Ok(bufs)
43    }
44
45    pub fn skip_element(&mut self) -> Result<(), DecodeError> {
46        self.read()?;
47        Ok(())
48    }
49}
50
51pub struct DecodeArrayLike<'t> {
52    inner: DecodeCompositeInner<'t>,
53}
54
55impl<'t> DecodeArrayLike<'t> {
56    pub fn new_array(buf: &'t [u8]) -> Result<Self, DecodeError> {
57        let inner = DecodeCompositeInner::read_array_like_header(buf, || {
58            errors::InvalidArrayShape.build()
59        })?;
60        Ok(DecodeArrayLike { inner })
61    }
62
63    pub fn new_set(buf: &'t [u8]) -> Result<Self, DecodeError> {
64        let inner =
65            DecodeCompositeInner::read_array_like_header(buf, || errors::InvalidSetShape.build())?;
66        Ok(DecodeArrayLike { inner })
67    }
68
69    pub fn new_collection(buf: &'t [u8]) -> Result<Self, DecodeError> {
70        let inner = DecodeCompositeInner::read_array_like_header(buf, || {
71            errors::InvalidArrayOrSetShape.build()
72        })?;
73        Ok(DecodeArrayLike { inner })
74    }
75
76    pub fn new_tuple_header(buf: &'t [u8]) -> Result<Self, DecodeError> {
77        let inner = DecodeCompositeInner::read_tuple_like_header(buf)?;
78        Ok(Self { inner })
79    }
80}
81
82pub struct DecodeRange<'t> {
83    inner: DecodeCompositeInner<'t>,
84}
85
86impl<'t> DecodeRange<'t> {
87    pub fn new(buf: &'t [u8]) -> Result<Self, DecodeError> {
88        // flags header should already have been read externally
89        let inner = DecodeCompositeInner { raw: buf, count: 2 };
90        Ok(DecodeRange { inner })
91    }
92    pub fn read(&mut self) -> Result<&[u8], DecodeError> {
93        self.inner.read_array_like_element()
94    }
95}
96
97impl<'t> Iterator for DecodeArrayLike<'t> {
98    type Item = Result<&'t [u8], DecodeError>;
99
100    fn next(&mut self) -> Option<Self::Item> {
101        if self.len() > 0 {
102            Some(self.inner.read_array_like_element())
103        } else {
104            None
105        }
106    }
107
108    fn size_hint(&self) -> (usize, Option<usize>) {
109        let len = self.len();
110        (len, Some(len))
111    }
112}
113
114impl ExactSizeIterator for DecodeArrayLike<'_> {
115    fn len(&self) -> usize {
116        self.inner.count()
117    }
118}
119
120mod inner {
121    use crate::errors::{self, DecodeError};
122    use bytes::Buf;
123    use snafu::ensure;
124
125    pub(super) struct DecodeCompositeInner<'t> {
126        pub raw: &'t [u8],
127        pub count: usize,
128    }
129
130    impl std::fmt::Debug for DecodeCompositeInner<'_> {
131        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
132            f.write_fmt(format_args!(
133                "count = {} data = {:x?}",
134                self.count, self.raw
135            ))
136        }
137    }
138
139    impl<'t> DecodeCompositeInner<'t> {
140        fn underflow(&mut self) -> errors::Underflow {
141            // after one underflow happened, all further reads should underflow as well
142            // all other errors should be recoverable, since they only affect the content of one element and not the size of that element
143            self.raw = &[0u8; 0];
144            errors::Underflow
145        }
146
147        pub fn count(&self) -> usize {
148            self.count
149        }
150
151        fn new(bytes: &'t [u8], count: usize) -> Self {
152            DecodeCompositeInner { raw: bytes, count }
153        }
154
155        fn read_element(&mut self, position: usize) -> Result<&'t [u8], DecodeError> {
156            assert!(
157                self.count() > 0,
158                "reading from a finished elements sequence"
159            );
160            self.count -= 1;
161            ensure!(self.raw.len() >= position, self.underflow());
162            let result = &self.raw[..position];
163            self.raw.advance(position);
164            ensure!(self.count > 0 || self.raw.is_empty(), errors::ExtraData);
165            Ok(result)
166        }
167
168        pub fn read_raw_object_element(&mut self) -> Result<Option<&'t [u8]>, DecodeError> {
169            ensure!(self.raw.remaining() >= 4, self.underflow());
170            let len = self.raw.get_i32();
171            if len < 0 {
172                ensure!(len == -1, errors::InvalidMarker);
173                return Ok(None);
174            }
175            let len = len as usize;
176            Ok(Some(self.read_element(len)?))
177        }
178
179        pub fn read_object_element(&mut self) -> Result<Option<&'t [u8]>, DecodeError> {
180            ensure!(self.raw.remaining() >= 8, self.underflow());
181            let _reserved = self.raw.get_i32();
182            self.read_raw_object_element()
183        }
184
185        pub fn read_array_like_element(&mut self) -> Result<&'t [u8], DecodeError> {
186            ensure!(self.raw.remaining() >= 4, self.underflow());
187            let len = self.raw.get_i32() as usize;
188            self.read_element(len)
189        }
190
191        pub fn read_tuple_like_header(mut buf: &'t [u8]) -> Result<Self, DecodeError> {
192            ensure!(buf.remaining() >= 4, errors::Underflow);
193            let count = buf.get_u32() as usize;
194            Ok(Self::new(buf, count))
195        }
196
197        pub fn read_array_like_header(
198            mut buf: &'t [u8],
199            error: impl Fn() -> DecodeError,
200        ) -> Result<Self, DecodeError> {
201            ensure!(buf.remaining() >= 12, errors::Underflow);
202            let ndims = buf.get_u32();
203            let _reserved0 = buf.get_u32();
204            let _reserved1 = buf.get_u32();
205            if ndims == 0 {
206                return Ok(Self::new(buf, 0));
207            }
208            if ndims != 1 {
209                return Err(error());
210            }
211            ensure!(buf.remaining() >= 8, errors::Underflow);
212            let size = buf.get_u32() as usize;
213            let lower = buf.get_u32();
214            if lower != 1 {
215                return Err(error());
216            }
217            Ok(Self::new(buf, size))
218        }
219    }
220}