QCBOR
Toggle main menu visibility
Loading...
Searching...
No Matches
inc
qcbor
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
45
extern
"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
*/
198
typedef
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
*/
221
struct
_QCBOREncodeContext
{
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
*/
246
typedef
struct
__QCBORDecodeNesting
{
247
/* PRIVATE DATA STRUCTURE */
248
struct
nesting_decode_level
{
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
325
typedef
struct
{
326
/* PRIVATE DATA STRUCTURE */
327
void
*pAllocateCxt;
328
UsefulBuf
(* pfAllocator)(
void
*pAllocateCxt,
void
*pOldMem,
size_t
uNewSize);
329
}
QCBORInternalAllocator
;
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
*/
342
struct
_QCBORDecodeContext
{
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 */
UsefulBuf.h
UsefulBuf
struct q_useful_buf UsefulBuf
UsefulInputBuf
struct useful_input_buf UsefulInputBuf
UsefulOutBuf
struct useful_out_buf UsefulOutBuf
qcbor_common.h
QCBOR_MAX_ARRAY_NESTING
#define QCBOR_MAX_ARRAY_NESTING
Definition
qcbor_common.h:577
__QCBORDecodeNesting::nesting_decode_level
Definition
qcbor_private.h:248
__QCBORDecodeNesting
Definition
qcbor_private.h:246
__QCBORTrackNesting
Definition
qcbor_private.h:198
_QCBORDecodeContext
Definition
qcbor_private.h:342
_QCBOREncodeContext
Definition
qcbor_private.h:221
QCBORInternalAllocator
Definition
qcbor_private.h:325
Generated by
1.17.0