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