cbor_data/validated/
mod.rs1use self::iterators::{ArrayIter, BytesIter, DictIter, StringIter};
3use crate::{
4 constants::*,
5 reader::{float, indefinite, integer, major, tags},
6 Cbor, ItemKind, Tags,
7};
8
9pub mod indexing;
10pub mod item;
11pub mod iterators;
12pub mod tags;
13
14fn skip_bytes(bytes: &[u8]) -> (Option<&[u8]>, &[u8]) {
15 let (len, _, mut rest) = integer(bytes).or_else(|| indefinite(bytes)).unwrap();
16 if len == u64::MAX {
17 while rest[0] != STOP_BYTE {
19 let (len, _, r) = integer(rest).unwrap();
20 rest = &r[len as usize..];
21 }
22 rest = &rest[1..];
23 (None, rest)
24 } else {
25 let len = len as usize;
26 (Some(&rest[..len]), &rest[len..])
27 }
28}
29
30fn skip(bytes: &[u8]) -> (Option<&[u8]>, &[u8]) {
31 match major(bytes).unwrap() {
32 MAJOR_POS | MAJOR_NEG | MAJOR_LIT => (None, integer(bytes).unwrap().2),
33 MAJOR_STR | MAJOR_BYTES => skip_bytes(bytes),
34 MAJOR_TAG => skip(integer(bytes).unwrap().2),
35 MAJOR_ARRAY => {
36 let (len, _, mut rest) = integer(bytes).or_else(|| indefinite(bytes)).unwrap();
37 if len == u64::MAX {
38 while rest[0] != STOP_BYTE {
40 rest = skip(rest).1;
41 }
42 rest = &rest[1..];
43 } else {
44 for _ in 0..len {
45 rest = skip(rest).1;
46 }
47 }
48 (None, rest)
49 }
50 MAJOR_DICT => {
51 let (len, _, mut rest) = integer(bytes).or_else(|| indefinite(bytes)).unwrap();
52 if len == u64::MAX {
53 while rest[0] != STOP_BYTE {
55 rest = skip(rest).1;
56 rest = skip(rest).1;
57 }
58 rest = &rest[1..];
59 } else {
60 for _ in 0..len {
61 rest = skip(rest).1;
62 rest = skip(rest).1;
63 }
64 }
65 (None, rest)
66 }
67 _ => unreachable!(),
68 }
69}
70
71fn string_iter(bytes: &[u8]) -> StringIter<'_> {
72 if bytes[0] & 31 == INDEFINITE_SIZE {
73 StringIter::new(&bytes[1..], None)
74 } else {
75 StringIter::new(bytes, Some(1))
76 }
77}
78
79fn bytes_iter(bytes: &[u8]) -> BytesIter<'_> {
80 if bytes[0] & 31 == INDEFINITE_SIZE {
81 BytesIter::new(&bytes[1..], None)
82 } else {
83 BytesIter::new(bytes, Some(1))
84 }
85}
86
87fn item(bytes: &[u8]) -> ItemKind {
88 use ItemKind::*;
89
90 match major(bytes).unwrap() {
91 MAJOR_POS => Pos(integer(bytes).unwrap().0),
92 MAJOR_NEG => Neg(integer(bytes).unwrap().0),
93 MAJOR_BYTES => Bytes(bytes_iter(bytes)),
94 MAJOR_STR => Str(string_iter(bytes)),
95 MAJOR_LIT => match bytes[0] & 31 {
96 LIT_FALSE => Bool(false),
97 LIT_TRUE => Bool(true),
98 LIT_NULL => Null,
99 LIT_UNDEFINED => Undefined,
100 LIT_SIMPLE => Simple(bytes[1]),
101 LIT_FLOAT16 | LIT_FLOAT32 | LIT_FLOAT64 => Float(float(bytes).unwrap().0),
102 x if x < 24 => Simple(x),
103 _ => unreachable!(),
104 },
105 MAJOR_TAG => item(integer(bytes).unwrap().2),
106 MAJOR_ARRAY => {
107 let (len, _, arr) = integer(bytes).or_else(|| indefinite(bytes)).unwrap();
108 let len = if len == u64::MAX { None } else { Some(len) };
109 Array(ArrayIter::new(arr, len))
110 }
111 MAJOR_DICT => {
112 let (len, _, dict) = integer(bytes).or_else(|| indefinite(bytes)).unwrap();
113 let len = if len == u64::MAX { None } else { Some(len) };
114 Dict(DictIter::new(dict, len))
115 }
116 _ => unreachable!(),
117 }
118}
119
120pub fn tagged_item(bytes: &[u8]) -> (Tags, ItemKind) {
121 let (tags, rest) = tags(bytes).unwrap();
122 let kind = item(rest);
123 (tags, kind)
124}
125
126#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
130struct CborIter<'a>(&'a [u8], Option<u64>);
131
132impl<'a> CborIter<'a> {
133 pub fn new(bytes: &'a [u8], len: Option<u64>) -> Self {
134 Self(bytes, len)
135 }
136 pub fn size(&self) -> Option<u64> {
137 self.1
138 }
139}
140
141impl<'a> Iterator for CborIter<'a> {
142 type Item = (Option<&'a [u8]>, &'a Cbor);
143
144 fn next(&mut self) -> Option<Self::Item> {
145 let CborIter(b, elems) = self;
146 if *elems == Some(0) || *elems == None && b[0] == STOP_BYTE {
147 None
148 } else {
149 let (value, rest) = skip(b);
150 let bytes = &b[..b.len() - rest.len()];
151 if let Some(x) = elems.as_mut() {
152 *x -= 1;
153 }
154 *b = rest;
155 Some((value, Cbor::unchecked(bytes)))
156 }
157 }
158}