/src/libcbor/src/cbor/common.c
Line | Count | Source (jump to first uncovered line) |
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 | 291M | bool cbor_isa_uint(const cbor_item_t* item) { |
23 | 291M | return item->type == CBOR_TYPE_UINT; |
24 | 291M | } |
25 | | |
26 | 16.3M | bool cbor_isa_negint(const cbor_item_t* item) { |
27 | 16.3M | return item->type == CBOR_TYPE_NEGINT; |
28 | 16.3M | } |
29 | | |
30 | 30.6M | bool cbor_isa_bytestring(const cbor_item_t* item) { |
31 | 30.6M | return item->type == CBOR_TYPE_BYTESTRING; |
32 | 30.6M | } |
33 | | |
34 | 36.1M | bool cbor_isa_string(const cbor_item_t* item) { |
35 | 36.1M | return item->type == CBOR_TYPE_STRING; |
36 | 36.1M | } |
37 | | |
38 | 353M | bool cbor_isa_array(const cbor_item_t* item) { |
39 | 353M | return item->type == CBOR_TYPE_ARRAY; |
40 | 353M | } |
41 | | |
42 | 36.3M | bool cbor_isa_map(const cbor_item_t* item) { |
43 | 36.3M | return item->type == CBOR_TYPE_MAP; |
44 | 36.3M | } |
45 | | |
46 | 2.16M | bool cbor_isa_tag(const cbor_item_t* item) { |
47 | 2.16M | return item->type == CBOR_TYPE_TAG; |
48 | 2.16M | } |
49 | | |
50 | 90.3M | bool cbor_isa_float_ctrl(const cbor_item_t* item) { |
51 | 90.3M | return item->type == CBOR_TYPE_FLOAT_CTRL; |
52 | 90.3M | } |
53 | | |
54 | 94.6M | cbor_type cbor_typeof(const cbor_item_t* item) { return item->type; } |
55 | | |
56 | 279M | bool cbor_is_int(const cbor_item_t* item) { |
57 | 279M | return cbor_isa_uint(item) || cbor_isa_negint(item); |
58 | 279M | } |
59 | | |
60 | 6.04M | bool cbor_is_bool(const cbor_item_t* item) { |
61 | 6.04M | return cbor_isa_float_ctrl(item) && |
62 | 6.04M | (cbor_ctrl_value(item) == CBOR_CTRL_FALSE || |
63 | 6.04M | cbor_ctrl_value(item) == CBOR_CTRL_TRUE); |
64 | 6.04M | } |
65 | | |
66 | 109k | bool cbor_is_null(const cbor_item_t* item) { |
67 | 109k | return cbor_isa_float_ctrl(item) && cbor_ctrl_value(item) == CBOR_CTRL_NULL; |
68 | 109k | } |
69 | | |
70 | 139k | bool cbor_is_undef(const cbor_item_t* item) { |
71 | 139k | return cbor_isa_float_ctrl(item) && cbor_ctrl_value(item) == CBOR_CTRL_UNDEF; |
72 | 139k | } |
73 | | |
74 | 681k | bool cbor_is_float(const cbor_item_t* item) { |
75 | 681k | return cbor_isa_float_ctrl(item) && !cbor_float_ctrl_is_ctrl(item); |
76 | 681k | } |
77 | | |
78 | 85.8M | cbor_item_t* cbor_incref(cbor_item_t* item) { |
79 | 85.8M | item->refcount++; |
80 | 85.8M | return item; |
81 | 85.8M | } |
82 | | |
83 | 131M | void cbor_decref(cbor_item_t** item_ref) { |
84 | 131M | cbor_item_t* item = *item_ref; |
85 | 131M | CBOR_ASSERT(item->refcount > 0); |
86 | 131M | if (--item->refcount == 0) { |
87 | 65.9M | switch (item->type) { |
88 | 31.3M | case CBOR_TYPE_UINT: |
89 | | /* Fallthrough */ |
90 | 33.4M | case CBOR_TYPE_NEGINT: |
91 | | /* Combined allocation, freeing the item suffices */ |
92 | 33.4M | { break; } |
93 | 1.41M | case CBOR_TYPE_BYTESTRING: { |
94 | 1.41M | if (cbor_bytestring_is_definite(item)) { |
95 | 1.40M | _cbor_free(item->data); |
96 | 1.40M | } else { |
97 | | /* We need to decref all chunks */ |
98 | 7.56k | cbor_item_t** handle = cbor_bytestring_chunks_handle(item); |
99 | 1.35M | for (size_t i = 0; i < cbor_bytestring_chunk_count(item); i++) |
100 | 1.34M | cbor_decref(&handle[i]); |
101 | 7.56k | _cbor_free(((struct cbor_indefinite_string_data*)item->data)->chunks); |
102 | 7.56k | _cbor_free(item->data); |
103 | 7.56k | } |
104 | 1.41M | break; |
105 | 31.3M | } |
106 | 1.78M | case CBOR_TYPE_STRING: { |
107 | 1.78M | if (cbor_string_is_definite(item)) { |
108 | 1.75M | _cbor_free(item->data); |
109 | 1.75M | } else { |
110 | | /* We need to decref all chunks */ |
111 | 29.0k | cbor_item_t** handle = cbor_string_chunks_handle(item); |
112 | 1.71M | for (size_t i = 0; i < cbor_string_chunk_count(item); i++) |
113 | 1.68M | cbor_decref(&handle[i]); |
114 | 29.0k | _cbor_free(((struct cbor_indefinite_string_data*)item->data)->chunks); |
115 | 29.0k | _cbor_free(item->data); |
116 | 29.0k | } |
117 | 1.78M | break; |
118 | 31.3M | } |
119 | 18.9M | case CBOR_TYPE_ARRAY: { |
120 | | /* Get all items and decref them */ |
121 | 18.9M | cbor_item_t** handle = cbor_array_handle(item); |
122 | 18.9M | size_t size = cbor_array_size(item); |
123 | 72.9M | for (size_t i = 0; i < size; i++) |
124 | 54.0M | if (handle[i] != NULL) cbor_decref(&handle[i]); |
125 | 18.9M | _cbor_free(item->data); |
126 | 18.9M | break; |
127 | 31.3M | } |
128 | 128k | case CBOR_TYPE_MAP: { |
129 | 128k | struct cbor_pair* handle = cbor_map_handle(item); |
130 | 4.28M | for (size_t i = 0; i < item->metadata.map_metadata.end_ptr; |
131 | 4.15M | i++, handle++) { |
132 | 4.15M | cbor_decref(&handle->key); |
133 | 4.15M | if (handle->value != NULL) cbor_decref(&handle->value); |
134 | 4.15M | } |
135 | 128k | _cbor_free(item->data); |
136 | 128k | break; |
137 | 31.3M | } |
138 | 471k | case CBOR_TYPE_TAG: { |
139 | 471k | if (item->metadata.tag_metadata.tagged_item != NULL) |
140 | 447k | cbor_decref(&item->metadata.tag_metadata.tagged_item); |
141 | 471k | _cbor_free(item->data); |
142 | 471k | break; |
143 | 31.3M | } |
144 | 9.75M | case CBOR_TYPE_FLOAT_CTRL: { |
145 | | /* Floats have combined allocation */ |
146 | 9.75M | break; |
147 | 31.3M | } |
148 | 65.9M | } |
149 | 65.9M | _cbor_free(item); |
150 | 65.9M | *item_ref = NULL; |
151 | 65.9M | } |
152 | 131M | } |
153 | | |
154 | 0 | void cbor_intermediate_decref(cbor_item_t* item) { cbor_decref(&item); } |
155 | | |
156 | 0 | size_t cbor_refcount(const cbor_item_t* item) { return item->refcount; } |
157 | | |
158 | 20.0M | cbor_item_t* cbor_move(cbor_item_t* item) { |
159 | 20.0M | item->refcount--; |
160 | 20.0M | return item; |
161 | 20.0M | } |