aboutsummaryrefslogtreecommitdiff
path: root/src/cbor/common.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/cbor/common.h')
-rw-r--r--src/cbor/common.h303
1 files changed, 303 insertions, 0 deletions
diff --git a/src/cbor/common.h b/src/cbor/common.h
new file mode 100644
index 000000000000..1f9b79e16d9d
--- /dev/null
+++ b/src/cbor/common.h
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com>
+ *
+ * libcbor is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See LICENSE for details.
+ */
+
+#ifndef LIBCBOR_COMMON_H
+#define LIBCBOR_COMMON_H
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include "cbor/cbor_export.h"
+#include "cbor/configuration.h"
+#include "data.h"
+
+#ifdef __cplusplus
+extern "C" {
+
+/**
+ * C++ is not a subset of C99 -- 'restrict' qualifier is not a part of the
+ * language. This is a workaround to keep it in C headers -- compilers allow
+ * linking non-restrict signatures with restrict implementations.
+ *
+ * If you know a nicer way, please do let me know.
+ */
+#define CBOR_RESTRICT_POINTER
+
+#else
+
+// MSVC + C++ workaround
+#define CBOR_RESTRICT_POINTER CBOR_RESTRICT_SPECIFIER
+
+#endif
+
+static const uint8_t cbor_major_version = CBOR_MAJOR_VERSION;
+static const uint8_t cbor_minor_version = CBOR_MINOR_VERSION;
+static const uint8_t cbor_patch_version = CBOR_PATCH_VERSION;
+
+#define CBOR_VERSION \
+ TO_STR(CBOR_MAJOR_VERSION) \
+ "." TO_STR(CBOR_MINOR_VERSION) "." TO_STR(CBOR_PATCH_VERSION)
+#define CBOR_HEX_VERSION \
+ ((CBOR_MAJOR_VERSION << 16) | (CBOR_MINOR_VERSION << 8) | CBOR_PATCH_VERSION)
+
+/* http://stackoverflow.com/questions/1644868/c-define-macro-for-debug-printing
+ */
+#ifdef DEBUG
+#include <stdio.h>
+#define debug_print(fmt, ...) \
+ do { \
+ if (DEBUG) \
+ fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, __LINE__, __func__, \
+ __VA_ARGS__); \
+ } while (0)
+#else
+#define debug_print(fmt, ...) \
+ do { \
+ } while (0)
+#endif
+
+#define TO_STR_(x) #x
+#define TO_STR(x) TO_STR_(x) /* enables proper double expansion */
+
+// Macro to short-circuit builder functions when memory allocation fails
+#define _CBOR_NOTNULL(cbor_item) \
+ do { \
+ if (cbor_item == NULL) { \
+ return NULL; \
+ } \
+ } while (0)
+
+// Macro to short-circuit builders when memory allocation of nested data fails
+#define _CBOR_DEPENDENT_NOTNULL(cbor_item, pointer) \
+ do { \
+ if (pointer == NULL) { \
+ _CBOR_FREE(cbor_item); \
+ return NULL; \
+ } \
+ } while (0)
+
+#if CBOR_CUSTOM_ALLOC
+
+typedef void *(*_cbor_malloc_t)(size_t);
+typedef void *(*_cbor_realloc_t)(void *, size_t);
+typedef void (*_cbor_free_t)(void *);
+
+CBOR_EXPORT extern _cbor_malloc_t _cbor_malloc;
+CBOR_EXPORT extern _cbor_realloc_t _cbor_realloc;
+CBOR_EXPORT extern _cbor_free_t _cbor_free;
+
+/** Sets the memory management routines to use.
+ *
+ * Only available when `CBOR_CUSTOM_ALLOC` is truthy
+ *
+ * \rst
+ * .. warning:: This function modifies the global state and should therefore be
+ * used accordingly. Changing the memory handlers while allocated items exist
+ * will result in a ``free``/``malloc`` mismatch. This function is not thread
+ * safe with respect to both itself and all the other *libcbor* functions that
+ * work with the heap.
+ *
+ * .. note:: `realloc` implementation must correctly support `NULL` reallocation
+ * (see e.g. http://en.cppreference.com/w/c/memory/realloc)
+ * \endrst
+ *
+ * @param custom_malloc malloc implementation
+ * @param custom_realloc realloc implementation
+ * @param custom_free free implementation
+ */
+CBOR_EXPORT void cbor_set_allocs(_cbor_malloc_t custom_malloc,
+ _cbor_realloc_t custom_realloc,
+ _cbor_free_t custom_free);
+
+#define _CBOR_MALLOC _cbor_malloc
+#define _CBOR_REALLOC _cbor_realloc
+#define _CBOR_FREE _cbor_free
+
+#else
+
+#define _CBOR_MALLOC malloc
+#define _CBOR_REALLOC realloc
+#define _CBOR_FREE free
+
+#endif
+
+/*
+ * ============================================================================
+ * Type manipulation
+ * ============================================================================
+ */
+
+/** Get the type of the item
+ *
+ * @param item[borrow]
+ * @return The type
+ */
+CBOR_EXPORT cbor_type cbor_typeof(
+ const cbor_item_t *item); /* Will be inlined iff link-time opt is enabled */
+
+/* Standard item types as described by the RFC */
+
+/** Does the item have the appropriate major type?
+ * @param item[borrow] the item
+ * @return Is the item an #CBOR_TYPE_UINT?
+ */
+CBOR_EXPORT bool cbor_isa_uint(const cbor_item_t *item);
+
+/** Does the item have the appropriate major type?
+ * @param item[borrow] the item
+ * @return Is the item a #CBOR_TYPE_NEGINT?
+ */
+CBOR_EXPORT bool cbor_isa_negint(const cbor_item_t *item);
+
+/** Does the item have the appropriate major type?
+ * @param item[borrow] the item
+ * @return Is the item a #CBOR_TYPE_BYTESTRING?
+ */
+CBOR_EXPORT bool cbor_isa_bytestring(const cbor_item_t *item);
+
+/** Does the item have the appropriate major type?
+ * @param item[borrow] the item
+ * @return Is the item a #CBOR_TYPE_STRING?
+ */
+CBOR_EXPORT bool cbor_isa_string(const cbor_item_t *item);
+
+/** Does the item have the appropriate major type?
+ * @param item[borrow] the item
+ * @return Is the item an #CBOR_TYPE_ARRAY?
+ */
+CBOR_EXPORT bool cbor_isa_array(const cbor_item_t *item);
+
+/** Does the item have the appropriate major type?
+ * @param item[borrow] the item
+ * @return Is the item a #CBOR_TYPE_MAP?
+ */
+CBOR_EXPORT bool cbor_isa_map(const cbor_item_t *item);
+
+/** Does the item have the appropriate major type?
+ * @param item[borrow] the item
+ * @return Is the item a #CBOR_TYPE_TAG?
+ */
+CBOR_EXPORT bool cbor_isa_tag(const cbor_item_t *item);
+
+/** Does the item have the appropriate major type?
+ * @param item[borrow] the item
+ * @return Is the item a #CBOR_TYPE_FLOAT_CTRL?
+ */
+CBOR_EXPORT bool cbor_isa_float_ctrl(const cbor_item_t *item);
+
+/* Practical types with respect to their semantics (but not tag values) */
+
+/** Is the item an integer, either positive or negative?
+ * @param item[borrow] the item
+ * @return Is the item an integer, either positive or negative?
+ */
+CBOR_EXPORT bool cbor_is_int(const cbor_item_t *item);
+
+/** Is the item an a floating point number?
+ * @param item[borrow] the item
+ * @return Is the item a floating point number?
+ */
+CBOR_EXPORT bool cbor_is_float(const cbor_item_t *item);
+
+/** Is the item an a boolean?
+ * @param item[borrow] the item
+ * @return Is the item a boolean?
+ */
+CBOR_EXPORT bool cbor_is_bool(const cbor_item_t *item);
+
+/** Does this item represent `null`
+ *
+ * \rst
+ * .. warning:: This is in no way related to the value of the pointer. Passing a
+ * null pointer will most likely result in a crash.
+ * \endrst
+ *
+ * @param item[borrow] the item
+ * @return Is the item (CBOR logical) null?
+ */
+CBOR_EXPORT bool cbor_is_null(const cbor_item_t *item);
+
+/** Does this item represent `undefined`
+ *
+ * \rst
+ * .. warning:: Care must be taken to distinguish nulls and undefined values in
+ * C.
+ * \endrst
+ *
+ * @param item[borrow] the item
+ * @return Is the item (CBOR logical) undefined?
+ */
+CBOR_EXPORT bool cbor_is_undef(const cbor_item_t *item);
+
+/*
+ * ============================================================================
+ * Memory management
+ * ============================================================================
+ */
+
+/** Increases the reference count by one
+ *
+ * No dependent items are affected.
+ *
+ * @param item[incref] item the item
+ * @return the input reference
+ */
+CBOR_EXPORT cbor_item_t *cbor_incref(cbor_item_t *item);
+
+/** Decreases the reference count by one, deallocating the item if needed
+ *
+ * In case the item is deallocated, the reference count of any dependent items
+ * is adjusted accordingly in a recursive manner.
+ *
+ * @param item[take] the item. Set to `NULL` if deallocated
+ */
+CBOR_EXPORT void cbor_decref(cbor_item_t **item);
+
+/** Decreases the reference count by one, deallocating the item if needed
+ *
+ * Convenience wrapper for #cbor_decref when its set-to-null behavior is not
+ * needed
+ *
+ * @param item[take] the item
+ */
+CBOR_EXPORT void cbor_intermediate_decref(cbor_item_t *item);
+
+/** Get the reference count
+ *
+ * \rst
+ * .. warning:: This does *not* account for transitive references.
+ * \endrst
+ *
+ * @param item[borrow] the item
+ * @return the reference count
+ */
+CBOR_EXPORT size_t cbor_refcount(const cbor_item_t *item);
+
+/** Provides CPP-like move construct
+ *
+ * Decreases the reference count by one, but does not deallocate the item even
+ * if its refcount reaches zero. This is useful for passing intermediate values
+ * to functions that increase reference count. Should only be used with
+ * functions that `incref` their arguments.
+ *
+ * \rst
+ * .. warning:: If the item is moved without correctly increasing the reference
+ * count afterwards, the memory will be leaked.
+ * \endrst
+ *
+ * @param item[take] the item
+ * @return the item with reference count decreased by one
+ */
+CBOR_EXPORT cbor_item_t *cbor_move(cbor_item_t *item);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LIBCBOR_COMMON_H