Skip to main content

substrate_data/wire/binary/
decoder.rs

1//! [`Decoder`]: reads the binary form — as a [`Value`] here, borrowed as a
2//! [`ValueRef`] (`decoder_ref`), or step by step by a schema reading itself
3//! (`decoder_straight`).
4
5use super::{
6    DecodeError, MAGIC, MAX_DEPTH, NEW_STRING, STREAM_LEN_BYTES, VERSION, read_varint, tag,
7    unzigzag,
8};
9use crate::model::value::{KindName, Map, Ref, RefKey, Value};
10use crate::sync::Arc;
11
12/// Strings a decoder makes room for at once: a message's keys and values.
13pub(super) const STRINGS_START: usize = 16;
14
15/// Bytes of a float, and of a 32-bit one.
16pub(super) const F64_BYTES: usize = 8;
17pub(super) const F32_BYTES: usize = 4;
18
19/// Bytes a map entry takes at least: its key and its value's tag.
20pub(super) const MAP_ENTRY_MIN: usize = 2;
21
22/// Reads the binary form. The step-by-step reads ([`Decoder::int`],
23/// [`Decoder::map`] …) answer `None` for anything but what
24/// [`crate::Schema::encode`] writes there — the schema then reads the
25/// slow way, which says what's wrong.
26#[derive(Debug)]
27pub struct Decoder<'b> {
28    pub(super) b: &'b [u8],
29    pub(super) i: usize,
30    pub(super) strings: Vec<&'b str>,
31    /// Map keys made so far, by table index: each key is allocated once.
32    pub(super) keys: Vec<Option<Arc<str>>>,
33    pub(super) depth: usize,
34}
35
36impl<'b> Decoder<'b> {
37    /// After the header: the root value next.
38    ///
39    /// # Errors
40    ///
41    /// [`DecodeError`] when the header isn't `SDAT` and this version.
42    pub fn open(bytes: &'b [u8]) -> Result<Self, DecodeError> {
43        let mut d = Decoder {
44            b: bytes,
45            i: 0,
46            strings: Vec::with_capacity(STRINGS_START),
47            keys: Vec::new(),
48            depth: 0,
49        };
50        if !bytes.starts_with(MAGIC) {
51            return Err(d.error("not Substrate Data (no `SDAT` header)"));
52        }
53        d.i = MAGIC.len();
54        let version = d.byte()?;
55        if version != VERSION {
56            return Err(d.error(format!(
57                "Substrate Data version {version}, this reads version {VERSION}"
58            )));
59        }
60        Ok(d)
61    }
62
63    /// A stream's body ([`crate::Stream`]): its count and values, its strings its own.
64    pub(crate) fn body(bytes: &'b [u8]) -> Self {
65        Decoder {
66            b: bytes,
67            i: 0,
68            strings: Vec::with_capacity(STRINGS_START),
69            keys: Vec::new(),
70            depth: 0,
71        }
72    }
73
74    /// A stream's body: its bytes, read past.
75    pub(super) fn stream_body(&mut self) -> Result<&'b [u8], DecodeError> {
76        let len = u32::from_le_bytes(self.fixed::<STREAM_LEN_BYTES>()?) as usize;
77        self.take(len)
78    }
79
80    /// A stream's values, decoded as a list.
81    pub(super) fn stream_values(&mut self) -> Result<Vec<Value>, DecodeError> {
82        let mut d = Decoder::body(self.stream_body()?);
83        d.depth = self.depth;
84        let n = d.count(1)?;
85        let mut items = Vec::with_capacity(n);
86        for _ in 0..n {
87            items.push(d.value()?);
88        }
89        d.end()?;
90        Ok(items)
91    }
92
93    /// Whether every byte was read.
94    #[must_use]
95    pub fn at_end(&self) -> bool {
96        self.i == self.b.len()
97    }
98
99    pub(super) fn end(&self) -> Result<(), DecodeError> {
100        if self.at_end() {
101            Ok(())
102        } else {
103            Err(self.error("bytes after the value"))
104        }
105    }
106
107    pub(super) fn error(&self, message: impl Into<String>) -> DecodeError {
108        DecodeError {
109            message: message.into(),
110            offset: self.i,
111        }
112    }
113
114    pub(super) fn byte(&mut self) -> Result<u8, DecodeError> {
115        let b = *self
116            .b
117            .get(self.i)
118            .ok_or_else(|| self.error("unexpected end"))?;
119        self.i += 1;
120        Ok(b)
121    }
122
123    pub(super) fn varint(&mut self) -> Result<u64, DecodeError> {
124        read_varint(self.b, &mut self.i)
125            .ok_or_else(|| self.error("a varint cut short or longer than 64 bits"))
126    }
127
128    /// A length, checked against what's left: each of the `count` things takes at least `min` bytes.
129    pub(super) fn count(&mut self, min: usize) -> Result<usize, DecodeError> {
130        let n = self.varint()?;
131        let left = self.b.len() - self.i;
132        match usize::try_from(n) {
133            Ok(n) if n <= left / min.max(1) => Ok(n),
134            _ => Err(self.error(format!("length {n} past the end ({left} bytes left)"))),
135        }
136    }
137
138    pub(super) fn fixed<const N: usize>(&mut self) -> Result<[u8; N], DecodeError> {
139        let bytes = self
140            .b
141            .get(self.i..self.i + N)
142            .ok_or_else(|| self.error("unexpected end"))?;
143        self.i += N;
144        bytes.try_into().map_err(|_| self.error("unexpected end"))
145    }
146
147    /// `len` bytes.
148    pub(super) fn take(&mut self, len: usize) -> Result<&'b [u8], DecodeError> {
149        let end = self
150            .i
151            .checked_add(len)
152            .filter(|&e| e <= self.b.len())
153            .ok_or_else(|| self.error("bytes past the end"))?;
154        let out = &self.b[self.i..end];
155        self.i = end;
156        Ok(out)
157    }
158
159    /// A packed list of floats `N` bytes wide: each one's bytes, read in place (no alignment asked).
160    pub(super) fn packed_floats<const N: usize>(
161        &mut self,
162    ) -> Result<std::slice::Iter<'b, [u8; N]>, DecodeError> {
163        let n = self.count(N)?;
164        let bytes = self.take(n * N)?;
165        Ok(bytes.as_chunks::<N>().0.iter())
166    }
167
168    /// A length and that many bytes.
169    pub(super) fn length_bytes(&mut self) -> Result<&'b [u8], DecodeError> {
170        let len =
171            usize::try_from(self.varint()?).map_err(|_| self.error("a length beyond memory"))?;
172        self.take(len)
173    }
174
175    /// A string: new (read, and added to the table) or the table's.
176    pub(super) fn string(&mut self) -> Result<&'b str, DecodeError> {
177        let i = self.string_index()?;
178        Ok(self.strings[i])
179    }
180
181    pub(super) fn string_index(&mut self) -> Result<usize, DecodeError> {
182        let v = self.varint()?;
183        if v & NEW_STRING == 0 {
184            let i = (v >> 1) as usize;
185            return if i < self.strings.len() {
186                Ok(i)
187            } else {
188                Err(self.error(format!("string {i} isn't in the table")))
189            };
190        }
191        let len = usize::try_from(v >> 1).map_err(|_| self.error("a length beyond memory"))?;
192        let at = self.i;
193        let s = std::str::from_utf8(self.take(len)?).map_err(|_| DecodeError {
194            message: "a string isn't UTF-8".into(),
195            offset: at,
196        })?;
197        self.strings.push(s);
198        Ok(self.strings.len() - 1)
199    }
200
201    /// A map key: shared with every other map that has it.
202    pub(super) fn shared_key(&mut self) -> Result<Arc<str>, DecodeError> {
203        let i = self.string_index()?;
204        if self.keys.len() <= i {
205            self.keys.resize(i + 1, None);
206        }
207        Ok(self.keys[i]
208            .get_or_insert_with(|| self.strings[i].into())
209            .clone())
210    }
211
212    /// A reference's kind and id, each checked: a malformed one is an error.
213    pub(super) fn reference(&mut self) -> Result<(KindName, &'b str), DecodeError> {
214        let kind_at = self.i;
215        let kind = KindName::new(self.string()?).map_err(|e| DecodeError {
216            message: e.to_string(),
217            offset: kind_at,
218        })?;
219        let id_at = self.i;
220        let id = self.string()?;
221        if !RefKey::is_valid(id) {
222            return Err(DecodeError {
223                message: format!("`{id}` isn't a reference's id"),
224                offset: id_at,
225            });
226        }
227        Ok((kind, id))
228    }
229
230    pub(super) fn deeper(&mut self) -> Result<(), DecodeError> {
231        self.depth += 1;
232        if self.depth > MAX_DEPTH {
233            return Err(self.error(format!("nested deeper than {MAX_DEPTH} levels")));
234        }
235        Ok(())
236    }
237
238    /// The next value, owned.
239    ///
240    /// # Errors
241    ///
242    /// [`DecodeError`] when the bytes aren't a value.
243    pub fn value(&mut self) -> Result<Value, DecodeError> {
244        Ok(match self.byte()? {
245            tag::NULL => Value::Null,
246            tag::FALSE => Value::Bool(false),
247            tag::TRUE => Value::Bool(true),
248            tag::INT => Value::Int(unzigzag(self.varint()?)),
249            tag::FLOAT => Value::Float(f64::from_le_bytes(self.fixed()?)),
250            tag::FLOAT32 => Value::Float(f64::from(f32::from_le_bytes(self.fixed()?))),
251            tag::FLOATS => Value::List(
252                self.packed_floats::<F64_BYTES>()?
253                    .map(|f| Value::Float(f64::from_le_bytes(*f)))
254                    .collect(),
255            ),
256            tag::FLOATS32 => Value::List(
257                self.packed_floats::<F32_BYTES>()?
258                    .map(|f| Value::Float(f64::from(f32::from_le_bytes(*f))))
259                    .collect(),
260            ),
261            tag::STR => Value::Str(self.string()?.to_owned()),
262            tag::LIST => self.list_value()?,
263            tag::MAP => self.map_value()?,
264            tag::REF => {
265                let (kind, id) = self.reference()?;
266                Value::Ref(Ref::new(kind, RefKey::spelled(id)))
267            }
268            tag::BYTES => Value::Bytes(self.length_bytes()?.to_vec()),
269            tag::INTS => self.ints_value()?,
270            tag::STREAM => Value::List(self.stream_values()?),
271            t => {
272                self.i -= 1;
273                return Err(self.error(format!("unknown tag {t}")));
274            }
275        })
276    }
277
278    fn list_value(&mut self) -> Result<Value, DecodeError> {
279        let n = self.count(1)?;
280        self.deeper()?;
281        let mut items = Vec::with_capacity(n);
282        for _ in 0..n {
283            items.push(self.value()?);
284        }
285        self.depth -= 1;
286        Ok(Value::List(items))
287    }
288
289    fn map_value(&mut self) -> Result<Value, DecodeError> {
290        let n = self.count(MAP_ENTRY_MIN)?;
291        self.deeper()?;
292        let mut map = Map::with_capacity(n);
293        for _ in 0..n {
294            let k = self.shared_key()?;
295            map.push_unchecked(k, self.value()?);
296        }
297        self.depth -= 1;
298        Ok(Value::Map(map))
299    }
300
301    fn ints_value(&mut self) -> Result<Value, DecodeError> {
302        let n = self.count(1)?;
303        let mut items = Vec::with_capacity(n);
304        for _ in 0..n {
305            items.push(Value::Int(unzigzag(self.varint()?)));
306        }
307        Ok(Value::List(items))
308    }
309}