Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_jdat/src/bdat/dec.rs

66.2 KiB, 28 runs

created by r1870400018:447, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1use crate::{
2 prelude::*,
3 bdat::limits::DecodeLimits,
4 note::NoteConfig,
5 usr::{
6 UsrKindCode,
7 UsrKindId,
8 },
9};
10
11use oxedyne_fe2o3_core::{
12 prelude::*,
13 byte::FromBytes,
14};
15use oxedyne_fe2o3_num::float::{
16 Float32,
17 Float64,
18};
19
20use std::convert::TryFrom;
21
22use bigdecimal::{
23 BigDecimal,
24 Zero,
25};
26use num_bigint::BigInt;
27
28
29impl FromBytes for Dat {
30
31 /// Read the `Dat` from the buffer, and include the number of bytes required in the return
32 /// tuple.
33 ///
34 /// The bytes are trusted, so a hostile encoding can nest deeply enough to exhaust the stack.
35 /// Read anything you did not encode yourself with [`Dat::from_bytes_limited`] instead.
36 fn from_bytes(buf: &[u8]) -> Outcome<(Self, usize)> {
37 Self::from_bytes_depth(buf, &DecodeLimits::UNLIMITED, 1, 0)
38 }
39}
40
41impl Dat {
42
43 pub fn from_bytes_limited(
44 buf: &[u8],
45 lims: &DecodeLimits,
46 )
47 -> Outcome<(Self, usize)>
48 {
49 res!(lims.check_len(buf.len()));
50 Self::from_bytes_depth(buf, lims, 1, 0)
51 }
52
53 fn from_bytes_depth(
54 buf: &[u8],
55 lims: &DecodeLimits,
56 depth: usize,
57 pos: usize,
58 )
59 -> Outcome<(Self, usize)>
60 {
61 res!(lims.check_depth(depth, pos));
62 if buf.len() == 0 {
63 return Err(err!("No bytes to decode."; Input, Invalid));
64 }
65 match buf[0] {
66 // Molecular Kinds ========================
67 // Unitary
68 Self::USR_CODE => return Self::from_bytes_usr(buf, lims, depth, pos),
69 Self::BOX_CODE => return Self::from_bytes_box(buf, lims, depth, pos),
70 Self::OPT_SOME_CODE => return Self::from_bytes_opt_some(buf, lims, depth, pos),
71 Self::ABOX_CODE => return Self::from_bytes_abox(buf, lims, depth, pos),
72 // Heterogenous
73 Self::LIST_CODE |
74 Self::VEK_CODE => return Self::from_bytes_list(buf, lims, depth, pos),
75 Self::TUP2_CODE |
76 Self::TUP3_CODE |
77 Self::TUP4_CODE |
78 Self::TUP5_CODE |
79 Self::TUP6_CODE |
80 Self::TUP7_CODE |
81 Self::TUP8_CODE |
82 Self::TUP9_CODE |
83 Self::TUP10_CODE => return Self::from_bytes_tuple(buf, lims, depth, pos),
84 Self::MAP_CODE => return Self::from_bytes_map(buf, lims, depth, pos),
85 Self::OMAP_CODE => return Self::from_bytes_ordmap(buf, lims, depth, pos),
86 // Every other kind is atomic, enclosing no other value. Those arms carry the
87 // bulk of the decoder's stack frame, so they too are decoded in a frame of their
88 // own, leaving the frame that nesting repeats a small one.
89 _ => return Self::from_bytes_atomic(buf),
90 }
91 }
92
93 #[inline(never)]
94 fn from_bytes_usr(
95 buf: &[u8],
96 lims: &DecodeLimits,
97 depth: usize,
98 pos: usize,
99 )
100 -> Outcome<(Self, usize)>
101 {
102 //
103 // +---+---+---+---+---+---+---+---+---+
104 // | c | u16 | | | | | | |
105 // +---+---+---+---+---+---+---+---+---+
106 // ^ ^ ^ \___________________/
107 // | | | |
108 // | | opt code inner Dat
109 // | ukid_code (if some)
110 // daticle
111 // code
112 //
113 const CODE_LEN: usize = UsrKindId::CODE_BYTE_LEN;
114 // A usr daticle is the daticle code, the kind code, then an option code, so the smallest
115 // valid encoding is `2 + CODE_LEN` bytes. Guarding on `CODE_LEN` alone let a buffer one byte
116 // short reach the `buf[1 + CODE_LEN]` read below and panic on hostile input.
117 if buf.len() > 1 + CODE_LEN {
118 let ukid_code = UsrKindCode::from_be_bytes(
119 res!(<[u8; CODE_LEN]>::try_from(&buf[1..1 + CODE_LEN]), Decode, Bytes)
120 );
121 let opt_code = buf[1 + CODE_LEN];
122 match opt_code {
123 Self::OPT_NONE_CODE => return Ok((
124 Dat::Usr(
125 UsrKindId::from(ukid_code),
126 None,
127 ),
128 2 + CODE_LEN,
129 )),
130 Self::OPT_SOME_CODE => {
131 let (inner, n) = res!(Self::from_bytes_depth(&buf[2 + CODE_LEN..], lims, depth + 1, pos + 2 + CODE_LEN));
132 return Ok((
133 Dat::Usr(
134 UsrKindId::from(ukid_code),
135 Some(Box::new(inner)),
136 ),
137 2 + CODE_LEN + n,
138 ));
139 }
140 _ => return Err(err!(
141 "Expecting an option code {} (for none) or {} (for some), \
142 instead found code {}.",
143 Self::OPT_NONE_CODE, Self::OPT_SOME_CODE, opt_code;
144 Bytes, Input, Decode, Missing)),
145 }
146 } else {
147 return Err(<Dat as FromBytes>::too_few(
148 buf.len(), CODE_LEN, &Self::code_name(buf[0]), file!(), line!()));
149 }
150 }
151
152 #[inline(never)]
153 fn from_bytes_box(
154 buf: &[u8],
155 lims: &DecodeLimits,
156 depth: usize,
157 pos: usize,
158 )
159 -> Outcome<(Self, usize)>
160 {
161 //
162 // +---+---+---+---+---+---+---+---+---+
163 // | c | | | | | | | | |
164 // +---+---+---+---+---+---+---+---+---+
165 // \_______________________________/
166 // |
167 // inner Dat
168 //
169 // Dat::Box(k) byte encoding does nothing more than prepend Dat k with
170 // Dat::BOX_CODE
171 //
172 if buf.len() > 1 {
173 let (inner, n) = res!(Self::from_bytes_depth(&buf[1..], lims, depth + 1, pos + 1));
174 return Ok((Dat::Box(Box::new(inner)), 1 + n));
175 } else {
176 return Err(<Dat as FromBytes>::too_few(
177 buf.len(), 1, &Self::code_name(buf[0]), file!(), line!()));
178 }
179 }
180
181 #[inline(never)]
182 fn from_bytes_opt_some(
183 buf: &[u8],
184 lims: &DecodeLimits,
185 depth: usize,
186 pos: usize,
187 )
188 -> Outcome<(Self, usize)>
189 {
190 //
191 // +---+---+---+---+---+---+---+---+---+
192 // | c | | | | | | | | |
193 // +---+---+---+---+---+---+---+---+---+
194 // \_______________________________/
195 // |
196 // inner Dat
197 //
198 // Dat::Opt(Some(k)) byte encoding does nothing more than prepend Dat k
199 // with Dat::OPT_SOME_CODE
200 //
201 if buf.len() > 1 {
202 let (inner, n) = res!(Self::from_bytes_depth(&buf[1..], lims, depth + 1, pos + 1));
203 return Ok((Dat::Opt(Box::new(Some(inner))), 1 + n));
204 } else {
205 return Err(<Dat as FromBytes>::too_few(
206 buf.len(), 1, &Self::code_name(buf[0]), file!(), line!()));
207 }
208 }
209
210 #[inline(never)]
211 fn from_bytes_abox(
212 buf: &[u8],
213 lims: &DecodeLimits,
214 depth: usize,
215 pos: usize,
216 )
217 -> Outcome<(Self, usize)>
218 {
219 //
220 // 0 1 2 ... n 1 2 ... v
221 // +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
222 // | c | | | | | | | | | | | | | | | ... | |
223 // +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
224 // | \_______________________________/\______________/\______________/
225 // | | | |
226 // NoteConfig inner Dat c64 payload bytes
227 //
228 if buf.len() > 1 {
229 let mut start: usize = 1;
230 let (ncfg, n) = res!(NoteConfig::from_bytes(&buf[start..]));
231 start += n;
232 let (boxd, n) = if buf.len() > start {
233 let (inner, n) = res!(Self::from_bytes_depth(&buf[start..], lims, depth + 1, pos + start));
234 (Box::new(inner), n)
235 } else {
236 return Err(<Dat as FromBytes>::too_few(
237 buf.len(), start, &Self::code_name(buf[0]), file!(), line!()));
238 };
239 start += n;
240 // The inner value may consume the rest of the buffer, leaving no byte for the trailing
241 // annotation length. Without this guard `buf[start]` panics on hostile input.
242 if start >= buf.len() {
243 return Err(<Dat as FromBytes>::too_few(
244 buf.len(), start, &Self::code_name(buf[0]), file!(), line!()));
245 }
246 match buf[start] {
247 Self::C64_CODE_START..=Self::C64_CODE_END => {
248 let (v, n) = res!(Self::read_c64(&buf[start..]));
249 if v == 0 {
250 return Ok((
251 Self::ABox(ncfg, boxd, String::new()),
252 start + n,
253 ));
254 }
255 let v = v as usize;
256 if buf.len() > start - 1 + n + v {
257 let owned = &buf[start + n .. start + n + v].to_vec();
258 return Ok((
259 Self::ABox(
260 ncfg,
261 boxd,
262 res!(std::str::from_utf8(owned)).to_string(),
263 ),
264 start + n + v,
265 ));
266 } else {
267 return Err(<Dat as FromBytes>::too_few(
268 buf.len(),
269 start + n + v,
270 &Self::code_name(buf[0]),
271 file!(),
272 line!(),
273 ));
274 }
275 }
276 _ => return Err(err!(
277 "{} code was not followed by a code for a Dat::C64 in the correct \
278 range {}..{}, the code found was {}.",
279 Self::code_name(buf[0]), Self::C64_CODE_START, Self::C64_CODE_END,
280 buf[start];
281 Bytes, Input, Decode, Missing)),
282 }
283 } else {
284 return Err(<Dat as FromBytes>::too_few(
285 buf.len(), 1, &Self::code_name(buf[0]), file!(), line!()));
286 }
287 }
288
289 #[inline(never)]
290 fn from_bytes_list(
291 buf: &[u8],
292 lims: &DecodeLimits,
293 depth: usize,
294 pos: usize,
295 )
296 -> Outcome<(Self, usize)>
297 {
298 //
299 // 0 1 ...
300 // +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
301 // | c | | | | c | | | c | | | c | | | | ... | |
302 // +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
303 // \__________/\__________/\__________/\______________/ ...
304 // | | | |
305 // payload_len item item item
306 //
307 if buf.len() > 1 {
308 match buf[1] {
309 Self::C64_CODE_START..=Self::C64_CODE_END => {
310 let (payload_len, n) = res!(Self::read_c64(&buf[1..]));
311 if payload_len == 0 {
312 return Ok((Self::List(Vec::new()), 1 + n));
313 }
314 let payload_len = payload_len as usize;
315 // `payload_len` is attacker-controlled and can be near `usize::MAX`, so the bound
316 // is expressed by subtraction from the buffer length rather than by adding to
317 // `payload_len`, which would overflow both the guard and `byt_len`.
318 if payload_len <= buf.len().saturating_sub(1 + n) {
319 let byt_len = 1 + n + payload_len;
320 let mut list = Vec::new();
321 let mut i = 1 + n;
322 while i < byt_len {
323 let (dat, n) = res!(Dat::from_bytes_depth(&buf[i..], lims, depth + 1, pos + i));
324 i += n;
325 list.push(dat);
326 }
327 let result = if buf[0] == Self::LIST_CODE {
328 Self::List(list)
329 } else {
330 res!(Self::try_vek_from(list))
331 };
332 return Ok((
333 result,
334 byt_len,
335 ));
336 } else {
337 return Err(<Dat as FromBytes>::too_few(
338 buf.len(), (1 + n).saturating_add(payload_len),
339 &Self::code_name(buf[0]), file!(), line!()));
340 }
341 }
342 _ => {
343 return Err(err!(
344 "Dat::List code was not followed by a code for a \
345 Dat::C64 in the correct range {}..{}, the code found \
346 was {}",
347 Self::C64_CODE_START,
348 Self::C64_CODE_END,
349 buf[1];
350 Bytes, Input, Decode, Missing));
351 }
352 }
353 } else {
354 return Err(<Dat as FromBytes>::too_few(
355 buf.len(), 1, &Self::code_name(buf[0]), file!(), line!()));
356 }
357 }
358
359 #[inline(never)]
360 fn from_bytes_map(
361 buf: &[u8],
362 lims: &DecodeLimits,
363 depth: usize,
364 pos: usize,
365 )
366 -> Outcome<(Self, usize)>
367 {
368 //
369 // 0 1 ...
370 // +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
371 // | c | | | | c | | | c | | | c | | | | ... | |
372 // +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
373 // \__________/\__________/\__________/\______________/ ...
374 // | | | |
375 // payload_len key value key
376 //
377 if buf.len() > 1 {
378 match buf[1] {
379 Self::C64_CODE_START..=Self::C64_CODE_END => {
380 let (payload_len, n) = res!(Self::read_c64(&buf[1..]));
381 if payload_len == 0 {
382 return Ok((Self::Map(DaticleMap::new()), 1 + n));
383 }
384 let payload_len = payload_len as usize;
385 // `payload_len` is attacker-controlled and can be near `usize::MAX`, so the bound
386 // is expressed by subtraction from the buffer length rather than by adding to
387 // `payload_len`, which would overflow both the guard and `byt_len`.
388 if payload_len <= buf.len().saturating_sub(1 + n) {
389 let byt_len = 1 + n + payload_len;
390 let mut map = DaticleMap::new();
391 let mut i = 1 + n;
392 let mut count: usize = 0;
393 while i < byt_len {
394 let (key, n) = res!(Dat::from_bytes_depth(&buf[i..], lims, depth + 1, pos + i));
395 i += n;
396 if i >= byt_len {
397 return Err(err!(
398 "Not enough bytes to decode the required value \
399 for key {:?} in the {:?}, after successfully \
400 decoding {} key-value pairs.",
401 key, Self::code_name(buf[0]), count;
402 Bytes, Input, Decode, Missing));
403 }
404 let (val, n) = res!(Dat::from_bytes_depth(&buf[i..], lims, depth + 1, pos + i));
405 i += n;
406 map.insert(key, val);
407 count += 1;
408 }
409 return Ok((
410 Self::Map(map),
411 byt_len,
412 ));
413 } else {
414 return Err(err!(
415 "Not enough bytes to decode the {:?} bytes. \
416 The map length is {} bytes, but the remaining buffer \
417 length is {} bytes.",
418 Self::code_name(buf[0]), payload_len, buf.len() - 1 - n;
419 Bytes, Input, Decode, Missing));
420 }
421 }
422 _ => {
423 return Err(err!(
424 "{:?} code was not followed by a code for a \
425 Dat::C64 in the correct range {}..{}, the code found \
426 was {}",
427 Self::code_name(buf[0]), Self::C64_CODE_START, Self::C64_CODE_END, buf[1];
428 Bytes, Input, Decode, Missing));
429 }
430 }
431 } else {
432 return Err(<Dat as FromBytes>::too_few(
433 buf.len(), 1, &Self::code_name(buf[0]), file!(), line!()));
434 }
435 }
436
437 #[inline(never)]
438 fn from_bytes_ordmap(
439 buf: &[u8],
440 lims: &DecodeLimits,
441 depth: usize,
442 pos: usize,
443 )
444 -> Outcome<(Self, usize)>
445 {
446 //
447 // 0 1 ...
448 // +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
449 // | c | | | | c | | | c | | | c | | | | ... | |
450 // +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
451 // \__________/\__________/\__________/\______________/ ...
452 // | | | |
453 // payload_len key value key
454 //
455 if buf.len() > 1 {
456 match buf[1] {
457 Self::C64_CODE_START..=Self::C64_CODE_END => {
458 let (payload_len, n) = res!(Self::read_c64(&buf[1..]));
459 if payload_len == 0 {
460 return Ok((Self::OrdMap(OrdDaticleMap::new()), 1 + n));
461 }
462 let payload_len = payload_len as usize;
463 let byt_len = 1 + n + payload_len;
464 if buf.len() > n + payload_len {
465 let mut map = OrdDaticleMap::new();
466 let mut i = 1 + n;
467 let mut count: u64 = 0;
468 let mut order: u64 = Dat::OMAP_ORDER_START_DEFAULT;
469 while i < byt_len {
470 let (key, n) = res!(Dat::from_bytes_depth(&buf[i..], lims, depth + 1, pos + i));
471 i += n;
472 if i >= byt_len {
473 return Err(err!(
474 "Not enough bytes to decode the required value \
475 for key {:?} in the {:?}, after successfully \
476 decoding {} key-value pairs.",
477 key, Self::code_name(buf[0]), count;
478 Bytes, Input, Decode, Missing));
479 }
480 let (val, n) = res!(Dat::from_bytes_depth(&buf[i..], lims, depth + 1, pos + i));
481 i += n;
482 map.insert(MapKey::new(order, key), val);
483 order = try_add!(order, Dat::OMAP_ORDER_DELTA_DEFAULT);
484 count = try_add!(count, 1);
485 }
486 return Ok((
487 Self::OrdMap(map),
488 byt_len,
489 ));
490 } else {
491 return Err(err!(
492 "Not enough bytes to decode the {:?} bytes. \
493 The map length is {} bytes, but the remaining buffer \
494 length is {} bytes.",
495 Self::code_name(buf[0]), payload_len, buf.len() - 1 - n;
496 Bytes, Input, Decode, Missing));
497 }
498 }
499 _ => {
500 return Err(err!(
501 "{:?} code was not followed by a code for a \
502 Dat::C64 in the correct range {}..{}, the code found \
503 was {}",
504 Self::code_name(buf[0]), Self::C64_CODE_START, Self::C64_CODE_END, buf[1];
505 Bytes, Input, Decode, Missing));
506 }
507 }
508 } else {
509 return Err(<Dat as FromBytes>::too_few(
510 buf.len(), 1, &Self::code_name(buf[0]), file!(), line!()));
511 }
512 }
513
514 #[inline(never)]
515 fn from_bytes_tuple(
516 buf: &[u8],
517 lims: &DecodeLimits,
518 depth: usize,
519 pos: usize,
520 )
521 -> Outcome<(Self, usize)>
522 {
523 match buf[0] {
524 Self::TUP2_CODE => {
525 //
526 // 0 1 ...
527 // +---+---+---+---+---+---+---+
528 // | c | c | | | c | | |
529 // +---+---+---+---+---+---+---+
530 // \__________/\__________/
531 // | |
532 // item item
533 //
534 if buf.len() > 1 {
535 const N: usize = 2;
536 let mut list = [
537 Dat::default(),
538 Dat::default(),
539 ];
540 let mut i: usize = 1;
541 for j in 0..N {
542 let (dat, k) = res!(Dat::from_bytes_depth(&buf[i..], lims, depth + 1, pos + i));
543 list[j] = dat;
544 i += k;
545 }
546 return Ok((Self::Tup2(Box::new(list)), i));
547 } else {
548 return Err(<Dat as FromBytes>::too_few(
549 buf.len(), 1, &Self::code_name(buf[0]), file!(), line!()));
550 }
551 }
552 Self::TUP3_CODE => {
553 //
554 // 0 1 ...
555 // +---+---+---+---+---+---+---+---+---+---+---+
556 // | c | c | | | c | | | c | | | |
557 // +---+---+---+---+---+---+---+---+---+---+---+
558 // \__________/\__________/\______________/
559 // | | |
560 // item item item
561 //
562 if buf.len() > 1 {
563 const N: usize = 3;
564 let mut list = [
565 Dat::default(),
566 Dat::default(),
567 Dat::default(),
568 ];
569 let mut i: usize = 1;
570 for j in 0..N {
571 let (dat, k) = res!(Dat::from_bytes_depth(&buf[i..], lims, depth + 1, pos + i));
572 list[j] = dat;
573 i += k;
574 }
575 return Ok((Self::Tup3(Box::new(list)), i));
576 } else {
577 return Err(<Dat as FromBytes>::too_few(
578 buf.len(), 1, &Self::code_name(buf[0]), file!(), line!()));
579 }
580 }
581 Self::TUP4_CODE => {
582 if buf.len() > 1 {
583 const N: usize = 4;
584 let mut list = [
585 Dat::default(),
586 Dat::default(),
587 Dat::default(),
588 Dat::default(),
589 ];
590 let mut i: usize = 1;
591 for j in 0..N {
592 let (dat, k) = res!(Dat::from_bytes_depth(&buf[i..], lims, depth + 1, pos + i));
593 list[j] = dat;
594 i += k;
595 }
596 return Ok((Self::Tup4(Box::new(list)), i));
597 } else {
598 return Err(<Dat as FromBytes>::too_few(
599 buf.len(), 1, &Self::code_name(buf[0]), file!(), line!()));
600 }
601 }
602 Self::TUP5_CODE => {
603 if buf.len() > 1 {
604 const N: usize = 5;
605 let mut list = [
606 Dat::default(),
607 Dat::default(),
608 Dat::default(),
609 Dat::default(),
610 Dat::default(),
611 ];
612 let mut i: usize = 1;
613 for j in 0..N {
614 let (dat, k) = res!(Dat::from_bytes_depth(&buf[i..], lims, depth + 1, pos + i));
615 list[j] = dat;
616 i += k;
617 }
618 return Ok((Self::Tup5(Box::new(list)), i));
619 } else {
620 return Err(<Dat as FromBytes>::too_few(
621 buf.len(), 1, &Self::code_name(buf[0]), file!(), line!()));
622 }
623 }
624 Self::TUP6_CODE => {
625 if buf.len() > 1 {
626 const N: usize = 6;
627 let mut list = [
628 Dat::default(),
629 Dat::default(),
630 Dat::default(),
631 Dat::default(),
632 Dat::default(),
633 Dat::default(),
634 ];
635 let mut i: usize = 1;
636 for j in 0..N {
637 let (dat, k) = res!(Dat::from_bytes_depth(&buf[i..], lims, depth + 1, pos + i));
638 list[j] = dat;
639 i += k;
640 }
641 return Ok((Self::Tup6(Box::new(list)), i));
642 } else {
643 return Err(<Dat as FromBytes>::too_few(
644 buf.len(), 1, &Self::code_name(buf[0]), file!(), line!()));
645 }
646 }
647 Self::TUP7_CODE => {
648 if buf.len() > 1 {
649 const N: usize = 7;
650 let mut list = [
651 Dat::default(),
652 Dat::default(),
653 Dat::default(),
654 Dat::default(),
655 Dat::default(),
656 Dat::default(),
657 Dat::default(),
658 ];
659 let mut i: usize = 1;
660 for j in 0..N {
661 let (dat, k) = res!(Dat::from_bytes_depth(&buf[i..], lims, depth + 1, pos + i));
662 list[j] = dat;
663 i += k;
664 }
665 return Ok((Self::Tup7(Box::new(list)), i));
666 } else {
667 return Err(<Dat as FromBytes>::too_few(
668 buf.len(), 1, &Self::code_name(buf[0]), file!(), line!()));
669 }
670 }
671 Self::TUP8_CODE => {
672 if buf.len() > 1 {
673 const N: usize = 8;
674 let mut list = [
675 Dat::default(),
676 Dat::default(),
677 Dat::default(),
678 Dat::default(),
679 Dat::default(),
680 Dat::default(),
681 Dat::default(),
682 Dat::default(),
683 ];
684 let mut i: usize = 1;
685 for j in 0..N {
686 let (dat, k) = res!(Dat::from_bytes_depth(&buf[i..], lims, depth + 1, pos + i));
687 list[j] = dat;
688 i += k;
689 }
690 return Ok((Self::Tup8(Box::new(list)), i));
691 } else {
692 return Err(<Dat as FromBytes>::too_few(
693 buf.len(), 1, &Self::code_name(buf[0]), file!(), line!()));
694 }
695 }
696 Self::TUP9_CODE => {
697 if buf.len() > 1 {
698 const N: usize = 9;
699 let mut list = [
700 Dat::default(),
701 Dat::default(),
702 Dat::default(),
703 Dat::default(),
704 Dat::default(),
705 Dat::default(),
706 Dat::default(),
707 Dat::default(),
708 Dat::default(),
709 ];
710 let mut i: usize = 1;
711 for j in 0..N {
712 let (dat, k) = res!(Dat::from_bytes_depth(&buf[i..], lims, depth + 1, pos + i));
713 list[j] = dat;
714 i += k;
715 }
716 return Ok((Self::Tup9(Box::new(list)), i));
717 } else {
718 return Err(<Dat as FromBytes>::too_few(
719 buf.len(), 1, &Self::code_name(buf[0]), file!(), line!()));
720 }
721 }
722 Self::TUP10_CODE => {
723 if buf.len() > 1 {
724 const N: usize = 10;
725 let mut list = [
726 Dat::default(),
727 Dat::default(),
728 Dat::default(),
729 Dat::default(),
730 Dat::default(),
731 Dat::default(),
732 Dat::default(),
733 Dat::default(),
734 Dat::default(),
735 Dat::default(),
736 ];
737 let mut i: usize = 1;
738 for j in 0..N {
739 let (dat, k) = res!(Dat::from_bytes_depth(&buf[i..], lims, depth + 1, pos + i));
740 list[j] = dat;
741 i += k;
742 }
743 return Ok((Self::Tup10(Box::new(list)), i));
744 } else {
745 return Err(<Dat as FromBytes>::too_few(
746 buf.len(), 1, &Self::code_name(buf[0]), file!(), line!()));
747 }
748 }
749 code => return Err(err!(
750 "Byte code 0x{:02x} is not that of a heterogenous tuple.", code;
751 Bug, Input, Invalid)),
752 }
753 }
754
755 #[inline(never)]
756 fn from_bytes_atomic(buf: &[u8]) -> Outcome<(Self, usize)> {
757 match buf[0] {
758 // Atomic Kinds ===========================
759 // Logic
760 Self::EMPTY_CODE => return Ok((Self::Empty, 1)),
761 Self::TRUE_CODE => return Ok((Self::Bool(true), 1)),
762 Self::FALSE_CODE => return Ok((Self::Bool(false), 1)),
763 Self::OPT_NONE_CODE => return Ok((Self::Opt(Box::new(None)), 1)),
764 // Fixed
765 Self::U8_CODE => {
766 // +---+---+
767 // | c | |
768 // +---+---+
769 // \___/
770 // |
771 // u8
772 //
773 if buf.len() > 1 {
774 return Ok((
775 Self::U8(u8::from_be_bytes(
776 res!(<[u8; 1]>::try_from(&buf[1..2]), Decode, Bytes)
777 )),
778 2,
779 ));
780 } else {
781 return Err(<Dat as FromBytes>::too_few(
782 buf.len(), 2, &Self::code_name(buf[0]), file!(), line!()));
783 }
784 }
785 Self::U16_CODE => {
786 // MSB LSB
787 // +---+---+---+
788 // | c | | |
789 // +---+---+---+
790 // \_______/
791 // |
792 // u16
793 //
794 if buf.len() > 2 {
795 return Ok((
796 Self::U16(u16::from_be_bytes(
797 res!(<[u8; 2]>::try_from(&buf[1..3]), Decode, Bytes)
798 )),
799 3,
800 ));
801 } else {
802 return Err(<Dat as FromBytes>::too_few(
803 buf.len(), 3, &Self::code_name(buf[0]), file!(), line!()));
804 }
805 }
806 Self::U32_CODE => {
807 // MSB LSB
808 // +---+---+---+---+---+
809 // | c | | | | |
810 // +---+---+---+---+---+
811 // \_______________/
812 // |
813 // u32
814 //
815 if buf.len() > 4 {
816 return Ok((
817 Self::U32(u32::from_be_bytes(
818 res!(<[u8; 4]>::try_from(&buf[1..5]), Decode, Bytes)
819 )),
820 5,
821 ));
822 } else {
823 return Err(<Dat as FromBytes>::too_few(
824 buf.len(), 5, &Self::code_name(buf[0]), file!(), line!()));
825 }
826 }
827 Self::U64_CODE => {
828 // MSB LSB
829 // +---+---+---+---+---+---+---+---+---+
830 // | c | | | | | | | | |
831 // +---+---+---+---+---+---+---+---+---+
832 // \_______________________________/
833 // |
834 // u64
835 //
836 if buf.len() > 8 {
837 return Ok((
838 Self::U64(u64::from_be_bytes(
839 res!(<[u8; 8]>::try_from(&buf[1..9]), Decode, Bytes)
840 )),
841 9,
842 ));
843 } else {
844 return Err(<Dat as FromBytes>::too_few(
845 buf.len(), 9, &Self::code_name(buf[0]), file!(), line!()));
846 }
847 }
848 Self::U128_CODE => {
849 // MSB LSB
850 // +---+---+---+---+---+---+---+---+---+
851 // | c | | | | | | | | |
852 // +---+---+---+---+---+---+---+---+---+
853 // \_______________________________/
854 // |
855 // u128
856 //
857 if buf.len() > 16 {
858 return Ok((
859 Self::U128(u128::from_be_bytes(
860 res!(<[u8; 16]>::try_from(&buf[1..17]), Decode, Bytes)
861 )),
862 17,
863 ));
864 } else {
865 return Err(<Dat as FromBytes>::too_few(
866 buf.len(), 17, &Self::code_name(buf[0]), file!(), line!()));
867 }
868 }
869 Self::I8_CODE => {
870 // +---+---+
871 // | c | |
872 // +---+---+
873 // \___/
874 // |
875 // i8
876 //
877 if buf.len() > 1 {
878 return Ok((
879 Self::I8(i8::from_be_bytes(
880 res!(<[u8; 1]>::try_from(&buf[1..2]), Decode, Bytes)
881 )),
882 2,
883 ));
884 } else {
885 return Err(<Dat as FromBytes>::too_few(
886 buf.len(), 2, &Self::code_name(buf[0]), file!(), line!()));
887 }
888 }
889 Self::I16_CODE => {
890 // MSB LSB
891 // +---+---+---+
892 // | c | | |
893 // +---+---+---+
894 // \_______/
895 // |
896 // i16
897 //
898 if buf.len() > 2 {
899 return Ok((
900 Self::I16(i16::from_be_bytes(
901 res!(<[u8; 2]>::try_from(&buf[1..3]), Decode, Bytes)
902 )),
903 3,
904 ));
905 } else {
906 return Err(<Dat as FromBytes>::too_few(
907 buf.len(), 3, &Self::code_name(buf[0]), file!(), line!()));
908 }
909 }
910 Self::I32_CODE => {
911 // MSB LSB
912 // +---+---+---+---+---+
913 // | c | | | | |
914 // +---+---+---+---+---+
915 // \_______________/
916 // |
917 // i32
918 //
919 if buf.len() > 4 {
920 return Ok((
921 Self::I32(i32::from_be_bytes(
922 res!(<[u8; 4]>::try_from(&buf[1..5]), Decode, Bytes)
923 )),
924 5,
925 ));
926 } else {
927 return Err(<Dat as FromBytes>::too_few(
928 buf.len(), 5, &Self::code_name(buf[0]), file!(), line!()));
929 }
930 }
931 Self::I64_CODE => {
932 // MSB LSB
933 // +---+---+---+---+---+---+---+---+---+
934 // | c | | | | | | | | |
935 // +---+---+---+---+---+---+---+---+---+
936 // \_______________________________/
937 // |
938 // i64
939 //
940 if buf.len() > 8 {
941 return Ok((
942 Self::I64(i64::from_be_bytes(
943 res!(<[u8; 8]>::try_from(&buf[1..9]), Decode, Bytes)
944 )),
945 9,
946 ));
947 } else {
948 return Err(<Dat as FromBytes>::too_few(
949 buf.len(), 9, &Self::code_name(buf[0]), file!(), line!()));
950 }
951 }
952 Self::I128_CODE => {
953 // MSB LSB
954 // +---+---+---+---+---+---+---+---+---+
955 // | c | | | | | | | | |
956 // +---+---+---+---+---+---+---+---+---+
957 // \_______________________________/
958 // |
959 // i128
960 //
961 if buf.len() > 16 {
962 return Ok((
963 Self::I128(i128::from_be_bytes(
964 res!(<[u8; 16]>::try_from(&buf[1..17]), Decode, Bytes)
965 )),
966 17,
967 ));
968 } else {
969 return Err(<Dat as FromBytes>::too_few(
970 buf.len(), 17, &Self::code_name(buf[0]), file!(), line!()));
971 }
972 }
973 Self::F32_CODE => {
974 // MSB LSB
975 // +---+---+---+---+---+
976 // | c | | | | |
977 // +---+---+---+---+---+
978 // \_______________/
979 // |
980 // f32
981 //
982 if buf.len() > 4 {
983 return Ok((
984 Self::F32(Float32(f32::from_be_bytes(
985 res!(<[u8; 4]>::try_from(&buf[1..5]), Decode, Bytes)
986 ))),
987 5,
988 ));
989 } else {
990 return Err(<Dat as FromBytes>::too_few(
991 buf.len(), 5, &Self::code_name(buf[0]), file!(), line!()));
992 }
993 }
994 Self::F64_CODE => {
995 // MSB LSB
996 // +---+---+---+---+---+---+---+---+---+
997 // | c | | | | | | | | |
998 // +---+---+---+---+---+---+---+---+---+
999 // \_______________________________/
1000 // |
1001 // f64
1002 //
1003 if buf.len() > 8 {
1004 return Ok((
1005 Self::F64(Float64(f64::from_be_bytes(
1006 res!(<[u8; 8]>::try_from(&buf[1..9]), Decode, Bytes)
1007 ))),
1008 9,
1009 ));
1010 } else {
1011 return Err(<Dat as FromBytes>::too_few(
1012 buf.len(), 9, &Self::code_name(buf[0]), file!(), line!()));
1013 }
1014 }
1015 // Variable
1016 Self::C64_CODE_START..=Self::C64_CODE_END => { // C64
1017 //
1018 // MSB big endian LSB
1019 // +---+---+---+---+---+---+---+---+
1020 // | 0 | 0 | 0 | 0 | 0 | 0 | 0 |128|
1021 // +---+---+---+---+---+---+---+---+
1022 // \_______________________________/
1023 // |
1024 // u64
1025 //
1026 // Potential encoding for: Dat::C64
1027 // +---+---+---+
1028 // | c | n |128| n = 1
1029 // +---+---+---+
1030 // \___________/
1031 // |
1032 // c64
1033 //
1034 // Actual encoding for: Dat::C64
1035 // +---+---+
1036 // | c |128| c -> c + 1 (n = 1 incorporated into prefix code)
1037 // +---+---+
1038 // \_______/
1039 // |
1040 // c64
1041 //
1042 let (n64, n) = res!(Self::read_c64(buf));
1043 return Ok((Dat::C64(n64), n));
1044 }
1045 Self::BC64_CODE => {
1046 //
1047 // 0 1 2 ... n 1 2 ... v
1048 // +---+---+---+---+---+---+---+---+---+
1049 // | c | | | | | | ... | |
1050 // +---+---+---+---+---+---+---+---+---+
1051 // \______________/\______________/
1052 // | |
1053 // c64 payload bytes
1054 //
1055 if buf.len() > 1 {
1056 match buf[1] {
1057 Self::C64_CODE_START..=Self::C64_CODE_END => {
1058 let (v, n) = res!(Self::read_c64(&buf[1..]));
1059 if v == 0 {
1060 return Ok((
1061 Self::BC64(Vec::new()),
1062 1 + n,
1063 ));
1064 }
1065 let v = v as usize;
1066 if buf.len() > 1 - 1 + n + v {
1067 return Ok((
1068 Self::BC64(buf[1 + n .. 1 + n + v].to_vec()),
1069 1 + n + v,
1070 ));
1071 } else {
1072 return Err(<Dat as FromBytes>::too_few(
1073 buf.len(),
1074 1 + n + v,
1075 &Self::code_name(buf[0]),
1076 file!(),
1077 line!(),
1078 ));
1079 }
1080 }
1081 _ => return Err(err!(
1082 "{} code was not followed by a code for a Dat::C64 in the correct \
1083 range {}..{}, the code found was {}.",
1084 Self::code_name(buf[0]), Self::C64_CODE_START, Self::C64_CODE_END,
1085 buf[1];
1086 Bytes, Input, Decode, Missing)),
1087 }
1088 } else {
1089 return Err(<Dat as FromBytes>::too_few(
1090 buf.len(), 1, &Self::code_name(buf[0]), file!(), line!()));
1091 }
1092 }
1093 Self::STR_CODE => {
1094 //
1095 // 0 1 2 ... n 1 2 ... v
1096 // +---+---+---+---+---+---+---+---+---+
1097 // | c | | | | | | ... | |
1098 // +---+---+---+---+---+---+---+---+---+
1099 // \______________/\______________/
1100 // | |
1101 // c64 payload bytes
1102 //
1103 if buf.len() > 1 {
1104 match buf[1] {
1105 Self::C64_CODE_START..=Self::C64_CODE_END => {
1106 let (v, n) = res!(Self::read_c64(&buf[1..]));
1107 if v == 0 {
1108 return Ok((
1109 Self::Str(String::new()),
1110 1 + n,
1111 ));
1112 }
1113 let v = v as usize;
1114 if buf.len() > 1 - 1 + n + v {
1115 let owned = &buf[1 + n .. 1 + n + v].to_vec();
1116 return Ok((
1117 Self::Str(res!(std::str::from_utf8(
1118 owned
1119 )).to_string()),
1120 1 + n + v,
1121 ));
1122 } else {
1123 return Err(<Dat as FromBytes>::too_few(
1124 buf.len(),
1125 1 + n + v,
1126 &Self::code_name(buf[0]),
1127 file!(),
1128 line!(),
1129 ));
1130 }
1131 }
1132 _ => return Err(err!(
1133 "{} code was not followed by a code for a Dat::C64 in the correct \
1134 range {}..{}, the code found was {}.",
1135 Self::code_name(buf[0]), Self::C64_CODE_START, Self::C64_CODE_END,
1136 buf[1];
1137 Bytes, Input, Decode, Missing)),
1138 }
1139 } else {
1140 return Err(<Dat as FromBytes>::too_few(
1141 buf.len(), 1, &Self::code_name(buf[0]), file!(), line!()));
1142 }
1143 }
1144 Self::AINT_CODE => {
1145 //
1146 // 0 1 2 ... n 1 2 ... v
1147 // +---+---+---+---+---+---+---+---+---+
1148 // | c | | | | | | ... | |
1149 // +---+---+---+---+---+---+---+---+---+
1150 // \______________/\______________/
1151 // | |
1152 // c64 payload bytes
1153 //
1154 if buf.len() > 1 {
1155 match buf[1] {
1156 Self::C64_CODE_START..=Self::C64_CODE_END => {
1157 let (v, n) = res!(Self::read_c64(&buf[1..]));
1158 if v == 0 {
1159 return Ok((
1160 Self::Aint(BigInt::zero()),
1161 1 + n,
1162 ));
1163 }
1164 let v = v as usize;
1165 if buf.len() > 1 - 1 + n + v {
1166 return Ok((
1167 Self::Aint(BigInt::from_signed_bytes_be(
1168 &buf[1 + n .. 1 + n + v]
1169 )),
1170 1 + n + v,
1171 ));
1172 } else {
1173 return Err(<Dat as FromBytes>::too_few(
1174 buf.len(),
1175 1 + n + v,
1176 &Self::code_name(buf[0]),
1177 file!(),
1178 line!(),
1179 ));
1180 }
1181 }
1182 _ => return Err(err!(
1183 "{} code was not followed by a code for a Dat::C64 in the correct \
1184 range {}..{}, the code found was {}.",
1185 Self::code_name(buf[0]), Self::C64_CODE_START, Self::C64_CODE_END,
1186 buf[1];
1187 Bytes, Input, Decode, Missing)),
1188 }
1189 } else {
1190 return Err(<Dat as FromBytes>::too_few(
1191 buf.len(), 1, &Self::code_name(buf[0]), file!(), line!()));
1192 }
1193 }
1194 Self::ADEC_CODE => {
1195 //
1196 // 0 1 2 ... n 1 2 ... v
1197 // +---+---+---+---+---+---+---+---+---+
1198 // | c | | | | | | ... | |
1199 // +---+---+---+---+---+---+---+---+---+
1200 // \______________/\______________/
1201 // | |
1202 // c64 payload bytes
1203 //
1204 if buf.len() > 1 {
1205 match buf[1] {
1206 Self::C64_CODE_START..=Self::C64_CODE_END => {
1207 let (v, n) = res!(Self::read_c64(&buf[1..]));
1208 if v == 0 {
1209 return Ok((
1210 Self::Adec(BigDecimal::zero()),
1211 1 + n,
1212 ));
1213 }
1214 let v = v as usize;
1215 if buf.len() > 1 - 1 + n + v {
1216 let bigint = BigInt::from_signed_bytes_be(
1217 &buf[1 + n .. 1 + n + v - 8]
1218 );
1219 let expi64 = i64::from_be_bytes(
1220 res!(<[u8; 8]>::try_from(&buf[1 + n + v - 8 ..]),
1221 Decode, Bytes)
1222 );
1223 return Ok((
1224 Self::Adec(BigDecimal::new(bigint, expi64)),
1225 1 + n + v,
1226 ));
1227 } else {
1228 return Err(<Dat as FromBytes>::too_few(
1229 buf.len(),
1230 1 + n + v,
1231 &Self::code_name(buf[0]),
1232 file!(),
1233 line!(),
1234 ));
1235 }
1236 }
1237 _ => return Err(err!(
1238 "{} code was not followed by a code for a Dat::C64 in the correct \
1239 range {}..{}, the code found was {}.",
1240 Self::code_name(buf[0]), Self::C64_CODE_START, Self::C64_CODE_END,
1241 buf[1];
1242 Bytes, Input, Decode, Missing)),
1243 }
1244 } else {
1245 return Err(<Dat as FromBytes>::too_few(
1246 buf.len(), 1, &Self::code_name(buf[0]), file!(), line!()));
1247 }
1248 }
1249 // Homogenous
1250 // Byte arrays
1251 // Variable length bytes
1252 Self::BU8_CODE => {
1253 //
1254 // 0 1 1 2 ... v
1255 // +---+---+---+---+---+---+ Fixed size, raw u8 for payload length
1256 // | c | | | ... | |
1257 // +---+---+---+---+---+---+
1258 // \__/\______________/
1259 // | |
1260 // raw u8 payload bytes
1261 //
1262 if buf.len() > 1 {
1263 let v = u8::from_be_bytes(
1264 res!(<[u8; 1]>::try_from(&buf[1..2]), Decode, Bytes)
1265 ) as usize;
1266 if buf.len() > 1 + v {
1267 return Ok((
1268 Self::BU8(buf[1 + 1 .. 1 + 1 + v].to_vec()),
1269 1 + 1 + v,
1270 ));
1271 } else {
1272 return Err(<Dat as FromBytes>::too_few(
1273 buf.len(), 1 + 1 + v, &Self::code_name(buf[0]), file!(), line!()));
1274 }
1275 } else {
1276 return Err(<Dat as FromBytes>::too_few(
1277 buf.len(), 1, &Self::code_name(buf[0]), file!(), line!()));
1278 }
1279 }
1280 Self::BU16_CODE => {
1281 //
1282 // 0 1 2 1 2 ... v
1283 // +---+---+---+---+---+---+---+ Fixed size, raw u16 for payload length
1284 // | c | | | | ... | |
1285 // +---+---+---+---+---+---+---+
1286 // \______/\______________/
1287 // | |
1288 // raw u16 payload bytes
1289 //
1290 if buf.len() > 2 {
1291 let v = u16::from_be_bytes(
1292 res!(<[u8; 2]>::try_from(&buf[1..3]), Decode, Bytes)
1293 ) as usize;
1294 if buf.len() > 2 + v {
1295 return Ok((
1296 Self::BU16(buf[1 + 2 .. 1 + 2 + v].to_vec()),
1297 1 + 2 + v,
1298 ));
1299 } else {
1300 return Err(<Dat as FromBytes>::too_few(
1301 buf.len(), 1 + 2 + v, &Self::code_name(buf[0]), file!(), line!()));
1302 }
1303 } else {
1304 return Err(<Dat as FromBytes>::too_few(
1305 buf.len(), 1, &Self::code_name(buf[0]), file!(), line!()));
1306 }
1307 }
1308 Self::BU32_CODE => {
1309 //
1310 // 0 1 2 ... 4 1 2 ... v
1311 // +---+---+---+---+---+---+---+---+---+ Fixed size, raw u32 for payload length
1312 // | c | | | | | | ... | |
1313 // +---+---+---+---+---+---+---+---+---+
1314 // \______________/\______________/
1315 // | |
1316 // raw u32 payload bytes
1317 //
1318 if buf.len() > 4 {
1319 let v = u32::from_be_bytes(
1320 res!(<[u8; 4]>::try_from(&buf[1..5]), Decode, Bytes)
1321 ) as usize;
1322 if buf.len() > 4 + v {
1323 return Ok((
1324 Self::BU32(buf[1 + 4 .. 1 + 4 + v].to_vec()),
1325 1 + 4 + v,
1326 ));
1327 } else {
1328 return Err(<Dat as FromBytes>::too_few(
1329 buf.len(), 1 + 4 + v, &Self::code_name(buf[0]), file!(), line!()));
1330 }
1331 } else {
1332 return Err(<Dat as FromBytes>::too_few(
1333 buf.len(), 1, &Self::code_name(buf[0]), file!(), line!()));
1334 }
1335 }
1336 Self::BU64_CODE => {
1337 //
1338 // 0 1 2 ... 8 1 2 ... v
1339 // +---+---+---+---+---+---+---+---+---+ Fixed size, raw u64 for payload length
1340 // | c | | | | | | ... | |
1341 // +---+---+---+---+---+---+---+---+---+
1342 // \______________/\______________/
1343 // | |
1344 // raw u64 payload bytes
1345 //
1346 if buf.len() > 8 {
1347 let v = u64::from_be_bytes(
1348 res!(<[u8; 8]>::try_from(&buf[1..9]), Decode, Bytes)
1349 ) as usize;
1350 if buf.len() > 8 + v {
1351 return Ok((
1352 Self::BU64(buf[1 + 8 .. 1 + 8 + v].to_vec()),
1353 1 + 8 + v,
1354 ));
1355 } else {
1356 return Err(<Dat as FromBytes>::too_few(
1357 buf.len(), 1 + 8 + v, &Self::code_name(buf[0]), file!(), line!()));
1358 }
1359 } else {
1360 return Err(<Dat as FromBytes>::too_few(
1361 buf.len(), 1, &Self::code_name(buf[0]), file!(), line!()));
1362 }
1363 }
1364 // Fixed length bytes
1365 Self::B2_CODE => binary_decode_byte_tuple! { B2, u8, 2, buf },
1366 // MSB LSB
1367 // +---+---+---+
1368 // | c | | |
1369 // +---+---+---+
1370 // \_______/
1371 // |
1372 // 2 bytes
1373 //
1374 Self::B3_CODE => binary_decode_byte_tuple! { B3, u8, 3, buf },
1375 Self::B4_CODE => binary_decode_byte_tuple! { B4, u8, 4, buf },
1376 Self::B5_CODE => binary_decode_byte_tuple! { B5, u8, 5, buf },
1377 Self::B6_CODE => binary_decode_byte_tuple! { B6, u8, 6, buf },
1378 Self::B7_CODE => binary_decode_byte_tuple! { B7, u8, 7, buf },
1379 Self::B8_CODE => binary_decode_byte_tuple! { B8, u8, 8, buf },
1380 Self::B9_CODE => binary_decode_byte_tuple! { B9, u8, 9, buf },
1381 Self::B10_CODE => binary_decode_byte_tuple! { B10, u8, 10, buf },
1382 Self::B16_CODE => binary_decode_byte_tuple! { B16, u8, 16, buf },
1383 Self::B32_CODE => binary_decode_byte_tuple! { B32, B32, u8, 32, buf },
1384 // MSB LSB
1385 // +---+---+---+---+---+---+---+---+---+
1386 // | c | | | | | | | | |
1387 // +---+---+---+---+---+---+---+---+---+
1388 // \_______________________________/
1389 // |
1390 // 32 bytes
1391 //
1392 // Fixed length numbers
1393 Self::TUP2_U8_CODE => binary_decode_byte_tuple! { Tup2u8, u8, 2, buf },
1394 Self::TUP3_U8_CODE => binary_decode_byte_tuple! { Tup3u8, u8, 3, buf },
1395 Self::TUP4_U8_CODE => binary_decode_byte_tuple! { Tup4u8, u8, 4, buf },
1396 Self::TUP5_U8_CODE => binary_decode_byte_tuple! { Tup5u8, u8, 5, buf },
1397 Self::TUP6_U8_CODE => binary_decode_byte_tuple! { Tup6u8, u8, 6, buf },
1398 Self::TUP7_U8_CODE => binary_decode_byte_tuple! { Tup7u8, u8, 7, buf },
1399 Self::TUP8_U8_CODE => binary_decode_byte_tuple! { Tup8u8, u8, 8, buf },
1400 Self::TUP9_U8_CODE => binary_decode_byte_tuple! { Tup9u8, u8, 9, buf },
1401 Self::TUP10_U8_CODE => binary_decode_byte_tuple! { Tup10u8, u8, 10, buf },
1402 Self::TUP2_U16_CODE => binary_decode_byte_tuple! { Tup2u16, u16, 2, buf },
1403 Self::TUP3_U16_CODE => binary_decode_byte_tuple! { Tup3u16, u16, 3, buf },
1404 Self::TUP4_U16_CODE => binary_decode_byte_tuple! { Tup4u16, u16, 4, buf },
1405 Self::TUP5_U16_CODE => binary_decode_byte_tuple! { Tup5u16, u16, 5, buf },
1406 Self::TUP6_U16_CODE => binary_decode_byte_tuple! { Tup6u16, u16, 6, buf },
1407 Self::TUP7_U16_CODE => binary_decode_byte_tuple! { Tup7u16, u16, 7, buf },
1408 Self::TUP8_U16_CODE => binary_decode_byte_tuple! { Tup8u16, u16, 8, buf },
1409 Self::TUP9_U16_CODE => binary_decode_byte_tuple! { Tup9u16, u16, 9, buf },
1410 Self::TUP10_U16_CODE => binary_decode_byte_tuple! { Tup10u16, u16, 10, buf },
1411
1412 Self::TUP2_U32_CODE => binary_decode_byte_tuple! { Tup2u32, u32, 2, buf },
1413 Self::TUP3_U32_CODE => binary_decode_byte_tuple! { Tup3u32, u32, 3, buf },
1414 Self::TUP4_U32_CODE => binary_decode_byte_tuple! { Tup4u32, u32, 4, buf },
1415 Self::TUP5_U32_CODE => binary_decode_byte_tuple! { Tup5u32, u32, 5, buf },
1416 Self::TUP6_U32_CODE => binary_decode_byte_tuple! { Tup6u32, u32, 6, buf },
1417 Self::TUP7_U32_CODE => binary_decode_byte_tuple! { Tup7u32, u32, 7, buf },
1418 Self::TUP8_U32_CODE => binary_decode_byte_tuple! { Tup8u32, u32, 8, buf },
1419 Self::TUP9_U32_CODE => binary_decode_byte_tuple! { Tup9u32, u32, 9, buf },
1420 Self::TUP10_U32_CODE => binary_decode_byte_tuple! { Tup10u32, u32, 10, buf },
1421
1422 Self::TUP2_U64_CODE => binary_decode_byte_tuple! { Tup2u64, u64, 2, buf },
1423 Self::TUP3_U64_CODE => binary_decode_byte_tuple! { Tup3u64, u64, 3, buf },
1424 Self::TUP4_U64_CODE => binary_decode_byte_tuple! { Tup4u64, u64, 4, buf },
1425 Self::TUP5_U64_CODE => binary_decode_byte_tuple! { Tup5u64, u64, 5, buf },
1426 Self::TUP6_U64_CODE => binary_decode_byte_tuple! { Tup6u64, u64, 6, buf },
1427 Self::TUP7_U64_CODE => binary_decode_byte_tuple! { Tup7u64, u64, 7, buf },
1428 Self::TUP8_U64_CODE => binary_decode_byte_tuple! { Tup8u64, u64, 8, buf },
1429 Self::TUP9_U64_CODE => binary_decode_byte_tuple! { Tup9u64, u64, 9, buf },
1430 Self::TUP10_U64_CODE => binary_decode_byte_tuple! { Tup10u64, u64, 10, buf },
1431 Self::TUP2_I8_CODE => binary_decode_byte_tuple! { Tup2i8, i8, 2, buf },
1432 Self::TUP3_I8_CODE => binary_decode_byte_tuple! { Tup3i8, i8, 3, buf },
1433 Self::TUP4_I8_CODE => binary_decode_byte_tuple! { Tup4i8, i8, 4, buf },
1434 Self::TUP5_I8_CODE => binary_decode_byte_tuple! { Tup5i8, i8, 5, buf },
1435 Self::TUP6_I8_CODE => binary_decode_byte_tuple! { Tup6i8, i8, 6, buf },
1436 Self::TUP7_I8_CODE => binary_decode_byte_tuple! { Tup7i8, i8, 7, buf },
1437 Self::TUP8_I8_CODE => binary_decode_byte_tuple! { Tup8i8, i8, 8, buf },
1438 Self::TUP9_I8_CODE => binary_decode_byte_tuple! { Tup9i8, i8, 9, buf },
1439 Self::TUP10_I8_CODE => binary_decode_byte_tuple! { Tup10i8, i8, 10, buf },
1440 Self::TUP2_I16_CODE => binary_decode_byte_tuple! { Tup2i16, i16, 2, buf },
1441 Self::TUP3_I16_CODE => binary_decode_byte_tuple! { Tup3i16, i16, 3, buf },
1442 Self::TUP4_I16_CODE => binary_decode_byte_tuple! { Tup4i16, i16, 4, buf },
1443 Self::TUP5_I16_CODE => binary_decode_byte_tuple! { Tup5i16, i16, 5, buf },
1444 Self::TUP6_I16_CODE => binary_decode_byte_tuple! { Tup6i16, i16, 6, buf },
1445 Self::TUP7_I16_CODE => binary_decode_byte_tuple! { Tup7i16, i16, 7, buf },
1446 Self::TUP8_I16_CODE => binary_decode_byte_tuple! { Tup8i16, i16, 8, buf },
1447 Self::TUP9_I16_CODE => binary_decode_byte_tuple! { Tup9i16, i16, 9, buf },
1448 Self::TUP10_I16_CODE => binary_decode_byte_tuple! { Tup10i16, i16, 10, buf },
1449 Self::TUP2_I32_CODE => binary_decode_byte_tuple! { Tup2i32, i32, 2, buf },
1450 Self::TUP3_I32_CODE => binary_decode_byte_tuple! { Tup3i32, i32, 3, buf },
1451 Self::TUP4_I32_CODE => binary_decode_byte_tuple! { Tup4i32, i32, 4, buf },
1452 Self::TUP5_I32_CODE => binary_decode_byte_tuple! { Tup5i32, i32, 5, buf },
1453 Self::TUP6_I32_CODE => binary_decode_byte_tuple! { Tup6i32, i32, 6, buf },
1454 Self::TUP7_I32_CODE => binary_decode_byte_tuple! { Tup7i32, i32, 7, buf },
1455 Self::TUP8_I32_CODE => binary_decode_byte_tuple! { Tup8i32, i32, 8, buf },
1456 Self::TUP9_I32_CODE => binary_decode_byte_tuple! { Tup9i32, i32, 9, buf },
1457 Self::TUP10_I32_CODE => binary_decode_byte_tuple! { Tup10i32, i32, 10, buf },
1458 Self::TUP2_I64_CODE => binary_decode_byte_tuple! { Tup2i64, i64, 2, buf },
1459 Self::TUP3_I64_CODE => binary_decode_byte_tuple! { Tup3i64, i64, 3, buf },
1460 Self::TUP4_I64_CODE => binary_decode_byte_tuple! { Tup4i64, i64, 4, buf },
1461 Self::TUP5_I64_CODE => binary_decode_byte_tuple! { Tup5i64, i64, 5, buf },
1462 Self::TUP6_I64_CODE => binary_decode_byte_tuple! { Tup6i64, i64, 6, buf },
1463 Self::TUP7_I64_CODE => binary_decode_byte_tuple! { Tup7i64, i64, 7, buf },
1464 Self::TUP8_I64_CODE => binary_decode_byte_tuple! { Tup8i64, i64, 8, buf },
1465 Self::TUP9_I64_CODE => binary_decode_byte_tuple! { Tup9i64, i64, 9, buf },
1466 Self::TUP10_I64_CODE => binary_decode_byte_tuple! { Tup10i64, i64, 10, buf },
1467
1468 code => return Err(err!(
1469 "Byte code 0x{:02x} not implemented.", code;
1470 Unimplemented, Input)),
1471 }
1472 }
1473}
1474
1475impl Dat {
1476
1477 /// Read a `u64` from bytes in the given buffer, and include the number of bytes read in the
1478 /// return tuple. The code prefix must be included in the buffer, but it is assumed that it has
1479 /// already been verified as within the correct range.
1480 ///
1481 /// A `c64` must be minimal: the code says how many bytes follow, so a leading zero among them
1482 /// encodes a value that a shorter code already encodes, and the encoder never writes one. Such
1483 /// an encoding is refused rather than read, because accepting it would give one value two valid
1484 /// byte strings. o3db hashes these bytes to decide which node owns a record, so a second
1485 /// encoding of the same key is a second node, and a record that can be written in one place and
1486 /// looked for in another.
1487 pub fn read_c64(buf: &[u8]) -> Outcome<(u64, usize)> {
1488 let len = (buf[0] - Dat::C64_CODE_START) as usize;
1489 if buf.len() < len + 1 {
1490 return Err(err!(
1491 "Not enough bytes to decode the Dat::C64.";
1492 Bytes, Input, Decode, Missing));
1493 }
1494 if len > 0 && buf[1] == 0 {
1495 return Err(err!(
1496 "The Dat::C64 code 0x{:02x} declares {} bytes, but the first is zero. A c64 is \
1497 minimally encoded, so this value has a shorter encoding and this one is not \
1498 canonical.", buf[0], len;
1499 Bytes, Input, Decode, Invalid));
1500 }
1501 let mut byts = [0_u8; 8];
1502 let offset = 8-len;
1503 for i in 0..len {
1504 byts[offset+i] = buf[i+1];
1505 }
1506 return Ok((
1507 u64::from_be_bytes(byts),
1508 len+1,
1509 ));
1510 }
1511
1512 /// Assumes the `Dat` code has been removed.
1513 pub fn read_c64_as_usize(buf: &[u8]) -> usize {
1514 let len = buf.len();
1515 let mut byts = [0_u8; 8];
1516 let offset = 8-len;
1517 for i in 0..len {
1518 byts[offset+i] = buf[i];
1519 }
1520 u64::from_be_bytes(byts) as usize
1521 }
1522
1523}