blob: d541a106473de09a78256e3f53f184429abb7ed2 [file] [log] [blame]
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001/*==============================================================================
2 Copyright (c) 2016-2018, The Linux Foundation.
3 Copyright (c) 2018-2019, Laurence Lundblade.
4 All rights reserved.
5
6Redistribution and use in source and binary forms, with or without
7modification, are permitted provided that the following conditions are
8met:
9 * Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above
12 copyright notice, this list of conditions and the following
13 disclaimer in the documentation and/or other materials provided
14 with the distribution.
15 * Neither the name of The Linux Foundation nor the names of its
16 contributors, nor the name "Laurence Lundblade" may be used to
17 endorse or promote products derived from this software without
18 specific prior written permission.
19
20THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
21WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
23ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
24BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
30IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 ==============================================================================*/
32
33
34/*===================================================================================
35 FILE: qcbor.h
36
37 DESCRIPTION: This is the full public API and data structures for QCBOR
38
39 EDIT HISTORY FOR FILE:
40
41 This section contains comments describing changes made to the module.
42 Notice that changes are listed in reverse chronological order.
43
Laurence Lundblade852a33c2019-06-11 09:00:07 -070044 when who what, where, why
45 -------- ---- ---------------------------------------------------
Laurence Lundblade234fe422019-12-02 13:04:34 -080046 08/7/19 llundblade Better handling of not well-formed encode and decode.
47 07/31/19 llundblade New error code for better end of data handling.
48 7/25/19 janjongboom Add indefinite length encoding for maps and arrays.
Laurence Lundblade852a33c2019-06-11 09:00:07 -070049 05/26/19 llundblade Add QCBOREncode_GetErrorState() and _IsBufferNULL().
50 04/26/19 llundblade Big documentation & style update. No interface change.
51 02/16/19 llundblade Redesign MemPool to fix memory access alignment bug.
52 12/18/18 llundblade Move decode malloc optional code to separate repository.
53 12/13/18 llundblade Documentatation improvements.
54 11/29/18 llundblade Rework to simpler handling of tags and labels.
55 11/9/18 llundblade Error codes are now enums.
56 11/1/18 llundblade Floating support.
57 10/31/18 llundblade Switch to one license that is almost BSD-3.
58 10/15/18 llundblade indefinite-length maps and arrays supported
59 10/8/18 llundblade indefinite-length strings supported
60 09/28/18 llundblade Added bstr wrapping feature for COSE implementation.
61 07/05/17 llundbla Add bstr wrapping of maps/arrays for COSE.
62 03/01/17 llundbla More data types; decoding improvements and fixes.
63 11/13/16 llundbla Integrate most TZ changes back into github version.
64 09/30/16 gkanike Porting to TZ.
65 03/15/16 llundbla Initial Version.
Laurence Lundblade6ed34222018-12-18 09:46:23 -080066
67 =====================================================================================*/
68
69#ifndef __QCBOR__qcbor__
70#define __QCBOR__qcbor__
71
Laurence Lundblade6ed34222018-12-18 09:46:23 -080072
73/* ===========================================================================
74 BEGINNING OF PRIVATE PART OF THIS FILE
75
76 Caller of QCBOR should not reference any of the details below up until
77 the start of the public part.
78 =========================================================================== */
79
80/*
81 Standard integer types are used in the interface to be precise about
82 sizes to be better at preventing underflow/overflow errors.
83 */
84#include <stdint.h>
85#include <stdbool.h>
86#include "UsefulBuf.h"
87
Laurence Lundbladed425fb32019-02-18 10:56:18 -080088#ifdef __cplusplus
89extern "C" {
90#endif
Laurence Lundblade6ed34222018-12-18 09:46:23 -080091
92/*
93 The maxium nesting of arrays and maps when encoding or decoding.
94 (Further down in the file there is a definition that refers to this
95 that is public. This is done this way so there can be a nice
96 separation of public and private parts in this file.
97*/
98#define QCBOR_MAX_ARRAY_NESTING1 15 // Do not increase this over 255
99
100
101/* The largest offset to the start of an array or map. It is slightly
102 less than UINT32_MAX so the error condition can be tests on 32-bit machines.
103 UINT32_MAX comes from uStart in QCBORTrackNesting being a uin32_t.
104
105 This will cause trouble on a machine where size_t is less than 32-bits.
106 */
107#define QCBOR_MAX_ARRAY_OFFSET (UINT32_MAX - 100)
108
109/*
110 PRIVATE DATA STRUCTURE
111
112 Holds the data for tracking array and map nesting during encoding. Pairs up with
113 the Nesting_xxx functions to make an "object" to handle nesting encoding.
114
115 uStart is a uint32_t instead of a size_t to keep the size of this
116 struct down so it can be on the stack without any concern. It would be about
117 double if size_t was used instead.
118
119 Size approximation (varies with CPU/compiler):
120 64-bit machine: (15 + 1) * (4 + 2 + 1 + 1 pad) + 8 = 136 bytes
121 32-bit machine: (15 + 1) * (4 + 2 + 1 + 1 pad) + 4 = 132 bytes
122*/
123typedef struct __QCBORTrackNesting {
124 // PRIVATE DATA STRUCTURE
125 struct {
126 // See function OpenArrayInternal() for detailed comments on how this works
127 uint32_t uStart; // uStart is the byte position where the array starts
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700128 uint16_t uCount; // Number of items in the arrary or map; counts items
129 // in a map, not pairs of items
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800130 uint8_t uMajorType; // Indicates if item is a map or an array
131 } pArrays[QCBOR_MAX_ARRAY_NESTING1+1], // stored state for the nesting levels
132 *pCurrentNesting; // the current nesting level
133} QCBORTrackNesting;
134
135
136/*
137 PRIVATE DATA STRUCTURE
138
139 Context / data object for encoding some CBOR. Used by all encode functions to
140 form a public "object" that does the job of encdoing.
141
142 Size approximation (varies with CPU/compiler):
143 64-bit machine: 27 + 1 (+ 4 padding) + 136 = 32 + 136 = 168 bytes
144 32-bit machine: 15 + 1 + 132 = 148 bytes
145*/
146struct _QCBOREncodeContext {
147 // PRIVATE DATA STRUCTURE
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700148 UsefulOutBuf OutBuf; // Pointer to output buffer, its length and
149 // position in it
150 uint8_t uError; // Error state, always from QCBORError enum
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800151 QCBORTrackNesting nesting; // Keep track of array and map nesting
152};
153
154
155/*
156 PRIVATE DATA STRUCTURE
157
158 Holds the data for array and map nesting for decoding work. This structure
159 and the DecodeNesting_xxx functions form an "object" that does the work
160 for arrays and maps.
161
162 Size approximation (varies with CPU/compiler):
163 64-bit machine: 4 * 16 + 8 = 72
164 32-bit machine: 4 * 16 + 4 = 68
165 */
166typedef struct __QCBORDecodeNesting {
167 // PRIVATE DATA STRUCTURE
168 struct {
169 uint16_t uCount;
170 uint8_t uMajorType;
171 } pMapsAndArrays[QCBOR_MAX_ARRAY_NESTING1+1],
172 *pCurrent;
173} QCBORDecodeNesting;
174
175
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800176typedef struct {
177 // PRIVATE DATA STRUCTURE
178 void *pAllocateCxt;
179 UsefulBuf (* pfAllocator)(void *pAllocateCxt, void *pOldMem, size_t uNewSize);
180} QCORInternalAllocator;
181
182
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800183/*
184 PRIVATE DATA STRUCTURE
185
186 The decode context. This data structure plus the public QCBORDecode_xxx
187 functions form an "object" that does CBOR decoding.
188
189 Size approximation (varies with CPU/compiler):
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800190 64-bit machine: 32 + 1 + 1 + 6 bytes padding + 72 + 16 + 8 + 8 = 144 bytes
191 32-bit machine: 16 + 1 + 1 + 2 bytes padding + 68 + 8 + 8 + 4 = 108 bytes
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800192 */
193struct _QCBORDecodeContext {
194 // PRIVATE DATA STRUCTURE
195 UsefulInputBuf InBuf;
196
197 uint8_t uDecodeMode;
198 uint8_t bStringAllocateAll;
199
200 QCBORDecodeNesting nesting;
201
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700202 // If a string allocator is configured for indefinite-length
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800203 // strings, it is configured here.
204 QCORInternalAllocator StringAllocator;
205
206 // These are special for the internal MemPool allocator.
207 // They are not used otherwise. We tried packing these
208 // in the MemPool itself, but there are issues
209 // with memory alignment.
210 uint32_t uMemPoolSize;
211 uint32_t uMemPoolFreeOffset;
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800212
213 // This is NULL or points to QCBORTagList.
214 // It is type void for the same reason as above.
215 const void *pCallerConfiguredTagList;
216};
217
218// Used internally in the impementation here
219// Must not conflict with any of the official CBOR types
220#define CBOR_MAJOR_NONE_TYPE_RAW 9
221#define CBOR_MAJOR_NONE_TAG_LABEL_REORDER 10
Laurence Lundbladec93b5a72019-04-06 12:17:16 -0700222#define CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY 11
Laurence Lundblade234fe422019-12-02 13:04:34 -0800223#define CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN 12
224#define CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN 13
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800225
226
227/* ===========================================================================
228 END OF PRIVATE PART OF THIS FILE
229
230 BEGINNING OF PUBLIC PART OF THIS FILE
231 =========================================================================== */
232
233
234
235/* ===========================================================================
236 BEGINNING OF CONSTANTS THAT COME FROM THE CBOR STANDARD, RFC 7049
237
238 It is not necessary to use these directly when encoding or decoding
239 CBOR with this implementation.
240 =========================================================================== */
241
242/* Standard CBOR Major type for positive integers of various lengths */
243#define CBOR_MAJOR_TYPE_POSITIVE_INT 0
244
245/* Standard CBOR Major type for negative integer of various lengths */
246#define CBOR_MAJOR_TYPE_NEGATIVE_INT 1
247
248/* Standard CBOR Major type for an array of arbitrary 8-bit bytes. */
249#define CBOR_MAJOR_TYPE_BYTE_STRING 2
250
251/* Standard CBOR Major type for a UTF-8 string. Note this is true 8-bit UTF8
252 with no encoding and no NULL termination */
253#define CBOR_MAJOR_TYPE_TEXT_STRING 3
254
255/* Standard CBOR Major type for an ordered array of other CBOR data items */
256#define CBOR_MAJOR_TYPE_ARRAY 4
257
258/* Standard CBOR Major type for CBOR MAP. Maps an array of pairs. The
259 first item in the pair is the "label" (key, name or identfier) and the second
260 item is the value. */
261#define CBOR_MAJOR_TYPE_MAP 5
262
263/* Standard CBOR optional tagging. This tags things like dates and URLs */
264#define CBOR_MAJOR_TYPE_OPTIONAL 6
265
266/* Standard CBOR extra simple types like floats and the values true and false */
267#define CBOR_MAJOR_TYPE_SIMPLE 7
268
269
270/*
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700271 These are special values for the AdditionalInfo bits that are part of
272 the first byte. Mostly they encode the length of the data item.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800273 */
274#define LEN_IS_ONE_BYTE 24
275#define LEN_IS_TWO_BYTES 25
276#define LEN_IS_FOUR_BYTES 26
277#define LEN_IS_EIGHT_BYTES 27
278#define ADDINFO_RESERVED1 28
279#define ADDINFO_RESERVED2 29
280#define ADDINFO_RESERVED3 30
281#define LEN_IS_INDEFINITE 31
282
283
284/*
285 24 is a special number for CBOR. Integers and lengths
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700286 less than it are encoded in the same byte as the major type.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800287 */
288#define CBOR_TWENTY_FOUR 24
289
290
291/*
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700292 Tags that are used with CBOR_MAJOR_TYPE_OPTIONAL. These
293 are types defined in RFC 7049 and some additional ones
294 in the IANA CBOR tags registry.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800295 */
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700296/** See QCBOREncode_AddDateString(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800297#define CBOR_TAG_DATE_STRING 0
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700298/** See QCBOREncode_AddDateEpoch(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800299#define CBOR_TAG_DATE_EPOCH 1
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700300/** See QCBOREncode_AddPositiveBignum(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800301#define CBOR_TAG_POS_BIGNUM 2
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700302/** See QCBOREncode_AddNegativeBignum(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800303#define CBOR_TAG_NEG_BIGNUM 3
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700304/** CBOR tag for a two-element array representing a fraction with a
305 mantissa and base-10 scaling factor. No API is provided for this
306 tag. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800307#define CBOR_TAG_FRACTION 4
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700308/** CBOR tag for a two-element array representing a fraction with a
309 mantissa and base-2 scaling factor. No API is provided for this
310 tag. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800311#define CBOR_TAG_BIGFLOAT 5
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700312/** Tag for COSE format encryption with no recipient
313 identification. See [RFC 8152, COSE]
314 (https://tools.ietf.org/html/rfc8152). No API is provided for this
315 tag. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800316#define CBOR_TAG_COSE_ENCRYPTO 16
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700317/** Tag for COSE format MAC'd data with no recipient
318 identification. See [RFC 8152, COSE]
319 (https://tools.ietf.org/html/rfc8152). No API is provided for this
320 tag.*/
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800321#define CBOR_TAG_COSE_MAC0 17
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700322/** Tag for COSE format single signature signing. No API is provided
323 for this tag. See [RFC 8152, COSE]
324 (https://tools.ietf.org/html/rfc8152). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800325#define CBOR_TAG_COSE_SIGN1 18
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700326/** A hint that the following byte string should be encoded in
327 Base64URL when converting to JSON or similar text-based
328 representations. Call @c
329 QCBOREncode_AddTag(pCtx,CBOR_TAG_ENC_AS_B64URL) before the call to
330 QCBOREncode_AddBytes(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800331#define CBOR_TAG_ENC_AS_B64URL 21
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700332/** A hint that the following byte string should be encoded in Base64
333 when converting to JSON or similar text-based
334 representations. Call @c
335 QCBOREncode_AddTag(pCtx,CBOR_TAG_ENC_AS_B64) before the call to
336 QCBOREncode_AddBytes(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800337#define CBOR_TAG_ENC_AS_B64 22
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700338/** A hint that the following byte string should be encoded in base-16
339 format per [RFC 4648] (https://tools.ietf.org/html/rfc4648) when
340 converting to JSON or similar text-based
341 representations. Essentially, Base-16 encoding is the standard
342 case- insensitive hex encoding and may be referred to as
343 "hex". Call @c QCBOREncode_AddTag(pCtx,CBOR_TAG_ENC_AS_B16) before
344 the call to QCBOREncode_AddBytes(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800345#define CBOR_TAG_ENC_AS_B16 23
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700346/** Tag to indicate a byte string contains encoded CBOR. No API is
347 provided for this tag. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800348#define CBOR_TAG_CBOR 24
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700349/** See QCBOREncode_AddURI(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800350#define CBOR_TAG_URI 32
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700351/** See QCBOREncode_AddB64URLText(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800352#define CBOR_TAG_B64URL 33
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700353/** See QCBOREncode_AddB64Text(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800354#define CBOR_TAG_B64 34
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700355/** See QCBOREncode_AddRegex(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800356#define CBOR_TAG_REGEX 35
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700357/** See QCBOREncode_AddMIMEData(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800358#define CBOR_TAG_MIME 36
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700359/** See QCBOREncode_AddBinaryUUID(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800360#define CBOR_TAG_BIN_UUID 37
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700361/** The data is a CBOR Web Token per [RFC 8392]
362 (https://tools.ietf.org/html/rfc8932). No API is provided for this
363 tag. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800364#define CBOR_TAG_CWT 61
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700365/** Tag for COSE format encryption. See [RFC 8152, COSE]
366 (https://tools.ietf.org/html/rfc8152). No API is provided for this
367 tag. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800368#define CBOR_TAG_ENCRYPT 96
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700369/** Tag for COSE format MAC. See [RFC 8152, COSE]
370 (https://tools.ietf.org/html/rfc8152). No API is provided for this
371 tag. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800372#define CBOR_TAG_MAC 97
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700373/** Tag for COSE format signed data. See [RFC 8152, COSE]
374 (https://tools.ietf.org/html/rfc8152). No API is provided for this
375 tag. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800376#define CBOR_TAG_SIGN 98
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700377/** World geographic coordinates. See ISO 6709, [RFC 5870]
378 (https://tools.ietf.org/html/rfc5870) and WGS-84. No API is
379 provided for this tag. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800380#define CBOR_TAG_GEO_COORD 103
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700381/** The magic number, self-described CBOR. No API is provided for this
382 tag. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800383#define CBOR_TAG_CBOR_MAGIC 55799
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700384
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800385#define CBOR_TAG_NONE UINT64_MAX
386
387
388/*
389 Values for the 5 bits for items of major type 7
390 */
391#define CBOR_SIMPLEV_FALSE 20
392#define CBOR_SIMPLEV_TRUE 21
393#define CBOR_SIMPLEV_NULL 22
394#define CBOR_SIMPLEV_UNDEF 23
395#define CBOR_SIMPLEV_ONEBYTE 24
396#define HALF_PREC_FLOAT 25
397#define SINGLE_PREC_FLOAT 26
398#define DOUBLE_PREC_FLOAT 27
399#define CBOR_SIMPLE_BREAK 31
Laurence Lundblade234fe422019-12-02 13:04:34 -0800400#define CBOR_SIMPLEV_RESERVED_START CBOR_SIMPLEV_ONEBYTE
401#define CBOR_SIMPLEV_RESERVED_END CBOR_SIMPLE_BREAK
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800402
403
404
405/* ===========================================================================
406
407 END OF CONSTANTS THAT COME FROM THE CBOR STANDARD, RFC 7049
408
409 BEGINNING OF PUBLIC INTERFACE FOR QCBOR ENCODER / DECODER
410
411 =========================================================================== */
412
413/**
414
415 @file qcbor.h
416
417 Q C B O R E n c o d e / D e c o d e
418
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700419 This implements CBOR -- Concise Binary Object Representation as
420 defined in [RFC 7049] (https://tools.ietf.org/html/rfc7049). More
421 info is at http://cbor.io. This is a near-complete implementation of
422 the specification. Limitations are listed further down.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800423
424 CBOR is intentionally designed to be translatable to JSON, but not
425 all CBOR can convert to JSON. See RFC 7049 for more info on how to
426 construct CBOR that is the most JSON friendly.
427
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700428 The memory model for encoding and decoding is that encoded CBOR must
429 be in a contiguous buffer in memory. During encoding the caller must
430 supply an output buffer and if the encoding would go off the end of
431 the buffer an error is returned. During decoding the caller supplies
432 the encoded CBOR in a contiguous buffer and the decoder returns
433 pointers and lengths into that buffer for strings.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800434
435 This implementation does not require malloc. All data structures
436 passed in/out of the APIs can fit on the stack.
437
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700438 Decoding of indefinite-length strings is a special case that requires
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800439 a "string allocator" to allocate memory into which the segments of
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700440 the string are coalesced. Without this, decoding will error out if an
441 indefinite-length string is encountered (indefinite-length maps and
442 arrays do not require the string allocator). A simple string
443 allocator called MemPool is built-in and will work if supplied with a
444 block of memory to allocate. The string allocator can optionally use
445 malloc() or some other custom scheme.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800446
447 Here are some terms and definitions:
448
449 - "Item", "Data Item": An integer or string or such. The basic "thing" that
450 CBOR is about. An array is an item itself that contains some items.
451
452 - "Array": An ordered sequence of items, the same as JSON.
453
454 - "Map": A collection of label/value pairs. Each pair is a data
455 item. A JSON "object" is the same as a CBOR "map".
456
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700457 - "Label": The data item in a pair in a map that names or identifies
458 the pair, not the value. This implementation refers to it as a
459 "label". JSON refers to it as the "name". The CBOR RFC refers to it
460 this as a "key". This implementation chooses label instead because
461 key is too easily confused with a cryptographic key. The COSE
462 standard, which uses CBOR, has also chosen to use the term "label"
463 rather than "key" for this same reason.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800464
465 - "Key": See "Label" above.
466
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700467 - "Tag": Optional integer that can be added before each data item
468 usually to indicate it is new or more specific data type. For
469 example, a tag can indicate an integer is a date, or that a map is to
470 be considered a type (analogous to a typedef in C).
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800471
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700472 - "Initial Byte": The first byte of an encoded item. Encoding and
473 decoding of this byte is taken care of by the implementation.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800474
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700475 - "Additional Info": In addition to the major type, all data items
476 have some other info. This is usually the length of the data but can
477 be several other things. Encoding and decoding of this is taken care
478 of by the implementation.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800479
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700480 CBOR has two mechanisms for tagging and labeling the data values like
481 integers and strings. For example, an integer that represents
482 someone's birthday in epoch seconds since Jan 1, 1970 could be
483 encoded like this:
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800484
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700485 - First it is CBOR_MAJOR_TYPE_POSITIVE_INT (@ref QCBOR_TYPE_INT64),
486 the primitive positive integer.
487
488 - Next it has a "tag" @ref CBOR_TAG_DATE_EPOCH indicating the integer
489 represents a date in the form of the number of seconds since Jan 1,
490 1970.
491
492 - Last it has a string "label" like "BirthDate" indicating the
493 meaning of the data.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800494
495 The encoded binary looks like this:
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800496
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700497 a1 # Map of 1 item
498 69 # Indicates text string of 9 bytes
499 426972746844617465 # The text "BirthDate"
500 c1 # Tags next integer as epoch date
501 1a # Indicates a 4-byte integer
502 580d4172 # unsigned integer date 1477263730
503
504 Implementors using this API will primarily work with
505 labels. Generally, tags are only needed for making up new data
506 types. This implementation covers most of the data types defined in
507 the RFC using tags. It also, allows for the use of custom tags if
508 necessary.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800509
510 This implementation explicitly supports labels that are text strings
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700511 and integers. Text strings translate nicely into JSON objects and are
512 very readable. Integer labels are much less readable but can be very
513 compact. If they are in the range of 0 to 23, they take up only one
514 byte.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800515
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700516 CBOR allows a label to be any type of data including an array or a
517 map. It is possible to use this API to construct and parse such
518 labels, but it is not explicitly supported.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800519
520 A common encoding usage mode is to invoke the encoding twice. First
521 with no output buffer to compute the length of the needed output
522 buffer. Then the correct sized output buffer is allocated. Last the
523 encoder is invoked again, this time with the output buffer.
524
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700525 The double invocation is not required if the maximum output buffer
526 size can be predicted. This is usually possible for simple CBOR
527 structures. If the double invocation is implemented, it can be in a
528 loop or function as in the example code so that the code doesn't have
529 to actually be written twice, saving code size.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800530
531 If a buffer too small to hold the encoded output is given, the error
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700532 @ref QCBOR_ERR_BUFFER_TOO_SMALL will be returned. Data will never be
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800533 written off the end of the output buffer no matter which functions
534 here are called or what parameters are passed to them.
535
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700536 The encoding error handling is simple. The only possible errors are
537 trying to encode structures that are too large or too complex. There
538 are no internal malloc calls so there will be no failures for out of
Laurence Lundblade234fe422019-12-02 13:04:34 -0800539 memory. The error state is tracked internally, so there is no need
540 to check for errors when encoding. Only the return code from
541 QCBOREncode_Finish() need be checked as once an error happens, the
542 encoder goes into an error state and calls to it to add more data
543 will do nothing. An error check is not needed after every data item
544 is added.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800545
546 Encoding generally proceeds by calling QCBOREncode_Init(), calling
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700547 lots of @c QCBOREncode_AddXxx() functions and calling
548 QCBOREncode_Finish(). There are many @c QCBOREncode_AddXxx()
549 functions for various data types. The input buffers need only to be
550 valid during the @c QCBOREncode_AddXxx() calls as the data is copied
551 into the output buffer.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800552
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700553 There are three `Add` functions for each data type. The first / main
554 one for the type is for adding the data item to an array. The second
555 one's name ends in `ToMap`, is used for adding data items to maps and
556 takes a string argument that is its label in the map. The third one
557 ends in `ToMapN`, is also used for adding data items to maps, and
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800558 takes an integer argument that is its label in the map.
559
560 The simplest aggregate type is an array, which is a simple ordered
561 set of items without labels the same as JSON arrays. Call
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700562 QCBOREncode_OpenArray() to open a new array, then various @c
563 QCBOREncode_AddXxx() functions to put items in the array and then
564 QCBOREncode_CloseArray(). Nesting to the limit @ref
565 QCBOR_MAX_ARRAY_NESTING is allowed. All opens must be matched by
566 closes or an encoding error will be returned.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800567
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700568 The other aggregate type is a map which does use labels. The `Add`
569 functions that end in `ToMap` and `ToMapN` are convenient ways to add
570 labeled data items to a map. You can also call any type of `Add`
571 function once to add a label of any time and then call any type of
572 `Add` again to add its value.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800573
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700574 Note that when you nest arrays or maps in a map, the nested array or
575 map has a label.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800576
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700577 @anchor Tags-Overview
578 Any CBOR data item can be tagged to add semantics, define a new data
579 type or such. Some tags are fully standardized and some are just
580 registered. Others are not registered and used in a proprietary way.
581
582 Encoding and decoding of many of the registered tags is fully
583 implemented by QCBOR. It is also possible to encode and decode tags
584 that are not directly supported. For many use cases the built-in tag
585 support should be adequate.
586
587 For example, the registered epoch date tag is supported in encoding
588 by QCBOREncode_AddDateEpoch() and in decoding by @ref
589 QCBOR_TYPE_DATE_EPOCH and the @c epochDate member of @ref
590 QCBORItem. This is typical of the built-in tag support. There is an
591 API to encode data for it and a @c QCBOR_TYPE_XXX when it is decoded.
592
593 Tags are registered in the [IANA CBOR Tags Registry]
594 (https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml). There
595 are roughly three options to create a new tag. First, a public
596 specification can be created and the new tag registered with IANA.
597 This is the most formal. Second, the new tag can be registered with
598 IANA with just a short description rather than a full specification.
599 These tags must be greater than 256. Third, a tag can be used without
600 any IANA registration, though the registry should be checked to see
601 that the new value doesn't collide with one that is registered. The
602 value of these tags must be 256 or larger.
603
604 The encoding side of tags not built-in is handled by
605 QCBOREncode_AddTag() and is relatively simple. Tag decoding is more
606 complex and mainly handled by QCBORDecode_GetNext(). Decoding of the
607 structure of tagged data not built-in (if there is any) has to be
608 implemented by the caller.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800609
610 Summary Limits of this implementation:
611 - The entire encoded CBOR must fit into contiguous memory.
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700612 - Max size of encoded / decoded CBOR data is @c UINT32_MAX (4GB).
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800613 - Max array / map nesting level when encoding / decoding is
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700614 @ref QCBOR_MAX_ARRAY_NESTING (this is typically 15).
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800615 - Max items in an array or map when encoding / decoding is
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700616 @ref QCBOR_MAX_ITEMS_IN_ARRAY (typically 65,536).
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800617 - Does not directly support some tagged types: decimal fractions, big floats
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700618 - Does not directly support labels in maps other than text strings and integers.
619 - Does not directly support integer labels greater than @c INT64_MAX.
620 - Epoch dates limited to @c INT64_MAX (+/- 292 billion years).
621 - Tags on labels are ignored during decoding.
622 - Works only on 32- and 64-bit CPUs (modifications could make it work
623 on 16-bit CPUs).
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800624
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700625 The public interface uses @c size_t for all lengths. Internally the
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800626 implementation uses 32-bit lengths by design to use less memory and
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700627 fit structures on the stack. This limits the encoded CBOR it can work
628 with to size @c UINT32_MAX (4GB) which should be enough.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800629
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700630 This implementation assumes two's compliment integer machines. @c
631 <stdint.h> also requires this. It is possible to modify this
632 implementation for another integer representation, but all modern
633 machines seem to be two's compliment.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800634
635 */
636
637
638/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700639 The maximum number of items in a single array or map when encoding of
640 decoding.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800641*/
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700642// -1 is because the value UINT16_MAX is used to track indefinite-length arrays
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800643#define QCBOR_MAX_ITEMS_IN_ARRAY (UINT16_MAX-1)
644
645/**
646 The maximum nesting of arrays and maps when encoding or decoding. The
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700647 error @ref QCBOR_ERR_ARRAY_NESTING_TOO_DEEP will be returned on
648 encoding of decoding if it is exceeded.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800649*/
650#define QCBOR_MAX_ARRAY_NESTING QCBOR_MAX_ARRAY_NESTING1
651
652/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700653 The maximum number of tags that can be in @ref QCBORTagListIn and passed to
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800654 QCBORDecode_SetCallerConfiguredTagList()
655 */
656#define QCBOR_MAX_CUSTOM_TAGS 16
657
658
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700659/**
660 Error codes returned by QCBOR Encoder and Decoder.
661 */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800662typedef enum {
663 /** The encode or decode completely correctly. */
664 QCBOR_SUCCESS = 0,
665
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700666 /** The buffer provided for the encoded output when doing encoding
667 was too small and the encoded output will not fit. Also, when
668 the buffer given to QCBORDecode_SetMemPool() is too small. */
669 QCBOR_ERR_BUFFER_TOO_SMALL = 1,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800670
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700671 /** During encoding or decoding, the array or map nesting was
672 deeper than this implementation can handle. Note that in the
673 interest of code size and memory use, this implementation has a
674 hard limit on array nesting. The limit is defined as the
675 constant @ref QCBOR_MAX_ARRAY_NESTING. */
676 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP = 2,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800677
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700678 /** During decoding or encoding, the array or map had too many
679 items in it. This limit @ref QCBOR_MAX_ITEMS_IN_ARRAY,
680 typically 65,535. */
681 QCBOR_ERR_ARRAY_TOO_LONG = 3,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800682
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700683 /** During encoding, more arrays or maps were closed than
684 opened. This is a coding error on the part of the caller of the
685 encoder. */
686 QCBOR_ERR_TOO_MANY_CLOSES = 4,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800687
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700688 /** During decoding, some CBOR construct was encountered that this
689 decoder doesn't support, primarily this is the reserved
Laurence Lundblade234fe422019-12-02 13:04:34 -0800690 additional info values, 28 through 30. During encoding,
691 an attempt to create simple value between 24 and 31. */
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700692 QCBOR_ERR_UNSUPPORTED = 5,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800693
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700694 /** During decoding, hit the end of the given data to decode. For
695 example, a byte string of 100 bytes was expected, but the end
696 of the input was hit before finding those 100 bytes. Corrupted
Laurence Lundblade234fe422019-12-02 13:04:34 -0800697 CBOR input will often result in this error. See also @ref
698 QCBOR_ERR_NO_MORE_ITEMS.
699 */
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700700 QCBOR_ERR_HIT_END = 6,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800701
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700702 /** During encoding, the length of the encoded CBOR exceeded @c
703 UINT32_MAX. */
704 QCBOR_ERR_BUFFER_TOO_LARGE = 7,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800705
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700706 /** During decoding, an integer smaller than INT64_MIN was received
707 (CBOR can represent integers smaller than INT64_MIN, but C
708 cannot). */
709 QCBOR_ERR_INT_OVERFLOW = 8,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800710
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700711 /** During decoding, the label for a map entry is bad. What causes
712 this error depends on the decoding mode. */
713 QCBOR_ERR_MAP_LABEL_TYPE = 9,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800714
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700715 /** During encoding or decoding, the number of array or map opens
716 was not matched by the number of closes. */
717 QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN = 10,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800718
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700719 /** During decoding, a date greater than +- 292 billion years from
720 Jan 1 1970 encountered during parsing. */
721 QCBOR_ERR_DATE_OVERFLOW = 11,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800722
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700723 /** During decoding, the CBOR is not valid, primarily a simple type
724 is encoded in a prohibited way. */
725 QCBOR_ERR_BAD_TYPE_7 = 12,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800726
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700727 /** Optional tagging that doesn't make sense (an integer is tagged
728 as a date string) or can't be handled. */
729 QCBOR_ERR_BAD_OPT_TAG = 13,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800730
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700731 /** Returned by QCBORDecode_Finish() if all the inputs bytes have
732 not been consumed. */
733 QCBOR_ERR_EXTRA_BYTES = 14,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800734
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700735 /** During encoding, @c QCBOREncode_CloseXxx() called with a
736 different type than is currently open. */
737 QCBOR_ERR_CLOSE_MISMATCH = 15,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800738
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700739 /** Unable to decode an indefinite-length string because no string
740 allocator was configured. See QCBORDecode_SetMemPool() or
741 QCBORDecode_SetUpAllocator(). */
742 QCBOR_ERR_NO_STRING_ALLOCATOR = 16,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800743
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700744 /** One of the chunks in an indefinite-length string is not of the
745 type of the start of the string. */
746 QCBOR_ERR_INDEFINITE_STRING_CHUNK = 17,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800747
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700748 /** Error allocating space for a string, usually for an
749 indefinite-length string. */
750 QCBOR_ERR_STRING_ALLOCATE = 18,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800751
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700752 /** During decoding, a break occurred outside an indefinite-length
753 item. */
754 QCBOR_ERR_BAD_BREAK = 19,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800755
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700756 /** During decoding, too many tags in the caller-configured tag
757 list, or not enough space in @ref QCBORTagListOut. */
758 QCBOR_ERR_TOO_MANY_TAGS = 20,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800759
Laurence Lundblade234fe422019-12-02 13:04:34 -0800760 /** An integer type is encoded with a bad length (an indefinite length) */
761 QCBOR_ERR_BAD_INT = 21,
762
763 /** All well-formed data items have been consumed and there are no
764 more. If parsing a CBOR stream this indicates the non-error
765 end of the stream. If parsing a CBOR stream / sequence, this
766 probably indicates that some data items expected are not present.
767 See also @ref QCBOR_ERR_HIT_END. */
768 QCBOR_ERR_NO_MORE_ITEMS = 22
769
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800770} QCBORError;
771
772
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700773/**
774 The decode mode options.
775 */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800776typedef enum {
777 /** See QCBORDecode_Init() */
778 QCBOR_DECODE_MODE_NORMAL = 0,
779 /** See QCBORDecode_Init() */
780 QCBOR_DECODE_MODE_MAP_STRINGS_ONLY = 1,
781 /** See QCBORDecode_Init() */
782 QCBOR_DECODE_MODE_MAP_AS_ARRAY = 2
783} QCBORDecodeMode;
784
785
786
787
788
789/* Do not renumber these. Code depends on some of these values. */
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700790/** The data type is unknown, unset or invalid. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800791#define QCBOR_TYPE_NONE 0
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700792/** Type for an integer that decoded either between @c INT64_MIN and
793 @c INT32_MIN or @c INT32_MAX and @c INT64_MAX. Data is in member
794 @c val.int64. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800795#define QCBOR_TYPE_INT64 2
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700796/** Type for an integer that decoded to a more than @c INT64_MAX and
797 @c UINT64_MAX. Data is in member @c val.uint64. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800798#define QCBOR_TYPE_UINT64 3
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700799/** Type for an array. The number of items in the array is in @c
800 val.uCount. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800801#define QCBOR_TYPE_ARRAY 4
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700802/** Type for a map; number of items in map is in @c val.uCount. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800803#define QCBOR_TYPE_MAP 5
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700804/** Type for a buffer full of bytes. Data is in @c val.string. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800805#define QCBOR_TYPE_BYTE_STRING 6
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700806/** Type for a UTF-8 string. It is not NULL-terminated. Data is in @c
807 val.string. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800808#define QCBOR_TYPE_TEXT_STRING 7
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700809/** Type for a positive big number. Data is in @c val.bignum, a
810 pointer and a length. */
811#define QCBOR_TYPE_POSBIGNUM 9
812/** Type for a negative big number. Data is in @c val.bignum, a
813 pointer and a length. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800814#define QCBOR_TYPE_NEGBIGNUM 10
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700815/** Type for [RFC 3339] (https://tools.ietf.org/html/rfc3339) date
816 string, possibly with time zone. Data is in @c val.dateString */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800817#define QCBOR_TYPE_DATE_STRING 11
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700818/** Type for integer seconds since Jan 1970 + floating point
819 fraction. Data is in @c val.epochDate */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800820#define QCBOR_TYPE_DATE_EPOCH 12
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700821/** A simple type that this CBOR implementation doesn't know about;
822 Type is in @c val.uSimple. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800823#define QCBOR_TYPE_UKNOWN_SIMPLE 13
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700824/** Type for the value false. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800825#define QCBOR_TYPE_FALSE 20
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700826/** Type for the value true. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800827#define QCBOR_TYPE_TRUE 21
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700828/** Type for the value null. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800829#define QCBOR_TYPE_NULL 22
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700830/** Type for the value undef. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800831#define QCBOR_TYPE_UNDEF 23
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700832/** Type for a floating-point number. Data is in @c val.float. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800833#define QCBOR_TYPE_FLOAT 26
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700834/** Type for a double floating-point number. Data is in @c val.double. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800835#define QCBOR_TYPE_DOUBLE 27
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700836/** For @ref QCBOR_DECODE_MODE_MAP_AS_ARRAY decode mode, a map that is
837 being traversed as an array. See QCBORDecode_Init() */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800838#define QCBOR_TYPE_MAP_AS_ARRAY 32
839
840#define QCBOR_TYPE_BREAK 31 // Used internally; never returned
841
842#define QCBOR_TYPE_OPTTAG 254 // Used internally; never returned
843
844
845
846/*
847 Approx Size of this:
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700848 8 + 8 + 1 + 1 + 1 + (1 padding) + (4 padding) = 24 for first part
849 (20 on a 32-bit machine)
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800850 16 bytes for the val union
851 16 bytes for label union
852 total = 56 bytes (52 bytes on 32-bit machine)
853 */
854
855/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700856 The main data structure that holds the type, value and other info for
857 a decoded item returned by QCBORDecode_GetNext() and
858 QCBORDecode_GetNextWithTags().
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800859 */
860typedef struct _QCBORItem {
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700861 /** Tells what element of the @c val union to use. One of @c
862 QCBOR_TYPE_XXXX */
863 uint8_t uDataType;
864 /** How deep the nesting from arrays and maps are. 0 is the top
865 level with no arrays or maps entered. */
866 uint8_t uNestingLevel;
867 /** Tells what element of the label union to use. */
868 uint8_t uLabelType;
869 /** 1 if allocated with string allocator, 0 if not. See
870 QCBORDecode_SetMemPool() or QCBORDecode_SetUpAllocator() */
871 uint8_t uDataAlloc;
872 /** Like @c uDataAlloc, but for label. */
873 uint8_t uLabelAlloc;
874 /** If not equal to @c uNestingLevel, this item closed out at least
875 one map/array */
876 uint8_t uNextNestLevel;
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800877
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700878 /** The union holding the item's value. Select union member based
879 on @c uDataType */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800880 union {
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700881 /** The value for @c uDataType @ref QCBOR_TYPE_INT64. */
882 int64_t int64;
883 /** The value for uDataType @ref QCBOR_TYPE_UINT64. */
884 uint64_t uint64;
885 /** The value for @c uDataType @ref QCBOR_TYPE_BYTE_STRING and
886 @ref QCBOR_TYPE_TEXT_STRING. */
887 UsefulBufC string;
888 /** The "value" for @c uDataType @ref QCBOR_TYPE_ARRAY or @ref
889 QCBOR_TYPE_MAP -- the number of items in the array or map.
890 It is @c UINT16_MAX when decoding indefinite-lengths maps
891 and arrays. */
892 uint16_t uCount;
893 /** The value for @c uDataType @ref QCBOR_TYPE_DOUBLE. */
894 double dfnum;
895 /** The value for @c uDataType @ref QCBOR_TYPE_DATE_EPOCH. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800896 struct {
897 int64_t nSeconds;
898 double fSecondsFraction;
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700899 } epochDate;
900 /** The value for @c uDataType @ref QCBOR_TYPE_DATE_STRING. */
901 UsefulBufC dateString;
902 /** The value for @c uDataType @ref QCBOR_TYPE_POSBIGNUM and
903 @ref QCBOR_TYPE_NEGBIGNUM. */
904 UsefulBufC bigNum;
905 /** The integer value for unknown simple types. */
906 uint8_t uSimple;
907 uint64_t uTagV; // Used internally during decoding
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800908
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700909 } val;
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800910
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700911 /** Union holding the different label types selected based on @c
912 uLabelType */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800913 union {
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700914 /** The label for @c uLabelType @ref QCBOR_TYPE_BYTE_STRING and
915 @ref QCBOR_TYPE_TEXT_STRING */
916 UsefulBufC string;
917 /** The label for @c uLabelType for @ref QCBOR_TYPE_INT64 */
918 int64_t int64;
919 /** The label for @c uLabelType for @ref QCBOR_TYPE_UINT64 */
920 uint64_t uint64;
921 } label;
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800922
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700923 /** Bit indicating which tags (major type 6) on this item. See
924 QCBORDecode_IsTagged(). */
925 uint64_t uTagBits;
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800926
927} QCBORItem;
928
929
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800930
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800931/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700932 @brief The type defining what a string allocator function must do.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800933
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700934 @param[in] pAllocateCxt Pointer to context for the particular
935 allocator implementation What is in the
936 context is dependent on how a particular
937 string allocator works. Typically, it
938 will contain a pointer to the memory pool
939 and some booking keeping data.
940 @param[in] pOldMem Points to some memory allocated by the
941 allocator that is either to be freed or
942 to be reallocated to be larger. It is
943 @c NULL for new allocations and when called as
944 a destructor to clean up the whole
945 allocation.
946 @param[in] uNewSize Size of memory to be allocated or new
947 size of chunk to be reallocated. Zero for
948 a new allocation or when called as a
949 destructor.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800950
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700951 @return Either the allocated buffer is returned, or @ref
952 NULLUsefulBufC. @ref NULLUsefulBufC is returned on a failed
953 allocation and in the two cases where there is nothing to
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800954 return.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800955
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800956 This is called in one of four modes:
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800957
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700958 Allocate -- @c uNewSize is the amount to allocate. @c pOldMem is @c
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800959 NULL.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800960
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700961 Free -- @c uNewSize is 0. @c pOldMem points to the memory to be
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800962 freed. When the decoder calls this, it will always be the most
963 recent block that was either allocated or reallocated.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800964
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700965 Reallocate -- @c pOldMem is the block to reallocate. @c uNewSize is
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800966 its new size. When the decoder calls this, it will always be the
967 most recent block that was either allocated or reallocated.
968
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700969 Destruct -- @c pOldMem is @c NULL and @c uNewSize is 0. This is called
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800970 when the decoding is complete by QCBORDecode_Finish(). Usually the
971 strings allocated by a string allocator are in use after the decoding
972 is completed so this usually will not free those strings. Many string
973 allocators will not need to do anything in this mode.
974
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700975 The strings allocated by this will have @c uDataAlloc set to true in
976 the @ref QCBORItem when they are returned. The user of the strings
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800977 will have to free them. How they free them, depends on the string
978 allocator.
979
980 If QCBORDecode_SetMemPool() is called, the internal MemPool will be
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700981 used. It has its own internal implementation of this function, so
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800982 one does not need to be implemented.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800983 */
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800984typedef UsefulBuf (* QCBORStringAllocate)(void *pAllocateCxt, void *pOldMem, size_t uNewSize);
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800985
986
987/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700988 This only matters if you use the built-in string allocator by setting
989 it up with QCBORDecode_SetMemPool(). This is the size of the overhead
990 needed by QCBORDecode_SetMemPool(). The amount of memory available
991 for decoded strings will be the size of the buffer given to
992 QCBORDecode_SetMemPool() less this amount.
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800993
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700994 If you write your own string allocator or use the separately
995 available malloc based string allocator, this size will not apply.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800996 */
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800997#define QCBOR_DECODE_MIN_MEM_POOL_SIZE 8
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800998
999
1000/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001001 This is used by QCBORDecode_SetCallerConfiguredTagList() to set a
1002 list of tags beyond the built-in ones.
1003
1004 See also QCBORDecode_GetNext() for general description of tag
1005 decoding.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001006 */
1007typedef struct {
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001008 /** The number of tags in the @c puTags. The maximum size is @ref
1009 QCBOR_MAX_CUSTOM_TAGS. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001010 uint8_t uNumTags;
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001011 /** An array of tags to add to recognize in addition to the
1012 built-in ones. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001013 const uint64_t *puTags;
1014} QCBORTagListIn;
1015
1016
1017/**
1018 This is for QCBORDecode_GetNextWithTags() to be able to return the
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001019 full list of tags on an item. It is not needed for most CBOR protocol
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001020 implementations. Its primary use is for pretty-printing CBOR or
1021 protocol conversion to another format.
1022
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001023 On input, @c puTags points to a buffer to be filled in and
1024 uNumAllocated is the number of @c uint64_t values in the buffer.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001025
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001026 On output the buffer contains the tags for the item. @c uNumUsed
1027 tells how many there are.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001028 */
1029typedef struct {
1030 uint8_t uNumUsed;
1031 uint8_t uNumAllocated;
1032 uint64_t *puTags;
1033} QCBORTagListOut;
1034
1035
1036/**
1037 QCBOREncodeContext is the data type that holds context for all the
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001038 encoding functions. It is less than 200 bytes, so it can go on the
1039 stack. The contents are opaque, and the caller should not access
1040 internal members. A context may be re used serially as long as it is
1041 re initialized.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001042 */
1043typedef struct _QCBOREncodeContext QCBOREncodeContext;
1044
1045
1046/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001047 Initialize the encoder to prepare to encode some CBOR.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001048
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001049 @param[in,out] pCtx The encoder context to initialize.
1050 @param[in] Storage The buffer into which this encoded result
1051 will be placed.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001052
1053 Call this once at the start of an encoding of a CBOR structure. Then
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001054 call the various @c QCBOREncode_AddXxx() functions to add the data
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001055 items. Then call QCBOREncode_Finish().
1056
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001057 The maximum output buffer is @c UINT32_MAX (4GB). This is not a
1058 practical limit in any way and reduces the memory needed by the
1059 implementation. The error @ref QCBOR_ERR_BUFFER_TOO_LARGE will be
1060 returned by QCBOREncode_Finish() if a larger buffer length is passed
1061 in.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001062
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001063 If this is called with @c Storage.ptr as @c NULL and @c Storage.len a
1064 large value like @c UINT32_MAX, all the QCBOREncode_AddXxx()
1065 functions and QCBOREncode_Finish() can still be called. No data will
1066 be encoded, but the length of what would be encoded will be
1067 calculated. The length of the encoded structure will be handed back
1068 in the call to QCBOREncode_Finish(). You can then allocate a buffer
1069 of that size and call all the encoding again, this time to fill in
1070 the buffer.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001071
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001072 A @ref QCBOREncodeContext can be reused over and over as long as
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001073 QCBOREncode_Init() is called.
1074 */
1075void QCBOREncode_Init(QCBOREncodeContext *pCtx, UsefulBuf Storage);
1076
1077
1078/**
1079 @brief Add a signed 64-bit integer to the encoded output.
1080
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001081 @param[in] pCtx The encoding context to add the integer to.
1082 @param[in] nNum The integer to add.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001083
1084 The integer will be encoded and added to the CBOR output.
1085
1086 This function figures out the size and the sign and encodes in the
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001087 correct minimal CBOR. Specifically, it will select CBOR major type 0
1088 or 1 based on sign and will encode to 1, 2, 4 or 8 bytes depending on
1089 the value of the integer. Values less than 24 effectively encode to
1090 one byte because they are encoded in with the CBOR major type. This
1091 is a neat and efficient characteristic of CBOR that can be taken
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001092 advantage of when designing CBOR-based protocols. If integers like
1093 tags can be kept between -23 and 23 they will be encoded in one byte
1094 including the major type.
1095
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001096 If you pass a smaller int, say an @c int16_t or a small value, say
1097 100, the encoding will still be CBOR's most compact that can
1098 represent the value. For example, CBOR always encodes the value 0 as
1099 one byte, 0x00. The representation as 0x00 includes identification of
1100 the type as an integer too as the major type for an integer is 0. See
1101 [RFC 7049] (https://tools.ietf.org/html/rfc7049) Appendix A for more
1102 examples of CBOR encoding. This compact encoding is also canonical
1103 CBOR as per section 3.9 in RFC 7049.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001104
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001105 There are no functions to add @c int16_t or @c int32_t because they
1106 are not necessary because this always encodes to the smallest number
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001107 of bytes based on the value (If this code is running on a 32-bit
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001108 machine having a way to add 32-bit integers would reduce code size
1109 some).
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001110
1111 If the encoding context is in an error state, this will do
1112 nothing. If an error occurs when adding this integer, the internal
1113 error flag will be set, and the error will be returned when
1114 QCBOREncode_Finish() is called.
1115
1116 See also QCBOREncode_AddUInt64().
1117 */
1118void QCBOREncode_AddInt64(QCBOREncodeContext *pCtx, int64_t nNum);
1119
1120static void QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum);
1121
1122static void QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum);
1123
1124
1125/**
1126 @brief Add an unsigned 64-bit integer to the encoded output.
1127
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001128 @param[in] pCtx The encoding context to add the integer to.
1129 @param[in] uNum The integer to add.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001130
1131 The integer will be encoded and added to the CBOR output.
1132
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001133 The only reason so use this function is for integers larger than @c
1134 INT64_MAX and smaller than @c UINT64_MAX. Otherwise
1135 QCBOREncode_AddInt64() will work fine.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001136
1137 Error handling is the same as for QCBOREncode_AddInt64().
1138 */
1139void QCBOREncode_AddUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
1140
1141static void QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum);
1142
1143static void QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum);
1144
1145
1146/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001147 @brief Add a UTF-8 text string to the encoded output.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001148
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001149 @param[in] pCtx The context to initialize.
1150 @param[in] Text Pointer and length of text to add.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001151
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001152 The text passed in must be unencoded UTF-8 according to [RFC 3629]
1153 (https://tools.ietf.org/html/rfc3629). There is no NULL
1154 termination. The text is added as CBOR major type 3.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001155
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001156 If called with @c nBytesLen equal to 0, an empty string will be
1157 added. When @c nBytesLen is 0, @c pBytes may be @c NULL.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001158
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001159 Note that the restriction of the buffer length to a @c uint32_t is
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001160 entirely intentional as this encoder is not capable of encoding
1161 lengths greater. This limit to 4GB for a text string should not be a
1162 problem.
1163
1164 Error handling is the same as QCBOREncode_AddInt64().
1165 */
1166static void QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text);
1167
1168static void QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text);
1169
1170static void QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text);
1171
1172
1173/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001174 @brief Add a UTF-8 text string to the encoded output.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001175
1176 @param[in] pCtx The context to initialize.
1177 @param[in] szString Null-terminated text to add.
1178
1179 This works the same as QCBOREncode_AddText().
1180 */
1181static void QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString);
1182
1183static void QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString);
1184
1185static void QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString);
1186
1187
1188/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001189 @brief Add a floating-point number to the encoded output.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001190
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001191 @param[in] pCtx The encoding context to add the float to.
1192 @param[in] dNum The double precision number to add.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001193
1194 This outputs a floating-point number with CBOR major type 7.
1195
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001196 This will selectively encode the double-precision floating-point
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001197 number as either double-precision, single-precision or
1198 half-precision. It will always encode infinity, NaN and 0 has half
1199 precision. If no precision will be lost in the conversion to
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001200 half-precision, then it will be converted and encoded. If not and no
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001201 precision will be lost in conversion to single-precision, then it
1202 will be converted and encoded. If not, then no conversion is
1203 performed, and it encoded as a double.
1204
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001205 Half-precision floating-point numbers take up 2 bytes, half that of
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001206 single-precision, one quarter of double-precision
1207
1208 This automatically reduces the size of encoded messages a lot, maybe
1209 even by four if most of values are 0, infinity or NaN.
1210
1211 On decode, these will always be returned as a double.
1212
1213 Error handling is the same as QCBOREncode_AddInt64().
1214 */
1215void QCBOREncode_AddDouble(QCBOREncodeContext *pCtx, double dNum);
1216
1217static void QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
1218
1219static void QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
1220
1221
1222/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001223 @brief Add an optional tag.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001224
1225 @param[in] pCtx The encoding context to add the integer to.
1226 @param[in] uTag The tag to add
1227
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001228 This outputs a CBOR major type 6 item that tags the next data item
1229 that is output usually to indicate it is some new data type.
1230
1231 For many of the common standard tags, a function to encode data using
1232 it is provided and this is not needed. For example,
1233 QCBOREncode_AddDateEpoch() already exists to output integers
1234 representing dates with the right tag.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001235
1236 The tag is applied to the next data item added to the encoded
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001237 output. That data item that is to be tagged can be of any major CBOR
1238 type. Any number of tags can be added to a data item by calling this
1239 multiple times before the data item is added.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001240
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001241 See @ref Tags-Overview for discussion of creating new non-standard
1242 tags. See QCBORDecode_GetNext() for discussion of decoding custom
1243 tags.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001244*/
1245void QCBOREncode_AddTag(QCBOREncodeContext *pCtx,uint64_t uTag);
1246
1247
1248/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001249 @brief Add an epoch-based date.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001250
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001251 @param[in] pCtx The encoding context to add the simple value to.
1252 @param[in] date Number of seconds since 1970-01-01T00:00Z in UTC time.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001253
1254 As per RFC 7049 this is similar to UNIX/Linux/POSIX dates. This is
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001255 the most compact way to specify a date and time in CBOR. Note that
1256 this is always UTC and does not include the time zone. Use
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001257 QCBOREncode_AddDateString() if you want to include the time zone.
1258
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001259 The integer encoding rules apply here so the date will be encoded in
1260 a minimal number of bytes. Until about the year 2106 these dates will
1261 encode in 6 bytes -- one byte for the tag, one byte for the type and
1262 4 bytes for the integer. After that it will encode to 10 bytes.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001263
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001264 Negative values are supported for dates before 1970.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001265
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001266 If you care about leap-seconds and that level of accuracy, make sure
1267 the system you are running this code on does it correctly. This code
1268 just takes the value passed in.
1269
1270 This implementation cannot encode fractional seconds using float or
1271 double even though that is allowed by CBOR, but you can encode them
1272 if you want to by calling QCBOREncode_AddDouble() and
1273 QCBOREncode_AddTag().
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001274
1275 Error handling is the same as QCBOREncode_AddInt64().
1276 */
1277static void QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx, int64_t date);
1278
1279static void QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t date);
1280
1281static void QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t date);
1282
1283
1284/**
1285 @brief Add a byte string to the encoded output.
1286
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001287 @param[in] pCtx The context to initialize.
1288 @param[in] Bytes Pointer and length of the input data.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001289
1290 Simply adds the bytes to the encoded output as CBOR major type 2.
1291
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001292 If called with @c Bytes.len equal to 0, an empty string will be
1293 added. When @c Bytes.len is 0, @c Bytes.ptr may be @c NULL.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001294
1295 Error handling is the same as QCBOREncode_AddInt64().
1296 */
1297static void QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
1298
1299static void QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
1300
1301static void QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
1302
1303
1304
1305/**
1306 @brief Add a binary UUID to the encoded output.
1307
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001308 @param[in] pCtx The context to initialize.
1309 @param[in] Bytes Pointer and length of the binary UUID.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001310
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001311 A binary UUID as defined in [RFC 4122]
1312 (https://tools.ietf.org/html/rfc4122) is added to the output.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001313
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001314 It is output as CBOR major type 2, a binary string, with tag @ref
1315 CBOR_TAG_BIN_UUID indicating the binary string is a UUID.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001316 */
1317static void QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
1318
1319static void QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
1320
1321static void QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
1322
1323
1324/**
1325 @brief Add a positive big number to the encoded output.
1326
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001327 @param[in] pCtx The context to initialize.
1328 @param[in] Bytes Pointer and length of the big number.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001329
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001330 Big numbers are integers larger than 64-bits. Their format is
1331 described in [RFC 7049] (https://tools.ietf.org/html/rfc7049).
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001332
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001333 It is output as CBOR major type 2, a binary string, with tag @ref
1334 CBOR_TAG_POS_BIGNUM indicating the binary string is a positive big
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001335 number.
1336
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001337 Often big numbers are used to represent cryptographic keys, however,
1338 COSE which defines representations for keys chose not to use this
1339 particular type.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001340 */
1341static void QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
1342
1343static void QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
1344
1345static void QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
1346
1347
1348/**
1349 @brief Add a negative big number to the encoded output.
1350
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001351 @param[in] pCtx The context to initialize.
1352 @param[in] Bytes Pointer and length of the big number.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001353
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001354 Big numbers are integers larger than 64-bits. Their format is
1355 described in [RFC 7049] (https://tools.ietf.org/html/rfc7049).
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001356
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001357 It is output as CBOR major type 2, a binary string, with tag @ref
1358 CBOR_TAG_NEG_BIGNUM indicating the binary string is a negative big
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001359 number.
1360
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001361 Often big numbers are used to represent cryptographic keys, however,
1362 COSE which defines representations for keys chose not to use this
1363 particular type.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001364 */
1365static void QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
1366
1367static void QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
1368
1369static void QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
1370
1371
1372/**
1373 @brief Add a text URI to the encoded output.
1374
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001375 @param[in] pCtx The context to initialize.
1376 @param[in] URI Pointer and length of the URI.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001377
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001378 The format of URI must be per [RFC 3986]
1379 (https://tools.ietf.org/html/rfc3986).
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001380
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001381 It is output as CBOR major type 3, a text string, with tag @ref
1382 CBOR_TAG_URI indicating the text string is a URI.
1383
1384 A URI in a NULL-terminated string, @c szURI, can be easily added with
1385 this code:
1386
1387 QCBOREncode_AddURI(pCtx, UsefulBuf_FromSZ(szURI));
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001388 */
1389static void QCBOREncode_AddURI(QCBOREncodeContext *pCtx, UsefulBufC URI);
1390
1391static void QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC URI);
1392
1393static void QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC URI);
1394
1395
1396/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001397 @brief Add Base64-encoded text to encoded output.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001398
1399 @param[in] pCtx The context to initialize.
1400 @param[in] B64Text Pointer and length of the base-64 encoded text.
1401
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001402 The text content is Base64 encoded data per [RFC 4648]
1403 (https://tools.ietf.org/html/rfc4648).
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001404
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001405 It is output as CBOR major type 3, a text string, with tag @ref
1406 CBOR_TAG_B64 indicating the text string is Base64 encoded.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001407 */
1408static void QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx, UsefulBufC B64Text);
1409
1410static void QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text);
1411
1412static void QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text);
1413
1414
1415/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001416 @brief Add base64url encoded data to encoded output.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001417
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001418 @param[in] pCtx The context to initialize.
1419 @param[in] B64Text Pointer and length of the base64url encoded text.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001420
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001421 The text content is base64URL encoded text as per [RFC 4648]
1422 (https://tools.ietf.org/html/rfc4648).
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001423
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001424 It is output as CBOR major type 3, a text string, with tag @ref
1425 CBOR_TAG_B64URL indicating the text string is a Base64url encoded.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001426 */
1427static void QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx, UsefulBufC B64Text);
1428
1429static void QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text);
1430
1431static void QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text);
1432
1433
1434/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001435 @brief Add Perl Compatible Regular Expression.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001436
1437 @param[in] pCtx The context to initialize.
1438 @param[in] Regex Pointer and length of the regular expression.
1439
1440 The text content is Perl Compatible Regular
1441 Expressions (PCRE) / JavaScript syntax [ECMA262].
1442
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001443 It is output as CBOR major type 3, a text string, with tag @ref
1444 CBOR_TAG_REGEX indicating the text string is a regular expression.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001445 */
1446static void QCBOREncode_AddRegex(QCBOREncodeContext *pCtx, UsefulBufC Regex);
1447
1448static void QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Regex);
1449
1450static void QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Regex);
1451
1452
1453/**
1454 @brief MIME encoded text to the encoded output.
1455
1456 @param[in] pCtx The context to initialize.
1457 @param[in] MIMEData Pointer and length of the regular expression.
1458
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001459 The text content is in MIME format per [RFC 2045]
1460 (https://tools.ietf.org/html/rfc2045) including the headers. Note
1461 that this only supports text-format MIME. Binary MIME is not
1462 supported.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001463
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001464 It is output as CBOR major type 3, a text string, with tag
1465 @ref CBOR_TAG_MIME indicating the text string is MIME data.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001466 */
1467static void QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx, UsefulBufC MIMEData);
1468
1469static void QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC MIMEData);
1470
1471static void QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC MIMEData);
1472
1473
1474/**
1475 @brief Add an RFC 3339 date string
1476
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001477 @param[in] pCtx The encoding context to add the simple value to.
1478 @param[in] szDate Null-terminated string with date to add.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001479
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001480 The string szDate should be in the form of [RFC 3339]
1481 (https://tools.ietf.org/html/rfc3339) as defined by section 3.3 in
1482 [RFC 4287] (https://tools.ietf.org/html/rfc4287). This is as
1483 described in section 2.4.1 in [RFC 7049]
1484 (https://tools.ietf.org/html/rfc7049).
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001485
1486 Note that this function doesn't validate the format of the date string
1487 at all. If you add an incorrect format date string, the generated
1488 CBOR will be incorrect and the receiver may not be able to handle it.
1489
1490 Error handling is the same as QCBOREncode_AddInt64().
1491 */
1492static void QCBOREncode_AddDateString(QCBOREncodeContext *pCtx, const char *szDate);
1493
1494static void QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szDate);
1495
1496static void QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szDate);
1497
1498
1499/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001500 @brief Add a standard Boolean.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001501
1502 @param[in] pCtx The encoding context to add the simple value to.
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001503 @param[in] b true or false from @c <stdbool.h>. Anything will result in an error.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001504
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001505 Adds a Boolean value as CBOR major type 7.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001506
1507 Error handling is the same as QCBOREncode_AddInt64().
1508 */
1509static void QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b);
1510
1511static void QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b);
1512
1513static void QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b);
1514
1515
1516
1517/**
1518 @brief Add a NULL to the encoded output.
1519
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001520 @param[in] pCtx The encoding context to add the simple value to.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001521
1522 Adds the NULL value as CBOR major type 7.
1523
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001524 This NULL doesn't have any special meaning in CBOR such as a
1525 terminating value for a string or an empty value.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001526
1527 Error handling is the same as QCBOREncode_AddInt64().
1528 */
1529static void QCBOREncode_AddNULL(QCBOREncodeContext *pCtx);
1530
1531static void QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1532
1533static void QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1534
1535
1536/**
1537 @brief Add an "undef" to the encoded output.
1538
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001539 @param[in] pCtx The encoding context to add the simple value to.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001540
1541 Adds the undef value as CBOR major type 7.
1542
1543 Note that this value will not translate to JSON.
1544
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001545 This Undef doesn't have any special meaning in CBOR such as a
1546 terminating value for a string or an empty value.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001547
1548 Error handling is the same as QCBOREncode_AddInt64().
1549 */
1550static void QCBOREncode_AddUndef(QCBOREncodeContext *pCtx);
1551
1552static void QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1553
1554static void QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1555
1556
1557/**
1558 @brief Indicates that the next items added are in an array.
1559
1560 @param[in] pCtx The encoding context to open the array in.
1561
1562 Arrays are the basic CBOR aggregate or structure type. Call this
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001563 function to start or open an array. Then call the various @c
1564 QCBOREncode_AddXxx() functions to add the items that go into the
1565 array. Then call QCBOREncode_CloseArray() when all items have been
1566 added. The data items in the array can be of any type and can be of
1567 mixed types.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001568
1569 Nesting of arrays and maps is allowed and supported just by calling
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001570 QCBOREncode_OpenArray() again before calling
1571 QCBOREncode_CloseArray(). While CBOR has no limit on nesting, this
1572 implementation does in order to keep it smaller and simpler. The
1573 limit is @ref QCBOR_MAX_ARRAY_NESTING. This is the max number of
1574 times this can be called without calling
1575 QCBOREncode_CloseArray(). QCBOREncode_Finish() will return @ref
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001576 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP when it is called as this function
1577 just sets an error state and returns no value when this occurs.
1578
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001579 If you try to add more than @ref QCBOR_MAX_ITEMS_IN_ARRAY items to a
1580 single array or map, @ref QCBOR_ERR_ARRAY_TOO_LONG will be returned
1581 when QCBOREncode_Finish() is called.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001582
1583 An array itself must have a label if it is being added to a map.
1584 Note that array elements do not have labels (but map elements do).
1585
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001586 An array itself may be tagged by calling QCBOREncode_AddTag() before this call.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001587 */
1588static void QCBOREncode_OpenArray(QCBOREncodeContext *pCtx);
1589
1590static void QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1591
1592static void QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1593
1594
1595/**
1596 @brief Close an open array.
1597
1598 @param[in] pCtx The context to add to.
1599
1600 The closes an array opened by QCBOREncode_OpenArray(). It reduces
1601 nesting level by one. All arrays (and maps) must be closed before
1602 calling QCBOREncode_Finish().
1603
1604 When an error occurs as a result of this call, the encoder records
1605 the error and enters the error state. The error will be returned when
1606 QCBOREncode_Finish() is called.
1607
1608 If this has been called more times than QCBOREncode_OpenArray(), then
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001609 @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when QCBOREncode_Finish()
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001610 is called.
1611
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001612 If this is called and it is not an array that is currently open, @ref
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001613 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
1614 is called.
1615 */
1616static void QCBOREncode_CloseArray(QCBOREncodeContext *pCtx);
1617
1618
1619/**
1620 @brief Indicates that the next items added are in a map.
1621
1622 @param[in] pCtx The context to add to.
1623
1624 See QCBOREncode_OpenArray() for more information, particularly error
1625 handling.
1626
1627 CBOR maps are an aggregate type where each item in the map consists
1628 of a label and a value. They are similar to JSON objects.
1629
1630 The value can be any CBOR type including another map.
1631
1632 The label can also be any CBOR type, but in practice they are
1633 typically, integers as this gives the most compact output. They might
1634 also be text strings which gives readability and translation to JSON.
1635
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001636 Every @c QCBOREncode_AddXxx() call has one version that ends with @c
1637 InMap for adding items to maps with string labels and one that ends
1638 with @c InMapN that is for adding with integer labels.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001639
1640 RFC 7049 uses the term "key" instead of "label".
1641
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001642 If you wish to use map labels that are neither integer labels nor
1643 text strings, then just call the QCBOREncode_AddXxx() function
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001644 explicitly to add the label. Then call it again to add the value.
1645
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001646 See the [RFC 7049] (https://tools.ietf.org/html/rfc7049) for a lot
1647 more information on creating maps.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001648 */
1649static void QCBOREncode_OpenMap(QCBOREncodeContext *pCtx);
1650
1651static void QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1652
1653static void QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1654
1655
1656
1657/**
1658 @brief Close an open map.
1659
1660 @param[in] pCtx The context to add to.
1661
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001662 This closes a map opened by QCBOREncode_OpenMap(). It reduces nesting
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001663 level by one.
1664
1665 When an error occurs as a result of this call, the encoder records
1666 the error and enters the error state. The error will be returned when
1667 QCBOREncode_Finish() is called.
1668
1669 If this has been called more times than QCBOREncode_OpenMap(),
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001670 then @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001671 QCBOREncode_Finish() is called.
1672
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001673 If this is called and it is not a map that is currently open, @ref
1674 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001675 is called.
1676 */
1677static void QCBOREncode_CloseMap(QCBOREncodeContext *pCtx);
1678
1679
1680/**
1681 @brief Indicate start of encoded CBOR to be wrapped in a bstr.
1682
1683 @param[in] pCtx The context to add to.
1684
1685 All added encoded items between this call and a call to
1686 QCBOREncode_CloseBstrWrap() will be wrapped in a bstr. They will
1687 appear in the final output as a byte string. That byte string will
1688 contain encoded CBOR.
1689
1690 The typical use case is for encoded CBOR that is to be
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001691 cryptographically hashed, as part of a [RFC 8152, COSE]
1692 (https://tools.ietf.org/html/rfc8152) implementation. This avoids
1693 having to encode the items first in one buffer (e.g., the COSE
1694 payload) and then add that buffer as a bstr to another encoding
1695 (e.g. the COSE to-be-signed bytes, the @c Sig_structure) potentially
1696 saving a lot of memory.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001697
1698 When constructing cryptographically signed CBOR objects, maps or
1699 arrays, they typically are encoded normally and then wrapped as a
1700 byte string. The COSE standard for example does this. The wrapping is
1701 simply treating the encoded CBOR map as a byte string.
1702
1703 The stated purpose of this wrapping is to prevent code relaying the
1704 signed data but not verifying it from tampering with the signed data
1705 thus making the signature unverifiable. It is also quite beneficial
1706 for the signature verification code. Standard CBOR parsers usually do
1707 not give access to partially parsed CBOR as would be need to check
1708 the signature of some CBOR. With this wrapping, standard CBOR parsers
1709 can be used to get to all the data needed for a signature
1710 verification.
1711 */
1712static void QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx);
1713
1714static void QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1715
1716static void QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1717
1718
1719/**
1720 @brief Close a wrapping bstr.
1721
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001722 @param[in] pCtx The context to add to.
1723 @param[out] pWrappedCBOR A @ref UsefulBufC containing wrapped bytes.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001724
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001725 The closes a wrapping bstr opened by QCBOREncode_CloseBstrWrap(). It reduces
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001726 nesting level by one.
1727
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001728 A pointer and length of the enclosed encoded CBOR is returned in @c
1729 *pWrappedCBOR if it is not @c NULL. The main purpose of this is so
1730 this data can be hashed (e.g., with SHA-256) as part of a [RFC 8152,
1731 COSE] (https://tools.ietf.org/html/rfc8152)
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001732 implementation. **WARNING**, this pointer and length should be used
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001733 right away before any other calls to @c QCBOREncode_Xxx() as they
1734 will move data around and the pointer and length will no longer be to
1735 the correct encoded CBOR.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001736
1737 When an error occurs as a result of this call, the encoder records
1738 the error and enters the error state. The error will be returned when
1739 QCBOREncode_Finish() is called.
1740
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001741 If this has been called more times than QCBOREncode_BstrWrap(),
1742 then @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001743 QCBOREncode_Finish() is called.
1744
1745 If this is called and it is not a wrapping bstr that is currently
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001746 open, @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
1747 QCBOREncode_Finish() is called.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001748 */
1749static void QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR);
1750
1751
1752/**
1753 @brief Add some already-encoded CBOR bytes.
1754
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001755 @param[in] pCtx The context to add to.
1756 @param[in] Encoded The already-encoded CBOR to add to the context.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001757
1758 The encoded CBOR being added must be fully conforming CBOR. It must
1759 be complete with no arrays or maps that are incomplete. While this
1760 encoder doesn't ever produce indefinite lengths, it is OK for the
1761 raw CBOR added here to have indefinite lengths.
1762
1763 The raw CBOR added here is not checked in anyway. If it is not
1764 conforming or has open arrays or such, the final encoded CBOR
1765 will probably be wrong or not what was intended.
1766
1767 If the encoded CBOR being added here contains multiple items, they
1768 must be enclosed in a map or array. At the top level the raw
1769 CBOR must be a single data item.
1770 */
1771static void QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded);
1772
1773static void QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded);
1774
1775static void QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded);
1776
1777
1778/**
1779 @brief Get the encoded result.
1780
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001781 @param[in] pCtx The context to finish encoding with.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001782 @param[out] pEncodedCBOR Pointer and length of encoded CBOR.
1783
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001784 @retval QCBOR_ERR_TOO_MANY_CLOSES Nesting error
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001785
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001786 @retval QCBOR_ERR_CLOSE_MISMATCH Nesting error
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001787
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001788 @retval QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN Nesting error
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001789
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001790 @retval QCBOR_ERR_BUFFER_TOO_LARGE Encoded output buffer size
1791
1792 @retval QCBOR_ERR_BUFFER_TOO_SMALL Encoded output buffer size
1793
1794 @retval QCBOR_ERR_ARRAY_NESTING_TOO_DEEP Implementation limit
1795
1796 @retval QCBOR_ERR_ARRAY_TOO_LONG Implementation limit
1797
1798 If this returns success @ref QCBOR_SUCCESS the encoding was a success
1799 and the return length is correct and complete.
1800
1801 If no buffer was passed to QCBOREncode_Init(), then only the length
1802 was computed. If a buffer was passed, then the encoded CBOR is in the
1803 buffer.
1804
Laurence Lundblade234fe422019-12-02 13:04:34 -08001805 Encoding errors primarily manifest here as most other encoding function
1806 do no return an error. They just set the error state in the encode
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001807 context after which no encoding function does anything.
1808
1809 Three types of errors manifest here. The first type are nesting
1810 errors where the number of @c QCBOREncode_OpenXxx() calls do not
1811 match the number @c QCBOREncode_CloseXxx() calls. The solution is to
1812 fix the calling code.
1813
1814 The second type of error is because the buffer given is either too
1815 small or too large. The remedy is to give a correctly sized buffer.
1816
1817 The third type are due to limits in this implementation. @ref
1818 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP can be worked around by encoding the
1819 CBOR in two (or more) phases and adding the CBOR from the first phase
1820 to the second with @c QCBOREncode_AddEncoded().
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001821
1822 If an error is returned, the buffer may have partially encoded
1823 incorrect CBOR in it and it should not be used. Likewise, the length
1824 may be incorrect and should not be used.
1825
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001826 Note that the error could have occurred in one of the many @c
1827 QCBOREncode_AddXxx() calls long before QCBOREncode_Finish() was
1828 called. This error handling reduces the CBOR implementation size but
1829 makes debugging harder.
1830
1831 This may be called multiple times. It will always return the same. It
1832 can also be interleaved with calls to QCBOREncode_FinishGetSize().
Laurence Lundblade234fe422019-12-02 13:04:34 -08001833
1834 QCBOREncode_GetErrorState() can be called to get the current
1835 error state and abort encoding early as an optimization, but is
1836 is never required.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001837 */
1838QCBORError QCBOREncode_Finish(QCBOREncodeContext *pCtx, UsefulBufC *pEncodedCBOR);
1839
1840
1841/**
1842 @brief Get the encoded CBOR and error status.
1843
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001844 @param[in] pCtx The context to finish encoding with.
1845 @param[out] uEncodedLen The length of the encoded or potentially
1846 encoded CBOR in bytes.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001847
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001848 @return The same errors as QCBOREncode_Finish().
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001849
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001850 This functions the same as QCBOREncode_Finish(), but only returns the
1851 size of the encoded output.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001852 */
1853QCBORError QCBOREncode_FinishGetSize(QCBOREncodeContext *pCtx, size_t *uEncodedLen);
1854
1855
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001856/**
1857 @brief Indicate whether output buffer is NULL or not.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001858
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001859 @param[in] pCtx The encoding ontext.
1860
1861 @return 1 if the output buffer is @c NULL.
1862
1863 Sometimes a @c NULL input buffer is given to QCBOREncode_Init() so
1864 that the size of the generated CBOR can be calculated without
1865 allocating a buffer for it. This returns 1 when the output buffer is
1866 NULL and 0 when it is not.
1867*/
1868static int QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx);
1869
1870 /**
1871 @brief Get the encoding error state.
1872
1873 @param[in] pCtx The encoding ontext.
1874
1875 @return One of \ref QCBORError. See return values from
1876 QCBOREncode_Finish()
1877
1878 Normally encoding errors need only be handled at the end of encoding
1879 when QCBOREncode_Finish() is called. This can be called to get the
1880 error result before finish should there be a need to halt encoding
Laurence Lundblade234fe422019-12-02 13:04:34 -08001881 before QCBOREncode_Finish() is called.
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001882*/
1883static QCBORError QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx);
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001884
1885
1886
1887/**
1888 QCBORDecodeContext is the data type that holds context decoding the
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001889 data items for some received CBOR. It is about 100 bytes, so it can
1890 go on the stack. The contents are opaque, and the caller should not
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001891 access any internal items. A context may be re used serially as long
1892 as it is re initialized.
1893 */
1894typedef struct _QCBORDecodeContext QCBORDecodeContext;
1895
1896
1897/**
1898 Initialize the CBOR decoder context.
1899
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001900 @param[in] pCtx The context to initialize.
1901 @param[in] EncodedCBOR The buffer with CBOR encoded bytes to be decoded.
1902 @param[in] nMode See below and @ref QCBORDecodeMode.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001903
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001904 Initialize context for a pre-order traversal of the encoded CBOR
1905 tree.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001906
1907 Most CBOR decoding can be completed by calling this function to start
1908 and QCBORDecode_GetNext() in a loop.
1909
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001910 If indefinite-length strings are to be decoded, then
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001911 QCBORDecode_SetMemPool() or QCBORDecode_SetUpAllocator() must be
1912 called to set up a string allocator.
1913
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001914 If tags other than built-in tags are to be recognized and recorded in
1915 @c uTagBits, then QCBORDecode_SetCallerConfiguredTagList() must be
1916 called. The built-in tags are those for which a macro of the form @c
1917 CBOR_TAG_XXX is defined.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001918
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001919 Three decoding modes are supported. In normal mode, @ref
1920 QCBOR_DECODE_MODE_NORMAL, maps are decoded and strings and integers
1921 are accepted as map labels. If a label is other than these, the error
1922 @ref QCBOR_ERR_MAP_LABEL_TYPE is returned by QCBORDecode_GetNext().
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001923
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001924 In strings-only mode, @ref QCBOR_DECODE_MODE_MAP_STRINGS_ONLY, only
1925 text strings are accepted for map labels. This lines up with CBOR
1926 that converts to JSON. The error @ref QCBOR_ERR_MAP_LABEL_TYPE is
1927 returned by QCBORDecode_GetNext() if anything but a text string label
1928 is encountered.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001929
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001930 In @ref QCBOR_DECODE_MODE_MAP_AS_ARRAY maps are treated as special
1931 arrays. They will be return with special @c uDataType @ref
1932 QCBOR_TYPE_MAP_AS_ARRAY and @c uCount, the number of items, will be
1933 double what it would be for a normal map because the labels are also
1934 counted. This mode is useful for decoding CBOR that has labels that
1935 are not integers or text strings, but the caller must manage much of
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001936 the map decoding.
1937 */
1938void QCBORDecode_Init(QCBORDecodeContext *pCtx, UsefulBufC EncodedCBOR, QCBORDecodeMode nMode);
1939
1940
1941/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001942 @brief Set up the MemPool string allocator for indefinite-length strings.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001943
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001944 @param[in] pCtx The decode context.
1945 @param[in] MemPool The pointer and length of the memory pool.
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001946 @param[in] bAllStrings If true, all strings, even of definite
1947 length, will be allocated with the string
1948 allocator.
1949
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001950 @return Error if the MemPool was less than @ref QCBOR_DECODE_MIN_MEM_POOL_SIZE.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001951
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001952 indefinite-length strings (text and byte) cannot be decoded unless
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001953 there is a string allocator configured. MemPool is a simple built-in
1954 string allocator that allocates bytes from a memory pool handed to it
1955 by calling this function. The memory pool is just a pointer and
1956 length for some block of memory that is to be used for string
1957 allocation. It can come from the stack, heap or other.
1958
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001959 The memory pool must be @ref QCBOR_DECODE_MIN_MEM_POOL_SIZE plus
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001960 space for all the strings allocated. There is no overhead per string
1961 allocated. A conservative way to size this buffer is to make it the
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001962 same size as the CBOR being decoded plus @ref
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001963 QCBOR_DECODE_MIN_MEM_POOL_SIZE.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001964
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001965 This memory pool is used for all indefinite-length strings that are
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001966 text strings or byte strings, including strings used as labels.
1967
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001968 The pointers to strings in @ref QCBORItem will point into the memory
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001969 pool set here. They do not need to be individually freed. Just
1970 discard the buffer when they are no longer needed.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001971
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001972 If @c bAllStrings is set, then the size will be the overhead plus the
1973 space to hold **all** strings, definite and indefinite-length, value
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001974 or label. The advantage of this is that after the decode is complete,
1975 the original memory holding the encoded CBOR does not need to remain
1976 valid.
1977
1978 If this function is never called because there is no need to support
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001979 indefinite-length strings, the internal MemPool implementation should
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001980 be dead-stripped by the loader and not add to code size.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001981 */
1982QCBORError QCBORDecode_SetMemPool(QCBORDecodeContext *pCtx, UsefulBuf MemPool, bool bAllStrings);
1983
1984
1985/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001986 @brief Sets up a custom string allocator for indefinite-length strings
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001987
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001988 @param[in] pCtx The decoder context to set up an
1989 allocator for.
1990 @param[in] pfAllocateFunction Pointer to function that will be
1991 called by QCBOR for allocations and
1992 frees.
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001993 @param[in] pAllocateContext Context passed to @c
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001994 pfAllocateFunction.
1995 @param[in] bAllStrings If true, all strings, even of definite
1996 length, will be allocated with the
1997 string allocator.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001998
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001999 indefinite-length strings (text and byte) cannot be decoded unless
Laurence Lundbladed425fb32019-02-18 10:56:18 -08002000 there a string allocator is configured. QCBORDecode_SetUpAllocator()
2001 allows the caller to configure an external string allocator
2002 implementation if the internal string allocator is not suitable. See
2003 QCBORDecode_SetMemPool() to configure the internal allocator. Note
2004 that the internal allocator is not automatically set up.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002005
Laurence Lundbladed425fb32019-02-18 10:56:18 -08002006 The string allocator configured here can be a custom one designed and
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002007 implemented by the caller. See @ref QCBORStringAllocate for the
Laurence Lundbladed425fb32019-02-18 10:56:18 -08002008 requirements for a string allocator implementation.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002009
Laurence Lundbladed425fb32019-02-18 10:56:18 -08002010 A malloc-based string external allocator can be obtained by calling
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002011 @c QCBORDecode_MakeMallocStringAllocator(). It will return a function
2012 and pointer that can be given here as @c pAllocatorFunction and @c
2013 pAllocatorContext. It uses standard @c malloc() so @c free() must be
2014 called on all strings marked by @c uDataAlloc @c == @c 1 or @c
2015 uLabelAlloc @c == @c 1 in @ref QCBORItem.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002016
Laurence Lundbladed425fb32019-02-18 10:56:18 -08002017 Note that an older version of this function took an allocator
2018 structure, rather than single function and pointer. The older
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002019 version @c QCBORDecode_MakeMallocStringAllocator() also implemented
Laurence Lundbladed425fb32019-02-18 10:56:18 -08002020 the older interface.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002021 */
Laurence Lundbladed425fb32019-02-18 10:56:18 -08002022void QCBORDecode_SetUpAllocator(QCBORDecodeContext *pCtx,
2023 QCBORStringAllocate pfAllocateFunction,
2024 void *pAllocateContext,
2025 bool bAllStrings);
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002026
2027/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002028 @brief Configure list of caller-selected tags to be recognized.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002029
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002030 @param[in] pCtx The decode context.
2031 @param[out] pTagList Structure holding the list of tags to configure.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002032
2033 This is used to tell the decoder about tags beyond those that are
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002034 built-in that should be recognized. The built-in tags are those with
2035 macros of the form @c CBOR_TAG_XXX.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002036
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002037 The list pointed to by @c pTagList must persist during decoding. No
2038 copy of it is made.
2039
2040 The maximum number of tags that can be added is @ref
2041 QCBOR_MAX_CUSTOM_TAGS. If a list larger than this is given, the
2042 error will be returned when QCBORDecode_GetNext() is called, not
2043 here.
2044
2045 See description of @ref QCBORTagListIn.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002046 */
2047void QCBORDecode_SetCallerConfiguredTagList(QCBORDecodeContext *pCtx, const QCBORTagListIn *pTagList);
2048
2049
2050/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002051 @brief Gets the next item (integer, byte string, array...) in
2052 preorder traversal of CBOR tree.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002053
2054 @param[in] pCtx The decoder context.
2055 @param[out] pDecodedItem Holds the CBOR item just decoded.
2056
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002057 @retval QCBOR_ERR_INDEFINITE_STRING_CHUNK Not well-formed, one of the
2058 chunks in indefinite-length
2059 string is wrong type.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002060
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002061 @retval QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN Not well-formed, array or map
2062 not closed.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002063
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002064 @retval QCBOR_ERR_UNSUPPORTED Not well-formed, input contains
2065 unsupported CBOR.
2066
Laurence Lundblade234fe422019-12-02 13:04:34 -08002067 @retval QCBOR_ERR_HIT_END Not well-formed, unexpectedly ran out
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002068 of bytes.
2069
2070 @retval QCBOR_ERR_BAD_TYPE_7 Not well-formed, bad simple type value.
2071
2072 @retval QCBOR_ERR_BAD_BREAK Not well-formed, break occurs where
2073 not allowed.
2074
2075 @retval QCBOR_ERR_EXTRA_BYTES Not well-formed, unprocessed bytes at
2076 the end.
2077
Laurence Lundblade234fe422019-12-02 13:04:34 -08002078 @retval QCBOR_ERR_BAD_INT Not well-formed, length of integer is
2079 bad.
2080
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002081 @retval QCBOR_ERR_BAD_OPT_TAG Invalid CBOR, tag on wrong type.
2082
2083 @retval QCBOR_ERR_ARRAY_TOO_LONG Implementation limit, array or map
2084 too long.
2085
2086 @retval QCBOR_ERR_INT_OVERFLOW Implementation limit, negative
2087 integer too large.
2088
2089 @retval QCBOR_ERR_DATE_OVERFLOW Implementation limit, date larger
2090 than can be handled.
2091
2092 @retval QCBOR_ERR_ARRAY_NESTING_TOO_DEEP Implementation limit, nesting
2093 too deep.
2094
2095 @retval QCBOR_ERR_STRING_ALLOCATE Resource exhaustion, string allocator
2096 failed.
2097
2098 @retval QCBOR_ERR_MAP_LABEL_TYPE Configuration error / Implementation
2099 limit encountered a map label this is
2100 not a string on an integer.
2101
2102 @retval QCBOR_ERR_NO_STRING_ALLOCATOR Configuration error, encountered
2103 indefinite-length string with no
2104 allocator configured.
Laurence Lundblade234fe422019-12-02 13:04:34 -08002105 @retval QCBOR_ERR_NO_MORE_ITEMS No more bytes to decode. The previous
2106 item was successfully decoded. This
2107 is usually how the non-error end of
2108 a CBOR stream / sequence is detected.
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002109
2110 @c pDecodedItem is filled in with the value parsed. Generally, the
2111 following data is returned in the structure:
2112
2113 - @c uDataType which indicates which member of the @c val union the
2114 data is in. This decoder figures out the type based on the CBOR
2115 major type, the CBOR "additionalInfo", the CBOR optional tags and
2116 the value of the integer.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002117
2118 - The value of the item, which might be an integer, a pointer and a
2119 length, the count of items in an array, a floating-point number or
2120 other.
2121
2122 - The nesting level for maps and arrays.
2123
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002124 - The label for an item in a map, which may be a text or byte string
2125 or an integer.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002126
2127 - The CBOR optional tag or tags.
2128
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002129 See documentation on in the data type @ref _QCBORItem for all the
2130 details on what is returned.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002131
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002132 This function handles arrays and maps. When first encountered a @ref
2133 QCBORItem will be returned with major type @ref QCBOR_TYPE_ARRAY or
2134 @ref QCBOR_TYPE_MAP. @c QCBORItem.val.uCount will indicate the number
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002135 of Items in the array or map. Typically, an implementation will call
2136 QCBORDecode_GetNext() in a for loop to fetch them all. When decoding
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002137 indefinite-length maps and arrays, @c QCBORItem.val.uCount is @c
2138 UINT16_MAX and @c uNextNestLevel must be used to know when the end of
2139 a map or array is reached.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002140
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002141 Nesting level 0 is the outside top-most nesting level. For example,
2142 in a CBOR structure with two items, an integer and a byte string
2143 only, both would be at nesting level 0. A CBOR structure with an
2144 array open, an integer and a byte string, would have the integer and
2145 byte string as nesting level 1.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002146
2147 Here is an example of how the nesting level is reported with no arrays
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002148 or maps at all.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002149
2150 @verbatim
2151 CBOR Structure Nesting Level
2152 Integer 0
2153 Byte String 0
2154 @endverbatim
2155
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002156 Here is an example of how the nesting level is reported with a simple
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002157 array and some top-level items.
2158
2159 @verbatim
2160 Integer 0
2161 Array (with 2 items) 0
2162 Byte String 1
2163 Byte string 1
2164 Integer 0
2165 @endverbatim
2166
2167
2168 Here's a more complex example
2169 @verbatim
2170
2171 Map with 2 items 0
2172 Text string 1
2173 Array with 3 integers 1
2174 integer 2
2175 integer 2
2176 integer 2
2177 text string 1
2178 byte string 1
2179 @endverbatim
2180
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002181 In @ref _QCBORItem, @c uNextNestLevel is the nesting level for the
2182 next call to QCBORDecode_GetNext(). It indicates if any maps or
2183 arrays were closed out during the processing of the just-fetched @ref
2184 QCBORItem. This processing includes a look-ahead for any breaks that
2185 close out indefinite-length arrays or maps. This value is needed to
2186 be able to understand the hierarchical structure. If @c
2187 uNextNestLevel is not equal to @c uNestLevel the end of the current
2188 map or array has been encountered. This works the same for both
2189 definite and indefinite-length arrays.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002190
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002191 This decoder support CBOR type 6 tagging. The decoding of particular
2192 given tag value may be supported in one of three different ways.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002193
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002194 First, some common tags are fully and transparently supported by
2195 automatically decoding them and returning them in a @ref QCBORItem.
2196 These tags have a @c QCBOR_TYPE_XXX associated with them and manifest
2197 pretty much the same as a standard CBOR type. @ref
2198 QCBOR_TYPE_DATE_EPOCH and the @c epochDate member of @ref QCBORItem
2199 is an example.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002200
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002201 Second are tags that are automatically recognized, but not decoded.
2202 These are tags that have a @c \#define of the form @c CBOR_TAG_XXX.
2203 These are recorded in the @c uTagBits member of @ref QCBORItem. There
2204 is an internal table that maps each bit to a particular tag value
2205 allowing up to 64 tags on an individual item to be reported (it is
2206 rare to have more than one or two). To find out if a particular tag
2207 value is set call QCBORDecode_IsTagged() on the @ref QCBORItem. See
2208 also QCBORDecode_GetNextWithTags().
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002209
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002210 Third are tags that are not automatically recognized, because they
2211 are proprietary, custom or more recently registered with [IANA]
2212 (https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml). The
2213 internal mapping table has to be configured to recognize these. Call
2214 QCBORDecode_SetCallerConfiguredTagList() to do that. Then
2215 QCBORDecode_IsTagged() will work with them.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002216
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002217 The actual decoding of tags supported in the second and third way
2218 must be handled by the caller. Often this is simply verifying that
2219 the expected tag is present on a map, byte string or such. In other
2220 cases, there might a complicated map structure to decode.
2221
2222 See @ref Tags-Overview for a description of how to go about creating
2223 custom tags.
2224
2225 This tag decoding design is to be open-ended and flexible to be able
2226 to handle newly defined tags, while using very little memory, in
2227 particular keeping @ref QCBORItem as small as possible.
2228
Laurence Lundblade234fe422019-12-02 13:04:34 -08002229 If any error occurs, \c uDataType and \c uLabelType will be set
2230 to \ref QCBOR_TYPE_NONE. If there is no need to know the specific
2231 error, \ref QCBOR_TYPE_NONE can be checked for and the return value
2232 ignored.
2233
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002234 Errors fall in several categories as noted in list above:
2235
2236 - Not well-formed errors are those where there is something
2237 syntactically and fundamentally wrong with the CBOR being
2238 decoded. Encoding should stop completely.
2239
2240 - Invalid CBOR is well-formed, but still not correct. It is probably
2241 best to stop decoding, but not necessary.
2242
2243 - This implementation has some size limits. They should rarely be
2244 encountered. If they are it may because something is wrong with the
2245 CBOR, for example an array size is incorrect.
2246
2247 - Resource exhaustion. This only occurs when a string allocator is
2248 configured to handle indefinite-length strings as other than that,
2249 this implementation does no dynamic memory allocation.
2250
2251 - There are a few CBOR constructs that are not handled without some
2252 extra configuration. These are indefinite length strings and maps
2253 with labels that are not strings or integers. See QCBORDecode_Init().
2254
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002255 */
2256QCBORError QCBORDecode_GetNext(QCBORDecodeContext *pCtx, QCBORItem *pDecodedItem);
2257
2258
2259/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002260 @brief Gets the next item including full list of tags for item.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002261
2262 @param[in] pCtx The decoder context.
2263 @param[out] pDecodedItem Holds the CBOR item just decoded.
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002264 @param[in,out] pTagList On input array to put tags in; on output
2265 the tags on this item. See
2266 @ref QCBORTagListOut.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002267
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002268 @return See return values for QCBORDecode_GetNext().
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002269
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002270 @retval QCBOR_ERR_TOO_MANY_TAGS The size of @c pTagList is too small.
2271
2272 This works the same as QCBORDecode_GetNext() except that it also
2273 returns the full list of tags for the data item. This function should
2274 only be needed when parsing CBOR to print it out or convert it to
2275 some other format. It should not be needed to implement a CBOR-based
2276 protocol. See QCBORDecode_GetNext() for the main description of tag
2277 decoding.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002278
2279 Tags will be returned here whether or not they are in the built-in or
2280 caller-configured tag lists.
2281
2282 CBOR has no upper bound of limit on the number of tags that can be
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002283 associated with a data item though in practice the number of tags on
2284 an item will usually be small, perhaps less than five. This will
2285 return @ref QCBOR_ERR_TOO_MANY_TAGS if the array in @c pTagList is
2286 too small to hold all the tags for the item.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002287
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002288 (This function is separate from QCBORDecode_GetNext() so as to not
2289 have to make @ref QCBORItem large enough to be able to hold a full
2290 list of tags. Even a list of five tags would nearly double its size
2291 because tags can be a @c uint64_t ).
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002292 */
2293QCBORError QCBORDecode_GetNextWithTags(QCBORDecodeContext *pCtx, QCBORItem *pDecodedItem, QCBORTagListOut *pTagList);
2294
2295
2296/**
2297 @brief Determine if a CBOR item was tagged with a particular tag
2298
2299 @param[in] pCtx The decoder context.
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002300 @param[in] pItem The CBOR item to check.
2301 @param[in] uTag The tag to check, one of @c CBOR_TAG_XXX.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002302
2303 @return 1 if it was tagged, 0 if not
2304
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002305 See QCBORDecode_GetNext() for the main description of tag
2306 handling. For tags that are not fully decoded a bit corresponding to
2307 the tag is set in in @c uTagBits in the @ref QCBORItem. The
2308 particular bit depends on an internal mapping table. This function
2309 checks for set bits against the mapping table.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002310
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002311 Typically, a protocol implementation just wants to know if a
2312 particular tag is present. That is what this provides. To get the
2313 full list of tags on a data item, see QCBORDecode_GetNextWithTags().
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002314
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002315 Also see QCBORDecode_SetCallerConfiguredTagList() for the means to
2316 add new tags to the internal list so they can be checked for with
2317 this function.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002318 */
2319int QCBORDecode_IsTagged(QCBORDecodeContext *pCtx, const QCBORItem *pItem, uint64_t uTag);
2320
2321
2322/**
2323 Check whether all the bytes have been decoded and maps and arrays closed.
2324
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002325 @param[in] pCtx The context to check.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002326
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002327 @return An error or @ref QCBOR_SUCCESS.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002328
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002329 This tells you if all the bytes given to QCBORDecode_Init() have been
2330 consumed and whether all maps and arrays were closed. The decode is
2331 considered to be incorrect or incomplete if not and an error will be
2332 returned.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002333 */
2334QCBORError QCBORDecode_Finish(QCBORDecodeContext *pCtx);
2335
2336
2337
2338
2339/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002340 @brief Convert int64_t to smaller integers safely.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002341
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002342 @param [in] src An @c int64_t.
2343 @param [out] dest A smaller sized integer to convert to.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002344
2345 @return 0 on success -1 if not
2346
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002347 When decoding an integer, the CBOR decoder will return the value as
2348 an int64_t unless the integer is in the range of @c INT64_MAX and @c
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002349 UINT64_MAX. That is, unless the value is so large that it can only be
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002350 represented as a @c uint64_t, it will be an @c int64_t.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002351
2352 CBOR itself doesn't size the individual integers it carries at
2353 all. The only limits it puts on the major integer types is that they
2354 are 8 bytes or less in length. Then encoders like this one use the
2355 smallest number of 1, 2, 4 or 8 bytes to represent the integer based
2356 on its value. There is thus no notion that one data item in CBOR is
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002357 a 1-byte integer and another is a 4-byte integer.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002358
2359 The interface to this CBOR encoder only uses 64-bit integers. Some
2360 CBOR protocols or implementations of CBOR protocols may not want to
2361 work with something smaller than a 64-bit integer. Perhaps an array
2362 of 1000 integers needs to be sent and none has a value larger than
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002363 50,000 and are represented as @c uint16_t.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002364
2365 The sending / encoding side is easy. Integers are temporarily widened
2366 to 64-bits as a parameter passing through QCBOREncode_AddInt64() and
2367 encoded in the smallest way possible for their value, possibly in
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002368 less than an @c uint16_t.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002369
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002370 On the decoding side the integers will be returned at @c int64_t even if
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002371 they are small and were represented by only 1 or 2 bytes in the
2372 encoded CBOR. The functions here will convert integers to a small
2373 representation with an overflow check.
2374
2375 (The decoder could have support 8 different integer types and
2376 represented the integer with the smallest type automatically, but
2377 this would have made the decoder more complex and code calling the
2378 decoder more complex in most use cases. In most use cases on 64-bit
2379 machines it is no burden to carry around even small integers as
2380 64-bit values).
2381 */
2382static inline int QCBOR_Int64ToInt32(int64_t src, int32_t *dest)
2383{
2384 if(src > INT32_MAX || src < INT32_MIN) {
2385 return -1;
2386 } else {
2387 *dest = (int32_t) src;
2388 }
2389 return 0;
2390}
2391
2392static inline int QCBOR_Int64ToInt16(int64_t src, int16_t *dest)
2393{
2394 if(src > INT16_MAX || src < INT16_MIN) {
2395 return -1;
2396 } else {
2397 *dest = (int16_t) src;
2398 }
2399 return 0;
2400}
2401
2402static inline int QCBOR_Int64ToInt8(int64_t src, int8_t *dest)
2403{
2404 if(src > INT8_MAX || src < INT8_MIN) {
2405 return -1;
2406 } else {
2407 *dest = (int8_t) src;
2408 }
2409 return 0;
2410}
2411
2412static inline int QCBOR_Int64ToUInt32(int64_t src, uint32_t *dest)
2413{
2414 if(src > UINT32_MAX || src < 0) {
2415 return -1;
2416 } else {
2417 *dest = (uint32_t) src;
2418 }
2419 return 0;
2420}
2421
2422static inline int QCBOR_Int64UToInt16(int64_t src, uint16_t *dest)
2423{
2424 if(src > UINT16_MAX || src < 0) {
2425 return -1;
2426 } else {
2427 *dest = (uint16_t) src;
2428 }
2429 return 0;
2430}
2431
2432static inline int QCBOR_Int64ToUInt8(int64_t src, uint8_t *dest)
2433{
2434 if(src > UINT8_MAX || src < 0) {
2435 return -1;
2436 } else {
2437 *dest = (uint8_t) src;
2438 }
2439 return 0;
2440}
2441
2442static inline int QCBOR_Int64ToUInt64(int64_t src, uint64_t *dest)
2443{
2444 if(src > 0) {
2445 return -1;
2446 } else {
2447 *dest = (uint64_t) src;
2448 }
2449 return 0;
2450}
2451
2452
2453
2454
2455
2456/* ===========================================================================
2457 BEGINNING OF PRIVATE INLINE IMPLEMENTATION
2458
2459 =========================================================================== */
2460
2461/**
2462 @brief Semi-private method to add a buffer full of bytes to encoded output
2463
2464 @param[in] pCtx The encoding context to add the integer to.
2465 @param[in] uMajorType The CBOR major type of the bytes.
2466 @param[in] Bytes The bytes to add.
2467
2468 Use QCBOREncode_AddText() or QCBOREncode_AddBytes() or
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002469 QCBOREncode_AddEncoded() instead. They are inline functions that call
2470 this and supply the correct major type. This function is public to
2471 make the inline functions work to keep the overall code size down and
2472 because the C language has no way to make it private.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002473
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002474 If this is called the major type should be @c
2475 CBOR_MAJOR_TYPE_TEXT_STRING, @c CBOR_MAJOR_TYPE_BYTE_STRING or @c
2476 CBOR_MAJOR_NONE_TYPE_RAW. The last one is special for adding
2477 already-encoded CBOR.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002478 */
2479void QCBOREncode_AddBuffer(QCBOREncodeContext *pCtx, uint8_t uMajorType, UsefulBufC Bytes);
2480
2481
2482/**
2483 @brief Semi-private method to open a map, array or bstr wrapped CBOR
2484
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002485 @param[in] pCtx The context to add to.
2486 @param[in] uMajorType The major CBOR type to close
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002487
2488 Call QCBOREncode_OpenArray(), QCBOREncode_OpenMap() or
2489 QCBOREncode_BstrWrap() instead of this.
2490 */
2491void QCBOREncode_OpenMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType);
2492
2493
2494/**
Laurence Lundblade234fe422019-12-02 13:04:34 -08002495 @brief Semi-private method to open a map, array or bstr wrapped CBOR with indefinite length
2496
2497 @param[in] pCtx The context to add to.
2498 @param[in] uMajorType The major CBOR type to close
2499
2500 Call QCBOREncode_OpenArrayIndefiniteLength() or QCBOREncode_OpenMapIndefiniteLength()
2501 instead of this.
2502 */
2503void QCBOREncode_OpenMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx, uint8_t uMajorType);
2504
2505
2506/**
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002507 @brief Semi-private method to close a map, array or bstr wrapped CBOR
2508
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002509 @param[in] pCtx The context to add to.
2510 @param[in] uMajorType The major CBOR type to close.
2511 @param[out] pWrappedCBOR Pointer to @ref UsefulBufC containing wrapped bytes.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002512
2513 Call QCBOREncode_CloseArray(), QCBOREncode_CloseMap() or
2514 QCBOREncode_CloseBstrWrap() instead of this.
2515 */
2516void QCBOREncode_CloseMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType, UsefulBufC *pWrappedCBOR);
2517
Laurence Lundblade234fe422019-12-02 13:04:34 -08002518/**
2519 @brief Semi-private method to close a map, array or bstr wrapped CBOR with indefinite length
2520
2521 @param[in] pCtx The context to add to.
2522 @param[in] uMajorType The major CBOR type to close.
2523 @param[out] pWrappedCBOR Pointer to @ref UsefulBufC containing wrapped bytes.
2524
2525 Call QCBOREncode_CloseArrayIndefiniteLength() or QCBOREncode_CloseMapIndefiniteLength()
2526 instead of this.
2527 */
2528void QCBOREncode_CloseMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx, uint8_t uMajorType, UsefulBufC *pWrappedCBOR);
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002529
2530/**
2531 @brief Semi-private method to add simple types.
2532
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002533 @param[in] pCtx The encoding context to add the simple value to.
2534 @param[in] uSize Minimum encoding size for uNum. Usually 0.
2535 @param[in] uNum One of CBOR_SIMPLEV_FALSE through _UNDEF or other.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002536
2537 This is used to add simple types like true and false.
2538
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002539 Call QCBOREncode_AddBool(), QCBOREncode_AddNULL(),
2540 QCBOREncode_AddUndef() instead of this.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002541
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002542 This function can add simple values that are not defined by CBOR
2543 yet. This expansion point in CBOR should not be used unless they are
2544 standardized.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002545
2546 Error handling is the same as QCBOREncode_AddInt64().
2547 */
2548void QCBOREncode_AddType7(QCBOREncodeContext *pCtx, size_t uSize, uint64_t uNum);
2549
2550
Laurence Lundbladec93b5a72019-04-06 12:17:16 -07002551/**
2552 @brief Semi-private method to add only the type and length of a byte string.
2553
2554 @param[in] pCtx The context to initialize.
2555 @param[in] Bytes Pointer and length of the input data.
2556
2557 This is the same as QCBOREncode_AddBytes() except it only adds the
2558 CBOR encoding for the type and the length. It doesn't actually add
2559 the bytes. You can't actually produce correct CBOR with this and the
2560 rest of this API. It is only used for a special case where
2561 the valid CBOR is created manually by putting this type and length in
2562 and then adding the actual bytes. In particular, when only a hash of
2563 the encoded CBOR is needed, where the type and header are hashed
2564 separately and then the bytes is hashed. This makes it possible to
2565 implement COSE Sign1 with only one copy of the payload in the output
2566 buffer, rather than two, roughly cutting memory use in half.
2567
2568 This is only used for this odd case, but this is a supported
2569 tested function.
2570*/
2571static inline void QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
2572
2573static inline void QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
2574
2575static inline void QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
2576
2577
2578
2579
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002580static inline void QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum)
2581{
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002582 // Use _AddBuffer() because _AddSZString() is defined below, not above
2583 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002584 QCBOREncode_AddInt64(pCtx, uNum);
2585}
2586
2587static inline void QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum)
2588{
2589 QCBOREncode_AddInt64(pCtx, nLabel);
2590 QCBOREncode_AddInt64(pCtx, uNum);
2591}
2592
2593
2594static inline void QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum)
2595{
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002596 // Use _AddBuffer() because _AddSZString() is defined below, not above
2597 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002598 QCBOREncode_AddUInt64(pCtx, uNum);
2599}
2600
2601static inline void QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum)
2602{
2603 QCBOREncode_AddInt64(pCtx, nLabel);
2604 QCBOREncode_AddUInt64(pCtx, uNum);
2605}
2606
2607
2608static inline void QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text)
2609{
2610 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, Text);
2611}
2612
2613static inline void QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text)
2614{
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002615 // Use _AddBuffer() because _AddSZString() is defined below, not above
2616 QCBOREncode_AddText(pCtx, UsefulBuf_FromSZ(szLabel));
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002617 QCBOREncode_AddText(pCtx, Text);
2618}
2619
2620static inline void QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text)
2621{
2622 QCBOREncode_AddInt64(pCtx, nLabel);
2623 QCBOREncode_AddText(pCtx, Text);
2624}
2625
2626
2627inline static void QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString)
2628{
2629 QCBOREncode_AddText(pCtx, UsefulBuf_FromSZ(szString));
2630}
2631
2632static inline void QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString)
2633{
2634 QCBOREncode_AddSZString(pCtx, szLabel);
2635 QCBOREncode_AddSZString(pCtx, szString);
2636}
2637
2638static inline void QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString)
2639{
2640 QCBOREncode_AddInt64(pCtx, nLabel);
2641 QCBOREncode_AddSZString(pCtx, szString);
2642}
2643
2644
2645static inline void QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum)
2646{
2647 QCBOREncode_AddSZString(pCtx, szLabel);
2648 QCBOREncode_AddDouble(pCtx, dNum);
2649}
2650
2651static inline void QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum)
2652{
2653 QCBOREncode_AddInt64(pCtx, nLabel);
2654 QCBOREncode_AddDouble(pCtx, dNum);
2655}
2656
2657
2658static inline void QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx, int64_t date)
2659{
2660 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_EPOCH);
2661 QCBOREncode_AddInt64(pCtx, date);
2662}
2663
2664static inline void QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t date)
2665{
2666 QCBOREncode_AddSZString(pCtx, szLabel);
2667 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_EPOCH);
2668 QCBOREncode_AddInt64(pCtx, date);
2669}
2670
2671static inline void QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t date)
2672{
2673 QCBOREncode_AddInt64(pCtx, nLabel);
2674 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_EPOCH);
2675 QCBOREncode_AddInt64(pCtx, date);
2676}
2677
2678
2679static inline void QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
2680{
2681 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes);
2682}
2683
2684static inline void QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
2685{
2686 QCBOREncode_AddSZString(pCtx, szLabel);
2687 QCBOREncode_AddBytes(pCtx, Bytes);
2688}
2689
2690static inline void QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
2691{
2692 QCBOREncode_AddInt64(pCtx, nLabel);
2693 QCBOREncode_AddBytes(pCtx, Bytes);
2694}
2695
Laurence Lundbladec93b5a72019-04-06 12:17:16 -07002696static inline void QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
2697{
2698 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY, Bytes);
2699}
2700
2701static inline void QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
2702{
2703 QCBOREncode_AddSZString(pCtx, szLabel);
2704 QCBOREncode_AddBytesLenOnly(pCtx, Bytes);
2705}
2706
2707static inline void QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
2708{
2709 QCBOREncode_AddInt64(pCtx, nLabel);
2710 QCBOREncode_AddBytesLenOnly(pCtx, Bytes);
2711}
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002712
2713static inline void QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
2714{
2715 QCBOREncode_AddTag(pCtx, CBOR_TAG_BIN_UUID);
2716 QCBOREncode_AddBytes(pCtx, Bytes);
2717}
2718
2719static inline void QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
2720{
2721 QCBOREncode_AddSZString(pCtx, szLabel);
2722 QCBOREncode_AddTag(pCtx, CBOR_TAG_BIN_UUID);
2723 QCBOREncode_AddBytes(pCtx, Bytes);
2724}
2725
2726static inline void QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
2727{
2728 QCBOREncode_AddInt64(pCtx, nLabel);
2729 QCBOREncode_AddTag(pCtx, CBOR_TAG_BIN_UUID);
2730 QCBOREncode_AddBytes(pCtx, Bytes);
2731}
2732
2733
2734static inline void QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
2735{
2736 QCBOREncode_AddTag(pCtx, CBOR_TAG_POS_BIGNUM);
2737 QCBOREncode_AddBytes(pCtx, Bytes);
2738}
2739
2740static inline void QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
2741{
2742 QCBOREncode_AddSZString(pCtx, szLabel);
2743 QCBOREncode_AddTag(pCtx, CBOR_TAG_POS_BIGNUM);
2744 QCBOREncode_AddBytes(pCtx, Bytes);
2745}
2746
2747static inline void QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
2748{
2749 QCBOREncode_AddInt64(pCtx, nLabel);
2750 QCBOREncode_AddTag(pCtx, CBOR_TAG_POS_BIGNUM);
2751 QCBOREncode_AddBytes(pCtx, Bytes);
2752}
2753
2754
2755static inline void QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
2756{
2757 QCBOREncode_AddTag(pCtx, CBOR_TAG_NEG_BIGNUM);
2758 QCBOREncode_AddBytes(pCtx, Bytes);
2759}
2760
2761static inline void QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
2762{
2763 QCBOREncode_AddSZString(pCtx, szLabel);
2764 QCBOREncode_AddTag(pCtx, CBOR_TAG_NEG_BIGNUM);
2765 QCBOREncode_AddBytes(pCtx, Bytes);
2766}
2767
2768static inline void QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
2769{
2770 QCBOREncode_AddInt64(pCtx, nLabel);
2771 QCBOREncode_AddTag(pCtx, CBOR_TAG_NEG_BIGNUM);
2772 QCBOREncode_AddBytes(pCtx, Bytes);
2773}
2774
2775
2776static inline void QCBOREncode_AddURI(QCBOREncodeContext *pCtx, UsefulBufC URI)
2777{
2778 QCBOREncode_AddTag(pCtx, CBOR_TAG_URI);
2779 QCBOREncode_AddText(pCtx, URI);
2780}
2781
2782static inline void QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC URI)
2783{
2784 QCBOREncode_AddSZString(pCtx, szLabel);
2785 QCBOREncode_AddTag(pCtx, CBOR_TAG_URI);
2786 QCBOREncode_AddText(pCtx, URI);
2787}
2788
2789static inline void QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC URI)
2790{
2791 QCBOREncode_AddInt64(pCtx, nLabel);
2792 QCBOREncode_AddTag(pCtx, CBOR_TAG_URI);
2793 QCBOREncode_AddText(pCtx, URI);
2794}
2795
2796
2797
2798static inline void QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx, UsefulBufC B64Text)
2799{
2800 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64);
2801 QCBOREncode_AddText(pCtx, B64Text);
2802}
2803
2804static inline void QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text)
2805{
2806 QCBOREncode_AddSZString(pCtx, szLabel);
2807 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64);
2808 QCBOREncode_AddText(pCtx, B64Text);
2809}
2810
2811static inline void QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text)
2812{
2813 QCBOREncode_AddInt64(pCtx, nLabel);
2814 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64);
2815 QCBOREncode_AddText(pCtx, B64Text);
2816}
2817
2818
2819static inline void QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx, UsefulBufC B64Text)
2820{
2821 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64URL);
2822 QCBOREncode_AddText(pCtx, B64Text);
2823}
2824
2825static inline void QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text)
2826{
2827 QCBOREncode_AddSZString(pCtx, szLabel);
2828 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64URL);
2829 QCBOREncode_AddText(pCtx, B64Text);
2830}
2831
2832static inline void QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text)
2833{
2834 QCBOREncode_AddInt64(pCtx, nLabel);
2835 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64URL);
2836 QCBOREncode_AddText(pCtx, B64Text);
2837}
2838
2839
2840static inline void QCBOREncode_AddRegex(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
2841{
2842 QCBOREncode_AddTag(pCtx, CBOR_TAG_REGEX);
2843 QCBOREncode_AddText(pCtx, Bytes);
2844}
2845
2846static inline void QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
2847{
2848 QCBOREncode_AddSZString(pCtx, szLabel);
2849 QCBOREncode_AddTag(pCtx, CBOR_TAG_REGEX);
2850 QCBOREncode_AddText(pCtx, Bytes);
2851}
2852
2853static inline void QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
2854{
2855 QCBOREncode_AddInt64(pCtx, nLabel);
2856 QCBOREncode_AddTag(pCtx, CBOR_TAG_REGEX);
2857 QCBOREncode_AddText(pCtx, Bytes);
2858}
2859
2860
2861static inline void QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx, UsefulBufC MIMEData)
2862{
2863 QCBOREncode_AddTag(pCtx, CBOR_TAG_MIME);
2864 QCBOREncode_AddText(pCtx, MIMEData);
2865}
2866
2867static inline void QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC MIMEData)
2868{
2869 QCBOREncode_AddSZString(pCtx, szLabel);
2870 QCBOREncode_AddTag(pCtx, CBOR_TAG_MIME);
2871 QCBOREncode_AddText(pCtx, MIMEData);
2872}
2873
2874static inline void QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC MIMEData)
2875{
2876 QCBOREncode_AddInt64(pCtx, nLabel);
2877 QCBOREncode_AddTag(pCtx, CBOR_TAG_MIME);
2878 QCBOREncode_AddText(pCtx, MIMEData);
2879}
2880
2881
2882static inline void QCBOREncode_AddDateString(QCBOREncodeContext *pCtx, const char *szDate)
2883{
2884 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_STRING);
2885 QCBOREncode_AddSZString(pCtx, szDate);
2886}
2887
2888static inline void QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szDate)
2889{
2890 QCBOREncode_AddSZString(pCtx, szLabel);
2891 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_STRING);
2892 QCBOREncode_AddSZString(pCtx, szDate);
2893}
2894
2895static inline void QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szDate)
2896{
2897 QCBOREncode_AddInt64(pCtx, nLabel);
2898 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_STRING);
2899 QCBOREncode_AddSZString(pCtx, szDate);
2900}
2901
2902
2903static inline void QCBOREncode_AddSimple(QCBOREncodeContext *pCtx, uint64_t uNum)
2904{
2905 QCBOREncode_AddType7(pCtx, 0, uNum);
2906}
2907
2908static inline void QCBOREncode_AddSimpleToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint8_t uSimple)
2909{
2910 QCBOREncode_AddSZString(pCtx, szLabel);
2911 QCBOREncode_AddSimple(pCtx, uSimple);
2912}
2913
2914static inline void QCBOREncode_AddSimpleToMapN(QCBOREncodeContext *pCtx, int nLabel, uint8_t uSimple)
2915{
2916 QCBOREncode_AddInt64(pCtx, nLabel);
2917 QCBOREncode_AddSimple(pCtx, uSimple);
2918}
2919
2920
2921static inline void QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b)
2922{
2923 uint8_t uSimple = CBOR_SIMPLEV_FALSE;
2924 if(b) {
2925 uSimple = CBOR_SIMPLEV_TRUE;
2926 }
2927 QCBOREncode_AddSimple(pCtx, uSimple);
2928}
2929
2930static inline void QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b)
2931{
2932 QCBOREncode_AddSZString(pCtx, szLabel);
2933 QCBOREncode_AddBool(pCtx, b);
2934}
2935
2936static inline void QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b)
2937{
2938 QCBOREncode_AddInt64(pCtx, nLabel);
2939 QCBOREncode_AddBool(pCtx, b);
2940}
2941
2942
2943static inline void QCBOREncode_AddNULL(QCBOREncodeContext *pCtx)
2944{
2945 QCBOREncode_AddSimple(pCtx, CBOR_SIMPLEV_NULL);
2946}
2947
2948static inline void QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel)
2949{
2950 QCBOREncode_AddSZString(pCtx, szLabel);
2951 QCBOREncode_AddNULL(pCtx);
2952}
2953
2954static inline void QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
2955{
2956 QCBOREncode_AddInt64(pCtx, nLabel);
2957 QCBOREncode_AddNULL(pCtx);
2958}
2959
2960
2961static inline void QCBOREncode_AddUndef(QCBOREncodeContext *pCtx)
2962{
2963 QCBOREncode_AddSimple(pCtx, CBOR_SIMPLEV_UNDEF);
2964}
2965
2966static inline void QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel)
2967{
2968 QCBOREncode_AddSZString(pCtx, szLabel);
2969 QCBOREncode_AddUndef(pCtx);
2970}
2971
2972static inline void QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
2973{
2974 QCBOREncode_AddInt64(pCtx, nLabel);
2975 QCBOREncode_AddUndef(pCtx);
2976}
2977
2978
2979static inline void QCBOREncode_OpenArray(QCBOREncodeContext *pCtx)
2980{
2981 QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_ARRAY);
2982}
2983
2984static inline void QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel)
2985{
2986 QCBOREncode_AddSZString(pCtx, szLabel);
2987 QCBOREncode_OpenArray(pCtx);
2988}
2989
2990static inline void QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
2991{
2992 QCBOREncode_AddInt64(pCtx, nLabel);
2993 QCBOREncode_OpenArray(pCtx);
2994}
2995
2996static inline void QCBOREncode_CloseArray(QCBOREncodeContext *pCtx)
2997{
2998 QCBOREncode_CloseMapOrArray(pCtx, CBOR_MAJOR_TYPE_ARRAY, NULL);
2999}
3000
3001
3002static inline void QCBOREncode_OpenMap(QCBOREncodeContext *pCtx)
3003{
3004 QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_MAP);
3005}
3006
3007static inline void QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel)
3008{
3009 QCBOREncode_AddSZString(pCtx, szLabel);
3010 QCBOREncode_OpenMap(pCtx);
3011}
3012
3013static inline void QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
3014{
3015 QCBOREncode_AddInt64(pCtx, nLabel);
3016 QCBOREncode_OpenMap(pCtx);
3017}
3018
3019static inline void QCBOREncode_CloseMap(QCBOREncodeContext *pCtx)
3020{
3021 QCBOREncode_CloseMapOrArray(pCtx, CBOR_MAJOR_TYPE_MAP, NULL);
3022}
3023
Laurence Lundblade234fe422019-12-02 13:04:34 -08003024static inline void QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pCtx)
3025{
3026 QCBOREncode_OpenMapOrArrayIndefiniteLength(pCtx, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
3027}
3028
3029static inline void QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pCtx, const char *szLabel)
3030{
3031 QCBOREncode_AddSZString(pCtx, szLabel);
3032 QCBOREncode_OpenArrayIndefiniteLength(pCtx);
3033}
3034
3035static inline void QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
3036{
3037 QCBOREncode_AddInt64(pCtx, nLabel);
3038 QCBOREncode_OpenArrayIndefiniteLength(pCtx);
3039}
3040
3041static inline void QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pCtx)
3042{
3043 QCBOREncode_CloseMapOrArrayIndefiniteLength(pCtx, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN, NULL);
3044}
3045
3046
3047static inline void QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pCtx)
3048{
3049 QCBOREncode_OpenMapOrArrayIndefiniteLength(pCtx, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
3050}
3051
3052static inline void QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pCtx, const char *szLabel)
3053{
3054 QCBOREncode_AddSZString(pCtx, szLabel);
3055 QCBOREncode_OpenMapIndefiniteLength(pCtx);
3056}
3057
3058static inline void QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
3059{
3060 QCBOREncode_AddInt64(pCtx, nLabel);
3061 QCBOREncode_OpenMapIndefiniteLength(pCtx);
3062}
3063
3064static inline void QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pCtx)
3065{
3066 QCBOREncode_CloseMapOrArrayIndefiniteLength(pCtx, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN, NULL);
3067}
Laurence Lundblade6ed34222018-12-18 09:46:23 -08003068
3069static inline void QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx)
3070{
3071 QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_BYTE_STRING);
3072}
3073
3074static inline void QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel)
3075{
3076 QCBOREncode_AddSZString(pCtx, szLabel);
3077 QCBOREncode_BstrWrap(pCtx);
3078}
3079
3080static inline void QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
3081{
3082 QCBOREncode_AddInt64(pCtx, nLabel);
3083 QCBOREncode_BstrWrap(pCtx);
3084}
3085
3086static inline void QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR)
3087{
3088 QCBOREncode_CloseMapOrArray(pCtx, CBOR_MAJOR_TYPE_BYTE_STRING, pWrappedCBOR);
3089}
3090
3091
3092static inline void QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded)
3093{
3094 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_NONE_TYPE_RAW, Encoded);
3095}
3096
3097static inline void QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded)
3098{
3099 QCBOREncode_AddSZString(pCtx, szLabel);
3100 QCBOREncode_AddEncoded(pCtx, Encoded);
3101}
3102
3103static inline void QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded)
3104{
3105 QCBOREncode_AddInt64(pCtx, nLabel);
3106 QCBOREncode_AddEncoded(pCtx, Encoded);
3107}
3108
3109
Laurence Lundblade852a33c2019-06-11 09:00:07 -07003110static inline int QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx)
3111{
3112 return UsefulOutBuf_IsBufferNULL(&(pCtx->OutBuf));
3113}
3114
3115static inline QCBORError QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx)
3116{
Laurence Lundblade234fe422019-12-02 13:04:34 -08003117 if(UsefulOutBuf_GetError(&(pCtx->OutBuf))) {
3118 // Items didn't fit in the buffer.
3119 // This check catches this condition for all the appends and inserts
3120 // so checks aren't needed when the appends and inserts are performed.
3121 // And of course UsefulBuf will never overrun the input buffer given
3122 // to it. No complex analysis of the error handling in this file is
3123 // needed to know that is true. Just read the UsefulBuf code.
3124 pCtx->uError = QCBOR_ERR_BUFFER_TOO_SMALL;
3125 // QCBOR_ERR_BUFFER_TOO_SMALL masks other errors, but that is
3126 // OK. Once the caller fixes this, they'll be unmasked.
3127 }
3128
3129 return (QCBORError)pCtx->uError;
Laurence Lundblade852a33c2019-06-11 09:00:07 -07003130}
3131
3132
Laurence Lundblade6ed34222018-12-18 09:46:23 -08003133/* ===========================================================================
3134 END OF PRIVATE INLINE IMPLEMENTATION
3135
3136 =========================================================================== */
3137
Laurence Lundbladed425fb32019-02-18 10:56:18 -08003138#ifdef __cplusplus
3139}
3140#endif
3141
Laurence Lundblade6ed34222018-12-18 09:46:23 -08003142#endif /* defined(__QCBOR__qcbor__) */