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 "builder_callbacks.h" 95d3e7166SEd Maste 1010ff414cSEd Maste #include <string.h> 115d3e7166SEd Maste 1210ff414cSEd Maste #include "../arrays.h" 1310ff414cSEd Maste #include "../bytestrings.h" 145d3e7166SEd Maste #include "../common.h" 1510ff414cSEd Maste #include "../floats_ctrls.h" 1610ff414cSEd Maste #include "../ints.h" 1710ff414cSEd Maste #include "../maps.h" 1810ff414cSEd Maste #include "../strings.h" 1910ff414cSEd Maste #include "../tags.h" 2010ff414cSEd Maste #include "unicode.h" 2110ff414cSEd Maste 225d3e7166SEd Maste // `_cbor_builder_append` takes ownership of `item`. If adding the item to 235d3e7166SEd Maste // parent container fails, `item` will be deallocated to prevent memory. 2410ff414cSEd Maste void _cbor_builder_append(cbor_item_t *item, 2510ff414cSEd Maste struct _cbor_decoder_context *ctx) { 2610ff414cSEd Maste if (ctx->stack->size == 0) { 2710ff414cSEd Maste /* Top level item */ 2810ff414cSEd Maste ctx->root = item; 295d3e7166SEd Maste return; 305d3e7166SEd Maste } 3110ff414cSEd Maste /* Part of a bigger structure */ 3210ff414cSEd Maste switch (ctx->stack->top->item->type) { 335d3e7166SEd Maste // Handle Arrays and Maps since they can contain subitems of any type. 345d3e7166SEd Maste // Byte/string construction from chunks is handled in the respective chunk 355d3e7166SEd Maste // handlers. 3610ff414cSEd Maste case CBOR_TYPE_ARRAY: { 3710ff414cSEd Maste if (cbor_array_is_definite(ctx->stack->top->item)) { 385d3e7166SEd Maste // We don't need an explicit check for whether the item still belongs 395d3e7166SEd Maste // into this array because if there are extra items, they will cause a 405d3e7166SEd Maste // syntax error when decoded. 415d3e7166SEd Maste CBOR_ASSERT(ctx->stack->top->subitems > 0); 425d3e7166SEd Maste // This should never happen since the definite array should be 435d3e7166SEd Maste // preallocated for the expected number of items. 445d3e7166SEd Maste if (!cbor_array_push(ctx->stack->top->item, item)) { 455d3e7166SEd Maste ctx->creation_failed = true; 465d3e7166SEd Maste cbor_decref(&item); 475d3e7166SEd Maste break; 4810ff414cSEd Maste } 4910ff414cSEd Maste cbor_decref(&item); 505d3e7166SEd Maste ctx->stack->top->subitems--; 515d3e7166SEd Maste if (ctx->stack->top->subitems == 0) { 525d3e7166SEd Maste cbor_item_t *stack_item = ctx->stack->top->item; 535d3e7166SEd Maste _cbor_stack_pop(ctx->stack); 545d3e7166SEd Maste _cbor_builder_append(stack_item, ctx); 555d3e7166SEd Maste } 5610ff414cSEd Maste } else { 5710ff414cSEd Maste /* Indefinite array, don't bother with subitems */ 585d3e7166SEd Maste if (!cbor_array_push(ctx->stack->top->item, item)) { 595d3e7166SEd Maste ctx->creation_failed = true; 605d3e7166SEd Maste } 6110ff414cSEd Maste cbor_decref(&item); 6210ff414cSEd Maste } 6310ff414cSEd Maste break; 6410ff414cSEd Maste } 6510ff414cSEd Maste case CBOR_TYPE_MAP: { 665d3e7166SEd Maste // Handle both definite and indefinite maps the same initially. 675d3e7166SEd Maste // Note: We use 0 and 1 subitems to distinguish between keys and values in 685d3e7166SEd Maste // indefinite items 6910ff414cSEd Maste if (ctx->stack->top->subitems % 2) { 70*abd87254SEd Maste // Odd record, this is a value. 71*abd87254SEd Maste ctx->creation_failed = 72*abd87254SEd Maste !_cbor_map_add_value(ctx->stack->top->item, item); 73*abd87254SEd Maste // Adding a value never fails since the memory is allocated when the 74*abd87254SEd Maste // key is added 75*abd87254SEd Maste CBOR_ASSERT(!ctx->creation_failed); 7610ff414cSEd Maste } else { 77*abd87254SEd Maste // Even record, this is a key. 785d3e7166SEd Maste if (!_cbor_map_add_key(ctx->stack->top->item, item)) { 795d3e7166SEd Maste ctx->creation_failed = true; 805d3e7166SEd Maste cbor_decref(&item); 815d3e7166SEd Maste break; 8210ff414cSEd Maste } 835d3e7166SEd Maste } 845d3e7166SEd Maste cbor_decref(&item); 8510ff414cSEd Maste if (cbor_map_is_definite(ctx->stack->top->item)) { 865d3e7166SEd Maste CBOR_ASSERT(ctx->stack->top->subitems > 0); 8710ff414cSEd Maste ctx->stack->top->subitems--; 8810ff414cSEd Maste if (ctx->stack->top->subitems == 0) { 895d3e7166SEd Maste cbor_item_t *map_entry = ctx->stack->top->item; 9010ff414cSEd Maste _cbor_stack_pop(ctx->stack); 915d3e7166SEd Maste _cbor_builder_append(map_entry, ctx); 9210ff414cSEd Maste } 9310ff414cSEd Maste } else { 9410ff414cSEd Maste ctx->stack->top->subitems ^= 9510ff414cSEd Maste 1; /* Flip the indicator for indefinite items */ 9610ff414cSEd Maste } 9710ff414cSEd Maste break; 9810ff414cSEd Maste } 9910ff414cSEd Maste case CBOR_TYPE_TAG: { 1005d3e7166SEd Maste CBOR_ASSERT(ctx->stack->top->subitems == 1); 10110ff414cSEd Maste cbor_tag_set_item(ctx->stack->top->item, item); 10210ff414cSEd Maste cbor_decref(&item); /* Give up on our reference */ 1035d3e7166SEd Maste cbor_item_t *tagged_item = ctx->stack->top->item; 10410ff414cSEd Maste _cbor_stack_pop(ctx->stack); 1055d3e7166SEd Maste _cbor_builder_append(tagged_item, ctx); 10610ff414cSEd Maste break; 10710ff414cSEd Maste } 1085d3e7166SEd Maste // We have an item to append but nothing to append it to. 10910ff414cSEd Maste default: { 11010ff414cSEd Maste cbor_decref(&item); 11110ff414cSEd Maste ctx->syntax_error = true; 11210ff414cSEd Maste } 11310ff414cSEd Maste } 11410ff414cSEd Maste } 11510ff414cSEd Maste 11610ff414cSEd Maste #define CHECK_RES(ctx, res) \ 11710ff414cSEd Maste do { \ 11810ff414cSEd Maste if (res == NULL) { \ 11910ff414cSEd Maste ctx->creation_failed = true; \ 12010ff414cSEd Maste return; \ 12110ff414cSEd Maste } \ 12210ff414cSEd Maste } while (0) 12310ff414cSEd Maste 1245d3e7166SEd Maste // Check that the length fits into size_t. If not, we cannot possibly allocate 1255d3e7166SEd Maste // the required memory and should fail fast. 1265d3e7166SEd Maste #define CHECK_LENGTH(ctx, length) \ 1275d3e7166SEd Maste do { \ 1285d3e7166SEd Maste if (length > SIZE_MAX) { \ 1295d3e7166SEd Maste ctx->creation_failed = true; \ 1305d3e7166SEd Maste return; \ 1315d3e7166SEd Maste } \ 1325d3e7166SEd Maste } while (0) 1335d3e7166SEd Maste 13410ff414cSEd Maste #define PUSH_CTX_STACK(ctx, res, subitems) \ 13510ff414cSEd Maste do { \ 13610ff414cSEd Maste if (_cbor_stack_push(ctx->stack, res, subitems) == NULL) { \ 13710ff414cSEd Maste cbor_decref(&res); \ 13810ff414cSEd Maste ctx->creation_failed = true; \ 13910ff414cSEd Maste } \ 14010ff414cSEd Maste } while (0) 14110ff414cSEd Maste 14210ff414cSEd Maste void cbor_builder_uint8_callback(void *context, uint8_t value) { 14310ff414cSEd Maste struct _cbor_decoder_context *ctx = context; 14410ff414cSEd Maste cbor_item_t *res = cbor_new_int8(); 14510ff414cSEd Maste CHECK_RES(ctx, res); 14610ff414cSEd Maste cbor_mark_uint(res); 14710ff414cSEd Maste cbor_set_uint8(res, value); 14810ff414cSEd Maste _cbor_builder_append(res, ctx); 14910ff414cSEd Maste } 15010ff414cSEd Maste 15110ff414cSEd Maste void cbor_builder_uint16_callback(void *context, uint16_t value) { 15210ff414cSEd Maste struct _cbor_decoder_context *ctx = context; 15310ff414cSEd Maste cbor_item_t *res = cbor_new_int16(); 15410ff414cSEd Maste CHECK_RES(ctx, res); 15510ff414cSEd Maste cbor_mark_uint(res); 15610ff414cSEd Maste cbor_set_uint16(res, value); 15710ff414cSEd Maste _cbor_builder_append(res, ctx); 15810ff414cSEd Maste } 15910ff414cSEd Maste 16010ff414cSEd Maste void cbor_builder_uint32_callback(void *context, uint32_t value) { 16110ff414cSEd Maste struct _cbor_decoder_context *ctx = context; 16210ff414cSEd Maste cbor_item_t *res = cbor_new_int32(); 16310ff414cSEd Maste CHECK_RES(ctx, res); 16410ff414cSEd Maste cbor_mark_uint(res); 16510ff414cSEd Maste cbor_set_uint32(res, value); 16610ff414cSEd Maste _cbor_builder_append(res, ctx); 16710ff414cSEd Maste } 16810ff414cSEd Maste 16910ff414cSEd Maste void cbor_builder_uint64_callback(void *context, uint64_t value) { 17010ff414cSEd Maste struct _cbor_decoder_context *ctx = context; 17110ff414cSEd Maste cbor_item_t *res = cbor_new_int64(); 17210ff414cSEd Maste CHECK_RES(ctx, res); 17310ff414cSEd Maste cbor_mark_uint(res); 17410ff414cSEd Maste cbor_set_uint64(res, value); 17510ff414cSEd Maste _cbor_builder_append(res, ctx); 17610ff414cSEd Maste } 17710ff414cSEd Maste 17810ff414cSEd Maste void cbor_builder_negint8_callback(void *context, uint8_t value) { 17910ff414cSEd Maste struct _cbor_decoder_context *ctx = context; 18010ff414cSEd Maste cbor_item_t *res = cbor_new_int8(); 18110ff414cSEd Maste CHECK_RES(ctx, res); 18210ff414cSEd Maste cbor_mark_negint(res); 18310ff414cSEd Maste cbor_set_uint8(res, value); 18410ff414cSEd Maste _cbor_builder_append(res, ctx); 18510ff414cSEd Maste } 18610ff414cSEd Maste 18710ff414cSEd Maste void cbor_builder_negint16_callback(void *context, uint16_t value) { 18810ff414cSEd Maste struct _cbor_decoder_context *ctx = context; 18910ff414cSEd Maste cbor_item_t *res = cbor_new_int16(); 1905d3e7166SEd Maste CHECK_RES(ctx, res); 19110ff414cSEd Maste cbor_mark_negint(res); 19210ff414cSEd Maste cbor_set_uint16(res, value); 19310ff414cSEd Maste _cbor_builder_append(res, ctx); 19410ff414cSEd Maste } 19510ff414cSEd Maste 19610ff414cSEd Maste void cbor_builder_negint32_callback(void *context, uint32_t value) { 19710ff414cSEd Maste struct _cbor_decoder_context *ctx = context; 19810ff414cSEd Maste cbor_item_t *res = cbor_new_int32(); 19910ff414cSEd Maste CHECK_RES(ctx, res); 20010ff414cSEd Maste cbor_mark_negint(res); 20110ff414cSEd Maste cbor_set_uint32(res, value); 20210ff414cSEd Maste _cbor_builder_append(res, ctx); 20310ff414cSEd Maste } 20410ff414cSEd Maste 20510ff414cSEd Maste void cbor_builder_negint64_callback(void *context, uint64_t value) { 20610ff414cSEd Maste struct _cbor_decoder_context *ctx = context; 20710ff414cSEd Maste cbor_item_t *res = cbor_new_int64(); 20810ff414cSEd Maste CHECK_RES(ctx, res); 20910ff414cSEd Maste cbor_mark_negint(res); 21010ff414cSEd Maste cbor_set_uint64(res, value); 21110ff414cSEd Maste _cbor_builder_append(res, ctx); 21210ff414cSEd Maste } 21310ff414cSEd Maste 21410ff414cSEd Maste void cbor_builder_byte_string_callback(void *context, cbor_data data, 2155d3e7166SEd Maste uint64_t length) { 21610ff414cSEd Maste struct _cbor_decoder_context *ctx = context; 2175d3e7166SEd Maste CHECK_LENGTH(ctx, length); 2185d3e7166SEd Maste unsigned char *new_handle = _cbor_malloc(length); 21910ff414cSEd Maste if (new_handle == NULL) { 22010ff414cSEd Maste ctx->creation_failed = true; 22110ff414cSEd Maste return; 22210ff414cSEd Maste } 22310ff414cSEd Maste 22410ff414cSEd Maste memcpy(new_handle, data, length); 2255d3e7166SEd Maste cbor_item_t *new_chunk = cbor_new_definite_bytestring(); 22610ff414cSEd Maste 2275d3e7166SEd Maste if (new_chunk == NULL) { 2285d3e7166SEd Maste _cbor_free(new_handle); 22910ff414cSEd Maste ctx->creation_failed = true; 23010ff414cSEd Maste return; 23110ff414cSEd Maste } 23210ff414cSEd Maste 2335d3e7166SEd Maste cbor_bytestring_set_handle(new_chunk, new_handle, length); 23410ff414cSEd Maste 2355d3e7166SEd Maste // If an indef bytestring is on the stack, extend it (if it were closed, it 2365d3e7166SEd Maste // would have been popped). Handle any syntax errors upstream. 2375d3e7166SEd Maste if (ctx->stack->size > 0 && cbor_isa_bytestring(ctx->stack->top->item) && 2385d3e7166SEd Maste cbor_bytestring_is_indefinite(ctx->stack->top->item)) { 2395d3e7166SEd Maste if (!cbor_bytestring_add_chunk(ctx->stack->top->item, new_chunk)) { 2405d3e7166SEd Maste ctx->creation_failed = true; 24110ff414cSEd Maste } 2425d3e7166SEd Maste cbor_decref(&new_chunk); 24310ff414cSEd Maste } else { 2445d3e7166SEd Maste _cbor_builder_append(new_chunk, ctx); 24510ff414cSEd Maste } 24610ff414cSEd Maste } 24710ff414cSEd Maste 24810ff414cSEd Maste void cbor_builder_byte_string_start_callback(void *context) { 24910ff414cSEd Maste struct _cbor_decoder_context *ctx = context; 25010ff414cSEd Maste cbor_item_t *res = cbor_new_indefinite_bytestring(); 25110ff414cSEd Maste CHECK_RES(ctx, res); 25210ff414cSEd Maste PUSH_CTX_STACK(ctx, res, 0); 25310ff414cSEd Maste } 25410ff414cSEd Maste 25510ff414cSEd Maste void cbor_builder_string_callback(void *context, cbor_data data, 2565d3e7166SEd Maste uint64_t length) { 25710ff414cSEd Maste struct _cbor_decoder_context *ctx = context; 2585d3e7166SEd Maste CHECK_LENGTH(ctx, length); 25910ff414cSEd Maste 2605d3e7166SEd Maste unsigned char *new_handle = _cbor_malloc(length); 26110ff414cSEd Maste if (new_handle == NULL) { 26210ff414cSEd Maste ctx->creation_failed = true; 26310ff414cSEd Maste return; 26410ff414cSEd Maste } 26510ff414cSEd Maste 26610ff414cSEd Maste memcpy(new_handle, data, length); 2675d3e7166SEd Maste cbor_item_t *new_chunk = cbor_new_definite_string(); 2685d3e7166SEd Maste if (new_chunk == NULL) { 2695d3e7166SEd Maste _cbor_free(new_handle); 27010ff414cSEd Maste ctx->creation_failed = true; 27110ff414cSEd Maste return; 27210ff414cSEd Maste } 2735d3e7166SEd Maste cbor_string_set_handle(new_chunk, new_handle, length); 27410ff414cSEd Maste 2755d3e7166SEd Maste // If an indef string is on the stack, extend it (if it were closed, it would 2765d3e7166SEd Maste // have been popped). Handle any syntax errors upstream. 2775d3e7166SEd Maste if (ctx->stack->size > 0 && cbor_isa_string(ctx->stack->top->item) && 2785d3e7166SEd Maste cbor_string_is_indefinite(ctx->stack->top->item)) { 2795d3e7166SEd Maste if (!cbor_string_add_chunk(ctx->stack->top->item, new_chunk)) { 2805d3e7166SEd Maste ctx->creation_failed = true; 28110ff414cSEd Maste } 2825d3e7166SEd Maste cbor_decref(&new_chunk); 28310ff414cSEd Maste } else { 2845d3e7166SEd Maste _cbor_builder_append(new_chunk, ctx); 28510ff414cSEd Maste } 28610ff414cSEd Maste } 28710ff414cSEd Maste 28810ff414cSEd Maste void cbor_builder_string_start_callback(void *context) { 28910ff414cSEd Maste struct _cbor_decoder_context *ctx = context; 29010ff414cSEd Maste cbor_item_t *res = cbor_new_indefinite_string(); 29110ff414cSEd Maste CHECK_RES(ctx, res); 29210ff414cSEd Maste PUSH_CTX_STACK(ctx, res, 0); 29310ff414cSEd Maste } 29410ff414cSEd Maste 2955d3e7166SEd Maste void cbor_builder_array_start_callback(void *context, uint64_t size) { 29610ff414cSEd Maste struct _cbor_decoder_context *ctx = context; 2975d3e7166SEd Maste CHECK_LENGTH(ctx, size); 29810ff414cSEd Maste cbor_item_t *res = cbor_new_definite_array(size); 29910ff414cSEd Maste CHECK_RES(ctx, res); 30010ff414cSEd Maste if (size > 0) { 30110ff414cSEd Maste PUSH_CTX_STACK(ctx, res, size); 30210ff414cSEd Maste } else { 30310ff414cSEd Maste _cbor_builder_append(res, ctx); 30410ff414cSEd Maste } 30510ff414cSEd Maste } 30610ff414cSEd Maste 30710ff414cSEd Maste void cbor_builder_indef_array_start_callback(void *context) { 30810ff414cSEd Maste struct _cbor_decoder_context *ctx = context; 30910ff414cSEd Maste cbor_item_t *res = cbor_new_indefinite_array(); 31010ff414cSEd Maste CHECK_RES(ctx, res); 31110ff414cSEd Maste PUSH_CTX_STACK(ctx, res, 0); 31210ff414cSEd Maste } 31310ff414cSEd Maste 31410ff414cSEd Maste void cbor_builder_indef_map_start_callback(void *context) { 31510ff414cSEd Maste struct _cbor_decoder_context *ctx = context; 31610ff414cSEd Maste cbor_item_t *res = cbor_new_indefinite_map(); 31710ff414cSEd Maste CHECK_RES(ctx, res); 31810ff414cSEd Maste PUSH_CTX_STACK(ctx, res, 0); 31910ff414cSEd Maste } 32010ff414cSEd Maste 3215d3e7166SEd Maste void cbor_builder_map_start_callback(void *context, uint64_t size) { 32210ff414cSEd Maste struct _cbor_decoder_context *ctx = context; 3235d3e7166SEd Maste CHECK_LENGTH(ctx, size); 32410ff414cSEd Maste cbor_item_t *res = cbor_new_definite_map(size); 32510ff414cSEd Maste CHECK_RES(ctx, res); 32610ff414cSEd Maste if (size > 0) { 32710ff414cSEd Maste PUSH_CTX_STACK(ctx, res, size * 2); 32810ff414cSEd Maste } else { 32910ff414cSEd Maste _cbor_builder_append(res, ctx); 33010ff414cSEd Maste } 33110ff414cSEd Maste } 33210ff414cSEd Maste 33310ff414cSEd Maste /** 33410ff414cSEd Maste * Is the (partially constructed) item indefinite? 33510ff414cSEd Maste */ 33610ff414cSEd Maste bool _cbor_is_indefinite(cbor_item_t *item) { 33710ff414cSEd Maste switch (item->type) { 33810ff414cSEd Maste case CBOR_TYPE_BYTESTRING: 3395d3e7166SEd Maste return cbor_bytestring_is_indefinite(item); 34010ff414cSEd Maste case CBOR_TYPE_STRING: 3415d3e7166SEd Maste return cbor_string_is_indefinite(item); 34210ff414cSEd Maste case CBOR_TYPE_ARRAY: 3435d3e7166SEd Maste return cbor_array_is_indefinite(item); 34410ff414cSEd Maste case CBOR_TYPE_MAP: 3455d3e7166SEd Maste return cbor_map_is_indefinite(item); 34610ff414cSEd Maste default: 347*abd87254SEd Maste // Should never happen since a non-nested item cannot be on top of the 348*abd87254SEd Maste // stack. 34910ff414cSEd Maste return false; 35010ff414cSEd Maste } 35110ff414cSEd Maste } 35210ff414cSEd Maste 35310ff414cSEd Maste void cbor_builder_indef_break_callback(void *context) { 35410ff414cSEd Maste struct _cbor_decoder_context *ctx = context; 35510ff414cSEd Maste /* There must be an item to break out of*/ 35610ff414cSEd Maste if (ctx->stack->size > 0) { 35710ff414cSEd Maste cbor_item_t *item = ctx->stack->top->item; 35810ff414cSEd Maste if (_cbor_is_indefinite( 35910ff414cSEd Maste item) && /* Only indefinite items can be terminated by 0xFF */ 36010ff414cSEd Maste /* Special case: we cannot append up if an indefinite map is incomplete 36110ff414cSEd Maste (we are expecting a value). */ 36210ff414cSEd Maste (item->type != CBOR_TYPE_MAP || ctx->stack->top->subitems % 2 == 0)) { 36310ff414cSEd Maste _cbor_stack_pop(ctx->stack); 36410ff414cSEd Maste _cbor_builder_append(item, ctx); 36510ff414cSEd Maste return; 36610ff414cSEd Maste } 36710ff414cSEd Maste } 36810ff414cSEd Maste 36910ff414cSEd Maste ctx->syntax_error = true; 37010ff414cSEd Maste } 37110ff414cSEd Maste 37210ff414cSEd Maste void cbor_builder_float2_callback(void *context, float value) { 37310ff414cSEd Maste struct _cbor_decoder_context *ctx = context; 37410ff414cSEd Maste cbor_item_t *res = cbor_new_float2(); 3755d3e7166SEd Maste CHECK_RES(ctx, res); 37610ff414cSEd Maste cbor_set_float2(res, value); 37710ff414cSEd Maste _cbor_builder_append(res, ctx); 37810ff414cSEd Maste } 37910ff414cSEd Maste 38010ff414cSEd Maste void cbor_builder_float4_callback(void *context, float value) { 38110ff414cSEd Maste struct _cbor_decoder_context *ctx = context; 38210ff414cSEd Maste cbor_item_t *res = cbor_new_float4(); 38310ff414cSEd Maste CHECK_RES(ctx, res); 38410ff414cSEd Maste cbor_set_float4(res, value); 38510ff414cSEd Maste _cbor_builder_append(res, ctx); 38610ff414cSEd Maste } 38710ff414cSEd Maste 38810ff414cSEd Maste void cbor_builder_float8_callback(void *context, double value) { 38910ff414cSEd Maste struct _cbor_decoder_context *ctx = context; 39010ff414cSEd Maste cbor_item_t *res = cbor_new_float8(); 39110ff414cSEd Maste CHECK_RES(ctx, res); 39210ff414cSEd Maste cbor_set_float8(res, value); 39310ff414cSEd Maste _cbor_builder_append(res, ctx); 39410ff414cSEd Maste } 39510ff414cSEd Maste 39610ff414cSEd Maste void cbor_builder_null_callback(void *context) { 39710ff414cSEd Maste struct _cbor_decoder_context *ctx = context; 39810ff414cSEd Maste cbor_item_t *res = cbor_new_null(); 39910ff414cSEd Maste CHECK_RES(ctx, res); 40010ff414cSEd Maste _cbor_builder_append(res, ctx); 40110ff414cSEd Maste } 40210ff414cSEd Maste 40310ff414cSEd Maste void cbor_builder_undefined_callback(void *context) { 40410ff414cSEd Maste struct _cbor_decoder_context *ctx = context; 40510ff414cSEd Maste cbor_item_t *res = cbor_new_undef(); 40610ff414cSEd Maste CHECK_RES(ctx, res); 40710ff414cSEd Maste _cbor_builder_append(res, ctx); 40810ff414cSEd Maste } 40910ff414cSEd Maste 41010ff414cSEd Maste void cbor_builder_boolean_callback(void *context, bool value) { 41110ff414cSEd Maste struct _cbor_decoder_context *ctx = context; 41210ff414cSEd Maste cbor_item_t *res = cbor_build_bool(value); 41310ff414cSEd Maste CHECK_RES(ctx, res); 41410ff414cSEd Maste _cbor_builder_append(res, ctx); 41510ff414cSEd Maste } 41610ff414cSEd Maste 41710ff414cSEd Maste void cbor_builder_tag_callback(void *context, uint64_t value) { 41810ff414cSEd Maste struct _cbor_decoder_context *ctx = context; 41910ff414cSEd Maste cbor_item_t *res = cbor_new_tag(value); 42010ff414cSEd Maste CHECK_RES(ctx, res); 42110ff414cSEd Maste PUSH_CTX_STACK(ctx, res, 1); 42210ff414cSEd Maste } 423