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