28enum CborTag { UNSIGNED, NEGATIVE, BYTES, TEXT, ARRAY, MAP, TAG, PRIMITIVE };
82 std::vector<CborDoc> children_;
93 bool decode(
const uint8_t in[],
size_t len,
size_t &pos,
size_t offset) {
95 header_pos_ = pos + offset;
100 uint8_t b = in[pos++];
102 size_t type = (b >> 5) & 0x7u;
103 size_t count0 = b & 0x1Fu;
109 }
else if (count0 == 24) {
114 }
else if (count0 == 25) {
115 if (pos + 1 >= len) {
118 count = in[pos] * 256 + in[pos + 1];
120 }
else if (count0 == 26) {
121 if (pos + 3 >= len) {
124 for (
size_t i = 0; i < 4; ++i) {
139 u_.i64 = -(int64_t)count;
144 if (pos + count > len) {
147 t_ = (type == 2) ? BYTES : TEXT;
149 u_.string.len = count;
154 if (pos + count > len) {
157 return decode_items(ARRAY, count, count, in, len, pos, offset);
160 if (pos + 2 * count > len) {
163 return decode_items(MAP, 2 * count, count, in, len, pos, offset);
168 if (pos + 1 + 10 > len) {
172 return decode_items(TAG, 1, count, in, len, pos, offset);
196 const CborDoc *index(
size_t index)
const {
197 if (t_ == ARRAY && index < u_.items.nchildren) {
198 return &children_[index];
209 const CborDoc *lookup(
const uint8_t *
const in,
size_t len,
210 const uint8_t bytes[],
size_t &ndx)
const {
212 for (
size_t i = 0; i < u_.items.n; ++i) {
213 if (children_[2 * i].eq(in, len, bytes)) {
215 return &children_[2 * i];
224 const CborDoc *lookup_unsigned(uint64_t k,
size_t &ndx)
const {
226 for (
size_t i = 0; i < u_.items.n; ++i) {
227 const CborDoc *key = &children_[2 * i];
228 if (key->t_ == UNSIGNED && key->u_.u64 == k) {
239 const CborDoc *lookup_negative(int64_t k,
size_t &ndx)
const {
241 for (
size_t i = 0; i < u_.items.n; ++i) {
242 const CborDoc *key = &children_[2 * i];
243 if (key->t_ == NEGATIVE && key->u_.i64 == k) {
253 size_t position()
const {
259 return u_.string.pos;
261 return children_[0].u_.string.pos;
265 check(
false,
"valueIndex called on non-value type");
274 size_t length()
const {
279 }
else if (u_.u64 < 256) {
281 }
else if (u_.u64 < 65536) {
287 return u_.string.len;
289 return children_[0].u_.string.len;
293 check(
false,
"valueLength called on non-value type");
300 bool decode_items(CborTag t,
size_t nchildren,
size_t items_n,
301 const uint8_t in[],
size_t len,
size_t &pos,
304 u_.items.n = items_n;
305 u_.items.nchildren = nchildren;
306 children_.resize(nchildren);
307 for (
size_t i = 0; i < nchildren; ++i) {
308 if (!children_[i].decode(in, len, pos, offset))
return false;
314 bool eq(
const uint8_t *
const in,
size_t len,
315 const uint8_t bytes[])
const {
316 return t_ == TEXT && u_.string.len == len &&
317 memcmp(bytes, &in[u_.string.pos], len) == 0;