1 module deimos.cbor.common; 2 3 import deimos.cbor.configuration; 4 import deimos.cbor.data; 5 6 /* 7 * Copyright (c) 2014-2019 Pavel Kalvoda <me@pavelkalvoda.com> 8 * 9 * libcbor is free software; you can redistribute it and/or modify 10 * it under the terms of the MIT license. See LICENSE for details. 11 */ 12 13 import core.stdc.stdlib; 14 15 extern __gshared const ubyte cbor_major_version; 16 extern __gshared const ubyte cbor_minor_version; 17 extern __gshared const ubyte cbor_patch_version; 18 19 enum CBOR_VERSION = TO_STR(CBOR_MAJOR_VERSION) ~ "." ~ TO_STR( 20 CBOR_MINOR_VERSION) ~ "." ~ TO_STR(CBOR_PATCH_VERSION); 21 enum CBOR_HEX_VERSION = (CBOR_MAJOR_VERSION << 16) | (CBOR_MINOR_VERSION << 8) | CBOR_PATCH_VERSION; 22 23 /* http://stackoverflow.com/questions/1644868/c-define-macro-for-debug-printing 24 */ 25 26 extern (D) string TO_STR_(T)(auto ref T x) 27 { 28 import std.conv : to; 29 30 return to!string(x); 31 } 32 33 alias TO_STR = TO_STR_; /* enables proper double expansion */ 34 35 // Macro to short-circuit builder functions when memory allocation fails 36 37 // Macro to short-circuit builders when memory allocation of nested data fails 38 39 /** Sets the memory management routines to use. 40 * 41 * Only available when `CBOR_CUSTOM_ALLOC` is truthy 42 * 43 * \rst 44 * .. warning:: This function modifies the global state and should therefore be 45 * used accordingly. Changing the memory handlers while allocated items exist 46 * will result in a ``free``/``malloc`` mismatch. This function is not thread 47 * safe with respect to both itself and all the other *libcbor* functions that 48 * work with the heap. 49 * .. note:: `realloc` implementation must correctly support `NULL` reallocation 50 * (see e.g. http://en.cppreference.com/w/c/memory/realloc) \endrst 51 * 52 * @param custom_malloc malloc implementation 53 * @param custom_realloc realloc implementation 54 * @param custom_free free implementation 55 */ 56 57 enum _CBOR_MALLOC = &malloc; 58 enum _CBOR_REALLOC = &realloc; 59 enum _CBOR_FREE = &free; 60 61 extern (C): 62 63 /* 64 * ============================================================================ 65 * Type manipulation 66 * ============================================================================ 67 */ 68 69 /** Get the type of the item 70 * 71 * @param item[borrow] 72 * @return The type 73 */ 74 cbor_type cbor_typeof(const cbor_item_t* item); /* Will be inlined iff link-time opt is enabled */ 75 76 /* Standard item types as described by the RFC */ 77 78 /** Does the item have the appropriate major type? 79 * @param item[borrow] the item 80 * @return Is the item an #CBOR_TYPE_UINT? 81 */ 82 bool cbor_isa_uint(const cbor_item_t* item); 83 84 /** Does the item have the appropriate major type? 85 * @param item[borrow] the item 86 * @return Is the item a #CBOR_TYPE_NEGINT? 87 */ 88 bool cbor_isa_negint(const cbor_item_t* item); 89 90 /** Does the item have the appropriate major type? 91 * @param item[borrow] the item 92 * @return Is the item a #CBOR_TYPE_BYTESTRING? 93 */ 94 bool cbor_isa_bytestring(const cbor_item_t* item); 95 96 /** Does the item have the appropriate major type? 97 * @param item[borrow] the item 98 * @return Is the item a #CBOR_TYPE_STRING? 99 */ 100 bool cbor_isa_string(const cbor_item_t* item); 101 102 /** Does the item have the appropriate major type? 103 * @param item[borrow] the item 104 * @return Is the item an #CBOR_TYPE_ARRAY? 105 */ 106 bool cbor_isa_array(const cbor_item_t* item); 107 108 /** Does the item have the appropriate major type? 109 * @param item[borrow] the item 110 * @return Is the item a #CBOR_TYPE_MAP? 111 */ 112 bool cbor_isa_map(const cbor_item_t* item); 113 114 /** Does the item have the appropriate major type? 115 * @param item[borrow] the item 116 * @return Is the item a #CBOR_TYPE_TAG? 117 */ 118 bool cbor_isa_tag(const cbor_item_t* item); 119 120 /** Does the item have the appropriate major type? 121 * @param item[borrow] the item 122 * @return Is the item a #CBOR_TYPE_FLOAT_CTRL? 123 */ 124 bool cbor_isa_float_ctrl(const cbor_item_t* item); 125 126 /* Practical types with respect to their semantics (but not tag values) */ 127 128 /** Is the item an integer, either positive or negative? 129 * @param item[borrow] the item 130 * @return Is the item an integer, either positive or negative? 131 */ 132 bool cbor_is_int(const cbor_item_t* item); 133 134 /** Is the item an a floating point number? 135 * @param item[borrow] the item 136 * @return Is the item a floating point number? 137 */ 138 bool cbor_is_float(const cbor_item_t* item); 139 140 /** Is the item an a boolean? 141 * @param item[borrow] the item 142 * @return Is the item a boolean? 143 */ 144 bool cbor_is_bool(const cbor_item_t* item); 145 146 /** Does this item represent `null` 147 * \rst 148 * .. warning:: This is in no way related to the value of the pointer. Passing a 149 * null pointer will most likely result in a crash. \endrst 150 * @param item[borrow] the item 151 * @return Is the item (CBOR logical) null? 152 */ 153 bool cbor_is_null(const cbor_item_t* item); 154 155 /** Does this item represent `undefined` 156 * \rst 157 * .. warning:: Care must be taken to distinguish nulls and undefined values in 158 * C. \endrst 159 * @param item[borrow] the item 160 * @return Is the item (CBOR logical) undefined? 161 */ 162 bool cbor_is_undef(const cbor_item_t* item); 163 164 /* 165 * ============================================================================ 166 * Memory management 167 * ============================================================================ 168 */ 169 170 /** Increases the reference count by one 171 * 172 * No dependent items are affected. 173 * 174 * @param item[incref] item the item 175 * @return the input reference 176 */ 177 cbor_item_t* cbor_incref(cbor_item_t* item); 178 179 /** Decreases the reference count by one, deallocating the item if needed 180 * 181 * In case the item is deallocated, the reference count of any dependent items 182 * is adjusted accordingly in a recursive manner. 183 * 184 * @param item[take] the item. Set to `NULL` if deallocated 185 */ 186 void cbor_decref(cbor_item_t** item); 187 188 /** Decreases the reference count by one, deallocating the item if needed 189 * 190 * Convenience wrapper for #cbor_decref when its set-to-null behavior is not 191 * needed 192 * 193 * @param item[take] the item 194 */ 195 void cbor_intermediate_decref(cbor_item_t* item); 196 197 /** Get the reference count 198 * 199 * \rst 200 * .. warning:: This does *not* account for transitive references. 201 * \endrst 202 * 203 * @param item[borrow] the item 204 * @return the reference count 205 */ 206 size_t cbor_refcount(const cbor_item_t* item); 207 208 /** Provides CPP-like move construct 209 * 210 * Decreases the reference count by one, but does not deallocate the item even 211 * if its refcount reaches zero. This is useful for passing intermediate values 212 * to functions that increase reference count. Should only be used with 213 * functions that `incref` their arguments. 214 * 215 * \rst 216 * .. warning:: If the item is moved without correctly increasing the reference 217 * count afterwards, the memory will be leaked. \endrst 218 * 219 * @param item[take] the item 220 * @return the item with reference count decreased by one 221 */ 222 cbor_item_t* cbor_move(cbor_item_t* item);