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 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 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