blob: 00e3656d5f4f86bfff1683da36878318d87112c4 [file] [log] [blame]
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001/*==============================================================================
2 Copyright (c) 2016-2018, The Linux Foundation.
Laurence Lundbladeac515e52020-01-30 10:44:06 -08003 Copyright (c) 2018-2020, Laurence Lundblade.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08004 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.
Laurence Lundbladeac515e52020-01-30 10:44:06 -080031 =============================================================================*/
Laurence Lundblade6ed34222018-12-18 09:46:23 -080032
33
Laurence Lundbladeac515e52020-01-30 10:44:06 -080034/*=============================================================================
Laurence Lundblade6ed34222018-12-18 09:46:23 -080035 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 Lundbladeac515e52020-01-30 10:44:06 -080044 when who what, where, why
45 -------- ---- ---------------------------------------------------
46 01/25/2020 llundblade Cleaner handling of too-long encoded string input.
47 01/08/2020 llundblade Documentation corrections & improved code formatting.
48 12/30/19 llundblade Add support for decimal fractions and bigfloats.
49 08/7/19 llundblade Better handling of not well-formed encode and decode.
50 07/31/19 llundblade New error code for better end of data handling.
51 7/25/19 janjongboom Add indefinite length encoding for maps and arrays.
52 05/26/19 llundblade Add QCBOREncode_GetErrorState() and _IsBufferNULL().
53 04/26/19 llundblade Big documentation & style update. No interface change.
54 02/16/19 llundblade Redesign MemPool to fix memory access alignment bug.
55 12/18/18 llundblade Move decode malloc optional code to separate repo.
56 12/13/18 llundblade Documentatation improvements.
57 11/29/18 llundblade Rework to simpler handling of tags and labels.
58 11/9/18 llundblade Error codes are now enums.
59 11/1/18 llundblade Floating support.
60 10/31/18 llundblade Switch to one license that is almost BSD-3.
61 10/15/18 llundblade indefinite-length maps and arrays supported
62 10/8/18 llundblade indefinite-length strings supported
63 09/28/18 llundblade Added bstr wrapping feature for COSE implementation.
64 07/05/17 llundbla Add bstr wrapping of maps/arrays for COSE.
65 03/01/17 llundbla More data types; decoding improvements and fixes.
66 11/13/16 llundbla Integrate most TZ changes back into github version.
67 09/30/16 gkanike Porting to TZ.
68 03/15/16 llundbla Initial Version.
Laurence Lundblade6ed34222018-12-18 09:46:23 -080069
Laurence Lundbladeac515e52020-01-30 10:44:06 -080070 =============================================================================*/
Laurence Lundblade6ed34222018-12-18 09:46:23 -080071
72#ifndef __QCBOR__qcbor__
73#define __QCBOR__qcbor__
74
Laurence Lundblade6ed34222018-12-18 09:46:23 -080075
76/* ===========================================================================
77 BEGINNING OF PRIVATE PART OF THIS FILE
78
79 Caller of QCBOR should not reference any of the details below up until
80 the start of the public part.
Laurence Lundbladeac515e52020-01-30 10:44:06 -080081 ========================================================================== */
Laurence Lundblade6ed34222018-12-18 09:46:23 -080082
83/*
84 Standard integer types are used in the interface to be precise about
85 sizes to be better at preventing underflow/overflow errors.
86 */
87#include <stdint.h>
88#include <stdbool.h>
89#include "UsefulBuf.h"
90
Laurence Lundbladed425fb32019-02-18 10:56:18 -080091#ifdef __cplusplus
92extern "C" {
93#endif
Laurence Lundblade6ed34222018-12-18 09:46:23 -080094
95/*
96 The maxium nesting of arrays and maps when encoding or decoding.
97 (Further down in the file there is a definition that refers to this
98 that is public. This is done this way so there can be a nice
99 separation of public and private parts in this file.
100*/
101#define QCBOR_MAX_ARRAY_NESTING1 15 // Do not increase this over 255
102
103
104/* The largest offset to the start of an array or map. It is slightly
105 less than UINT32_MAX so the error condition can be tests on 32-bit machines.
106 UINT32_MAX comes from uStart in QCBORTrackNesting being a uin32_t.
107
108 This will cause trouble on a machine where size_t is less than 32-bits.
109 */
110#define QCBOR_MAX_ARRAY_OFFSET (UINT32_MAX - 100)
111
112/*
113 PRIVATE DATA STRUCTURE
114
Laurence Lundbladeac515e52020-01-30 10:44:06 -0800115 Holds the data for tracking array and map nesting during encoding. Pairs up
116 with the Nesting_xxx functions to make an "object" to handle nesting encoding.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800117
118 uStart is a uint32_t instead of a size_t to keep the size of this
119 struct down so it can be on the stack without any concern. It would be about
120 double if size_t was used instead.
121
122 Size approximation (varies with CPU/compiler):
123 64-bit machine: (15 + 1) * (4 + 2 + 1 + 1 pad) + 8 = 136 bytes
124 32-bit machine: (15 + 1) * (4 + 2 + 1 + 1 pad) + 4 = 132 bytes
125*/
126typedef struct __QCBORTrackNesting {
127 // PRIVATE DATA STRUCTURE
128 struct {
Laurence Lundbladeac515e52020-01-30 10:44:06 -0800129 // See function QCBOREncode_OpenMapOrArray() for details on how this works
130 uint32_t uStart; // uStart is the byte position where the array starts
131 uint16_t uCount; // Number of items in the arrary or map; counts items
132 // in a map, not pairs of items
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800133 uint8_t uMajorType; // Indicates if item is a map or an array
134 } pArrays[QCBOR_MAX_ARRAY_NESTING1+1], // stored state for the nesting levels
135 *pCurrentNesting; // the current nesting level
136} QCBORTrackNesting;
137
138
139/*
140 PRIVATE DATA STRUCTURE
141
142 Context / data object for encoding some CBOR. Used by all encode functions to
143 form a public "object" that does the job of encdoing.
144
145 Size approximation (varies with CPU/compiler):
146 64-bit machine: 27 + 1 (+ 4 padding) + 136 = 32 + 136 = 168 bytes
147 32-bit machine: 15 + 1 + 132 = 148 bytes
148*/
149struct _QCBOREncodeContext {
150 // PRIVATE DATA STRUCTURE
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700151 UsefulOutBuf OutBuf; // Pointer to output buffer, its length and
152 // position in it
153 uint8_t uError; // Error state, always from QCBORError enum
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800154 QCBORTrackNesting nesting; // Keep track of array and map nesting
155};
156
157
158/*
159 PRIVATE DATA STRUCTURE
160
161 Holds the data for array and map nesting for decoding work. This structure
162 and the DecodeNesting_xxx functions form an "object" that does the work
163 for arrays and maps.
164
165 Size approximation (varies with CPU/compiler):
166 64-bit machine: 4 * 16 + 8 = 72
167 32-bit machine: 4 * 16 + 4 = 68
168 */
169typedef struct __QCBORDecodeNesting {
170 // PRIVATE DATA STRUCTURE
171 struct {
172 uint16_t uCount;
173 uint8_t uMajorType;
174 } pMapsAndArrays[QCBOR_MAX_ARRAY_NESTING1+1],
175 *pCurrent;
176} QCBORDecodeNesting;
177
178
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800179typedef struct {
180 // PRIVATE DATA STRUCTURE
181 void *pAllocateCxt;
182 UsefulBuf (* pfAllocator)(void *pAllocateCxt, void *pOldMem, size_t uNewSize);
183} QCORInternalAllocator;
184
185
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800186/*
187 PRIVATE DATA STRUCTURE
188
189 The decode context. This data structure plus the public QCBORDecode_xxx
190 functions form an "object" that does CBOR decoding.
191
192 Size approximation (varies with CPU/compiler):
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800193 64-bit machine: 32 + 1 + 1 + 6 bytes padding + 72 + 16 + 8 + 8 = 144 bytes
194 32-bit machine: 16 + 1 + 1 + 2 bytes padding + 68 + 8 + 8 + 4 = 108 bytes
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800195 */
196struct _QCBORDecodeContext {
197 // PRIVATE DATA STRUCTURE
198 UsefulInputBuf InBuf;
199
200 uint8_t uDecodeMode;
201 uint8_t bStringAllocateAll;
202
203 QCBORDecodeNesting nesting;
204
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700205 // If a string allocator is configured for indefinite-length
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800206 // strings, it is configured here.
207 QCORInternalAllocator StringAllocator;
208
209 // These are special for the internal MemPool allocator.
210 // They are not used otherwise. We tried packing these
211 // in the MemPool itself, but there are issues
212 // with memory alignment.
213 uint32_t uMemPoolSize;
214 uint32_t uMemPoolFreeOffset;
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800215
216 // This is NULL or points to QCBORTagList.
217 // It is type void for the same reason as above.
218 const void *pCallerConfiguredTagList;
219};
220
221// Used internally in the impementation here
222// Must not conflict with any of the official CBOR types
223#define CBOR_MAJOR_NONE_TYPE_RAW 9
224#define CBOR_MAJOR_NONE_TAG_LABEL_REORDER 10
Laurence Lundbladec93b5a72019-04-06 12:17:16 -0700225#define CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY 11
Laurence Lundblade234fe422019-12-02 13:04:34 -0800226#define CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN 12
227#define CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN 13
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800228
229
Laurence Lundbladeac515e52020-01-30 10:44:06 -0800230/* ==========================================================================
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800231 END OF PRIVATE PART OF THIS FILE
232
233 BEGINNING OF PUBLIC PART OF THIS FILE
Laurence Lundbladeac515e52020-01-30 10:44:06 -0800234 ========================================================================== */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800235
236
237
Laurence Lundbladeac515e52020-01-30 10:44:06 -0800238/* ==========================================================================
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800239 BEGINNING OF CONSTANTS THAT COME FROM THE CBOR STANDARD, RFC 7049
240
241 It is not necessary to use these directly when encoding or decoding
242 CBOR with this implementation.
Laurence Lundbladeac515e52020-01-30 10:44:06 -0800243 ========================================================================== */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800244
245/* Standard CBOR Major type for positive integers of various lengths */
246#define CBOR_MAJOR_TYPE_POSITIVE_INT 0
247
248/* Standard CBOR Major type for negative integer of various lengths */
249#define CBOR_MAJOR_TYPE_NEGATIVE_INT 1
250
251/* Standard CBOR Major type for an array of arbitrary 8-bit bytes. */
252#define CBOR_MAJOR_TYPE_BYTE_STRING 2
253
254/* Standard CBOR Major type for a UTF-8 string. Note this is true 8-bit UTF8
255 with no encoding and no NULL termination */
256#define CBOR_MAJOR_TYPE_TEXT_STRING 3
257
258/* Standard CBOR Major type for an ordered array of other CBOR data items */
259#define CBOR_MAJOR_TYPE_ARRAY 4
260
261/* Standard CBOR Major type for CBOR MAP. Maps an array of pairs. The
262 first item in the pair is the "label" (key, name or identfier) and the second
263 item is the value. */
264#define CBOR_MAJOR_TYPE_MAP 5
265
266/* Standard CBOR optional tagging. This tags things like dates and URLs */
267#define CBOR_MAJOR_TYPE_OPTIONAL 6
268
269/* Standard CBOR extra simple types like floats and the values true and false */
270#define CBOR_MAJOR_TYPE_SIMPLE 7
271
272
273/*
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700274 These are special values for the AdditionalInfo bits that are part of
275 the first byte. Mostly they encode the length of the data item.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800276 */
277#define LEN_IS_ONE_BYTE 24
278#define LEN_IS_TWO_BYTES 25
279#define LEN_IS_FOUR_BYTES 26
280#define LEN_IS_EIGHT_BYTES 27
281#define ADDINFO_RESERVED1 28
282#define ADDINFO_RESERVED2 29
283#define ADDINFO_RESERVED3 30
284#define LEN_IS_INDEFINITE 31
285
286
287/*
288 24 is a special number for CBOR. Integers and lengths
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700289 less than it are encoded in the same byte as the major type.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800290 */
291#define CBOR_TWENTY_FOUR 24
292
293
294/*
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700295 Tags that are used with CBOR_MAJOR_TYPE_OPTIONAL. These
296 are types defined in RFC 7049 and some additional ones
297 in the IANA CBOR tags registry.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800298 */
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700299/** See QCBOREncode_AddDateString(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800300#define CBOR_TAG_DATE_STRING 0
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700301/** See QCBOREncode_AddDateEpoch(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800302#define CBOR_TAG_DATE_EPOCH 1
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700303/** See QCBOREncode_AddPositiveBignum(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800304#define CBOR_TAG_POS_BIGNUM 2
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700305/** See QCBOREncode_AddNegativeBignum(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800306#define CBOR_TAG_NEG_BIGNUM 3
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700307/** CBOR tag for a two-element array representing a fraction with a
Laurence Lundbladeac515e52020-01-30 10:44:06 -0800308 mantissa and base-10 scaling factor. See QCBOREncode_AddDecimalFraction()
309 and @ref expAndMantissa.
310 */
311#define CBOR_TAG_DECIMAL_FRACTION 4
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700312/** CBOR tag for a two-element array representing a fraction with a
Laurence Lundbladeac515e52020-01-30 10:44:06 -0800313 mantissa and base-2 scaling factor. See QCBOREncode_AddBigFloat()
314 and @ref expAndMantissa. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800315#define CBOR_TAG_BIGFLOAT 5
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700316/** Tag for COSE format encryption with no recipient
317 identification. See [RFC 8152, COSE]
318 (https://tools.ietf.org/html/rfc8152). No API is provided for this
319 tag. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800320#define CBOR_TAG_COSE_ENCRYPTO 16
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700321/** Tag for COSE format MAC'd data with no recipient
322 identification. See [RFC 8152, COSE]
323 (https://tools.ietf.org/html/rfc8152). No API is provided for this
324 tag.*/
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800325#define CBOR_TAG_COSE_MAC0 17
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700326/** Tag for COSE format single signature signing. No API is provided
327 for this tag. See [RFC 8152, COSE]
328 (https://tools.ietf.org/html/rfc8152). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800329#define CBOR_TAG_COSE_SIGN1 18
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700330/** A hint that the following byte string should be encoded in
331 Base64URL when converting to JSON or similar text-based
332 representations. Call @c
333 QCBOREncode_AddTag(pCtx,CBOR_TAG_ENC_AS_B64URL) before the call to
334 QCBOREncode_AddBytes(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800335#define CBOR_TAG_ENC_AS_B64URL 21
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700336/** A hint that the following byte string should be encoded in Base64
337 when converting to JSON or similar text-based
338 representations. Call @c
339 QCBOREncode_AddTag(pCtx,CBOR_TAG_ENC_AS_B64) before the call to
340 QCBOREncode_AddBytes(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800341#define CBOR_TAG_ENC_AS_B64 22
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700342/** A hint that the following byte string should be encoded in base-16
343 format per [RFC 4648] (https://tools.ietf.org/html/rfc4648) when
344 converting to JSON or similar text-based
345 representations. Essentially, Base-16 encoding is the standard
346 case- insensitive hex encoding and may be referred to as
347 "hex". Call @c QCBOREncode_AddTag(pCtx,CBOR_TAG_ENC_AS_B16) before
348 the call to QCBOREncode_AddBytes(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800349#define CBOR_TAG_ENC_AS_B16 23
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700350/** Tag to indicate a byte string contains encoded CBOR. No API is
351 provided for this tag. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800352#define CBOR_TAG_CBOR 24
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700353/** See QCBOREncode_AddURI(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800354#define CBOR_TAG_URI 32
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700355/** See QCBOREncode_AddB64URLText(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800356#define CBOR_TAG_B64URL 33
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700357/** See QCBOREncode_AddB64Text(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800358#define CBOR_TAG_B64 34
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700359/** See QCBOREncode_AddRegex(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800360#define CBOR_TAG_REGEX 35
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700361/** See QCBOREncode_AddMIMEData(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800362#define CBOR_TAG_MIME 36
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700363/** See QCBOREncode_AddBinaryUUID(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800364#define CBOR_TAG_BIN_UUID 37
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700365/** The data is a CBOR Web Token per [RFC 8392]
366 (https://tools.ietf.org/html/rfc8932). No API is provided for this
367 tag. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800368#define CBOR_TAG_CWT 61
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700369/** Tag for COSE format encryption. 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_ENCRYPT 96
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700373/** Tag for COSE format MAC. 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_MAC 97
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700377/** Tag for COSE format signed data. See [RFC 8152, COSE]
378 (https://tools.ietf.org/html/rfc8152). No API is provided for this
379 tag. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800380#define CBOR_TAG_SIGN 98
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700381/** World geographic coordinates. See ISO 6709, [RFC 5870]
382 (https://tools.ietf.org/html/rfc5870) and WGS-84. No API is
383 provided for this tag. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800384#define CBOR_TAG_GEO_COORD 103
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700385/** The magic number, self-described CBOR. No API is provided for this
386 tag. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800387#define CBOR_TAG_CBOR_MAGIC 55799
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700388
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800389#define CBOR_TAG_NONE UINT64_MAX
390
391
392/*
393 Values for the 5 bits for items of major type 7
394 */
395#define CBOR_SIMPLEV_FALSE 20
396#define CBOR_SIMPLEV_TRUE 21
397#define CBOR_SIMPLEV_NULL 22
398#define CBOR_SIMPLEV_UNDEF 23
399#define CBOR_SIMPLEV_ONEBYTE 24
400#define HALF_PREC_FLOAT 25
401#define SINGLE_PREC_FLOAT 26
402#define DOUBLE_PREC_FLOAT 27
403#define CBOR_SIMPLE_BREAK 31
Laurence Lundblade234fe422019-12-02 13:04:34 -0800404#define CBOR_SIMPLEV_RESERVED_START CBOR_SIMPLEV_ONEBYTE
405#define CBOR_SIMPLEV_RESERVED_END CBOR_SIMPLE_BREAK
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800406
407
408
409/* ===========================================================================
410
411 END OF CONSTANTS THAT COME FROM THE CBOR STANDARD, RFC 7049
412
413 BEGINNING OF PUBLIC INTERFACE FOR QCBOR ENCODER / DECODER
414
415 =========================================================================== */
416
417/**
418
419 @file qcbor.h
420
421 Q C B O R E n c o d e / D e c o d e
422
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700423 This implements CBOR -- Concise Binary Object Representation as
424 defined in [RFC 7049] (https://tools.ietf.org/html/rfc7049). More
425 info is at http://cbor.io. This is a near-complete implementation of
426 the specification. Limitations are listed further down.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800427
428 CBOR is intentionally designed to be translatable to JSON, but not
429 all CBOR can convert to JSON. See RFC 7049 for more info on how to
430 construct CBOR that is the most JSON friendly.
431
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700432 The memory model for encoding and decoding is that encoded CBOR must
433 be in a contiguous buffer in memory. During encoding the caller must
434 supply an output buffer and if the encoding would go off the end of
435 the buffer an error is returned. During decoding the caller supplies
436 the encoded CBOR in a contiguous buffer and the decoder returns
437 pointers and lengths into that buffer for strings.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800438
439 This implementation does not require malloc. All data structures
440 passed in/out of the APIs can fit on the stack.
441
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700442 Decoding of indefinite-length strings is a special case that requires
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800443 a "string allocator" to allocate memory into which the segments of
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700444 the string are coalesced. Without this, decoding will error out if an
445 indefinite-length string is encountered (indefinite-length maps and
446 arrays do not require the string allocator). A simple string
447 allocator called MemPool is built-in and will work if supplied with a
448 block of memory to allocate. The string allocator can optionally use
449 malloc() or some other custom scheme.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800450
451 Here are some terms and definitions:
452
453 - "Item", "Data Item": An integer or string or such. The basic "thing" that
454 CBOR is about. An array is an item itself that contains some items.
455
456 - "Array": An ordered sequence of items, the same as JSON.
457
458 - "Map": A collection of label/value pairs. Each pair is a data
459 item. A JSON "object" is the same as a CBOR "map".
460
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700461 - "Label": The data item in a pair in a map that names or identifies
462 the pair, not the value. This implementation refers to it as a
463 "label". JSON refers to it as the "name". The CBOR RFC refers to it
464 this as a "key". This implementation chooses label instead because
465 key is too easily confused with a cryptographic key. The COSE
466 standard, which uses CBOR, has also chosen to use the term "label"
467 rather than "key" for this same reason.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800468
469 - "Key": See "Label" above.
470
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700471 - "Tag": Optional integer that can be added before each data item
472 usually to indicate it is new or more specific data type. For
473 example, a tag can indicate an integer is a date, or that a map is to
474 be considered a type (analogous to a typedef in C).
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800475
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700476 - "Initial Byte": The first byte of an encoded item. Encoding and
477 decoding of this byte is taken care of by the implementation.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800478
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700479 - "Additional Info": In addition to the major type, all data items
480 have some other info. This is usually the length of the data but can
481 be several other things. Encoding and decoding of this is taken care
482 of by the implementation.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800483
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700484 CBOR has two mechanisms for tagging and labeling the data values like
485 integers and strings. For example, an integer that represents
486 someone's birthday in epoch seconds since Jan 1, 1970 could be
487 encoded like this:
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800488
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700489 - First it is CBOR_MAJOR_TYPE_POSITIVE_INT (@ref QCBOR_TYPE_INT64),
490 the primitive positive integer.
491
492 - Next it has a "tag" @ref CBOR_TAG_DATE_EPOCH indicating the integer
493 represents a date in the form of the number of seconds since Jan 1,
494 1970.
495
496 - Last it has a string "label" like "BirthDate" indicating the
497 meaning of the data.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800498
499 The encoded binary looks like this:
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800500
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700501 a1 # Map of 1 item
502 69 # Indicates text string of 9 bytes
503 426972746844617465 # The text "BirthDate"
504 c1 # Tags next integer as epoch date
505 1a # Indicates a 4-byte integer
506 580d4172 # unsigned integer date 1477263730
507
508 Implementors using this API will primarily work with
509 labels. Generally, tags are only needed for making up new data
510 types. This implementation covers most of the data types defined in
511 the RFC using tags. It also, allows for the use of custom tags if
512 necessary.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800513
514 This implementation explicitly supports labels that are text strings
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700515 and integers. Text strings translate nicely into JSON objects and are
516 very readable. Integer labels are much less readable but can be very
517 compact. If they are in the range of 0 to 23, they take up only one
518 byte.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800519
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700520 CBOR allows a label to be any type of data including an array or a
521 map. It is possible to use this API to construct and parse such
522 labels, but it is not explicitly supported.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800523
524 A common encoding usage mode is to invoke the encoding twice. First
525 with no output buffer to compute the length of the needed output
526 buffer. Then the correct sized output buffer is allocated. Last the
527 encoder is invoked again, this time with the output buffer.
528
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700529 The double invocation is not required if the maximum output buffer
530 size can be predicted. This is usually possible for simple CBOR
531 structures. If the double invocation is implemented, it can be in a
532 loop or function as in the example code so that the code doesn't have
533 to actually be written twice, saving code size.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800534
535 If a buffer too small to hold the encoded output is given, the error
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700536 @ref QCBOR_ERR_BUFFER_TOO_SMALL will be returned. Data will never be
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800537 written off the end of the output buffer no matter which functions
538 here are called or what parameters are passed to them.
539
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700540 The encoding error handling is simple. The only possible errors are
541 trying to encode structures that are too large or too complex. There
542 are no internal malloc calls so there will be no failures for out of
Laurence Lundblade234fe422019-12-02 13:04:34 -0800543 memory. The error state is tracked internally, so there is no need
544 to check for errors when encoding. Only the return code from
545 QCBOREncode_Finish() need be checked as once an error happens, the
546 encoder goes into an error state and calls to it to add more data
547 will do nothing. An error check is not needed after every data item
548 is added.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800549
550 Encoding generally proceeds by calling QCBOREncode_Init(), calling
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700551 lots of @c QCBOREncode_AddXxx() functions and calling
552 QCBOREncode_Finish(). There are many @c QCBOREncode_AddXxx()
553 functions for various data types. The input buffers need only to be
554 valid during the @c QCBOREncode_AddXxx() calls as the data is copied
555 into the output buffer.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800556
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700557 There are three `Add` functions for each data type. The first / main
558 one for the type is for adding the data item to an array. The second
559 one's name ends in `ToMap`, is used for adding data items to maps and
560 takes a string argument that is its label in the map. The third one
561 ends in `ToMapN`, is also used for adding data items to maps, and
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800562 takes an integer argument that is its label in the map.
563
564 The simplest aggregate type is an array, which is a simple ordered
565 set of items without labels the same as JSON arrays. Call
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700566 QCBOREncode_OpenArray() to open a new array, then various @c
567 QCBOREncode_AddXxx() functions to put items in the array and then
568 QCBOREncode_CloseArray(). Nesting to the limit @ref
569 QCBOR_MAX_ARRAY_NESTING is allowed. All opens must be matched by
570 closes or an encoding error will be returned.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800571
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700572 The other aggregate type is a map which does use labels. The `Add`
573 functions that end in `ToMap` and `ToMapN` are convenient ways to add
574 labeled data items to a map. You can also call any type of `Add`
575 function once to add a label of any time and then call any type of
576 `Add` again to add its value.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800577
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700578 Note that when you nest arrays or maps in a map, the nested array or
579 map has a label.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800580
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700581 @anchor Tags-Overview
582 Any CBOR data item can be tagged to add semantics, define a new data
583 type or such. Some tags are fully standardized and some are just
584 registered. Others are not registered and used in a proprietary way.
585
586 Encoding and decoding of many of the registered tags is fully
587 implemented by QCBOR. It is also possible to encode and decode tags
588 that are not directly supported. For many use cases the built-in tag
589 support should be adequate.
590
591 For example, the registered epoch date tag is supported in encoding
592 by QCBOREncode_AddDateEpoch() and in decoding by @ref
593 QCBOR_TYPE_DATE_EPOCH and the @c epochDate member of @ref
594 QCBORItem. This is typical of the built-in tag support. There is an
595 API to encode data for it and a @c QCBOR_TYPE_XXX when it is decoded.
596
597 Tags are registered in the [IANA CBOR Tags Registry]
598 (https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml). There
599 are roughly three options to create a new tag. First, a public
600 specification can be created and the new tag registered with IANA.
601 This is the most formal. Second, the new tag can be registered with
602 IANA with just a short description rather than a full specification.
603 These tags must be greater than 256. Third, a tag can be used without
604 any IANA registration, though the registry should be checked to see
605 that the new value doesn't collide with one that is registered. The
606 value of these tags must be 256 or larger.
607
608 The encoding side of tags not built-in is handled by
609 QCBOREncode_AddTag() and is relatively simple. Tag decoding is more
610 complex and mainly handled by QCBORDecode_GetNext(). Decoding of the
611 structure of tagged data not built-in (if there is any) has to be
612 implemented by the caller.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800613
614 Summary Limits of this implementation:
615 - The entire encoded CBOR must fit into contiguous memory.
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700616 - Max size of encoded / decoded CBOR data is @c UINT32_MAX (4GB).
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800617 - Max array / map nesting level when encoding / decoding is
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700618 @ref QCBOR_MAX_ARRAY_NESTING (this is typically 15).
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800619 - Max items in an array or map when encoding / decoding is
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700620 @ref QCBOR_MAX_ITEMS_IN_ARRAY (typically 65,536).
Laurence Lundbladeac515e52020-01-30 10:44:06 -0800621 - Does not directly support labels in maps other than text strings & integers.
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700622 - Does not directly support integer labels greater than @c INT64_MAX.
623 - Epoch dates limited to @c INT64_MAX (+/- 292 billion years).
Laurence Lundbladeac515e52020-01-30 10:44:06 -0800624 - Exponents for bigfloats and decimal integers are limited to @c INT64_MAX.
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700625 - Tags on labels are ignored during decoding.
Laurence Lundbladeac515e52020-01-30 10:44:06 -0800626 - There is no duplicate detection of map labels (but duplicates are passed on).
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700627 - Works only on 32- and 64-bit CPUs (modifications could make it work
628 on 16-bit CPUs).
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800629
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700630 The public interface uses @c size_t for all lengths. Internally the
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800631 implementation uses 32-bit lengths by design to use less memory and
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700632 fit structures on the stack. This limits the encoded CBOR it can work
633 with to size @c UINT32_MAX (4GB) which should be enough.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800634
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700635 This implementation assumes two's compliment integer machines. @c
636 <stdint.h> also requires this. It is possible to modify this
637 implementation for another integer representation, but all modern
638 machines seem to be two's compliment.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800639
640 */
641
642
643/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700644 The maximum number of items in a single array or map when encoding of
645 decoding.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800646*/
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700647// -1 is because the value UINT16_MAX is used to track indefinite-length arrays
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800648#define QCBOR_MAX_ITEMS_IN_ARRAY (UINT16_MAX-1)
649
650/**
651 The maximum nesting of arrays and maps when encoding or decoding. The
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700652 error @ref QCBOR_ERR_ARRAY_NESTING_TOO_DEEP will be returned on
653 encoding of decoding if it is exceeded.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800654*/
655#define QCBOR_MAX_ARRAY_NESTING QCBOR_MAX_ARRAY_NESTING1
656
657/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700658 The maximum number of tags that can be in @ref QCBORTagListIn and passed to
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800659 QCBORDecode_SetCallerConfiguredTagList()
660 */
661#define QCBOR_MAX_CUSTOM_TAGS 16
662
663
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700664/**
665 Error codes returned by QCBOR Encoder and Decoder.
666 */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800667typedef enum {
668 /** The encode or decode completely correctly. */
669 QCBOR_SUCCESS = 0,
670
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700671 /** The buffer provided for the encoded output when doing encoding
672 was too small and the encoded output will not fit. Also, when
673 the buffer given to QCBORDecode_SetMemPool() is too small. */
674 QCBOR_ERR_BUFFER_TOO_SMALL = 1,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800675
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700676 /** During encoding or decoding, the array or map nesting was
677 deeper than this implementation can handle. Note that in the
678 interest of code size and memory use, this implementation has a
679 hard limit on array nesting. The limit is defined as the
680 constant @ref QCBOR_MAX_ARRAY_NESTING. */
681 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP = 2,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800682
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700683 /** During decoding or encoding, the array or map had too many
684 items in it. This limit @ref QCBOR_MAX_ITEMS_IN_ARRAY,
685 typically 65,535. */
686 QCBOR_ERR_ARRAY_TOO_LONG = 3,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800687
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700688 /** During encoding, more arrays or maps were closed than
689 opened. This is a coding error on the part of the caller of the
690 encoder. */
691 QCBOR_ERR_TOO_MANY_CLOSES = 4,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800692
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700693 /** During decoding, some CBOR construct was encountered that this
694 decoder doesn't support, primarily this is the reserved
Laurence Lundblade234fe422019-12-02 13:04:34 -0800695 additional info values, 28 through 30. During encoding,
696 an attempt to create simple value between 24 and 31. */
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700697 QCBOR_ERR_UNSUPPORTED = 5,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800698
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700699 /** During decoding, hit the end of the given data to decode. For
700 example, a byte string of 100 bytes was expected, but the end
701 of the input was hit before finding those 100 bytes. Corrupted
Laurence Lundblade234fe422019-12-02 13:04:34 -0800702 CBOR input will often result in this error. See also @ref
703 QCBOR_ERR_NO_MORE_ITEMS.
704 */
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700705 QCBOR_ERR_HIT_END = 6,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800706
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700707 /** During encoding, the length of the encoded CBOR exceeded @c
708 UINT32_MAX. */
709 QCBOR_ERR_BUFFER_TOO_LARGE = 7,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800710
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700711 /** During decoding, an integer smaller than INT64_MIN was received
712 (CBOR can represent integers smaller than INT64_MIN, but C
713 cannot). */
714 QCBOR_ERR_INT_OVERFLOW = 8,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800715
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700716 /** During decoding, the label for a map entry is bad. What causes
717 this error depends on the decoding mode. */
718 QCBOR_ERR_MAP_LABEL_TYPE = 9,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800719
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700720 /** During encoding or decoding, the number of array or map opens
721 was not matched by the number of closes. */
722 QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN = 10,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800723
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700724 /** During decoding, a date greater than +- 292 billion years from
725 Jan 1 1970 encountered during parsing. */
726 QCBOR_ERR_DATE_OVERFLOW = 11,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800727
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700728 /** During decoding, the CBOR is not valid, primarily a simple type
729 is encoded in a prohibited way. */
730 QCBOR_ERR_BAD_TYPE_7 = 12,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800731
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700732 /** Optional tagging that doesn't make sense (an integer is tagged
733 as a date string) or can't be handled. */
734 QCBOR_ERR_BAD_OPT_TAG = 13,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800735
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700736 /** Returned by QCBORDecode_Finish() if all the inputs bytes have
737 not been consumed. */
738 QCBOR_ERR_EXTRA_BYTES = 14,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800739
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700740 /** During encoding, @c QCBOREncode_CloseXxx() called with a
741 different type than is currently open. */
742 QCBOR_ERR_CLOSE_MISMATCH = 15,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800743
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700744 /** Unable to decode an indefinite-length string because no string
745 allocator was configured. See QCBORDecode_SetMemPool() or
746 QCBORDecode_SetUpAllocator(). */
747 QCBOR_ERR_NO_STRING_ALLOCATOR = 16,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800748
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700749 /** One of the chunks in an indefinite-length string is not of the
750 type of the start of the string. */
751 QCBOR_ERR_INDEFINITE_STRING_CHUNK = 17,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800752
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700753 /** Error allocating space for a string, usually for an
754 indefinite-length string. */
755 QCBOR_ERR_STRING_ALLOCATE = 18,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800756
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700757 /** During decoding, a break occurred outside an indefinite-length
758 item. */
759 QCBOR_ERR_BAD_BREAK = 19,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800760
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700761 /** During decoding, too many tags in the caller-configured tag
762 list, or not enough space in @ref QCBORTagListOut. */
763 QCBOR_ERR_TOO_MANY_TAGS = 20,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800764
Laurence Lundblade234fe422019-12-02 13:04:34 -0800765 /** An integer type is encoded with a bad length (an indefinite length) */
766 QCBOR_ERR_BAD_INT = 21,
767
768 /** All well-formed data items have been consumed and there are no
769 more. If parsing a CBOR stream this indicates the non-error
770 end of the stream. If parsing a CBOR stream / sequence, this
771 probably indicates that some data items expected are not present.
772 See also @ref QCBOR_ERR_HIT_END. */
Laurence Lundbladeac515e52020-01-30 10:44:06 -0800773 QCBOR_ERR_NO_MORE_ITEMS = 22,
774
775 /** Something is wrong with a decimal fraction or bigfloat such as
776 it not consisting of an array with two integers */
777 QCBOR_ERR_BAD_EXP_AND_MANTISSA = 23,
778
779 /** When decoding, a string's size is greater than size_t. In all but some
780 very strange situations this is because of corrupt input CBOR and
781 should be treated as such. The strange situation is a CPU with a very
782 small size_t (e.g., a 16-bit CPU) and a large string (e.g., > 65KB).
783 */
784 QCBOR_ERR_STRING_TOO_LONG = 24
Laurence Lundblade234fe422019-12-02 13:04:34 -0800785
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800786} QCBORError;
787
788
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700789/**
790 The decode mode options.
791 */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800792typedef enum {
793 /** See QCBORDecode_Init() */
794 QCBOR_DECODE_MODE_NORMAL = 0,
795 /** See QCBORDecode_Init() */
796 QCBOR_DECODE_MODE_MAP_STRINGS_ONLY = 1,
797 /** See QCBORDecode_Init() */
798 QCBOR_DECODE_MODE_MAP_AS_ARRAY = 2
799} QCBORDecodeMode;
800
801
802
803
804
805/* Do not renumber these. Code depends on some of these values. */
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700806/** The data type is unknown, unset or invalid. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800807#define QCBOR_TYPE_NONE 0
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700808/** Type for an integer that decoded either between @c INT64_MIN and
809 @c INT32_MIN or @c INT32_MAX and @c INT64_MAX. Data is in member
810 @c val.int64. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800811#define QCBOR_TYPE_INT64 2
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700812/** Type for an integer that decoded to a more than @c INT64_MAX and
813 @c UINT64_MAX. Data is in member @c val.uint64. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800814#define QCBOR_TYPE_UINT64 3
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700815/** Type for an array. The number of items in the array is in @c
816 val.uCount. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800817#define QCBOR_TYPE_ARRAY 4
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700818/** Type for a map; number of items in map is in @c val.uCount. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800819#define QCBOR_TYPE_MAP 5
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700820/** Type for a buffer full of bytes. Data is in @c val.string. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800821#define QCBOR_TYPE_BYTE_STRING 6
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700822/** Type for a UTF-8 string. It is not NULL-terminated. Data is in @c
823 val.string. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800824#define QCBOR_TYPE_TEXT_STRING 7
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700825/** Type for a positive big number. Data is in @c val.bignum, a
826 pointer and a length. */
827#define QCBOR_TYPE_POSBIGNUM 9
828/** Type for a negative big number. Data is in @c val.bignum, a
829 pointer and a length. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800830#define QCBOR_TYPE_NEGBIGNUM 10
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700831/** Type for [RFC 3339] (https://tools.ietf.org/html/rfc3339) date
832 string, possibly with time zone. Data is in @c val.dateString */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800833#define QCBOR_TYPE_DATE_STRING 11
Laurence Lundbladeac515e52020-01-30 10:44:06 -0800834/** Type for integer seconds since Jan 1970 + floating-point
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700835 fraction. Data is in @c val.epochDate */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800836#define QCBOR_TYPE_DATE_EPOCH 12
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700837/** A simple type that this CBOR implementation doesn't know about;
838 Type is in @c val.uSimple. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800839#define QCBOR_TYPE_UKNOWN_SIMPLE 13
Laurence Lundbladeac515e52020-01-30 10:44:06 -0800840
841/** A decimal fraction made of decimal exponent and integer mantissa.
842 See @ref expAndMantissa and QCBOREncode_AddDecimalFraction(). */
843#define QCBOR_TYPE_DECIMAL_FRACTION 14
844
845/** A decimal fraction made of decimal exponent and positive big
846 number mantissa. See @ref expAndMantissa and
847 QCBOREncode_AddDecimalFractionBigNum(). */
848#define QCBOR_TYPE_DECIMAL_FRACTION_POS_BIGNUM 15
849
850/** A decimal fraction made of decimal exponent and negative big
851 number mantissa. See @ref expAndMantissa and
852 QCBOREncode_AddDecimalFractionBigNum(). */
853#define QCBOR_TYPE_DECIMAL_FRACTION_NEG_BIGNUM 16
854
855/** A floating-point number made of base-2 exponent and integer
856 mantissa. See @ref expAndMantissa and
857 QCBOREncode_AddBigFloat(). */
858#define QCBOR_TYPE_BIGFLOAT 17
859
860/** A floating-point number made of base-2 exponent and positive big
861 number mantissa. See @ref expAndMantissa and
862 QCBOREncode_AddBigFloatBigNum(). */
863#define QCBOR_TYPE_BIGFLOAT_POS_BIGNUM 18
864
865/** A floating-point number made of base-2 exponent and negative big
866 number mantissa. See @ref expAndMantissa and
867 QCBOREncode_AddBigFloatBigNum(). */
868#define QCBOR_TYPE_BIGFLOAT_NEG_BIGNUM 19
869
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700870/** Type for the value false. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800871#define QCBOR_TYPE_FALSE 20
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700872/** Type for the value true. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800873#define QCBOR_TYPE_TRUE 21
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700874/** Type for the value null. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800875#define QCBOR_TYPE_NULL 22
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700876/** Type for the value undef. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800877#define QCBOR_TYPE_UNDEF 23
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700878/** Type for a floating-point number. Data is in @c val.float. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800879#define QCBOR_TYPE_FLOAT 26
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700880/** Type for a double floating-point number. Data is in @c val.double. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800881#define QCBOR_TYPE_DOUBLE 27
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700882/** For @ref QCBOR_DECODE_MODE_MAP_AS_ARRAY decode mode, a map that is
883 being traversed as an array. See QCBORDecode_Init() */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800884#define QCBOR_TYPE_MAP_AS_ARRAY 32
885
886#define QCBOR_TYPE_BREAK 31 // Used internally; never returned
887
888#define QCBOR_TYPE_OPTTAG 254 // Used internally; never returned
889
890
891
892/*
893 Approx Size of this:
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700894 8 + 8 + 1 + 1 + 1 + (1 padding) + (4 padding) = 24 for first part
895 (20 on a 32-bit machine)
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800896 16 bytes for the val union
897 16 bytes for label union
898 total = 56 bytes (52 bytes on 32-bit machine)
899 */
900
901/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700902 The main data structure that holds the type, value and other info for
903 a decoded item returned by QCBORDecode_GetNext() and
904 QCBORDecode_GetNextWithTags().
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800905 */
906typedef struct _QCBORItem {
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700907 /** Tells what element of the @c val union to use. One of @c
908 QCBOR_TYPE_XXXX */
909 uint8_t uDataType;
910 /** How deep the nesting from arrays and maps are. 0 is the top
911 level with no arrays or maps entered. */
912 uint8_t uNestingLevel;
913 /** Tells what element of the label union to use. */
914 uint8_t uLabelType;
915 /** 1 if allocated with string allocator, 0 if not. See
916 QCBORDecode_SetMemPool() or QCBORDecode_SetUpAllocator() */
917 uint8_t uDataAlloc;
918 /** Like @c uDataAlloc, but for label. */
919 uint8_t uLabelAlloc;
920 /** If not equal to @c uNestingLevel, this item closed out at least
921 one map/array */
922 uint8_t uNextNestLevel;
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800923
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700924 /** The union holding the item's value. Select union member based
925 on @c uDataType */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800926 union {
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700927 /** The value for @c uDataType @ref QCBOR_TYPE_INT64. */
928 int64_t int64;
929 /** The value for uDataType @ref QCBOR_TYPE_UINT64. */
930 uint64_t uint64;
931 /** The value for @c uDataType @ref QCBOR_TYPE_BYTE_STRING and
932 @ref QCBOR_TYPE_TEXT_STRING. */
933 UsefulBufC string;
934 /** The "value" for @c uDataType @ref QCBOR_TYPE_ARRAY or @ref
935 QCBOR_TYPE_MAP -- the number of items in the array or map.
936 It is @c UINT16_MAX when decoding indefinite-lengths maps
937 and arrays. */
938 uint16_t uCount;
939 /** The value for @c uDataType @ref QCBOR_TYPE_DOUBLE. */
940 double dfnum;
941 /** The value for @c uDataType @ref QCBOR_TYPE_DATE_EPOCH. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800942 struct {
943 int64_t nSeconds;
944 double fSecondsFraction;
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700945 } epochDate;
946 /** The value for @c uDataType @ref QCBOR_TYPE_DATE_STRING. */
947 UsefulBufC dateString;
948 /** The value for @c uDataType @ref QCBOR_TYPE_POSBIGNUM and
949 @ref QCBOR_TYPE_NEGBIGNUM. */
950 UsefulBufC bigNum;
951 /** The integer value for unknown simple types. */
952 uint8_t uSimple;
Laurence Lundbladeac515e52020-01-30 10:44:06 -0800953#ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
954 /** @anchor expAndMantissa
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800955
Laurence Lundbladeac515e52020-01-30 10:44:06 -0800956 The value for bigfloats and decimal fractions. The use of the
957 fields in this structure depend on @c uDataType.
958
959 When @c uDataType is a @c DECIMAL_FRACTION, the exponent is
960 base-10. When it is a @c BIG_FLOAT it is base-2.
961
962 When @c uDataType is a @c POS_BIGNUM or a @c NEG_BIGNUM then the
963 @c bigNum part of @c Mantissa is valid. Otherwise the
964 @c nInt part of @c Mantissa is valid.
965
966 See @ref QCBOR_TYPE_DECIMAL_FRACTION,
967 @ref QCBOR_TYPE_DECIMAL_FRACTION_POS_BIGNUM,
968 @ref QCBOR_TYPE_DECIMAL_FRACTION_NEG_BIGNUM,
969 @ref QCBOR_TYPE_BIGFLOAT, @ref QCBOR_TYPE_BIGFLOAT_POS_BIGNUM,
970 and @ref QCBOR_TYPE_BIGFLOAT_NEG_BIGNUM.
971
972 Also see QCBOREncode_AddDecimalFraction(), QCBOREncode_AddBigFloat(),
973 QCBOREncode_AddDecimalFractionBigNum() and
974 QCBOREncode_AddBigFloatBigNum().
975 */
976 struct {
977 int64_t nExponent;
978 union {
979 int64_t nInt;
980 UsefulBufC bigNum;
981 } Mantissa;
982 } expAndMantissa;
983#endif
984 uint64_t uTagV; // Used internally during decoding
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700985 } val;
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800986
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700987 /** Union holding the different label types selected based on @c
988 uLabelType */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800989 union {
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700990 /** The label for @c uLabelType @ref QCBOR_TYPE_BYTE_STRING and
991 @ref QCBOR_TYPE_TEXT_STRING */
992 UsefulBufC string;
993 /** The label for @c uLabelType for @ref QCBOR_TYPE_INT64 */
994 int64_t int64;
995 /** The label for @c uLabelType for @ref QCBOR_TYPE_UINT64 */
996 uint64_t uint64;
997 } label;
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800998
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700999 /** Bit indicating which tags (major type 6) on this item. See
1000 QCBORDecode_IsTagged(). */
1001 uint64_t uTagBits;
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001002
1003} QCBORItem;
1004
1005
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001006
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001007/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001008 @brief The type defining what a string allocator function must do.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001009
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001010 @param[in] pAllocateCxt Pointer to context for the particular
1011 allocator implementation What is in the
1012 context is dependent on how a particular
1013 string allocator works. Typically, it
1014 will contain a pointer to the memory pool
1015 and some booking keeping data.
1016 @param[in] pOldMem Points to some memory allocated by the
1017 allocator that is either to be freed or
1018 to be reallocated to be larger. It is
1019 @c NULL for new allocations and when called as
1020 a destructor to clean up the whole
1021 allocation.
1022 @param[in] uNewSize Size of memory to be allocated or new
1023 size of chunk to be reallocated. Zero for
1024 a new allocation or when called as a
1025 destructor.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001026
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001027 @return Either the allocated buffer is returned, or @ref
1028 NULLUsefulBufC. @ref NULLUsefulBufC is returned on a failed
1029 allocation and in the two cases where there is nothing to
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001030 return.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001031
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001032 This is called in one of four modes:
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001033
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001034 Allocate -- @c uNewSize is the amount to allocate. @c pOldMem is @c
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001035 NULL.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001036
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001037 Free -- @c uNewSize is 0. @c pOldMem points to the memory to be
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001038 freed. When the decoder calls this, it will always be the most
1039 recent block that was either allocated or reallocated.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001040
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001041 Reallocate -- @c pOldMem is the block to reallocate. @c uNewSize is
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001042 its new size. When the decoder calls this, it will always be the
1043 most recent block that was either allocated or reallocated.
1044
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001045 Destruct -- @c pOldMem is @c NULL and @c uNewSize is 0. This is called
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001046 when the decoding is complete by QCBORDecode_Finish(). Usually the
1047 strings allocated by a string allocator are in use after the decoding
1048 is completed so this usually will not free those strings. Many string
1049 allocators will not need to do anything in this mode.
1050
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001051 The strings allocated by this will have @c uDataAlloc set to true in
1052 the @ref QCBORItem when they are returned. The user of the strings
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001053 will have to free them. How they free them, depends on the string
1054 allocator.
1055
1056 If QCBORDecode_SetMemPool() is called, the internal MemPool will be
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001057 used. It has its own internal implementation of this function, so
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001058 one does not need to be implemented.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001059 */
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001060typedef UsefulBuf (* QCBORStringAllocate)(void *pAllocateCxt, void *pOldMem, size_t uNewSize);
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001061
1062
1063/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001064 This only matters if you use the built-in string allocator by setting
1065 it up with QCBORDecode_SetMemPool(). This is the size of the overhead
1066 needed by QCBORDecode_SetMemPool(). The amount of memory available
1067 for decoded strings will be the size of the buffer given to
1068 QCBORDecode_SetMemPool() less this amount.
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001069
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001070 If you write your own string allocator or use the separately
1071 available malloc based string allocator, this size will not apply.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001072 */
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001073#define QCBOR_DECODE_MIN_MEM_POOL_SIZE 8
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001074
1075
1076/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001077 This is used by QCBORDecode_SetCallerConfiguredTagList() to set a
1078 list of tags beyond the built-in ones.
1079
1080 See also QCBORDecode_GetNext() for general description of tag
1081 decoding.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001082 */
1083typedef struct {
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001084 /** The number of tags in the @c puTags. The maximum size is @ref
1085 QCBOR_MAX_CUSTOM_TAGS. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001086 uint8_t uNumTags;
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001087 /** An array of tags to add to recognize in addition to the
1088 built-in ones. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001089 const uint64_t *puTags;
1090} QCBORTagListIn;
1091
1092
1093/**
1094 This is for QCBORDecode_GetNextWithTags() to be able to return the
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001095 full list of tags on an item. It is not needed for most CBOR protocol
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001096 implementations. Its primary use is for pretty-printing CBOR or
1097 protocol conversion to another format.
1098
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001099 On input, @c puTags points to a buffer to be filled in and
1100 uNumAllocated is the number of @c uint64_t values in the buffer.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001101
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001102 On output the buffer contains the tags for the item. @c uNumUsed
1103 tells how many there are.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001104 */
1105typedef struct {
1106 uint8_t uNumUsed;
1107 uint8_t uNumAllocated;
1108 uint64_t *puTags;
1109} QCBORTagListOut;
1110
1111
1112/**
1113 QCBOREncodeContext is the data type that holds context for all the
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001114 encoding functions. It is less than 200 bytes, so it can go on the
1115 stack. The contents are opaque, and the caller should not access
1116 internal members. A context may be re used serially as long as it is
1117 re initialized.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001118 */
1119typedef struct _QCBOREncodeContext QCBOREncodeContext;
1120
1121
1122/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001123 Initialize the encoder to prepare to encode some CBOR.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001124
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001125 @param[in,out] pCtx The encoder context to initialize.
1126 @param[in] Storage The buffer into which this encoded result
1127 will be placed.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001128
1129 Call this once at the start of an encoding of a CBOR structure. Then
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001130 call the various @c QCBOREncode_AddXxx() functions to add the data
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001131 items. Then call QCBOREncode_Finish().
1132
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001133 The maximum output buffer is @c UINT32_MAX (4GB). This is not a
1134 practical limit in any way and reduces the memory needed by the
1135 implementation. The error @ref QCBOR_ERR_BUFFER_TOO_LARGE will be
1136 returned by QCBOREncode_Finish() if a larger buffer length is passed
1137 in.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001138
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001139 If this is called with @c Storage.ptr as @c NULL and @c Storage.len a
1140 large value like @c UINT32_MAX, all the QCBOREncode_AddXxx()
1141 functions and QCBOREncode_Finish() can still be called. No data will
1142 be encoded, but the length of what would be encoded will be
1143 calculated. The length of the encoded structure will be handed back
1144 in the call to QCBOREncode_Finish(). You can then allocate a buffer
1145 of that size and call all the encoding again, this time to fill in
1146 the buffer.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001147
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001148 A @ref QCBOREncodeContext can be reused over and over as long as
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001149 QCBOREncode_Init() is called.
1150 */
1151void QCBOREncode_Init(QCBOREncodeContext *pCtx, UsefulBuf Storage);
1152
1153
1154/**
1155 @brief Add a signed 64-bit integer to the encoded output.
1156
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001157 @param[in] pCtx The encoding context to add the integer to.
1158 @param[in] nNum The integer to add.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001159
1160 The integer will be encoded and added to the CBOR output.
1161
1162 This function figures out the size and the sign and encodes in the
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001163 correct minimal CBOR. Specifically, it will select CBOR major type 0
1164 or 1 based on sign and will encode to 1, 2, 4 or 8 bytes depending on
1165 the value of the integer. Values less than 24 effectively encode to
1166 one byte because they are encoded in with the CBOR major type. This
1167 is a neat and efficient characteristic of CBOR that can be taken
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001168 advantage of when designing CBOR-based protocols. If integers like
1169 tags can be kept between -23 and 23 they will be encoded in one byte
1170 including the major type.
1171
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001172 If you pass a smaller int, say an @c int16_t or a small value, say
1173 100, the encoding will still be CBOR's most compact that can
1174 represent the value. For example, CBOR always encodes the value 0 as
1175 one byte, 0x00. The representation as 0x00 includes identification of
1176 the type as an integer too as the major type for an integer is 0. See
1177 [RFC 7049] (https://tools.ietf.org/html/rfc7049) Appendix A for more
1178 examples of CBOR encoding. This compact encoding is also canonical
1179 CBOR as per section 3.9 in RFC 7049.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001180
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001181 There are no functions to add @c int16_t or @c int32_t because they
1182 are not necessary because this always encodes to the smallest number
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001183 of bytes based on the value (If this code is running on a 32-bit
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001184 machine having a way to add 32-bit integers would reduce code size
1185 some).
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001186
1187 If the encoding context is in an error state, this will do
1188 nothing. If an error occurs when adding this integer, the internal
1189 error flag will be set, and the error will be returned when
1190 QCBOREncode_Finish() is called.
1191
1192 See also QCBOREncode_AddUInt64().
1193 */
1194void QCBOREncode_AddInt64(QCBOREncodeContext *pCtx, int64_t nNum);
1195
1196static void QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum);
1197
1198static void QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum);
1199
1200
1201/**
1202 @brief Add an unsigned 64-bit integer to the encoded output.
1203
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001204 @param[in] pCtx The encoding context to add the integer to.
1205 @param[in] uNum The integer to add.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001206
1207 The integer will be encoded and added to the CBOR output.
1208
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001209 The only reason so use this function is for integers larger than @c
1210 INT64_MAX and smaller than @c UINT64_MAX. Otherwise
1211 QCBOREncode_AddInt64() will work fine.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001212
1213 Error handling is the same as for QCBOREncode_AddInt64().
1214 */
1215void QCBOREncode_AddUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
1216
1217static void QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum);
1218
1219static void QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum);
1220
1221
1222/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001223 @brief Add a UTF-8 text string to the encoded output.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001224
Laurence Lundbladeac515e52020-01-30 10:44:06 -08001225 @param[in] pCtx The encoding context to add the text to.
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001226 @param[in] Text Pointer and length of text to add.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001227
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001228 The text passed in must be unencoded UTF-8 according to [RFC 3629]
1229 (https://tools.ietf.org/html/rfc3629). There is no NULL
1230 termination. The text is added as CBOR major type 3.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001231
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001232 If called with @c nBytesLen equal to 0, an empty string will be
1233 added. When @c nBytesLen is 0, @c pBytes may be @c NULL.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001234
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001235 Note that the restriction of the buffer length to a @c uint32_t is
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001236 entirely intentional as this encoder is not capable of encoding
1237 lengths greater. This limit to 4GB for a text string should not be a
1238 problem.
1239
1240 Error handling is the same as QCBOREncode_AddInt64().
1241 */
1242static void QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text);
1243
1244static void QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text);
1245
1246static void QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text);
1247
1248
1249/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001250 @brief Add a UTF-8 text string to the encoded output.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001251
Laurence Lundbladeac515e52020-01-30 10:44:06 -08001252 @param[in] pCtx The encoding context to add the text to.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001253 @param[in] szString Null-terminated text to add.
1254
1255 This works the same as QCBOREncode_AddText().
1256 */
1257static void QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString);
1258
1259static void QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString);
1260
1261static void QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString);
1262
1263
1264/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001265 @brief Add a floating-point number to the encoded output.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001266
Laurence Lundbladeac515e52020-01-30 10:44:06 -08001267 @param[in] pCtx The encoding context to add the double to.
1268 @param[in] dNum The double-precision number to add.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001269
1270 This outputs a floating-point number with CBOR major type 7.
1271
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001272 This will selectively encode the double-precision floating-point
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001273 number as either double-precision, single-precision or
1274 half-precision. It will always encode infinity, NaN and 0 has half
1275 precision. If no precision will be lost in the conversion to
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001276 half-precision, then it will be converted and encoded. If not and no
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001277 precision will be lost in conversion to single-precision, then it
1278 will be converted and encoded. If not, then no conversion is
1279 performed, and it encoded as a double.
1280
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001281 Half-precision floating-point numbers take up 2 bytes, half that of
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001282 single-precision, one quarter of double-precision
1283
1284 This automatically reduces the size of encoded messages a lot, maybe
1285 even by four if most of values are 0, infinity or NaN.
1286
1287 On decode, these will always be returned as a double.
1288
1289 Error handling is the same as QCBOREncode_AddInt64().
1290 */
1291void QCBOREncode_AddDouble(QCBOREncodeContext *pCtx, double dNum);
1292
1293static void QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
1294
1295static void QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
1296
1297
1298/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001299 @brief Add an optional tag.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001300
Laurence Lundbladeac515e52020-01-30 10:44:06 -08001301 @param[in] pCtx The encoding context to add the tag to.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001302 @param[in] uTag The tag to add
1303
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001304 This outputs a CBOR major type 6 item that tags the next data item
1305 that is output usually to indicate it is some new data type.
1306
1307 For many of the common standard tags, a function to encode data using
1308 it is provided and this is not needed. For example,
1309 QCBOREncode_AddDateEpoch() already exists to output integers
1310 representing dates with the right tag.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001311
1312 The tag is applied to the next data item added to the encoded
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001313 output. That data item that is to be tagged can be of any major CBOR
1314 type. Any number of tags can be added to a data item by calling this
1315 multiple times before the data item is added.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001316
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001317 See @ref Tags-Overview for discussion of creating new non-standard
1318 tags. See QCBORDecode_GetNext() for discussion of decoding custom
1319 tags.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001320*/
1321void QCBOREncode_AddTag(QCBOREncodeContext *pCtx,uint64_t uTag);
1322
1323
1324/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001325 @brief Add an epoch-based date.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001326
Laurence Lundbladeac515e52020-01-30 10:44:06 -08001327 @param[in] pCtx The encoding context to add the date to.
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001328 @param[in] date Number of seconds since 1970-01-01T00:00Z in UTC time.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001329
1330 As per RFC 7049 this is similar to UNIX/Linux/POSIX dates. This is
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001331 the most compact way to specify a date and time in CBOR. Note that
1332 this is always UTC and does not include the time zone. Use
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001333 QCBOREncode_AddDateString() if you want to include the time zone.
1334
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001335 The integer encoding rules apply here so the date will be encoded in
1336 a minimal number of bytes. Until about the year 2106 these dates will
1337 encode in 6 bytes -- one byte for the tag, one byte for the type and
1338 4 bytes for the integer. After that it will encode to 10 bytes.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001339
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001340 Negative values are supported for dates before 1970.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001341
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001342 If you care about leap-seconds and that level of accuracy, make sure
1343 the system you are running this code on does it correctly. This code
1344 just takes the value passed in.
1345
1346 This implementation cannot encode fractional seconds using float or
1347 double even though that is allowed by CBOR, but you can encode them
1348 if you want to by calling QCBOREncode_AddDouble() and
1349 QCBOREncode_AddTag().
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001350
1351 Error handling is the same as QCBOREncode_AddInt64().
1352 */
1353static void QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx, int64_t date);
1354
1355static void QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t date);
1356
1357static void QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t date);
1358
1359
1360/**
1361 @brief Add a byte string to the encoded output.
1362
Laurence Lundbladeac515e52020-01-30 10:44:06 -08001363 @param[in] pCtx The encoding context to add the bytes to.
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001364 @param[in] Bytes Pointer and length of the input data.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001365
1366 Simply adds the bytes to the encoded output as CBOR major type 2.
1367
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001368 If called with @c Bytes.len equal to 0, an empty string will be
1369 added. When @c Bytes.len is 0, @c Bytes.ptr may be @c NULL.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001370
1371 Error handling is the same as QCBOREncode_AddInt64().
1372 */
1373static void QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
1374
1375static void QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
1376
1377static void QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
1378
1379
1380
1381/**
1382 @brief Add a binary UUID to the encoded output.
1383
Laurence Lundbladeac515e52020-01-30 10:44:06 -08001384 @param[in] pCtx The encoding context to add the UUID to.
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001385 @param[in] Bytes Pointer and length of the binary UUID.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001386
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001387 A binary UUID as defined in [RFC 4122]
1388 (https://tools.ietf.org/html/rfc4122) is added to the output.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001389
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001390 It is output as CBOR major type 2, a binary string, with tag @ref
1391 CBOR_TAG_BIN_UUID indicating the binary string is a UUID.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001392 */
1393static void QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
1394
1395static void QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
1396
1397static void QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
1398
1399
1400/**
1401 @brief Add a positive big number to the encoded output.
1402
Laurence Lundbladeac515e52020-01-30 10:44:06 -08001403 @param[in] pCtx The encoding context to add the big number to.
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001404 @param[in] Bytes Pointer and length of the big number.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001405
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001406 Big numbers are integers larger than 64-bits. Their format is
1407 described in [RFC 7049] (https://tools.ietf.org/html/rfc7049).
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001408
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001409 It is output as CBOR major type 2, a binary string, with tag @ref
1410 CBOR_TAG_POS_BIGNUM indicating the binary string is a positive big
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001411 number.
1412
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001413 Often big numbers are used to represent cryptographic keys, however,
1414 COSE which defines representations for keys chose not to use this
1415 particular type.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001416 */
1417static void QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
1418
1419static void QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
1420
1421static void QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
1422
1423
1424/**
1425 @brief Add a negative big number to the encoded output.
1426
Laurence Lundbladeac515e52020-01-30 10:44:06 -08001427 @param[in] pCtx The encoding context to add the big number to.
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001428 @param[in] Bytes Pointer and length of the big number.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001429
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001430 Big numbers are integers larger than 64-bits. Their format is
1431 described in [RFC 7049] (https://tools.ietf.org/html/rfc7049).
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001432
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001433 It is output as CBOR major type 2, a binary string, with tag @ref
1434 CBOR_TAG_NEG_BIGNUM indicating the binary string is a negative big
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001435 number.
1436
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001437 Often big numbers are used to represent cryptographic keys, however,
1438 COSE which defines representations for keys chose not to use this
1439 particular type.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001440 */
1441static void QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
1442
1443static void QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
1444
1445static void QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
1446
1447
Laurence Lundbladeac515e52020-01-30 10:44:06 -08001448#ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
1449/**
1450 @brief Add a decimal fraction to the encoded output.
1451
1452 @param[in] pCtx The encoding context to add the decimal fraction to.
1453 @param[in] nMantissa The mantissa.
1454 @param[in] nBase10Exponent The exponent.
1455
1456 The value is nMantissa * 10 ^ nBase10Exponent.
1457
1458 A decimal fraction is good for exact representation of some values
1459 that can't be represented exactly with standard C (IEEE 754)
1460 floating-point numbers. Much larger and much smaller numbers can
1461 also be represented than floating-point because of the larger number
1462 of bits in the exponent.
1463
1464 The decimal fraction is conveyed as two integers, a mantissa and a
1465 base-10 scaling factor.
1466
1467 For example, 273.15 is represented by the two integers 27315 and -2.
1468
1469 The exponent and mantissa have the range from @c INT64_MIN to
1470 @c INT64_MAX for both encoding and decoding (CBOR allows @c -UINT64_MAX
1471 to @c UINT64_MAX, but this implementation doesn't support this range to
1472 reduce code size and interface complexity a little).
1473
1474 CBOR Preferred encoding of the integers is used, thus they will be encoded
1475 in the smallest number of bytes possible.
1476
1477 See also QCBOREncode_AddDecimalFractionBigNum() for a decimal
1478 fraction with arbitrarily large precision and QCBOREncode_AddBigFloat().
1479
1480 There is no representation of positive or negative infinity or NaN
1481 (Not a Number). Use QCBOREncode_AddDouble() to encode them.
1482
1483 See @ref expAndMantissa for decoded representation.
1484 */
1485static void QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pCtx,
1486 int64_t nMantissa,
1487 int64_t nBase10Exponent);
1488
1489static void QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pCtx,
1490 const char *szLabel,
1491 int64_t nMantissa,
1492 int64_t nBase10Exponent);
1493
1494static void QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pCtx,
1495 int64_t nLabel,
1496 int64_t nMantissa,
1497 int64_t nBase10Exponent);
1498
1499/**
1500 @brief Add a decimal fraction with a big number mantissa to the encoded output.
1501
1502 @param[in] pCtx The encoding context to add the decimal fraction to.
1503 @param[in] Mantissa The mantissa.
1504 @param[in] bIsNegative false if mantissa is positive, true if negative.
1505 @param[in] nBase10Exponent The exponent.
1506
1507 This is the same as QCBOREncode_AddDecimalFraction() except the
1508 mantissa is a big number (See QCBOREncode_AddPositiveBignum())
1509 allowing for arbitrarily large precision.
1510
1511 See @ref expAndMantissa for decoded representation.
1512 */
1513static void QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pCtx,
1514 UsefulBufC Mantissa,
1515 bool bIsNegative,
1516 int64_t nBase10Exponent);
1517
1518static void QCBOREncode_AddDecimalFractionBigNumToMap(QCBOREncodeContext *pCtx,
1519 const char *szLabel,
1520 UsefulBufC Mantissa,
1521 bool bIsNegative,
1522 int64_t nBase10Exponent);
1523
1524static void QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
1525 int64_t nLabel,
1526 UsefulBufC Mantissa,
1527 bool bIsNegative,
1528 int64_t nBase10Exponent);
1529
1530/**
1531 @brief Add a big floating-point number to the encoded output.
1532
1533 @param[in] pCtx The encoding context to add the bigfloat to.
1534 @param[in] nMantissa The mantissa.
1535 @param[in] nBase2Exponent The exponent.
1536
1537 The value is nMantissa * 2 ^ nBase2Exponent.
1538
1539 "Bigfloats", as CBOR terms them, are similar to IEEE floating-point
1540 numbers in having a mantissa and base-2 exponent, but they are not
1541 supported by hardware or encoded the same. They explicitly use two
1542 CBOR-encoded integers to convey the mantissa and exponent, each of which
1543 can be 8, 16, 32 or 64 bits. With both the mantissa and exponent
1544 64 bits they can express more precision and a larger range than an
1545 IEEE double floating-point number. See
1546 QCBOREncode_AddBigFloatBigNum() for even more precision.
1547
1548 For example, 1.5 would be represented by a mantissa of 3 and an
1549 exponent of -1.
1550
1551 The exponent and mantissa have the range from @c INT64_MIN to
1552 @c INT64_MAX for both encoding and decoding (CBOR allows @c -UINT64_MAX
1553 to @c UINT64_MAX, but this implementation doesn't support this range to
1554 reduce code size and interface complexity a little).
1555
1556 CBOR Preferred encoding of the integers is used, thus they will be encoded
1557 in the smallest number of bytes possible.
1558
1559 This can also be used to represent floating-point numbers in
1560 environments that don't support IEEE 754.
1561
1562 See @ref expAndMantissa for decoded representation.
1563 */
1564static void QCBOREncode_AddBigFloat(QCBOREncodeContext *pCtx,
1565 int64_t nMantissa,
1566 int64_t nBase2Exponent);
1567
1568static void QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pCtx,
1569 const char *szLabel,
1570 int64_t nMantissa,
1571 int64_t nBase2Exponent);
1572
1573static void QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pCtx,
1574 int64_t nLabel,
1575 int64_t nMantissa,
1576 int64_t nBase2Exponent);
1577
1578
1579/**
1580 @brief Add a big floating-point number with a big number mantissa to
1581 the encoded output.
1582
1583 @param[in] pCtx The encoding context to add the bigfloat to.
1584 @param[in] Mantissa The mantissa.
1585 @param[in] bIsNegative false if mantissa is positive, true if negative.
1586 @param[in] nBase2Exponent The exponent.
1587
1588 This is the same as QCBOREncode_AddBigFloat() except the mantissa is
1589 a big number (See QCBOREncode_AddPositiveBignum()) allowing for
1590 arbitrary precision.
1591
1592 See @ref expAndMantissa for decoded representation.
1593 */
1594static void QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pCtx,
1595 UsefulBufC Mantissa,
1596 bool bIsNegative,
1597 int64_t nBase2Exponent);
1598
1599static void QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pCtx,
1600 const char *szLabel,
1601 UsefulBufC Mantissa,
1602 bool bIsNegative,
1603 int64_t nBase2Exponent);
1604
1605static void QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1606 int64_t nLabel,
1607 UsefulBufC Mantissa,
1608 bool bIsNegative,
1609 int64_t nBase2Exponent);
1610#endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
1611
1612
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001613/**
1614 @brief Add a text URI to the encoded output.
1615
Laurence Lundbladeac515e52020-01-30 10:44:06 -08001616 @param[in] pCtx The encoding context to add the URI to.
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001617 @param[in] URI Pointer and length of the URI.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001618
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001619 The format of URI must be per [RFC 3986]
1620 (https://tools.ietf.org/html/rfc3986).
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001621
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001622 It is output as CBOR major type 3, a text string, with tag @ref
1623 CBOR_TAG_URI indicating the text string is a URI.
1624
1625 A URI in a NULL-terminated string, @c szURI, can be easily added with
1626 this code:
1627
1628 QCBOREncode_AddURI(pCtx, UsefulBuf_FromSZ(szURI));
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001629 */
1630static void QCBOREncode_AddURI(QCBOREncodeContext *pCtx, UsefulBufC URI);
1631
1632static void QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC URI);
1633
1634static void QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC URI);
1635
1636
1637/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001638 @brief Add Base64-encoded text to encoded output.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001639
Laurence Lundbladeac515e52020-01-30 10:44:06 -08001640 @param[in] pCtx The encoding context to add the base-64 text to.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001641 @param[in] B64Text Pointer and length of the base-64 encoded text.
1642
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001643 The text content is Base64 encoded data per [RFC 4648]
1644 (https://tools.ietf.org/html/rfc4648).
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001645
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001646 It is output as CBOR major type 3, a text string, with tag @ref
1647 CBOR_TAG_B64 indicating the text string is Base64 encoded.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001648 */
1649static void QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx, UsefulBufC B64Text);
1650
1651static void QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text);
1652
1653static void QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text);
1654
1655
1656/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001657 @brief Add base64url encoded data to encoded output.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001658
Laurence Lundbladeac515e52020-01-30 10:44:06 -08001659 @param[in] pCtx The encoding context to add the base64url to.
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001660 @param[in] B64Text Pointer and length of the base64url encoded text.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001661
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001662 The text content is base64URL encoded text as per [RFC 4648]
1663 (https://tools.ietf.org/html/rfc4648).
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001664
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001665 It is output as CBOR major type 3, a text string, with tag @ref
1666 CBOR_TAG_B64URL indicating the text string is a Base64url encoded.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001667 */
1668static void QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx, UsefulBufC B64Text);
1669
1670static void QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text);
1671
1672static void QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text);
1673
1674
1675/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001676 @brief Add Perl Compatible Regular Expression.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001677
Laurence Lundbladeac515e52020-01-30 10:44:06 -08001678 @param[in] pCtx The encoding context to add the regular expression to.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001679 @param[in] Regex Pointer and length of the regular expression.
1680
1681 The text content is Perl Compatible Regular
1682 Expressions (PCRE) / JavaScript syntax [ECMA262].
1683
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001684 It is output as CBOR major type 3, a text string, with tag @ref
1685 CBOR_TAG_REGEX indicating the text string is a regular expression.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001686 */
1687static void QCBOREncode_AddRegex(QCBOREncodeContext *pCtx, UsefulBufC Regex);
1688
1689static void QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Regex);
1690
1691static void QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Regex);
1692
1693
1694/**
1695 @brief MIME encoded text to the encoded output.
1696
Laurence Lundbladeac515e52020-01-30 10:44:06 -08001697 @param[in] pCtx The encoding context to add the MIME data to.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001698 @param[in] MIMEData Pointer and length of the regular expression.
1699
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001700 The text content is in MIME format per [RFC 2045]
1701 (https://tools.ietf.org/html/rfc2045) including the headers. Note
1702 that this only supports text-format MIME. Binary MIME is not
1703 supported.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001704
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001705 It is output as CBOR major type 3, a text string, with tag
1706 @ref CBOR_TAG_MIME indicating the text string is MIME data.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001707 */
1708static void QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx, UsefulBufC MIMEData);
1709
1710static void QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC MIMEData);
1711
1712static void QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC MIMEData);
1713
1714
1715/**
1716 @brief Add an RFC 3339 date string
1717
Laurence Lundbladeac515e52020-01-30 10:44:06 -08001718 @param[in] pCtx The encoding context to add the date to.
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001719 @param[in] szDate Null-terminated string with date to add.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001720
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001721 The string szDate should be in the form of [RFC 3339]
1722 (https://tools.ietf.org/html/rfc3339) as defined by section 3.3 in
1723 [RFC 4287] (https://tools.ietf.org/html/rfc4287). This is as
1724 described in section 2.4.1 in [RFC 7049]
1725 (https://tools.ietf.org/html/rfc7049).
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001726
1727 Note that this function doesn't validate the format of the date string
1728 at all. If you add an incorrect format date string, the generated
1729 CBOR will be incorrect and the receiver may not be able to handle it.
1730
1731 Error handling is the same as QCBOREncode_AddInt64().
1732 */
1733static void QCBOREncode_AddDateString(QCBOREncodeContext *pCtx, const char *szDate);
1734
1735static void QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szDate);
1736
1737static void QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szDate);
1738
1739
1740/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001741 @brief Add a standard Boolean.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001742
Laurence Lundbladeac515e52020-01-30 10:44:06 -08001743 @param[in] pCtx The encoding context to add the Boolean to.
1744 @param[in] b true or false from @c <stdbool.h>.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001745
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001746 Adds a Boolean value as CBOR major type 7.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001747
1748 Error handling is the same as QCBOREncode_AddInt64().
1749 */
1750static void QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b);
1751
1752static void QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b);
1753
1754static void QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b);
1755
1756
1757
1758/**
1759 @brief Add a NULL to the encoded output.
1760
Laurence Lundbladeac515e52020-01-30 10:44:06 -08001761 @param[in] pCtx The encoding context to add the NULL to.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001762
1763 Adds the NULL value as CBOR major type 7.
1764
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001765 This NULL doesn't have any special meaning in CBOR such as a
1766 terminating value for a string or an empty value.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001767
1768 Error handling is the same as QCBOREncode_AddInt64().
1769 */
1770static void QCBOREncode_AddNULL(QCBOREncodeContext *pCtx);
1771
1772static void QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1773
1774static void QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1775
1776
1777/**
1778 @brief Add an "undef" to the encoded output.
1779
Laurence Lundbladeac515e52020-01-30 10:44:06 -08001780 @param[in] pCtx The encoding context to add the "undef" to.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001781
1782 Adds the undef value as CBOR major type 7.
1783
1784 Note that this value will not translate to JSON.
1785
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001786 This Undef doesn't have any special meaning in CBOR such as a
1787 terminating value for a string or an empty value.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001788
1789 Error handling is the same as QCBOREncode_AddInt64().
1790 */
1791static void QCBOREncode_AddUndef(QCBOREncodeContext *pCtx);
1792
1793static void QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1794
1795static void QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1796
1797
1798/**
1799 @brief Indicates that the next items added are in an array.
1800
1801 @param[in] pCtx The encoding context to open the array in.
1802
1803 Arrays are the basic CBOR aggregate or structure type. Call this
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001804 function to start or open an array. Then call the various @c
1805 QCBOREncode_AddXxx() functions to add the items that go into the
1806 array. Then call QCBOREncode_CloseArray() when all items have been
1807 added. The data items in the array can be of any type and can be of
1808 mixed types.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001809
1810 Nesting of arrays and maps is allowed and supported just by calling
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001811 QCBOREncode_OpenArray() again before calling
1812 QCBOREncode_CloseArray(). While CBOR has no limit on nesting, this
1813 implementation does in order to keep it smaller and simpler. The
1814 limit is @ref QCBOR_MAX_ARRAY_NESTING. This is the max number of
1815 times this can be called without calling
1816 QCBOREncode_CloseArray(). QCBOREncode_Finish() will return @ref
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001817 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP when it is called as this function
1818 just sets an error state and returns no value when this occurs.
1819
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001820 If you try to add more than @ref QCBOR_MAX_ITEMS_IN_ARRAY items to a
1821 single array or map, @ref QCBOR_ERR_ARRAY_TOO_LONG will be returned
1822 when QCBOREncode_Finish() is called.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001823
1824 An array itself must have a label if it is being added to a map.
1825 Note that array elements do not have labels (but map elements do).
1826
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001827 An array itself may be tagged by calling QCBOREncode_AddTag() before this call.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001828 */
1829static void QCBOREncode_OpenArray(QCBOREncodeContext *pCtx);
1830
1831static void QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1832
1833static void QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1834
1835
1836/**
1837 @brief Close an open array.
1838
Laurence Lundbladeac515e52020-01-30 10:44:06 -08001839 @param[in] pCtx The encoding context to close the array in.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001840
1841 The closes an array opened by QCBOREncode_OpenArray(). It reduces
1842 nesting level by one. All arrays (and maps) must be closed before
1843 calling QCBOREncode_Finish().
1844
1845 When an error occurs as a result of this call, the encoder records
1846 the error and enters the error state. The error will be returned when
1847 QCBOREncode_Finish() is called.
1848
1849 If this has been called more times than QCBOREncode_OpenArray(), then
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001850 @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when QCBOREncode_Finish()
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001851 is called.
1852
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001853 If this is called and it is not an array that is currently open, @ref
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001854 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
1855 is called.
1856 */
1857static void QCBOREncode_CloseArray(QCBOREncodeContext *pCtx);
1858
1859
1860/**
1861 @brief Indicates that the next items added are in a map.
1862
Laurence Lundbladeac515e52020-01-30 10:44:06 -08001863 @param[in] pCtx The encoding context to open the map in.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001864
1865 See QCBOREncode_OpenArray() for more information, particularly error
1866 handling.
1867
1868 CBOR maps are an aggregate type where each item in the map consists
1869 of a label and a value. They are similar to JSON objects.
1870
1871 The value can be any CBOR type including another map.
1872
1873 The label can also be any CBOR type, but in practice they are
1874 typically, integers as this gives the most compact output. They might
1875 also be text strings which gives readability and translation to JSON.
1876
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001877 Every @c QCBOREncode_AddXxx() call has one version that ends with @c
1878 InMap for adding items to maps with string labels and one that ends
1879 with @c InMapN that is for adding with integer labels.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001880
1881 RFC 7049 uses the term "key" instead of "label".
1882
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001883 If you wish to use map labels that are neither integer labels nor
1884 text strings, then just call the QCBOREncode_AddXxx() function
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001885 explicitly to add the label. Then call it again to add the value.
1886
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001887 See the [RFC 7049] (https://tools.ietf.org/html/rfc7049) for a lot
1888 more information on creating maps.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001889 */
1890static void QCBOREncode_OpenMap(QCBOREncodeContext *pCtx);
1891
1892static void QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1893
1894static void QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1895
1896
1897
1898/**
1899 @brief Close an open map.
1900
Laurence Lundbladeac515e52020-01-30 10:44:06 -08001901 @param[in] pCtx The encoding context to close the map in .
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001902
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001903 This closes a map opened by QCBOREncode_OpenMap(). It reduces nesting
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001904 level by one.
1905
1906 When an error occurs as a result of this call, the encoder records
1907 the error and enters the error state. The error will be returned when
1908 QCBOREncode_Finish() is called.
1909
1910 If this has been called more times than QCBOREncode_OpenMap(),
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001911 then @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001912 QCBOREncode_Finish() is called.
1913
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001914 If this is called and it is not a map that is currently open, @ref
1915 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001916 is called.
1917 */
1918static void QCBOREncode_CloseMap(QCBOREncodeContext *pCtx);
1919
1920
1921/**
1922 @brief Indicate start of encoded CBOR to be wrapped in a bstr.
1923
Laurence Lundbladeac515e52020-01-30 10:44:06 -08001924 @param[in] pCtx The encoding context to open the bstr-wrapped CBOR in.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001925
1926 All added encoded items between this call and a call to
1927 QCBOREncode_CloseBstrWrap() will be wrapped in a bstr. They will
1928 appear in the final output as a byte string. That byte string will
1929 contain encoded CBOR.
1930
1931 The typical use case is for encoded CBOR that is to be
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001932 cryptographically hashed, as part of a [RFC 8152, COSE]
1933 (https://tools.ietf.org/html/rfc8152) implementation. This avoids
1934 having to encode the items first in one buffer (e.g., the COSE
1935 payload) and then add that buffer as a bstr to another encoding
1936 (e.g. the COSE to-be-signed bytes, the @c Sig_structure) potentially
1937 saving a lot of memory.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001938
1939 When constructing cryptographically signed CBOR objects, maps or
1940 arrays, they typically are encoded normally and then wrapped as a
1941 byte string. The COSE standard for example does this. The wrapping is
1942 simply treating the encoded CBOR map as a byte string.
1943
1944 The stated purpose of this wrapping is to prevent code relaying the
1945 signed data but not verifying it from tampering with the signed data
1946 thus making the signature unverifiable. It is also quite beneficial
1947 for the signature verification code. Standard CBOR parsers usually do
1948 not give access to partially parsed CBOR as would be need to check
1949 the signature of some CBOR. With this wrapping, standard CBOR parsers
1950 can be used to get to all the data needed for a signature
1951 verification.
1952 */
1953static void QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx);
1954
1955static void QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1956
1957static void QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1958
1959
1960/**
1961 @brief Close a wrapping bstr.
1962
Laurence Lundbladeac515e52020-01-30 10:44:06 -08001963 @param[in] pCtx The encoding context to close of bstr wrapping in.
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001964 @param[out] pWrappedCBOR A @ref UsefulBufC containing wrapped bytes.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001965
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001966 The closes a wrapping bstr opened by QCBOREncode_CloseBstrWrap(). It reduces
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001967 nesting level by one.
1968
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001969 A pointer and length of the enclosed encoded CBOR is returned in @c
1970 *pWrappedCBOR if it is not @c NULL. The main purpose of this is so
1971 this data can be hashed (e.g., with SHA-256) as part of a [RFC 8152,
1972 COSE] (https://tools.ietf.org/html/rfc8152)
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001973 implementation. **WARNING**, this pointer and length should be used
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001974 right away before any other calls to @c QCBOREncode_Xxx() as they
1975 will move data around and the pointer and length will no longer be to
1976 the correct encoded CBOR.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001977
1978 When an error occurs as a result of this call, the encoder records
1979 the error and enters the error state. The error will be returned when
1980 QCBOREncode_Finish() is called.
1981
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001982 If this has been called more times than QCBOREncode_BstrWrap(),
1983 then @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001984 QCBOREncode_Finish() is called.
1985
1986 If this is called and it is not a wrapping bstr that is currently
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001987 open, @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
1988 QCBOREncode_Finish() is called.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001989 */
1990static void QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR);
1991
1992
1993/**
1994 @brief Add some already-encoded CBOR bytes.
1995
Laurence Lundbladeac515e52020-01-30 10:44:06 -08001996 @param[in] pCtx The encoding context to add the already-encode CBOR to.
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001997 @param[in] Encoded The already-encoded CBOR to add to the context.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001998
1999 The encoded CBOR being added must be fully conforming CBOR. It must
2000 be complete with no arrays or maps that are incomplete. While this
2001 encoder doesn't ever produce indefinite lengths, it is OK for the
2002 raw CBOR added here to have indefinite lengths.
2003
2004 The raw CBOR added here is not checked in anyway. If it is not
2005 conforming or has open arrays or such, the final encoded CBOR
2006 will probably be wrong or not what was intended.
2007
2008 If the encoded CBOR being added here contains multiple items, they
2009 must be enclosed in a map or array. At the top level the raw
2010 CBOR must be a single data item.
2011 */
2012static void QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded);
2013
2014static void QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded);
2015
2016static void QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded);
2017
2018
2019/**
2020 @brief Get the encoded result.
2021
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002022 @param[in] pCtx The context to finish encoding with.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002023 @param[out] pEncodedCBOR Pointer and length of encoded CBOR.
2024
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002025 @retval QCBOR_ERR_TOO_MANY_CLOSES Nesting error
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002026
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002027 @retval QCBOR_ERR_CLOSE_MISMATCH Nesting error
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002028
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002029 @retval QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN Nesting error
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002030
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002031 @retval QCBOR_ERR_BUFFER_TOO_LARGE Encoded output buffer size
2032
2033 @retval QCBOR_ERR_BUFFER_TOO_SMALL Encoded output buffer size
2034
2035 @retval QCBOR_ERR_ARRAY_NESTING_TOO_DEEP Implementation limit
2036
2037 @retval QCBOR_ERR_ARRAY_TOO_LONG Implementation limit
2038
2039 If this returns success @ref QCBOR_SUCCESS the encoding was a success
2040 and the return length is correct and complete.
2041
2042 If no buffer was passed to QCBOREncode_Init(), then only the length
2043 was computed. If a buffer was passed, then the encoded CBOR is in the
2044 buffer.
2045
Laurence Lundblade234fe422019-12-02 13:04:34 -08002046 Encoding errors primarily manifest here as most other encoding function
2047 do no return an error. They just set the error state in the encode
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002048 context after which no encoding function does anything.
2049
2050 Three types of errors manifest here. The first type are nesting
2051 errors where the number of @c QCBOREncode_OpenXxx() calls do not
2052 match the number @c QCBOREncode_CloseXxx() calls. The solution is to
2053 fix the calling code.
2054
2055 The second type of error is because the buffer given is either too
2056 small or too large. The remedy is to give a correctly sized buffer.
2057
2058 The third type are due to limits in this implementation. @ref
2059 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP can be worked around by encoding the
2060 CBOR in two (or more) phases and adding the CBOR from the first phase
2061 to the second with @c QCBOREncode_AddEncoded().
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002062
2063 If an error is returned, the buffer may have partially encoded
2064 incorrect CBOR in it and it should not be used. Likewise, the length
2065 may be incorrect and should not be used.
2066
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002067 Note that the error could have occurred in one of the many @c
2068 QCBOREncode_AddXxx() calls long before QCBOREncode_Finish() was
2069 called. This error handling reduces the CBOR implementation size but
2070 makes debugging harder.
2071
2072 This may be called multiple times. It will always return the same. It
2073 can also be interleaved with calls to QCBOREncode_FinishGetSize().
Laurence Lundblade234fe422019-12-02 13:04:34 -08002074
2075 QCBOREncode_GetErrorState() can be called to get the current
2076 error state and abort encoding early as an optimization, but is
2077 is never required.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002078 */
2079QCBORError QCBOREncode_Finish(QCBOREncodeContext *pCtx, UsefulBufC *pEncodedCBOR);
2080
2081
2082/**
2083 @brief Get the encoded CBOR and error status.
2084
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002085 @param[in] pCtx The context to finish encoding with.
2086 @param[out] uEncodedLen The length of the encoded or potentially
2087 encoded CBOR in bytes.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002088
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002089 @return The same errors as QCBOREncode_Finish().
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002090
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002091 This functions the same as QCBOREncode_Finish(), but only returns the
2092 size of the encoded output.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002093 */
2094QCBORError QCBOREncode_FinishGetSize(QCBOREncodeContext *pCtx, size_t *uEncodedLen);
2095
2096
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002097/**
2098 @brief Indicate whether output buffer is NULL or not.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002099
Laurence Lundbladeac515e52020-01-30 10:44:06 -08002100 @param[in] pCtx The encoding context.
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002101
2102 @return 1 if the output buffer is @c NULL.
2103
2104 Sometimes a @c NULL input buffer is given to QCBOREncode_Init() so
2105 that the size of the generated CBOR can be calculated without
2106 allocating a buffer for it. This returns 1 when the output buffer is
2107 NULL and 0 when it is not.
2108*/
2109static int QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx);
2110
2111 /**
2112 @brief Get the encoding error state.
2113
Laurence Lundbladeac515e52020-01-30 10:44:06 -08002114 @param[in] pCtx The encoding context.
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002115
2116 @return One of \ref QCBORError. See return values from
2117 QCBOREncode_Finish()
2118
2119 Normally encoding errors need only be handled at the end of encoding
2120 when QCBOREncode_Finish() is called. This can be called to get the
2121 error result before finish should there be a need to halt encoding
Laurence Lundblade234fe422019-12-02 13:04:34 -08002122 before QCBOREncode_Finish() is called.
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002123*/
2124static QCBORError QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx);
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002125
2126
2127
2128/**
2129 QCBORDecodeContext is the data type that holds context decoding the
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002130 data items for some received CBOR. It is about 100 bytes, so it can
2131 go on the stack. The contents are opaque, and the caller should not
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002132 access any internal items. A context may be re used serially as long
2133 as it is re initialized.
2134 */
2135typedef struct _QCBORDecodeContext QCBORDecodeContext;
2136
2137
2138/**
2139 Initialize the CBOR decoder context.
2140
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002141 @param[in] pCtx The context to initialize.
2142 @param[in] EncodedCBOR The buffer with CBOR encoded bytes to be decoded.
2143 @param[in] nMode See below and @ref QCBORDecodeMode.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002144
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002145 Initialize context for a pre-order traversal of the encoded CBOR
2146 tree.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002147
2148 Most CBOR decoding can be completed by calling this function to start
2149 and QCBORDecode_GetNext() in a loop.
2150
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002151 If indefinite-length strings are to be decoded, then
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002152 QCBORDecode_SetMemPool() or QCBORDecode_SetUpAllocator() must be
2153 called to set up a string allocator.
2154
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002155 If tags other than built-in tags are to be recognized and recorded in
2156 @c uTagBits, then QCBORDecode_SetCallerConfiguredTagList() must be
2157 called. The built-in tags are those for which a macro of the form @c
2158 CBOR_TAG_XXX is defined.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002159
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002160 Three decoding modes are supported. In normal mode, @ref
2161 QCBOR_DECODE_MODE_NORMAL, maps are decoded and strings and integers
2162 are accepted as map labels. If a label is other than these, the error
2163 @ref QCBOR_ERR_MAP_LABEL_TYPE is returned by QCBORDecode_GetNext().
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002164
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002165 In strings-only mode, @ref QCBOR_DECODE_MODE_MAP_STRINGS_ONLY, only
2166 text strings are accepted for map labels. This lines up with CBOR
2167 that converts to JSON. The error @ref QCBOR_ERR_MAP_LABEL_TYPE is
2168 returned by QCBORDecode_GetNext() if anything but a text string label
2169 is encountered.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002170
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002171 In @ref QCBOR_DECODE_MODE_MAP_AS_ARRAY maps are treated as special
2172 arrays. They will be return with special @c uDataType @ref
2173 QCBOR_TYPE_MAP_AS_ARRAY and @c uCount, the number of items, will be
2174 double what it would be for a normal map because the labels are also
2175 counted. This mode is useful for decoding CBOR that has labels that
2176 are not integers or text strings, but the caller must manage much of
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002177 the map decoding.
2178 */
2179void QCBORDecode_Init(QCBORDecodeContext *pCtx, UsefulBufC EncodedCBOR, QCBORDecodeMode nMode);
2180
2181
2182/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002183 @brief Set up the MemPool string allocator for indefinite-length strings.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002184
Laurence Lundbladed425fb32019-02-18 10:56:18 -08002185 @param[in] pCtx The decode context.
2186 @param[in] MemPool The pointer and length of the memory pool.
Laurence Lundbladed425fb32019-02-18 10:56:18 -08002187 @param[in] bAllStrings If true, all strings, even of definite
2188 length, will be allocated with the string
2189 allocator.
2190
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002191 @return Error if the MemPool was less than @ref QCBOR_DECODE_MIN_MEM_POOL_SIZE.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002192
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002193 indefinite-length strings (text and byte) cannot be decoded unless
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002194 there is a string allocator configured. MemPool is a simple built-in
2195 string allocator that allocates bytes from a memory pool handed to it
2196 by calling this function. The memory pool is just a pointer and
2197 length for some block of memory that is to be used for string
2198 allocation. It can come from the stack, heap or other.
2199
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002200 The memory pool must be @ref QCBOR_DECODE_MIN_MEM_POOL_SIZE plus
Laurence Lundbladed425fb32019-02-18 10:56:18 -08002201 space for all the strings allocated. There is no overhead per string
2202 allocated. A conservative way to size this buffer is to make it the
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002203 same size as the CBOR being decoded plus @ref
Laurence Lundbladed425fb32019-02-18 10:56:18 -08002204 QCBOR_DECODE_MIN_MEM_POOL_SIZE.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002205
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002206 This memory pool is used for all indefinite-length strings that are
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002207 text strings or byte strings, including strings used as labels.
2208
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002209 The pointers to strings in @ref QCBORItem will point into the memory
Laurence Lundbladed425fb32019-02-18 10:56:18 -08002210 pool set here. They do not need to be individually freed. Just
2211 discard the buffer when they are no longer needed.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002212
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002213 If @c bAllStrings is set, then the size will be the overhead plus the
2214 space to hold **all** strings, definite and indefinite-length, value
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002215 or label. The advantage of this is that after the decode is complete,
2216 the original memory holding the encoded CBOR does not need to remain
2217 valid.
2218
2219 If this function is never called because there is no need to support
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002220 indefinite-length strings, the internal MemPool implementation should
Laurence Lundbladed425fb32019-02-18 10:56:18 -08002221 be dead-stripped by the loader and not add to code size.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002222 */
2223QCBORError QCBORDecode_SetMemPool(QCBORDecodeContext *pCtx, UsefulBuf MemPool, bool bAllStrings);
2224
2225
2226/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002227 @brief Sets up a custom string allocator for indefinite-length strings
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002228
Laurence Lundbladed425fb32019-02-18 10:56:18 -08002229 @param[in] pCtx The decoder context to set up an
2230 allocator for.
2231 @param[in] pfAllocateFunction Pointer to function that will be
2232 called by QCBOR for allocations and
2233 frees.
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002234 @param[in] pAllocateContext Context passed to @c
Laurence Lundbladed425fb32019-02-18 10:56:18 -08002235 pfAllocateFunction.
2236 @param[in] bAllStrings If true, all strings, even of definite
2237 length, will be allocated with the
2238 string allocator.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002239
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002240 indefinite-length strings (text and byte) cannot be decoded unless
Laurence Lundbladed425fb32019-02-18 10:56:18 -08002241 there a string allocator is configured. QCBORDecode_SetUpAllocator()
2242 allows the caller to configure an external string allocator
2243 implementation if the internal string allocator is not suitable. See
2244 QCBORDecode_SetMemPool() to configure the internal allocator. Note
2245 that the internal allocator is not automatically set up.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002246
Laurence Lundbladed425fb32019-02-18 10:56:18 -08002247 The string allocator configured here can be a custom one designed and
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002248 implemented by the caller. See @ref QCBORStringAllocate for the
Laurence Lundbladed425fb32019-02-18 10:56:18 -08002249 requirements for a string allocator implementation.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002250
Laurence Lundbladed425fb32019-02-18 10:56:18 -08002251 A malloc-based string external allocator can be obtained by calling
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002252 @c QCBORDecode_MakeMallocStringAllocator(). It will return a function
2253 and pointer that can be given here as @c pAllocatorFunction and @c
2254 pAllocatorContext. It uses standard @c malloc() so @c free() must be
2255 called on all strings marked by @c uDataAlloc @c == @c 1 or @c
2256 uLabelAlloc @c == @c 1 in @ref QCBORItem.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002257
Laurence Lundbladed425fb32019-02-18 10:56:18 -08002258 Note that an older version of this function took an allocator
2259 structure, rather than single function and pointer. The older
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002260 version @c QCBORDecode_MakeMallocStringAllocator() also implemented
Laurence Lundbladed425fb32019-02-18 10:56:18 -08002261 the older interface.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002262 */
Laurence Lundbladed425fb32019-02-18 10:56:18 -08002263void QCBORDecode_SetUpAllocator(QCBORDecodeContext *pCtx,
2264 QCBORStringAllocate pfAllocateFunction,
2265 void *pAllocateContext,
2266 bool bAllStrings);
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002267
2268/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002269 @brief Configure list of caller-selected tags to be recognized.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002270
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002271 @param[in] pCtx The decode context.
2272 @param[out] pTagList Structure holding the list of tags to configure.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002273
2274 This is used to tell the decoder about tags beyond those that are
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002275 built-in that should be recognized. The built-in tags are those with
2276 macros of the form @c CBOR_TAG_XXX.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002277
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002278 The list pointed to by @c pTagList must persist during decoding. No
2279 copy of it is made.
2280
2281 The maximum number of tags that can be added is @ref
2282 QCBOR_MAX_CUSTOM_TAGS. If a list larger than this is given, the
2283 error will be returned when QCBORDecode_GetNext() is called, not
2284 here.
2285
2286 See description of @ref QCBORTagListIn.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002287 */
2288void QCBORDecode_SetCallerConfiguredTagList(QCBORDecodeContext *pCtx, const QCBORTagListIn *pTagList);
2289
2290
2291/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002292 @brief Gets the next item (integer, byte string, array...) in
2293 preorder traversal of CBOR tree.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002294
2295 @param[in] pCtx The decoder context.
2296 @param[out] pDecodedItem Holds the CBOR item just decoded.
2297
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002298 @retval QCBOR_ERR_INDEFINITE_STRING_CHUNK Not well-formed, one of the
2299 chunks in indefinite-length
2300 string is wrong type.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002301
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002302 @retval QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN Not well-formed, array or map
2303 not closed.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002304
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002305 @retval QCBOR_ERR_UNSUPPORTED Not well-formed, input contains
2306 unsupported CBOR.
2307
Laurence Lundblade234fe422019-12-02 13:04:34 -08002308 @retval QCBOR_ERR_HIT_END Not well-formed, unexpectedly ran out
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002309 of bytes.
2310
2311 @retval QCBOR_ERR_BAD_TYPE_7 Not well-formed, bad simple type value.
2312
2313 @retval QCBOR_ERR_BAD_BREAK Not well-formed, break occurs where
2314 not allowed.
2315
2316 @retval QCBOR_ERR_EXTRA_BYTES Not well-formed, unprocessed bytes at
2317 the end.
2318
Laurence Lundblade234fe422019-12-02 13:04:34 -08002319 @retval QCBOR_ERR_BAD_INT Not well-formed, length of integer is
2320 bad.
2321
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002322 @retval QCBOR_ERR_BAD_OPT_TAG Invalid CBOR, tag on wrong type.
2323
2324 @retval QCBOR_ERR_ARRAY_TOO_LONG Implementation limit, array or map
2325 too long.
2326
2327 @retval QCBOR_ERR_INT_OVERFLOW Implementation limit, negative
2328 integer too large.
2329
2330 @retval QCBOR_ERR_DATE_OVERFLOW Implementation limit, date larger
2331 than can be handled.
2332
2333 @retval QCBOR_ERR_ARRAY_NESTING_TOO_DEEP Implementation limit, nesting
2334 too deep.
2335
2336 @retval QCBOR_ERR_STRING_ALLOCATE Resource exhaustion, string allocator
2337 failed.
2338
2339 @retval QCBOR_ERR_MAP_LABEL_TYPE Configuration error / Implementation
2340 limit encountered a map label this is
2341 not a string on an integer.
2342
2343 @retval QCBOR_ERR_NO_STRING_ALLOCATOR Configuration error, encountered
2344 indefinite-length string with no
2345 allocator configured.
Laurence Lundblade234fe422019-12-02 13:04:34 -08002346 @retval QCBOR_ERR_NO_MORE_ITEMS No more bytes to decode. The previous
2347 item was successfully decoded. This
2348 is usually how the non-error end of
2349 a CBOR stream / sequence is detected.
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002350
2351 @c pDecodedItem is filled in with the value parsed. Generally, the
2352 following data is returned in the structure:
2353
2354 - @c uDataType which indicates which member of the @c val union the
2355 data is in. This decoder figures out the type based on the CBOR
2356 major type, the CBOR "additionalInfo", the CBOR optional tags and
2357 the value of the integer.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002358
2359 - The value of the item, which might be an integer, a pointer and a
2360 length, the count of items in an array, a floating-point number or
2361 other.
2362
2363 - The nesting level for maps and arrays.
2364
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002365 - The label for an item in a map, which may be a text or byte string
2366 or an integer.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002367
2368 - The CBOR optional tag or tags.
2369
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002370 See documentation on in the data type @ref _QCBORItem for all the
2371 details on what is returned.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002372
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002373 This function handles arrays and maps. When first encountered a @ref
2374 QCBORItem will be returned with major type @ref QCBOR_TYPE_ARRAY or
2375 @ref QCBOR_TYPE_MAP. @c QCBORItem.val.uCount will indicate the number
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002376 of Items in the array or map. Typically, an implementation will call
2377 QCBORDecode_GetNext() in a for loop to fetch them all. When decoding
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002378 indefinite-length maps and arrays, @c QCBORItem.val.uCount is @c
2379 UINT16_MAX and @c uNextNestLevel must be used to know when the end of
2380 a map or array is reached.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002381
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002382 Nesting level 0 is the outside top-most nesting level. For example,
2383 in a CBOR structure with two items, an integer and a byte string
2384 only, both would be at nesting level 0. A CBOR structure with an
2385 array open, an integer and a byte string, would have the integer and
2386 byte string as nesting level 1.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002387
2388 Here is an example of how the nesting level is reported with no arrays
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002389 or maps at all.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002390
2391 @verbatim
2392 CBOR Structure Nesting Level
2393 Integer 0
2394 Byte String 0
2395 @endverbatim
2396
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002397 Here is an example of how the nesting level is reported with a simple
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002398 array and some top-level items.
2399
2400 @verbatim
2401 Integer 0
2402 Array (with 2 items) 0
2403 Byte String 1
2404 Byte string 1
2405 Integer 0
2406 @endverbatim
2407
2408
2409 Here's a more complex example
2410 @verbatim
2411
2412 Map with 2 items 0
2413 Text string 1
2414 Array with 3 integers 1
2415 integer 2
2416 integer 2
2417 integer 2
2418 text string 1
2419 byte string 1
2420 @endverbatim
2421
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002422 In @ref _QCBORItem, @c uNextNestLevel is the nesting level for the
2423 next call to QCBORDecode_GetNext(). It indicates if any maps or
2424 arrays were closed out during the processing of the just-fetched @ref
2425 QCBORItem. This processing includes a look-ahead for any breaks that
2426 close out indefinite-length arrays or maps. This value is needed to
2427 be able to understand the hierarchical structure. If @c
2428 uNextNestLevel is not equal to @c uNestLevel the end of the current
2429 map or array has been encountered. This works the same for both
2430 definite and indefinite-length arrays.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002431
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002432 This decoder support CBOR type 6 tagging. The decoding of particular
2433 given tag value may be supported in one of three different ways.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002434
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002435 First, some common tags are fully and transparently supported by
2436 automatically decoding them and returning them in a @ref QCBORItem.
2437 These tags have a @c QCBOR_TYPE_XXX associated with them and manifest
2438 pretty much the same as a standard CBOR type. @ref
2439 QCBOR_TYPE_DATE_EPOCH and the @c epochDate member of @ref QCBORItem
2440 is an example.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002441
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002442 Second are tags that are automatically recognized, but not decoded.
2443 These are tags that have a @c \#define of the form @c CBOR_TAG_XXX.
2444 These are recorded in the @c uTagBits member of @ref QCBORItem. There
2445 is an internal table that maps each bit to a particular tag value
2446 allowing up to 64 tags on an individual item to be reported (it is
2447 rare to have more than one or two). To find out if a particular tag
2448 value is set call QCBORDecode_IsTagged() on the @ref QCBORItem. See
2449 also QCBORDecode_GetNextWithTags().
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002450
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002451 Third are tags that are not automatically recognized, because they
2452 are proprietary, custom or more recently registered with [IANA]
2453 (https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml). The
2454 internal mapping table has to be configured to recognize these. Call
2455 QCBORDecode_SetCallerConfiguredTagList() to do that. Then
2456 QCBORDecode_IsTagged() will work with them.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002457
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002458 The actual decoding of tags supported in the second and third way
2459 must be handled by the caller. Often this is simply verifying that
2460 the expected tag is present on a map, byte string or such. In other
2461 cases, there might a complicated map structure to decode.
2462
2463 See @ref Tags-Overview for a description of how to go about creating
2464 custom tags.
2465
2466 This tag decoding design is to be open-ended and flexible to be able
2467 to handle newly defined tags, while using very little memory, in
2468 particular keeping @ref QCBORItem as small as possible.
2469
Laurence Lundblade234fe422019-12-02 13:04:34 -08002470 If any error occurs, \c uDataType and \c uLabelType will be set
2471 to \ref QCBOR_TYPE_NONE. If there is no need to know the specific
2472 error, \ref QCBOR_TYPE_NONE can be checked for and the return value
2473 ignored.
2474
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002475 Errors fall in several categories as noted in list above:
2476
2477 - Not well-formed errors are those where there is something
2478 syntactically and fundamentally wrong with the CBOR being
2479 decoded. Encoding should stop completely.
2480
2481 - Invalid CBOR is well-formed, but still not correct. It is probably
2482 best to stop decoding, but not necessary.
2483
2484 - This implementation has some size limits. They should rarely be
2485 encountered. If they are it may because something is wrong with the
2486 CBOR, for example an array size is incorrect.
2487
2488 - Resource exhaustion. This only occurs when a string allocator is
2489 configured to handle indefinite-length strings as other than that,
2490 this implementation does no dynamic memory allocation.
2491
2492 - There are a few CBOR constructs that are not handled without some
2493 extra configuration. These are indefinite length strings and maps
2494 with labels that are not strings or integers. See QCBORDecode_Init().
2495
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002496 */
2497QCBORError QCBORDecode_GetNext(QCBORDecodeContext *pCtx, QCBORItem *pDecodedItem);
2498
2499
2500/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002501 @brief Gets the next item including full list of tags for item.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002502
2503 @param[in] pCtx The decoder context.
2504 @param[out] pDecodedItem Holds the CBOR item just decoded.
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002505 @param[in,out] pTagList On input array to put tags in; on output
2506 the tags on this item. See
2507 @ref QCBORTagListOut.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002508
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002509 @return See return values for QCBORDecode_GetNext().
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002510
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002511 @retval QCBOR_ERR_TOO_MANY_TAGS The size of @c pTagList is too small.
2512
2513 This works the same as QCBORDecode_GetNext() except that it also
2514 returns the full list of tags for the data item. This function should
2515 only be needed when parsing CBOR to print it out or convert it to
2516 some other format. It should not be needed to implement a CBOR-based
2517 protocol. See QCBORDecode_GetNext() for the main description of tag
2518 decoding.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002519
2520 Tags will be returned here whether or not they are in the built-in or
2521 caller-configured tag lists.
2522
2523 CBOR has no upper bound of limit on the number of tags that can be
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002524 associated with a data item though in practice the number of tags on
2525 an item will usually be small, perhaps less than five. This will
2526 return @ref QCBOR_ERR_TOO_MANY_TAGS if the array in @c pTagList is
2527 too small to hold all the tags for the item.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002528
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002529 (This function is separate from QCBORDecode_GetNext() so as to not
2530 have to make @ref QCBORItem large enough to be able to hold a full
2531 list of tags. Even a list of five tags would nearly double its size
2532 because tags can be a @c uint64_t ).
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002533 */
2534QCBORError QCBORDecode_GetNextWithTags(QCBORDecodeContext *pCtx, QCBORItem *pDecodedItem, QCBORTagListOut *pTagList);
2535
2536
2537/**
2538 @brief Determine if a CBOR item was tagged with a particular tag
2539
2540 @param[in] pCtx The decoder context.
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002541 @param[in] pItem The CBOR item to check.
2542 @param[in] uTag The tag to check, one of @c CBOR_TAG_XXX.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002543
2544 @return 1 if it was tagged, 0 if not
2545
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002546 See QCBORDecode_GetNext() for the main description of tag
2547 handling. For tags that are not fully decoded a bit corresponding to
2548 the tag is set in in @c uTagBits in the @ref QCBORItem. The
2549 particular bit depends on an internal mapping table. This function
2550 checks for set bits against the mapping table.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002551
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002552 Typically, a protocol implementation just wants to know if a
2553 particular tag is present. That is what this provides. To get the
2554 full list of tags on a data item, see QCBORDecode_GetNextWithTags().
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002555
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002556 Also see QCBORDecode_SetCallerConfiguredTagList() for the means to
2557 add new tags to the internal list so they can be checked for with
2558 this function.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002559 */
2560int QCBORDecode_IsTagged(QCBORDecodeContext *pCtx, const QCBORItem *pItem, uint64_t uTag);
2561
2562
2563/**
2564 Check whether all the bytes have been decoded and maps and arrays closed.
2565
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002566 @param[in] pCtx The context to check.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002567
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002568 @return An error or @ref QCBOR_SUCCESS.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002569
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002570 This tells you if all the bytes given to QCBORDecode_Init() have been
2571 consumed and whether all maps and arrays were closed. The decode is
2572 considered to be incorrect or incomplete if not and an error will be
2573 returned.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002574 */
2575QCBORError QCBORDecode_Finish(QCBORDecodeContext *pCtx);
2576
2577
2578
2579
2580/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002581 @brief Convert int64_t to smaller integers safely.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002582
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002583 @param [in] src An @c int64_t.
2584 @param [out] dest A smaller sized integer to convert to.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002585
2586 @return 0 on success -1 if not
2587
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002588 When decoding an integer, the CBOR decoder will return the value as
2589 an int64_t unless the integer is in the range of @c INT64_MAX and @c
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002590 UINT64_MAX. That is, unless the value is so large that it can only be
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002591 represented as a @c uint64_t, it will be an @c int64_t.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002592
2593 CBOR itself doesn't size the individual integers it carries at
2594 all. The only limits it puts on the major integer types is that they
2595 are 8 bytes or less in length. Then encoders like this one use the
2596 smallest number of 1, 2, 4 or 8 bytes to represent the integer based
2597 on its value. There is thus no notion that one data item in CBOR is
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002598 a 1-byte integer and another is a 4-byte integer.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002599
2600 The interface to this CBOR encoder only uses 64-bit integers. Some
2601 CBOR protocols or implementations of CBOR protocols may not want to
2602 work with something smaller than a 64-bit integer. Perhaps an array
2603 of 1000 integers needs to be sent and none has a value larger than
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002604 50,000 and are represented as @c uint16_t.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002605
2606 The sending / encoding side is easy. Integers are temporarily widened
2607 to 64-bits as a parameter passing through QCBOREncode_AddInt64() and
2608 encoded in the smallest way possible for their value, possibly in
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002609 less than an @c uint16_t.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002610
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002611 On the decoding side the integers will be returned at @c int64_t even if
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002612 they are small and were represented by only 1 or 2 bytes in the
2613 encoded CBOR. The functions here will convert integers to a small
2614 representation with an overflow check.
2615
2616 (The decoder could have support 8 different integer types and
2617 represented the integer with the smallest type automatically, but
2618 this would have made the decoder more complex and code calling the
2619 decoder more complex in most use cases. In most use cases on 64-bit
2620 machines it is no burden to carry around even small integers as
2621 64-bit values).
2622 */
2623static inline int QCBOR_Int64ToInt32(int64_t src, int32_t *dest)
2624{
2625 if(src > INT32_MAX || src < INT32_MIN) {
2626 return -1;
2627 } else {
2628 *dest = (int32_t) src;
2629 }
2630 return 0;
2631}
2632
2633static inline int QCBOR_Int64ToInt16(int64_t src, int16_t *dest)
2634{
2635 if(src > INT16_MAX || src < INT16_MIN) {
2636 return -1;
2637 } else {
2638 *dest = (int16_t) src;
2639 }
2640 return 0;
2641}
2642
2643static inline int QCBOR_Int64ToInt8(int64_t src, int8_t *dest)
2644{
2645 if(src > INT8_MAX || src < INT8_MIN) {
2646 return -1;
2647 } else {
2648 *dest = (int8_t) src;
2649 }
2650 return 0;
2651}
2652
2653static inline int QCBOR_Int64ToUInt32(int64_t src, uint32_t *dest)
2654{
2655 if(src > UINT32_MAX || src < 0) {
2656 return -1;
2657 } else {
2658 *dest = (uint32_t) src;
2659 }
2660 return 0;
2661}
2662
2663static inline int QCBOR_Int64UToInt16(int64_t src, uint16_t *dest)
2664{
2665 if(src > UINT16_MAX || src < 0) {
2666 return -1;
2667 } else {
2668 *dest = (uint16_t) src;
2669 }
2670 return 0;
2671}
2672
2673static inline int QCBOR_Int64ToUInt8(int64_t src, uint8_t *dest)
2674{
2675 if(src > UINT8_MAX || src < 0) {
2676 return -1;
2677 } else {
2678 *dest = (uint8_t) src;
2679 }
2680 return 0;
2681}
2682
2683static inline int QCBOR_Int64ToUInt64(int64_t src, uint64_t *dest)
2684{
2685 if(src > 0) {
2686 return -1;
2687 } else {
2688 *dest = (uint64_t) src;
2689 }
2690 return 0;
2691}
2692
2693
2694
2695
2696
2697/* ===========================================================================
2698 BEGINNING OF PRIVATE INLINE IMPLEMENTATION
2699
2700 =========================================================================== */
2701
2702/**
2703 @brief Semi-private method to add a buffer full of bytes to encoded output
2704
2705 @param[in] pCtx The encoding context to add the integer to.
2706 @param[in] uMajorType The CBOR major type of the bytes.
2707 @param[in] Bytes The bytes to add.
2708
2709 Use QCBOREncode_AddText() or QCBOREncode_AddBytes() or
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002710 QCBOREncode_AddEncoded() instead. They are inline functions that call
2711 this and supply the correct major type. This function is public to
2712 make the inline functions work to keep the overall code size down and
2713 because the C language has no way to make it private.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002714
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002715 If this is called the major type should be @c
2716 CBOR_MAJOR_TYPE_TEXT_STRING, @c CBOR_MAJOR_TYPE_BYTE_STRING or @c
2717 CBOR_MAJOR_NONE_TYPE_RAW. The last one is special for adding
2718 already-encoded CBOR.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002719 */
2720void QCBOREncode_AddBuffer(QCBOREncodeContext *pCtx, uint8_t uMajorType, UsefulBufC Bytes);
2721
2722
2723/**
Laurence Lundbladeac515e52020-01-30 10:44:06 -08002724 @brief Semi-private method to open a map, array or bstr-wrapped CBOR
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002725
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002726 @param[in] pCtx The context to add to.
2727 @param[in] uMajorType The major CBOR type to close
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002728
2729 Call QCBOREncode_OpenArray(), QCBOREncode_OpenMap() or
2730 QCBOREncode_BstrWrap() instead of this.
2731 */
2732void QCBOREncode_OpenMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType);
2733
2734
2735/**
Laurence Lundbladeac515e52020-01-30 10:44:06 -08002736 @brief Semi-private method to open a map, array with indefinite length
Laurence Lundblade234fe422019-12-02 13:04:34 -08002737
2738 @param[in] pCtx The context to add to.
2739 @param[in] uMajorType The major CBOR type to close
2740
Laurence Lundbladeac515e52020-01-30 10:44:06 -08002741 Call QCBOREncode_OpenArrayIndefiniteLength() or
2742 QCBOREncode_OpenMapIndefiniteLength() instead of this.
Laurence Lundblade234fe422019-12-02 13:04:34 -08002743 */
2744void QCBOREncode_OpenMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx, uint8_t uMajorType);
2745
2746
2747/**
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002748 @brief Semi-private method to close a map, array or bstr wrapped CBOR
2749
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002750 @param[in] pCtx The context to add to.
2751 @param[in] uMajorType The major CBOR type to close.
2752 @param[out] pWrappedCBOR Pointer to @ref UsefulBufC containing wrapped bytes.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002753
2754 Call QCBOREncode_CloseArray(), QCBOREncode_CloseMap() or
2755 QCBOREncode_CloseBstrWrap() instead of this.
2756 */
Laurence Lundbladeac515e52020-01-30 10:44:06 -08002757void QCBOREncode_CloseMapOrArray(QCBOREncodeContext *pCtx,
2758 uint8_t uMajorType,
2759 UsefulBufC *pWrappedCBOR);
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002760
Laurence Lundblade234fe422019-12-02 13:04:34 -08002761/**
Laurence Lundbladeac515e52020-01-30 10:44:06 -08002762 @brief Semi-private method to close a map, array with indefinite length
Laurence Lundblade234fe422019-12-02 13:04:34 -08002763
2764 @param[in] pCtx The context to add to.
2765 @param[in] uMajorType The major CBOR type to close.
2766 @param[out] pWrappedCBOR Pointer to @ref UsefulBufC containing wrapped bytes.
2767
Laurence Lundbladeac515e52020-01-30 10:44:06 -08002768 Call QCBOREncode_CloseArrayIndefiniteLength() or
2769 QCBOREncode_CloseMapIndefiniteLength() instead of this.
Laurence Lundblade234fe422019-12-02 13:04:34 -08002770 */
Laurence Lundbladeac515e52020-01-30 10:44:06 -08002771void QCBOREncode_CloseMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx,
2772 uint8_t uMajorType,
2773 UsefulBufC *pWrappedCBOR);
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002774
2775/**
2776 @brief Semi-private method to add simple types.
2777
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002778 @param[in] pCtx The encoding context to add the simple value to.
2779 @param[in] uSize Minimum encoding size for uNum. Usually 0.
2780 @param[in] uNum One of CBOR_SIMPLEV_FALSE through _UNDEF or other.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002781
2782 This is used to add simple types like true and false.
2783
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002784 Call QCBOREncode_AddBool(), QCBOREncode_AddNULL(),
2785 QCBOREncode_AddUndef() instead of this.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002786
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002787 This function can add simple values that are not defined by CBOR
2788 yet. This expansion point in CBOR should not be used unless they are
2789 standardized.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002790
2791 Error handling is the same as QCBOREncode_AddInt64().
2792 */
2793void QCBOREncode_AddType7(QCBOREncodeContext *pCtx, size_t uSize, uint64_t uNum);
2794
2795
Laurence Lundbladec93b5a72019-04-06 12:17:16 -07002796/**
Laurence Lundbladeac515e52020-01-30 10:44:06 -08002797 @brief Semi-private method to add bigfloats and decimal fractions.
2798
2799 @param[in] pCtx The encoding context to add the value to.
2800 @param[in] uTag The type 6 tag indicating what this is to be
2801 @param[in] BigNumMantissa Is @ref NULLUsefulBufC if mantissa is an
2802 @c int64_t or the actual big number mantissa
2803 if not.
2804 @param[in] nMantissa The @c int64_t mantissa if it is not a big number.
2805 @param[in] nExponent The exponent.
2806
2807 This adds a tagged array with two members, the mantissa and exponent. The
2808 mantissa can be either a big number or an @c int64_t.
2809
2810 Typically, QCBOREncode_AddDecimalFraction(), QCBOREncode_AddBigFloat(),
2811 QCBOREncode_AddDecimalFractionBigNum() or QCBOREncode_AddBigFloatBigNum()
2812 is called instead of this.
2813 */
2814void QCBOREncode_AddExponentAndMantissa(QCBOREncodeContext *pCtx,
2815 uint64_t uTag,
2816 UsefulBufC BigNumMantissa,
2817 bool bBigNumIsNegative,
2818 int64_t nMantissa,
2819 int64_t nExponent);
2820
2821/**
Laurence Lundbladec93b5a72019-04-06 12:17:16 -07002822 @brief Semi-private method to add only the type and length of a byte string.
2823
2824 @param[in] pCtx The context to initialize.
2825 @param[in] Bytes Pointer and length of the input data.
2826
2827 This is the same as QCBOREncode_AddBytes() except it only adds the
2828 CBOR encoding for the type and the length. It doesn't actually add
2829 the bytes. You can't actually produce correct CBOR with this and the
2830 rest of this API. It is only used for a special case where
2831 the valid CBOR is created manually by putting this type and length in
2832 and then adding the actual bytes. In particular, when only a hash of
2833 the encoded CBOR is needed, where the type and header are hashed
2834 separately and then the bytes is hashed. This makes it possible to
2835 implement COSE Sign1 with only one copy of the payload in the output
2836 buffer, rather than two, roughly cutting memory use in half.
2837
2838 This is only used for this odd case, but this is a supported
2839 tested function.
2840*/
2841static inline void QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
2842
2843static inline void QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
2844
2845static inline void QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
2846
2847
2848
2849
Laurence Lundbladeac515e52020-01-30 10:44:06 -08002850
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002851static inline void QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum)
2852{
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002853 // Use _AddBuffer() because _AddSZString() is defined below, not above
2854 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002855 QCBOREncode_AddInt64(pCtx, uNum);
2856}
2857
2858static inline void QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum)
2859{
2860 QCBOREncode_AddInt64(pCtx, nLabel);
2861 QCBOREncode_AddInt64(pCtx, uNum);
2862}
2863
2864
2865static inline void QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum)
2866{
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002867 // Use _AddBuffer() because _AddSZString() is defined below, not above
2868 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002869 QCBOREncode_AddUInt64(pCtx, uNum);
2870}
2871
2872static inline void QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum)
2873{
2874 QCBOREncode_AddInt64(pCtx, nLabel);
2875 QCBOREncode_AddUInt64(pCtx, uNum);
2876}
2877
2878
2879static inline void QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text)
2880{
2881 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, Text);
2882}
2883
2884static inline void QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text)
2885{
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002886 // Use _AddBuffer() because _AddSZString() is defined below, not above
2887 QCBOREncode_AddText(pCtx, UsefulBuf_FromSZ(szLabel));
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002888 QCBOREncode_AddText(pCtx, Text);
2889}
2890
2891static inline void QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text)
2892{
2893 QCBOREncode_AddInt64(pCtx, nLabel);
2894 QCBOREncode_AddText(pCtx, Text);
2895}
2896
2897
2898inline static void QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString)
2899{
2900 QCBOREncode_AddText(pCtx, UsefulBuf_FromSZ(szString));
2901}
2902
2903static inline void QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString)
2904{
2905 QCBOREncode_AddSZString(pCtx, szLabel);
2906 QCBOREncode_AddSZString(pCtx, szString);
2907}
2908
2909static inline void QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString)
2910{
2911 QCBOREncode_AddInt64(pCtx, nLabel);
2912 QCBOREncode_AddSZString(pCtx, szString);
2913}
2914
2915
2916static inline void QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum)
2917{
2918 QCBOREncode_AddSZString(pCtx, szLabel);
2919 QCBOREncode_AddDouble(pCtx, dNum);
2920}
2921
2922static inline void QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum)
2923{
2924 QCBOREncode_AddInt64(pCtx, nLabel);
2925 QCBOREncode_AddDouble(pCtx, dNum);
2926}
2927
2928
2929static inline void QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx, int64_t date)
2930{
2931 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_EPOCH);
2932 QCBOREncode_AddInt64(pCtx, date);
2933}
2934
2935static inline void QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t date)
2936{
2937 QCBOREncode_AddSZString(pCtx, szLabel);
2938 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_EPOCH);
2939 QCBOREncode_AddInt64(pCtx, date);
2940}
2941
2942static inline void QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t date)
2943{
2944 QCBOREncode_AddInt64(pCtx, nLabel);
2945 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_EPOCH);
2946 QCBOREncode_AddInt64(pCtx, date);
2947}
2948
2949
2950static inline void QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
2951{
2952 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes);
2953}
2954
2955static inline void QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
2956{
2957 QCBOREncode_AddSZString(pCtx, szLabel);
2958 QCBOREncode_AddBytes(pCtx, Bytes);
2959}
2960
2961static inline void QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
2962{
2963 QCBOREncode_AddInt64(pCtx, nLabel);
2964 QCBOREncode_AddBytes(pCtx, Bytes);
2965}
2966
Laurence Lundbladec93b5a72019-04-06 12:17:16 -07002967static inline void QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
2968{
2969 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY, Bytes);
2970}
2971
2972static inline void QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
2973{
2974 QCBOREncode_AddSZString(pCtx, szLabel);
2975 QCBOREncode_AddBytesLenOnly(pCtx, Bytes);
2976}
2977
2978static inline void QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
2979{
2980 QCBOREncode_AddInt64(pCtx, nLabel);
2981 QCBOREncode_AddBytesLenOnly(pCtx, Bytes);
2982}
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002983
2984static inline void QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
2985{
2986 QCBOREncode_AddTag(pCtx, CBOR_TAG_BIN_UUID);
2987 QCBOREncode_AddBytes(pCtx, Bytes);
2988}
2989
2990static inline void QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
2991{
2992 QCBOREncode_AddSZString(pCtx, szLabel);
2993 QCBOREncode_AddTag(pCtx, CBOR_TAG_BIN_UUID);
2994 QCBOREncode_AddBytes(pCtx, Bytes);
2995}
2996
2997static inline void QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
2998{
2999 QCBOREncode_AddInt64(pCtx, nLabel);
3000 QCBOREncode_AddTag(pCtx, CBOR_TAG_BIN_UUID);
3001 QCBOREncode_AddBytes(pCtx, Bytes);
3002}
3003
3004
3005static inline void QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
3006{
3007 QCBOREncode_AddTag(pCtx, CBOR_TAG_POS_BIGNUM);
3008 QCBOREncode_AddBytes(pCtx, Bytes);
3009}
3010
3011static inline void QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
3012{
3013 QCBOREncode_AddSZString(pCtx, szLabel);
3014 QCBOREncode_AddTag(pCtx, CBOR_TAG_POS_BIGNUM);
3015 QCBOREncode_AddBytes(pCtx, Bytes);
3016}
3017
3018static inline void QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
3019{
3020 QCBOREncode_AddInt64(pCtx, nLabel);
3021 QCBOREncode_AddTag(pCtx, CBOR_TAG_POS_BIGNUM);
3022 QCBOREncode_AddBytes(pCtx, Bytes);
3023}
3024
3025
3026static inline void QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
3027{
3028 QCBOREncode_AddTag(pCtx, CBOR_TAG_NEG_BIGNUM);
3029 QCBOREncode_AddBytes(pCtx, Bytes);
3030}
3031
3032static inline void QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
3033{
3034 QCBOREncode_AddSZString(pCtx, szLabel);
3035 QCBOREncode_AddTag(pCtx, CBOR_TAG_NEG_BIGNUM);
3036 QCBOREncode_AddBytes(pCtx, Bytes);
3037}
3038
3039static inline void QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
3040{
3041 QCBOREncode_AddInt64(pCtx, nLabel);
3042 QCBOREncode_AddTag(pCtx, CBOR_TAG_NEG_BIGNUM);
3043 QCBOREncode_AddBytes(pCtx, Bytes);
3044}
3045
3046
Laurence Lundbladeac515e52020-01-30 10:44:06 -08003047#ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
3048
3049static inline void QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pCtx,
3050 int64_t nMantissa,
3051 int64_t nBase10Exponent)
3052{
3053 QCBOREncode_AddExponentAndMantissa(pCtx,
3054 CBOR_TAG_DECIMAL_FRACTION,
3055 NULLUsefulBufC,
3056 false,
3057 nMantissa,
3058 nBase10Exponent);
3059}
3060
3061static inline void QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pCtx,
3062 const char *szLabel,
3063 int64_t nMantissa,
3064 int64_t nBase10Exponent)
3065{
3066 QCBOREncode_AddSZString(pCtx, szLabel);
3067 QCBOREncode_AddDecimalFraction(pCtx, nMantissa, nBase10Exponent);
3068}
3069
3070static inline void QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pCtx,
3071 int64_t nLabel,
3072 int64_t nMantissa,
3073 int64_t nBase10Exponent)
3074{
3075 QCBOREncode_AddInt64(pCtx, nLabel);
3076 QCBOREncode_AddDecimalFraction(pCtx, nMantissa, nBase10Exponent);
3077}
3078
3079static inline void QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pCtx,
3080 UsefulBufC Mantissa,
3081 bool bIsNegative,
3082 int64_t nBase10Exponent)
3083{
3084 QCBOREncode_AddExponentAndMantissa(pCtx,
3085 CBOR_TAG_DECIMAL_FRACTION,
3086 Mantissa, bIsNegative,
3087 0,
3088 nBase10Exponent);
3089}
3090
3091static inline void QCBOREncode_AddDecimalFractionBigNumToMap(QCBOREncodeContext *pCtx,
3092 const char *szLabel,
3093 UsefulBufC Mantissa,
3094 bool bIsNegative,
3095 int64_t nBase10Exponent)
3096{
3097 QCBOREncode_AddSZString(pCtx, szLabel);
3098 QCBOREncode_AddDecimalFractionBigNum(pCtx, Mantissa, bIsNegative, nBase10Exponent);
3099}
3100
3101static inline void QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
3102 int64_t nLabel,
3103 UsefulBufC Mantissa,
3104 bool bIsNegative,
3105 int64_t nBase2Exponent)
3106{
3107 QCBOREncode_AddInt64(pCtx, nLabel);
3108 QCBOREncode_AddDecimalFractionBigNum(pCtx, Mantissa, bIsNegative, nBase2Exponent);
3109}
3110
3111static inline void QCBOREncode_AddBigFloat(QCBOREncodeContext *pCtx,
3112 int64_t nMantissa,
3113 int64_t nBase2Exponent)
3114{
3115 QCBOREncode_AddExponentAndMantissa(pCtx, CBOR_TAG_BIGFLOAT, NULLUsefulBufC, false, nMantissa, nBase2Exponent);
3116}
3117
3118static inline void QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pCtx,
3119 const char *szLabel,
3120 int64_t nMantissa,
3121 int64_t nBase2Exponent)
3122{
3123 QCBOREncode_AddSZString(pCtx, szLabel);
3124 QCBOREncode_AddBigFloat(pCtx, nMantissa, nBase2Exponent);
3125}
3126
3127static inline void QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pCtx,
3128 int64_t nLabel,
3129 int64_t nMantissa,
3130 int64_t nBase2Exponent)
3131{
3132 QCBOREncode_AddInt64(pCtx, nLabel);
3133 QCBOREncode_AddBigFloat(pCtx, nMantissa, nBase2Exponent);
3134}
3135
3136static inline void QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pCtx,
3137 UsefulBufC Mantissa,
3138 bool bIsNegative,
3139 int64_t nBase2Exponent)
3140{
3141 QCBOREncode_AddExponentAndMantissa(pCtx, CBOR_TAG_BIGFLOAT, Mantissa, bIsNegative, 0, nBase2Exponent);
3142}
3143
3144static inline void QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pCtx,
3145 const char *szLabel,
3146 UsefulBufC Mantissa,
3147 bool bIsNegative,
3148 int64_t nBase2Exponent)
3149{
3150 QCBOREncode_AddSZString(pCtx, szLabel);
3151 QCBOREncode_AddBigFloatBigNum(pCtx, Mantissa, bIsNegative, nBase2Exponent);
3152}
3153
3154static inline void QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
3155 int64_t nLabel,
3156 UsefulBufC Mantissa,
3157 bool bIsNegative,
3158 int64_t nBase2Exponent)
3159{
3160 QCBOREncode_AddInt64(pCtx, nLabel);
3161 QCBOREncode_AddBigFloatBigNum(pCtx, Mantissa, bIsNegative, nBase2Exponent);
3162}
3163#endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
3164
3165
Laurence Lundblade6ed34222018-12-18 09:46:23 -08003166static inline void QCBOREncode_AddURI(QCBOREncodeContext *pCtx, UsefulBufC URI)
3167{
3168 QCBOREncode_AddTag(pCtx, CBOR_TAG_URI);
3169 QCBOREncode_AddText(pCtx, URI);
3170}
3171
3172static inline void QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC URI)
3173{
3174 QCBOREncode_AddSZString(pCtx, szLabel);
3175 QCBOREncode_AddTag(pCtx, CBOR_TAG_URI);
3176 QCBOREncode_AddText(pCtx, URI);
3177}
3178
3179static inline void QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC URI)
3180{
3181 QCBOREncode_AddInt64(pCtx, nLabel);
3182 QCBOREncode_AddTag(pCtx, CBOR_TAG_URI);
3183 QCBOREncode_AddText(pCtx, URI);
3184}
3185
3186
3187
3188static inline void QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx, UsefulBufC B64Text)
3189{
3190 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64);
3191 QCBOREncode_AddText(pCtx, B64Text);
3192}
3193
3194static inline void QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text)
3195{
3196 QCBOREncode_AddSZString(pCtx, szLabel);
3197 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64);
3198 QCBOREncode_AddText(pCtx, B64Text);
3199}
3200
3201static inline void QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text)
3202{
3203 QCBOREncode_AddInt64(pCtx, nLabel);
3204 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64);
3205 QCBOREncode_AddText(pCtx, B64Text);
3206}
3207
3208
3209static inline void QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx, UsefulBufC B64Text)
3210{
3211 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64URL);
3212 QCBOREncode_AddText(pCtx, B64Text);
3213}
3214
3215static inline void QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text)
3216{
3217 QCBOREncode_AddSZString(pCtx, szLabel);
3218 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64URL);
3219 QCBOREncode_AddText(pCtx, B64Text);
3220}
3221
3222static inline void QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text)
3223{
3224 QCBOREncode_AddInt64(pCtx, nLabel);
3225 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64URL);
3226 QCBOREncode_AddText(pCtx, B64Text);
3227}
3228
3229
3230static inline void QCBOREncode_AddRegex(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
3231{
3232 QCBOREncode_AddTag(pCtx, CBOR_TAG_REGEX);
3233 QCBOREncode_AddText(pCtx, Bytes);
3234}
3235
3236static inline void QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
3237{
3238 QCBOREncode_AddSZString(pCtx, szLabel);
3239 QCBOREncode_AddTag(pCtx, CBOR_TAG_REGEX);
3240 QCBOREncode_AddText(pCtx, Bytes);
3241}
3242
3243static inline void QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
3244{
3245 QCBOREncode_AddInt64(pCtx, nLabel);
3246 QCBOREncode_AddTag(pCtx, CBOR_TAG_REGEX);
3247 QCBOREncode_AddText(pCtx, Bytes);
3248}
3249
3250
3251static inline void QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx, UsefulBufC MIMEData)
3252{
3253 QCBOREncode_AddTag(pCtx, CBOR_TAG_MIME);
3254 QCBOREncode_AddText(pCtx, MIMEData);
3255}
3256
3257static inline void QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC MIMEData)
3258{
3259 QCBOREncode_AddSZString(pCtx, szLabel);
3260 QCBOREncode_AddTag(pCtx, CBOR_TAG_MIME);
3261 QCBOREncode_AddText(pCtx, MIMEData);
3262}
3263
3264static inline void QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC MIMEData)
3265{
3266 QCBOREncode_AddInt64(pCtx, nLabel);
3267 QCBOREncode_AddTag(pCtx, CBOR_TAG_MIME);
3268 QCBOREncode_AddText(pCtx, MIMEData);
3269}
3270
3271
3272static inline void QCBOREncode_AddDateString(QCBOREncodeContext *pCtx, const char *szDate)
3273{
3274 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_STRING);
3275 QCBOREncode_AddSZString(pCtx, szDate);
3276}
3277
3278static inline void QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szDate)
3279{
3280 QCBOREncode_AddSZString(pCtx, szLabel);
3281 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_STRING);
3282 QCBOREncode_AddSZString(pCtx, szDate);
3283}
3284
3285static inline void QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szDate)
3286{
3287 QCBOREncode_AddInt64(pCtx, nLabel);
3288 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_STRING);
3289 QCBOREncode_AddSZString(pCtx, szDate);
3290}
3291
3292
3293static inline void QCBOREncode_AddSimple(QCBOREncodeContext *pCtx, uint64_t uNum)
3294{
3295 QCBOREncode_AddType7(pCtx, 0, uNum);
3296}
3297
3298static inline void QCBOREncode_AddSimpleToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint8_t uSimple)
3299{
3300 QCBOREncode_AddSZString(pCtx, szLabel);
3301 QCBOREncode_AddSimple(pCtx, uSimple);
3302}
3303
3304static inline void QCBOREncode_AddSimpleToMapN(QCBOREncodeContext *pCtx, int nLabel, uint8_t uSimple)
3305{
3306 QCBOREncode_AddInt64(pCtx, nLabel);
3307 QCBOREncode_AddSimple(pCtx, uSimple);
3308}
3309
3310
3311static inline void QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b)
3312{
3313 uint8_t uSimple = CBOR_SIMPLEV_FALSE;
3314 if(b) {
3315 uSimple = CBOR_SIMPLEV_TRUE;
3316 }
3317 QCBOREncode_AddSimple(pCtx, uSimple);
3318}
3319
3320static inline void QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b)
3321{
3322 QCBOREncode_AddSZString(pCtx, szLabel);
3323 QCBOREncode_AddBool(pCtx, b);
3324}
3325
3326static inline void QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b)
3327{
3328 QCBOREncode_AddInt64(pCtx, nLabel);
3329 QCBOREncode_AddBool(pCtx, b);
3330}
3331
3332
3333static inline void QCBOREncode_AddNULL(QCBOREncodeContext *pCtx)
3334{
3335 QCBOREncode_AddSimple(pCtx, CBOR_SIMPLEV_NULL);
3336}
3337
3338static inline void QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel)
3339{
3340 QCBOREncode_AddSZString(pCtx, szLabel);
3341 QCBOREncode_AddNULL(pCtx);
3342}
3343
3344static inline void QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
3345{
3346 QCBOREncode_AddInt64(pCtx, nLabel);
3347 QCBOREncode_AddNULL(pCtx);
3348}
3349
3350
3351static inline void QCBOREncode_AddUndef(QCBOREncodeContext *pCtx)
3352{
3353 QCBOREncode_AddSimple(pCtx, CBOR_SIMPLEV_UNDEF);
3354}
3355
3356static inline void QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel)
3357{
3358 QCBOREncode_AddSZString(pCtx, szLabel);
3359 QCBOREncode_AddUndef(pCtx);
3360}
3361
3362static inline void QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
3363{
3364 QCBOREncode_AddInt64(pCtx, nLabel);
3365 QCBOREncode_AddUndef(pCtx);
3366}
3367
3368
3369static inline void QCBOREncode_OpenArray(QCBOREncodeContext *pCtx)
3370{
3371 QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_ARRAY);
3372}
3373
3374static inline void QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel)
3375{
3376 QCBOREncode_AddSZString(pCtx, szLabel);
3377 QCBOREncode_OpenArray(pCtx);
3378}
3379
3380static inline void QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
3381{
3382 QCBOREncode_AddInt64(pCtx, nLabel);
3383 QCBOREncode_OpenArray(pCtx);
3384}
3385
3386static inline void QCBOREncode_CloseArray(QCBOREncodeContext *pCtx)
3387{
3388 QCBOREncode_CloseMapOrArray(pCtx, CBOR_MAJOR_TYPE_ARRAY, NULL);
3389}
3390
3391
3392static inline void QCBOREncode_OpenMap(QCBOREncodeContext *pCtx)
3393{
3394 QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_MAP);
3395}
3396
3397static inline void QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel)
3398{
3399 QCBOREncode_AddSZString(pCtx, szLabel);
3400 QCBOREncode_OpenMap(pCtx);
3401}
3402
3403static inline void QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
3404{
3405 QCBOREncode_AddInt64(pCtx, nLabel);
3406 QCBOREncode_OpenMap(pCtx);
3407}
3408
3409static inline void QCBOREncode_CloseMap(QCBOREncodeContext *pCtx)
3410{
3411 QCBOREncode_CloseMapOrArray(pCtx, CBOR_MAJOR_TYPE_MAP, NULL);
3412}
3413
Laurence Lundblade234fe422019-12-02 13:04:34 -08003414static inline void QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pCtx)
3415{
3416 QCBOREncode_OpenMapOrArrayIndefiniteLength(pCtx, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
3417}
3418
3419static inline void QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pCtx, const char *szLabel)
3420{
3421 QCBOREncode_AddSZString(pCtx, szLabel);
3422 QCBOREncode_OpenArrayIndefiniteLength(pCtx);
3423}
3424
3425static inline void QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
3426{
3427 QCBOREncode_AddInt64(pCtx, nLabel);
3428 QCBOREncode_OpenArrayIndefiniteLength(pCtx);
3429}
3430
3431static inline void QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pCtx)
3432{
3433 QCBOREncode_CloseMapOrArrayIndefiniteLength(pCtx, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN, NULL);
3434}
3435
3436
3437static inline void QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pCtx)
3438{
3439 QCBOREncode_OpenMapOrArrayIndefiniteLength(pCtx, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
3440}
3441
3442static inline void QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pCtx, const char *szLabel)
3443{
3444 QCBOREncode_AddSZString(pCtx, szLabel);
3445 QCBOREncode_OpenMapIndefiniteLength(pCtx);
3446}
3447
3448static inline void QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
3449{
3450 QCBOREncode_AddInt64(pCtx, nLabel);
3451 QCBOREncode_OpenMapIndefiniteLength(pCtx);
3452}
3453
3454static inline void QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pCtx)
3455{
3456 QCBOREncode_CloseMapOrArrayIndefiniteLength(pCtx, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN, NULL);
3457}
Laurence Lundblade6ed34222018-12-18 09:46:23 -08003458
3459static inline void QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx)
3460{
3461 QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_BYTE_STRING);
3462}
3463
3464static inline void QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel)
3465{
3466 QCBOREncode_AddSZString(pCtx, szLabel);
3467 QCBOREncode_BstrWrap(pCtx);
3468}
3469
3470static inline void QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
3471{
3472 QCBOREncode_AddInt64(pCtx, nLabel);
3473 QCBOREncode_BstrWrap(pCtx);
3474}
3475
3476static inline void QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR)
3477{
3478 QCBOREncode_CloseMapOrArray(pCtx, CBOR_MAJOR_TYPE_BYTE_STRING, pWrappedCBOR);
3479}
3480
3481
3482static inline void QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded)
3483{
3484 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_NONE_TYPE_RAW, Encoded);
3485}
3486
3487static inline void QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded)
3488{
3489 QCBOREncode_AddSZString(pCtx, szLabel);
3490 QCBOREncode_AddEncoded(pCtx, Encoded);
3491}
3492
3493static inline void QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded)
3494{
3495 QCBOREncode_AddInt64(pCtx, nLabel);
3496 QCBOREncode_AddEncoded(pCtx, Encoded);
3497}
3498
3499
Laurence Lundblade852a33c2019-06-11 09:00:07 -07003500static inline int QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx)
3501{
3502 return UsefulOutBuf_IsBufferNULL(&(pCtx->OutBuf));
3503}
3504
3505static inline QCBORError QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx)
3506{
Laurence Lundblade234fe422019-12-02 13:04:34 -08003507 if(UsefulOutBuf_GetError(&(pCtx->OutBuf))) {
3508 // Items didn't fit in the buffer.
3509 // This check catches this condition for all the appends and inserts
3510 // so checks aren't needed when the appends and inserts are performed.
3511 // And of course UsefulBuf will never overrun the input buffer given
3512 // to it. No complex analysis of the error handling in this file is
3513 // needed to know that is true. Just read the UsefulBuf code.
3514 pCtx->uError = QCBOR_ERR_BUFFER_TOO_SMALL;
3515 // QCBOR_ERR_BUFFER_TOO_SMALL masks other errors, but that is
3516 // OK. Once the caller fixes this, they'll be unmasked.
3517 }
3518
3519 return (QCBORError)pCtx->uError;
Laurence Lundblade852a33c2019-06-11 09:00:07 -07003520}
3521
3522
Laurence Lundblade6ed34222018-12-18 09:46:23 -08003523/* ===========================================================================
3524 END OF PRIVATE INLINE IMPLEMENTATION
3525
3526 =========================================================================== */
3527
Laurence Lundbladed425fb32019-02-18 10:56:18 -08003528#ifdef __cplusplus
3529}
3530#endif
3531
Laurence Lundblade6ed34222018-12-18 09:46:23 -08003532#endif /* defined(__QCBOR__qcbor__) */