110ff414cSEd Maste /*
210ff414cSEd Maste * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com>
310ff414cSEd Maste *
410ff414cSEd Maste * libcbor is free software; you can redistribute it and/or modify
510ff414cSEd Maste * it under the terms of the MIT license. See LICENSE for details.
610ff414cSEd Maste */
710ff414cSEd Maste
810ff414cSEd Maste #include "streaming.h"
910ff414cSEd Maste #include "internal/loaders.h"
1010ff414cSEd Maste
claim_bytes(size_t required,size_t provided,struct cbor_decoder_result * result)115d3e7166SEd Maste static bool claim_bytes(size_t required, size_t provided,
1210ff414cSEd Maste struct cbor_decoder_result *result) {
1310ff414cSEd Maste if (required > (provided - result->read)) {
1410ff414cSEd Maste result->required = required + result->read;
1510ff414cSEd Maste result->read = 0;
1610ff414cSEd Maste result->status = CBOR_DECODER_NEDATA;
1710ff414cSEd Maste return false;
1810ff414cSEd Maste } else {
1910ff414cSEd Maste result->read += required;
2010ff414cSEd Maste result->required = 0;
2110ff414cSEd Maste return true;
2210ff414cSEd Maste }
2310ff414cSEd Maste }
2410ff414cSEd Maste
255d3e7166SEd Maste // Use implicit capture as an exception to avoid the super long parameter list
265d3e7166SEd Maste #define CLAIM_BYTES_AND_INVOKE(callback_name, length, source_extra_offset) \
275d3e7166SEd Maste do { \
285d3e7166SEd Maste if (claim_bytes(length, source_size, &result)) { \
295d3e7166SEd Maste callbacks->callback_name(context, source + 1 + source_extra_offset, \
305d3e7166SEd Maste length); \
315d3e7166SEd Maste } \
325d3e7166SEd Maste } while (0)
335d3e7166SEd Maste
345d3e7166SEd Maste #define READ_CLAIM_INVOKE(callback_name, length_reader, length_bytes) \
355d3e7166SEd Maste do { \
365d3e7166SEd Maste if (claim_bytes(length_bytes, source_size, &result)) { \
375d3e7166SEd Maste uint64_t length = length_reader(source + 1); \
385d3e7166SEd Maste CLAIM_BYTES_AND_INVOKE(callback_name, length, length_bytes); \
395d3e7166SEd Maste } \
405d3e7166SEd Maste return result; \
415d3e7166SEd Maste } while (0)
425d3e7166SEd Maste
cbor_stream_decode(cbor_data source,size_t source_size,const struct cbor_callbacks * callbacks,void * context)4310ff414cSEd Maste struct cbor_decoder_result cbor_stream_decode(
4410ff414cSEd Maste cbor_data source, size_t source_size,
4510ff414cSEd Maste const struct cbor_callbacks *callbacks, void *context) {
4610ff414cSEd Maste // Attempt to claim the initial MTB byte
4710ff414cSEd Maste struct cbor_decoder_result result = {.status = CBOR_DECODER_FINISHED};
4810ff414cSEd Maste if (!claim_bytes(1, source_size, &result)) {
4910ff414cSEd Maste return result;
5010ff414cSEd Maste }
5110ff414cSEd Maste
5210ff414cSEd Maste switch (*source) {
5310ff414cSEd Maste case 0x00: /* Fallthrough */
5410ff414cSEd Maste case 0x01: /* Fallthrough */
5510ff414cSEd Maste case 0x02: /* Fallthrough */
5610ff414cSEd Maste case 0x03: /* Fallthrough */
5710ff414cSEd Maste case 0x04: /* Fallthrough */
5810ff414cSEd Maste case 0x05: /* Fallthrough */
5910ff414cSEd Maste case 0x06: /* Fallthrough */
6010ff414cSEd Maste case 0x07: /* Fallthrough */
6110ff414cSEd Maste case 0x08: /* Fallthrough */
6210ff414cSEd Maste case 0x09: /* Fallthrough */
6310ff414cSEd Maste case 0x0A: /* Fallthrough */
6410ff414cSEd Maste case 0x0B: /* Fallthrough */
6510ff414cSEd Maste case 0x0C: /* Fallthrough */
6610ff414cSEd Maste case 0x0D: /* Fallthrough */
6710ff414cSEd Maste case 0x0E: /* Fallthrough */
6810ff414cSEd Maste case 0x0F: /* Fallthrough */
6910ff414cSEd Maste case 0x10: /* Fallthrough */
7010ff414cSEd Maste case 0x11: /* Fallthrough */
7110ff414cSEd Maste case 0x12: /* Fallthrough */
7210ff414cSEd Maste case 0x13: /* Fallthrough */
7310ff414cSEd Maste case 0x14: /* Fallthrough */
7410ff414cSEd Maste case 0x15: /* Fallthrough */
7510ff414cSEd Maste case 0x16: /* Fallthrough */
7610ff414cSEd Maste case 0x17:
7710ff414cSEd Maste /* Embedded one byte unsigned integer */
7810ff414cSEd Maste {
7910ff414cSEd Maste callbacks->uint8(context, _cbor_load_uint8(source));
8010ff414cSEd Maste return result;
8110ff414cSEd Maste }
8210ff414cSEd Maste case 0x18:
8310ff414cSEd Maste /* One byte unsigned integer */
8410ff414cSEd Maste {
8510ff414cSEd Maste if (claim_bytes(1, source_size, &result)) {
8610ff414cSEd Maste callbacks->uint8(context, _cbor_load_uint8(source + 1));
8710ff414cSEd Maste }
8810ff414cSEd Maste return result;
8910ff414cSEd Maste }
9010ff414cSEd Maste case 0x19:
9110ff414cSEd Maste /* Two bytes unsigned integer */
9210ff414cSEd Maste {
9310ff414cSEd Maste if (claim_bytes(2, source_size, &result)) {
9410ff414cSEd Maste callbacks->uint16(context, _cbor_load_uint16(source + 1));
9510ff414cSEd Maste }
9610ff414cSEd Maste return result;
9710ff414cSEd Maste }
9810ff414cSEd Maste case 0x1A:
9910ff414cSEd Maste /* Four bytes unsigned integer */
10010ff414cSEd Maste {
10110ff414cSEd Maste if (claim_bytes(4, source_size, &result)) {
10210ff414cSEd Maste callbacks->uint32(context, _cbor_load_uint32(source + 1));
10310ff414cSEd Maste }
10410ff414cSEd Maste return result;
10510ff414cSEd Maste }
10610ff414cSEd Maste case 0x1B:
10710ff414cSEd Maste /* Eight bytes unsigned integer */
10810ff414cSEd Maste {
10910ff414cSEd Maste if (claim_bytes(8, source_size, &result)) {
11010ff414cSEd Maste callbacks->uint64(context, _cbor_load_uint64(source + 1));
11110ff414cSEd Maste }
11210ff414cSEd Maste return result;
11310ff414cSEd Maste }
11410ff414cSEd Maste case 0x1C: /* Fallthrough */
11510ff414cSEd Maste case 0x1D: /* Fallthrough */
11610ff414cSEd Maste case 0x1E: /* Fallthrough */
11710ff414cSEd Maste case 0x1F:
11810ff414cSEd Maste /* Reserved */
1195d3e7166SEd Maste { return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; }
12010ff414cSEd Maste case 0x20: /* Fallthrough */
12110ff414cSEd Maste case 0x21: /* Fallthrough */
12210ff414cSEd Maste case 0x22: /* Fallthrough */
12310ff414cSEd Maste case 0x23: /* Fallthrough */
12410ff414cSEd Maste case 0x24: /* Fallthrough */
12510ff414cSEd Maste case 0x25: /* Fallthrough */
12610ff414cSEd Maste case 0x26: /* Fallthrough */
12710ff414cSEd Maste case 0x27: /* Fallthrough */
12810ff414cSEd Maste case 0x28: /* Fallthrough */
12910ff414cSEd Maste case 0x29: /* Fallthrough */
13010ff414cSEd Maste case 0x2A: /* Fallthrough */
13110ff414cSEd Maste case 0x2B: /* Fallthrough */
13210ff414cSEd Maste case 0x2C: /* Fallthrough */
13310ff414cSEd Maste case 0x2D: /* Fallthrough */
13410ff414cSEd Maste case 0x2E: /* Fallthrough */
13510ff414cSEd Maste case 0x2F: /* Fallthrough */
13610ff414cSEd Maste case 0x30: /* Fallthrough */
13710ff414cSEd Maste case 0x31: /* Fallthrough */
13810ff414cSEd Maste case 0x32: /* Fallthrough */
13910ff414cSEd Maste case 0x33: /* Fallthrough */
14010ff414cSEd Maste case 0x34: /* Fallthrough */
14110ff414cSEd Maste case 0x35: /* Fallthrough */
14210ff414cSEd Maste case 0x36: /* Fallthrough */
14310ff414cSEd Maste case 0x37:
14410ff414cSEd Maste /* Embedded one byte negative integer */
14510ff414cSEd Maste {
14610ff414cSEd Maste callbacks->negint8(context,
14710ff414cSEd Maste _cbor_load_uint8(source) - 0x20); /* 0x20 offset */
14810ff414cSEd Maste return result;
14910ff414cSEd Maste }
15010ff414cSEd Maste case 0x38:
15110ff414cSEd Maste /* One byte negative integer */
15210ff414cSEd Maste {
15310ff414cSEd Maste if (claim_bytes(1, source_size, &result)) {
15410ff414cSEd Maste callbacks->negint8(context, _cbor_load_uint8(source + 1));
15510ff414cSEd Maste }
15610ff414cSEd Maste return result;
15710ff414cSEd Maste }
15810ff414cSEd Maste case 0x39:
15910ff414cSEd Maste /* Two bytes negative integer */
16010ff414cSEd Maste {
16110ff414cSEd Maste if (claim_bytes(2, source_size, &result)) {
16210ff414cSEd Maste callbacks->negint16(context, _cbor_load_uint16(source + 1));
16310ff414cSEd Maste }
16410ff414cSEd Maste return result;
16510ff414cSEd Maste }
16610ff414cSEd Maste case 0x3A:
16710ff414cSEd Maste /* Four bytes negative integer */
16810ff414cSEd Maste {
16910ff414cSEd Maste if (claim_bytes(4, source_size, &result)) {
17010ff414cSEd Maste callbacks->negint32(context, _cbor_load_uint32(source + 1));
17110ff414cSEd Maste }
17210ff414cSEd Maste return result;
17310ff414cSEd Maste }
17410ff414cSEd Maste case 0x3B:
17510ff414cSEd Maste /* Eight bytes negative integer */
17610ff414cSEd Maste {
17710ff414cSEd Maste if (claim_bytes(8, source_size, &result)) {
17810ff414cSEd Maste callbacks->negint64(context, _cbor_load_uint64(source + 1));
17910ff414cSEd Maste }
18010ff414cSEd Maste return result;
18110ff414cSEd Maste }
18210ff414cSEd Maste case 0x3C: /* Fallthrough */
18310ff414cSEd Maste case 0x3D: /* Fallthrough */
18410ff414cSEd Maste case 0x3E: /* Fallthrough */
18510ff414cSEd Maste case 0x3F:
18610ff414cSEd Maste /* Reserved */
1875d3e7166SEd Maste { return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; }
18810ff414cSEd Maste case 0x40: /* Fallthrough */
18910ff414cSEd Maste case 0x41: /* Fallthrough */
19010ff414cSEd Maste case 0x42: /* Fallthrough */
19110ff414cSEd Maste case 0x43: /* Fallthrough */
19210ff414cSEd Maste case 0x44: /* Fallthrough */
19310ff414cSEd Maste case 0x45: /* Fallthrough */
19410ff414cSEd Maste case 0x46: /* Fallthrough */
19510ff414cSEd Maste case 0x47: /* Fallthrough */
19610ff414cSEd Maste case 0x48: /* Fallthrough */
19710ff414cSEd Maste case 0x49: /* Fallthrough */
19810ff414cSEd Maste case 0x4A: /* Fallthrough */
19910ff414cSEd Maste case 0x4B: /* Fallthrough */
20010ff414cSEd Maste case 0x4C: /* Fallthrough */
20110ff414cSEd Maste case 0x4D: /* Fallthrough */
20210ff414cSEd Maste case 0x4E: /* Fallthrough */
20310ff414cSEd Maste case 0x4F: /* Fallthrough */
20410ff414cSEd Maste case 0x50: /* Fallthrough */
20510ff414cSEd Maste case 0x51: /* Fallthrough */
20610ff414cSEd Maste case 0x52: /* Fallthrough */
20710ff414cSEd Maste case 0x53: /* Fallthrough */
20810ff414cSEd Maste case 0x54: /* Fallthrough */
20910ff414cSEd Maste case 0x55: /* Fallthrough */
21010ff414cSEd Maste case 0x56: /* Fallthrough */
21110ff414cSEd Maste case 0x57:
21210ff414cSEd Maste /* Embedded length byte string */
21310ff414cSEd Maste {
2145d3e7166SEd Maste uint64_t length = _cbor_load_uint8(source) - 0x40; /* 0x40 offset */
2155d3e7166SEd Maste CLAIM_BYTES_AND_INVOKE(byte_string, length, 0);
21610ff414cSEd Maste return result;
21710ff414cSEd Maste }
21810ff414cSEd Maste case 0x58:
21910ff414cSEd Maste /* One byte length byte string */
2205d3e7166SEd Maste READ_CLAIM_INVOKE(byte_string, _cbor_load_uint8, 1);
22110ff414cSEd Maste case 0x59:
22210ff414cSEd Maste /* Two bytes length byte string */
2235d3e7166SEd Maste READ_CLAIM_INVOKE(byte_string, _cbor_load_uint16, 2);
22410ff414cSEd Maste case 0x5A:
22510ff414cSEd Maste /* Four bytes length byte string */
2265d3e7166SEd Maste READ_CLAIM_INVOKE(byte_string, _cbor_load_uint32, 4);
22710ff414cSEd Maste case 0x5B:
22810ff414cSEd Maste /* Eight bytes length byte string */
2295d3e7166SEd Maste READ_CLAIM_INVOKE(byte_string, _cbor_load_uint64, 8);
23010ff414cSEd Maste case 0x5C: /* Fallthrough */
23110ff414cSEd Maste case 0x5D: /* Fallthrough */
23210ff414cSEd Maste case 0x5E:
23310ff414cSEd Maste /* Reserved */
2345d3e7166SEd Maste { return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; }
23510ff414cSEd Maste case 0x5F:
23610ff414cSEd Maste /* Indefinite byte string */
23710ff414cSEd Maste {
23810ff414cSEd Maste callbacks->byte_string_start(context);
23910ff414cSEd Maste return result;
24010ff414cSEd Maste }
24110ff414cSEd Maste case 0x60: /* Fallthrough */
24210ff414cSEd Maste case 0x61: /* Fallthrough */
24310ff414cSEd Maste case 0x62: /* Fallthrough */
24410ff414cSEd Maste case 0x63: /* Fallthrough */
24510ff414cSEd Maste case 0x64: /* Fallthrough */
24610ff414cSEd Maste case 0x65: /* Fallthrough */
24710ff414cSEd Maste case 0x66: /* Fallthrough */
24810ff414cSEd Maste case 0x67: /* Fallthrough */
24910ff414cSEd Maste case 0x68: /* Fallthrough */
25010ff414cSEd Maste case 0x69: /* Fallthrough */
25110ff414cSEd Maste case 0x6A: /* Fallthrough */
25210ff414cSEd Maste case 0x6B: /* Fallthrough */
25310ff414cSEd Maste case 0x6C: /* Fallthrough */
25410ff414cSEd Maste case 0x6D: /* Fallthrough */
25510ff414cSEd Maste case 0x6E: /* Fallthrough */
25610ff414cSEd Maste case 0x6F: /* Fallthrough */
25710ff414cSEd Maste case 0x70: /* Fallthrough */
25810ff414cSEd Maste case 0x71: /* Fallthrough */
25910ff414cSEd Maste case 0x72: /* Fallthrough */
26010ff414cSEd Maste case 0x73: /* Fallthrough */
26110ff414cSEd Maste case 0x74: /* Fallthrough */
26210ff414cSEd Maste case 0x75: /* Fallthrough */
26310ff414cSEd Maste case 0x76: /* Fallthrough */
26410ff414cSEd Maste case 0x77:
26510ff414cSEd Maste /* Embedded one byte length string */
26610ff414cSEd Maste {
2675d3e7166SEd Maste uint64_t length = _cbor_load_uint8(source) - 0x60; /* 0x60 offset */
2685d3e7166SEd Maste CLAIM_BYTES_AND_INVOKE(string, length, 0);
26910ff414cSEd Maste return result;
27010ff414cSEd Maste }
27110ff414cSEd Maste case 0x78:
27210ff414cSEd Maste /* One byte length string */
2735d3e7166SEd Maste READ_CLAIM_INVOKE(string, _cbor_load_uint8, 1);
27410ff414cSEd Maste case 0x79:
27510ff414cSEd Maste /* Two bytes length string */
2765d3e7166SEd Maste READ_CLAIM_INVOKE(string, _cbor_load_uint16, 2);
27710ff414cSEd Maste case 0x7A:
27810ff414cSEd Maste /* Four bytes length string */
2795d3e7166SEd Maste READ_CLAIM_INVOKE(string, _cbor_load_uint32, 4);
28010ff414cSEd Maste case 0x7B:
28110ff414cSEd Maste /* Eight bytes length string */
2825d3e7166SEd Maste READ_CLAIM_INVOKE(string, _cbor_load_uint64, 8);
28310ff414cSEd Maste case 0x7C: /* Fallthrough */
28410ff414cSEd Maste case 0x7D: /* Fallthrough */
28510ff414cSEd Maste case 0x7E:
28610ff414cSEd Maste /* Reserved */
2875d3e7166SEd Maste { return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; }
28810ff414cSEd Maste case 0x7F:
28910ff414cSEd Maste /* Indefinite length string */
29010ff414cSEd Maste {
29110ff414cSEd Maste callbacks->string_start(context);
29210ff414cSEd Maste return result;
29310ff414cSEd Maste }
29410ff414cSEd Maste case 0x80: /* Fallthrough */
29510ff414cSEd Maste case 0x81: /* Fallthrough */
29610ff414cSEd Maste case 0x82: /* Fallthrough */
29710ff414cSEd Maste case 0x83: /* Fallthrough */
29810ff414cSEd Maste case 0x84: /* Fallthrough */
29910ff414cSEd Maste case 0x85: /* Fallthrough */
30010ff414cSEd Maste case 0x86: /* Fallthrough */
30110ff414cSEd Maste case 0x87: /* Fallthrough */
30210ff414cSEd Maste case 0x88: /* Fallthrough */
30310ff414cSEd Maste case 0x89: /* Fallthrough */
30410ff414cSEd Maste case 0x8A: /* Fallthrough */
30510ff414cSEd Maste case 0x8B: /* Fallthrough */
30610ff414cSEd Maste case 0x8C: /* Fallthrough */
30710ff414cSEd Maste case 0x8D: /* Fallthrough */
30810ff414cSEd Maste case 0x8E: /* Fallthrough */
30910ff414cSEd Maste case 0x8F: /* Fallthrough */
31010ff414cSEd Maste case 0x90: /* Fallthrough */
31110ff414cSEd Maste case 0x91: /* Fallthrough */
31210ff414cSEd Maste case 0x92: /* Fallthrough */
31310ff414cSEd Maste case 0x93: /* Fallthrough */
31410ff414cSEd Maste case 0x94: /* Fallthrough */
31510ff414cSEd Maste case 0x95: /* Fallthrough */
31610ff414cSEd Maste case 0x96: /* Fallthrough */
31710ff414cSEd Maste case 0x97:
31810ff414cSEd Maste /* Embedded one byte length array */
31910ff414cSEd Maste {
32010ff414cSEd Maste callbacks->array_start(
3215d3e7166SEd Maste context, _cbor_load_uint8(source) - 0x80); /* 0x40 offset */
32210ff414cSEd Maste return result;
32310ff414cSEd Maste }
32410ff414cSEd Maste case 0x98:
32510ff414cSEd Maste /* One byte length array */
32610ff414cSEd Maste {
32710ff414cSEd Maste if (claim_bytes(1, source_size, &result)) {
3285d3e7166SEd Maste callbacks->array_start(context, _cbor_load_uint8(source + 1));
32910ff414cSEd Maste }
33010ff414cSEd Maste return result;
33110ff414cSEd Maste }
33210ff414cSEd Maste case 0x99:
33310ff414cSEd Maste /* Two bytes length array */
33410ff414cSEd Maste {
33510ff414cSEd Maste if (claim_bytes(2, source_size, &result)) {
3365d3e7166SEd Maste callbacks->array_start(context, _cbor_load_uint16(source + 1));
33710ff414cSEd Maste }
33810ff414cSEd Maste return result;
33910ff414cSEd Maste }
34010ff414cSEd Maste case 0x9A:
34110ff414cSEd Maste /* Four bytes length array */
34210ff414cSEd Maste {
34310ff414cSEd Maste if (claim_bytes(4, source_size, &result)) {
3445d3e7166SEd Maste callbacks->array_start(context, _cbor_load_uint32(source + 1));
34510ff414cSEd Maste }
34610ff414cSEd Maste return result;
34710ff414cSEd Maste }
34810ff414cSEd Maste case 0x9B:
34910ff414cSEd Maste /* Eight bytes length array */
35010ff414cSEd Maste {
35110ff414cSEd Maste if (claim_bytes(8, source_size, &result)) {
3525d3e7166SEd Maste callbacks->array_start(context, _cbor_load_uint64(source + 1));
35310ff414cSEd Maste }
35410ff414cSEd Maste return result;
35510ff414cSEd Maste }
35610ff414cSEd Maste case 0x9C: /* Fallthrough */
35710ff414cSEd Maste case 0x9D: /* Fallthrough */
35810ff414cSEd Maste case 0x9E:
35910ff414cSEd Maste /* Reserved */
3605d3e7166SEd Maste { return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; }
36110ff414cSEd Maste case 0x9F:
36210ff414cSEd Maste /* Indefinite length array */
36310ff414cSEd Maste {
36410ff414cSEd Maste callbacks->indef_array_start(context);
36510ff414cSEd Maste return result;
36610ff414cSEd Maste }
36710ff414cSEd Maste case 0xA0: /* Fallthrough */
36810ff414cSEd Maste case 0xA1: /* Fallthrough */
36910ff414cSEd Maste case 0xA2: /* Fallthrough */
37010ff414cSEd Maste case 0xA3: /* Fallthrough */
37110ff414cSEd Maste case 0xA4: /* Fallthrough */
37210ff414cSEd Maste case 0xA5: /* Fallthrough */
37310ff414cSEd Maste case 0xA6: /* Fallthrough */
37410ff414cSEd Maste case 0xA7: /* Fallthrough */
37510ff414cSEd Maste case 0xA8: /* Fallthrough */
37610ff414cSEd Maste case 0xA9: /* Fallthrough */
37710ff414cSEd Maste case 0xAA: /* Fallthrough */
37810ff414cSEd Maste case 0xAB: /* Fallthrough */
37910ff414cSEd Maste case 0xAC: /* Fallthrough */
38010ff414cSEd Maste case 0xAD: /* Fallthrough */
38110ff414cSEd Maste case 0xAE: /* Fallthrough */
38210ff414cSEd Maste case 0xAF: /* Fallthrough */
38310ff414cSEd Maste case 0xB0: /* Fallthrough */
38410ff414cSEd Maste case 0xB1: /* Fallthrough */
38510ff414cSEd Maste case 0xB2: /* Fallthrough */
38610ff414cSEd Maste case 0xB3: /* Fallthrough */
38710ff414cSEd Maste case 0xB4: /* Fallthrough */
38810ff414cSEd Maste case 0xB5: /* Fallthrough */
38910ff414cSEd Maste case 0xB6: /* Fallthrough */
39010ff414cSEd Maste case 0xB7:
39110ff414cSEd Maste /* Embedded one byte length map */
39210ff414cSEd Maste {
3935d3e7166SEd Maste callbacks->map_start(context,
3945d3e7166SEd Maste _cbor_load_uint8(source) - 0xA0); /* 0xA0 offset */
39510ff414cSEd Maste return result;
39610ff414cSEd Maste }
39710ff414cSEd Maste case 0xB8:
39810ff414cSEd Maste /* One byte length map */
39910ff414cSEd Maste {
40010ff414cSEd Maste if (claim_bytes(1, source_size, &result)) {
4015d3e7166SEd Maste callbacks->map_start(context, _cbor_load_uint8(source + 1));
40210ff414cSEd Maste }
40310ff414cSEd Maste return result;
40410ff414cSEd Maste }
40510ff414cSEd Maste case 0xB9:
40610ff414cSEd Maste /* Two bytes length map */
40710ff414cSEd Maste {
40810ff414cSEd Maste if (claim_bytes(2, source_size, &result)) {
4095d3e7166SEd Maste callbacks->map_start(context, _cbor_load_uint16(source + 1));
41010ff414cSEd Maste }
41110ff414cSEd Maste return result;
41210ff414cSEd Maste }
41310ff414cSEd Maste case 0xBA:
41410ff414cSEd Maste /* Four bytes length map */
41510ff414cSEd Maste {
41610ff414cSEd Maste if (claim_bytes(4, source_size, &result)) {
4175d3e7166SEd Maste callbacks->map_start(context, _cbor_load_uint32(source + 1));
41810ff414cSEd Maste }
41910ff414cSEd Maste return result;
42010ff414cSEd Maste }
42110ff414cSEd Maste case 0xBB:
42210ff414cSEd Maste /* Eight bytes length map */
42310ff414cSEd Maste {
42410ff414cSEd Maste if (claim_bytes(8, source_size, &result)) {
4255d3e7166SEd Maste callbacks->map_start(context, _cbor_load_uint64(source + 1));
42610ff414cSEd Maste }
42710ff414cSEd Maste return result;
42810ff414cSEd Maste }
42910ff414cSEd Maste case 0xBC: /* Fallthrough */
43010ff414cSEd Maste case 0xBD: /* Fallthrough */
43110ff414cSEd Maste case 0xBE:
43210ff414cSEd Maste /* Reserved */
4335d3e7166SEd Maste { return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; }
43410ff414cSEd Maste case 0xBF:
43510ff414cSEd Maste /* Indefinite length map */
43610ff414cSEd Maste {
43710ff414cSEd Maste callbacks->indef_map_start(context);
43810ff414cSEd Maste return result;
43910ff414cSEd Maste }
440*abd87254SEd Maste /* See https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml for tag
441*abd87254SEd Maste * assignment. All well-formed tags are processed regardless of validity
442*abd87254SEd Maste * since maintaining the known mapping would be impractical.
443*abd87254SEd Maste *
444*abd87254SEd Maste * Moreover, even tags in the reserved "standard" range are not assigned
445*abd87254SEd Maste * but may get assigned in the future (see e.g.
446*abd87254SEd Maste * https://github.com/PJK/libcbor/issues/307), so processing all tags
447*abd87254SEd Maste * improves forward compatibility.
448*abd87254SEd Maste */
449*abd87254SEd Maste case 0xC0: /* Fallthrough */
450*abd87254SEd Maste case 0xC1: /* Fallthrough */
451*abd87254SEd Maste case 0xC2: /* Fallthrough */
452*abd87254SEd Maste case 0xC3: /* Fallthrough */
453*abd87254SEd Maste case 0xC4: /* Fallthrough */
454*abd87254SEd Maste case 0xC5: /* Fallthrough */
45510ff414cSEd Maste case 0xC6: /* Fallthrough */
45610ff414cSEd Maste case 0xC7: /* Fallthrough */
45710ff414cSEd Maste case 0xC8: /* Fallthrough */
45810ff414cSEd Maste case 0xC9: /* Fallthrough */
45910ff414cSEd Maste case 0xCA: /* Fallthrough */
46010ff414cSEd Maste case 0xCB: /* Fallthrough */
46110ff414cSEd Maste case 0xCC: /* Fallthrough */
46210ff414cSEd Maste case 0xCD: /* Fallthrough */
46310ff414cSEd Maste case 0xCE: /* Fallthrough */
46410ff414cSEd Maste case 0xCF: /* Fallthrough */
46510ff414cSEd Maste case 0xD0: /* Fallthrough */
46610ff414cSEd Maste case 0xD1: /* Fallthrough */
46710ff414cSEd Maste case 0xD2: /* Fallthrough */
46810ff414cSEd Maste case 0xD3: /* Fallthrough */
469*abd87254SEd Maste case 0xD4: /* Fallthrough */
470*abd87254SEd Maste case 0xD5: /* Fallthrough */
471*abd87254SEd Maste case 0xD6: /* Fallthrough */
472*abd87254SEd Maste case 0xD7: /* Fallthrough */
47310ff414cSEd Maste {
4745d3e7166SEd Maste callbacks->tag(context, (uint64_t)(_cbor_load_uint8(source) -
4755d3e7166SEd Maste 0xC0)); /* 0xC0 offset */
47610ff414cSEd Maste return result;
47710ff414cSEd Maste }
47810ff414cSEd Maste case 0xD8: /* 1B tag */
47910ff414cSEd Maste {
48010ff414cSEd Maste if (claim_bytes(1, source_size, &result)) {
48110ff414cSEd Maste callbacks->tag(context, _cbor_load_uint8(source + 1));
48210ff414cSEd Maste }
48310ff414cSEd Maste return result;
48410ff414cSEd Maste }
48510ff414cSEd Maste case 0xD9: /* 2B tag */
48610ff414cSEd Maste {
48710ff414cSEd Maste if (claim_bytes(2, source_size, &result)) {
48810ff414cSEd Maste callbacks->tag(context, _cbor_load_uint16(source + 1));
48910ff414cSEd Maste }
49010ff414cSEd Maste return result;
49110ff414cSEd Maste }
49210ff414cSEd Maste case 0xDA: /* 4B tag */
49310ff414cSEd Maste {
49410ff414cSEd Maste if (claim_bytes(4, source_size, &result)) {
49510ff414cSEd Maste callbacks->tag(context, _cbor_load_uint32(source + 1));
49610ff414cSEd Maste }
49710ff414cSEd Maste return result;
49810ff414cSEd Maste }
49910ff414cSEd Maste case 0xDB: /* 8B tag */
50010ff414cSEd Maste {
50110ff414cSEd Maste if (claim_bytes(8, source_size, &result)) {
50210ff414cSEd Maste callbacks->tag(context, _cbor_load_uint64(source + 1));
50310ff414cSEd Maste }
50410ff414cSEd Maste return result;
50510ff414cSEd Maste }
50610ff414cSEd Maste case 0xDC: /* Fallthrough */
50710ff414cSEd Maste case 0xDD: /* Fallthrough */
50810ff414cSEd Maste case 0xDE: /* Fallthrough */
50910ff414cSEd Maste case 0xDF: /* Reserved */
51010ff414cSEd Maste {
5115d3e7166SEd Maste return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR};
51210ff414cSEd Maste }
51310ff414cSEd Maste case 0xE0: /* Fallthrough */
51410ff414cSEd Maste case 0xE1: /* Fallthrough */
51510ff414cSEd Maste case 0xE2: /* Fallthrough */
51610ff414cSEd Maste case 0xE3: /* Fallthrough */
51710ff414cSEd Maste case 0xE4: /* Fallthrough */
51810ff414cSEd Maste case 0xE5: /* Fallthrough */
51910ff414cSEd Maste case 0xE6: /* Fallthrough */
52010ff414cSEd Maste case 0xE7: /* Fallthrough */
52110ff414cSEd Maste case 0xE8: /* Fallthrough */
52210ff414cSEd Maste case 0xE9: /* Fallthrough */
52310ff414cSEd Maste case 0xEA: /* Fallthrough */
52410ff414cSEd Maste case 0xEB: /* Fallthrough */
52510ff414cSEd Maste case 0xEC: /* Fallthrough */
52610ff414cSEd Maste case 0xED: /* Fallthrough */
52710ff414cSEd Maste case 0xEE: /* Fallthrough */
52810ff414cSEd Maste case 0xEF: /* Fallthrough */
52910ff414cSEd Maste case 0xF0: /* Fallthrough */
53010ff414cSEd Maste case 0xF1: /* Fallthrough */
53110ff414cSEd Maste case 0xF2: /* Fallthrough */
53210ff414cSEd Maste case 0xF3: /* Simple value - unassigned */
53310ff414cSEd Maste {
5345d3e7166SEd Maste return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR};
53510ff414cSEd Maste }
53610ff414cSEd Maste case 0xF4:
53710ff414cSEd Maste /* False */
53810ff414cSEd Maste {
53910ff414cSEd Maste callbacks->boolean(context, false);
54010ff414cSEd Maste return result;
54110ff414cSEd Maste }
54210ff414cSEd Maste case 0xF5:
54310ff414cSEd Maste /* True */
54410ff414cSEd Maste {
54510ff414cSEd Maste callbacks->boolean(context, true);
54610ff414cSEd Maste return result;
54710ff414cSEd Maste }
54810ff414cSEd Maste case 0xF6:
54910ff414cSEd Maste /* Null */
55010ff414cSEd Maste {
55110ff414cSEd Maste callbacks->null(context);
55210ff414cSEd Maste return result;
55310ff414cSEd Maste }
55410ff414cSEd Maste case 0xF7:
55510ff414cSEd Maste /* Undefined */
55610ff414cSEd Maste {
55710ff414cSEd Maste callbacks->undefined(context);
55810ff414cSEd Maste return result;
55910ff414cSEd Maste }
56010ff414cSEd Maste case 0xF8:
56110ff414cSEd Maste /* 1B simple value, unassigned */
5625d3e7166SEd Maste { return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; }
56310ff414cSEd Maste case 0xF9:
56410ff414cSEd Maste /* 2B float */
56510ff414cSEd Maste {
56610ff414cSEd Maste if (claim_bytes(2, source_size, &result)) {
56710ff414cSEd Maste callbacks->float2(context, _cbor_load_half(source + 1));
56810ff414cSEd Maste }
56910ff414cSEd Maste return result;
57010ff414cSEd Maste }
57110ff414cSEd Maste case 0xFA:
57210ff414cSEd Maste /* 4B float */
57310ff414cSEd Maste {
57410ff414cSEd Maste if (claim_bytes(4, source_size, &result)) {
57510ff414cSEd Maste callbacks->float4(context, _cbor_load_float(source + 1));
57610ff414cSEd Maste }
57710ff414cSEd Maste return result;
57810ff414cSEd Maste }
57910ff414cSEd Maste case 0xFB:
58010ff414cSEd Maste /* 8B float */
58110ff414cSEd Maste {
58210ff414cSEd Maste if (claim_bytes(8, source_size, &result)) {
58310ff414cSEd Maste callbacks->float8(context, _cbor_load_double(source + 1));
58410ff414cSEd Maste }
58510ff414cSEd Maste return result;
58610ff414cSEd Maste }
58710ff414cSEd Maste case 0xFC: /* Fallthrough */
58810ff414cSEd Maste case 0xFD: /* Fallthrough */
58910ff414cSEd Maste case 0xFE:
59010ff414cSEd Maste /* Reserved */
5915d3e7166SEd Maste { return (struct cbor_decoder_result){.status = CBOR_DECODER_ERROR}; }
59210ff414cSEd Maste case 0xFF:
59310ff414cSEd Maste /* Break */
59410ff414cSEd Maste callbacks->indef_break(context);
5955d3e7166SEd Maste // Never happens, the switch statement is exhaustive on the 1B range; make
5965d3e7166SEd Maste // compiler happy
5975d3e7166SEd Maste default:
59810ff414cSEd Maste return result;
59910ff414cSEd Maste }
60010ff414cSEd Maste }
601