QCBOR
Loading...
Searching...
No Matches
qcbor_private.h
1/* ==========================================================================
2 * Copyright (c) 2016-2018, The Linux Foundation.
3 * Copyright (c) 2018-2024, Laurence Lundblade.
4 * Copyright (c) 2021, Arm Limited.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials provided
15 * with the distribution.
16 * * Neither the name of The Linux Foundation nor the names of its
17 * contributors, nor the name "Laurence Lundblade" may be used to
18 * endorse or promote products derived from this software without
19 * specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
22 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
30 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
31 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * ========================================================================= */
33
34
35#ifndef qcbor_private_h
36#define qcbor_private_h
37
38
39#include <stdint.h>
40#include "UsefulBuf.h"
41#include "qcbor/qcbor_common.h"
42
43
44#ifdef __cplusplus
45extern "C" {
46#if 0
47} // Keep editor indention formatting happy
48#endif
49#endif
50
51
52/* This was originally defined as QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA,
53 * but this is inconsistent with all the other QCBOR_DISABLE_
54 * #defines, so the name was changed and this was added for backwards
55 * compatibility
56 */
57#ifdef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
58#define QCBOR_DISABLE_EXP_AND_MANTISSA
59#endif
60
61/* If USEFULBUF_DISABLE_ALL_FLOATis defined then define
62 * QCBOR_DISABLE_FLOAT_HW_USE and QCBOR_DISABLE_PREFERRED_FLOAT
63 */
64#ifdef USEFULBUF_DISABLE_ALL_FLOAT
65#ifndef QCBOR_DISABLE_FLOAT_HW_USE
66#define QCBOR_DISABLE_FLOAT_HW_USE
67#endif /* QCBOR_DISABLE_FLOAT_HW_USE */
68#ifndef QCBOR_DISABLE_PREFERRED_FLOAT
69#define QCBOR_DISABLE_PREFERRED_FLOAT
70#endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
71#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
72
73
74/*
75 * Convenience macro for selecting the proper return value in case floating
76 * point feature(s) are disabled.
77 *
78 * The macros:
79 *
80 * FLOAT_ERR_CODE_NO_FLOAT(x) Can be used when disabled floating point should
81 * result error, and all other cases should return
82 * 'x'.
83 *
84 * The below macros always return QCBOR_ERR_ALL_FLOAT_DISABLED when all
85 * floating point is disabled.
86 *
87 * FLOAT_ERR_CODE_NO_HALF_PREC(x) Can be used when disabled preferred float
88 * results in error, and all other cases should
89 * return 'x'.
90 * FLOAT_ERR_CODE_NO_FLOAT_HW(x) Can be used when disabled hardware floating
91 * point results in error, and all other cases
92 * should return 'x'.
93 * FLOAT_ERR_CODE_NO_HALF_PREC_NO_FLOAT_HW(x) Can be used when either disabled
94 * preferred float or disabling
95 * hardware floating point results in
96 * error, and all other cases should
97 * return 'x'.
98 */
99#ifdef USEFULBUF_DISABLE_ALL_FLOAT
100 #define FLOAT_ERR_CODE_NO_FLOAT(x) QCBOR_ERR_ALL_FLOAT_DISABLED
101 #define FLOAT_ERR_CODE_NO_HALF_PREC(x) QCBOR_ERR_ALL_FLOAT_DISABLED
102 #define FLOAT_ERR_CODE_NO_FLOAT_HW(x) QCBOR_ERR_ALL_FLOAT_DISABLED
103 #define FLOAT_ERR_CODE_NO_HALF_PREC_NO_FLOAT_HW(x) QCBOR_ERR_ALL_FLOAT_DISABLED
104#else /* USEFULBUF_DISABLE_ALL_FLOAT*/
105 #define FLOAT_ERR_CODE_NO_FLOAT(x) x
106 #ifdef QCBOR_DISABLE_PREFERRED_FLOAT
107 #define FLOAT_ERR_CODE_NO_HALF_PREC(x) QCBOR_ERR_HALF_PRECISION_DISABLED
108 #define FLOAT_ERR_CODE_NO_HALF_PREC_NO_FLOAT_HW(x) QCBOR_ERR_HALF_PRECISION_DISABLED
109 #else /* QCBOR_DISABLE_PREFERRED_FLOAT */
110 #define FLOAT_ERR_CODE_NO_HALF_PREC(x) x
111 #ifdef QCBOR_DISABLE_FLOAT_HW_USE
112 #define FLOAT_ERR_CODE_NO_HALF_PREC_NO_FLOAT_HW(x) QCBOR_ERR_HW_FLOAT_DISABLED
113 #else
114 #define FLOAT_ERR_CODE_NO_HALF_PREC_NO_FLOAT_HW(x) x
115 #endif
116 #endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
117 #ifdef QCBOR_DISABLE_FLOAT_HW_USE
118 #define FLOAT_ERR_CODE_NO_FLOAT_HW(x) QCBOR_ERR_HW_FLOAT_DISABLED
119 #else /* QCBOR_DISABLE_FLOAT_HW_USE */
120 #define FLOAT_ERR_CODE_NO_FLOAT_HW(x) x
121 #endif /* QCBOR_DISABLE_FLOAT_HW_USE */
122#endif /*USEFULBUF_DISABLE_ALL_FLOAT*/
123
124
125/*
126 * These are special values for the AdditionalInfo bits that are part of
127 * the first byte. Mostly they encode the length of the data item.
128 */
129#define LEN_IS_ONE_BYTE 24
130#define LEN_IS_TWO_BYTES 25
131#define LEN_IS_FOUR_BYTES 26
132#define LEN_IS_EIGHT_BYTES 27
133#define ADDINFO_RESERVED1 28
134#define ADDINFO_RESERVED2 29
135#define ADDINFO_RESERVED3 30
136#define LEN_IS_INDEFINITE 31
137
138
139/*
140 * 24 is a special number for CBOR. Integers and lengths
141 * less than it are encoded in the same byte as the major type.
142 */
143#define CBOR_TWENTY_FOUR 24
144
145
146/*
147 * Values for the 5 bits for items of major type 7
148 */
149#define CBOR_SIMPLEV_FALSE 20
150#define CBOR_SIMPLEV_TRUE 21
151#define CBOR_SIMPLEV_NULL 22
152#define CBOR_SIMPLEV_UNDEF 23
153#define CBOR_SIMPLEV_ONEBYTE 24
154#define HALF_PREC_FLOAT 25
155#define SINGLE_PREC_FLOAT 26
156#define DOUBLE_PREC_FLOAT 27
157#define CBOR_SIMPLE_BREAK 31
158#define CBOR_SIMPLEV_RESERVED_START CBOR_SIMPLEV_ONEBYTE
159#define CBOR_SIMPLEV_RESERVED_END CBOR_SIMPLE_BREAK
160
161
162/* The largest offset to the start of an array or map. It is slightly
163 * less than UINT32_MAX so the error condition can be tested on 32-bit
164 * machines. UINT32_MAX comes from uStart in QCBORTrackNesting being
165 * a uin32_t.
166 *
167 * This will cause trouble on a machine where size_t is less than 32-bits.
168 */
169#define QCBOR_MAX_ARRAY_OFFSET (UINT32_MAX - 100)
170
171
172/* The number of tags that are 16-bit or larger that can be handled
173 * in a decode.
174 */
175#define QCBOR_NUM_MAPPED_TAGS 4
176
177/* The number of tags (of any size) recorded for an individual item. */
178#define QCBOR_MAX_TAGS_PER_ITEM1 4
179
180
181
182
183/*
184 * PRIVATE DATA STRUCTURE
185 *
186 * Holds the data for tracking array and map nesting during
187 * encoding. Pairs up with the Nesting_xxx functions to make an
188 * "object" to handle nesting encoding.
189 *
190 * uStart is a uint32_t instead of a size_t to keep the size of this
191 * struct down so it can be on the stack without any concern. It
192 * would be about double if size_t was used instead.
193 *
194 * Size approximation (varies with CPU/compiler):
195 * 64-bit machine: (15 + 1) * (4 + 2 + 1 + 1 pad) + 8 = 136 bytes
196 * 32-bit machine: (15 + 1) * (4 + 2 + 1 + 1 pad) + 4 = 132 bytes
197 */
198typedef struct __QCBORTrackNesting {
199 /* PRIVATE DATA STRUCTURE */
200 struct {
201 /* See QCBOREncode_OpenMapOrArray() for details on how this works */
202 uint32_t uStart; /* uStart is the position where the array starts */
203 uint16_t uCount; /* Number of items in the arrary or map; counts items
204 * in a map, not pairs of items */
205 uint8_t uMajorType; /* Indicates if item is a map or an array */
206 } pArrays[QCBOR_MAX_ARRAY_NESTING+1], /* stored state for nesting levels */
207 *pCurrentNesting; /* the current nesting level */
208} QCBORTrackNesting;
209
210
211/*
212 * PRIVATE DATA STRUCTURE
213 *
214 * Context / data object for encoding some CBOR. Used by all encode
215 * functions to form a public "object" that does the job of encdoing.
216 *
217 * Size approximation (varies with CPU/compiler):
218 * 64-bit machine: 27 + 1 (+ 4 padding) + 136 = 32 + 136 = 168 bytes
219 * 32-bit machine: 15 + 1 + 132 = 148 bytes
220 */
222 /* PRIVATE DATA STRUCTURE */
223 UsefulOutBuf OutBuf; /* Pointer to output buffer, its length and
224 * position in it. */
225 uint8_t uError; /* Error state, always from QCBORError enum */
226 QCBORTrackNesting nesting; /* Keep track of array and map nesting */
227};
228
229
230/*
231 * PRIVATE DATA STRUCTURE
232 *
233 * Holds the data for array and map nesting for decoding work. This
234 * structure and the DecodeNesting_Xxx() functions in qcbor_decode.c
235 * form an "object" that does the work for arrays and maps. All access
236 * to this structure is through DecodeNesting_Xxx() functions.
237 *
238 * 64-bit machine size
239 * 128 = 16 * 8 for the two unions
240 * 64 = 16 * 4 for the uLevelType, 1 byte padded to 4 bytes for alignment
241 * 16 = 16 bytes for two pointers
242 * 208 TOTAL
243 *
244 * 32-bit machine size is 200 bytes
245 */
246typedef struct __QCBORDecodeNesting {
247 /* PRIVATE DATA STRUCTURE */
249 /*
250 * This keeps tracking info for each nesting level. There are two
251 * main types of levels:
252 * 1) Byte count tracking. This is for the top level input CBOR
253 * which might be a single item or a CBOR sequence and byte
254 * string wrapped encoded CBOR.
255 * 2) Item count tracking. This is for maps and arrays.
256 *
257 * uLevelType has value QCBOR_TYPE_BYTE_STRING for 1) and
258 * QCBOR_TYPE_MAP or QCBOR_TYPE_ARRAY or QCBOR_TYPE_MAP_AS_ARRAY
259 * for 2).
260 *
261 * Item count tracking is either for definite or indefinite-length
262 * maps/arrays. For definite lengths, the total count and items
263 * unconsumed are tracked. For indefinite-length, uTotalCount is
264 * QCBOR_COUNT_INDICATES_INDEFINITE_LENGTH (UINT16_MAX) and
265 * there is no per-item count of members. For indefinite-length
266 * maps and arrays, uCountCursor is UINT16_MAX if not consumed
267 * and zero if it is consumed in the pre-order
268 * traversal. Additionally, if entered in bounded mode,
269 * uCountCursor is QCBOR_COUNT_INDICATES_ZERO_LENGTH to indicate
270 * it is empty.
271 *
272 * This also records whether a level is bounded or not. All
273 * byte-count tracked levels (the top-level sequence and
274 * bstr-wrapped CBOR) are bounded implicitly. Maps and arrays
275 * may or may not be bounded. They are bounded if they were
276 * Entered() and not if they were traversed with GetNext(). They
277 * are marked as bounded by uStartOffset not being @c UINT32_MAX.
278 */
279 /*
280 * If uLevelType can put in a separately indexed array, the
281 * union/struct will be 8 bytes rather than 9 and a lot of
282 * wasted padding for alignment will be saved.
283 */
284 uint8_t uLevelType;
285 union {
286 struct {
287#define QCBOR_COUNT_INDICATES_INDEFINITE_LENGTH UINT16_MAX
288#define QCBOR_COUNT_INDICATES_ZERO_LENGTH UINT16_MAX-1
289 uint16_t uCountTotal;
290 uint16_t uCountCursor;
291#define QCBOR_NON_BOUNDED_OFFSET UINT32_MAX
292 /* The start of the array or map in bounded mode so
293 * the input can be rewound for GetInMapXx() by label. */
294 uint32_t uStartOffset;
295 } ma; /* for maps and arrays */
296 struct {
297 /* The end of the input before the bstr was entered so that
298 * it can be restored when the bstr is exited. */
299 uint32_t uSavedEndOffset;
300 /* The beginning of the bstr so that it can be rewound. */
301 uint32_t uBstrStartOffset;
302 } bs; /* for top-level sequence and bstr-wrapped CBOR */
303 } u;
304 } pLevels[QCBOR_MAX_ARRAY_NESTING+1],
305 *pCurrent,
306 *pCurrentBounded;
307 /*
308 * pCurrent is for item-by-item pre-order traversal.
309 *
310 * pCurrentBounded points to the current bounding level or is NULL
311 * if there isn't one.
312 *
313 * pCurrent must always be below pCurrentBounded as the pre-order
314 * traversal is always bounded by the bounding level.
315 *
316 * When a bounded level is entered, the pre-order traversal is set
317 * to the first item in the bounded level. When a bounded level is
318 * exited, the pre-order traversl is set to the next item after the
319 * map, array or bstr. This may be more than one level up, or even
320 * the end of the input CBOR.
321 */
322} QCBORDecodeNesting;
323
324
325typedef struct {
326 /* PRIVATE DATA STRUCTURE */
327 void *pAllocateCxt;
328 UsefulBuf (* pfAllocator)(void *pAllocateCxt, void *pOldMem, size_t uNewSize);
330
331
332/*
333 * PRIVATE DATA STRUCTURE
334 *
335 * The decode context. This data structure plus the public
336 * QCBORDecode_xxx functions form an "object" that does CBOR decoding.
337 *
338 * Size approximation (varies with CPU/compiler):
339 * 64-bit machine: 32 + 1 + 1 + 6 bytes padding + 72 + 16 + 8 + 8 = 144 bytes
340 * 32-bit machine: 16 + 1 + 1 + 2 bytes padding + 68 + 8 + 8 + 4 = 108 bytes
341 */
343 /* PRIVATE DATA STRUCTURE */
344 UsefulInputBuf InBuf;
345
346 QCBORDecodeNesting nesting;
347
348 /* If a string allocator is configured for indefinite-length
349 * strings, it is configured here.
350 */
351 QCBORInternalAllocator StringAllocator;
352
353 /* These are special for the internal MemPool allocator. They are
354 * not used otherwise. We tried packing these in the MemPool
355 * itself, but there are issues with memory alignment.
356 */
357 uint32_t uMemPoolSize;
358 uint32_t uMemPoolFreeOffset;
359
360 /* A cached offset to the end of the current map 0 if no value is
361 * cached.
362 */
363#define QCBOR_MAP_OFFSET_CACHE_INVALID UINT32_MAX
364 uint32_t uMapEndOffsetCache;
365
366 uint8_t uDecodeMode;
367 uint8_t bStringAllocateAll;
368 uint8_t uLastError; /* QCBORError stuffed into a uint8_t */
369
370 /* See MapTagNumber() for description of how tags are mapped. */
371 uint64_t auMappedTags[QCBOR_NUM_MAPPED_TAGS];
372
373 uint16_t uLastTags[QCBOR_MAX_TAGS_PER_ITEM1];
374};
375
376
377/* Used internally in the impementation here Must not conflict with
378 * any of the official CBOR types
379 */
380#define CBOR_MAJOR_NONE_TAG_LABEL_REORDER 10
381#define CBOR_MAJOR_NONE_TYPE_OPEN_BSTR 12
382
383
384/* Add this to types to indicate they are to be encoded as indefinite lengths */
385#define QCBOR_INDEFINITE_LEN_TYPE_MODIFIER 0x80
386#define CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN \
387 CBOR_MAJOR_TYPE_ARRAY + QCBOR_INDEFINITE_LEN_TYPE_MODIFIER
388#define CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN \
389 CBOR_MAJOR_TYPE_MAP + QCBOR_INDEFINITE_LEN_TYPE_MODIFIER
390#define CBOR_MAJOR_NONE_TYPE_SIMPLE_BREAK \
391 CBOR_MAJOR_TYPE_SIMPLE + QCBOR_INDEFINITE_LEN_TYPE_MODIFIER
392
393
394/* Value of QCBORItem.val.string.len when the string length is
395 * indefinite. Used temporarily in the implementation and never
396 * returned in the public interface.
397 */
398#define QCBOR_STRING_LENGTH_INDEFINITE SIZE_MAX
399
400
401/* The number of elements in a C array of a particular type */
402#define C_ARRAY_COUNT(array, type) (sizeof(array)/sizeof(type))
403
404
405#ifdef __cplusplus
406}
407#endif
408
409#endif /* qcbor_private_h */
struct q_useful_buf UsefulBuf
struct useful_input_buf UsefulInputBuf
struct useful_out_buf UsefulOutBuf
#define QCBOR_MAX_ARRAY_NESTING
Definition qcbor_common.h:577
Definition qcbor_private.h:248
Definition qcbor_private.h:246
Definition qcbor_private.h:198
Definition qcbor_private.h:342
Definition qcbor_private.h:221
Definition qcbor_private.h:325