blob: 8da2f39b0bb8bd8579566e22b471ee35c1d05d08 [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
44 when who what, where, why
45 -------- ---- ---------------------------------------------------
Laurence Lundbladec93b5a72019-04-06 12:17:16 -070046 4/6/19 llundblade Wrapped bstr returned now includes the wrapping bstr
Laurence Lundbladed425fb32019-02-18 10:56:18 -080047 02/16/19 llundblade Redesign MemPool to fix memory access alignment bug
Laurence Lundblade6ed34222018-12-18 09:46:23 -080048 12/18/18 llundblade Move decode malloc optional code to separate repository
49 12/13/18 llundblade Documentatation improvements
50 11/29/18 llundblade Rework to simpler handling of tags and labels.
51 11/9/18 llundblade Error codes are now enums.
52 11/1/18 llundblade Floating support.
53 10/31/18 llundblade Switch to one license that is almost BSD-3.
54 10/15/18 llundblade Indefinite length maps and arrays supported
55 10/8/18 llundblade Indefinite length strings supported
56 09/28/18 llundblade Added bstr wrapping feature for COSE implementation.
57 07/05/17 llundbla Add bstr wrapping of maps/arrays for COSE.
58 03/01/17 llundbla More data types; decoding improvements and fixes.
59 11/13/16 llundbla Integrate most TZ changes back into github version.
60 09/30/16 gkanike Porting to TZ.
61 03/15/16 llundbla Initial Version.
62
63 =====================================================================================*/
64
65#ifndef __QCBOR__qcbor__
66#define __QCBOR__qcbor__
67
68/*...... This is a ruler that is 80 characters long...........................*/
69
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
125 uint16_t uCount; // Number of items in the arrary or map; counts items in a map, not pairs of items
126 uint8_t uMajorType; // Indicates if item is a map or an array
127 } pArrays[QCBOR_MAX_ARRAY_NESTING1+1], // stored state for the nesting levels
128 *pCurrentNesting; // the current nesting level
129} QCBORTrackNesting;
130
131
132/*
133 PRIVATE DATA STRUCTURE
134
135 Context / data object for encoding some CBOR. Used by all encode functions to
136 form a public "object" that does the job of encdoing.
137
138 Size approximation (varies with CPU/compiler):
139 64-bit machine: 27 + 1 (+ 4 padding) + 136 = 32 + 136 = 168 bytes
140 32-bit machine: 15 + 1 + 132 = 148 bytes
141*/
142struct _QCBOREncodeContext {
143 // PRIVATE DATA STRUCTURE
144 UsefulOutBuf OutBuf; // Pointer to output buffer, its length and position in it
145 uint8_t uError; // Error state
146 QCBORTrackNesting nesting; // Keep track of array and map nesting
147};
148
149
150/*
151 PRIVATE DATA STRUCTURE
152
153 Holds the data for array and map nesting for decoding work. This structure
154 and the DecodeNesting_xxx functions form an "object" that does the work
155 for arrays and maps.
156
157 Size approximation (varies with CPU/compiler):
158 64-bit machine: 4 * 16 + 8 = 72
159 32-bit machine: 4 * 16 + 4 = 68
160 */
161typedef struct __QCBORDecodeNesting {
162 // PRIVATE DATA STRUCTURE
163 struct {
164 uint16_t uCount;
165 uint8_t uMajorType;
166 } pMapsAndArrays[QCBOR_MAX_ARRAY_NESTING1+1],
167 *pCurrent;
168} QCBORDecodeNesting;
169
170
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800171typedef struct {
172 // PRIVATE DATA STRUCTURE
173 void *pAllocateCxt;
174 UsefulBuf (* pfAllocator)(void *pAllocateCxt, void *pOldMem, size_t uNewSize);
175} QCORInternalAllocator;
176
177
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800178/*
179 PRIVATE DATA STRUCTURE
180
181 The decode context. This data structure plus the public QCBORDecode_xxx
182 functions form an "object" that does CBOR decoding.
183
184 Size approximation (varies with CPU/compiler):
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800185 64-bit machine: 32 + 1 + 1 + 6 bytes padding + 72 + 16 + 8 + 8 = 144 bytes
186 32-bit machine: 16 + 1 + 1 + 2 bytes padding + 68 + 8 + 8 + 4 = 108 bytes
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800187 */
188struct _QCBORDecodeContext {
189 // PRIVATE DATA STRUCTURE
190 UsefulInputBuf InBuf;
191
192 uint8_t uDecodeMode;
193 uint8_t bStringAllocateAll;
194
195 QCBORDecodeNesting nesting;
196
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800197 // If a string allocator is configured for indefinite length
198 // strings, it is configured here.
199 QCORInternalAllocator StringAllocator;
200
201 // These are special for the internal MemPool allocator.
202 // They are not used otherwise. We tried packing these
203 // in the MemPool itself, but there are issues
204 // with memory alignment.
205 uint32_t uMemPoolSize;
206 uint32_t uMemPoolFreeOffset;
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800207
208 // This is NULL or points to QCBORTagList.
209 // It is type void for the same reason as above.
210 const void *pCallerConfiguredTagList;
211};
212
213// Used internally in the impementation here
214// Must not conflict with any of the official CBOR types
215#define CBOR_MAJOR_NONE_TYPE_RAW 9
216#define CBOR_MAJOR_NONE_TAG_LABEL_REORDER 10
Laurence Lundbladec93b5a72019-04-06 12:17:16 -0700217#define CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY 11
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800218
219
220/* ===========================================================================
221 END OF PRIVATE PART OF THIS FILE
222
223 BEGINNING OF PUBLIC PART OF THIS FILE
224 =========================================================================== */
225
226
227
228/* ===========================================================================
229 BEGINNING OF CONSTANTS THAT COME FROM THE CBOR STANDARD, RFC 7049
230
231 It is not necessary to use these directly when encoding or decoding
232 CBOR with this implementation.
233 =========================================================================== */
234
235/* Standard CBOR Major type for positive integers of various lengths */
236#define CBOR_MAJOR_TYPE_POSITIVE_INT 0
237
238/* Standard CBOR Major type for negative integer of various lengths */
239#define CBOR_MAJOR_TYPE_NEGATIVE_INT 1
240
241/* Standard CBOR Major type for an array of arbitrary 8-bit bytes. */
242#define CBOR_MAJOR_TYPE_BYTE_STRING 2
243
244/* Standard CBOR Major type for a UTF-8 string. Note this is true 8-bit UTF8
245 with no encoding and no NULL termination */
246#define CBOR_MAJOR_TYPE_TEXT_STRING 3
247
248/* Standard CBOR Major type for an ordered array of other CBOR data items */
249#define CBOR_MAJOR_TYPE_ARRAY 4
250
251/* Standard CBOR Major type for CBOR MAP. Maps an array of pairs. The
252 first item in the pair is the "label" (key, name or identfier) and the second
253 item is the value. */
254#define CBOR_MAJOR_TYPE_MAP 5
255
256/* Standard CBOR optional tagging. This tags things like dates and URLs */
257#define CBOR_MAJOR_TYPE_OPTIONAL 6
258
259/* Standard CBOR extra simple types like floats and the values true and false */
260#define CBOR_MAJOR_TYPE_SIMPLE 7
261
262
263/*
264 These are special values for the AdditionalInfo bits that are part of the first byte.
265 Mostly they encode the length of the data item.
266 */
267#define LEN_IS_ONE_BYTE 24
268#define LEN_IS_TWO_BYTES 25
269#define LEN_IS_FOUR_BYTES 26
270#define LEN_IS_EIGHT_BYTES 27
271#define ADDINFO_RESERVED1 28
272#define ADDINFO_RESERVED2 29
273#define ADDINFO_RESERVED3 30
274#define LEN_IS_INDEFINITE 31
275
276
277/*
278 24 is a special number for CBOR. Integers and lengths
279 less than it are encoded in the same byte as the major type
280 */
281#define CBOR_TWENTY_FOUR 24
282
283
284/*
285 Tags that are used with CBOR_MAJOR_TYPE_OPTIONAL. These are
286 the ones defined in the CBOR spec.
287 */
288/** See QCBOREncode_AddDateString() below */
289#define CBOR_TAG_DATE_STRING 0
290/** See QCBOREncode_AddDateEpoch_2() */
291#define CBOR_TAG_DATE_EPOCH 1
292#define CBOR_TAG_POS_BIGNUM 2
293#define CBOR_TAG_NEG_BIGNUM 3
294#define CBOR_TAG_FRACTION 4
295#define CBOR_TAG_BIGFLOAT 5
296
297#define CBOR_TAG_COSE_ENCRYPTO 16
298#define CBOR_TAG_COSE_MAC0 17
299#define CBOR_TAG_COSE_SIGN1 18
300
301/* The data in byte string should be converted in base 64 URL when encoding in JSON or similar text-based representations */
302#define CBOR_TAG_ENC_AS_B64URL 21
303/* The data in byte string should be encoded in base 64 when encoding in JSON */
304#define CBOR_TAG_ENC_AS_B64 22
305/* The data in byte string should be encoded in base 16 when encoding in JSON */
306#define CBOR_TAG_ENC_AS_B16 23
307#define CBOR_TAG_CBOR 24
308/** The data in the string is a URIs, as defined in RFC3986 */
309#define CBOR_TAG_URI 32
310/** The data in the string is a base 64'd URL */
311#define CBOR_TAG_B64URL 33
312/** The data in the string is base 64'd */
313#define CBOR_TAG_B64 34
314/** regular expressions in Perl Compatible Regular Expressions (PCRE) / JavaScript syntax ECMA262. */
315#define CBOR_TAG_REGEX 35
316/** MIME messages (including all headers), as defined in RFC2045 */
317#define CBOR_TAG_MIME 36
318/** Binary UUID */
319#define CBOR_TAG_BIN_UUID 37
320
321#define CBOR_TAG_CWT 61
322
323#define CBOR_TAG_ENCRYPT 96
324#define CBOR_TAG_MAC 97
325#define CBOR_TAG_SIGN 98
326
327#define CBOR_TAG_GEO_COORD 103
328
329
330/** The data is CBOR data */
331#define CBOR_TAG_CBOR_MAGIC 55799
332#define CBOR_TAG_NONE UINT64_MAX
333
334
335/*
336 Values for the 5 bits for items of major type 7
337 */
338#define CBOR_SIMPLEV_FALSE 20
339#define CBOR_SIMPLEV_TRUE 21
340#define CBOR_SIMPLEV_NULL 22
341#define CBOR_SIMPLEV_UNDEF 23
342#define CBOR_SIMPLEV_ONEBYTE 24
343#define HALF_PREC_FLOAT 25
344#define SINGLE_PREC_FLOAT 26
345#define DOUBLE_PREC_FLOAT 27
346#define CBOR_SIMPLE_BREAK 31
347
348
349
350/* ===========================================================================
351
352 END OF CONSTANTS THAT COME FROM THE CBOR STANDARD, RFC 7049
353
354 BEGINNING OF PUBLIC INTERFACE FOR QCBOR ENCODER / DECODER
355
356 =========================================================================== */
357
358/**
359
360 @file qcbor.h
361
362 Q C B O R E n c o d e / D e c o d e
363
364 This implements CBOR -- Concise Binary Object Representation as defined
365 in RFC 7049. More info is at http://cbor.io. This is a near-complete
366 implementation of the specification. Limitations are listed further down.
367
368 CBOR is intentionally designed to be translatable to JSON, but not
369 all CBOR can convert to JSON. See RFC 7049 for more info on how to
370 construct CBOR that is the most JSON friendly.
371
372 The memory model for encoding and decoding is that encoded CBOR
373 must be in a contiguous buffer in memory. During encoding the
374 caller must supply an output buffer and if the encoding would go
375 off the end of the buffer an error is returned. During decoding
376 the caller supplies the encoded CBOR in a contiguous buffer
377 and the decoder returns pointers and lengths into that buffer
378 for strings.
379
380 This implementation does not require malloc. All data structures
381 passed in/out of the APIs can fit on the stack.
382
383 Decoding of indefinite length strings is a special case that requires
384 a "string allocator" to allocate memory into which the segments of
385 the string are coalesced. Without this, decoding will error out if
386 an indefinite length string is encountered (indefinite length maps
387 and arrays do not require the string allocator). A simple string
388 allocator called MemPool is built-in and will work if supplied with
389 a block of memory to allocate. The string allocator can optionally
390 use malloc() or some other custom scheme.
391
392 Here are some terms and definitions:
393
394 - "Item", "Data Item": An integer or string or such. The basic "thing" that
395 CBOR is about. An array is an item itself that contains some items.
396
397 - "Array": An ordered sequence of items, the same as JSON.
398
399 - "Map": A collection of label/value pairs. Each pair is a data
400 item. A JSON "object" is the same as a CBOR "map".
401
402 - "Label": The data item in a pair in a map that names or identifies the
403 pair, not the value. This implementation refers to it as a "label".
404 JSON refers to it as the "name". The CBOR RFC refers to it this as a "key".
405 This implementation chooses label instead because key is too easily confused
406 with a cryptographic key. The COSE standard, which uses CBOR, has also
407 chosen to use the term "label" rather than "key" for this same reason.
408
409 - "Key": See "Label" above.
410
411 - "Tag": Optional info that can be added before each data item. This is always
412 CBOR major type 6.
413
414 - "Initial Byte": The first byte of an encoded item. Encoding and decoding of
415 this byte is taken care of by the implementation.
416
417 - "Additional Info": In addition to the major type, all data items have some
418 other info. This is usually the length of the data, but can be several
419 other things. Encoding and decoding of this is taken care of by the
420 implementation.
421
422 CBOR has two mechanisms for tagging and labeling the data
423 values like integers and strings. For example, an integer that
424 represents someone's birthday in epoch seconds since Jan 1, 1970
425 could be encoded like this:
426
427 - First it is CBOR_MAJOR_TYPE_POSITIVE_INT, the primitive positive
428 integer.
429 - Next it has a "tag" CBOR_TAG_DATE_EPOCH indicating the integer
430 represents a date in the form of the number of seconds since
431 Jan 1, 1970.
432 - Last it has a string "label" like "BirthDate" indicating
433 the meaning of the data.
434
435 The encoded binary looks like this:
436 a1 # Map of 1 item
437 69 # Indicates text string of 9 bytes
438 426972746844617465 # The text "BirthDate"
439 c1 # Tags next int as epoch date
440 1a # Indicates 4 byte integer
441 580d4172 # unsigned integer date 1477263730
442
443 Implementors using this API will primarily work with labels. Generally
444 tags are only needed for making up new data types. This implementation
445 covers most of the data types defined in the RFC using tags. It also,
446 allows for the creation of news tags if necessary.
447
448 This implementation explicitly supports labels that are text strings
449 and integers. Text strings translate nicely into JSON objects and
450 are very readable. Integer labels are much less readable, but
451 can be very compact. If they are in the range of -23 to
452 23 they take up only one byte.
453
454 CBOR allows a label to be any type of data including an array or
455 a map. It is possible to use this API to construct and
456 parse such labels, but it is not explicitly supported.
457
458 A common encoding usage mode is to invoke the encoding twice. First
459 with no output buffer to compute the length of the needed output
460 buffer. Then the correct sized output buffer is allocated. Last the
461 encoder is invoked again, this time with the output buffer.
462
463 The double invocation is not required if the max output buffer size
464 can be predicted. This is usually possible for simple CBOR structures.
465 If the double invocation is implemented, it can be
466 in a loop or function as in the example code so that the code doesn't
467 have to actually be written twice, saving code size.
468
469 If a buffer too small to hold the encoded output is given, the error
470 QCBOR_ERR_BUFFER_TOO_SMALL will be returned. Data will never be
471 written off the end of the output buffer no matter which functions
472 here are called or what parameters are passed to them.
473
474 The error handling is simple. The only possible errors are trying to
475 encode structures that are too large or too complex. There are no
476 internal malloc calls so there will be no failures for out of memory.
477 Only the final call, QCBOREncode_Finish(), returns an error code.
478 Once an error happens, the encoder goes into an error state and calls
479 to it will do nothing so the encoding can just go on. An error
480 check is not needed after every data item is added.
481
482 Encoding generally proceeds by calling QCBOREncode_Init(), calling
483 lots of "Add" functions and calling QCBOREncode_Finish(). There
484 are many "Add" functions for various data types. The input
485 buffers need only to be valid during the "Add" calls. The
486 data is copied into the output buf during the "Add" call.
487
488 There are three `Add` functions for each data type. The first
489 / main one for the type is for adding the data item to an array.
490 The second one's name ends in `ToMap`, is used for adding
491 data items to maps and takes a string
492 argument that is its label in the map. The third one ends in
493 `ToMapN`, is also used for adding data items to maps, and
494 takes an integer argument that is its label in the map.
495
496 The simplest aggregate type is an array, which is a simple ordered
497 set of items without labels the same as JSON arrays. Call
498 QCBOREncode_OpenArray() to open a new array, then "Add" to
499 put items in the array and then QCBOREncode_CloseArray(). Nesting
500 to a limit is allowed. All opens must be matched by closes or an
501 encoding error will be returned.
502
503 The other aggregate type is a map which does use labels. The
504 `Add` functions that end in `ToMap` and `ToMapN` are convenient
505 ways to add labeled data items to a map. You can also call
506 any type of `Add` function once to add a label of any time and
507 then call any type of `Add` again to add its value.
508
509 Note that when you nest arrays or maps in a map, the nested
510 array or map has a label.
511
512 Usually it is not necessary to add tags explicitly as most
513 tagged types have functions here, but they can be added by
514 calling QCBOREncode_AddTag(). There is an IANA registry for new tags that are
515 for broad use and standardization as per RFC 7049. It is also
516 allowed for protocols to make up new tags in the range above 256.
517 Note that even arrays and maps can be tagged.
518
519 Summary Limits of this implementation:
520 - The entire encoded CBOR must fit into contiguous memory.
521 - Max size of encoded / decoded CBOR data is UINT32_MAX (4GB).
522 - Max array / map nesting level when encoding / decoding is
523 QCBOR_MAX_ARRAY_NESTING (this is typically 15).
524 - Max items in an array or map when encoding / decoding is
525 QCBOR_MAX_ITEMS_IN_ARRAY (typically 65,536).
526 - Does not support encoding indefinite lengths (decoding is supported).
527 - Does not directly support some tagged types: decimal fractions, big floats
528 - Does not directly support labels in maps other than text strings and ints.
529 - Does not directly support int labels greater than INT64_MAX
530 - Epoch dates limited to INT64_MAX (+/- 292 billion years)
531 - Tags on labels are ignored during decoding
532
533 This implementation is intended to run on 32 and 64-bit CPUs. Minor
534 modifications are needed for it to work on 16-bit CPUs.
535
536 The public interface uses size_t for all lengths. Internally the
537 implementation uses 32-bit lengths by design to use less memory and
538 fit structures on the stack. This limits the encoded
539 CBOR it can work with to size UINT32_MAX (4GB) which should be
540 enough.
541
542 This implementation assumes two's compliment integer
543 machines. Stdint.h also requires this. It of course would be easy to
544 fix this implementation for another integer representation, but all
545 modern machines seem to be two's compliment.
546
547 */
548
549
550/**
551 The maximum number of items in a single array or map when encoding of decoding.
552*/
553// -1 is because the value UINT16_MAX is used to track indefinite length arraysUINT16_MAX
554#define QCBOR_MAX_ITEMS_IN_ARRAY (UINT16_MAX-1)
555
556/**
557 The maximum nesting of arrays and maps when encoding or decoding. The
558 error QCBOR_ERR_ARRAY_NESTING_TOO_DEEP will be returned on encoding
559 of decoding if it is exceeded
560*/
561#define QCBOR_MAX_ARRAY_NESTING QCBOR_MAX_ARRAY_NESTING1
562
563/**
564 The maximum number of tags that can be in QCBORTagListIn and passed to
565 QCBORDecode_SetCallerConfiguredTagList()
566 */
567#define QCBOR_MAX_CUSTOM_TAGS 16
568
569
570typedef enum {
571 /** The encode or decode completely correctly. */
572 QCBOR_SUCCESS = 0,
573
574 /** The buffer provided for the encoded output when doing encoding was
575 too small and the encoded output will not fit. Also, when the buffer
576 given to QCBORDecode_SetMemPool() is too small. */
577 QCBOR_ERR_BUFFER_TOO_SMALL,
578
579 /** During encoding or decoding, the array or map nesting was deeper than
580 this implementation can handle. Note that in the interest of code size
581 and memory use, this implementation has a hard limit on array nesting. The
582 limit is defined as the constant QCBOR_MAX_ARRAY_NESTING. */
583 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP,
584
585 /** During decoding or encoding, the array or map had too many items in it.
586 This limit QCBOR_MAX_ITEMS_IN_ARRAY, typically 65,535. */
587 QCBOR_ERR_ARRAY_TOO_LONG,
588
589 /** During encoding, more arrays or maps were closed than opened. This is a
590 coding error on the part of the caller of the encoder. */
591 QCBOR_ERR_TOO_MANY_CLOSES,
592
593 /** During decoding, some CBOR construct was encountered that this decoder
594 doesn't support, primarily this is the reserved additional info values,
595 28 through 30. */
596 QCBOR_ERR_UNSUPPORTED,
597
598 /** During decoding, hit the end of the given data to decode. For example,
599 a byte string of 100 bytes was expected, but the end of the input was
600 hit before finding those 100 bytes. Corrupted CBOR input will often
601 result in this error. */
602 QCBOR_ERR_HIT_END,
603
604 /** During encoding, the length of the encoded CBOR exceeded UINT32_MAX.
605 */
606 QCBOR_ERR_BUFFER_TOO_LARGE,
607
608 /** During decoding, an integer smaller than INT64_MIN was received (CBOR
609 can represent integers smaller than INT64_MIN, but C cannot). */
610 QCBOR_ERR_INT_OVERFLOW,
611
612 /** During decoding, the label for a map entry is bad. What causes this
613 error depends on the decoding mode. */
614 QCBOR_ERR_MAP_LABEL_TYPE,
615
616 /** During encoding or decoding, the number of array or map opens was not
617 matched by the number of closes. */
618 QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN,
619
620 /** During encoding, the simple value is not between CBOR_SIMPLEV_FALSE
621 and CBOR_SIMPLEV_UNDEF. */
622 QCBOR_ERR_BAD_SIMPLE,
623
624 /** During decoding, a date greater than +- 292 billion years from Jan 1
625 1970 encountered during parsing. */
626 QCBOR_ERR_DATE_OVERFLOW,
627
628 /** During decoding, the CBOR is not valid, primarily a simple type is encoded in
629 a prohibited way. */
630 QCBOR_ERR_INVALID_CBOR,
631
632 /** Optional tagging that doesn't make sense (an int is tagged as a
633 date string) or can't be handled. */
634 QCBOR_ERR_BAD_OPT_TAG,
635
636 /** Returned by QCBORDecode_Finish() if all the inputs bytes have not
637 been consumed. */
638 QCBOR_ERR_EXTRA_BYTES,
639
640 /** During encoding, QCBOREncode_Close() call with a different type than
641 is currently open. */
642 QCBOR_ERR_CLOSE_MISMATCH,
643
644 /** Unable to decode an indefinite length string because no string
645 allocator was configured. */
646 QCBOR_ERR_NO_STRING_ALLOCATOR,
647
648 /** One of the chunks in an indefinite length string is not of the type of
649 the string. */
650 QCBOR_ERR_INDEFINITE_STRING_CHUNK,
651
652 /** Error allocating space for a string, usually for an indefinite length
653 string. */
654 QCBOR_ERR_STRING_ALLOCATE,
655
656 /** During decoding, a break occurred outside an indefinite length item. */
657 QCBOR_ERR_BAD_BREAK,
658
659 /** During decoding, too many tags in the caller-configured tag list, or not
660 enough space in QCBORTagListOut. */
661 QCBOR_ERR_TOO_MANY_TAGS,
662
663 /** Returned by QCBORDecode_SetMemPool() when xx is too small. This should
664 never happen on a machine with 64-bit or smaller pointers. Fixing
665 it is probably by increasing QCBOR_DECODE_MIN_MEM_POOL_SIZE. */
666 QCBOR_ERR_MEM_POOL_INTERNAL
667
668} QCBORError;
669
670
671typedef enum {
672 /** See QCBORDecode_Init() */
673 QCBOR_DECODE_MODE_NORMAL = 0,
674 /** See QCBORDecode_Init() */
675 QCBOR_DECODE_MODE_MAP_STRINGS_ONLY = 1,
676 /** See QCBORDecode_Init() */
677 QCBOR_DECODE_MODE_MAP_AS_ARRAY = 2
678} QCBORDecodeMode;
679
680
681
682
683
684/* Do not renumber these. Code depends on some of these values. */
685/** The type is unknown, unset or invalid */
686#define QCBOR_TYPE_NONE 0
687/** Type for an integer that decoded either between INT64_MIN and INT32_MIN or INT32_MAX and INT64_MAX; val.int64 */
688#define QCBOR_TYPE_INT64 2
689/** Type for an integer that decoded to a more than INT64_MAX and UINT64_MAX; val.uint64 */
690#define QCBOR_TYPE_UINT64 3
691/** Type for an array. The number of items in the array is in val.uCount. */
692#define QCBOR_TYPE_ARRAY 4
693/** Type for a map; number of items in map is in val.uCount */
694#define QCBOR_TYPE_MAP 5
695/** Type for a buffer full of bytes. Data is in val.string. */
696#define QCBOR_TYPE_BYTE_STRING 6
697/** Type for a UTF-8 string. It is not NULL terminated. Data is in val.string. */
698#define QCBOR_TYPE_TEXT_STRING 7
699/** Type for a positive big number. Data is in val.bignum, a pointer and a length. */
700#define QCBOR_TYPE_POSBIGNUM 9
701/** Type for a negative big number. Data is in val.bignum, a pointer and a length. */
702#define QCBOR_TYPE_NEGBIGNUM 10
703/** Type for RFC 3339 date string, possibly with time zone. Data is in val.dateString */
704#define QCBOR_TYPE_DATE_STRING 11
705/** Type for integer seconds since Jan 1970 + floating point fraction. Data is in val.epochDate */
706#define QCBOR_TYPE_DATE_EPOCH 12
707/** A simple type that this CBOR implementation doesn't know about; Type is in val.uSimple. */
708#define QCBOR_TYPE_UKNOWN_SIMPLE 13
709/** Type for the simple value false; nothing more; nothing in val union. */
710#define QCBOR_TYPE_FALSE 20
711/** Type for the simple value true; nothing more; nothing in val union. */
712#define QCBOR_TYPE_TRUE 21
713/** Type for the simple value null; nothing more; nothing in val union. */
714#define QCBOR_TYPE_NULL 22
715/** Type for the simple value undef; nothing more; nothing in val union. */
716#define QCBOR_TYPE_UNDEF 23
717/** Type for a floating point number. Data is in val.float. */
718#define QCBOR_TYPE_FLOAT 26
719/** Type for a double floating point number. Data is in val.double. */
720#define QCBOR_TYPE_DOUBLE 27
721/** For QCBOR_DECODE_MODE_MAP_AS_ARRAY decode mode, a map that is being traversed as an array. See QCBORDecode_Init() */
722#define QCBOR_TYPE_MAP_AS_ARRAY 32
723
724#define QCBOR_TYPE_BREAK 31 // Used internally; never returned
725
726#define QCBOR_TYPE_OPTTAG 254 // Used internally; never returned
727
728
729
730/*
731 Approx Size of this:
732 8 + 8 + 1 + 1 + 1 + (1 padding) + (4 padding on 64-bit machine) = 24 for first part (20 on a 32-bit machine)
733 16 bytes for the val union
734 16 bytes for label union
735 total = 56 bytes (52 bytes on 32-bit machine)
736 */
737
738/**
739 QCBORItem holds the type, value and other info for a decoded item returned by GetNextItem().
740 */
741typedef struct _QCBORItem {
742 uint8_t uDataType; /** Tells what element of the val union to use. One of QCBOR_TYPE_XXXX */
743 uint8_t uNestingLevel; /** How deep the nesting from arrays and maps are. 0 is the top level with no arrays or maps entered */
744 uint8_t uLabelType; /** Tells what element of the label union to use */
745 uint8_t uDataAlloc; /** 1 if allocated with string allocator, 0 if not. See QCBORDecode_MakeMallocStringAllocator() */
746 uint8_t uLabelAlloc; /** Like uDataAlloc, but for label */
747 uint8_t uNextNestLevel; /** If not equal to uNestingLevel, this item closed out at least one map/array */
748
749 union {
750 int64_t int64; /** The value for uDataType QCBOR_TYPE_INT64 */
751 uint64_t uint64; /** The value for uDataType QCBOR_TYPE_UINT64 */
752
753 UsefulBufC string; /** The value for uDataType QCBOR_TYPE_BYTE_STRING and QCBOR_TYPE_TEXT_STRING */
754 uint16_t uCount; /** The "value" for uDataType QCBOR_TYPE_ARRAY or QCBOR_TYPE_MAP -- the number of items in the array or map
755 UINT16_MAX when decoding indefinite lengths maps and arrays. */
756 double dfnum; /** The value for uDataType QCBOR_TYPE_DOUBLE */
757 struct {
758 int64_t nSeconds;
759 double fSecondsFraction;
760 } epochDate; /** The value for uDataType QCBOR_TYPE_DATE_EPOCH */
761 UsefulBufC dateString; /** The value for uDataType QCBOR_TYPE_DATE_STRING */
762 UsefulBufC bigNum; /** The value for uDataType QCBOR_TYPE_BIGNUM */
763 uint8_t uSimple; /** The integer value for unknown simple types */
764 uint64_t uTagV;
765
766 } val; /** The union holding the item's value. Select union member based on uDataType */
767
768 union {
769 UsefulBufC string; /** The label for uLabelType QCBOR_TYPE_BYTE_STRING and QCBOR_TYPE_TEXT_STRING */
770 int64_t int64; /** The label for uLabelType for QCBOR_TYPE_INT64 */
771 uint64_t uint64; /** The label for uLabelType for QCBOR_TYPE_UINT64 */
772 } label; /** Union holding the different label types selected based on uLabelType */
773
774 uint64_t uTagBits; /** Bit indicating which tags (major type 6) on this item. */
775
776} QCBORItem;
777
778
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800779
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800780/**
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800781 \brief The type defining what a string allocator function must do.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800782
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800783 * \param[in] pAllocateCxt Pointer to context for the particular
784 allocator implementation What is in the
785 context is dependent on how a particular
786 string allocator works. Typically, it
787 will contain a pointer to the memory pool
788 and some booking keeping data.
789 \param[in] pOldMem Points to some memory allocated by the
790 allocator that is either to be freed or
791 to be reallocated to be larger. It is
792 NULL for new allocations and when call as
793 a destructor to clean up the whole
794 allocation.
795 \param[in] uNewSize Size of memory to be allocated or new
796 size of chunk to be reallocated. Zero for
797 a new allocation or when called as a
798 destructor.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800799
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800800 \return Either the allocated buffer is returned, or \c
801 NULLUsefulBufC. \c NULLUsefulBufC is returned on a failed
802 allocation or in the two cases where there is nothing to
803 return.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800804
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800805 This is called in one of four modes:
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800806
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800807 Allocate -- \c uNewSize is the amount to allocate. \c pOldMem is \c
808 NULL.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800809
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800810 Free -- \c uNewSize is 0. \c pOldMem points to the memory to be
811 freed. When the decoder calls this, it will always be the most
812 recent block that was either allocated or reallocated.
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800813
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800814 Reallocate -- \c pOldMem is the block to reallocate. \c uNewSize is
815 its new size. When the decoder calls this, it will always be the
816 most recent block that was either allocated or reallocated.
817
818 Destruct -- \c pOldMem is NULL and \c uNewSize is 0. This is called
819 when the decoding is complete by QCBORDecode_Finish(). Usually the
820 strings allocated by a string allocator are in use after the decoding
821 is completed so this usually will not free those strings. Many string
822 allocators will not need to do anything in this mode.
823
824 The strings allocated by this will have \c uDataAlloc set to true in
825 the \ref QCBORItem when they are returned. The user of the strings
826 will have to free them. How they free them, depends on the string
827 allocator.
828
829 If QCBORDecode_SetMemPool() is called, the internal MemPool will be
830 used. It has it's own internal implementation of this function, so
831 one does not need to be implemented.
832
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800833 */
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800834typedef UsefulBuf (* QCBORStringAllocate)(void *pAllocateCxt, void *pOldMem, size_t uNewSize);
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800835
836
837/**
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800838 This only matters if you use the built-in string allocator
839 by settig it up with QCBORDecode_SetMemPool(). This is
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800840 the size of the overhead needed needed by
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800841 QCBORDecode_SetMemPool(). The amount of memory
842 available for decoded strings will be the
843 size of the buffer given to QCBORDecode_SetMemPool() less
844 this amount.
845
846 If you write your own
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800847 string allocator or use the separately available malloc
848 based string allocator, this size will not apply
849 */
Laurence Lundbladed425fb32019-02-18 10:56:18 -0800850#define QCBOR_DECODE_MIN_MEM_POOL_SIZE 8
Laurence Lundblade6ed34222018-12-18 09:46:23 -0800851
852
853/**
854 This is used to tell the decoder about tags that it should
855 record in uTagBits in QCBORItem beyond the built-in
856 tags. puTags points to an
857 array of uint64_t integers that are the tags. uNumTags
858 is the number of integers in the array. The maximum
859 size is QCBOR_MAX_CUSTOM_TAGS. See QCBORDecode_IsTagged()
860 and QCBORDecode_SetCallerAddedTagMap().
861 */
862typedef struct {
863 uint8_t uNumTags;
864 const uint64_t *puTags;
865} QCBORTagListIn;
866
867
868/**
869 This is for QCBORDecode_GetNextWithTags() to be able to return the
870 full list of tags on an item. It not needed for most CBOR protocol
871 implementations. Its primary use is for pretty-printing CBOR or
872 protocol conversion to another format.
873
874 On input, puTags points to a buffer to be filled in
875 and uNumAllocated is the number of uint64_t values
876 in the buffer.
877
878 On output the buffer contains the tags for the item.
879 uNumUsed tells how many there are.
880 */
881typedef struct {
882 uint8_t uNumUsed;
883 uint8_t uNumAllocated;
884 uint64_t *puTags;
885} QCBORTagListOut;
886
887
888/**
889 QCBOREncodeContext is the data type that holds context for all the
890 encoding functions. It is less than 200 bytes, so it can go on
891 the stack. The contents are opaque, and the caller should not access
892 any internal items. A context may be re used serially as long as
893 it is re initialized.
894 */
895typedef struct _QCBOREncodeContext QCBOREncodeContext;
896
897
898/**
899 Initialize the the encoder to prepare to encode some CBOR.
900
901 @param[in,out] pCtx The encoder context to initialize.
902 @param[in] Storage The buffer into which this encoded result will be placed.
903
904 Call this once at the start of an encoding of a CBOR structure. Then
905 call the various QCBOREncode_AddXXX() functions to add the data
906 items. Then call QCBOREncode_Finish().
907
908 The maximum output buffer is UINT32_MAX (4GB). This is not a practical
909 limit in any way and reduces the memory needed by the implementation.
910 The error QCBOR_ERR_BUFFER_TOO_LARGE will be returned by QCBOR_Finish()
911 if a larger buffer length is passed in.
912
913 If this is called with pBuf as NULL and uBufLen a large value like
914 UINT32_MAX, all the QCBOREncode_AddXXXX() functions and
915 QCBORE_Encode_Finish() can still be called. No data will be encoded,
916 but the length of what would be encoded will be calculated. The
917 length of the encoded structure will be handed back in the call to
918 QCBOREncode_Finish(). You can then allocate a buffer of that size
919 and call all the encoding again, this time to fill in the buffer.
920
921 A QCBORContext can be reused over and over as long as
922 QCBOREncode_Init() is called.
923 */
924void QCBOREncode_Init(QCBOREncodeContext *pCtx, UsefulBuf Storage);
925
926
927/**
928 @brief Add a signed 64-bit integer to the encoded output.
929
930 @param[in] pCtx The encoding context to add the integer to.
931 @param[in] nNum The integer to add.
932
933 The integer will be encoded and added to the CBOR output.
934
935 This function figures out the size and the sign and encodes in the
936 correct minimal CBOR. Specifically, it will select CBOR major type 0 or 1
937 based on sign and will encode to 1, 2, 4 or 8 bytes depending on the
938 value of the integer. Values less than 24 effectively encode to one
939 byte because they are encoded in with the CBOR major type. This is
940 a neat and efficient characteristic of CBOR that can be taken
941 advantage of when designing CBOR-based protocols. If integers like
942 tags can be kept between -23 and 23 they will be encoded in one byte
943 including the major type.
944
945 If you pass a smaller int, say an int16_t or a small value, say 100,
946 the encoding will still be CBOR's most compact that can represent the
947 value. For example, CBOR always encodes the value 0 as one byte,
948 0x00. The representation as 0x00 includes identification of the type
949 as an integer too as the major type for an integer is 0. See RFC 7049
950 Appendix A for more examples of CBOR encoding. This compact encoding
951 is also canonical CBOR as per section 3.9 in RFC 7049.
952
953 There are no functions to add int16_t or int32_t because they are
954 not necessary because this always encodes to the smallest number
955 of bytes based on the value (If this code is running on a 32-bit
956 machine having a way to add 32-bit integers would reduce code size some).
957
958 If the encoding context is in an error state, this will do
959 nothing. If an error occurs when adding this integer, the internal
960 error flag will be set, and the error will be returned when
961 QCBOREncode_Finish() is called.
962
963 See also QCBOREncode_AddUInt64().
964 */
965void QCBOREncode_AddInt64(QCBOREncodeContext *pCtx, int64_t nNum);
966
967static void QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum);
968
969static void QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum);
970
971
972/**
973 @brief Add an unsigned 64-bit integer to the encoded output.
974
975 @param[in] pCtx The encoding context to add the integer to.
976 @param[in] uNum The integer to add.
977
978 The integer will be encoded and added to the CBOR output.
979
980 The only reason so use this function is for integers larger than
981 INT64_MAX and smaller than UINT64_MAX. Otherwise QCBOREncode_AddInt64()
982 will work fine.
983
984 Error handling is the same as for QCBOREncode_AddInt64().
985 */
986void QCBOREncode_AddUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
987
988static void QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum);
989
990static void QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum);
991
992
993/**
994
995 @brief Add a UTF-8 text string to the encoded output
996
997 @param[in] pCtx The context to initialize.
998 @param[in] Text Pointer and length of text to add.
999
1000 The text passed in must be unencoded UTF-8 according to RFC
1001 3629. There is no NULL termination. The text is added as CBOR
1002 major type 3.
1003
1004 If called with nBytesLen equal to 0, an empty string will be
1005 added. When nBytesLen is 0, pBytes may be NULL.
1006
1007 Note that the restriction of the buffer length to an uint32_t is
1008 entirely intentional as this encoder is not capable of encoding
1009 lengths greater. This limit to 4GB for a text string should not be a
1010 problem.
1011
1012 Error handling is the same as QCBOREncode_AddInt64().
1013 */
1014static void QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text);
1015
1016static void QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text);
1017
1018static void QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text);
1019
1020
1021/**
1022 @brief Add a UTF-8 text string to the encoded output
1023
1024 @param[in] pCtx The context to initialize.
1025 @param[in] szString Null-terminated text to add.
1026
1027 This works the same as QCBOREncode_AddText().
1028 */
1029static void QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString);
1030
1031static void QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString);
1032
1033static void QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString);
1034
1035
1036/**
1037 @brief Add a floating-point number to the encoded output
1038
1039 @param[in] pCtx The encoding context to add the float to.
1040 @param[in] dNum The double precision number to add.
1041
1042 This outputs a floating-point number with CBOR major type 7.
1043
1044 This will selectively encode the double-precision floating point
1045 number as either double-precision, single-precision or
1046 half-precision. It will always encode infinity, NaN and 0 has half
1047 precision. If no precision will be lost in the conversion to
1048 half-precision then it will be converted and encoded. If not and no
1049 precision will be lost in conversion to single-precision, then it
1050 will be converted and encoded. If not, then no conversion is
1051 performed, and it encoded as a double.
1052
1053 Half-precision floating point numbers take up 2 bytes, half that of
1054 single-precision, one quarter of double-precision
1055
1056 This automatically reduces the size of encoded messages a lot, maybe
1057 even by four if most of values are 0, infinity or NaN.
1058
1059 On decode, these will always be returned as a double.
1060
1061 Error handling is the same as QCBOREncode_AddInt64().
1062 */
1063void QCBOREncode_AddDouble(QCBOREncodeContext *pCtx, double dNum);
1064
1065static void QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
1066
1067static void QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
1068
1069
1070/**
1071 @brief[in] Add an optional tag
1072
1073 @param[in] pCtx The encoding context to add the integer to.
1074 @param[in] uTag The tag to add
1075
1076 This outputs a CBOR major type 6 optional tag.
1077
1078 The tag is applied to the next data item added to the encoded
1079 output. That data item that is to be tagged can be of any major
1080 CBOR type. Any number of tags can be added to a data item by calling
1081 this multiple times before the data item is added.
1082
1083 For many of the common standard tags a function to encode
1084 data using it already exists and this is not needed. For example,
1085 QCBOREncode_AddDateEpoch() already exists to output
1086 integers representing dates with the right tag.
1087*/
1088void QCBOREncode_AddTag(QCBOREncodeContext *pCtx,uint64_t uTag);
1089
1090
1091/**
1092 @brief Add an epoch-based date
1093
1094 @param[in] pCtx The encoding context to add the simple value to.
1095 @param[in] date Number of seconds since 1970-01-01T00:00Z in UTC time.
1096
1097 As per RFC 7049 this is similar to UNIX/Linux/POSIX dates. This is
1098 the most compact way to specify a date and time in CBOR. Note that this
1099 is always UTC and does not include the time zone. Use
1100 QCBOREncode_AddDateString() if you want to include the time zone.
1101
1102 The integer encoding rules apply here so the date will be encoded in a
1103 minimal number of 1, 2 4 or 8 bytes. Until about the year 2106 these
1104 dates should encode in 6 bytes -- one byte for the tag, one byte for the type
1105 and 4 bytes for the integer.
1106
1107 If you care about leap-seconds and that level of accuracy, make sure the
1108 system you are running this code on does it correctly. This code just takes
1109 the value passed in.
1110
1111 This implementation cannot encode fractional seconds using float or double
1112 even though that is allowed by CBOR, but you can encode them if you
1113 want to by calling QCBOREncode_AddDouble()
1114 with the right parameters.
1115
1116 Error handling is the same as QCBOREncode_AddInt64().
1117 */
1118static void QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx, int64_t date);
1119
1120static void QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t date);
1121
1122static void QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t date);
1123
1124
1125/**
1126 @brief Add a byte string to the encoded output.
1127
1128 @param[in] pCtx The context to initialize.
1129 @param[in] Bytes Pointer and length of the input data.
1130
1131 Simply adds the bytes to the encoded output as CBOR major type 2.
1132
1133 If called with Bytes.len equal to 0, an empty string will be
1134 added. When Bytes.len is 0, Bytes.ptr may be NULL.
1135
1136 Error handling is the same as QCBOREncode_AddInt64().
1137 */
1138static void QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
1139
1140static void QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
1141
1142static void QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
1143
1144
1145
1146/**
1147 @brief Add a binary UUID to the encoded output.
1148
1149 @param[in] pCtx The context to initialize.
1150 @param[in] Bytes Pointer and length of the binary UUID.
1151
1152 A binary UUID as defined in RFC 4122 is added to the ouput.
1153
1154 It is output as CBOR major type 2, a binary string, with
1155 optional tag 36 indicating the binary string is a UUID.
1156 */
1157static void QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
1158
1159static void QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
1160
1161static void QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
1162
1163
1164/**
1165 @brief Add a positive big number to the encoded output.
1166
1167 @param[in] pCtx The context to initialize.
1168 @param[in] Bytes Pointer and length of the big number.
1169
1170 Big numbers are integers larger than 64-bits. Their format
1171 is described in RFC 7049.
1172
1173 It is output as CBOR major type 2, a binary string, with
1174 optional tag 2 indicating the binary string is a positive big
1175 number.
1176
1177 Often big numbers are used to represent cryptographic keys,
1178 however, COSE which defines representations for keys chose not
1179 to use this particular type.
1180 */
1181static void QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
1182
1183static void QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
1184
1185static void QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
1186
1187
1188/**
1189 @brief Add a negative big number to the encoded output.
1190
1191 @param[in] pCtx The context to initialize.
1192 @param[in] Bytes Pointer and length of the big number.
1193
1194 Big numbers are integers larger than 64-bits. Their format
1195 is described in RFC 7049.
1196
1197 It is output as CBOR major type 2, a binary string, with
1198 optional tag 2 indicating the binary string is a negative big
1199 number.
1200
1201 Often big numbers are used to represent cryptographic keys,
1202 however, COSE which defines representations for keys chose not
1203 to use this particular type.
1204 */
1205static void QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
1206
1207static void QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
1208
1209static void QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
1210
1211
1212/**
1213 @brief Add a text URI to the encoded output.
1214
1215 @param[in] pCtx The context to initialize.
1216 @param[in] URI Pointer and length of the URI.
1217
1218 The format of URI is RFC 3986.
1219
1220 It is output as CBOR major type 3, a text string, with
1221 optional tag 32 indicating the text string is a URI.
1222 */
1223static void QCBOREncode_AddURI(QCBOREncodeContext *pCtx, UsefulBufC URI);
1224
1225static void QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC URI);
1226
1227static void QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC URI);
1228
1229
1230/**
1231 @brief Add base 64-encoded text to encoded output.
1232
1233 @param[in] pCtx The context to initialize.
1234 @param[in] B64Text Pointer and length of the base-64 encoded text.
1235
1236 The text content is base 64 encoded data per RFC 4648.
1237
1238 It is output as CBOR major type 3, a text string, with
1239 optional tag 34 indicating the text string is a URI.
1240 */
1241static void QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx, UsefulBufC B64Text);
1242
1243static void QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text);
1244
1245static void QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text);
1246
1247
1248/**
1249 @brief Add base 64URL -encoded URL to encoded output.
1250
1251 @param[in] pCtx The context to initialize.
1252 @param[in] B64Text Pointer and length of the base-64 encoded text.
1253
1254 The text content is base 64 URL format encoded text as per RFC 4648.
1255
1256 It is output as CBOR major type 3, a text string, with
1257 optional tag 33 indicating the text string is a URI.
1258 */
1259static void QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx, UsefulBufC B64Text);
1260
1261static void QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text);
1262
1263static void QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text);
1264
1265
1266/**
1267 @brief Add Perl Compatible Regular Expression
1268
1269 @param[in] pCtx The context to initialize.
1270 @param[in] Regex Pointer and length of the regular expression.
1271
1272 The text content is Perl Compatible Regular
1273 Expressions (PCRE) / JavaScript syntax [ECMA262].
1274
1275 It is output as CBOR major type 3, a text string, with
1276 optional tag 35 indicating the text string is a regular expression.
1277 */
1278static void QCBOREncode_AddRegex(QCBOREncodeContext *pCtx, UsefulBufC Regex);
1279
1280static void QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Regex);
1281
1282static void QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Regex);
1283
1284
1285/**
1286 @brief MIME encoded text to the encoded output.
1287
1288 @param[in] pCtx The context to initialize.
1289 @param[in] MIMEData Pointer and length of the regular expression.
1290
1291 The text content is in MIME format per RFC 2045 including the headers.
1292
1293 It is output as CBOR major type 3, a text string, with
1294 optional tag 36 indicating the text string is MIME data.
1295 */
1296static void QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx, UsefulBufC MIMEData);
1297
1298static void QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC MIMEData);
1299
1300static void QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC MIMEData);
1301
1302
1303/**
1304 @brief Add an RFC 3339 date string
1305
1306 @param[in] pCtx The encoding context to add the simple value to.
1307 @param[in] szDate Null-terminated string with date to add
1308
1309 The string szDate should be in the form of RFC 3339 as defined by section
1310 3.3 in RFC 4287. This is as described in section 2.4.1 in RFC 7049.
1311
1312 Note that this function doesn't validate the format of the date string
1313 at all. If you add an incorrect format date string, the generated
1314 CBOR will be incorrect and the receiver may not be able to handle it.
1315
1316 Error handling is the same as QCBOREncode_AddInt64().
1317 */
1318static void QCBOREncode_AddDateString(QCBOREncodeContext *pCtx, const char *szDate);
1319
1320static void QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szDate);
1321
1322static void QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szDate);
1323
1324
1325/**
1326 @brief Add a standard boolean.
1327
1328 @param[in] pCtx The encoding context to add the simple value to.
1329 @param[in] b true or false from stdbool. Anything will result in an error.
1330
1331 Adds a boolean value as CBOR major type 7.
1332
1333 Error handling is the same as QCBOREncode_AddInt64().
1334 */
1335static void QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b);
1336
1337static void QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b);
1338
1339static void QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b);
1340
1341
1342
1343/**
1344 @brief Add a NULL to the encoded output.
1345
1346 @param[in] pCtx The encoding context to add the simple value to.
1347
1348 Adds the NULL value as CBOR major type 7.
1349
1350 This NULL doesn't have any special meaning in CBOR such as a terminating
1351 value for a string or an empty value.
1352
1353 Error handling is the same as QCBOREncode_AddInt64().
1354 */
1355static void QCBOREncode_AddNULL(QCBOREncodeContext *pCtx);
1356
1357static void QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1358
1359static void QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1360
1361
1362/**
1363 @brief Add an "undef" to the encoded output.
1364
1365 @param[in] pCtx The encoding context to add the simple value to.
1366
1367 Adds the undef value as CBOR major type 7.
1368
1369 Note that this value will not translate to JSON.
1370
1371 This Undef doesn't have any special meaning in CBOR such as a terminating
1372 value for a string or an empty value.
1373
1374 Error handling is the same as QCBOREncode_AddInt64().
1375 */
1376static void QCBOREncode_AddUndef(QCBOREncodeContext *pCtx);
1377
1378static void QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1379
1380static void QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1381
1382
1383/**
1384 @brief Indicates that the next items added are in an array.
1385
1386 @param[in] pCtx The encoding context to open the array in.
1387
1388 Arrays are the basic CBOR aggregate or structure type. Call this
1389 function to start or open an array. Then call the various AddXXX
1390 functions to add the items that go into the array. Then call
1391 QCBOREncode_CloseArray() when all items have been added. The data
1392 items in the array can be of any type and can be of mixed types.
1393
1394 Nesting of arrays and maps is allowed and supported just by calling
1395 QCBOREncode_OpenArray() again before calling CloseArray. While CBOR
1396 has no limit on nesting, this implementation does in order to keep it
1397 smaller and simpler. The limit is QCBOR_MAX_ARRAY_NESTING. This is
1398 the max number of times this can be called without calling
1399 QCBOREncode_CloseArray(). QCBOREncode_Finish() will return
1400 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP when it is called as this function
1401 just sets an error state and returns no value when this occurs.
1402
1403 If you try to add more than QCBOR_MAX_ITEMS_IN_ARRAY items to a
1404 single array or map, QCBOR_ERR_ARRAY_TOO_LONG will be returned when
1405 QCBOREncode_Finish() is called.
1406
1407 An array itself must have a label if it is being added to a map.
1408 Note that array elements do not have labels (but map elements do).
1409
1410 An array itself may be tagged.
1411 */
1412static void QCBOREncode_OpenArray(QCBOREncodeContext *pCtx);
1413
1414static void QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1415
1416static void QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1417
1418
1419/**
1420 @brief Close an open array.
1421
1422 @param[in] pCtx The context to add to.
1423
1424 The closes an array opened by QCBOREncode_OpenArray(). It reduces
1425 nesting level by one. All arrays (and maps) must be closed before
1426 calling QCBOREncode_Finish().
1427
1428 When an error occurs as a result of this call, the encoder records
1429 the error and enters the error state. The error will be returned when
1430 QCBOREncode_Finish() is called.
1431
1432 If this has been called more times than QCBOREncode_OpenArray(), then
1433 QCBOR_ERR_TOO_MANY_CLOSES will be returned when QCBOREncode_Finish()
1434 is called.
1435
1436 If this is called and it is not an array that is currently open,
1437 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
1438 is called.
1439 */
1440static void QCBOREncode_CloseArray(QCBOREncodeContext *pCtx);
1441
1442
1443/**
1444 @brief Indicates that the next items added are in a map.
1445
1446 @param[in] pCtx The context to add to.
1447
1448 See QCBOREncode_OpenArray() for more information, particularly error
1449 handling.
1450
1451 CBOR maps are an aggregate type where each item in the map consists
1452 of a label and a value. They are similar to JSON objects.
1453
1454 The value can be any CBOR type including another map.
1455
1456 The label can also be any CBOR type, but in practice they are
1457 typically, integers as this gives the most compact output. They might
1458 also be text strings which gives readability and translation to JSON.
1459
1460 Every QCBOREncode_AddXXX() call has once version that is "InMap" for
1461 adding items to maps with string labels and on that is "InMapN" that
1462 is for adding with integer labels.
1463
1464 RFC 7049 uses the term "key" instead of "label".
1465
1466 If you wish to use map labels that are neither integer labels or
1467 text strings, then just call the QCBOREncode_AddXXX() function
1468 explicitly to add the label. Then call it again to add the value.
1469
1470 See the RFC7049 for a lot more information on creating maps.
1471 */
1472static void QCBOREncode_OpenMap(QCBOREncodeContext *pCtx);
1473
1474static void QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1475
1476static void QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1477
1478
1479
1480/**
1481 @brief Close an open map.
1482
1483 @param[in] pCtx The context to add to.
1484
1485 The closes a map opened by QCBOREncode_OpenMap(). It reduces nesting
1486 level by one.
1487
1488 When an error occurs as a result of this call, the encoder records
1489 the error and enters the error state. The error will be returned when
1490 QCBOREncode_Finish() is called.
1491
1492 If this has been called more times than QCBOREncode_OpenMap(),
1493 then QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1494 QCBOREncode_Finish() is called.
1495
1496 If this is called and it is not a map that is currently
1497 open, QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
1498 is called.
1499 */
1500static void QCBOREncode_CloseMap(QCBOREncodeContext *pCtx);
1501
1502
1503/**
1504 @brief Indicate start of encoded CBOR to be wrapped in a bstr.
1505
1506 @param[in] pCtx The context to add to.
1507
1508 All added encoded items between this call and a call to
1509 QCBOREncode_CloseBstrWrap() will be wrapped in a bstr. They will
1510 appear in the final output as a byte string. That byte string will
1511 contain encoded CBOR.
1512
1513 The typical use case is for encoded CBOR that is to be
1514 cryptographically hashed, as part of a COSE (RFC 8152)
1515 implementation. This avoids having to encode the items first in one
1516 buffer (e.g., the COSE payload) and then add that buffer as a bstr to
1517 another encoding (e.g. the COSE to-be-signed bytes, the
1518 Sig_structure) potentially saving a lot of memory.
1519
1520 When constructing cryptographically signed CBOR objects, maps or
1521 arrays, they typically are encoded normally and then wrapped as a
1522 byte string. The COSE standard for example does this. The wrapping is
1523 simply treating the encoded CBOR map as a byte string.
1524
1525 The stated purpose of this wrapping is to prevent code relaying the
1526 signed data but not verifying it from tampering with the signed data
1527 thus making the signature unverifiable. It is also quite beneficial
1528 for the signature verification code. Standard CBOR parsers usually do
1529 not give access to partially parsed CBOR as would be need to check
1530 the signature of some CBOR. With this wrapping, standard CBOR parsers
1531 can be used to get to all the data needed for a signature
1532 verification.
1533 */
1534static void QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx);
1535
1536static void QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1537
1538static void QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1539
1540
1541/**
1542 @brief Close a wrapping bstr.
1543
Laurence Lundbladec93b5a72019-04-06 12:17:16 -07001544 @param[in] pCtx The context to add to.
1545 @param[out] pWrappedCBOR UsefulBufC containing wrapped bytes.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001546
1547 The closes a wrapping bstr opened by QCBOREncode_BstrWrap(). It reduces
1548 nesting level by one.
1549
Laurence Lundbladec93b5a72019-04-06 12:17:16 -07001550 A pointer and length of the wrapped and encoded CBOR is returned in
1551 *pWrappedCBOR if it is not NULL. This includes the wrapping bstr
1552 itself. The main purpose of this is so this data can be hashed
1553 (e.g., with SHA-256) as part of a COSE (RFC 8152)
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001554 implementation. **WARNING**, this pointer and length should be used
1555 right away before any other calls to QCBOREncode_xxxx() as they will
1556 move data around and the pointer and length will no longer be to the
1557 correct encoded CBOR.
1558
1559 When an error occurs as a result of this call, the encoder records
1560 the error and enters the error state. The error will be returned when
1561 QCBOREncode_Finish() is called.
1562
1563 If this has been called more times then QCBOREncode_BstrWrap(),
1564 then QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1565 QCBOREncode_Finish() is called.
1566
1567 If this is called and it is not a wrapping bstr that is currently
1568 open, QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
1569 is called.
1570 */
1571static void QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR);
1572
1573
1574/**
1575 @brief Add some already-encoded CBOR bytes.
1576
1577 @param[in] pCtx The context to add to.
1578 @param[in] Encoded The already-encoded CBOR to add to the context.
1579
1580 The encoded CBOR being added must be fully conforming CBOR. It must
1581 be complete with no arrays or maps that are incomplete. While this
1582 encoder doesn't ever produce indefinite lengths, it is OK for the
1583 raw CBOR added here to have indefinite lengths.
1584
1585 The raw CBOR added here is not checked in anyway. If it is not
1586 conforming or has open arrays or such, the final encoded CBOR
1587 will probably be wrong or not what was intended.
1588
1589 If the encoded CBOR being added here contains multiple items, they
1590 must be enclosed in a map or array. At the top level the raw
1591 CBOR must be a single data item.
1592 */
1593static void QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded);
1594
1595static void QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded);
1596
1597static void QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded);
1598
1599
1600/**
1601 @brief Get the encoded result.
1602
1603 @param[in] pCtx The context to finish encoding with.
1604 @param[out] pEncodedCBOR Pointer and length of encoded CBOR.
1605
1606 @return
1607 One of the CBOR error codes.
1608
1609 If this returns success QCBOR_SUCCESS the encoding was a success and
1610 the return length is correct and complete.
1611
1612 If no buffer was passed to QCBOR_Init(), then only the length and
1613 number of items was computed. The length is in
1614 pEncodedCBOR->Bytes.len. pEncodedCBOR->Bytes.ptr is NULL.
1615
1616 If a buffer was passed, then pEncodedCBOR->Bytes.ptr is the same as
1617 the buffer passed to QCBOR_Init() and contains the encoded CBOR
1618 and the length is filled in.
1619
1620 If an error is returned, the buffer may have partially encoded
1621 incorrect CBOR in it and it should not be used. Likewise, the length
1622 may be incorrect and should not be used.
1623
1624 Note that the error could have occurred in one of the many
1625 QCBOR_AddXXX calls long before QCBOREncode_Finish() was called. This
1626 error handling approach reduces the CBOR implementation size, but makes
1627 debugging a problem a little more difficult.
1628 */
1629QCBORError QCBOREncode_Finish(QCBOREncodeContext *pCtx, UsefulBufC *pEncodedCBOR);
1630
1631
1632/**
1633 @brief Get the encoded CBOR and error status.
1634
1635 @param[in] pCtx The context to finish encoding with.
1636 @param[out] uEncodedLen The length of the encoded or potentially encoded CBOR in bytes.
1637
1638 @return
1639 One of the CBOR error codes.
1640
1641 If this returns success QCBOR_SUCCESS the encoding was a success and
1642 the return length is correct and complete.
1643
1644 If no buffer was passed to QCBOR_Init(), then only the length was
1645 computed. If a buffer was passed, then the encoded CBOR is in the
1646 buffer.
1647
1648 If an error is returned, the buffer may have partially encoded
1649 incorrect CBOR in it and it should not be used. Likewise, the length
1650 may be incorrect and should not be used.
1651
1652 Note that the error could have occurred in one of the many
1653 QCBOR_AddXXX calls long before QCBOREncode_Finish() was called. This
1654 error handling reduces the CBOR implementation size, but makes
1655 debugging harder.
1656 */
1657QCBORError QCBOREncode_FinishGetSize(QCBOREncodeContext *pCtx, size_t *uEncodedLen);
1658
1659
1660
1661
1662
1663
1664/**
1665 QCBORDecodeContext is the data type that holds context decoding the
1666 data items for some received CBOR. It is about 100 bytes, so it can go
1667 on the stack. The contents are opaque, and the caller should not
1668 access any internal items. A context may be re used serially as long
1669 as it is re initialized.
1670 */
1671typedef struct _QCBORDecodeContext QCBORDecodeContext;
1672
1673
1674/**
1675 Initialize the CBOR decoder context.
1676
1677 @param[in] pCtx The context to initialize.
1678 @param[in] EncodedCBOR The buffer with CBOR encoded bytes to be decoded.
1679 @param[in] nMode One of QCBOR_DECODE_MODE_xxx
1680
1681 Initialize context for a pre-order travesal of the encoded CBOR tree.
1682
1683 Most CBOR decoding can be completed by calling this function to start
1684 and QCBORDecode_GetNext() in a loop.
1685
1686 If indefinite length strings are to be decoded, then
1687 QCBORDecode_SetMemPool() or QCBORDecode_SetUpAllocator() must be
1688 called to set up a string allocator.
1689
1690 If tags other than built-in tags are to be recognized, then
1691 QCBORDecode_SetCallerAddedTagMap() must be called. The built-in tags
1692 are those for which a macro of the form CBOR_TAG_XXX is defined.
1693
1694 Three decoding modes are supported. In normal mode,
1695 QCBOR_DECODE_MODE_NORMAL, maps are decoded and strings and ints are
1696 accepted as map labels. If a label is other than these, the error
1697 QCBOR_ERR_MAP_LABEL_TYPE is returned by QCBORDecode_GetNext().
1698
1699 In strings-only mode, QCBOR_DECODE_MODE_MAP_STRINGS_ONLY, only text
1700 strings are accepted for map labels. This lines up with CBOR that
1701 converts to JSON. The error QCBOR_ERR_MAP_LABEL_TYPE is returned by
1702 QCBORDecode_GetNext() if anything but a text string label is
1703 encountered.
1704
1705 In QCBOR_DECODE_MODE_MAP_AS_ARRAY maps are treated as special arrays.
1706 They will be return with special uDataType QCBOR_TYPE_MAP_AS_ARRAY
1707 and uCount, the number of items, will be double what it would be
1708 for a normal map because the labels are also counted. This mode
1709 is useful for decoding CBOR that has labels that are not
1710 integers or text strings, but the caller must manage much of
1711 the map decoding.
1712 */
1713void QCBORDecode_Init(QCBORDecodeContext *pCtx, UsefulBufC EncodedCBOR, QCBORDecodeMode nMode);
1714
1715
1716/**
1717 @brief Set up the MemPool string allocator for indefinite length strings.
1718
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001719 @param[in] pCtx The decode context.
1720 @param[in] MemPool The pointer and length of the memory pool.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001721
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001722 @param[in] bAllStrings If true, all strings, even of definite
1723 length, will be allocated with the string
1724 allocator.
1725
1726 @return Error if the MemPool was less than \ref QCBOR_DECODE_MIN_MEM_POOL_SIZE.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001727
1728 Indefinite length strings (text and byte) cannot be decoded unless
1729 there is a string allocator configured. MemPool is a simple built-in
1730 string allocator that allocates bytes from a memory pool handed to it
1731 by calling this function. The memory pool is just a pointer and
1732 length for some block of memory that is to be used for string
1733 allocation. It can come from the stack, heap or other.
1734
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001735 The memory pool must be \ref QCBOR_DECODE_MIN_MEM_POOL_SIZE plus
1736 space for all the strings allocated. There is no overhead per string
1737 allocated. A conservative way to size this buffer is to make it the
1738 same size as the CBOR being decoded plus \ref
1739 QCBOR_DECODE_MIN_MEM_POOL_SIZE.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001740
1741 This memory pool is used for all indefinite length strings that are
1742 text strings or byte strings, including strings used as labels.
1743
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001744 The pointers to strings in \ref QCBORItem will point into the memory
1745 pool set here. They do not need to be individually freed. Just
1746 discard the buffer when they are no longer needed.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001747
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001748 If \c bAllStrings is set, then the size will be the overhead plus the
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001749 space to hold **all** strings, definite and indefinite length, value
1750 or label. The advantage of this is that after the decode is complete,
1751 the original memory holding the encoded CBOR does not need to remain
1752 valid.
1753
1754 If this function is never called because there is no need to support
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001755 indefinite length strings, the internal MemPool implementation should
1756 be dead-stripped by the loader and not add to code size.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001757 */
1758QCBORError QCBORDecode_SetMemPool(QCBORDecodeContext *pCtx, UsefulBuf MemPool, bool bAllStrings);
1759
1760
1761/**
1762 @brief Sets up a custom string allocator for indefinite length strings
1763
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001764 @param[in] pCtx The decoder context to set up an
1765 allocator for.
1766 @param[in] pfAllocateFunction Pointer to function that will be
1767 called by QCBOR for allocations and
1768 frees.
1769 @param[in] pAllocateContext Context passed to \c
1770 pfAllocateFunction.
1771 @param[in] bAllStrings If true, all strings, even of definite
1772 length, will be allocated with the
1773 string allocator.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001774
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001775 Indefinite length strings (text and byte) cannot be decoded unless
1776 there a string allocator is configured. QCBORDecode_SetUpAllocator()
1777 allows the caller to configure an external string allocator
1778 implementation if the internal string allocator is not suitable. See
1779 QCBORDecode_SetMemPool() to configure the internal allocator. Note
1780 that the internal allocator is not automatically set up.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001781
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001782 The string allocator configured here can be a custom one designed and
1783 implemented by the caller. See \ref QCBORStringAllocate for the
1784 requirements for a string allocator implementation.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001785
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001786 A malloc-based string external allocator can be obtained by calling
1787 \c QCBORDecode_MakeMallocStringAllocator(). It will return a function
1788 and pointer that can be given here as \c pAllocatorFunction and \c
1789 pAllocatorContext. It uses standard \c malloc() so \c free() must be
1790 called onall strings marked by \c uDataAlloc \c == \c 1 or \c
1791 uLabelAlloc \c == \c 1 in \ref QCBORItem.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001792
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001793 Note that an older version of this function took an allocator
1794 structure, rather than single function and pointer. The older
1795 version \c QCBORDecode_MakeMallocStringAllocator() also implemented
1796 the older interface.
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001797 */
Laurence Lundbladed425fb32019-02-18 10:56:18 -08001798void QCBORDecode_SetUpAllocator(QCBORDecodeContext *pCtx,
1799 QCBORStringAllocate pfAllocateFunction,
1800 void *pAllocateContext,
1801 bool bAllStrings);
Laurence Lundblade6ed34222018-12-18 09:46:23 -08001802
1803/**
1804 @brief Configure list of caller selected tags to be recognized
1805
1806 @param[in] pCtx The decode context.
1807 @param[out] pTagList Structure holding the list of tags to configure
1808
1809 This is used to tell the decoder about tags beyond those that are
1810 built-in that should be recognized. The built-in tags are those
1811 with macros of the form CBOR_TAG_XXX.
1812
1813 See description of QCBORTagListIn.
1814 */
1815void QCBORDecode_SetCallerConfiguredTagList(QCBORDecodeContext *pCtx, const QCBORTagListIn *pTagList);
1816
1817
1818/**
1819 @brief Gets the next item (integer, byte string, array...) in pre order traversal of CBOR tree
1820
1821 @param[in] pCtx The decoder context.
1822 @param[out] pDecodedItem Holds the CBOR item just decoded.
1823
1824 @return 0 or error. All errors except QCBOR_ERR_TOO_MANY_TAGS
1825 and QCBOR_ERR_STRING_ALLOCATE indicate that the CBOR input
1826 could not be decoded. In most cases
1827 this is because the CBOR is invalid. In a few cases
1828 (QCBOR_ERR_ARRAY_NESTING_TOO_DEEP, QCBOR_ERR_INT_OVERFLOW,
1829 QCBOR_ERR_DATE_OVERFLOW) it is because the CBOR is beyond
1830 the limits of what this implementation can handle.
1831 QCBOR_ERR_NO_STRING_ALLOCATOR indicates CBOR that cannot
1832 be handled unless a string allocator is configured.
1833 QCBOR_ERR_MAP_LABEL_TYPE is in a way a limitation of
1834 this implementation, but can be avoided by decoding
1835 in QCBOR_DECODE_MODE_MAP_AS_ARRAY mode.
1836
1837 pDecodedItem is filled in with the value parsed. Generally, the
1838 following data is returned in the structure.
1839
1840 - The data type in uDataType which indicates which member of the val
1841 union the data is in. This decoder figures out the type based on the
1842 CBOR major type, the CBOR "additionalInfo", the CBOR optional tags
1843 and the value of the integer.
1844
1845 - The value of the item, which might be an integer, a pointer and a
1846 length, the count of items in an array, a floating-point number or
1847 other.
1848
1849 - The nesting level for maps and arrays.
1850
1851 - The label for an item in a map, which may be a text or byte string or an integer.
1852
1853 - The CBOR optional tag or tags.
1854
1855 See documentation on in the data type QCBORItem for all the details
1856 on what is returned.
1857
1858 This function also handles arrays and maps. When first encountered a
1859 QCBORItem will be returned with major type CBOR_MAJOR_TYPE_ARRAY or
1860 CBOR_MAJOR_TYPE_ARRAY_MAP. QCBORItem.val.uCount will indicate the number
1861 of Items in the array or map. Typically, an implementation will call
1862 QCBORDecode_GetNext() in a for loop to fetch them all. When decoding
1863 indefinite length maps and arrays, QCBORItem.val.uCount is UINT16_MAX
1864 and uNextNestLevel must be used to know when the end of a map
1865 or array is reached.
1866
1867 Nesting level 0 is the outside top-most nesting level. For example, in
1868 a CBOR structure with two items, an integer and a byte string only,
1869 both would be at nesting level 0. A CBOR structure with an array
1870 open, an integer and a byte string, would have the integer and byte
1871 string as nesting level 1.
1872
1873 Here is an example of how the nesting level is reported with no arrays
1874 or maps at all
1875
1876 @verbatim
1877 CBOR Structure Nesting Level
1878 Integer 0
1879 Byte String 0
1880 @endverbatim
1881
1882 Here is an example of how the nesting level is reported with an a simple
1883 array and some top-level items.
1884
1885 @verbatim
1886 Integer 0
1887 Array (with 2 items) 0
1888 Byte String 1
1889 Byte string 1
1890 Integer 0
1891 @endverbatim
1892
1893
1894 Here's a more complex example
1895 @verbatim
1896
1897 Map with 2 items 0
1898 Text string 1
1899 Array with 3 integers 1
1900 integer 2
1901 integer 2
1902 integer 2
1903 text string 1
1904 byte string 1
1905 @endverbatim
1906
1907 In QCBORItem, uNextNestLevel is the nesting level for the next call
1908 to QCBORDecode_GetNext(). It indicates if any maps or arrays were closed
1909 out during the processing of the just-fecthed QCBORItem. This processing
1910 includes a look-ahead for any breaks that close out indefinite length
1911 arrays or maps. This value is needed to be able to understand the
1912 hierarchical structure. If uNextNestLevel is not equal to uNestLevel
1913 the end of the current map or array has been encountered. This
1914 works the same for both definite and indefinite length arrays.
1915
1916 Most uses of this decoder will not need to do anything extra for
1917 tag handling. The built-in tags, those with a macro of the form
1918 CBOR_TAG_XXXX, will be enough.
1919
1920 If tags beyond built-in tags are to be recognized, they must be
1921 configured by calling QCBORDecode_SetCallerConfiguredTags(). If
1922 a tag is not recognized it is silently ignored.
1923
1924 Several tagged types are automatically recognized and decoded and
1925 returned in their decoded form.
1926
1927 To find out if a QCBORItem was tagged with a particular tag
1928 call QCBORDecode_IsTagged(). This works only for built-in
1929 tags and caller-configured tags.
1930
1931 To get the full list of tags on an Item without having to
1932 pre-configure any predetermined list of tags use
1933 QCBORDecode_GetNextWithTags().
1934 */
1935QCBORError QCBORDecode_GetNext(QCBORDecodeContext *pCtx, QCBORItem *pDecodedItem);
1936
1937
1938/**
1939 @brief Gets the next item including full list of tags for item
1940
1941 @param[in] pCtx The decoder context.
1942 @param[out] pDecodedItem Holds the CBOR item just decoded.
1943 @param[in,out] pTagList On input array to put tags in; on output the tags on this item.
1944
1945 @return 0 or error.
1946
1947 This works the same as QCBORDecode_GetNext() except that it also returns
1948 the full list of tags for the data item. This function should only
1949 be needed when parsing CBOR to print it out or convert it to some other
1950 format. It should not be needed in an actual CBOR protocol implementation.
1951
1952 Tags will be returned here whether or not they are in the built-in or
1953 caller-configured tag lists.
1954
1955 CBOR has no upper bound of limit on the number of tags that can be
1956 associated with a data item. In practice the number of tags on an item
1957 will usually be small, perhaps less than five. This will return an error
1958 if the array in pTagList is too small to hold all the tags for an item.
1959
1960 (This function is separate from QCBORDecode_GetNext() so as to not have to
1961 make QCBORItem large enough to be able to hold a full list of tags. Even a list of
1962 five tags would nearly double its size because tags can be a uint64_t).
1963 */
1964QCBORError QCBORDecode_GetNextWithTags(QCBORDecodeContext *pCtx, QCBORItem *pDecodedItem, QCBORTagListOut *pTagList);
1965
1966
1967/**
1968 @brief Determine if a CBOR item was tagged with a particular tag
1969
1970 @param[in] pCtx The decoder context.
1971 @param[in] pItem The CBOR item to check
1972 @param[in] uTag The tag to check
1973
1974 @return 1 if it was tagged, 0 if not
1975
1976 QCBORDecode_GetNext() processes tags by looking them up
1977 in two lists and setting a bit corresponding to the tag
1978 in uTagBits in the QCBORItem. To find out if a
1979 QCBORItem was tagged with a particular tag, call
1980 this function. It handles the mapping between
1981 the two lists of tags and the bits set for it.
1982
1983 The first tag list is the built-in tags, those
1984 with a macro of the form CBOR_TAG_XXX in this
1985 header file. There are up to 48 of these,
1986 corresponding to the lower 48 tag bits.
1987
1988 The other optional tag list is the ones
1989 the caller configured using QCBORDecode_SetCallerConfiguredTagList()
1990 There are QCBOR_MAX_CUSTOM_TAGS (16) of these corresponding to the
1991 upper 16 tag bits.
1992
1993 See also QCBORDecode_GetTags() and QCBORDecode_GetNextWithTags().
1994 */
1995int QCBORDecode_IsTagged(QCBORDecodeContext *pCtx, const QCBORItem *pItem, uint64_t uTag);
1996
1997
1998/**
1999 Check whether all the bytes have been decoded and maps and arrays closed.
2000
2001 @param[in] pCtx The context to check
2002
2003 @return QCBOR_SUCCESS or error
2004
2005 This tells you if all the bytes given to QCBORDecode_Init() have
2006 been consumed and whether all maps and arrays were closed.
2007 The decode is considered to be incorrect or incomplete if not
2008 and an error will be returned.
2009 */
2010QCBORError QCBORDecode_Finish(QCBORDecodeContext *pCtx);
2011
2012
2013
2014
2015/**
2016 Convert int64_t to smaller int's safely
2017
2018 @param [in] src An int64_t
2019 @param [out] dest A smaller sized int to convert to
2020
2021 @return 0 on success -1 if not
2022
2023 When decoding an integer, the CBOR decoder will return the value as an
2024 int64_t unless the integer is in the range of INT64_MAX and
2025 UINT64_MAX. That is, unless the value is so large that it can only be
2026 represented as a uint64_t, it will be an int64_t.
2027
2028 CBOR itself doesn't size the individual integers it carries at
2029 all. The only limits it puts on the major integer types is that they
2030 are 8 bytes or less in length. Then encoders like this one use the
2031 smallest number of 1, 2, 4 or 8 bytes to represent the integer based
2032 on its value. There is thus no notion that one data item in CBOR is
2033 an 1 byte integer and another is a 4 byte integer.
2034
2035 The interface to this CBOR encoder only uses 64-bit integers. Some
2036 CBOR protocols or implementations of CBOR protocols may not want to
2037 work with something smaller than a 64-bit integer. Perhaps an array
2038 of 1000 integers needs to be sent and none has a value larger than
2039 50,000 and are represented as uint16_t.
2040
2041 The sending / encoding side is easy. Integers are temporarily widened
2042 to 64-bits as a parameter passing through QCBOREncode_AddInt64() and
2043 encoded in the smallest way possible for their value, possibly in
2044 less than an uint16_t.
2045
2046 On the decoding side the integers will be returned at int64_t even if
2047 they are small and were represented by only 1 or 2 bytes in the
2048 encoded CBOR. The functions here will convert integers to a small
2049 representation with an overflow check.
2050
2051 (The decoder could have support 8 different integer types and
2052 represented the integer with the smallest type automatically, but
2053 this would have made the decoder more complex and code calling the
2054 decoder more complex in most use cases. In most use cases on 64-bit
2055 machines it is no burden to carry around even small integers as
2056 64-bit values).
2057 */
2058static inline int QCBOR_Int64ToInt32(int64_t src, int32_t *dest)
2059{
2060 if(src > INT32_MAX || src < INT32_MIN) {
2061 return -1;
2062 } else {
2063 *dest = (int32_t) src;
2064 }
2065 return 0;
2066}
2067
2068static inline int QCBOR_Int64ToInt16(int64_t src, int16_t *dest)
2069{
2070 if(src > INT16_MAX || src < INT16_MIN) {
2071 return -1;
2072 } else {
2073 *dest = (int16_t) src;
2074 }
2075 return 0;
2076}
2077
2078static inline int QCBOR_Int64ToInt8(int64_t src, int8_t *dest)
2079{
2080 if(src > INT8_MAX || src < INT8_MIN) {
2081 return -1;
2082 } else {
2083 *dest = (int8_t) src;
2084 }
2085 return 0;
2086}
2087
2088static inline int QCBOR_Int64ToUInt32(int64_t src, uint32_t *dest)
2089{
2090 if(src > UINT32_MAX || src < 0) {
2091 return -1;
2092 } else {
2093 *dest = (uint32_t) src;
2094 }
2095 return 0;
2096}
2097
2098static inline int QCBOR_Int64UToInt16(int64_t src, uint16_t *dest)
2099{
2100 if(src > UINT16_MAX || src < 0) {
2101 return -1;
2102 } else {
2103 *dest = (uint16_t) src;
2104 }
2105 return 0;
2106}
2107
2108static inline int QCBOR_Int64ToUInt8(int64_t src, uint8_t *dest)
2109{
2110 if(src > UINT8_MAX || src < 0) {
2111 return -1;
2112 } else {
2113 *dest = (uint8_t) src;
2114 }
2115 return 0;
2116}
2117
2118static inline int QCBOR_Int64ToUInt64(int64_t src, uint64_t *dest)
2119{
2120 if(src > 0) {
2121 return -1;
2122 } else {
2123 *dest = (uint64_t) src;
2124 }
2125 return 0;
2126}
2127
2128
2129
2130
2131
2132/* ===========================================================================
2133 BEGINNING OF PRIVATE INLINE IMPLEMENTATION
2134
2135 =========================================================================== */
2136
2137/**
2138 @brief Semi-private method to add a buffer full of bytes to encoded output
2139
2140 @param[in] pCtx The encoding context to add the integer to.
2141 @param[in] uMajorType The CBOR major type of the bytes.
2142 @param[in] Bytes The bytes to add.
2143
2144 Use QCBOREncode_AddText() or QCBOREncode_AddBytes() or
2145 QCBOREncode_AddEncoded() instead. They are inline functions
2146 that call this and supply the correct major type. This function
2147 is public to make the inline functions work to keep the overall
2148 code size down and because the C language has no way to make
2149 it private.
2150
2151 If this is called the major type should be CBOR_MAJOR_TYPE_TEXT_STRING,
2152 CBOR_MAJOR_TYPE_BYTE_STRING or CBOR_MAJOR_NONE_TYPE_RAW. The last
2153 one is special for adding already-encoded CBOR.
2154 */
2155void QCBOREncode_AddBuffer(QCBOREncodeContext *pCtx, uint8_t uMajorType, UsefulBufC Bytes);
2156
2157
2158/**
2159 @brief Semi-private method to open a map, array or bstr wrapped CBOR
2160
2161 @param[in] pCtx The context to add to.
2162 @param[in] uMajorType The major CBOR type to close
2163
2164 Call QCBOREncode_OpenArray(), QCBOREncode_OpenMap() or
2165 QCBOREncode_BstrWrap() instead of this.
2166 */
2167void QCBOREncode_OpenMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType);
2168
2169
2170/**
2171 @brief Semi-private method to close a map, array or bstr wrapped CBOR
2172
2173 @param[in] pCtx The context to add to.
2174 @param[in] uMajorType The major CBOR type to close
2175 @param[out] pWrappedCBOR UsefulBufC containing wrapped bytes
2176
2177 Call QCBOREncode_CloseArray(), QCBOREncode_CloseMap() or
2178 QCBOREncode_CloseBstrWrap() instead of this.
2179 */
2180void QCBOREncode_CloseMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType, UsefulBufC *pWrappedCBOR);
2181
2182
2183/**
2184 @brief Semi-private method to add simple types.
2185
2186 @param[in] pCtx The encoding context to add the simple value to.
2187 @param[in] uSize Minimum encoding size for uNum. Usually 0.
2188 @param[in] uNum One of CBOR_SIMPLEV_FALSE through _UNDEF or other.
2189
2190 This is used to add simple types like true and false.
2191
2192 Call QCBOREncode_AddBool(), QCBOREncode_AddNULL(), QCBOREncode_AddUndef()
2193 instead of this.
2194
2195 This function can add simple values that are not defined by CBOR yet. This expansion
2196 point in CBOR should not be used unless they are standardized.
2197
2198 Error handling is the same as QCBOREncode_AddInt64().
2199 */
2200void QCBOREncode_AddType7(QCBOREncodeContext *pCtx, size_t uSize, uint64_t uNum);
2201
2202
Laurence Lundbladec93b5a72019-04-06 12:17:16 -07002203/**
2204 @brief Semi-private method to add only the type and length of a byte string.
2205
2206 @param[in] pCtx The context to initialize.
2207 @param[in] Bytes Pointer and length of the input data.
2208
2209 This is the same as QCBOREncode_AddBytes() except it only adds the
2210 CBOR encoding for the type and the length. It doesn't actually add
2211 the bytes. You can't actually produce correct CBOR with this and the
2212 rest of this API. It is only used for a special case where
2213 the valid CBOR is created manually by putting this type and length in
2214 and then adding the actual bytes. In particular, when only a hash of
2215 the encoded CBOR is needed, where the type and header are hashed
2216 separately and then the bytes is hashed. This makes it possible to
2217 implement COSE Sign1 with only one copy of the payload in the output
2218 buffer, rather than two, roughly cutting memory use in half.
2219
2220 This is only used for this odd case, but this is a supported
2221 tested function.
2222*/
2223static inline void QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
2224
2225static inline void QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
2226
2227static inline void QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
2228
2229
2230
2231
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002232static inline void QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum)
2233{
2234 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel)); // AddSZString not defined yet
2235 QCBOREncode_AddInt64(pCtx, uNum);
2236}
2237
2238static inline void QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum)
2239{
2240 QCBOREncode_AddInt64(pCtx, nLabel);
2241 QCBOREncode_AddInt64(pCtx, uNum);
2242}
2243
2244
2245static inline void QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum)
2246{
2247 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel)); // AddSZString not defined yet
2248 QCBOREncode_AddUInt64(pCtx, uNum);
2249}
2250
2251static inline void QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum)
2252{
2253 QCBOREncode_AddInt64(pCtx, nLabel);
2254 QCBOREncode_AddUInt64(pCtx, uNum);
2255}
2256
2257
2258static inline void QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text)
2259{
2260 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, Text);
2261}
2262
2263static inline void QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text)
2264{
2265 QCBOREncode_AddText(pCtx, UsefulBuf_FromSZ(szLabel)); // AddSZString not defined yet
2266 QCBOREncode_AddText(pCtx, Text);
2267}
2268
2269static inline void QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text)
2270{
2271 QCBOREncode_AddInt64(pCtx, nLabel);
2272 QCBOREncode_AddText(pCtx, Text);
2273}
2274
2275
2276inline static void QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString)
2277{
2278 QCBOREncode_AddText(pCtx, UsefulBuf_FromSZ(szString));
2279}
2280
2281static inline void QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString)
2282{
2283 QCBOREncode_AddSZString(pCtx, szLabel);
2284 QCBOREncode_AddSZString(pCtx, szString);
2285}
2286
2287static inline void QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString)
2288{
2289 QCBOREncode_AddInt64(pCtx, nLabel);
2290 QCBOREncode_AddSZString(pCtx, szString);
2291}
2292
2293
2294static inline void QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum)
2295{
2296 QCBOREncode_AddSZString(pCtx, szLabel);
2297 QCBOREncode_AddDouble(pCtx, dNum);
2298}
2299
2300static inline void QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum)
2301{
2302 QCBOREncode_AddInt64(pCtx, nLabel);
2303 QCBOREncode_AddDouble(pCtx, dNum);
2304}
2305
2306
2307static inline void QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx, int64_t date)
2308{
2309 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_EPOCH);
2310 QCBOREncode_AddInt64(pCtx, date);
2311}
2312
2313static inline void QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t date)
2314{
2315 QCBOREncode_AddSZString(pCtx, szLabel);
2316 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_EPOCH);
2317 QCBOREncode_AddInt64(pCtx, date);
2318}
2319
2320static inline void QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t date)
2321{
2322 QCBOREncode_AddInt64(pCtx, nLabel);
2323 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_EPOCH);
2324 QCBOREncode_AddInt64(pCtx, date);
2325}
2326
2327
2328static inline void QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
2329{
2330 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes);
2331}
2332
2333static inline void QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
2334{
2335 QCBOREncode_AddSZString(pCtx, szLabel);
2336 QCBOREncode_AddBytes(pCtx, Bytes);
2337}
2338
2339static inline void QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
2340{
2341 QCBOREncode_AddInt64(pCtx, nLabel);
2342 QCBOREncode_AddBytes(pCtx, Bytes);
2343}
2344
Laurence Lundbladec93b5a72019-04-06 12:17:16 -07002345static inline void QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
2346{
2347 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY, Bytes);
2348}
2349
2350static inline void QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
2351{
2352 QCBOREncode_AddSZString(pCtx, szLabel);
2353 QCBOREncode_AddBytesLenOnly(pCtx, Bytes);
2354}
2355
2356static inline void QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
2357{
2358 QCBOREncode_AddInt64(pCtx, nLabel);
2359 QCBOREncode_AddBytesLenOnly(pCtx, Bytes);
2360}
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002361
2362static inline void QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
2363{
2364 QCBOREncode_AddTag(pCtx, CBOR_TAG_BIN_UUID);
2365 QCBOREncode_AddBytes(pCtx, Bytes);
2366}
2367
2368static inline void QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
2369{
2370 QCBOREncode_AddSZString(pCtx, szLabel);
2371 QCBOREncode_AddTag(pCtx, CBOR_TAG_BIN_UUID);
2372 QCBOREncode_AddBytes(pCtx, Bytes);
2373}
2374
2375static inline void QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
2376{
2377 QCBOREncode_AddInt64(pCtx, nLabel);
2378 QCBOREncode_AddTag(pCtx, CBOR_TAG_BIN_UUID);
2379 QCBOREncode_AddBytes(pCtx, Bytes);
2380}
2381
2382
2383static inline void QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
2384{
2385 QCBOREncode_AddTag(pCtx, CBOR_TAG_POS_BIGNUM);
2386 QCBOREncode_AddBytes(pCtx, Bytes);
2387}
2388
2389static inline void QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
2390{
2391 QCBOREncode_AddSZString(pCtx, szLabel);
2392 QCBOREncode_AddTag(pCtx, CBOR_TAG_POS_BIGNUM);
2393 QCBOREncode_AddBytes(pCtx, Bytes);
2394}
2395
2396static inline void QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
2397{
2398 QCBOREncode_AddInt64(pCtx, nLabel);
2399 QCBOREncode_AddTag(pCtx, CBOR_TAG_POS_BIGNUM);
2400 QCBOREncode_AddBytes(pCtx, Bytes);
2401}
2402
2403
2404static inline void QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
2405{
2406 QCBOREncode_AddTag(pCtx, CBOR_TAG_NEG_BIGNUM);
2407 QCBOREncode_AddBytes(pCtx, Bytes);
2408}
2409
2410static inline void QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
2411{
2412 QCBOREncode_AddSZString(pCtx, szLabel);
2413 QCBOREncode_AddTag(pCtx, CBOR_TAG_NEG_BIGNUM);
2414 QCBOREncode_AddBytes(pCtx, Bytes);
2415}
2416
2417static inline void QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
2418{
2419 QCBOREncode_AddInt64(pCtx, nLabel);
2420 QCBOREncode_AddTag(pCtx, CBOR_TAG_NEG_BIGNUM);
2421 QCBOREncode_AddBytes(pCtx, Bytes);
2422}
2423
2424
2425static inline void QCBOREncode_AddURI(QCBOREncodeContext *pCtx, UsefulBufC URI)
2426{
2427 QCBOREncode_AddTag(pCtx, CBOR_TAG_URI);
2428 QCBOREncode_AddText(pCtx, URI);
2429}
2430
2431static inline void QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC URI)
2432{
2433 QCBOREncode_AddSZString(pCtx, szLabel);
2434 QCBOREncode_AddTag(pCtx, CBOR_TAG_URI);
2435 QCBOREncode_AddText(pCtx, URI);
2436}
2437
2438static inline void QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC URI)
2439{
2440 QCBOREncode_AddInt64(pCtx, nLabel);
2441 QCBOREncode_AddTag(pCtx, CBOR_TAG_URI);
2442 QCBOREncode_AddText(pCtx, URI);
2443}
2444
2445
2446
2447static inline void QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx, UsefulBufC B64Text)
2448{
2449 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64);
2450 QCBOREncode_AddText(pCtx, B64Text);
2451}
2452
2453static inline void QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text)
2454{
2455 QCBOREncode_AddSZString(pCtx, szLabel);
2456 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64);
2457 QCBOREncode_AddText(pCtx, B64Text);
2458}
2459
2460static inline void QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text)
2461{
2462 QCBOREncode_AddInt64(pCtx, nLabel);
2463 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64);
2464 QCBOREncode_AddText(pCtx, B64Text);
2465}
2466
2467
2468static inline void QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx, UsefulBufC B64Text)
2469{
2470 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64URL);
2471 QCBOREncode_AddText(pCtx, B64Text);
2472}
2473
2474static inline void QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text)
2475{
2476 QCBOREncode_AddSZString(pCtx, szLabel);
2477 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64URL);
2478 QCBOREncode_AddText(pCtx, B64Text);
2479}
2480
2481static inline void QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text)
2482{
2483 QCBOREncode_AddInt64(pCtx, nLabel);
2484 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64URL);
2485 QCBOREncode_AddText(pCtx, B64Text);
2486}
2487
2488
2489static inline void QCBOREncode_AddRegex(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
2490{
2491 QCBOREncode_AddTag(pCtx, CBOR_TAG_REGEX);
2492 QCBOREncode_AddText(pCtx, Bytes);
2493}
2494
2495static inline void QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
2496{
2497 QCBOREncode_AddSZString(pCtx, szLabel);
2498 QCBOREncode_AddTag(pCtx, CBOR_TAG_REGEX);
2499 QCBOREncode_AddText(pCtx, Bytes);
2500}
2501
2502static inline void QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
2503{
2504 QCBOREncode_AddInt64(pCtx, nLabel);
2505 QCBOREncode_AddTag(pCtx, CBOR_TAG_REGEX);
2506 QCBOREncode_AddText(pCtx, Bytes);
2507}
2508
2509
2510static inline void QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx, UsefulBufC MIMEData)
2511{
2512 QCBOREncode_AddTag(pCtx, CBOR_TAG_MIME);
2513 QCBOREncode_AddText(pCtx, MIMEData);
2514}
2515
2516static inline void QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC MIMEData)
2517{
2518 QCBOREncode_AddSZString(pCtx, szLabel);
2519 QCBOREncode_AddTag(pCtx, CBOR_TAG_MIME);
2520 QCBOREncode_AddText(pCtx, MIMEData);
2521}
2522
2523static inline void QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC MIMEData)
2524{
2525 QCBOREncode_AddInt64(pCtx, nLabel);
2526 QCBOREncode_AddTag(pCtx, CBOR_TAG_MIME);
2527 QCBOREncode_AddText(pCtx, MIMEData);
2528}
2529
2530
2531static inline void QCBOREncode_AddDateString(QCBOREncodeContext *pCtx, const char *szDate)
2532{
2533 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_STRING);
2534 QCBOREncode_AddSZString(pCtx, szDate);
2535}
2536
2537static inline void QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szDate)
2538{
2539 QCBOREncode_AddSZString(pCtx, szLabel);
2540 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_STRING);
2541 QCBOREncode_AddSZString(pCtx, szDate);
2542}
2543
2544static inline void QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szDate)
2545{
2546 QCBOREncode_AddInt64(pCtx, nLabel);
2547 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_STRING);
2548 QCBOREncode_AddSZString(pCtx, szDate);
2549}
2550
2551
2552static inline void QCBOREncode_AddSimple(QCBOREncodeContext *pCtx, uint64_t uNum)
2553{
2554 QCBOREncode_AddType7(pCtx, 0, uNum);
2555}
2556
2557static inline void QCBOREncode_AddSimpleToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint8_t uSimple)
2558{
2559 QCBOREncode_AddSZString(pCtx, szLabel);
2560 QCBOREncode_AddSimple(pCtx, uSimple);
2561}
2562
2563static inline void QCBOREncode_AddSimpleToMapN(QCBOREncodeContext *pCtx, int nLabel, uint8_t uSimple)
2564{
2565 QCBOREncode_AddInt64(pCtx, nLabel);
2566 QCBOREncode_AddSimple(pCtx, uSimple);
2567}
2568
2569
2570static inline void QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b)
2571{
2572 uint8_t uSimple = CBOR_SIMPLEV_FALSE;
2573 if(b) {
2574 uSimple = CBOR_SIMPLEV_TRUE;
2575 }
2576 QCBOREncode_AddSimple(pCtx, uSimple);
2577}
2578
2579static inline void QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b)
2580{
2581 QCBOREncode_AddSZString(pCtx, szLabel);
2582 QCBOREncode_AddBool(pCtx, b);
2583}
2584
2585static inline void QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b)
2586{
2587 QCBOREncode_AddInt64(pCtx, nLabel);
2588 QCBOREncode_AddBool(pCtx, b);
2589}
2590
2591
2592static inline void QCBOREncode_AddNULL(QCBOREncodeContext *pCtx)
2593{
2594 QCBOREncode_AddSimple(pCtx, CBOR_SIMPLEV_NULL);
2595}
2596
2597static inline void QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel)
2598{
2599 QCBOREncode_AddSZString(pCtx, szLabel);
2600 QCBOREncode_AddNULL(pCtx);
2601}
2602
2603static inline void QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
2604{
2605 QCBOREncode_AddInt64(pCtx, nLabel);
2606 QCBOREncode_AddNULL(pCtx);
2607}
2608
2609
2610static inline void QCBOREncode_AddUndef(QCBOREncodeContext *pCtx)
2611{
2612 QCBOREncode_AddSimple(pCtx, CBOR_SIMPLEV_UNDEF);
2613}
2614
2615static inline void QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel)
2616{
2617 QCBOREncode_AddSZString(pCtx, szLabel);
2618 QCBOREncode_AddUndef(pCtx);
2619}
2620
2621static inline void QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
2622{
2623 QCBOREncode_AddInt64(pCtx, nLabel);
2624 QCBOREncode_AddUndef(pCtx);
2625}
2626
2627
2628static inline void QCBOREncode_OpenArray(QCBOREncodeContext *pCtx)
2629{
2630 QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_ARRAY);
2631}
2632
2633static inline void QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel)
2634{
2635 QCBOREncode_AddSZString(pCtx, szLabel);
2636 QCBOREncode_OpenArray(pCtx);
2637}
2638
2639static inline void QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
2640{
2641 QCBOREncode_AddInt64(pCtx, nLabel);
2642 QCBOREncode_OpenArray(pCtx);
2643}
2644
2645static inline void QCBOREncode_CloseArray(QCBOREncodeContext *pCtx)
2646{
2647 QCBOREncode_CloseMapOrArray(pCtx, CBOR_MAJOR_TYPE_ARRAY, NULL);
2648}
2649
2650
2651static inline void QCBOREncode_OpenMap(QCBOREncodeContext *pCtx)
2652{
2653 QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_MAP);
2654}
2655
2656static inline void QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel)
2657{
2658 QCBOREncode_AddSZString(pCtx, szLabel);
2659 QCBOREncode_OpenMap(pCtx);
2660}
2661
2662static inline void QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
2663{
2664 QCBOREncode_AddInt64(pCtx, nLabel);
2665 QCBOREncode_OpenMap(pCtx);
2666}
2667
2668static inline void QCBOREncode_CloseMap(QCBOREncodeContext *pCtx)
2669{
2670 QCBOREncode_CloseMapOrArray(pCtx, CBOR_MAJOR_TYPE_MAP, NULL);
2671}
2672
2673
2674static inline void QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx)
2675{
2676 QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_BYTE_STRING);
2677}
2678
2679static inline void QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel)
2680{
2681 QCBOREncode_AddSZString(pCtx, szLabel);
2682 QCBOREncode_BstrWrap(pCtx);
2683}
2684
2685static inline void QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
2686{
2687 QCBOREncode_AddInt64(pCtx, nLabel);
2688 QCBOREncode_BstrWrap(pCtx);
2689}
2690
2691static inline void QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR)
2692{
2693 QCBOREncode_CloseMapOrArray(pCtx, CBOR_MAJOR_TYPE_BYTE_STRING, pWrappedCBOR);
2694}
2695
2696
2697static inline void QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded)
2698{
2699 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_NONE_TYPE_RAW, Encoded);
2700}
2701
2702static inline void QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded)
2703{
2704 QCBOREncode_AddSZString(pCtx, szLabel);
2705 QCBOREncode_AddEncoded(pCtx, Encoded);
2706}
2707
2708static inline void QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded)
2709{
2710 QCBOREncode_AddInt64(pCtx, nLabel);
2711 QCBOREncode_AddEncoded(pCtx, Encoded);
2712}
2713
2714
2715/* ===========================================================================
2716 END OF PRIVATE INLINE IMPLEMENTATION
2717
2718 =========================================================================== */
2719
Laurence Lundbladed425fb32019-02-18 10:56:18 -08002720#ifdef __cplusplus
2721}
2722#endif
2723
Laurence Lundblade6ed34222018-12-18 09:46:23 -08002724#endif /* defined(__QCBOR__qcbor__) */
2725