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);