/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 | 795k | bool cbor_isa_uint(const cbor_item_t *item) { |
23 | 795k | return item->type == CBOR_TYPE_UINT; |
24 | 795k | } |
25 | | |
26 | 3.21k | bool cbor_isa_negint(const cbor_item_t *item) { |
27 | 3.21k | return item->type == CBOR_TYPE_NEGINT; |
28 | 3.21k | } |
29 | | |
30 | 551k | bool cbor_isa_bytestring(const cbor_item_t *item) { |
31 | 551k | return item->type == CBOR_TYPE_BYTESTRING; |
32 | 551k | } |
33 | | |
34 | 614k | bool cbor_isa_string(const cbor_item_t *item) { |
35 | 614k | return item->type == CBOR_TYPE_STRING; |
36 | 614k | } |
37 | | |
38 | 268k | bool cbor_isa_array(const cbor_item_t *item) { |
39 | 268k | return item->type == CBOR_TYPE_ARRAY; |
40 | 268k | } |
41 | | |
42 | 3.49M | bool cbor_isa_map(const cbor_item_t *item) { |
43 | 3.49M | return item->type == CBOR_TYPE_MAP; |
44 | 3.49M | } |
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 | 7.88M | cbor_type cbor_typeof(const cbor_item_t *item) { return item->type; } |
55 | | |
56 | 2.77k | bool cbor_is_int(const cbor_item_t *item) { |
57 | 2.77k | return cbor_isa_uint(item) || cbor_isa_negint(item); |
58 | 2.77k | } |
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 | 18.4M | cbor_item_t *cbor_incref(cbor_item_t *item) { |
79 | 18.4M | item->refcount++; |
80 | 18.4M | return item; |
81 | 18.4M | } |
82 | | |
83 | 34.5M | void cbor_decref(cbor_item_t **item_ref) { |
84 | 34.5M | cbor_item_t *item = *item_ref; |
85 | 34.5M | CBOR_ASSERT(item->refcount > 0); |
86 | 34.5M | if (--item->refcount == 0) { |
87 | 16.1M | switch (item->type) { |
88 | 6.67M | case CBOR_TYPE_UINT: |
89 | | /* Fallthrough */ |
90 | 7.25M | case CBOR_TYPE_NEGINT: |
91 | | /* Combined allocation, freeing the item suffices */ |
92 | 7.25M | { break; } |
93 | 546k | case CBOR_TYPE_BYTESTRING: { |
94 | 546k | if (cbor_bytestring_is_definite(item)) { |
95 | 534k | _cbor_free(item->data); |
96 | 534k | } else { |
97 | | /* We need to decref all chunks */ |
98 | 12.1k | cbor_item_t **handle = cbor_bytestring_chunks_handle(item); |
99 | 95.8k | for (size_t i = 0; i < cbor_bytestring_chunk_count(item); i++) |
100 | 83.7k | cbor_decref(&handle[i]); |
101 | 12.1k | _cbor_free( |
102 | 12.1k | ((struct cbor_indefinite_string_data *)item->data)->chunks); |
103 | 12.1k | _cbor_free(item->data); |
104 | 12.1k | } |
105 | 546k | break; |
106 | 6.67M | } |
107 | 646k | case CBOR_TYPE_STRING: { |
108 | 646k | if (cbor_string_is_definite(item)) { |
109 | 624k | _cbor_free(item->data); |
110 | 624k | } else { |
111 | | /* We need to decref all chunks */ |
112 | 22.0k | cbor_item_t **handle = cbor_string_chunks_handle(item); |
113 | 71.9k | for (size_t i = 0; i < cbor_string_chunk_count(item); i++) |
114 | 49.8k | cbor_decref(&handle[i]); |
115 | 22.0k | _cbor_free( |
116 | 22.0k | ((struct cbor_indefinite_string_data *)item->data)->chunks); |
117 | 22.0k | _cbor_free(item->data); |
118 | 22.0k | } |
119 | 646k | break; |
120 | 6.67M | } |
121 | 736k | case CBOR_TYPE_ARRAY: { |
122 | | /* Get all items and decref them */ |
123 | 736k | cbor_item_t **handle = cbor_array_handle(item); |
124 | 736k | size_t size = cbor_array_size(item); |
125 | 7.63M | for (size_t i = 0; i < size; i++) |
126 | 6.89M | if (handle[i] != NULL) cbor_decref(&handle[i]); |
127 | 736k | _cbor_free(item->data); |
128 | 736k | break; |
129 | 6.67M | } |
130 | 6.20M | case CBOR_TYPE_MAP: { |
131 | 6.20M | struct cbor_pair *handle = cbor_map_handle(item); |
132 | 9.99M | for (size_t i = 0; i < item->metadata.map_metadata.end_ptr; |
133 | 6.20M | i++, handle++) { |
134 | 3.78M | cbor_decref(&handle->key); |
135 | 3.78M | if (handle->value != NULL) cbor_decref(&handle->value); |
136 | 3.78M | } |
137 | 6.20M | _cbor_free(item->data); |
138 | 6.20M | break; |
139 | 6.67M | } |
140 | 515k | case CBOR_TYPE_TAG: { |
141 | 515k | if (item->metadata.tag_metadata.tagged_item != NULL) |
142 | 242k | cbor_decref(&item->metadata.tag_metadata.tagged_item); |
143 | 515k | _cbor_free(item->data); |
144 | 515k | break; |
145 | 6.67M | } |
146 | 243k | case CBOR_TYPE_FLOAT_CTRL: { |
147 | | /* Floats have combined allocation */ |
148 | 243k | break; |
149 | 6.67M | } |
150 | 16.1M | } |
151 | 16.1M | _cbor_free(item); |
152 | 16.1M | *item_ref = NULL; |
153 | 16.1M | } |
154 | 34.5M | } |
155 | | |
156 | 7.98M | 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 | } |