xref: /freebsd/contrib/libcbor/src/cbor/common.c (revision 10ff414c14eef433d8157f0c17904d740693933b)
1*10ff414cSEd Maste /*
2*10ff414cSEd Maste  * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com>
3*10ff414cSEd Maste  *
4*10ff414cSEd Maste  * libcbor is free software; you can redistribute it and/or modify
5*10ff414cSEd Maste  * it under the terms of the MIT license. See LICENSE for details.
6*10ff414cSEd Maste  */
7*10ff414cSEd Maste 
8*10ff414cSEd Maste #include "cbor/common.h"
9*10ff414cSEd Maste #include "arrays.h"
10*10ff414cSEd Maste #include "bytestrings.h"
11*10ff414cSEd Maste #include "data.h"
12*10ff414cSEd Maste #include "floats_ctrls.h"
13*10ff414cSEd Maste #include "ints.h"
14*10ff414cSEd Maste #include "maps.h"
15*10ff414cSEd Maste #include "strings.h"
16*10ff414cSEd Maste #include "tags.h"
17*10ff414cSEd Maste 
18*10ff414cSEd Maste bool cbor_isa_uint(const cbor_item_t *item) {
19*10ff414cSEd Maste   return item->type == CBOR_TYPE_UINT;
20*10ff414cSEd Maste }
21*10ff414cSEd Maste 
22*10ff414cSEd Maste bool cbor_isa_negint(const cbor_item_t *item) {
23*10ff414cSEd Maste   return item->type == CBOR_TYPE_NEGINT;
24*10ff414cSEd Maste }
25*10ff414cSEd Maste 
26*10ff414cSEd Maste bool cbor_isa_bytestring(const cbor_item_t *item) {
27*10ff414cSEd Maste   return item->type == CBOR_TYPE_BYTESTRING;
28*10ff414cSEd Maste }
29*10ff414cSEd Maste 
30*10ff414cSEd Maste bool cbor_isa_string(const cbor_item_t *item) {
31*10ff414cSEd Maste   return item->type == CBOR_TYPE_STRING;
32*10ff414cSEd Maste }
33*10ff414cSEd Maste 
34*10ff414cSEd Maste bool cbor_isa_array(const cbor_item_t *item) {
35*10ff414cSEd Maste   return item->type == CBOR_TYPE_ARRAY;
36*10ff414cSEd Maste }
37*10ff414cSEd Maste 
38*10ff414cSEd Maste bool cbor_isa_map(const cbor_item_t *item) {
39*10ff414cSEd Maste   return item->type == CBOR_TYPE_MAP;
40*10ff414cSEd Maste }
41*10ff414cSEd Maste 
42*10ff414cSEd Maste bool cbor_isa_tag(const cbor_item_t *item) {
43*10ff414cSEd Maste   return item->type == CBOR_TYPE_TAG;
44*10ff414cSEd Maste }
45*10ff414cSEd Maste 
46*10ff414cSEd Maste bool cbor_isa_float_ctrl(const cbor_item_t *item) {
47*10ff414cSEd Maste   return item->type == CBOR_TYPE_FLOAT_CTRL;
48*10ff414cSEd Maste }
49*10ff414cSEd Maste 
50*10ff414cSEd Maste cbor_type cbor_typeof(const cbor_item_t *item) { return item->type; }
51*10ff414cSEd Maste 
52*10ff414cSEd Maste bool cbor_is_int(const cbor_item_t *item) {
53*10ff414cSEd Maste   return cbor_isa_uint(item) || cbor_isa_negint(item);
54*10ff414cSEd Maste }
55*10ff414cSEd Maste 
56*10ff414cSEd Maste bool cbor_is_bool(const cbor_item_t *item) {
57*10ff414cSEd Maste   return cbor_isa_float_ctrl(item) &&
58*10ff414cSEd Maste          (cbor_ctrl_value(item) == CBOR_CTRL_FALSE ||
59*10ff414cSEd Maste           cbor_ctrl_value(item) == CBOR_CTRL_TRUE);
60*10ff414cSEd Maste }
61*10ff414cSEd Maste 
62*10ff414cSEd Maste bool cbor_is_null(const cbor_item_t *item) {
63*10ff414cSEd Maste   return cbor_isa_float_ctrl(item) && cbor_ctrl_value(item) == CBOR_CTRL_NULL;
64*10ff414cSEd Maste }
65*10ff414cSEd Maste 
66*10ff414cSEd Maste bool cbor_is_undef(const cbor_item_t *item) {
67*10ff414cSEd Maste   return cbor_isa_float_ctrl(item) && cbor_ctrl_value(item) == CBOR_CTRL_UNDEF;
68*10ff414cSEd Maste }
69*10ff414cSEd Maste 
70*10ff414cSEd Maste bool cbor_is_float(const cbor_item_t *item) {
71*10ff414cSEd Maste   return cbor_isa_float_ctrl(item) && !cbor_float_ctrl_is_ctrl(item);
72*10ff414cSEd Maste }
73*10ff414cSEd Maste 
74*10ff414cSEd Maste cbor_item_t *cbor_incref(cbor_item_t *item) {
75*10ff414cSEd Maste   item->refcount++;
76*10ff414cSEd Maste   return item;
77*10ff414cSEd Maste }
78*10ff414cSEd Maste 
79*10ff414cSEd Maste void cbor_decref(cbor_item_t **item_ref) {
80*10ff414cSEd Maste   cbor_item_t *item = *item_ref;
81*10ff414cSEd Maste   assert(item->refcount > 0);
82*10ff414cSEd Maste   if (--item->refcount == 0) {
83*10ff414cSEd Maste     switch (item->type) {
84*10ff414cSEd Maste       case CBOR_TYPE_UINT:
85*10ff414cSEd Maste         /* Fallthrough */
86*10ff414cSEd Maste       case CBOR_TYPE_NEGINT:
87*10ff414cSEd Maste         /* Combined allocation, freeing the item suffices */
88*10ff414cSEd Maste         { break; }
89*10ff414cSEd Maste       case CBOR_TYPE_BYTESTRING: {
90*10ff414cSEd Maste         if (cbor_bytestring_is_definite(item)) {
91*10ff414cSEd Maste           _CBOR_FREE(item->data);
92*10ff414cSEd Maste         } else {
93*10ff414cSEd Maste           /* We need to decref all chunks */
94*10ff414cSEd Maste           cbor_item_t **handle = cbor_bytestring_chunks_handle(item);
95*10ff414cSEd Maste           for (size_t i = 0; i < cbor_bytestring_chunk_count(item); i++)
96*10ff414cSEd Maste             cbor_decref(&handle[i]);
97*10ff414cSEd Maste           _CBOR_FREE(
98*10ff414cSEd Maste               ((struct cbor_indefinite_string_data *)item->data)->chunks);
99*10ff414cSEd Maste           _CBOR_FREE(item->data);
100*10ff414cSEd Maste         }
101*10ff414cSEd Maste         break;
102*10ff414cSEd Maste       }
103*10ff414cSEd Maste       case CBOR_TYPE_STRING: {
104*10ff414cSEd Maste         if (cbor_string_is_definite(item)) {
105*10ff414cSEd Maste           _CBOR_FREE(item->data);
106*10ff414cSEd Maste         } else {
107*10ff414cSEd Maste           /* We need to decref all chunks */
108*10ff414cSEd Maste           cbor_item_t **handle = cbor_string_chunks_handle(item);
109*10ff414cSEd Maste           for (size_t i = 0; i < cbor_string_chunk_count(item); i++)
110*10ff414cSEd Maste             cbor_decref(&handle[i]);
111*10ff414cSEd Maste           _CBOR_FREE(
112*10ff414cSEd Maste               ((struct cbor_indefinite_string_data *)item->data)->chunks);
113*10ff414cSEd Maste           _CBOR_FREE(item->data);
114*10ff414cSEd Maste         }
115*10ff414cSEd Maste         break;
116*10ff414cSEd Maste       }
117*10ff414cSEd Maste       case CBOR_TYPE_ARRAY: {
118*10ff414cSEd Maste         /* Get all items and decref them */
119*10ff414cSEd Maste         cbor_item_t **handle = cbor_array_handle(item);
120*10ff414cSEd Maste         size_t size = cbor_array_size(item);
121*10ff414cSEd Maste         for (size_t i = 0; i < size; i++)
122*10ff414cSEd Maste           if (handle[i] != NULL) cbor_decref(&handle[i]);
123*10ff414cSEd Maste         _CBOR_FREE(item->data);
124*10ff414cSEd Maste         break;
125*10ff414cSEd Maste       }
126*10ff414cSEd Maste       case CBOR_TYPE_MAP: {
127*10ff414cSEd Maste         struct cbor_pair *handle = cbor_map_handle(item);
128*10ff414cSEd Maste         for (size_t i = 0; i < item->metadata.map_metadata.end_ptr;
129*10ff414cSEd Maste              i++, handle++) {
130*10ff414cSEd Maste           cbor_decref(&handle->key);
131*10ff414cSEd Maste           if (handle->value != NULL) cbor_decref(&handle->value);
132*10ff414cSEd Maste         }
133*10ff414cSEd Maste         _CBOR_FREE(item->data);
134*10ff414cSEd Maste         break;
135*10ff414cSEd Maste       };
136*10ff414cSEd Maste       case CBOR_TYPE_TAG: {
137*10ff414cSEd Maste         if (item->metadata.tag_metadata.tagged_item != NULL)
138*10ff414cSEd Maste           cbor_decref(&item->metadata.tag_metadata.tagged_item);
139*10ff414cSEd Maste         _CBOR_FREE(item->data);
140*10ff414cSEd Maste         break;
141*10ff414cSEd Maste       }
142*10ff414cSEd Maste       case CBOR_TYPE_FLOAT_CTRL: {
143*10ff414cSEd Maste         /* Floats have combined allocation */
144*10ff414cSEd Maste         break;
145*10ff414cSEd Maste       }
146*10ff414cSEd Maste     }
147*10ff414cSEd Maste     _CBOR_FREE(item);
148*10ff414cSEd Maste     // TODO
149*10ff414cSEd Maste     *item_ref = NULL;
150*10ff414cSEd Maste   }
151*10ff414cSEd Maste }
152*10ff414cSEd Maste 
153*10ff414cSEd Maste void cbor_intermediate_decref(cbor_item_t *item) { cbor_decref(&item); }
154*10ff414cSEd Maste 
155*10ff414cSEd Maste size_t cbor_refcount(const cbor_item_t *item) { return item->refcount; }
156*10ff414cSEd Maste 
157*10ff414cSEd Maste cbor_item_t *cbor_move(cbor_item_t *item) {
158*10ff414cSEd Maste   item->refcount--;
159*10ff414cSEd Maste   return item;
160*10ff414cSEd Maste }
161