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