Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/libcbor/src/cbor/common.h
39488 views
1
/*
2
* Copyright (c) 2014-2020 Pavel Kalvoda <[email protected]>
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
#ifndef LIBCBOR_COMMON_H
9
#define LIBCBOR_COMMON_H
10
11
#include <assert.h>
12
#include <stdbool.h>
13
#include <stddef.h>
14
#include <stdint.h>
15
#include <stdlib.h>
16
17
#include "cbor/cbor_export.h"
18
#include "cbor/configuration.h"
19
#include "data.h"
20
21
#ifdef __cplusplus
22
extern "C" {
23
24
/**
25
* C99 is not a subset of C++ -- 'restrict' qualifier is not a part of the
26
* language. This is a workaround to keep it in C headers -- compilers allow
27
* linking non-restrict signatures with restrict implementations.
28
*
29
* If you know a nicer way, please do let me know.
30
*/
31
#define CBOR_RESTRICT_POINTER
32
33
#else
34
35
// MSVC + C++ workaround
36
#define CBOR_RESTRICT_POINTER CBOR_RESTRICT_SPECIFIER
37
38
#endif
39
40
static const uint8_t cbor_major_version = CBOR_MAJOR_VERSION;
41
static const uint8_t cbor_minor_version = CBOR_MINOR_VERSION;
42
static const uint8_t cbor_patch_version = CBOR_PATCH_VERSION;
43
44
#define CBOR_VERSION \
45
_CBOR_TO_STR(CBOR_MAJOR_VERSION) \
46
"." _CBOR_TO_STR(CBOR_MINOR_VERSION) "." _CBOR_TO_STR(CBOR_PATCH_VERSION)
47
#define CBOR_HEX_VERSION \
48
((CBOR_MAJOR_VERSION << 16) | (CBOR_MINOR_VERSION << 8) | CBOR_PATCH_VERSION)
49
50
/* http://stackoverflow.com/questions/1644868/c-define-macro-for-debug-printing
51
*/
52
#ifdef DEBUG
53
#include <stdio.h>
54
#define _cbor_debug_print(fmt, ...) \
55
do { \
56
if (DEBUG) \
57
fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, __LINE__, __func__, \
58
__VA_ARGS__); \
59
} while (0)
60
extern bool _cbor_enable_assert;
61
// Like `assert`, but can be dynamically disabled in tests to allow testing
62
// invalid behaviors.
63
#define CBOR_ASSERT(e) assert(!_cbor_enable_assert || (e))
64
#define _CBOR_TEST_DISABLE_ASSERT(block) \
65
do { \
66
_cbor_enable_assert = false; \
67
block _cbor_enable_assert = true; \
68
} while (0)
69
#else
70
#define debug_print(fmt, ...) \
71
do { \
72
} while (0)
73
#define CBOR_ASSERT(e)
74
#define _CBOR_TEST_DISABLE_ASSERT(block) \
75
do { \
76
block \
77
} while (0)
78
#endif
79
80
#define _CBOR_TO_STR_(x) #x
81
#define _CBOR_TO_STR(x) _CBOR_TO_STR_(x) /* enables proper double expansion */
82
83
#ifdef __GNUC__
84
#define _CBOR_UNUSED(x) __attribute__((__unused__)) x
85
// TODO(https://github.com/PJK/libcbor/issues/247): Prefer [[nodiscard]] if
86
// available
87
#define _CBOR_NODISCARD __attribute__((warn_unused_result))
88
#elif defined(_MSC_VER)
89
#define _CBOR_UNUSED(x) __pragma(warning(suppress : 4100 4101)) x
90
#define _CBOR_NODISCARD
91
#else
92
#define _CBOR_UNUSED(x) x
93
#define _CBOR_NODISCARD
94
#endif
95
96
typedef void *(*_cbor_malloc_t)(size_t);
97
typedef void *(*_cbor_realloc_t)(void *, size_t);
98
typedef void (*_cbor_free_t)(void *);
99
100
CBOR_EXPORT extern _cbor_malloc_t _cbor_malloc;
101
CBOR_EXPORT extern _cbor_realloc_t _cbor_realloc;
102
CBOR_EXPORT extern _cbor_free_t _cbor_free;
103
104
// Macro to short-circuit builder functions when memory allocation fails
105
#define _CBOR_NOTNULL(cbor_item) \
106
do { \
107
if (cbor_item == NULL) { \
108
return NULL; \
109
} \
110
} while (0)
111
112
// Macro to short-circuit builders when memory allocation of nested data fails
113
#define _CBOR_DEPENDENT_NOTNULL(cbor_item, pointer) \
114
do { \
115
if (pointer == NULL) { \
116
_cbor_free(cbor_item); \
117
return NULL; \
118
} \
119
} while (0)
120
121
/** Sets the memory management routines to use.
122
*
123
* By default, libcbor will use the standard library `malloc`, `realloc`, and
124
* `free`.
125
*
126
* \rst
127
* .. warning:: This function modifies the global state and should therefore be
128
* used accordingly. Changing the memory handlers while allocated items exist
129
* will result in a ``free``/``malloc`` mismatch. This function is not thread
130
* safe with respect to both itself and all the other *libcbor* functions that
131
* work with the heap.
132
*
133
* .. note:: `realloc` implementation must correctly support `NULL` reallocation
134
* (see e.g. http://en.cppreference.com/w/c/memory/realloc)
135
* \endrst
136
*
137
* @param custom_malloc malloc implementation
138
* @param custom_realloc realloc implementation
139
* @param custom_free free implementation
140
*/
141
CBOR_EXPORT void cbor_set_allocs(_cbor_malloc_t custom_malloc,
142
_cbor_realloc_t custom_realloc,
143
_cbor_free_t custom_free);
144
145
/*
146
* ============================================================================
147
* Type manipulation
148
* ============================================================================
149
*/
150
151
/** Get the type of the item
152
*
153
* @param item
154
* @return The type
155
*/
156
_CBOR_NODISCARD
157
CBOR_EXPORT cbor_type cbor_typeof(
158
const cbor_item_t *item); /* Will be inlined iff link-time opt is enabled */
159
160
/* Standard CBOR Major item types */
161
162
/** Does the item have the appropriate major type?
163
* @param item the item
164
* @return Is the item an #CBOR_TYPE_UINT?
165
*/
166
_CBOR_NODISCARD
167
CBOR_EXPORT bool cbor_isa_uint(const cbor_item_t *item);
168
169
/** Does the item have the appropriate major type?
170
* @param item the item
171
* @return Is the item a #CBOR_TYPE_NEGINT?
172
*/
173
_CBOR_NODISCARD
174
CBOR_EXPORT bool cbor_isa_negint(const cbor_item_t *item);
175
176
/** Does the item have the appropriate major type?
177
* @param item the item
178
* @return Is the item a #CBOR_TYPE_BYTESTRING?
179
*/
180
_CBOR_NODISCARD
181
CBOR_EXPORT bool cbor_isa_bytestring(const cbor_item_t *item);
182
183
/** Does the item have the appropriate major type?
184
* @param item the item
185
* @return Is the item a #CBOR_TYPE_STRING?
186
*/
187
_CBOR_NODISCARD
188
CBOR_EXPORT bool cbor_isa_string(const cbor_item_t *item);
189
190
/** Does the item have the appropriate major type?
191
* @param item the item
192
* @return Is the item an #CBOR_TYPE_ARRAY?
193
*/
194
_CBOR_NODISCARD
195
CBOR_EXPORT bool cbor_isa_array(const cbor_item_t *item);
196
197
/** Does the item have the appropriate major type?
198
* @param item the item
199
* @return Is the item a #CBOR_TYPE_MAP?
200
*/
201
_CBOR_NODISCARD
202
CBOR_EXPORT bool cbor_isa_map(const cbor_item_t *item);
203
204
/** Does the item have the appropriate major type?
205
* @param item the item
206
* @return Is the item a #CBOR_TYPE_TAG?
207
*/
208
_CBOR_NODISCARD
209
CBOR_EXPORT bool cbor_isa_tag(const cbor_item_t *item);
210
211
/** Does the item have the appropriate major type?
212
* @param item the item
213
* @return Is the item a #CBOR_TYPE_FLOAT_CTRL?
214
*/
215
_CBOR_NODISCARD
216
CBOR_EXPORT bool cbor_isa_float_ctrl(const cbor_item_t *item);
217
218
/* Practical types with respect to their semantics (but not tag values) */
219
220
/** Is the item an integer, either positive or negative?
221
* @param item the item
222
* @return Is the item an integer, either positive or negative?
223
*/
224
_CBOR_NODISCARD
225
CBOR_EXPORT bool cbor_is_int(const cbor_item_t *item);
226
227
/** Is the item an a floating point number?
228
* @param item the item
229
* @return Is the item a floating point number?
230
*/
231
_CBOR_NODISCARD
232
CBOR_EXPORT bool cbor_is_float(const cbor_item_t *item);
233
234
/** Is the item an a boolean?
235
* @param item the item
236
* @return Is the item a boolean?
237
*/
238
_CBOR_NODISCARD
239
CBOR_EXPORT bool cbor_is_bool(const cbor_item_t *item);
240
241
/** Does this item represent `null`
242
*
243
* \rst
244
* .. warning:: This is in no way related to the value of the pointer. Passing a
245
* null pointer will most likely result in a crash.
246
* \endrst
247
*
248
* @param item the item
249
* @return Is the item (CBOR logical) null?
250
*/
251
_CBOR_NODISCARD
252
CBOR_EXPORT bool cbor_is_null(const cbor_item_t *item);
253
254
/** Does this item represent `undefined`
255
*
256
* \rst
257
* .. warning:: Care must be taken to distinguish nulls and undefined values in
258
* C.
259
* \endrst
260
*
261
* @param item the item
262
* @return Is the item (CBOR logical) undefined?
263
*/
264
_CBOR_NODISCARD
265
CBOR_EXPORT bool cbor_is_undef(const cbor_item_t *item);
266
267
/*
268
* ============================================================================
269
* Memory management
270
* ============================================================================
271
*/
272
273
/** Increases the item's reference count by one
274
*
275
* Constant complexity; items referring to this one or items being referred to
276
* are not updated.
277
*
278
* This function can be used to extend reference counting to client code.
279
*
280
* @param item Reference to an item
281
* @return The input \p item
282
*/
283
CBOR_EXPORT cbor_item_t *cbor_incref(cbor_item_t *item);
284
285
/** Decreases the item's reference count by one, deallocating the item if needed
286
*
287
* In case the item is deallocated, the reference count of all items this item
288
* references will also be #cbor_decref 'ed recursively.
289
*
290
* @param item Reference to an item. Will be set to `NULL` if deallocated
291
*/
292
CBOR_EXPORT void cbor_decref(cbor_item_t **item);
293
294
/** Decreases the item's reference count by one, deallocating the item if needed
295
*
296
* Convenience wrapper for #cbor_decref when its set-to-null behavior is not
297
* needed
298
*
299
* @param item Reference to an item
300
*/
301
CBOR_EXPORT void cbor_intermediate_decref(cbor_item_t *item);
302
303
/** Get the item's reference count
304
*
305
* \rst
306
* .. warning:: This does *not* account for transitive references.
307
* \endrst
308
*
309
* @todo Add some inline examples for reference counting
310
*
311
* @param item the item
312
* @return the reference count
313
*/
314
_CBOR_NODISCARD
315
CBOR_EXPORT size_t cbor_refcount(const cbor_item_t *item);
316
317
/** Provides CPP-like move construct
318
*
319
* Decreases the reference count by one, but does not deallocate the item even
320
* if its refcount reaches zero. This is useful for passing intermediate values
321
* to functions that increase reference count. Should only be used with
322
* functions that `incref` their arguments.
323
*
324
* \rst
325
* .. warning:: If the item is moved without correctly increasing the reference
326
* count afterwards, the memory will be leaked.
327
* \endrst
328
*
329
* @param item Reference to an item
330
* @return the item with reference count decreased by one
331
*/
332
_CBOR_NODISCARD
333
CBOR_EXPORT cbor_item_t *cbor_move(cbor_item_t *item);
334
335
#ifdef __cplusplus
336
}
337
#endif
338
339
#endif // LIBCBOR_COMMON_H
340
341