blob: 29451920470aa0d46cd84aafc192b4bd24636e26 [file] [log] [blame]
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001/*==============================================================================
2 Copyright (c) 2016-2018, The Linux Foundation.
3 Copyright (c) 2018-2019, Laurence Lundblade.
4 All rights reserved.
5
6Redistribution and use in source and binary forms, with or without
7modification, are permitted provided that the following conditions are
8met:
9 * Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above
12 copyright notice, this list of conditions and the following
13 disclaimer in the documentation and/or other materials provided
14 with the distribution.
15 * Neither the name of The Linux Foundation nor the names of its
16 contributors, nor the name "Laurence Lundblade" may be used to
17 endorse or promote products derived from this software without
18 specific prior written permission.
19
20THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
21WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
23ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
24BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
30IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 ==============================================================================*/
32
33
34/*===================================================================================
35 FILE: qcbor.h
36
37 DESCRIPTION: This is the full public API and data structures for QCBOR
38
39 EDIT HISTORY FOR FILE:
40
41 This section contains comments describing changes made to the module.
42 Notice that changes are listed in reverse chronological order.
43
Laurence Lundblade852a33c2019-06-11 09:00:07 -070044 when who what, where, why
45 -------- ---- ---------------------------------------------------
46 05/26/19 llundblade Add QCBOREncode_GetErrorState() and _IsBufferNULL().
47 04/26/19 llundblade Big documentation & style update. No interface change.
48 02/16/19 llundblade Redesign MemPool to fix memory access alignment bug.
49 12/18/18 llundblade Move decode malloc optional code to separate repository.
50 12/13/18 llundblade Documentatation improvements.
51 11/29/18 llundblade Rework to simpler handling of tags and labels.
52 11/9/18 llundblade Error codes are now enums.
53 11/1/18 llundblade Floating support.
54 10/31/18 llundblade Switch to one license that is almost BSD-3.
55 10/15/18 llundblade indefinite-length maps and arrays supported
56 10/8/18 llundblade indefinite-length strings supported
57 09/28/18 llundblade Added bstr wrapping feature for COSE implementation.
58 07/05/17 llundbla Add bstr wrapping of maps/arrays for COSE.
59 03/01/17 llundbla More data types; decoding improvements and fixes.
60 11/13/16 llundbla Integrate most TZ changes back into github version.
61 09/30/16 gkanike Porting to TZ.
62 03/15/16 llundbla Initial Version.
Laurence Lundblade6ed34222018-12-18 09:46:23 -080063
64 =====================================================================================*/
65
66#ifndef __QCBOR__qcbor__
67#define __QCBOR__qcbor__
68
Laurence Lundblade6ed34222018-12-18 09:46:23 -080069
70/* ===========================================================================
71 BEGINNING OF PRIVATE PART OF THIS FILE
72
73 Caller of QCBOR should not reference any of the details below up until
74 the start of the public part.
75 =========================================================================== */
76
77/*
78 Standard integer types are used in the interface to be precise about
79 sizes to be better at preventing underflow/overflow errors.
80 */
81#include <stdint.h>
82#include <stdbool.h>
83#include "UsefulBuf.h"
84
Laurence Lundbladed425fb32019-02-18 10:56:18 -080085#ifdef __cplusplus
86extern "C" {
87#endif
Laurence Lundblade6ed34222018-12-18 09:46:23 -080088
89/*
90 The maxium nesting of arrays and maps when encoding or decoding.
91 (Further down in the file there is a definition that refers to this
92 that is public. This is done this way so there can be a nice
93 separation of public and private parts in this file.
94*/
95#define QCBOR_MAX_ARRAY_NESTING1 15 // Do not increase this over 255
96
97
98/* The largest offset to the start of an array or map. It is slightly
99 less than UINT32_MAX so the error condition can be tests on 32-bit machines.
100 UINT32_MAX comes from uStart in QCBORTrackNesting being a uin32_t.
101
102 This will cause trouble on a machine where size_t is less than 32-bits.
103 */
104#define QCBOR_MAX_ARRAY_OFFSET (UINT32_MAX - 100)
105
106/*
107 PRIVATE DATA STRUCTURE
108
109 Holds the data for tracking array and map nesting during encoding. Pairs up with
110 the Nesting_xxx functions to make an "object" to handle nesting encoding.
111
112 uStart is a uint32_t instead of a size_t to keep the size of this
113 struct down so it can be on the stack without any concern. It would be about
114 double if size_t was used instead.
115
116 Size approximation (varies with CPU/compiler):
117 64-bit machine: (15 + 1) * (4 + 2 + 1 + 1 pad) + 8 = 136 bytes
118 32-bit machine: (15 + 1) * (4 + 2 + 1 + 1 pad) + 4 = 132 bytes
119*/
120typedef struct __QCBORTrackNesting {
121 // PRIVATE DATA STRUCTURE
122 struct {
123 // See function OpenArrayInternal() for detailed comments on how this works
124 uint32_t uStart; // uStart is the byte position where the array starts
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700125 uint16_t uCount; // Number of items in the arrary or map; counts items
126 // in a map, not pairs of items
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800127 uint8_t uMajorType; // Indicates if item is a map or an array
128 } pArrays[QCBOR_MAX_ARRAY_NESTING1+1], // stored state for the nesting levels
129 *pCurrentNesting; // the current nesting level
130} QCBORTrackNesting;
131
132
133/*
134 PRIVATE DATA STRUCTURE
135
136 Context / data object for encoding some CBOR. Used by all encode functions to
137 form a public "object" that does the job of encdoing.
138
139 Size approximation (varies with CPU/compiler):
140 64-bit machine: 27 + 1 (+ 4 padding) + 136 = 32 + 136 = 168 bytes
141 32-bit machine: 15 + 1 + 132 = 148 bytes
142*/
143struct _QCBOREncodeContext {
144 // PRIVATE DATA STRUCTURE
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700145 UsefulOutBuf OutBuf; // Pointer to output buffer, its length and
146 // position in it
147 uint8_t uError; // Error state, always from QCBORError enum
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800148 QCBORTrackNesting nesting; // Keep track of array and map nesting
149};
150
151
152/*
153 PRIVATE DATA STRUCTURE
154
155 Holds the data for array and map nesting for decoding work. This structure
156 and the DecodeNesting_xxx functions form an "object" that does the work
157 for arrays and maps.
158
159 Size approximation (varies with CPU/compiler):
160 64-bit machine: 4 * 16 + 8 = 72
161 32-bit machine: 4 * 16 + 4 = 68
162 */
163typedef struct __QCBORDecodeNesting {
164 // PRIVATE DATA STRUCTURE
165 struct {
166 uint16_t uCount;
167 uint8_t uMajorType;
168 } pMapsAndArrays[QCBOR_MAX_ARRAY_NESTING1+1],
169 *pCurrent;
170} QCBORDecodeNesting;
171
172
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800173typedef struct {
174 // PRIVATE DATA STRUCTURE
175 void *pAllocateCxt;
176 UsefulBuf (* pfAllocator)(void *pAllocateCxt, void *pOldMem, size_t uNewSize);
177} QCORInternalAllocator;
178
179
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800180/*
181 PRIVATE DATA STRUCTURE
182
183 The decode context. This data structure plus the public QCBORDecode_xxx
184 functions form an "object" that does CBOR decoding.
185
186 Size approximation (varies with CPU/compiler):
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800187 64-bit machine: 32 + 1 + 1 + 6 bytes padding + 72 + 16 + 8 + 8 = 144 bytes
188 32-bit machine: 16 + 1 + 1 + 2 bytes padding + 68 + 8 + 8 + 4 = 108 bytes
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800189 */
190struct _QCBORDecodeContext {
191 // PRIVATE DATA STRUCTURE
192 UsefulInputBuf InBuf;
193
194 uint8_t uDecodeMode;
195 uint8_t bStringAllocateAll;
196
197 QCBORDecodeNesting nesting;
198
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700199 // If a string allocator is configured for indefinite-length
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800200 // strings, it is configured here.
201 QCORInternalAllocator StringAllocator;
202
203 // These are special for the internal MemPool allocator.
204 // They are not used otherwise. We tried packing these
205 // in the MemPool itself, but there are issues
206 // with memory alignment.
207 uint32_t uMemPoolSize;
208 uint32_t uMemPoolFreeOffset;
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800209
210 // This is NULL or points to QCBORTagList.
211 // It is type void for the same reason as above.
212 const void *pCallerConfiguredTagList;
213};
214
215// Used internally in the impementation here
216// Must not conflict with any of the official CBOR types
217#define CBOR_MAJOR_NONE_TYPE_RAW 9
218#define CBOR_MAJOR_NONE_TAG_LABEL_REORDER 10
Laurence Lundbladec93b5a72019-04-06 12:17:16 -0700219#define CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY 11
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800220
221
222/* ===========================================================================
223 END OF PRIVATE PART OF THIS FILE
224
225 BEGINNING OF PUBLIC PART OF THIS FILE
226 =========================================================================== */
227
228
229
230/* ===========================================================================
231 BEGINNING OF CONSTANTS THAT COME FROM THE CBOR STANDARD, RFC 7049
232
233 It is not necessary to use these directly when encoding or decoding
234 CBOR with this implementation.
235 =========================================================================== */
236
237/* Standard CBOR Major type for positive integers of various lengths */
238#define CBOR_MAJOR_TYPE_POSITIVE_INT 0
239
240/* Standard CBOR Major type for negative integer of various lengths */
241#define CBOR_MAJOR_TYPE_NEGATIVE_INT 1
242
243/* Standard CBOR Major type for an array of arbitrary 8-bit bytes. */
244#define CBOR_MAJOR_TYPE_BYTE_STRING 2
245
246/* Standard CBOR Major type for a UTF-8 string. Note this is true 8-bit UTF8
247 with no encoding and no NULL termination */
248#define CBOR_MAJOR_TYPE_TEXT_STRING 3
249
250/* Standard CBOR Major type for an ordered array of other CBOR data items */
251#define CBOR_MAJOR_TYPE_ARRAY 4
252
253/* Standard CBOR Major type for CBOR MAP. Maps an array of pairs. The
254 first item in the pair is the "label" (key, name or identfier) and the second
255 item is the value. */
256#define CBOR_MAJOR_TYPE_MAP 5
257
258/* Standard CBOR optional tagging. This tags things like dates and URLs */
259#define CBOR_MAJOR_TYPE_OPTIONAL 6
260
261/* Standard CBOR extra simple types like floats and the values true and false */
262#define CBOR_MAJOR_TYPE_SIMPLE 7
263
264
265/*
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700266 These are special values for the AdditionalInfo bits that are part of
267 the first byte. Mostly they encode the length of the data item.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800268 */
269#define LEN_IS_ONE_BYTE 24
270#define LEN_IS_TWO_BYTES 25
271#define LEN_IS_FOUR_BYTES 26
272#define LEN_IS_EIGHT_BYTES 27
273#define ADDINFO_RESERVED1 28
274#define ADDINFO_RESERVED2 29
275#define ADDINFO_RESERVED3 30
276#define LEN_IS_INDEFINITE 31
277
278
279/*
280 24 is a special number for CBOR. Integers and lengths
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700281 less than it are encoded in the same byte as the major type.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800282 */
283#define CBOR_TWENTY_FOUR 24
284
285
286/*
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700287 Tags that are used with CBOR_MAJOR_TYPE_OPTIONAL. These
288 are types defined in RFC 7049 and some additional ones
289 in the IANA CBOR tags registry.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800290 */
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700291/** See QCBOREncode_AddDateString(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800292#define CBOR_TAG_DATE_STRING 0
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700293/** See QCBOREncode_AddDateEpoch(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800294#define CBOR_TAG_DATE_EPOCH 1
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700295/** See QCBOREncode_AddPositiveBignum(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800296#define CBOR_TAG_POS_BIGNUM 2
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700297/** See QCBOREncode_AddNegativeBignum(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800298#define CBOR_TAG_NEG_BIGNUM 3
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700299/** CBOR tag for a two-element array representing a fraction with a
300 mantissa and base-10 scaling factor. No API is provided for this
301 tag. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800302#define CBOR_TAG_FRACTION 4
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700303/** CBOR tag for a two-element array representing a fraction with a
304 mantissa and base-2 scaling factor. No API is provided for this
305 tag. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800306#define CBOR_TAG_BIGFLOAT 5
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700307/** Tag for COSE format encryption with no recipient
308 identification. See [RFC 8152, COSE]
309 (https://tools.ietf.org/html/rfc8152). No API is provided for this
310 tag. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800311#define CBOR_TAG_COSE_ENCRYPTO 16
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700312/** Tag for COSE format MAC'd data with no recipient
313 identification. See [RFC 8152, COSE]
314 (https://tools.ietf.org/html/rfc8152). No API is provided for this
315 tag.*/
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800316#define CBOR_TAG_COSE_MAC0 17
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700317/** Tag for COSE format single signature signing. No API is provided
318 for this tag. See [RFC 8152, COSE]
319 (https://tools.ietf.org/html/rfc8152). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800320#define CBOR_TAG_COSE_SIGN1 18
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700321/** A hint that the following byte string should be encoded in
322 Base64URL when converting to JSON or similar text-based
323 representations. Call @c
324 QCBOREncode_AddTag(pCtx,CBOR_TAG_ENC_AS_B64URL) before the call to
325 QCBOREncode_AddBytes(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800326#define CBOR_TAG_ENC_AS_B64URL 21
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700327/** A hint that the following byte string should be encoded in Base64
328 when converting to JSON or similar text-based
329 representations. Call @c
330 QCBOREncode_AddTag(pCtx,CBOR_TAG_ENC_AS_B64) before the call to
331 QCBOREncode_AddBytes(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800332#define CBOR_TAG_ENC_AS_B64 22
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700333/** A hint that the following byte string should be encoded in base-16
334 format per [RFC 4648] (https://tools.ietf.org/html/rfc4648) when
335 converting to JSON or similar text-based
336 representations. Essentially, Base-16 encoding is the standard
337 case- insensitive hex encoding and may be referred to as
338 "hex". Call @c QCBOREncode_AddTag(pCtx,CBOR_TAG_ENC_AS_B16) before
339 the call to QCBOREncode_AddBytes(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800340#define CBOR_TAG_ENC_AS_B16 23
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700341/** Tag to indicate a byte string contains encoded CBOR. No API is
342 provided for this tag. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800343#define CBOR_TAG_CBOR 24
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700344/** See QCBOREncode_AddURI(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800345#define CBOR_TAG_URI 32
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700346/** See QCBOREncode_AddB64URLText(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800347#define CBOR_TAG_B64URL 33
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700348/** See QCBOREncode_AddB64Text(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800349#define CBOR_TAG_B64 34
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700350/** See QCBOREncode_AddRegex(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800351#define CBOR_TAG_REGEX 35
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700352/** See QCBOREncode_AddMIMEData(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800353#define CBOR_TAG_MIME 36
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700354/** See QCBOREncode_AddBinaryUUID(). */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800355#define CBOR_TAG_BIN_UUID 37
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700356/** The data is a CBOR Web Token per [RFC 8392]
357 (https://tools.ietf.org/html/rfc8932). No API is provided for this
358 tag. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800359#define CBOR_TAG_CWT 61
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700360/** Tag for COSE format encryption. See [RFC 8152, COSE]
361 (https://tools.ietf.org/html/rfc8152). No API is provided for this
362 tag. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800363#define CBOR_TAG_ENCRYPT 96
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700364/** Tag for COSE format MAC. See [RFC 8152, COSE]
365 (https://tools.ietf.org/html/rfc8152). No API is provided for this
366 tag. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800367#define CBOR_TAG_MAC 97
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700368/** Tag for COSE format signed data. See [RFC 8152, COSE]
369 (https://tools.ietf.org/html/rfc8152). No API is provided for this
370 tag. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800371#define CBOR_TAG_SIGN 98
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700372/** World geographic coordinates. See ISO 6709, [RFC 5870]
373 (https://tools.ietf.org/html/rfc5870) and WGS-84. No API is
374 provided for this tag. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800375#define CBOR_TAG_GEO_COORD 103
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700376/** The magic number, self-described CBOR. No API is provided for this
377 tag. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800378#define CBOR_TAG_CBOR_MAGIC 55799
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700379
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800380#define CBOR_TAG_NONE UINT64_MAX
381
382
383/*
384 Values for the 5 bits for items of major type 7
385 */
386#define CBOR_SIMPLEV_FALSE 20
387#define CBOR_SIMPLEV_TRUE 21
388#define CBOR_SIMPLEV_NULL 22
389#define CBOR_SIMPLEV_UNDEF 23
390#define CBOR_SIMPLEV_ONEBYTE 24
391#define HALF_PREC_FLOAT 25
392#define SINGLE_PREC_FLOAT 26
393#define DOUBLE_PREC_FLOAT 27
394#define CBOR_SIMPLE_BREAK 31
395
396
397
398/* ===========================================================================
399
400 END OF CONSTANTS THAT COME FROM THE CBOR STANDARD, RFC 7049
401
402 BEGINNING OF PUBLIC INTERFACE FOR QCBOR ENCODER / DECODER
403
404 =========================================================================== */
405
406/**
407
408 @file qcbor.h
409
410 Q C B O R E n c o d e / D e c o d e
411
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700412 This implements CBOR -- Concise Binary Object Representation as
413 defined in [RFC 7049] (https://tools.ietf.org/html/rfc7049). More
414 info is at http://cbor.io. This is a near-complete implementation of
415 the specification. Limitations are listed further down.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800416
417 CBOR is intentionally designed to be translatable to JSON, but not
418 all CBOR can convert to JSON. See RFC 7049 for more info on how to
419 construct CBOR that is the most JSON friendly.
420
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700421 The memory model for encoding and decoding is that encoded CBOR must
422 be in a contiguous buffer in memory. During encoding the caller must
423 supply an output buffer and if the encoding would go off the end of
424 the buffer an error is returned. During decoding the caller supplies
425 the encoded CBOR in a contiguous buffer and the decoder returns
426 pointers and lengths into that buffer for strings.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800427
428 This implementation does not require malloc. All data structures
429 passed in/out of the APIs can fit on the stack.
430
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700431 Decoding of indefinite-length strings is a special case that requires
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800432 a "string allocator" to allocate memory into which the segments of
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700433 the string are coalesced. Without this, decoding will error out if an
434 indefinite-length string is encountered (indefinite-length maps and
435 arrays do not require the string allocator). A simple string
436 allocator called MemPool is built-in and will work if supplied with a
437 block of memory to allocate. The string allocator can optionally use
438 malloc() or some other custom scheme.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800439
440 Here are some terms and definitions:
441
442 - "Item", "Data Item": An integer or string or such. The basic "thing" that
443 CBOR is about. An array is an item itself that contains some items.
444
445 - "Array": An ordered sequence of items, the same as JSON.
446
447 - "Map": A collection of label/value pairs. Each pair is a data
448 item. A JSON "object" is the same as a CBOR "map".
449
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700450 - "Label": The data item in a pair in a map that names or identifies
451 the pair, not the value. This implementation refers to it as a
452 "label". JSON refers to it as the "name". The CBOR RFC refers to it
453 this as a "key". This implementation chooses label instead because
454 key is too easily confused with a cryptographic key. The COSE
455 standard, which uses CBOR, has also chosen to use the term "label"
456 rather than "key" for this same reason.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800457
458 - "Key": See "Label" above.
459
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700460 - "Tag": Optional integer that can be added before each data item
461 usually to indicate it is new or more specific data type. For
462 example, a tag can indicate an integer is a date, or that a map is to
463 be considered a type (analogous to a typedef in C).
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800464
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700465 - "Initial Byte": The first byte of an encoded item. Encoding and
466 decoding of this byte is taken care of by the implementation.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800467
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700468 - "Additional Info": In addition to the major type, all data items
469 have some other info. This is usually the length of the data but can
470 be several other things. Encoding and decoding of this is taken care
471 of by the implementation.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800472
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700473 CBOR has two mechanisms for tagging and labeling the data values like
474 integers and strings. For example, an integer that represents
475 someone's birthday in epoch seconds since Jan 1, 1970 could be
476 encoded like this:
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800477
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700478 - First it is CBOR_MAJOR_TYPE_POSITIVE_INT (@ref QCBOR_TYPE_INT64),
479 the primitive positive integer.
480
481 - Next it has a "tag" @ref CBOR_TAG_DATE_EPOCH indicating the integer
482 represents a date in the form of the number of seconds since Jan 1,
483 1970.
484
485 - Last it has a string "label" like "BirthDate" indicating the
486 meaning of the data.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800487
488 The encoded binary looks like this:
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800489
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700490 a1 # Map of 1 item
491 69 # Indicates text string of 9 bytes
492 426972746844617465 # The text "BirthDate"
493 c1 # Tags next integer as epoch date
494 1a # Indicates a 4-byte integer
495 580d4172 # unsigned integer date 1477263730
496
497 Implementors using this API will primarily work with
498 labels. Generally, tags are only needed for making up new data
499 types. This implementation covers most of the data types defined in
500 the RFC using tags. It also, allows for the use of custom tags if
501 necessary.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800502
503 This implementation explicitly supports labels that are text strings
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700504 and integers. Text strings translate nicely into JSON objects and are
505 very readable. Integer labels are much less readable but can be very
506 compact. If they are in the range of 0 to 23, they take up only one
507 byte.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800508
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700509 CBOR allows a label to be any type of data including an array or a
510 map. It is possible to use this API to construct and parse such
511 labels, but it is not explicitly supported.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800512
513 A common encoding usage mode is to invoke the encoding twice. First
514 with no output buffer to compute the length of the needed output
515 buffer. Then the correct sized output buffer is allocated. Last the
516 encoder is invoked again, this time with the output buffer.
517
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700518 The double invocation is not required if the maximum output buffer
519 size can be predicted. This is usually possible for simple CBOR
520 structures. If the double invocation is implemented, it can be in a
521 loop or function as in the example code so that the code doesn't have
522 to actually be written twice, saving code size.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800523
524 If a buffer too small to hold the encoded output is given, the error
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700525 @ref QCBOR_ERR_BUFFER_TOO_SMALL will be returned. Data will never be
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800526 written off the end of the output buffer no matter which functions
527 here are called or what parameters are passed to them.
528
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700529 The encoding error handling is simple. The only possible errors are
530 trying to encode structures that are too large or too complex. There
531 are no internal malloc calls so there will be no failures for out of
532 memory. Only the final call, QCBOREncode_Finish(), returns an error
533 code. Once an error happens, the encoder goes into an error state
534 and calls to it will do nothing so the encoding can just go on. An
535 error check is not needed after every data item is added.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800536
537 Encoding generally proceeds by calling QCBOREncode_Init(), calling
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700538 lots of @c QCBOREncode_AddXxx() functions and calling
539 QCBOREncode_Finish(). There are many @c QCBOREncode_AddXxx()
540 functions for various data types. The input buffers need only to be
541 valid during the @c QCBOREncode_AddXxx() calls as the data is copied
542 into the output buffer.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800543
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700544 There are three `Add` functions for each data type. The first / main
545 one for the type is for adding the data item to an array. The second
546 one's name ends in `ToMap`, is used for adding data items to maps and
547 takes a string argument that is its label in the map. The third one
548 ends in `ToMapN`, is also used for adding data items to maps, and
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800549 takes an integer argument that is its label in the map.
550
551 The simplest aggregate type is an array, which is a simple ordered
552 set of items without labels the same as JSON arrays. Call
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700553 QCBOREncode_OpenArray() to open a new array, then various @c
554 QCBOREncode_AddXxx() functions to put items in the array and then
555 QCBOREncode_CloseArray(). Nesting to the limit @ref
556 QCBOR_MAX_ARRAY_NESTING is allowed. All opens must be matched by
557 closes or an encoding error will be returned.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800558
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700559 The other aggregate type is a map which does use labels. The `Add`
560 functions that end in `ToMap` and `ToMapN` are convenient ways to add
561 labeled data items to a map. You can also call any type of `Add`
562 function once to add a label of any time and then call any type of
563 `Add` again to add its value.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800564
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700565 Note that when you nest arrays or maps in a map, the nested array or
566 map has a label.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800567
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700568 @anchor Tags-Overview
569 Any CBOR data item can be tagged to add semantics, define a new data
570 type or such. Some tags are fully standardized and some are just
571 registered. Others are not registered and used in a proprietary way.
572
573 Encoding and decoding of many of the registered tags is fully
574 implemented by QCBOR. It is also possible to encode and decode tags
575 that are not directly supported. For many use cases the built-in tag
576 support should be adequate.
577
578 For example, the registered epoch date tag is supported in encoding
579 by QCBOREncode_AddDateEpoch() and in decoding by @ref
580 QCBOR_TYPE_DATE_EPOCH and the @c epochDate member of @ref
581 QCBORItem. This is typical of the built-in tag support. There is an
582 API to encode data for it and a @c QCBOR_TYPE_XXX when it is decoded.
583
584 Tags are registered in the [IANA CBOR Tags Registry]
585 (https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml). There
586 are roughly three options to create a new tag. First, a public
587 specification can be created and the new tag registered with IANA.
588 This is the most formal. Second, the new tag can be registered with
589 IANA with just a short description rather than a full specification.
590 These tags must be greater than 256. Third, a tag can be used without
591 any IANA registration, though the registry should be checked to see
592 that the new value doesn't collide with one that is registered. The
593 value of these tags must be 256 or larger.
594
595 The encoding side of tags not built-in is handled by
596 QCBOREncode_AddTag() and is relatively simple. Tag decoding is more
597 complex and mainly handled by QCBORDecode_GetNext(). Decoding of the
598 structure of tagged data not built-in (if there is any) has to be
599 implemented by the caller.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800600
601 Summary Limits of this implementation:
602 - The entire encoded CBOR must fit into contiguous memory.
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700603 - Max size of encoded / decoded CBOR data is @c UINT32_MAX (4GB).
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800604 - Max array / map nesting level when encoding / decoding is
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700605 @ref QCBOR_MAX_ARRAY_NESTING (this is typically 15).
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800606 - Max items in an array or map when encoding / decoding is
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700607 @ref QCBOR_MAX_ITEMS_IN_ARRAY (typically 65,536).
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800608 - Does not support encoding indefinite lengths (decoding is supported).
609 - Does not directly support some tagged types: decimal fractions, big floats
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700610 - Does not directly support labels in maps other than text strings and integers.
611 - Does not directly support integer labels greater than @c INT64_MAX.
612 - Epoch dates limited to @c INT64_MAX (+/- 292 billion years).
613 - Tags on labels are ignored during decoding.
614 - Works only on 32- and 64-bit CPUs (modifications could make it work
615 on 16-bit CPUs).
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800616
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700617 The public interface uses @c size_t for all lengths. Internally the
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800618 implementation uses 32-bit lengths by design to use less memory and
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700619 fit structures on the stack. This limits the encoded CBOR it can work
620 with to size @c UINT32_MAX (4GB) which should be enough.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800621
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700622 This implementation assumes two's compliment integer machines. @c
623 <stdint.h> also requires this. It is possible to modify this
624 implementation for another integer representation, but all modern
625 machines seem to be two's compliment.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800626
627 */
628
629
630/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700631 The maximum number of items in a single array or map when encoding of
632 decoding.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800633*/
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700634// -1 is because the value UINT16_MAX is used to track indefinite-length arrays
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800635#define QCBOR_MAX_ITEMS_IN_ARRAY (UINT16_MAX-1)
636
637/**
638 The maximum nesting of arrays and maps when encoding or decoding. The
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700639 error @ref QCBOR_ERR_ARRAY_NESTING_TOO_DEEP will be returned on
640 encoding of decoding if it is exceeded.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800641*/
642#define QCBOR_MAX_ARRAY_NESTING QCBOR_MAX_ARRAY_NESTING1
643
644/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700645 The maximum number of tags that can be in @ref QCBORTagListIn and passed to
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800646 QCBORDecode_SetCallerConfiguredTagList()
647 */
648#define QCBOR_MAX_CUSTOM_TAGS 16
649
650
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700651/**
652 Error codes returned by QCBOR Encoder and Decoder.
653 */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800654typedef enum {
655 /** The encode or decode completely correctly. */
656 QCBOR_SUCCESS = 0,
657
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700658 /** The buffer provided for the encoded output when doing encoding
659 was too small and the encoded output will not fit. Also, when
660 the buffer given to QCBORDecode_SetMemPool() is too small. */
661 QCBOR_ERR_BUFFER_TOO_SMALL = 1,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800662
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700663 /** During encoding or decoding, the array or map nesting was
664 deeper than this implementation can handle. Note that in the
665 interest of code size and memory use, this implementation has a
666 hard limit on array nesting. The limit is defined as the
667 constant @ref QCBOR_MAX_ARRAY_NESTING. */
668 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP = 2,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800669
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700670 /** During decoding or encoding, the array or map had too many
671 items in it. This limit @ref QCBOR_MAX_ITEMS_IN_ARRAY,
672 typically 65,535. */
673 QCBOR_ERR_ARRAY_TOO_LONG = 3,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800674
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700675 /** During encoding, more arrays or maps were closed than
676 opened. This is a coding error on the part of the caller of the
677 encoder. */
678 QCBOR_ERR_TOO_MANY_CLOSES = 4,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800679
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700680 /** During decoding, some CBOR construct was encountered that this
681 decoder doesn't support, primarily this is the reserved
682 additional info values, 28 through 30. */
683 QCBOR_ERR_UNSUPPORTED = 5,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800684
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700685 /** During decoding, hit the end of the given data to decode. For
686 example, a byte string of 100 bytes was expected, but the end
687 of the input was hit before finding those 100 bytes. Corrupted
688 CBOR input will often result in this error. */
689 QCBOR_ERR_HIT_END = 6,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800690
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700691 /** During encoding, the length of the encoded CBOR exceeded @c
692 UINT32_MAX. */
693 QCBOR_ERR_BUFFER_TOO_LARGE = 7,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800694
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700695 /** During decoding, an integer smaller than INT64_MIN was received
696 (CBOR can represent integers smaller than INT64_MIN, but C
697 cannot). */
698 QCBOR_ERR_INT_OVERFLOW = 8,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800699
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700700 /** During decoding, the label for a map entry is bad. What causes
701 this error depends on the decoding mode. */
702 QCBOR_ERR_MAP_LABEL_TYPE = 9,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800703
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700704 /** During encoding or decoding, the number of array or map opens
705 was not matched by the number of closes. */
706 QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN = 10,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800707
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700708 /** During decoding, a date greater than +- 292 billion years from
709 Jan 1 1970 encountered during parsing. */
710 QCBOR_ERR_DATE_OVERFLOW = 11,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800711
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700712 /** During decoding, the CBOR is not valid, primarily a simple type
713 is encoded in a prohibited way. */
714 QCBOR_ERR_BAD_TYPE_7 = 12,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800715
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700716 /** Optional tagging that doesn't make sense (an integer is tagged
717 as a date string) or can't be handled. */
718 QCBOR_ERR_BAD_OPT_TAG = 13,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800719
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700720 /** Returned by QCBORDecode_Finish() if all the inputs bytes have
721 not been consumed. */
722 QCBOR_ERR_EXTRA_BYTES = 14,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800723
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700724 /** During encoding, @c QCBOREncode_CloseXxx() called with a
725 different type than is currently open. */
726 QCBOR_ERR_CLOSE_MISMATCH = 15,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800727
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700728 /** Unable to decode an indefinite-length string because no string
729 allocator was configured. See QCBORDecode_SetMemPool() or
730 QCBORDecode_SetUpAllocator(). */
731 QCBOR_ERR_NO_STRING_ALLOCATOR = 16,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800732
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700733 /** One of the chunks in an indefinite-length string is not of the
734 type of the start of the string. */
735 QCBOR_ERR_INDEFINITE_STRING_CHUNK = 17,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800736
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700737 /** Error allocating space for a string, usually for an
738 indefinite-length string. */
739 QCBOR_ERR_STRING_ALLOCATE = 18,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800740
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700741 /** During decoding, a break occurred outside an indefinite-length
742 item. */
743 QCBOR_ERR_BAD_BREAK = 19,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800744
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700745 /** During decoding, too many tags in the caller-configured tag
746 list, or not enough space in @ref QCBORTagListOut. */
747 QCBOR_ERR_TOO_MANY_TAGS = 20,
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800748
749} QCBORError;
750
751
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700752/**
753 The decode mode options.
754 */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800755typedef enum {
756 /** See QCBORDecode_Init() */
757 QCBOR_DECODE_MODE_NORMAL = 0,
758 /** See QCBORDecode_Init() */
759 QCBOR_DECODE_MODE_MAP_STRINGS_ONLY = 1,
760 /** See QCBORDecode_Init() */
761 QCBOR_DECODE_MODE_MAP_AS_ARRAY = 2
762} QCBORDecodeMode;
763
764
765
766
767
768/* Do not renumber these. Code depends on some of these values. */
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700769/** The data type is unknown, unset or invalid. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800770#define QCBOR_TYPE_NONE 0
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700771/** Type for an integer that decoded either between @c INT64_MIN and
772 @c INT32_MIN or @c INT32_MAX and @c INT64_MAX. Data is in member
773 @c val.int64. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800774#define QCBOR_TYPE_INT64 2
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700775/** Type for an integer that decoded to a more than @c INT64_MAX and
776 @c UINT64_MAX. Data is in member @c val.uint64. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800777#define QCBOR_TYPE_UINT64 3
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700778/** Type for an array. The number of items in the array is in @c
779 val.uCount. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800780#define QCBOR_TYPE_ARRAY 4
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700781/** Type for a map; number of items in map is in @c val.uCount. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800782#define QCBOR_TYPE_MAP 5
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700783/** Type for a buffer full of bytes. Data is in @c val.string. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800784#define QCBOR_TYPE_BYTE_STRING 6
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700785/** Type for a UTF-8 string. It is not NULL-terminated. Data is in @c
786 val.string. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800787#define QCBOR_TYPE_TEXT_STRING 7
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700788/** Type for a positive big number. Data is in @c val.bignum, a
789 pointer and a length. */
790#define QCBOR_TYPE_POSBIGNUM 9
791/** Type for a negative big number. Data is in @c val.bignum, a
792 pointer and a length. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800793#define QCBOR_TYPE_NEGBIGNUM 10
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700794/** Type for [RFC 3339] (https://tools.ietf.org/html/rfc3339) date
795 string, possibly with time zone. Data is in @c val.dateString */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800796#define QCBOR_TYPE_DATE_STRING 11
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700797/** Type for integer seconds since Jan 1970 + floating point
798 fraction. Data is in @c val.epochDate */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800799#define QCBOR_TYPE_DATE_EPOCH 12
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700800/** A simple type that this CBOR implementation doesn't know about;
801 Type is in @c val.uSimple. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800802#define QCBOR_TYPE_UKNOWN_SIMPLE 13
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700803/** Type for the value false. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800804#define QCBOR_TYPE_FALSE 20
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700805/** Type for the value true. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800806#define QCBOR_TYPE_TRUE 21
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700807/** Type for the value null. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800808#define QCBOR_TYPE_NULL 22
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700809/** Type for the value undef. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800810#define QCBOR_TYPE_UNDEF 23
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700811/** Type for a floating-point number. Data is in @c val.float. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800812#define QCBOR_TYPE_FLOAT 26
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700813/** Type for a double floating-point number. Data is in @c val.double. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800814#define QCBOR_TYPE_DOUBLE 27
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700815/** For @ref QCBOR_DECODE_MODE_MAP_AS_ARRAY decode mode, a map that is
816 being traversed as an array. See QCBORDecode_Init() */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800817#define QCBOR_TYPE_MAP_AS_ARRAY 32
818
819#define QCBOR_TYPE_BREAK 31 // Used internally; never returned
820
821#define QCBOR_TYPE_OPTTAG 254 // Used internally; never returned
822
823
824
825/*
826 Approx Size of this:
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700827 8 + 8 + 1 + 1 + 1 + (1 padding) + (4 padding) = 24 for first part
828 (20 on a 32-bit machine)
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800829 16 bytes for the val union
830 16 bytes for label union
831 total = 56 bytes (52 bytes on 32-bit machine)
832 */
833
834/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700835 The main data structure that holds the type, value and other info for
836 a decoded item returned by QCBORDecode_GetNext() and
837 QCBORDecode_GetNextWithTags().
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800838 */
839typedef struct _QCBORItem {
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700840 /** Tells what element of the @c val union to use. One of @c
841 QCBOR_TYPE_XXXX */
842 uint8_t uDataType;
843 /** How deep the nesting from arrays and maps are. 0 is the top
844 level with no arrays or maps entered. */
845 uint8_t uNestingLevel;
846 /** Tells what element of the label union to use. */
847 uint8_t uLabelType;
848 /** 1 if allocated with string allocator, 0 if not. See
849 QCBORDecode_SetMemPool() or QCBORDecode_SetUpAllocator() */
850 uint8_t uDataAlloc;
851 /** Like @c uDataAlloc, but for label. */
852 uint8_t uLabelAlloc;
853 /** If not equal to @c uNestingLevel, this item closed out at least
854 one map/array */
855 uint8_t uNextNestLevel;
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800856
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700857 /** The union holding the item's value. Select union member based
858 on @c uDataType */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800859 union {
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700860 /** The value for @c uDataType @ref QCBOR_TYPE_INT64. */
861 int64_t int64;
862 /** The value for uDataType @ref QCBOR_TYPE_UINT64. */
863 uint64_t uint64;
864 /** The value for @c uDataType @ref QCBOR_TYPE_BYTE_STRING and
865 @ref QCBOR_TYPE_TEXT_STRING. */
866 UsefulBufC string;
867 /** The "value" for @c uDataType @ref QCBOR_TYPE_ARRAY or @ref
868 QCBOR_TYPE_MAP -- the number of items in the array or map.
869 It is @c UINT16_MAX when decoding indefinite-lengths maps
870 and arrays. */
871 uint16_t uCount;
872 /** The value for @c uDataType @ref QCBOR_TYPE_DOUBLE. */
873 double dfnum;
874 /** The value for @c uDataType @ref QCBOR_TYPE_DATE_EPOCH. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800875 struct {
876 int64_t nSeconds;
877 double fSecondsFraction;
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700878 } epochDate;
879 /** The value for @c uDataType @ref QCBOR_TYPE_DATE_STRING. */
880 UsefulBufC dateString;
881 /** The value for @c uDataType @ref QCBOR_TYPE_POSBIGNUM and
882 @ref QCBOR_TYPE_NEGBIGNUM. */
883 UsefulBufC bigNum;
884 /** The integer value for unknown simple types. */
885 uint8_t uSimple;
886 uint64_t uTagV; // Used internally during decoding
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800887
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700888 } val;
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800889
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700890 /** Union holding the different label types selected based on @c
891 uLabelType */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800892 union {
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700893 /** The label for @c uLabelType @ref QCBOR_TYPE_BYTE_STRING and
894 @ref QCBOR_TYPE_TEXT_STRING */
895 UsefulBufC string;
896 /** The label for @c uLabelType for @ref QCBOR_TYPE_INT64 */
897 int64_t int64;
898 /** The label for @c uLabelType for @ref QCBOR_TYPE_UINT64 */
899 uint64_t uint64;
900 } label;
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800901
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700902 /** Bit indicating which tags (major type 6) on this item. See
903 QCBORDecode_IsTagged(). */
904 uint64_t uTagBits;
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800905
906} QCBORItem;
907
908
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800909
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800910/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700911 @brief The type defining what a string allocator function must do.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800912
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700913 @param[in] pAllocateCxt Pointer to context for the particular
914 allocator implementation What is in the
915 context is dependent on how a particular
916 string allocator works. Typically, it
917 will contain a pointer to the memory pool
918 and some booking keeping data.
919 @param[in] pOldMem Points to some memory allocated by the
920 allocator that is either to be freed or
921 to be reallocated to be larger. It is
922 @c NULL for new allocations and when called as
923 a destructor to clean up the whole
924 allocation.
925 @param[in] uNewSize Size of memory to be allocated or new
926 size of chunk to be reallocated. Zero for
927 a new allocation or when called as a
928 destructor.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800929
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700930 @return Either the allocated buffer is returned, or @ref
931 NULLUsefulBufC. @ref NULLUsefulBufC is returned on a failed
932 allocation and in the two cases where there is nothing to
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800933 return.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800934
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800935 This is called in one of four modes:
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800936
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700937 Allocate -- @c uNewSize is the amount to allocate. @c pOldMem is @c
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800938 NULL.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800939
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700940 Free -- @c uNewSize is 0. @c pOldMem points to the memory to be
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800941 freed. When the decoder calls this, it will always be the most
942 recent block that was either allocated or reallocated.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800943
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700944 Reallocate -- @c pOldMem is the block to reallocate. @c uNewSize is
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800945 its new size. When the decoder calls this, it will always be the
946 most recent block that was either allocated or reallocated.
947
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700948 Destruct -- @c pOldMem is @c NULL and @c uNewSize is 0. This is called
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800949 when the decoding is complete by QCBORDecode_Finish(). Usually the
950 strings allocated by a string allocator are in use after the decoding
951 is completed so this usually will not free those strings. Many string
952 allocators will not need to do anything in this mode.
953
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700954 The strings allocated by this will have @c uDataAlloc set to true in
955 the @ref QCBORItem when they are returned. The user of the strings
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800956 will have to free them. How they free them, depends on the string
957 allocator.
958
959 If QCBORDecode_SetMemPool() is called, the internal MemPool will be
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700960 used. It has its own internal implementation of this function, so
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800961 one does not need to be implemented.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800962 */
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800963typedef UsefulBuf (* QCBORStringAllocate)(void *pAllocateCxt, void *pOldMem, size_t uNewSize);
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800964
965
966/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700967 This only matters if you use the built-in string allocator by setting
968 it up with QCBORDecode_SetMemPool(). This is the size of the overhead
969 needed by QCBORDecode_SetMemPool(). The amount of memory available
970 for decoded strings will be the size of the buffer given to
971 QCBORDecode_SetMemPool() less this amount.
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800972
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700973 If you write your own string allocator or use the separately
974 available malloc based string allocator, this size will not apply.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800975 */
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800976#define QCBOR_DECODE_MIN_MEM_POOL_SIZE 8
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800977
978
979/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700980 This is used by QCBORDecode_SetCallerConfiguredTagList() to set a
981 list of tags beyond the built-in ones.
982
983 See also QCBORDecode_GetNext() for general description of tag
984 decoding.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800985 */
986typedef struct {
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700987 /** The number of tags in the @c puTags. The maximum size is @ref
988 QCBOR_MAX_CUSTOM_TAGS. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800989 uint8_t uNumTags;
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700990 /** An array of tags to add to recognize in addition to the
991 built-in ones. */
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800992 const uint64_t *puTags;
993} QCBORTagListIn;
994
995
996/**
997 This is for QCBORDecode_GetNextWithTags() to be able to return the
Laurence Lundblade852a33c2019-06-11 09:00:07 -0700998 full list of tags on an item. It is not needed for most CBOR protocol
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800999 implementations. Its primary use is for pretty-printing CBOR or
1000 protocol conversion to another format.
1001
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001002 On input, @c puTags points to a buffer to be filled in and
1003 uNumAllocated is the number of @c uint64_t values in the buffer.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001004
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001005 On output the buffer contains the tags for the item. @c uNumUsed
1006 tells how many there are.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001007 */
1008typedef struct {
1009 uint8_t uNumUsed;
1010 uint8_t uNumAllocated;
1011 uint64_t *puTags;
1012} QCBORTagListOut;
1013
1014
1015/**
1016 QCBOREncodeContext is the data type that holds context for all the
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001017 encoding functions. It is less than 200 bytes, so it can go on the
1018 stack. The contents are opaque, and the caller should not access
1019 internal members. A context may be re used serially as long as it is
1020 re initialized.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001021 */
1022typedef struct _QCBOREncodeContext QCBOREncodeContext;
1023
1024
1025/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001026 Initialize the encoder to prepare to encode some CBOR.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001027
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001028 @param[in,out] pCtx The encoder context to initialize.
1029 @param[in] Storage The buffer into which this encoded result
1030 will be placed.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001031
1032 Call this once at the start of an encoding of a CBOR structure. Then
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001033 call the various @c QCBOREncode_AddXxx() functions to add the data
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001034 items. Then call QCBOREncode_Finish().
1035
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001036 The maximum output buffer is @c UINT32_MAX (4GB). This is not a
1037 practical limit in any way and reduces the memory needed by the
1038 implementation. The error @ref QCBOR_ERR_BUFFER_TOO_LARGE will be
1039 returned by QCBOREncode_Finish() if a larger buffer length is passed
1040 in.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001041
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001042 If this is called with @c Storage.ptr as @c NULL and @c Storage.len a
1043 large value like @c UINT32_MAX, all the QCBOREncode_AddXxx()
1044 functions and QCBOREncode_Finish() can still be called. No data will
1045 be encoded, but the length of what would be encoded will be
1046 calculated. The length of the encoded structure will be handed back
1047 in the call to QCBOREncode_Finish(). You can then allocate a buffer
1048 of that size and call all the encoding again, this time to fill in
1049 the buffer.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001050
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001051 A @ref QCBOREncodeContext can be reused over and over as long as
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001052 QCBOREncode_Init() is called.
1053 */
1054void QCBOREncode_Init(QCBOREncodeContext *pCtx, UsefulBuf Storage);
1055
1056
1057/**
1058 @brief Add a signed 64-bit integer to the encoded output.
1059
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001060 @param[in] pCtx The encoding context to add the integer to.
1061 @param[in] nNum The integer to add.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001062
1063 The integer will be encoded and added to the CBOR output.
1064
1065 This function figures out the size and the sign and encodes in the
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001066 correct minimal CBOR. Specifically, it will select CBOR major type 0
1067 or 1 based on sign and will encode to 1, 2, 4 or 8 bytes depending on
1068 the value of the integer. Values less than 24 effectively encode to
1069 one byte because they are encoded in with the CBOR major type. This
1070 is a neat and efficient characteristic of CBOR that can be taken
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001071 advantage of when designing CBOR-based protocols. If integers like
1072 tags can be kept between -23 and 23 they will be encoded in one byte
1073 including the major type.
1074
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001075 If you pass a smaller int, say an @c int16_t or a small value, say
1076 100, the encoding will still be CBOR's most compact that can
1077 represent the value. For example, CBOR always encodes the value 0 as
1078 one byte, 0x00. The representation as 0x00 includes identification of
1079 the type as an integer too as the major type for an integer is 0. See
1080 [RFC 7049] (https://tools.ietf.org/html/rfc7049) Appendix A for more
1081 examples of CBOR encoding. This compact encoding is also canonical
1082 CBOR as per section 3.9 in RFC 7049.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001083
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001084 There are no functions to add @c int16_t or @c int32_t because they
1085 are not necessary because this always encodes to the smallest number
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001086 of bytes based on the value (If this code is running on a 32-bit
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001087 machine having a way to add 32-bit integers would reduce code size
1088 some).
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001089
1090 If the encoding context is in an error state, this will do
1091 nothing. If an error occurs when adding this integer, the internal
1092 error flag will be set, and the error will be returned when
1093 QCBOREncode_Finish() is called.
1094
1095 See also QCBOREncode_AddUInt64().
1096 */
1097void QCBOREncode_AddInt64(QCBOREncodeContext *pCtx, int64_t nNum);
1098
1099static void QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum);
1100
1101static void QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum);
1102
1103
1104/**
1105 @brief Add an unsigned 64-bit integer to the encoded output.
1106
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001107 @param[in] pCtx The encoding context to add the integer to.
1108 @param[in] uNum The integer to add.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001109
1110 The integer will be encoded and added to the CBOR output.
1111
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001112 The only reason so use this function is for integers larger than @c
1113 INT64_MAX and smaller than @c UINT64_MAX. Otherwise
1114 QCBOREncode_AddInt64() will work fine.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001115
1116 Error handling is the same as for QCBOREncode_AddInt64().
1117 */
1118void QCBOREncode_AddUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
1119
1120static void QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum);
1121
1122static void QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum);
1123
1124
1125/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001126 @brief Add a UTF-8 text string to the encoded output.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001127
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001128 @param[in] pCtx The context to initialize.
1129 @param[in] Text Pointer and length of text to add.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001130
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001131 The text passed in must be unencoded UTF-8 according to [RFC 3629]
1132 (https://tools.ietf.org/html/rfc3629). There is no NULL
1133 termination. The text is added as CBOR major type 3.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001134
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001135 If called with @c nBytesLen equal to 0, an empty string will be
1136 added. When @c nBytesLen is 0, @c pBytes may be @c NULL.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001137
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001138 Note that the restriction of the buffer length to a @c uint32_t is
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001139 entirely intentional as this encoder is not capable of encoding
1140 lengths greater. This limit to 4GB for a text string should not be a
1141 problem.
1142
1143 Error handling is the same as QCBOREncode_AddInt64().
1144 */
1145static void QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text);
1146
1147static void QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text);
1148
1149static void QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text);
1150
1151
1152/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001153 @brief Add a UTF-8 text string to the encoded output.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001154
1155 @param[in] pCtx The context to initialize.
1156 @param[in] szString Null-terminated text to add.
1157
1158 This works the same as QCBOREncode_AddText().
1159 */
1160static void QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString);
1161
1162static void QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString);
1163
1164static void QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString);
1165
1166
1167/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001168 @brief Add a floating-point number to the encoded output.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001169
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001170 @param[in] pCtx The encoding context to add the float to.
1171 @param[in] dNum The double precision number to add.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001172
1173 This outputs a floating-point number with CBOR major type 7.
1174
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001175 This will selectively encode the double-precision floating-point
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001176 number as either double-precision, single-precision or
1177 half-precision. It will always encode infinity, NaN and 0 has half
1178 precision. If no precision will be lost in the conversion to
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001179 half-precision, then it will be converted and encoded. If not and no
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001180 precision will be lost in conversion to single-precision, then it
1181 will be converted and encoded. If not, then no conversion is
1182 performed, and it encoded as a double.
1183
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001184 Half-precision floating-point numbers take up 2 bytes, half that of
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001185 single-precision, one quarter of double-precision
1186
1187 This automatically reduces the size of encoded messages a lot, maybe
1188 even by four if most of values are 0, infinity or NaN.
1189
1190 On decode, these will always be returned as a double.
1191
1192 Error handling is the same as QCBOREncode_AddInt64().
1193 */
1194void QCBOREncode_AddDouble(QCBOREncodeContext *pCtx, double dNum);
1195
1196static void QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
1197
1198static void QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
1199
1200
1201/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001202 @brief Add an optional tag.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001203
1204 @param[in] pCtx The encoding context to add the integer to.
1205 @param[in] uTag The tag to add
1206
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001207 This outputs a CBOR major type 6 item that tags the next data item
1208 that is output usually to indicate it is some new data type.
1209
1210 For many of the common standard tags, a function to encode data using
1211 it is provided and this is not needed. For example,
1212 QCBOREncode_AddDateEpoch() already exists to output integers
1213 representing dates with the right tag.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001214
1215 The tag is applied to the next data item added to the encoded
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001216 output. That data item that is to be tagged can be of any major CBOR
1217 type. Any number of tags can be added to a data item by calling this
1218 multiple times before the data item is added.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001219
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001220 See @ref Tags-Overview for discussion of creating new non-standard
1221 tags. See QCBORDecode_GetNext() for discussion of decoding custom
1222 tags.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001223*/
1224void QCBOREncode_AddTag(QCBOREncodeContext *pCtx,uint64_t uTag);
1225
1226
1227/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001228 @brief Add an epoch-based date.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001229
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001230 @param[in] pCtx The encoding context to add the simple value to.
1231 @param[in] date Number of seconds since 1970-01-01T00:00Z in UTC time.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001232
1233 As per RFC 7049 this is similar to UNIX/Linux/POSIX dates. This is
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001234 the most compact way to specify a date and time in CBOR. Note that
1235 this is always UTC and does not include the time zone. Use
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001236 QCBOREncode_AddDateString() if you want to include the time zone.
1237
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001238 The integer encoding rules apply here so the date will be encoded in
1239 a minimal number of bytes. Until about the year 2106 these dates will
1240 encode in 6 bytes -- one byte for the tag, one byte for the type and
1241 4 bytes for the integer. After that it will encode to 10 bytes.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001242
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001243 Negative values are supported for dates before 1970.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001244
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001245 If you care about leap-seconds and that level of accuracy, make sure
1246 the system you are running this code on does it correctly. This code
1247 just takes the value passed in.
1248
1249 This implementation cannot encode fractional seconds using float or
1250 double even though that is allowed by CBOR, but you can encode them
1251 if you want to by calling QCBOREncode_AddDouble() and
1252 QCBOREncode_AddTag().
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001253
1254 Error handling is the same as QCBOREncode_AddInt64().
1255 */
1256static void QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx, int64_t date);
1257
1258static void QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t date);
1259
1260static void QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t date);
1261
1262
1263/**
1264 @brief Add a byte string to the encoded output.
1265
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001266 @param[in] pCtx The context to initialize.
1267 @param[in] Bytes Pointer and length of the input data.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001268
1269 Simply adds the bytes to the encoded output as CBOR major type 2.
1270
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001271 If called with @c Bytes.len equal to 0, an empty string will be
1272 added. When @c Bytes.len is 0, @c Bytes.ptr may be @c NULL.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001273
1274 Error handling is the same as QCBOREncode_AddInt64().
1275 */
1276static void QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
1277
1278static void QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
1279
1280static void QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
1281
1282
1283
1284/**
1285 @brief Add a binary UUID to the encoded output.
1286
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001287 @param[in] pCtx The context to initialize.
1288 @param[in] Bytes Pointer and length of the binary UUID.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001289
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001290 A binary UUID as defined in [RFC 4122]
1291 (https://tools.ietf.org/html/rfc4122) is added to the output.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001292
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001293 It is output as CBOR major type 2, a binary string, with tag @ref
1294 CBOR_TAG_BIN_UUID indicating the binary string is a UUID.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001295 */
1296static void QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
1297
1298static void QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
1299
1300static void QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
1301
1302
1303/**
1304 @brief Add a positive big number to the encoded output.
1305
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001306 @param[in] pCtx The context to initialize.
1307 @param[in] Bytes Pointer and length of the big number.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001308
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001309 Big numbers are integers larger than 64-bits. Their format is
1310 described in [RFC 7049] (https://tools.ietf.org/html/rfc7049).
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001311
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001312 It is output as CBOR major type 2, a binary string, with tag @ref
1313 CBOR_TAG_POS_BIGNUM indicating the binary string is a positive big
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001314 number.
1315
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001316 Often big numbers are used to represent cryptographic keys, however,
1317 COSE which defines representations for keys chose not to use this
1318 particular type.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001319 */
1320static void QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
1321
1322static void QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
1323
1324static void QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
1325
1326
1327/**
1328 @brief Add a negative big number to the encoded output.
1329
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001330 @param[in] pCtx The context to initialize.
1331 @param[in] Bytes Pointer and length of the big number.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001332
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001333 Big numbers are integers larger than 64-bits. Their format is
1334 described in [RFC 7049] (https://tools.ietf.org/html/rfc7049).
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001335
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001336 It is output as CBOR major type 2, a binary string, with tag @ref
1337 CBOR_TAG_NEG_BIGNUM indicating the binary string is a negative big
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001338 number.
1339
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001340 Often big numbers are used to represent cryptographic keys, however,
1341 COSE which defines representations for keys chose not to use this
1342 particular type.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001343 */
1344static void QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
1345
1346static void QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
1347
1348static void QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
1349
1350
1351/**
1352 @brief Add a text URI to the encoded output.
1353
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001354 @param[in] pCtx The context to initialize.
1355 @param[in] URI Pointer and length of the URI.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001356
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001357 The format of URI must be per [RFC 3986]
1358 (https://tools.ietf.org/html/rfc3986).
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001359
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001360 It is output as CBOR major type 3, a text string, with tag @ref
1361 CBOR_TAG_URI indicating the text string is a URI.
1362
1363 A URI in a NULL-terminated string, @c szURI, can be easily added with
1364 this code:
1365
1366 QCBOREncode_AddURI(pCtx, UsefulBuf_FromSZ(szURI));
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001367 */
1368static void QCBOREncode_AddURI(QCBOREncodeContext *pCtx, UsefulBufC URI);
1369
1370static void QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC URI);
1371
1372static void QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC URI);
1373
1374
1375/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001376 @brief Add Base64-encoded text to encoded output.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001377
1378 @param[in] pCtx The context to initialize.
1379 @param[in] B64Text Pointer and length of the base-64 encoded text.
1380
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001381 The text content is Base64 encoded data per [RFC 4648]
1382 (https://tools.ietf.org/html/rfc4648).
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001383
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001384 It is output as CBOR major type 3, a text string, with tag @ref
1385 CBOR_TAG_B64 indicating the text string is Base64 encoded.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001386 */
1387static void QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx, UsefulBufC B64Text);
1388
1389static void QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text);
1390
1391static void QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text);
1392
1393
1394/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001395 @brief Add base64url encoded data to encoded output.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001396
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001397 @param[in] pCtx The context to initialize.
1398 @param[in] B64Text Pointer and length of the base64url encoded text.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001399
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001400 The text content is base64URL encoded text as per [RFC 4648]
1401 (https://tools.ietf.org/html/rfc4648).
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001402
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001403 It is output as CBOR major type 3, a text string, with tag @ref
1404 CBOR_TAG_B64URL indicating the text string is a Base64url encoded.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001405 */
1406static void QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx, UsefulBufC B64Text);
1407
1408static void QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text);
1409
1410static void QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text);
1411
1412
1413/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001414 @brief Add Perl Compatible Regular Expression.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001415
1416 @param[in] pCtx The context to initialize.
1417 @param[in] Regex Pointer and length of the regular expression.
1418
1419 The text content is Perl Compatible Regular
1420 Expressions (PCRE) / JavaScript syntax [ECMA262].
1421
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001422 It is output as CBOR major type 3, a text string, with tag @ref
1423 CBOR_TAG_REGEX indicating the text string is a regular expression.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001424 */
1425static void QCBOREncode_AddRegex(QCBOREncodeContext *pCtx, UsefulBufC Regex);
1426
1427static void QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Regex);
1428
1429static void QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Regex);
1430
1431
1432/**
1433 @brief MIME encoded text to the encoded output.
1434
1435 @param[in] pCtx The context to initialize.
1436 @param[in] MIMEData Pointer and length of the regular expression.
1437
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001438 The text content is in MIME format per [RFC 2045]
1439 (https://tools.ietf.org/html/rfc2045) including the headers. Note
1440 that this only supports text-format MIME. Binary MIME is not
1441 supported.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001442
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001443 It is output as CBOR major type 3, a text string, with tag
1444 @ref CBOR_TAG_MIME indicating the text string is MIME data.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001445 */
1446static void QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx, UsefulBufC MIMEData);
1447
1448static void QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC MIMEData);
1449
1450static void QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC MIMEData);
1451
1452
1453/**
1454 @brief Add an RFC 3339 date string
1455
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001456 @param[in] pCtx The encoding context to add the simple value to.
1457 @param[in] szDate Null-terminated string with date to add.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001458
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001459 The string szDate should be in the form of [RFC 3339]
1460 (https://tools.ietf.org/html/rfc3339) as defined by section 3.3 in
1461 [RFC 4287] (https://tools.ietf.org/html/rfc4287). This is as
1462 described in section 2.4.1 in [RFC 7049]
1463 (https://tools.ietf.org/html/rfc7049).
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001464
1465 Note that this function doesn't validate the format of the date string
1466 at all. If you add an incorrect format date string, the generated
1467 CBOR will be incorrect and the receiver may not be able to handle it.
1468
1469 Error handling is the same as QCBOREncode_AddInt64().
1470 */
1471static void QCBOREncode_AddDateString(QCBOREncodeContext *pCtx, const char *szDate);
1472
1473static void QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szDate);
1474
1475static void QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szDate);
1476
1477
1478/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001479 @brief Add a standard Boolean.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001480
1481 @param[in] pCtx The encoding context to add the simple value to.
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001482 @param[in] b true or false from @c <stdbool.h>. Anything will result in an error.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001483
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001484 Adds a Boolean value as CBOR major type 7.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001485
1486 Error handling is the same as QCBOREncode_AddInt64().
1487 */
1488static void QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b);
1489
1490static void QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b);
1491
1492static void QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b);
1493
1494
1495
1496/**
1497 @brief Add a NULL to the encoded output.
1498
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001499 @param[in] pCtx The encoding context to add the simple value to.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001500
1501 Adds the NULL value as CBOR major type 7.
1502
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001503 This NULL doesn't have any special meaning in CBOR such as a
1504 terminating value for a string or an empty value.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001505
1506 Error handling is the same as QCBOREncode_AddInt64().
1507 */
1508static void QCBOREncode_AddNULL(QCBOREncodeContext *pCtx);
1509
1510static void QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1511
1512static void QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1513
1514
1515/**
1516 @brief Add an "undef" to the encoded output.
1517
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001518 @param[in] pCtx The encoding context to add the simple value to.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001519
1520 Adds the undef value as CBOR major type 7.
1521
1522 Note that this value will not translate to JSON.
1523
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001524 This Undef doesn't have any special meaning in CBOR such as a
1525 terminating value for a string or an empty value.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001526
1527 Error handling is the same as QCBOREncode_AddInt64().
1528 */
1529static void QCBOREncode_AddUndef(QCBOREncodeContext *pCtx);
1530
1531static void QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1532
1533static void QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1534
1535
1536/**
1537 @brief Indicates that the next items added are in an array.
1538
1539 @param[in] pCtx The encoding context to open the array in.
1540
1541 Arrays are the basic CBOR aggregate or structure type. Call this
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001542 function to start or open an array. Then call the various @c
1543 QCBOREncode_AddXxx() functions to add the items that go into the
1544 array. Then call QCBOREncode_CloseArray() when all items have been
1545 added. The data items in the array can be of any type and can be of
1546 mixed types.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001547
1548 Nesting of arrays and maps is allowed and supported just by calling
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001549 QCBOREncode_OpenArray() again before calling
1550 QCBOREncode_CloseArray(). While CBOR has no limit on nesting, this
1551 implementation does in order to keep it smaller and simpler. The
1552 limit is @ref QCBOR_MAX_ARRAY_NESTING. This is the max number of
1553 times this can be called without calling
1554 QCBOREncode_CloseArray(). QCBOREncode_Finish() will return @ref
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001555 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP when it is called as this function
1556 just sets an error state and returns no value when this occurs.
1557
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001558 If you try to add more than @ref QCBOR_MAX_ITEMS_IN_ARRAY items to a
1559 single array or map, @ref QCBOR_ERR_ARRAY_TOO_LONG will be returned
1560 when QCBOREncode_Finish() is called.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001561
1562 An array itself must have a label if it is being added to a map.
1563 Note that array elements do not have labels (but map elements do).
1564
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001565 An array itself may be tagged by calling QCBOREncode_AddTag() before this call.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001566 */
1567static void QCBOREncode_OpenArray(QCBOREncodeContext *pCtx);
1568
1569static void QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1570
1571static void QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1572
1573
1574/**
1575 @brief Close an open array.
1576
1577 @param[in] pCtx The context to add to.
1578
1579 The closes an array opened by QCBOREncode_OpenArray(). It reduces
1580 nesting level by one. All arrays (and maps) must be closed before
1581 calling QCBOREncode_Finish().
1582
1583 When an error occurs as a result of this call, the encoder records
1584 the error and enters the error state. The error will be returned when
1585 QCBOREncode_Finish() is called.
1586
1587 If this has been called more times than QCBOREncode_OpenArray(), then
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001588 @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when QCBOREncode_Finish()
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001589 is called.
1590
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001591 If this is called and it is not an array that is currently open, @ref
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001592 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
1593 is called.
1594 */
1595static void QCBOREncode_CloseArray(QCBOREncodeContext *pCtx);
1596
1597
1598/**
1599 @brief Indicates that the next items added are in a map.
1600
1601 @param[in] pCtx The context to add to.
1602
1603 See QCBOREncode_OpenArray() for more information, particularly error
1604 handling.
1605
1606 CBOR maps are an aggregate type where each item in the map consists
1607 of a label and a value. They are similar to JSON objects.
1608
1609 The value can be any CBOR type including another map.
1610
1611 The label can also be any CBOR type, but in practice they are
1612 typically, integers as this gives the most compact output. They might
1613 also be text strings which gives readability and translation to JSON.
1614
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001615 Every @c QCBOREncode_AddXxx() call has one version that ends with @c
1616 InMap for adding items to maps with string labels and one that ends
1617 with @c InMapN that is for adding with integer labels.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001618
1619 RFC 7049 uses the term "key" instead of "label".
1620
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001621 If you wish to use map labels that are neither integer labels nor
1622 text strings, then just call the QCBOREncode_AddXxx() function
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001623 explicitly to add the label. Then call it again to add the value.
1624
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001625 See the [RFC 7049] (https://tools.ietf.org/html/rfc7049) for a lot
1626 more information on creating maps.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001627 */
1628static void QCBOREncode_OpenMap(QCBOREncodeContext *pCtx);
1629
1630static void QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1631
1632static void QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1633
1634
1635
1636/**
1637 @brief Close an open map.
1638
1639 @param[in] pCtx The context to add to.
1640
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001641 This closes a map opened by QCBOREncode_OpenMap(). It reduces nesting
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001642 level by one.
1643
1644 When an error occurs as a result of this call, the encoder records
1645 the error and enters the error state. The error will be returned when
1646 QCBOREncode_Finish() is called.
1647
1648 If this has been called more times than QCBOREncode_OpenMap(),
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001649 then @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001650 QCBOREncode_Finish() is called.
1651
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001652 If this is called and it is not a map that is currently open, @ref
1653 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001654 is called.
1655 */
1656static void QCBOREncode_CloseMap(QCBOREncodeContext *pCtx);
1657
1658
1659/**
1660 @brief Indicate start of encoded CBOR to be wrapped in a bstr.
1661
1662 @param[in] pCtx The context to add to.
1663
1664 All added encoded items between this call and a call to
1665 QCBOREncode_CloseBstrWrap() will be wrapped in a bstr. They will
1666 appear in the final output as a byte string. That byte string will
1667 contain encoded CBOR.
1668
1669 The typical use case is for encoded CBOR that is to be
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001670 cryptographically hashed, as part of a [RFC 8152, COSE]
1671 (https://tools.ietf.org/html/rfc8152) implementation. This avoids
1672 having to encode the items first in one buffer (e.g., the COSE
1673 payload) and then add that buffer as a bstr to another encoding
1674 (e.g. the COSE to-be-signed bytes, the @c Sig_structure) potentially
1675 saving a lot of memory.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001676
1677 When constructing cryptographically signed CBOR objects, maps or
1678 arrays, they typically are encoded normally and then wrapped as a
1679 byte string. The COSE standard for example does this. The wrapping is
1680 simply treating the encoded CBOR map as a byte string.
1681
1682 The stated purpose of this wrapping is to prevent code relaying the
1683 signed data but not verifying it from tampering with the signed data
1684 thus making the signature unverifiable. It is also quite beneficial
1685 for the signature verification code. Standard CBOR parsers usually do
1686 not give access to partially parsed CBOR as would be need to check
1687 the signature of some CBOR. With this wrapping, standard CBOR parsers
1688 can be used to get to all the data needed for a signature
1689 verification.
1690 */
1691static void QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx);
1692
1693static void QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1694
1695static void QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1696
1697
1698/**
1699 @brief Close a wrapping bstr.
1700
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001701 @param[in] pCtx The context to add to.
1702 @param[out] pWrappedCBOR A @ref UsefulBufC containing wrapped bytes.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001703
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001704 The closes a wrapping bstr opened by QCBOREncode_CloseBstrWrap(). It reduces
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001705 nesting level by one.
1706
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001707 A pointer and length of the enclosed encoded CBOR is returned in @c
1708 *pWrappedCBOR if it is not @c NULL. The main purpose of this is so
1709 this data can be hashed (e.g., with SHA-256) as part of a [RFC 8152,
1710 COSE] (https://tools.ietf.org/html/rfc8152)
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001711 implementation. **WARNING**, this pointer and length should be used
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001712 right away before any other calls to @c QCBOREncode_Xxx() as they
1713 will move data around and the pointer and length will no longer be to
1714 the correct encoded CBOR.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001715
1716 When an error occurs as a result of this call, the encoder records
1717 the error and enters the error state. The error will be returned when
1718 QCBOREncode_Finish() is called.
1719
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001720 If this has been called more times than QCBOREncode_BstrWrap(),
1721 then @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001722 QCBOREncode_Finish() is called.
1723
1724 If this is called and it is not a wrapping bstr that is currently
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001725 open, @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
1726 QCBOREncode_Finish() is called.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001727 */
1728static void QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR);
1729
1730
1731/**
1732 @brief Add some already-encoded CBOR bytes.
1733
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001734 @param[in] pCtx The context to add to.
1735 @param[in] Encoded The already-encoded CBOR to add to the context.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001736
1737 The encoded CBOR being added must be fully conforming CBOR. It must
1738 be complete with no arrays or maps that are incomplete. While this
1739 encoder doesn't ever produce indefinite lengths, it is OK for the
1740 raw CBOR added here to have indefinite lengths.
1741
1742 The raw CBOR added here is not checked in anyway. If it is not
1743 conforming or has open arrays or such, the final encoded CBOR
1744 will probably be wrong or not what was intended.
1745
1746 If the encoded CBOR being added here contains multiple items, they
1747 must be enclosed in a map or array. At the top level the raw
1748 CBOR must be a single data item.
1749 */
1750static void QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded);
1751
1752static void QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded);
1753
1754static void QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded);
1755
1756
1757/**
1758 @brief Get the encoded result.
1759
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001760 @param[in] pCtx The context to finish encoding with.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001761 @param[out] pEncodedCBOR Pointer and length of encoded CBOR.
1762
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001763 @retval QCBOR_ERR_TOO_MANY_CLOSES Nesting error
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001764
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001765 @retval QCBOR_ERR_CLOSE_MISMATCH Nesting error
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001766
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001767 @retval QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN Nesting error
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001768
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001769 @retval QCBOR_ERR_BUFFER_TOO_LARGE Encoded output buffer size
1770
1771 @retval QCBOR_ERR_BUFFER_TOO_SMALL Encoded output buffer size
1772
1773 @retval QCBOR_ERR_ARRAY_NESTING_TOO_DEEP Implementation limit
1774
1775 @retval QCBOR_ERR_ARRAY_TOO_LONG Implementation limit
1776
1777 If this returns success @ref QCBOR_SUCCESS the encoding was a success
1778 and the return length is correct and complete.
1779
1780 If no buffer was passed to QCBOREncode_Init(), then only the length
1781 was computed. If a buffer was passed, then the encoded CBOR is in the
1782 buffer.
1783
1784 All encoding errors manifest here as no other encoding function
1785 returns any errors. They just set the error state in the encode
1786 context after which no encoding function does anything.
1787
1788 Three types of errors manifest here. The first type are nesting
1789 errors where the number of @c QCBOREncode_OpenXxx() calls do not
1790 match the number @c QCBOREncode_CloseXxx() calls. The solution is to
1791 fix the calling code.
1792
1793 The second type of error is because the buffer given is either too
1794 small or too large. The remedy is to give a correctly sized buffer.
1795
1796 The third type are due to limits in this implementation. @ref
1797 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP can be worked around by encoding the
1798 CBOR in two (or more) phases and adding the CBOR from the first phase
1799 to the second with @c QCBOREncode_AddEncoded().
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001800
1801 If an error is returned, the buffer may have partially encoded
1802 incorrect CBOR in it and it should not be used. Likewise, the length
1803 may be incorrect and should not be used.
1804
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001805 Note that the error could have occurred in one of the many @c
1806 QCBOREncode_AddXxx() calls long before QCBOREncode_Finish() was
1807 called. This error handling reduces the CBOR implementation size but
1808 makes debugging harder.
1809
1810 This may be called multiple times. It will always return the same. It
1811 can also be interleaved with calls to QCBOREncode_FinishGetSize().
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001812 */
1813QCBORError QCBOREncode_Finish(QCBOREncodeContext *pCtx, UsefulBufC *pEncodedCBOR);
1814
1815
1816/**
1817 @brief Get the encoded CBOR and error status.
1818
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001819 @param[in] pCtx The context to finish encoding with.
1820 @param[out] uEncodedLen The length of the encoded or potentially
1821 encoded CBOR in bytes.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001822
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001823 @return The same errors as QCBOREncode_Finish().
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001824
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001825 This functions the same as QCBOREncode_Finish(), but only returns the
1826 size of the encoded output.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001827 */
1828QCBORError QCBOREncode_FinishGetSize(QCBOREncodeContext *pCtx, size_t *uEncodedLen);
1829
1830
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001831/**
1832 @brief Indicate whether output buffer is NULL or not.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001833
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001834 @param[in] pCtx The encoding ontext.
1835
1836 @return 1 if the output buffer is @c NULL.
1837
1838 Sometimes a @c NULL input buffer is given to QCBOREncode_Init() so
1839 that the size of the generated CBOR can be calculated without
1840 allocating a buffer for it. This returns 1 when the output buffer is
1841 NULL and 0 when it is not.
1842*/
1843static int QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx);
1844
1845 /**
1846 @brief Get the encoding error state.
1847
1848 @param[in] pCtx The encoding ontext.
1849
1850 @return One of \ref QCBORError. See return values from
1851 QCBOREncode_Finish()
1852
1853 Normally encoding errors need only be handled at the end of encoding
1854 when QCBOREncode_Finish() is called. This can be called to get the
1855 error result before finish should there be a need to halt encoding
1856 before QCBOREncode_Finish(). is called.
1857*/
1858static QCBORError QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx);
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001859
1860
1861
1862/**
1863 QCBORDecodeContext is the data type that holds context decoding the
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001864 data items for some received CBOR. It is about 100 bytes, so it can
1865 go on the stack. The contents are opaque, and the caller should not
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001866 access any internal items. A context may be re used serially as long
1867 as it is re initialized.
1868 */
1869typedef struct _QCBORDecodeContext QCBORDecodeContext;
1870
1871
1872/**
1873 Initialize the CBOR decoder context.
1874
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001875 @param[in] pCtx The context to initialize.
1876 @param[in] EncodedCBOR The buffer with CBOR encoded bytes to be decoded.
1877 @param[in] nMode See below and @ref QCBORDecodeMode.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001878
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001879 Initialize context for a pre-order traversal of the encoded CBOR
1880 tree.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001881
1882 Most CBOR decoding can be completed by calling this function to start
1883 and QCBORDecode_GetNext() in a loop.
1884
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001885 If indefinite-length strings are to be decoded, then
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001886 QCBORDecode_SetMemPool() or QCBORDecode_SetUpAllocator() must be
1887 called to set up a string allocator.
1888
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001889 If tags other than built-in tags are to be recognized and recorded in
1890 @c uTagBits, then QCBORDecode_SetCallerConfiguredTagList() must be
1891 called. The built-in tags are those for which a macro of the form @c
1892 CBOR_TAG_XXX is defined.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001893
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001894 Three decoding modes are supported. In normal mode, @ref
1895 QCBOR_DECODE_MODE_NORMAL, maps are decoded and strings and integers
1896 are accepted as map labels. If a label is other than these, the error
1897 @ref QCBOR_ERR_MAP_LABEL_TYPE is returned by QCBORDecode_GetNext().
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001898
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001899 In strings-only mode, @ref QCBOR_DECODE_MODE_MAP_STRINGS_ONLY, only
1900 text strings are accepted for map labels. This lines up with CBOR
1901 that converts to JSON. The error @ref QCBOR_ERR_MAP_LABEL_TYPE is
1902 returned by QCBORDecode_GetNext() if anything but a text string label
1903 is encountered.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001904
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001905 In @ref QCBOR_DECODE_MODE_MAP_AS_ARRAY maps are treated as special
1906 arrays. They will be return with special @c uDataType @ref
1907 QCBOR_TYPE_MAP_AS_ARRAY and @c uCount, the number of items, will be
1908 double what it would be for a normal map because the labels are also
1909 counted. This mode is useful for decoding CBOR that has labels that
1910 are not integers or text strings, but the caller must manage much of
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001911 the map decoding.
1912 */
1913void QCBORDecode_Init(QCBORDecodeContext *pCtx, UsefulBufC EncodedCBOR, QCBORDecodeMode nMode);
1914
1915
1916/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001917 @brief Set up the MemPool string allocator for indefinite-length strings.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001918
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001919 @param[in] pCtx The decode context.
1920 @param[in] MemPool The pointer and length of the memory pool.
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001921 @param[in] bAllStrings If true, all strings, even of definite
1922 length, will be allocated with the string
1923 allocator.
1924
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001925 @return Error if the MemPool was less than @ref QCBOR_DECODE_MIN_MEM_POOL_SIZE.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001926
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001927 indefinite-length strings (text and byte) cannot be decoded unless
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001928 there is a string allocator configured. MemPool is a simple built-in
1929 string allocator that allocates bytes from a memory pool handed to it
1930 by calling this function. The memory pool is just a pointer and
1931 length for some block of memory that is to be used for string
1932 allocation. It can come from the stack, heap or other.
1933
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001934 The memory pool must be @ref QCBOR_DECODE_MIN_MEM_POOL_SIZE plus
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001935 space for all the strings allocated. There is no overhead per string
1936 allocated. A conservative way to size this buffer is to make it the
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001937 same size as the CBOR being decoded plus @ref
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001938 QCBOR_DECODE_MIN_MEM_POOL_SIZE.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001939
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001940 This memory pool is used for all indefinite-length strings that are
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001941 text strings or byte strings, including strings used as labels.
1942
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001943 The pointers to strings in @ref QCBORItem will point into the memory
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001944 pool set here. They do not need to be individually freed. Just
1945 discard the buffer when they are no longer needed.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001946
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001947 If @c bAllStrings is set, then the size will be the overhead plus the
1948 space to hold **all** strings, definite and indefinite-length, value
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001949 or label. The advantage of this is that after the decode is complete,
1950 the original memory holding the encoded CBOR does not need to remain
1951 valid.
1952
1953 If this function is never called because there is no need to support
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001954 indefinite-length strings, the internal MemPool implementation should
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001955 be dead-stripped by the loader and not add to code size.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001956 */
1957QCBORError QCBORDecode_SetMemPool(QCBORDecodeContext *pCtx, UsefulBuf MemPool, bool bAllStrings);
1958
1959
1960/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001961 @brief Sets up a custom string allocator for indefinite-length strings
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001962
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001963 @param[in] pCtx The decoder context to set up an
1964 allocator for.
1965 @param[in] pfAllocateFunction Pointer to function that will be
1966 called by QCBOR for allocations and
1967 frees.
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001968 @param[in] pAllocateContext Context passed to @c
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001969 pfAllocateFunction.
1970 @param[in] bAllStrings If true, all strings, even of definite
1971 length, will be allocated with the
1972 string allocator.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001973
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001974 indefinite-length strings (text and byte) cannot be decoded unless
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001975 there a string allocator is configured. QCBORDecode_SetUpAllocator()
1976 allows the caller to configure an external string allocator
1977 implementation if the internal string allocator is not suitable. See
1978 QCBORDecode_SetMemPool() to configure the internal allocator. Note
1979 that the internal allocator is not automatically set up.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001980
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001981 The string allocator configured here can be a custom one designed and
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001982 implemented by the caller. See @ref QCBORStringAllocate for the
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001983 requirements for a string allocator implementation.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001984
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001985 A malloc-based string external allocator can be obtained by calling
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001986 @c QCBORDecode_MakeMallocStringAllocator(). It will return a function
1987 and pointer that can be given here as @c pAllocatorFunction and @c
1988 pAllocatorContext. It uses standard @c malloc() so @c free() must be
1989 called on all strings marked by @c uDataAlloc @c == @c 1 or @c
1990 uLabelAlloc @c == @c 1 in @ref QCBORItem.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001991
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001992 Note that an older version of this function took an allocator
1993 structure, rather than single function and pointer. The older
Laurence Lundblade852a33c2019-06-11 09:00:07 -07001994 version @c QCBORDecode_MakeMallocStringAllocator() also implemented
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001995 the older interface.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001996 */
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001997void QCBORDecode_SetUpAllocator(QCBORDecodeContext *pCtx,
1998 QCBORStringAllocate pfAllocateFunction,
1999 void *pAllocateContext,
2000 bool bAllStrings);
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002001
2002/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002003 @brief Configure list of caller-selected tags to be recognized.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002004
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002005 @param[in] pCtx The decode context.
2006 @param[out] pTagList Structure holding the list of tags to configure.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002007
2008 This is used to tell the decoder about tags beyond those that are
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002009 built-in that should be recognized. The built-in tags are those with
2010 macros of the form @c CBOR_TAG_XXX.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002011
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002012 The list pointed to by @c pTagList must persist during decoding. No
2013 copy of it is made.
2014
2015 The maximum number of tags that can be added is @ref
2016 QCBOR_MAX_CUSTOM_TAGS. If a list larger than this is given, the
2017 error will be returned when QCBORDecode_GetNext() is called, not
2018 here.
2019
2020 See description of @ref QCBORTagListIn.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002021 */
2022void QCBORDecode_SetCallerConfiguredTagList(QCBORDecodeContext *pCtx, const QCBORTagListIn *pTagList);
2023
2024
2025/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002026 @brief Gets the next item (integer, byte string, array...) in
2027 preorder traversal of CBOR tree.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002028
2029 @param[in] pCtx The decoder context.
2030 @param[out] pDecodedItem Holds the CBOR item just decoded.
2031
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002032 @retval QCBOR_ERR_INDEFINITE_STRING_CHUNK Not well-formed, one of the
2033 chunks in indefinite-length
2034 string is wrong type.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002035
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002036 @retval QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN Not well-formed, array or map
2037 not closed.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002038
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002039 @retval QCBOR_ERR_UNSUPPORTED Not well-formed, input contains
2040 unsupported CBOR.
2041
2042 @retval QCBOR_ERR_HIT_END Not well-formed, unexpected ran out
2043 of bytes.
2044
2045 @retval QCBOR_ERR_BAD_TYPE_7 Not well-formed, bad simple type value.
2046
2047 @retval QCBOR_ERR_BAD_BREAK Not well-formed, break occurs where
2048 not allowed.
2049
2050 @retval QCBOR_ERR_EXTRA_BYTES Not well-formed, unprocessed bytes at
2051 the end.
2052
2053 @retval QCBOR_ERR_BAD_OPT_TAG Invalid CBOR, tag on wrong type.
2054
2055 @retval QCBOR_ERR_ARRAY_TOO_LONG Implementation limit, array or map
2056 too long.
2057
2058 @retval QCBOR_ERR_INT_OVERFLOW Implementation limit, negative
2059 integer too large.
2060
2061 @retval QCBOR_ERR_DATE_OVERFLOW Implementation limit, date larger
2062 than can be handled.
2063
2064 @retval QCBOR_ERR_ARRAY_NESTING_TOO_DEEP Implementation limit, nesting
2065 too deep.
2066
2067 @retval QCBOR_ERR_STRING_ALLOCATE Resource exhaustion, string allocator
2068 failed.
2069
2070 @retval QCBOR_ERR_MAP_LABEL_TYPE Configuration error / Implementation
2071 limit encountered a map label this is
2072 not a string on an integer.
2073
2074 @retval QCBOR_ERR_NO_STRING_ALLOCATOR Configuration error, encountered
2075 indefinite-length string with no
2076 allocator configured.
2077
2078 @c pDecodedItem is filled in with the value parsed. Generally, the
2079 following data is returned in the structure:
2080
2081 - @c uDataType which indicates which member of the @c val union the
2082 data is in. This decoder figures out the type based on the CBOR
2083 major type, the CBOR "additionalInfo", the CBOR optional tags and
2084 the value of the integer.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002085
2086 - The value of the item, which might be an integer, a pointer and a
2087 length, the count of items in an array, a floating-point number or
2088 other.
2089
2090 - The nesting level for maps and arrays.
2091
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002092 - The label for an item in a map, which may be a text or byte string
2093 or an integer.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002094
2095 - The CBOR optional tag or tags.
2096
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002097 See documentation on in the data type @ref _QCBORItem for all the
2098 details on what is returned.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002099
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002100 This function handles arrays and maps. When first encountered a @ref
2101 QCBORItem will be returned with major type @ref QCBOR_TYPE_ARRAY or
2102 @ref QCBOR_TYPE_MAP. @c QCBORItem.val.uCount will indicate the number
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002103 of Items in the array or map. Typically, an implementation will call
2104 QCBORDecode_GetNext() in a for loop to fetch them all. When decoding
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002105 indefinite-length maps and arrays, @c QCBORItem.val.uCount is @c
2106 UINT16_MAX and @c uNextNestLevel must be used to know when the end of
2107 a map or array is reached.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002108
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002109 Nesting level 0 is the outside top-most nesting level. For example,
2110 in a CBOR structure with two items, an integer and a byte string
2111 only, both would be at nesting level 0. A CBOR structure with an
2112 array open, an integer and a byte string, would have the integer and
2113 byte string as nesting level 1.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002114
2115 Here is an example of how the nesting level is reported with no arrays
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002116 or maps at all.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002117
2118 @verbatim
2119 CBOR Structure Nesting Level
2120 Integer 0
2121 Byte String 0
2122 @endverbatim
2123
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002124 Here is an example of how the nesting level is reported with a simple
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002125 array and some top-level items.
2126
2127 @verbatim
2128 Integer 0
2129 Array (with 2 items) 0
2130 Byte String 1
2131 Byte string 1
2132 Integer 0
2133 @endverbatim
2134
2135
2136 Here's a more complex example
2137 @verbatim
2138
2139 Map with 2 items 0
2140 Text string 1
2141 Array with 3 integers 1
2142 integer 2
2143 integer 2
2144 integer 2
2145 text string 1
2146 byte string 1
2147 @endverbatim
2148
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002149 In @ref _QCBORItem, @c uNextNestLevel is the nesting level for the
2150 next call to QCBORDecode_GetNext(). It indicates if any maps or
2151 arrays were closed out during the processing of the just-fetched @ref
2152 QCBORItem. This processing includes a look-ahead for any breaks that
2153 close out indefinite-length arrays or maps. This value is needed to
2154 be able to understand the hierarchical structure. If @c
2155 uNextNestLevel is not equal to @c uNestLevel the end of the current
2156 map or array has been encountered. This works the same for both
2157 definite and indefinite-length arrays.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002158
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002159 This decoder support CBOR type 6 tagging. The decoding of particular
2160 given tag value may be supported in one of three different ways.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002161
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002162 First, some common tags are fully and transparently supported by
2163 automatically decoding them and returning them in a @ref QCBORItem.
2164 These tags have a @c QCBOR_TYPE_XXX associated with them and manifest
2165 pretty much the same as a standard CBOR type. @ref
2166 QCBOR_TYPE_DATE_EPOCH and the @c epochDate member of @ref QCBORItem
2167 is an example.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002168
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002169 Second are tags that are automatically recognized, but not decoded.
2170 These are tags that have a @c \#define of the form @c CBOR_TAG_XXX.
2171 These are recorded in the @c uTagBits member of @ref QCBORItem. There
2172 is an internal table that maps each bit to a particular tag value
2173 allowing up to 64 tags on an individual item to be reported (it is
2174 rare to have more than one or two). To find out if a particular tag
2175 value is set call QCBORDecode_IsTagged() on the @ref QCBORItem. See
2176 also QCBORDecode_GetNextWithTags().
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002177
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002178 Third are tags that are not automatically recognized, because they
2179 are proprietary, custom or more recently registered with [IANA]
2180 (https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml). The
2181 internal mapping table has to be configured to recognize these. Call
2182 QCBORDecode_SetCallerConfiguredTagList() to do that. Then
2183 QCBORDecode_IsTagged() will work with them.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002184
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002185 The actual decoding of tags supported in the second and third way
2186 must be handled by the caller. Often this is simply verifying that
2187 the expected tag is present on a map, byte string or such. In other
2188 cases, there might a complicated map structure to decode.
2189
2190 See @ref Tags-Overview for a description of how to go about creating
2191 custom tags.
2192
2193 This tag decoding design is to be open-ended and flexible to be able
2194 to handle newly defined tags, while using very little memory, in
2195 particular keeping @ref QCBORItem as small as possible.
2196
2197 Errors fall in several categories as noted in list above:
2198
2199 - Not well-formed errors are those where there is something
2200 syntactically and fundamentally wrong with the CBOR being
2201 decoded. Encoding should stop completely.
2202
2203 - Invalid CBOR is well-formed, but still not correct. It is probably
2204 best to stop decoding, but not necessary.
2205
2206 - This implementation has some size limits. They should rarely be
2207 encountered. If they are it may because something is wrong with the
2208 CBOR, for example an array size is incorrect.
2209
2210 - Resource exhaustion. This only occurs when a string allocator is
2211 configured to handle indefinite-length strings as other than that,
2212 this implementation does no dynamic memory allocation.
2213
2214 - There are a few CBOR constructs that are not handled without some
2215 extra configuration. These are indefinite length strings and maps
2216 with labels that are not strings or integers. See QCBORDecode_Init().
2217
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002218 */
2219QCBORError QCBORDecode_GetNext(QCBORDecodeContext *pCtx, QCBORItem *pDecodedItem);
2220
2221
2222/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002223 @brief Gets the next item including full list of tags for item.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002224
2225 @param[in] pCtx The decoder context.
2226 @param[out] pDecodedItem Holds the CBOR item just decoded.
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002227 @param[in,out] pTagList On input array to put tags in; on output
2228 the tags on this item. See
2229 @ref QCBORTagListOut.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002230
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002231 @return See return values for QCBORDecode_GetNext().
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002232
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002233 @retval QCBOR_ERR_TOO_MANY_TAGS The size of @c pTagList is too small.
2234
2235 This works the same as QCBORDecode_GetNext() except that it also
2236 returns the full list of tags for the data item. This function should
2237 only be needed when parsing CBOR to print it out or convert it to
2238 some other format. It should not be needed to implement a CBOR-based
2239 protocol. See QCBORDecode_GetNext() for the main description of tag
2240 decoding.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002241
2242 Tags will be returned here whether or not they are in the built-in or
2243 caller-configured tag lists.
2244
2245 CBOR has no upper bound of limit on the number of tags that can be
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002246 associated with a data item though in practice the number of tags on
2247 an item will usually be small, perhaps less than five. This will
2248 return @ref QCBOR_ERR_TOO_MANY_TAGS if the array in @c pTagList is
2249 too small to hold all the tags for the item.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002250
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002251 (This function is separate from QCBORDecode_GetNext() so as to not
2252 have to make @ref QCBORItem large enough to be able to hold a full
2253 list of tags. Even a list of five tags would nearly double its size
2254 because tags can be a @c uint64_t ).
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002255 */
2256QCBORError QCBORDecode_GetNextWithTags(QCBORDecodeContext *pCtx, QCBORItem *pDecodedItem, QCBORTagListOut *pTagList);
2257
2258
2259/**
2260 @brief Determine if a CBOR item was tagged with a particular tag
2261
2262 @param[in] pCtx The decoder context.
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002263 @param[in] pItem The CBOR item to check.
2264 @param[in] uTag The tag to check, one of @c CBOR_TAG_XXX.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002265
2266 @return 1 if it was tagged, 0 if not
2267
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002268 See QCBORDecode_GetNext() for the main description of tag
2269 handling. For tags that are not fully decoded a bit corresponding to
2270 the tag is set in in @c uTagBits in the @ref QCBORItem. The
2271 particular bit depends on an internal mapping table. This function
2272 checks for set bits against the mapping table.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002273
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002274 Typically, a protocol implementation just wants to know if a
2275 particular tag is present. That is what this provides. To get the
2276 full list of tags on a data item, see QCBORDecode_GetNextWithTags().
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002277
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002278 Also see QCBORDecode_SetCallerConfiguredTagList() for the means to
2279 add new tags to the internal list so they can be checked for with
2280 this function.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002281 */
2282int QCBORDecode_IsTagged(QCBORDecodeContext *pCtx, const QCBORItem *pItem, uint64_t uTag);
2283
2284
2285/**
2286 Check whether all the bytes have been decoded and maps and arrays closed.
2287
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002288 @param[in] pCtx The context to check.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002289
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002290 @return An error or @ref QCBOR_SUCCESS.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002291
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002292 This tells you if all the bytes given to QCBORDecode_Init() have been
2293 consumed and whether all maps and arrays were closed. The decode is
2294 considered to be incorrect or incomplete if not and an error will be
2295 returned.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002296 */
2297QCBORError QCBORDecode_Finish(QCBORDecodeContext *pCtx);
2298
2299
2300
2301
2302/**
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002303 @brief Convert int64_t to smaller integers safely.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002304
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002305 @param [in] src An @c int64_t.
2306 @param [out] dest A smaller sized integer to convert to.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002307
2308 @return 0 on success -1 if not
2309
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002310 When decoding an integer, the CBOR decoder will return the value as
2311 an int64_t unless the integer is in the range of @c INT64_MAX and @c
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002312 UINT64_MAX. That is, unless the value is so large that it can only be
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002313 represented as a @c uint64_t, it will be an @c int64_t.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002314
2315 CBOR itself doesn't size the individual integers it carries at
2316 all. The only limits it puts on the major integer types is that they
2317 are 8 bytes or less in length. Then encoders like this one use the
2318 smallest number of 1, 2, 4 or 8 bytes to represent the integer based
2319 on its value. There is thus no notion that one data item in CBOR is
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002320 a 1-byte integer and another is a 4-byte integer.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002321
2322 The interface to this CBOR encoder only uses 64-bit integers. Some
2323 CBOR protocols or implementations of CBOR protocols may not want to
2324 work with something smaller than a 64-bit integer. Perhaps an array
2325 of 1000 integers needs to be sent and none has a value larger than
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002326 50,000 and are represented as @c uint16_t.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002327
2328 The sending / encoding side is easy. Integers are temporarily widened
2329 to 64-bits as a parameter passing through QCBOREncode_AddInt64() and
2330 encoded in the smallest way possible for their value, possibly in
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002331 less than an @c uint16_t.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002332
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002333 On the decoding side the integers will be returned at @c int64_t even if
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002334 they are small and were represented by only 1 or 2 bytes in the
2335 encoded CBOR. The functions here will convert integers to a small
2336 representation with an overflow check.
2337
2338 (The decoder could have support 8 different integer types and
2339 represented the integer with the smallest type automatically, but
2340 this would have made the decoder more complex and code calling the
2341 decoder more complex in most use cases. In most use cases on 64-bit
2342 machines it is no burden to carry around even small integers as
2343 64-bit values).
2344 */
2345static inline int QCBOR_Int64ToInt32(int64_t src, int32_t *dest)
2346{
2347 if(src > INT32_MAX || src < INT32_MIN) {
2348 return -1;
2349 } else {
2350 *dest = (int32_t) src;
2351 }
2352 return 0;
2353}
2354
2355static inline int QCBOR_Int64ToInt16(int64_t src, int16_t *dest)
2356{
2357 if(src > INT16_MAX || src < INT16_MIN) {
2358 return -1;
2359 } else {
2360 *dest = (int16_t) src;
2361 }
2362 return 0;
2363}
2364
2365static inline int QCBOR_Int64ToInt8(int64_t src, int8_t *dest)
2366{
2367 if(src > INT8_MAX || src < INT8_MIN) {
2368 return -1;
2369 } else {
2370 *dest = (int8_t) src;
2371 }
2372 return 0;
2373}
2374
2375static inline int QCBOR_Int64ToUInt32(int64_t src, uint32_t *dest)
2376{
2377 if(src > UINT32_MAX || src < 0) {
2378 return -1;
2379 } else {
2380 *dest = (uint32_t) src;
2381 }
2382 return 0;
2383}
2384
2385static inline int QCBOR_Int64UToInt16(int64_t src, uint16_t *dest)
2386{
2387 if(src > UINT16_MAX || src < 0) {
2388 return -1;
2389 } else {
2390 *dest = (uint16_t) src;
2391 }
2392 return 0;
2393}
2394
2395static inline int QCBOR_Int64ToUInt8(int64_t src, uint8_t *dest)
2396{
2397 if(src > UINT8_MAX || src < 0) {
2398 return -1;
2399 } else {
2400 *dest = (uint8_t) src;
2401 }
2402 return 0;
2403}
2404
2405static inline int QCBOR_Int64ToUInt64(int64_t src, uint64_t *dest)
2406{
2407 if(src > 0) {
2408 return -1;
2409 } else {
2410 *dest = (uint64_t) src;
2411 }
2412 return 0;
2413}
2414
2415
2416
2417
2418
2419/* ===========================================================================
2420 BEGINNING OF PRIVATE INLINE IMPLEMENTATION
2421
2422 =========================================================================== */
2423
2424/**
2425 @brief Semi-private method to add a buffer full of bytes to encoded output
2426
2427 @param[in] pCtx The encoding context to add the integer to.
2428 @param[in] uMajorType The CBOR major type of the bytes.
2429 @param[in] Bytes The bytes to add.
2430
2431 Use QCBOREncode_AddText() or QCBOREncode_AddBytes() or
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002432 QCBOREncode_AddEncoded() instead. They are inline functions that call
2433 this and supply the correct major type. This function is public to
2434 make the inline functions work to keep the overall code size down and
2435 because the C language has no way to make it private.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002436
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002437 If this is called the major type should be @c
2438 CBOR_MAJOR_TYPE_TEXT_STRING, @c CBOR_MAJOR_TYPE_BYTE_STRING or @c
2439 CBOR_MAJOR_NONE_TYPE_RAW. The last one is special for adding
2440 already-encoded CBOR.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002441 */
2442void QCBOREncode_AddBuffer(QCBOREncodeContext *pCtx, uint8_t uMajorType, UsefulBufC Bytes);
2443
2444
2445/**
2446 @brief Semi-private method to open a map, array or bstr wrapped CBOR
2447
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002448 @param[in] pCtx The context to add to.
2449 @param[in] uMajorType The major CBOR type to close
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002450
2451 Call QCBOREncode_OpenArray(), QCBOREncode_OpenMap() or
2452 QCBOREncode_BstrWrap() instead of this.
2453 */
2454void QCBOREncode_OpenMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType);
2455
2456
2457/**
2458 @brief Semi-private method to close a map, array or bstr wrapped CBOR
2459
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002460 @param[in] pCtx The context to add to.
2461 @param[in] uMajorType The major CBOR type to close.
2462 @param[out] pWrappedCBOR Pointer to @ref UsefulBufC containing wrapped bytes.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002463
2464 Call QCBOREncode_CloseArray(), QCBOREncode_CloseMap() or
2465 QCBOREncode_CloseBstrWrap() instead of this.
2466 */
2467void QCBOREncode_CloseMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType, UsefulBufC *pWrappedCBOR);
2468
2469
2470/**
2471 @brief Semi-private method to add simple types.
2472
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002473 @param[in] pCtx The encoding context to add the simple value to.
2474 @param[in] uSize Minimum encoding size for uNum. Usually 0.
2475 @param[in] uNum One of CBOR_SIMPLEV_FALSE through _UNDEF or other.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002476
2477 This is used to add simple types like true and false.
2478
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002479 Call QCBOREncode_AddBool(), QCBOREncode_AddNULL(),
2480 QCBOREncode_AddUndef() instead of this.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002481
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002482 This function can add simple values that are not defined by CBOR
2483 yet. This expansion point in CBOR should not be used unless they are
2484 standardized.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002485
2486 Error handling is the same as QCBOREncode_AddInt64().
2487 */
2488void QCBOREncode_AddType7(QCBOREncodeContext *pCtx, size_t uSize, uint64_t uNum);
2489
2490
Laurence Lundbladec93b5a72019-04-06 12:17:16 -07002491/**
2492 @brief Semi-private method to add only the type and length of a byte string.
2493
2494 @param[in] pCtx The context to initialize.
2495 @param[in] Bytes Pointer and length of the input data.
2496
2497 This is the same as QCBOREncode_AddBytes() except it only adds the
2498 CBOR encoding for the type and the length. It doesn't actually add
2499 the bytes. You can't actually produce correct CBOR with this and the
2500 rest of this API. It is only used for a special case where
2501 the valid CBOR is created manually by putting this type and length in
2502 and then adding the actual bytes. In particular, when only a hash of
2503 the encoded CBOR is needed, where the type and header are hashed
2504 separately and then the bytes is hashed. This makes it possible to
2505 implement COSE Sign1 with only one copy of the payload in the output
2506 buffer, rather than two, roughly cutting memory use in half.
2507
2508 This is only used for this odd case, but this is a supported
2509 tested function.
2510*/
2511static inline void QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
2512
2513static inline void QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
2514
2515static inline void QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
2516
2517
2518
2519
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002520static inline void QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum)
2521{
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002522 // Use _AddBuffer() because _AddSZString() is defined below, not above
2523 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002524 QCBOREncode_AddInt64(pCtx, uNum);
2525}
2526
2527static inline void QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum)
2528{
2529 QCBOREncode_AddInt64(pCtx, nLabel);
2530 QCBOREncode_AddInt64(pCtx, uNum);
2531}
2532
2533
2534static inline void QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum)
2535{
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002536 // Use _AddBuffer() because _AddSZString() is defined below, not above
2537 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002538 QCBOREncode_AddUInt64(pCtx, uNum);
2539}
2540
2541static inline void QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum)
2542{
2543 QCBOREncode_AddInt64(pCtx, nLabel);
2544 QCBOREncode_AddUInt64(pCtx, uNum);
2545}
2546
2547
2548static inline void QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text)
2549{
2550 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, Text);
2551}
2552
2553static inline void QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text)
2554{
Laurence Lundblade852a33c2019-06-11 09:00:07 -07002555 // Use _AddBuffer() because _AddSZString() is defined below, not above
2556 QCBOREncode_AddText(pCtx, UsefulBuf_FromSZ(szLabel));
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002557 QCBOREncode_AddText(pCtx, Text);
2558}
2559
2560static inline void QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text)
2561{
2562 QCBOREncode_AddInt64(pCtx, nLabel);
2563 QCBOREncode_AddText(pCtx, Text);
2564}
2565
2566
2567inline static void QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString)
2568{
2569 QCBOREncode_AddText(pCtx, UsefulBuf_FromSZ(szString));
2570}
2571
2572static inline void QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString)
2573{
2574 QCBOREncode_AddSZString(pCtx, szLabel);
2575 QCBOREncode_AddSZString(pCtx, szString);
2576}
2577
2578static inline void QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString)
2579{
2580 QCBOREncode_AddInt64(pCtx, nLabel);
2581 QCBOREncode_AddSZString(pCtx, szString);
2582}
2583
2584
2585static inline void QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum)
2586{
2587 QCBOREncode_AddSZString(pCtx, szLabel);
2588 QCBOREncode_AddDouble(pCtx, dNum);
2589}
2590
2591static inline void QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum)
2592{
2593 QCBOREncode_AddInt64(pCtx, nLabel);
2594 QCBOREncode_AddDouble(pCtx, dNum);
2595}
2596
2597
2598static inline void QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx, int64_t date)
2599{
2600 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_EPOCH);
2601 QCBOREncode_AddInt64(pCtx, date);
2602}
2603
2604static inline void QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t date)
2605{
2606 QCBOREncode_AddSZString(pCtx, szLabel);
2607 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_EPOCH);
2608 QCBOREncode_AddInt64(pCtx, date);
2609}
2610
2611static inline void QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t date)
2612{
2613 QCBOREncode_AddInt64(pCtx, nLabel);
2614 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_EPOCH);
2615 QCBOREncode_AddInt64(pCtx, date);
2616}
2617
2618
2619static inline void QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
2620{
2621 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes);
2622}
2623
2624static inline void QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
2625{
2626 QCBOREncode_AddSZString(pCtx, szLabel);
2627 QCBOREncode_AddBytes(pCtx, Bytes);
2628}
2629
2630static inline void QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
2631{
2632 QCBOREncode_AddInt64(pCtx, nLabel);
2633 QCBOREncode_AddBytes(pCtx, Bytes);
2634}
2635
Laurence Lundbladec93b5a72019-04-06 12:17:16 -07002636static inline void QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
2637{
2638 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY, Bytes);
2639}
2640
2641static inline void QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
2642{
2643 QCBOREncode_AddSZString(pCtx, szLabel);
2644 QCBOREncode_AddBytesLenOnly(pCtx, Bytes);
2645}
2646
2647static inline void QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
2648{
2649 QCBOREncode_AddInt64(pCtx, nLabel);
2650 QCBOREncode_AddBytesLenOnly(pCtx, Bytes);
2651}
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002652
2653static inline void QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
2654{
2655 QCBOREncode_AddTag(pCtx, CBOR_TAG_BIN_UUID);
2656 QCBOREncode_AddBytes(pCtx, Bytes);
2657}
2658
2659static inline void QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
2660{
2661 QCBOREncode_AddSZString(pCtx, szLabel);
2662 QCBOREncode_AddTag(pCtx, CBOR_TAG_BIN_UUID);
2663 QCBOREncode_AddBytes(pCtx, Bytes);
2664}
2665
2666static inline void QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
2667{
2668 QCBOREncode_AddInt64(pCtx, nLabel);
2669 QCBOREncode_AddTag(pCtx, CBOR_TAG_BIN_UUID);
2670 QCBOREncode_AddBytes(pCtx, Bytes);
2671}
2672
2673
2674static inline void QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
2675{
2676 QCBOREncode_AddTag(pCtx, CBOR_TAG_POS_BIGNUM);
2677 QCBOREncode_AddBytes(pCtx, Bytes);
2678}
2679
2680static inline void QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
2681{
2682 QCBOREncode_AddSZString(pCtx, szLabel);
2683 QCBOREncode_AddTag(pCtx, CBOR_TAG_POS_BIGNUM);
2684 QCBOREncode_AddBytes(pCtx, Bytes);
2685}
2686
2687static inline void QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
2688{
2689 QCBOREncode_AddInt64(pCtx, nLabel);
2690 QCBOREncode_AddTag(pCtx, CBOR_TAG_POS_BIGNUM);
2691 QCBOREncode_AddBytes(pCtx, Bytes);
2692}
2693
2694
2695static inline void QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
2696{
2697 QCBOREncode_AddTag(pCtx, CBOR_TAG_NEG_BIGNUM);
2698 QCBOREncode_AddBytes(pCtx, Bytes);
2699}
2700
2701static inline void QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
2702{
2703 QCBOREncode_AddSZString(pCtx, szLabel);
2704 QCBOREncode_AddTag(pCtx, CBOR_TAG_NEG_BIGNUM);
2705 QCBOREncode_AddBytes(pCtx, Bytes);
2706}
2707
2708static inline void QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
2709{
2710 QCBOREncode_AddInt64(pCtx, nLabel);
2711 QCBOREncode_AddTag(pCtx, CBOR_TAG_NEG_BIGNUM);
2712 QCBOREncode_AddBytes(pCtx, Bytes);
2713}
2714
2715
2716static inline void QCBOREncode_AddURI(QCBOREncodeContext *pCtx, UsefulBufC URI)
2717{
2718 QCBOREncode_AddTag(pCtx, CBOR_TAG_URI);
2719 QCBOREncode_AddText(pCtx, URI);
2720}
2721
2722static inline void QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC URI)
2723{
2724 QCBOREncode_AddSZString(pCtx, szLabel);
2725 QCBOREncode_AddTag(pCtx, CBOR_TAG_URI);
2726 QCBOREncode_AddText(pCtx, URI);
2727}
2728
2729static inline void QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC URI)
2730{
2731 QCBOREncode_AddInt64(pCtx, nLabel);
2732 QCBOREncode_AddTag(pCtx, CBOR_TAG_URI);
2733 QCBOREncode_AddText(pCtx, URI);
2734}
2735
2736
2737
2738static inline void QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx, UsefulBufC B64Text)
2739{
2740 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64);
2741 QCBOREncode_AddText(pCtx, B64Text);
2742}
2743
2744static inline void QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text)
2745{
2746 QCBOREncode_AddSZString(pCtx, szLabel);
2747 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64);
2748 QCBOREncode_AddText(pCtx, B64Text);
2749}
2750
2751static inline void QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text)
2752{
2753 QCBOREncode_AddInt64(pCtx, nLabel);
2754 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64);
2755 QCBOREncode_AddText(pCtx, B64Text);
2756}
2757
2758
2759static inline void QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx, UsefulBufC B64Text)
2760{
2761 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64URL);
2762 QCBOREncode_AddText(pCtx, B64Text);
2763}
2764
2765static inline void QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text)
2766{
2767 QCBOREncode_AddSZString(pCtx, szLabel);
2768 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64URL);
2769 QCBOREncode_AddText(pCtx, B64Text);
2770}
2771
2772static inline void QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text)
2773{
2774 QCBOREncode_AddInt64(pCtx, nLabel);
2775 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64URL);
2776 QCBOREncode_AddText(pCtx, B64Text);
2777}
2778
2779
2780static inline void QCBOREncode_AddRegex(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
2781{
2782 QCBOREncode_AddTag(pCtx, CBOR_TAG_REGEX);
2783 QCBOREncode_AddText(pCtx, Bytes);
2784}
2785
2786static inline void QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
2787{
2788 QCBOREncode_AddSZString(pCtx, szLabel);
2789 QCBOREncode_AddTag(pCtx, CBOR_TAG_REGEX);
2790 QCBOREncode_AddText(pCtx, Bytes);
2791}
2792
2793static inline void QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
2794{
2795 QCBOREncode_AddInt64(pCtx, nLabel);
2796 QCBOREncode_AddTag(pCtx, CBOR_TAG_REGEX);
2797 QCBOREncode_AddText(pCtx, Bytes);
2798}
2799
2800
2801static inline void QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx, UsefulBufC MIMEData)
2802{
2803 QCBOREncode_AddTag(pCtx, CBOR_TAG_MIME);
2804 QCBOREncode_AddText(pCtx, MIMEData);
2805}
2806
2807static inline void QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC MIMEData)
2808{
2809 QCBOREncode_AddSZString(pCtx, szLabel);
2810 QCBOREncode_AddTag(pCtx, CBOR_TAG_MIME);
2811 QCBOREncode_AddText(pCtx, MIMEData);
2812}
2813
2814static inline void QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC MIMEData)
2815{
2816 QCBOREncode_AddInt64(pCtx, nLabel);
2817 QCBOREncode_AddTag(pCtx, CBOR_TAG_MIME);
2818 QCBOREncode_AddText(pCtx, MIMEData);
2819}
2820
2821
2822static inline void QCBOREncode_AddDateString(QCBOREncodeContext *pCtx, const char *szDate)
2823{
2824 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_STRING);
2825 QCBOREncode_AddSZString(pCtx, szDate);
2826}
2827
2828static inline void QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szDate)
2829{
2830 QCBOREncode_AddSZString(pCtx, szLabel);
2831 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_STRING);
2832 QCBOREncode_AddSZString(pCtx, szDate);
2833}
2834
2835static inline void QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szDate)
2836{
2837 QCBOREncode_AddInt64(pCtx, nLabel);
2838 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_STRING);
2839 QCBOREncode_AddSZString(pCtx, szDate);
2840}
2841
2842
2843static inline void QCBOREncode_AddSimple(QCBOREncodeContext *pCtx, uint64_t uNum)
2844{
2845 QCBOREncode_AddType7(pCtx, 0, uNum);
2846}
2847
2848static inline void QCBOREncode_AddSimpleToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint8_t uSimple)
2849{
2850 QCBOREncode_AddSZString(pCtx, szLabel);
2851 QCBOREncode_AddSimple(pCtx, uSimple);
2852}
2853
2854static inline void QCBOREncode_AddSimpleToMapN(QCBOREncodeContext *pCtx, int nLabel, uint8_t uSimple)
2855{
2856 QCBOREncode_AddInt64(pCtx, nLabel);
2857 QCBOREncode_AddSimple(pCtx, uSimple);
2858}
2859
2860
2861static inline void QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b)
2862{
2863 uint8_t uSimple = CBOR_SIMPLEV_FALSE;
2864 if(b) {
2865 uSimple = CBOR_SIMPLEV_TRUE;
2866 }
2867 QCBOREncode_AddSimple(pCtx, uSimple);
2868}
2869
2870static inline void QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b)
2871{
2872 QCBOREncode_AddSZString(pCtx, szLabel);
2873 QCBOREncode_AddBool(pCtx, b);
2874}
2875
2876static inline void QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b)
2877{
2878 QCBOREncode_AddInt64(pCtx, nLabel);
2879 QCBOREncode_AddBool(pCtx, b);
2880}
2881
2882
2883static inline void QCBOREncode_AddNULL(QCBOREncodeContext *pCtx)
2884{
2885 QCBOREncode_AddSimple(pCtx, CBOR_SIMPLEV_NULL);
2886}
2887
2888static inline void QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel)
2889{
2890 QCBOREncode_AddSZString(pCtx, szLabel);
2891 QCBOREncode_AddNULL(pCtx);
2892}
2893
2894static inline void QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
2895{
2896 QCBOREncode_AddInt64(pCtx, nLabel);
2897 QCBOREncode_AddNULL(pCtx);
2898}
2899
2900
2901static inline void QCBOREncode_AddUndef(QCBOREncodeContext *pCtx)
2902{
2903 QCBOREncode_AddSimple(pCtx, CBOR_SIMPLEV_UNDEF);
2904}
2905
2906static inline void QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel)
2907{
2908 QCBOREncode_AddSZString(pCtx, szLabel);
2909 QCBOREncode_AddUndef(pCtx);
2910}
2911
2912static inline void QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
2913{
2914 QCBOREncode_AddInt64(pCtx, nLabel);
2915 QCBOREncode_AddUndef(pCtx);
2916}
2917
2918
2919static inline void QCBOREncode_OpenArray(QCBOREncodeContext *pCtx)
2920{
2921 QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_ARRAY);
2922}
2923
2924static inline void QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel)
2925{
2926 QCBOREncode_AddSZString(pCtx, szLabel);
2927 QCBOREncode_OpenArray(pCtx);
2928}
2929
2930static inline void QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
2931{
2932 QCBOREncode_AddInt64(pCtx, nLabel);
2933 QCBOREncode_OpenArray(pCtx);
2934}
2935
2936static inline void QCBOREncode_CloseArray(QCBOREncodeContext *pCtx)
2937{
2938 QCBOREncode_CloseMapOrArray(pCtx, CBOR_MAJOR_TYPE_ARRAY, NULL);
2939}
2940
2941
2942static inline void QCBOREncode_OpenMap(QCBOREncodeContext *pCtx)
2943{
2944 QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_MAP);
2945}
2946
2947static inline void QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel)
2948{
2949 QCBOREncode_AddSZString(pCtx, szLabel);
2950 QCBOREncode_OpenMap(pCtx);
2951}
2952
2953static inline void QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
2954{
2955 QCBOREncode_AddInt64(pCtx, nLabel);
2956 QCBOREncode_OpenMap(pCtx);
2957}
2958
2959static inline void QCBOREncode_CloseMap(QCBOREncodeContext *pCtx)
2960{
2961 QCBOREncode_CloseMapOrArray(pCtx, CBOR_MAJOR_TYPE_MAP, NULL);
2962}
2963
2964
2965static inline void QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx)
2966{
2967 QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_BYTE_STRING);
2968}
2969
2970static inline void QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel)
2971{
2972 QCBOREncode_AddSZString(pCtx, szLabel);
2973 QCBOREncode_BstrWrap(pCtx);
2974}
2975
2976static inline void QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
2977{
2978 QCBOREncode_AddInt64(pCtx, nLabel);
2979 QCBOREncode_BstrWrap(pCtx);
2980}
2981
2982static inline void QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR)
2983{
2984 QCBOREncode_CloseMapOrArray(pCtx, CBOR_MAJOR_TYPE_BYTE_STRING, pWrappedCBOR);
2985}
2986
2987
2988static inline void QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded)
2989{
2990 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_NONE_TYPE_RAW, Encoded);
2991}
2992
2993static inline void QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded)
2994{
2995 QCBOREncode_AddSZString(pCtx, szLabel);
2996 QCBOREncode_AddEncoded(pCtx, Encoded);
2997}
2998
2999static inline void QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded)
3000{
3001 QCBOREncode_AddInt64(pCtx, nLabel);
3002 QCBOREncode_AddEncoded(pCtx, Encoded);
3003}
3004
3005
Laurence Lundblade852a33c2019-06-11 09:00:07 -07003006static inline int QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx)
3007{
3008 return UsefulOutBuf_IsBufferNULL(&(pCtx->OutBuf));
3009}
3010
3011static inline QCBORError QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx)
3012{
3013 return pCtx->uError;
3014}
3015
3016
Laurence Lundblade6ed34222018-12-18 09:46:23 -08003017/* ===========================================================================
3018 END OF PRIVATE INLINE IMPLEMENTATION
3019
3020 =========================================================================== */
3021
Laurence Lundbladed425fb32019-02-18 10:56:18 -08003022#ifdef __cplusplus
3023}
3024#endif
3025
Laurence Lundblade6ed34222018-12-18 09:46:23 -08003026#endif /* defined(__QCBOR__qcbor__) */
3027