1use yog_sync::Arc;
5
6use bumpalo::Bump;
7
8use super::{
9 DecodeError, MAGIC, MAX_DEPTH, NEW_STRING, STREAM_LEN_BYTES, VERSION, read_varint, tag,
10 unzigzag,
11};
12use crate::borrowed::{MapRef, ValueRef};
13use crate::value::{Map, Ref, Res, Value};
14
15const STRINGS_START: usize = 16;
17
18const F64_BYTES: usize = 8;
20const F32_BYTES: usize = 4;
21
22const MAP_ENTRY_MIN: usize = 2;
24
25pub struct Decoder<'b> {
30 b: &'b [u8],
31 i: usize,
32 strings: Vec<&'b str>,
33 keys: Vec<Option<Arc<str>>>,
35 depth: usize,
36}
37
38impl<'b> Decoder<'b> {
39 pub fn open(bytes: &'b [u8]) -> Result<Self, DecodeError> {
41 let mut d = Decoder {
42 b: bytes,
43 i: 0,
44 strings: Vec::with_capacity(STRINGS_START),
45 keys: Vec::new(),
46 depth: 0,
47 };
48 if !bytes.starts_with(MAGIC) {
49 return Err(d.error("not Yog Data (no `YOGD` header)"));
50 }
51 d.i = MAGIC.len();
52 let version = d.byte()?;
53 if version != VERSION {
54 return Err(d.error(format!(
55 "Yog Data version {version}, this reads version {VERSION}"
56 )));
57 }
58 Ok(d)
59 }
60
61 pub(crate) fn body(bytes: &'b [u8]) -> Self {
63 Decoder {
64 b: bytes,
65 i: 0,
66 strings: Vec::with_capacity(STRINGS_START),
67 keys: Vec::new(),
68 depth: 0,
69 }
70 }
71
72 fn stream_body(&mut self) -> Result<&'b [u8], DecodeError> {
74 let len = u32::from_le_bytes(self.fixed::<STREAM_LEN_BYTES>()?) as usize;
75 self.take(len)
76 }
77
78 fn stream_values(&mut self) -> Result<Vec<Value>, DecodeError> {
80 let mut d = Decoder::body(self.stream_body()?);
81 d.depth = self.depth;
82 let n = d.count(1)?;
83 let mut items = Vec::with_capacity(n);
84 for _ in 0..n {
85 items.push(d.value()?);
86 }
87 d.end()?;
88 Ok(items)
89 }
90
91 pub fn at_end(&self) -> bool {
93 self.i == self.b.len()
94 }
95
96 pub(super) fn end(&self) -> Result<(), DecodeError> {
97 if self.at_end() {
98 Ok(())
99 } else {
100 Err(self.error("bytes after the value"))
101 }
102 }
103
104 fn error(&self, message: impl Into<String>) -> DecodeError {
105 DecodeError {
106 message: message.into(),
107 offset: self.i,
108 }
109 }
110
111 fn byte(&mut self) -> Result<u8, DecodeError> {
112 let b = *self
113 .b
114 .get(self.i)
115 .ok_or_else(|| self.error("unexpected end"))?;
116 self.i += 1;
117 Ok(b)
118 }
119
120 fn varint(&mut self) -> Result<u64, DecodeError> {
121 read_varint(self.b, &mut self.i)
122 .ok_or_else(|| self.error("a varint cut short or longer than 64 bits"))
123 }
124
125 fn count(&mut self, min: usize) -> Result<usize, DecodeError> {
127 let n = self.varint()?;
128 let left = self.b.len() - self.i;
129 if n > (left / min.max(1)) as u64 {
130 return Err(self.error(format!("length {n} past the end ({left} bytes left)")));
131 }
132 Ok(n as usize)
133 }
134
135 fn fixed<const N: usize>(&mut self) -> Result<[u8; N], DecodeError> {
136 let bytes = self
137 .b
138 .get(self.i..self.i + N)
139 .ok_or_else(|| self.error("unexpected end"))?;
140 self.i += N;
141 bytes.try_into().map_err(|_| self.error("unexpected end"))
142 }
143
144 fn take(&mut self, len: usize) -> Result<&'b [u8], DecodeError> {
146 let end = self
147 .i
148 .checked_add(len)
149 .filter(|&e| e <= self.b.len())
150 .ok_or_else(|| self.error("bytes past the end"))?;
151 let out = &self.b[self.i..end];
152 self.i = end;
153 Ok(out)
154 }
155
156 fn packed_floats<const N: usize>(
158 &mut self,
159 ) -> Result<std::slice::Iter<'b, [u8; N]>, DecodeError> {
160 let n = self.count(N)?;
161 let bytes = self.take(n * N)?;
162 Ok(bytes.as_chunks::<N>().0.iter())
163 }
164
165 fn length_bytes(&mut self) -> Result<&'b [u8], DecodeError> {
167 let len =
168 usize::try_from(self.varint()?).map_err(|_| self.error("a length beyond memory"))?;
169 self.take(len)
170 }
171
172 fn string(&mut self) -> Result<&'b str, DecodeError> {
174 let i = self.string_index()?;
175 Ok(self.strings[i])
176 }
177
178 fn string_index(&mut self) -> Result<usize, DecodeError> {
179 let v = self.varint()?;
180 if v & NEW_STRING == 0 {
181 let i = (v >> 1) as usize;
182 return if i < self.strings.len() {
183 Ok(i)
184 } else {
185 Err(self.error(format!("string {i} isn't in the table")))
186 };
187 }
188 let len = usize::try_from(v >> 1).map_err(|_| self.error("a length beyond memory"))?;
189 let at = self.i;
190 let s = std::str::from_utf8(self.take(len)?).map_err(|_| DecodeError {
191 message: "a string isn't UTF-8".into(),
192 offset: at,
193 })?;
194 self.strings.push(s);
195 Ok(self.strings.len() - 1)
196 }
197
198 fn shared_key(&mut self) -> Result<Arc<str>, DecodeError> {
200 let i = self.string_index()?;
201 if self.keys.len() <= i {
202 self.keys.resize(i + 1, None);
203 }
204 Ok(self.keys[i]
205 .get_or_insert_with(|| self.strings[i].into())
206 .clone())
207 }
208
209 fn deeper(&mut self) -> Result<(), DecodeError> {
210 self.depth += 1;
211 if self.depth > MAX_DEPTH {
212 return Err(self.error(format!("nested deeper than {MAX_DEPTH} levels")));
213 }
214 Ok(())
215 }
216
217 pub fn value(&mut self) -> Result<Value, DecodeError> {
219 Ok(match self.byte()? {
220 tag::NULL => Value::Null,
221 tag::FALSE => Value::Bool(false),
222 tag::TRUE => Value::Bool(true),
223 tag::INT => Value::Int(unzigzag(self.varint()?)),
224 tag::FLOAT => Value::Float(f64::from_le_bytes(self.fixed()?)),
225 tag::FLOAT32 => Value::Float(f64::from(f32::from_le_bytes(self.fixed()?))),
226 tag::FLOATS => Value::List(
227 self.packed_floats::<F64_BYTES>()?
228 .map(|f| Value::Float(f64::from_le_bytes(*f)))
229 .collect(),
230 ),
231 tag::FLOATS32 => Value::List(
232 self.packed_floats::<F32_BYTES>()?
233 .map(|f| Value::Float(f64::from(f32::from_le_bytes(*f))))
234 .collect(),
235 ),
236 tag::STR => Value::Str(self.string()?.to_owned()),
237 tag::LIST => {
238 let n = self.count(1)?;
239 self.deeper()?;
240 let mut items = Vec::with_capacity(n);
241 for _ in 0..n {
242 items.push(self.value()?);
243 }
244 self.depth -= 1;
245 Value::List(items)
246 }
247 tag::MAP => {
248 let n = self.count(MAP_ENTRY_MIN)?;
249 self.deeper()?;
250 let mut map = Map::with_capacity(n);
251 for _ in 0..n {
252 let k = self.shared_key()?;
253 map.push_unchecked(k, self.value()?);
254 }
255 self.depth -= 1;
256 Value::Map(map)
257 }
258 t @ (tag::REF | tag::TAG) => {
259 let r = Ref {
260 kind: self.string()?.to_owned(),
261 id: self.string()?.to_owned(),
262 };
263 if t == tag::REF {
264 Value::Ref(r)
265 } else {
266 Value::Tag(r)
267 }
268 }
269 tag::RES => Value::Res(Res {
270 set: self.string()?.to_owned(),
271 key: self.string()?.to_owned(),
272 }),
273 tag::TEXT => Value::Text(self.string()?.to_owned()),
274 tag::IMAGE => Value::Image(self.string()?.to_owned()),
275 tag::COLOR => Value::Color(u32::from_le_bytes(self.fixed()?)),
276 tag::LANG => Value::Lang(self.string()?.to_owned()),
277 tag::BYTES => Value::Bytes(self.length_bytes()?.to_vec()),
278 tag::INTS => {
279 let n = self.count(1)?;
280 let mut items = Vec::with_capacity(n);
281 for _ in 0..n {
282 items.push(Value::Int(unzigzag(self.varint()?)));
283 }
284 Value::List(items)
285 }
286 tag::STREAM => Value::List(self.stream_values()?),
287 t => {
288 self.i -= 1;
289 return Err(self.error(format!("unknown tag {t}")));
290 }
291 })
292 }
293
294 pub fn value_ref<'a>(&mut self, arena: &'a Bump) -> Result<ValueRef<'a>, DecodeError>
296 where
297 'b: 'a,
298 {
299 let mut stack = Vec::new();
300 self.value_ref_in(arena, &mut stack)
301 }
302
303 fn value_ref_in<'a>(
305 &mut self,
306 arena: &'a Bump,
307 stack: &mut Vec<ValueRef<'a>>,
308 ) -> Result<ValueRef<'a>, DecodeError>
309 where
310 'b: 'a,
311 {
312 Ok(match self.byte()? {
313 tag::NULL => ValueRef::Null,
314 tag::FALSE => ValueRef::Bool(false),
315 tag::TRUE => ValueRef::Bool(true),
316 tag::INT => ValueRef::Int(unzigzag(self.varint()?)),
317 tag::FLOAT => ValueRef::Float(f64::from_le_bytes(self.fixed()?)),
318 tag::FLOAT32 => ValueRef::Float(f64::from(f32::from_le_bytes(self.fixed()?))),
319 t @ (tag::FLOATS | tag::FLOATS32) => self.floats_ref(arena, t == tag::FLOATS)?,
320 tag::STR => ValueRef::Str(self.string()?),
321 tag::LIST => {
322 let n = self.count(1)?;
323 self.deeper()?;
324 let items = self.items_ref(arena, stack, n)?;
325 self.depth -= 1;
326 ValueRef::List(items)
327 }
328 tag::MAP => self.map_ref(arena, stack)?,
329 t @ (tag::REF | tag::TAG) => {
330 let (kind, id) = (self.string()?, self.string()?);
331 if t == tag::REF {
332 ValueRef::Ref { kind, id }
333 } else {
334 ValueRef::Tag { kind, id }
335 }
336 }
337 tag::RES => ValueRef::Res {
338 set: self.string()?,
339 key: self.string()?,
340 },
341 tag::TEXT => ValueRef::Text(self.string()?),
342 tag::IMAGE => ValueRef::Image(self.string()?),
343 tag::COLOR => ValueRef::Color(u32::from_le_bytes(self.fixed()?)),
344 tag::LANG => ValueRef::Lang(self.string()?),
345 tag::BYTES => ValueRef::Bytes(self.length_bytes()?),
346 tag::INTS => self.ints_ref(arena)?,
347 tag::STREAM => {
348 let mut d = Decoder::body(self.stream_body()?);
349 d.depth = self.depth;
350 let n = d.count(1)?;
351 let items = d.items_ref(arena, stack, n)?;
352 d.end()?;
353 ValueRef::List(items)
354 }
355 t => {
356 self.i -= 1;
357 return Err(self.error(format!("unknown tag {t}")));
358 }
359 })
360 }
361
362 fn items_ref<'a>(
364 &mut self,
365 arena: &'a Bump,
366 stack: &mut Vec<ValueRef<'a>>,
367 n: usize,
368 ) -> Result<&'a [ValueRef<'a>], DecodeError>
369 where
370 'b: 'a,
371 {
372 let start = stack.len();
373 for _ in 0..n {
374 let v = self.value_ref_in(arena, stack)?;
375 stack.push(v);
376 }
377 let items = arena.alloc_slice_copy(&stack[start..]);
378 stack.truncate(start);
379 Ok(items)
380 }
381
382 fn map_ref<'a>(
383 &mut self,
384 arena: &'a Bump,
385 stack: &mut Vec<ValueRef<'a>>,
386 ) -> Result<ValueRef<'a>, DecodeError>
387 where
388 'b: 'a,
389 {
390 let n = self.count(MAP_ENTRY_MIN)?;
391 self.deeper()?;
392 let mut entries = bumpalo::collections::Vec::with_capacity_in(n, arena);
393 for _ in 0..n {
394 let k = self.string()?;
395 entries.push((k, self.value_ref_in(arena, stack)?));
396 }
397 self.depth -= 1;
398 Ok(ValueRef::Map(MapRef(entries.into_bump_slice())))
399 }
400
401 fn ints_ref<'a>(&mut self, arena: &'a Bump) -> Result<ValueRef<'a>, DecodeError> {
402 let n = self.count(1)?;
403 let mut items = bumpalo::collections::Vec::with_capacity_in(n, arena);
404 for _ in 0..n {
405 items.push(ValueRef::Int(unzigzag(self.varint()?)));
406 }
407 Ok(ValueRef::List(items.into_bump_slice()))
408 }
409
410 fn floats_ref<'a>(&mut self, arena: &'a Bump, wide: bool) -> Result<ValueRef<'a>, DecodeError> {
412 let items: Vec<ValueRef<'a>> = if wide {
413 self.packed_floats::<F64_BYTES>()?
414 .map(|f| ValueRef::Float(f64::from_le_bytes(*f)))
415 .collect()
416 } else {
417 self.packed_floats::<F32_BYTES>()?
418 .map(|f| ValueRef::Float(f64::from(f32::from_le_bytes(*f))))
419 .collect()
420 };
421 Ok(ValueRef::List(arena.alloc_slice_copy(&items)))
422 }
423
424 fn next_is(&mut self, t: u8) -> Option<()> {
428 (self.b.get(self.i) == Some(&t)).then(|| self.i += 1)
429 }
430
431 pub fn null(&mut self) -> bool {
433 self.next_is(tag::NULL).is_some()
434 }
435
436 pub fn bool(&mut self) -> Option<bool> {
437 match *self.b.get(self.i)? {
438 tag::FALSE | tag::TRUE => {
439 self.i += 1;
440 Some(self.b[self.i - 1] == tag::TRUE)
441 }
442 _ => None,
443 }
444 }
445
446 pub fn int(&mut self) -> Option<i64> {
447 self.next_is(tag::INT)?;
448 self.varint().ok().map(unzigzag)
449 }
450
451 pub fn float(&mut self) -> Option<f64> {
453 match *self.b.get(self.i)? {
454 tag::FLOAT => {
455 self.i += 1;
456 self.fixed().ok().map(f64::from_le_bytes)
457 }
458 tag::FLOAT32 => {
459 self.i += 1;
460 self.fixed().ok().map(|b| f64::from(f32::from_le_bytes(b)))
461 }
462 tag::INT => self.int().map(|n| n as f64),
463 _ => None,
464 }
465 }
466
467 pub fn str(&mut self) -> Option<&'b str> {
468 self.next_is(tag::STR)?;
469 self.string().ok()
470 }
471
472 pub fn bytes(&mut self) -> Option<&'b [u8]> {
473 self.next_is(tag::BYTES)?;
474 self.length_bytes().ok()
475 }
476
477 pub fn list(&mut self) -> Option<usize> {
479 self.next_is(tag::LIST)?;
480 let n = self.count(1).ok()?;
481 self.deeper().ok()?;
482 Some(n)
483 }
484
485 pub fn ints(&mut self) -> Option<usize> {
487 self.next_is(tag::INTS)?;
488 self.count(1).ok()
489 }
490
491 pub fn stream(&mut self) -> Option<&'b [u8]> {
493 self.next_is(tag::STREAM)?;
494 self.stream_body().ok()
495 }
496
497 pub(crate) fn rest(&self) -> &'b [u8] {
499 &self.b[self.i..]
500 }
501
502 pub(crate) fn stream_count(&mut self) -> Option<usize> {
504 self.count(1).ok()
505 }
506
507 pub fn floats(&mut self) -> Option<Vec<f64>> {
510 if self.next_is(tag::FLOATS32).is_some() {
511 return Some(crate::frame::floats::widen(
512 self.packed_floats::<F32_BYTES>()
513 .ok()?
514 .as_slice()
515 .as_flattened(),
516 ));
517 }
518 self.next_is(tag::FLOATS)?;
519 Some(
520 self.packed_floats::<F64_BYTES>()
521 .ok()?
522 .map(|f| f64::from_le_bytes(*f))
523 .collect(),
524 )
525 }
526
527 pub fn floats32(&mut self) -> Option<Vec<f32>> {
529 self.next_is(tag::FLOATS32)?;
530 Some(
531 self.packed_floats::<F32_BYTES>()
532 .ok()?
533 .map(|f| f32::from_le_bytes(*f))
534 .collect(),
535 )
536 }
537
538 pub fn packed_int(&mut self) -> Option<i64> {
540 self.varint().ok().map(unzigzag)
541 }
542
543 pub fn map(&mut self) -> Option<usize> {
546 self.next_is(tag::MAP)?;
547 let n = self.count(MAP_ENTRY_MIN).ok()?;
548 self.deeper().ok()?;
549 Some(n)
550 }
551
552 pub fn leave(&mut self) {
554 self.depth = self.depth.saturating_sub(1);
555 }
556
557 pub fn key(&mut self) -> Option<&'b str> {
558 self.string().ok()
559 }
560
561 pub fn skip(&mut self) -> Option<()> {
563 let arena = Bump::new();
564 self.value_ref(&arena).ok().map(drop)
565 }
566}