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