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.
_cbor_builder_append(cbor_item_t * item,struct _cbor_decoder_context * ctx)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
cbor_builder_uint8_callback(void * context,uint8_t value)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
cbor_builder_uint16_callback(void * context,uint16_t value)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
cbor_builder_uint32_callback(void * context,uint32_t value)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
cbor_builder_uint64_callback(void * context,uint64_t value)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
cbor_builder_negint8_callback(void * context,uint8_t value)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
cbor_builder_negint16_callback(void * context,uint16_t value)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
cbor_builder_negint32_callback(void * context,uint32_t value)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
cbor_builder_negint64_callback(void * context,uint64_t value)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
cbor_builder_byte_string_callback(void * context,cbor_data data,uint64_t length)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
cbor_builder_byte_string_start_callback(void * context)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
cbor_builder_string_callback(void * context,cbor_data data,uint64_t length)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
cbor_builder_string_start_callback(void * context)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
cbor_builder_array_start_callback(void * context,uint64_t size)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
cbor_builder_indef_array_start_callback(void * context)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
cbor_builder_indef_map_start_callback(void * context)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
cbor_builder_map_start_callback(void * context,uint64_t size)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 */
_cbor_is_indefinite(cbor_item_t * item)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
cbor_builder_indef_break_callback(void * context)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
cbor_builder_float2_callback(void * context,float value)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
cbor_builder_float4_callback(void * context,float value)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
cbor_builder_float8_callback(void * context,double value)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
cbor_builder_null_callback(void * context)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
cbor_builder_undefined_callback(void * context)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
cbor_builder_boolean_callback(void * context,bool value)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
cbor_builder_tag_callback(void * context,uint64_t value)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