/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 | 879k | bool cbor_isa_uint(const cbor_item_t *item) { |
23 | 879k | return item->type == CBOR_TYPE_UINT; |
24 | 879k | } |
25 | | |
26 | 3.12k | bool cbor_isa_negint(const cbor_item_t *item) { |
27 | 3.12k | return item->type == CBOR_TYPE_NEGINT; |
28 | 3.12k | } |
29 | | |
30 | 581k | bool cbor_isa_bytestring(const cbor_item_t *item) { |
31 | 581k | return item->type == CBOR_TYPE_BYTESTRING; |
32 | 581k | } |
33 | | |
34 | 726k | bool cbor_isa_string(const cbor_item_t *item) { |
35 | 726k | return item->type == CBOR_TYPE_STRING; |
36 | 726k | } |
37 | | |
38 | 289k | bool cbor_isa_array(const cbor_item_t *item) { |
39 | 289k | return item->type == CBOR_TYPE_ARRAY; |
40 | 289k | } |
41 | | |
42 | 3.30M | bool cbor_isa_map(const cbor_item_t *item) { |
43 | 3.30M | return item->type == CBOR_TYPE_MAP; |
44 | 3.30M | } |
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.03M | cbor_type cbor_typeof(const cbor_item_t *item) { return item->type; } |
55 | | |
56 | 2.67k | bool cbor_is_int(const cbor_item_t *item) { |
57 | 2.67k | return cbor_isa_uint(item) || cbor_isa_negint(item); |
58 | 2.67k | } |
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.8M | cbor_item_t *cbor_incref(cbor_item_t *item) { |
79 | 18.8M | item->refcount++; |
80 | 18.8M | return item; |
81 | 18.8M | } |
82 | | |
83 | 35.6M | void cbor_decref(cbor_item_t **item_ref) { |
84 | 35.6M | cbor_item_t *item = *item_ref; |
85 | 35.6M | CBOR_ASSERT(item->refcount > 0); |
86 | 35.6M | if (--item->refcount == 0) { |
87 | 16.8M | switch (item->type) { |
88 | 7.20M | case CBOR_TYPE_UINT: |
89 | | /* Fallthrough */ |
90 | 7.80M | case CBOR_TYPE_NEGINT: |
91 | | /* Combined allocation, freeing the item suffices */ |
92 | 7.80M | { break; } |
93 | 575k | case CBOR_TYPE_BYTESTRING: { |
94 | 575k | if (cbor_bytestring_is_definite(item)) { |
95 | 563k | _cbor_free(item->data); |
96 | 563k | } else { |
97 | | /* We need to decref all chunks */ |
98 | 12.3k | cbor_item_t **handle = cbor_bytestring_chunks_handle(item); |
99 | 61.1k | for (size_t i = 0; i < cbor_bytestring_chunk_count(item); i++) |
100 | 48.8k | cbor_decref(&handle[i]); |
101 | 12.3k | _cbor_free( |
102 | 12.3k | ((struct cbor_indefinite_string_data *)item->data)->chunks); |
103 | 12.3k | _cbor_free(item->data); |
104 | 12.3k | } |
105 | 575k | break; |
106 | 7.20M | } |
107 | 742k | case CBOR_TYPE_STRING: { |
108 | 742k | if (cbor_string_is_definite(item)) { |
109 | 729k | _cbor_free(item->data); |
110 | 729k | } else { |
111 | | /* We need to decref all chunks */ |
112 | 13.4k | cbor_item_t **handle = cbor_string_chunks_handle(item); |
113 | 94.9k | for (size_t i = 0; i < cbor_string_chunk_count(item); i++) |
114 | 81.5k | cbor_decref(&handle[i]); |
115 | 13.4k | _cbor_free( |
116 | 13.4k | ((struct cbor_indefinite_string_data *)item->data)->chunks); |
117 | 13.4k | _cbor_free(item->data); |
118 | 13.4k | } |
119 | 742k | break; |
120 | 7.20M | } |
121 | 795k | case CBOR_TYPE_ARRAY: { |
122 | | /* Get all items and decref them */ |
123 | 795k | cbor_item_t **handle = cbor_array_handle(item); |
124 | 795k | size_t size = cbor_array_size(item); |
125 | 7.81M | for (size_t i = 0; i < size; i++) |
126 | 7.02M | if (handle[i] != NULL) cbor_decref(&handle[i]); |
127 | 795k | _cbor_free(item->data); |
128 | 795k | break; |
129 | 7.20M | } |
130 | 5.91M | case CBOR_TYPE_MAP: { |
131 | 5.91M | struct cbor_pair *handle = cbor_map_handle(item); |
132 | 9.91M | for (size_t i = 0; i < item->metadata.map_metadata.end_ptr; |
133 | 5.91M | i++, handle++) { |
134 | 3.99M | cbor_decref(&handle->key); |
135 | 3.99M | if (handle->value != NULL) cbor_decref(&handle->value); |
136 | 3.99M | } |
137 | 5.91M | _cbor_free(item->data); |
138 | 5.91M | break; |
139 | 7.20M | } |
140 | 755k | case CBOR_TYPE_TAG: { |
141 | 755k | if (item->metadata.tag_metadata.tagged_item != NULL) |
142 | 324k | cbor_decref(&item->metadata.tag_metadata.tagged_item); |
143 | 755k | _cbor_free(item->data); |
144 | 755k | break; |
145 | 7.20M | } |
146 | 233k | case CBOR_TYPE_FLOAT_CTRL: { |
147 | | /* Floats have combined allocation */ |
148 | 233k | break; |
149 | 7.20M | } |
150 | 16.8M | } |
151 | 16.8M | _cbor_free(item); |
152 | 16.8M | *item_ref = NULL; |
153 | 16.8M | } |
154 | 35.6M | } |
155 | | |
156 | 7.41M | 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 | } |