xref: /freebsd/contrib/libcbor/src/cbor/streaming.c (revision abd87254)
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