xref: /freebsd/contrib/libcbor/src/cbor/common.c (revision 5d3e7166f6a0187fa3f8831b16a06bd9955c21ff)
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 "cbor/common.h"
910ff414cSEd Maste #include "arrays.h"
1010ff414cSEd Maste #include "bytestrings.h"
1110ff414cSEd Maste #include "data.h"
1210ff414cSEd Maste #include "floats_ctrls.h"
1310ff414cSEd Maste #include "ints.h"
1410ff414cSEd Maste #include "maps.h"
1510ff414cSEd Maste #include "strings.h"
1610ff414cSEd Maste #include "tags.h"
1710ff414cSEd Maste 
18*5d3e7166SEd Maste #ifdef DEBUG
19*5d3e7166SEd Maste bool _cbor_enable_assert = true;
20*5d3e7166SEd Maste #endif
21*5d3e7166SEd Maste 
cbor_isa_uint(const cbor_item_t * item)2210ff414cSEd Maste bool cbor_isa_uint(const cbor_item_t *item) {
2310ff414cSEd Maste   return item->type == CBOR_TYPE_UINT;
2410ff414cSEd Maste }
2510ff414cSEd Maste 
cbor_isa_negint(const cbor_item_t * item)2610ff414cSEd Maste bool cbor_isa_negint(const cbor_item_t *item) {
2710ff414cSEd Maste   return item->type == CBOR_TYPE_NEGINT;
2810ff414cSEd Maste }
2910ff414cSEd Maste 
cbor_isa_bytestring(const cbor_item_t * item)3010ff414cSEd Maste bool cbor_isa_bytestring(const cbor_item_t *item) {
3110ff414cSEd Maste   return item->type == CBOR_TYPE_BYTESTRING;
3210ff414cSEd Maste }
3310ff414cSEd Maste 
cbor_isa_string(const cbor_item_t * item)3410ff414cSEd Maste bool cbor_isa_string(const cbor_item_t *item) {
3510ff414cSEd Maste   return item->type == CBOR_TYPE_STRING;
3610ff414cSEd Maste }
3710ff414cSEd Maste 
cbor_isa_array(const cbor_item_t * item)3810ff414cSEd Maste bool cbor_isa_array(const cbor_item_t *item) {
3910ff414cSEd Maste   return item->type == CBOR_TYPE_ARRAY;
4010ff414cSEd Maste }
4110ff414cSEd Maste 
cbor_isa_map(const cbor_item_t * item)4210ff414cSEd Maste bool cbor_isa_map(const cbor_item_t *item) {
4310ff414cSEd Maste   return item->type == CBOR_TYPE_MAP;
4410ff414cSEd Maste }
4510ff414cSEd Maste 
cbor_isa_tag(const cbor_item_t * item)4610ff414cSEd Maste bool cbor_isa_tag(const cbor_item_t *item) {
4710ff414cSEd Maste   return item->type == CBOR_TYPE_TAG;
4810ff414cSEd Maste }
4910ff414cSEd Maste 
cbor_isa_float_ctrl(const cbor_item_t * item)5010ff414cSEd Maste bool cbor_isa_float_ctrl(const cbor_item_t *item) {
5110ff414cSEd Maste   return item->type == CBOR_TYPE_FLOAT_CTRL;
5210ff414cSEd Maste }
5310ff414cSEd Maste 
cbor_typeof(const cbor_item_t * item)5410ff414cSEd Maste cbor_type cbor_typeof(const cbor_item_t *item) { return item->type; }
5510ff414cSEd Maste 
cbor_is_int(const cbor_item_t * item)5610ff414cSEd Maste bool cbor_is_int(const cbor_item_t *item) {
5710ff414cSEd Maste   return cbor_isa_uint(item) || cbor_isa_negint(item);
5810ff414cSEd Maste }
5910ff414cSEd Maste 
cbor_is_bool(const cbor_item_t * item)6010ff414cSEd Maste bool cbor_is_bool(const cbor_item_t *item) {
6110ff414cSEd Maste   return cbor_isa_float_ctrl(item) &&
6210ff414cSEd Maste          (cbor_ctrl_value(item) == CBOR_CTRL_FALSE ||
6310ff414cSEd Maste           cbor_ctrl_value(item) == CBOR_CTRL_TRUE);
6410ff414cSEd Maste }
6510ff414cSEd Maste 
cbor_is_null(const cbor_item_t * item)6610ff414cSEd Maste bool cbor_is_null(const cbor_item_t *item) {
6710ff414cSEd Maste   return cbor_isa_float_ctrl(item) && cbor_ctrl_value(item) == CBOR_CTRL_NULL;
6810ff414cSEd Maste }
6910ff414cSEd Maste 
cbor_is_undef(const cbor_item_t * item)7010ff414cSEd Maste bool cbor_is_undef(const cbor_item_t *item) {
7110ff414cSEd Maste   return cbor_isa_float_ctrl(item) && cbor_ctrl_value(item) == CBOR_CTRL_UNDEF;
7210ff414cSEd Maste }
7310ff414cSEd Maste 
cbor_is_float(const cbor_item_t * item)7410ff414cSEd Maste bool cbor_is_float(const cbor_item_t *item) {
7510ff414cSEd Maste   return cbor_isa_float_ctrl(item) && !cbor_float_ctrl_is_ctrl(item);
7610ff414cSEd Maste }
7710ff414cSEd Maste 
cbor_incref(cbor_item_t * item)7810ff414cSEd Maste cbor_item_t *cbor_incref(cbor_item_t *item) {
7910ff414cSEd Maste   item->refcount++;
8010ff414cSEd Maste   return item;
8110ff414cSEd Maste }
8210ff414cSEd Maste 
cbor_decref(cbor_item_t ** item_ref)8310ff414cSEd Maste void cbor_decref(cbor_item_t **item_ref) {
8410ff414cSEd Maste   cbor_item_t *item = *item_ref;
85*5d3e7166SEd Maste   CBOR_ASSERT(item->refcount > 0);
8610ff414cSEd Maste   if (--item->refcount == 0) {
8710ff414cSEd Maste     switch (item->type) {
8810ff414cSEd Maste       case CBOR_TYPE_UINT:
8910ff414cSEd Maste         /* Fallthrough */
9010ff414cSEd Maste       case CBOR_TYPE_NEGINT:
9110ff414cSEd Maste         /* Combined allocation, freeing the item suffices */
9210ff414cSEd Maste         { break; }
9310ff414cSEd Maste       case CBOR_TYPE_BYTESTRING: {
9410ff414cSEd Maste         if (cbor_bytestring_is_definite(item)) {
95*5d3e7166SEd Maste           _cbor_free(item->data);
9610ff414cSEd Maste         } else {
9710ff414cSEd Maste           /* We need to decref all chunks */
9810ff414cSEd Maste           cbor_item_t **handle = cbor_bytestring_chunks_handle(item);
9910ff414cSEd Maste           for (size_t i = 0; i < cbor_bytestring_chunk_count(item); i++)
10010ff414cSEd Maste             cbor_decref(&handle[i]);
101*5d3e7166SEd Maste           _cbor_free(
10210ff414cSEd Maste               ((struct cbor_indefinite_string_data *)item->data)->chunks);
103*5d3e7166SEd Maste           _cbor_free(item->data);
10410ff414cSEd Maste         }
10510ff414cSEd Maste         break;
10610ff414cSEd Maste       }
10710ff414cSEd Maste       case CBOR_TYPE_STRING: {
10810ff414cSEd Maste         if (cbor_string_is_definite(item)) {
109*5d3e7166SEd Maste           _cbor_free(item->data);
11010ff414cSEd Maste         } else {
11110ff414cSEd Maste           /* We need to decref all chunks */
11210ff414cSEd Maste           cbor_item_t **handle = cbor_string_chunks_handle(item);
11310ff414cSEd Maste           for (size_t i = 0; i < cbor_string_chunk_count(item); i++)
11410ff414cSEd Maste             cbor_decref(&handle[i]);
115*5d3e7166SEd Maste           _cbor_free(
11610ff414cSEd Maste               ((struct cbor_indefinite_string_data *)item->data)->chunks);
117*5d3e7166SEd Maste           _cbor_free(item->data);
11810ff414cSEd Maste         }
11910ff414cSEd Maste         break;
12010ff414cSEd Maste       }
12110ff414cSEd Maste       case CBOR_TYPE_ARRAY: {
12210ff414cSEd Maste         /* Get all items and decref them */
12310ff414cSEd Maste         cbor_item_t **handle = cbor_array_handle(item);
12410ff414cSEd Maste         size_t size = cbor_array_size(item);
12510ff414cSEd Maste         for (size_t i = 0; i < size; i++)
12610ff414cSEd Maste           if (handle[i] != NULL) cbor_decref(&handle[i]);
127*5d3e7166SEd Maste         _cbor_free(item->data);
12810ff414cSEd Maste         break;
12910ff414cSEd Maste       }
13010ff414cSEd Maste       case CBOR_TYPE_MAP: {
13110ff414cSEd Maste         struct cbor_pair *handle = cbor_map_handle(item);
13210ff414cSEd Maste         for (size_t i = 0; i < item->metadata.map_metadata.end_ptr;
13310ff414cSEd Maste              i++, handle++) {
13410ff414cSEd Maste           cbor_decref(&handle->key);
13510ff414cSEd Maste           if (handle->value != NULL) cbor_decref(&handle->value);
13610ff414cSEd Maste         }
137*5d3e7166SEd Maste         _cbor_free(item->data);
13810ff414cSEd Maste         break;
139*5d3e7166SEd Maste       }
14010ff414cSEd Maste       case CBOR_TYPE_TAG: {
14110ff414cSEd Maste         if (item->metadata.tag_metadata.tagged_item != NULL)
14210ff414cSEd Maste           cbor_decref(&item->metadata.tag_metadata.tagged_item);
143*5d3e7166SEd Maste         _cbor_free(item->data);
14410ff414cSEd Maste         break;
14510ff414cSEd Maste       }
14610ff414cSEd Maste       case CBOR_TYPE_FLOAT_CTRL: {
14710ff414cSEd Maste         /* Floats have combined allocation */
14810ff414cSEd Maste         break;
14910ff414cSEd Maste       }
15010ff414cSEd Maste     }
151*5d3e7166SEd Maste     _cbor_free(item);
15210ff414cSEd Maste     *item_ref = NULL;
15310ff414cSEd Maste   }
15410ff414cSEd Maste }
15510ff414cSEd Maste 
cbor_intermediate_decref(cbor_item_t * item)15610ff414cSEd Maste void cbor_intermediate_decref(cbor_item_t *item) { cbor_decref(&item); }
15710ff414cSEd Maste 
cbor_refcount(const cbor_item_t * item)15810ff414cSEd Maste size_t cbor_refcount(const cbor_item_t *item) { return item->refcount; }
15910ff414cSEd Maste 
cbor_move(cbor_item_t * item)16010ff414cSEd Maste cbor_item_t *cbor_move(cbor_item_t *item) {
16110ff414cSEd Maste   item->refcount--;
16210ff414cSEd Maste   return item;
16310ff414cSEd Maste }
164