xref: /optee_os/core/lib/qcbor/inc/qcbor/qcbor_encode.h (revision b586599be35c4311337a5d8db5f4b5e5c81a754d)
1 // SPDX-License-Identifier: BSD-3-Clause
2 /* ===========================================================================
3  * Copyright (c) 2016-2018, The Linux Foundation.
4  * Copyright (c) 2018-2024, Laurence Lundblade.
5  * Copyright (c) 2021, Arm Limited.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are
10  * met:
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above
14  *       copyright notice, this list of conditions and the following
15  *       disclaimer in the documentation and/or other materials provided
16  *       with the distribution.
17  *     * Neither the name of The Linux Foundation nor the names of its
18  *       contributors, nor the name "Laurence Lundblade" may be used to
19  *       endorse or promote products derived from this software without
20  *       specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
23  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
26  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
29  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
31  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
32  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  * ========================================================================= */
34 
35 
36 #ifndef qcbor_encode_h
37 #define qcbor_encode_h
38 
39 
40 #include "qcbor/qcbor_common.h"
41 #include "qcbor/qcbor_private.h"
42 #include <stdbool.h>
43 
44 
45 #ifdef __cplusplus
46 extern "C" {
47 #if 0
48 } // Keep editor indention formatting happy
49 #endif
50 #endif
51 
52 
53 /**
54  * @file qcbor_encode.h
55  *
56  * @anchor Overview
57  *
58  * # QCBOR Overview
59  *
60  * This implements CBOR -- Concise Binary Object Representation as
61  * defined in [RFC 8949] (https://tools.ietf.org/html/rfc8949). More
62  * information is at http://cbor.io.  This is a near-complete implementation of
63  * the specification. [RFC 8742] (https://tools.ietf.org/html/rfc8742) CBOR
64  * Sequences is also supported. Limitations are listed further down.
65  *
66  * See @ref Encoding for general discussion on encoding,
67  * @ref BasicDecode for general discussion on the basic decode features
68  * and @ref SpiffyDecode for general discussion on the easier-to-use
69  * decoder functions.
70  *
71  * CBOR is intentionally designed to be translatable to JSON, but not
72  * all CBOR can convert to JSON. See RFC 8949 for more info on how to
73  * construct CBOR that is the most JSON friendly.
74  *
75  * The memory model for encoding and decoding is that encoded CBOR must
76  * be in a contiguous buffer in memory.  During encoding the caller must
77  * supply an output buffer and if the encoding would go off the end of
78  * the buffer an error is returned.  During decoding the caller supplies
79  * the encoded CBOR in a contiguous buffer and the decoder returns
80  * pointers and lengths into that buffer for strings.
81  *
82  * This implementation does not require malloc. All data structures
83  * passed in/out of the APIs can fit on the stack.
84  *
85  * Decoding of indefinite-length strings is a special case that requires
86  * a "string allocator" to allocate memory into which the segments of
87  * the string are coalesced. Without this, decoding will error out if an
88  * indefinite-length string is encountered (indefinite-length maps and
89  * arrays do not require the string allocator). A simple string
90  * allocator called MemPool is built-in and will work if supplied with a
91  * block of memory to allocate. The string allocator can optionally use
92  * malloc() or some other custom scheme.
93  *
94  * Here are some terms and definitions:
95  *
96  * - "Item", "Data Item": An integer or string or such. The basic "thing" that
97  * CBOR is about. An array is an item itself that contains some items.
98  *
99  * - "Array": An ordered sequence of items, the same as JSON.
100  *
101  * - "Map": A collection of label/value pairs. Each pair is a data
102  * item. A JSON "object" is the same as a CBOR "map".
103  *
104  * - "Label": The data item in a pair in a map that names or identifies
105  * the pair, not the value. This implementation refers to it as a
106  * "label".  JSON refers to it as the "name". The CBOR RFC refers to it
107  * this as a "key".  This implementation chooses label instead because
108  * key is too easily confused with a cryptographic key. The COSE
109  * standard, which uses CBOR, has also chosen to use the term "label"
110  * rather than "key" for this same reason.
111  *
112  * - "Key": See "Label" above.
113  *
114  * - "Tag": A data item that is an explicitly labeled new data
115  * type made up of the tagging integer and the tag content.
116  * See @ref Tags-Overview and @ref Tag-Usage.
117  *
118  * - "Initial Byte": The first byte of an encoded item. Encoding and
119  * decoding of this byte is taken care of by the implementation.
120  *
121  * - "Additional Info": In addition to the major type, all data items
122  * have some other info. This is usually the length of the data but can
123  * be several other things. Encoding and decoding of this is taken care
124  * of by the implementation.
125  *
126  * CBOR has two mechanisms for tagging and labeling the data values like
127  * integers and strings. For example, an integer that represents
128  * someone's birthday in epoch seconds since Jan 1, 1970 could be
129  * encoded like this:
130  *
131  * - First it is CBOR_MAJOR_TYPE_POSITIVE_INT (@ref QCBOR_TYPE_INT64),
132  * the primitive positive integer.
133  *
134  * - Next it has a "tag" @ref CBOR_TAG_DATE_EPOCH indicating the integer
135  * represents a date in the form of the number of seconds since Jan 1,
136  * 1970.
137  *
138  * - Last it has a string "label" like "BirthDate" indicating the
139  * meaning of the data.
140  *
141  * The encoded binary looks like this:
142  *
143  *      a1                      # Map of 1 item
144  *         69                   # Indicates text string of 9 bytes
145  *           426972746844617465 # The text "BirthDate"
146  *        c1                    # Tags next integer as epoch date
147  *           1a                 # Indicates a 4-byte integer
148  *               580d4172       # unsigned integer date 1477263730
149  *
150  * Implementors using this API will primarily work with
151  * labels. Generally, tags are only needed for making up new data
152  * types. This implementation covers most of the data types defined in
153  * the RFC using tags. It also, allows for the use of custom tags if
154  * necessary.
155  *
156  * This implementation explicitly supports labels that are text strings
157  * and integers. Text strings translate nicely into JSON objects and are
158  * very readable.  Integer labels are much less readable but can be very
159  * compact. If they are in the range of 0 to 23, they take up only one
160  * byte.
161  *
162  * CBOR allows a label to be any type of data including an array or a
163  * map. It is possible to use this API to construct and parse such
164  * labels, but it is not explicitly supported.
165  *
166  * @anchor Encoding
167  *
168  * ## Encoding
169  *
170  * A common encoding usage mode is to invoke the encoding twice. First
171  * with the output buffer as @ref SizeCalculateUsefulBuf to compute the
172  * length of the needed output buffer. The correct sized output buffer
173  * is allocated. The encoder is invoked a second time with the allocated
174  * output buffer.
175  *
176  * The double invocation is not required if the maximum output buffer
177  * size can be predicted. This is usually possible for simple CBOR
178  * structures.
179  *
180  * If a buffer too small to hold the encoded output is given, the error
181  * @ref QCBOR_ERR_BUFFER_TOO_SMALL will be returned. Data will never be
182  * written off the end of the output buffer no matter which functions
183  * here are called or what parameters are passed to them.
184  *
185  * The encoding error handling is simple. The only possible errors are
186  * trying to encode structures that are too large or too complex. There
187  * are no internal malloc calls so there will be no failures for out of
188  * memory.  The error state is tracked internally, so there is no need
189  * to check for errors when encoding. Only the return code from
190  * QCBOREncode_Finish() need be checked as once an error happens, the
191  * encoder goes into an error state and calls to it to add more data
192  * will do nothing. An error check is not needed after every data item
193  * is added.
194  *
195  * Encoding generally proceeds by calling QCBOREncode_Init(), calling
196  * lots of @c QCBOREncode_AddXxx() functions and calling
197  * QCBOREncode_Finish(). There are many @c QCBOREncode_AddXxx()
198  * functions for various data types. The input buffers need only to be
199  * valid during the @c QCBOREncode_AddXxx() calls as the data is copied
200  * into the output buffer.
201  *
202  * There are three `Add` functions for each data type. The first / main
203  * one for the type is for adding the data item to an array.  The second
204  * one's name ends in `ToMap`, is used for adding data items to maps and
205  * takes a string argument that is its label in the map. The third one
206  * ends in `ToMapN`, is also used for adding data items to maps, and
207  * takes an integer argument that is its label in the map.
208  *
209  * The simplest aggregate type is an array, which is a simple ordered
210  * set of items without labels the same as JSON arrays. Call
211  * QCBOREncode_OpenArray() to open a new array, then various @c
212  * QCBOREncode_AddXxx() functions to put items in the array and then
213  * QCBOREncode_CloseArray(). Nesting to the limit @ref
214  * QCBOR_MAX_ARRAY_NESTING is allowed.  All opens must be matched by
215  * closes or an encoding error will be returned.
216  *
217  * The other aggregate type is a map which does use labels. The `Add`
218  * functions that end in `ToMap` and `ToMapN` are convenient ways to add
219  * labeled data items to a map. You can also call any type of `Add`
220  * function once to add a label of any type and then call any type of
221  * `Add` again to add its value.
222  *
223  * Note that when you nest arrays or maps in a map, the nested array or
224  * map has a label.
225  *
226  * Many CBOR-based protocols start with an array or map. This makes them
227  * self-delimiting. No external length or end marker is needed to know
228  * the end. It is also possible not start this way, in which case this
229  * it is usually called a CBOR sequence which is described in
230  * [RFC 8742] (https://tools.ietf.org/html/rfc8742). This encoder supports
231  * either just by whether the first item added is an array, map or other.
232  *
233  * If QCBOR is compiled with QCBOR_DISABLE_ENCODE_USAGE_GUARDS defined,
234  * the errors QCBOR_ERR_CLOSE_MISMATCH, QCBOR_ERR_ARRAY_TOO_LONG,
235  * QCBOR_ERR_TOO_MANY_CLOSES, QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN, and
236  * QCBOR_ERR_ENCODE_UNSUPPORTED will never be returned. It is up to the
237  * caller to make sure that opened maps, arrays and byte-string wrapping
238  * is closed correctly and that QCBOREncode_AddType7() is called
239  * correctly.  With this defined, it is easier to make a mistake when
240  * authoring the encoding of a protocol that will output not well formed
241  * CBOR, but as long as the calling code is correct, it is safe to
242  * disable these checks. Bounds checking that prevents security issues
243  * in the code is still enforced. This define reduces the size of
244  * encoding object code by about 150 bytes.
245  *
246  * @anchor Tags-Overview
247  *
248  * ## Tags Overview
249  *
250  * Any CBOR data item can be made into a tag to add semantics, define a
251  * new data type or such. Some tags are fully standardized and some are
252  * just registered. Others are not registered and used in a proprietary
253  * way.
254  *
255  * Encoding and decoding of many of the registered tags is fully
256  * implemented by QCBOR. It is also possible to encode and decode tags
257  * that are not directly supported.  For many use cases the built-in tag
258  * support should be adequate.
259  *
260  * For example, the registered epoch date tag is supported in encoding
261  * by QCBOREncode_AddDateEpoch() and in decoding by @ref
262  * QCBOR_TYPE_DATE_EPOCH and the @c epochDate member of @ref
263  * QCBORItem. This is typical of the built-in tag support. There is an
264  * API to encode data for it and a @c QCBOR_TYPE_XXX when it is decoded.
265  *
266  * Tags are registered in the [IANA CBOR Tags Registry]
267  * (https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml). There
268  * are roughly three options to create a new tag. First, a public
269  * specification can be created and the new tag registered with IANA.
270  * This is the most formal. Second, the new tag can be registered with
271  * IANA with just a short description rather than a full specification.
272  * These tags must be greater than 256. Third, a tag can be used without
273  * any IANA registration, though the registry should be checked to see
274  * that the new value doesn't collide with one that is registered. The
275  * value of these tags must be 256 or larger.
276  *
277  * See also @ref CBORTags and @ref Tag-Usage
278  *
279  * The encoding side of tags not built-in is handled by
280  * QCBOREncode_AddTag() and is relatively simple. Tag decoding is more
281  * complex and mainly handled by QCBORDecode_GetNext(). Decoding of the
282  * structure of tagged data not built-in (if there is any) has to be
283  * implemented by the caller.
284  *
285  * @anchor Floating-Point
286  *
287  * ## Floating-Point
288  *
289  * By default QCBOR fully supports IEEE 754 floating-point:
290  *  - Encode/decode of double, single and half-precision
291  *  - CBOR preferred serialization of floating-point
292  *  - Floating-point epoch dates
293  *
294  * For the most part, the type double is used in the interface for
295  * floating-point values. In the default configuration, all decoded
296  * floating-point values are returned as a double.
297  *
298  * With CBOR preferred serialization, the encoder outputs the smallest
299  * representation of the double or float that preserves precision. Zero,
300  * NaN and infinity are always output as a half-precision, each taking
301  * just 2 bytes. This reduces the number of bytes needed to encode
302  * double and single-precision, especially if zero, NaN and infinity are
303  * frequently used.
304  *
305  * To avoid use of preferred serialization in the standard configuration
306  * when encoding, use QCBOREncode_AddDoubleNoPreferred() or
307  * QCBOREncode_AddFloatNoPreferred().
308  *
309  * This implementation of preferred floating-point serialization and
310  * half-precision does not depend on the CPU having floating-point HW or
311  * the compiler bringing in a (sometimes large) library to compensate
312  * for lack of CPU support. This implementation uses shifts and masks
313  * rather than floating-point functions.
314  *
315  * To reduce overall object code by about 900 bytes, define
316  * QCBOR_DISABLE_PREFERRED_FLOAT. This will eliminate all support for
317  * preferred serialization and half-precision. An error will be returned
318  * when attempting to decode half-precision. A float will always be
319  * encoded and decoded as 32-bits and a double will always be encoded
320  * and decoded as 64 bits.
321  *
322  * Note that even if QCBOR_DISABLE_PREFERRED_FLOAT is not defined all
323  * the float-point encoding object code can be avoided by never calling
324  * any functions that encode double or float. Just not calling
325  * floating-point functions will reduce object code by about 500 bytes.
326  *
327  * On CPUs that have no floating-point hardware,
328  * QCBOR_DISABLE_FLOAT_HW_USE should be defined in most cases. If it is
329  * not, then the compiler will bring in possibly large software
330  * libraries to compensate. Defining QCBOR_DISABLE_FLOAT_HW_USE reduces
331  * object code size on CPUs with floating-point hardware by a tiny
332  * amount and eliminates the need for <math.h>
333  *
334  * When QCBOR_DISABLE_FLOAT_HW_USE is defined, trying to decoding
335  * floating-point dates will give error
336  * @ref QCBOR_ERR_FLOAT_DATE_DISABLED and decoded single-precision
337  * numbers will be returned as @ref QCBOR_TYPE_FLOAT instead of
338  * converting them to double as usual.
339  *
340  * If both QCBOR_DISABLE_FLOAT_HW_USE and QCBOR_DISABLE_PREFERRED_FLOAT
341  * are defined, then the only thing QCBOR can do is encode/decode a C
342  * float type as 32-bits and a C double type as 64-bits. Floating-point
343  * epoch dates will be unsupported.
344  *
345  * If USEFULBUF_DISABLE_ALL_FLOAT is defined, then floating point
346  * support is completely disabled. Decoding functions return
347  * @ref QCBOR_ERR_ALL_FLOAT_DISABLED if a floating point value is
348  * encountered during decoding. Functions that are encoding floating
349  * point values are not available.
350  *
351  * ## Limitations
352  *
353  * Summary limitations:
354  * - The entire encoded CBOR must fit into contiguous memory.
355  * - Max size of encoded CBOR data is a few bytes less than
356  *   @c UINT32_MAX (4GB).
357  * - Max array / map nesting level when encoding or decoding is
358  *   @ref QCBOR_MAX_ARRAY_NESTING (this is typically 15).
359  * - Max items in an array or map when encoding or decoding is
360  *   @ref QCBOR_MAX_ITEMS_IN_ARRAY (typically 65,536).
361  * - Does not directly support labels in maps other than text strings & integers.
362  * - Does not directly support integer labels beyond whats fits in @c int64_t
363  *   or @c uint64_t.
364  * - Epoch dates limited to @c INT64_MAX (+/- 292 billion years).
365  * - Exponents for bigfloats and decimal integers are limited to whats fits in
366  *   @c int64_t.
367  * - Tags on labels are ignored during decoding.
368  * - The maximum tag nesting is @c QCBOR_MAX_TAGS_PER_ITEM (typically 4).
369  * - Works only on 32- and 64-bit CPUs.
370  * - QCBORDecode_EnterBstrWrapped() doesn't work on indefinite-length strings.
371  *
372  * The public interface uses @c size_t for all lengths. Internally the
373  * implementation uses 32-bit lengths by design to use less memory and
374  * fit structures on the stack. This limits the encoded CBOR it can
375  * work with to size @c UINT32_MAX (4GB).
376  *
377  * This implementation requires two's compliment integers. While
378  * C doesn't require two's compliment,  <stdint.h> does. Other
379  * parts of this implementation may also require two's compliment.
380  */
381 
382 
383 /**
384  * The size of the buffer to be passed to QCBOREncode_EncodeHead(). It
385  * is one byte larger than sizeof(uint64_t) + 1, the actual maximum
386  * size of the head of a CBOR data item because
387  * QCBOREncode_EncodeHead() needs one extra byte to work.
388  */
389 #define QCBOR_HEAD_BUFFER_SIZE  (sizeof(uint64_t) + 2)
390 
391 
392 /**
393  * Output the full CBOR tag. See @ref CBORTags, @ref Tag-Usage and
394  * @ref Tags-Overview.
395  */
396 #define QCBOR_ENCODE_AS_TAG      0
397 
398 /**
399  * Output only the 'borrowed' content format for the relevant tag.
400  * See @ref CBORTags, @ref Tag-Usage and @ref Tags-Overview.
401  */
402 #define QCBOR_ENCODE_AS_BORROWED 1
403 
404 
405 /**
406  * QCBOREncodeContext is the data type that holds context for all the
407  * encoding functions. It is less than 200 bytes, so it can go on the
408  * stack. The contents are opaque, and the caller should not access
409  * internal members.  A context may be re used serially as long as it is
410  * re initialized.
411  */
412 typedef struct _QCBOREncodeContext QCBOREncodeContext;
413 
414 
415 /**
416  * Initialize the encoder to prepare to encode some CBOR.
417  *
418  * @param[in,out]  pCtx     The encoder context to initialize.
419  * @param[in]      Storage  The buffer into which the encoded result
420  *                          will be written.
421  *
422  * Call this once at the start of an encoding of some CBOR. Then call
423  * the many functions like QCBOREncode_AddInt64() and
424  * QCBOREncode_AddText() to add the different data items. Finally,
425  * call QCBOREncode_Finish() to get the pointer and length of the
426  * encoded result.
427  *
428  * The primary purpose of this function is to give the pointer and
429  * length of the output buffer into which the encoded CBOR will be
430  * written. This is done with a @ref UsefulBuf structure, which is
431  * just a pointer and length (it is equivalent to two parameters, one
432  * a pointer and one a length, but a little prettier).
433  *
434  * The output buffer can be allocated any way (malloc, stack,
435  * static). It is just some memory that QCBOR writes to. The length
436  * must be the length of the allocated buffer. QCBOR will never write
437  * past that length, but might write up to that length. If the buffer
438  * is too small, encoding will go into an error state and not write
439  * anything further.
440  *
441  * If allocating on the stack the convenience macro
442  * UsefulBuf_MAKE_STACK_UB() can be used, but its use is not required.
443  *
444  * Since there is no reallocation or such, the output buffer must be
445  * correctly sized when passed in here. It is OK, but wasteful if it
446  * is too large. One way to pick the size is to figure out the maximum
447  * size that will ever be needed and hard code a buffer of that size.
448  *
449  * Another way to do it is to have QCBOR calculate it for you. To do
450  * this, pass @ref SizeCalculateUsefulBuf for @c Storage.  Then call
451  * all the functions to add the CBOR exactly as if encoding for
452  * real. Finally, call QCBOREncode_FinishGetSize().  Once the length
453  * is obtained, allocate a buffer of that size, call
454  * QCBOREncode_Init() again with the real buffer. Call all the add
455  * functions again and finally, QCBOREncode_Finish() to obtain the
456  * final result. This uses twice the CPU time, but that is usually not
457  * an issue.
458  *
459  * See QCBOREncode_Finish() for how the pointer and length for the
460  * encoded CBOR is returned.
461  *
462  * For practical purposes QCBOR can't output encoded CBOR larger than
463  * @c UINT32_MAX (4GB) even on 64-bit CPUs because the internal
464  * offsets used to track the start of an array/map are 32 bits to
465  * reduce the size of the encoding context.
466  *
467  * A @ref QCBOREncodeContext can be reused over and over as long as
468  * QCBOREncode_Init() is called before each use.
469  */
470 void
471 QCBOREncode_Init(QCBOREncodeContext *pCtx, UsefulBuf Storage);
472 
473 
474 /**
475  * @brief  Add a signed 64-bit integer to the encoded output.
476  *
477  * @param[in] pCtx   The encoding context to add the integer to.
478  * @param[in] nNum   The integer to add.
479  *
480  * The integer will be encoded and added to the CBOR output.
481  *
482  * This function figures out the size and the sign and encodes in the
483  * correct minimal CBOR. Specifically, it will select CBOR major type
484  * 0 or 1 based on sign and will encode to 1, 2, 4 or 8 bytes
485  * depending on the value of the integer. Values less than 24
486  * effectively encode to one byte because they are encoded in with the
487  * CBOR major type.  This is a neat and efficient characteristic of
488  * CBOR that can be taken advantage of when designing CBOR-based
489  * protocols. If integers like tags can be kept between -23 and 23
490  * they will be encoded in one byte including the major type.
491  *
492  * If you pass a smaller int, say an @c int16_t or a small value, say
493  * 100, the encoding will still be CBOR's most compact that can
494  * represent the value.  For example, CBOR always encodes the value 0
495  * as one byte, 0x00. The representation as 0x00 includes
496  * identification of the type as an integer too as the major type for
497  * an integer is 0. See [RFC 8949]
498  * (https://tools.ietf.org/html/rfc8949) Appendix A for more examples
499  * of CBOR encoding. This compact encoding is also preferred
500  * serialization CBOR as per section 34.1 in RFC 8949.
501  *
502  * There are no functions to add @c int16_t or @c int32_t because they
503  * are not necessary because this always encodes to the smallest
504  * number of bytes based on the value (If this code is running on a
505  * 32-bit machine having a way to add 32-bit integers would reduce
506  * code size some).
507  *
508  * If the encoding context is in an error state, this will do
509  * nothing. If an error occurs when adding this integer, the internal
510  * error flag will be set, and the error will be returned when
511  * QCBOREncode_Finish() is called.
512  *
513  * See also QCBOREncode_AddUInt64().
514  */
515 void
516 QCBOREncode_AddInt64(QCBOREncodeContext *pCtx, int64_t nNum);
517 
518 static void
519 QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum);
520 
521 static void
522 QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum);
523 
524 
525 /**
526  * @brief  Add an unsigned 64-bit integer to the encoded output.
527  *
528  * @param[in] pCtx  The encoding context to add the integer to.
529  * @param[in] uNum  The integer to add.
530  *
531  * The integer will be encoded and added to the CBOR output.
532  *
533  * The only reason so use this function is for integers larger than
534  * @c INT64_MAX and smaller than @c UINT64_MAX. Otherwise
535  * QCBOREncode_AddInt64() will work fine.
536  *
537  * Error handling is the same as for QCBOREncode_AddInt64().
538  */
539 static void
540 QCBOREncode_AddUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
541 
542 static void
543 QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum);
544 
545 static void
546 QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum);
547 
548 
549 /**
550  * @brief  Add a UTF-8 text string to the encoded output.
551  *
552  * @param[in] pCtx   The encoding context to add the text to.
553  * @param[in] Text   Pointer and length of text to add.
554  *
555  * The text passed in must be unencoded UTF-8 according to [RFC 3629]
556  * (https://tools.ietf.org/html/rfc3629). There is no NULL
557  * termination. The text is added as CBOR major type 3.
558  *
559  * If called with @c nBytesLen equal to 0, an empty string will be
560  * added. When @c nBytesLen is 0, @c pBytes may be @c NULL.
561  *
562  * Note that the restriction of the buffer length to a @c uint32_t is
563  * entirely intentional as this encoder is not capable of encoding
564  * lengths greater. This limit to 4GB for a text string should not be
565  * a problem.
566  *
567  * Text lines in Internet protocols (on the wire) are delimited by
568  * either a CRLF or just an LF. Officially many protocols specify
569  * CRLF, but implementations often work with either. CBOR type 3 text
570  * can be either line ending, even a mixture of both.
571  *
572  * Operating systems usually have a line end convention. Windows uses
573  * CRLF. Linux and MacOS use LF. Some applications on a given OS may
574  * work with either and some may not.
575  *
576  * The majority of use cases and CBOR protocols using type 3 text will
577  * work with either line ending. However, some use cases or protocols
578  * may not work with either in which case translation to and/or from
579  * the local line end convention, typically that of the OS, is
580  * necessary.
581  *
582  * QCBOR does no line ending translation for type 3 text when encoding
583  * and decoding.
584  *
585  * Error handling is the same as QCBOREncode_AddInt64().
586  */
587 static void
588 QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text);
589 
590 static void
591 QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text);
592 
593 static void
594 QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text);
595 
596 
597 /**
598  * @brief  Add a UTF-8 text string to the encoded output.
599  *
600  * @param[in] pCtx      The encoding context to add the text to.
601  * @param[in] szString  Null-terminated text to add.
602  *
603  * This works the same as QCBOREncode_AddText().
604  */
605 static void
606 QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString);
607 
608 static void
609 QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString);
610 
611 static void
612 QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString);
613 
614 
615 #ifndef USEFULBUF_DISABLE_ALL_FLOAT
616 /**
617  * @brief Add a double-precision floating-point number to the encoded output.
618  *
619  * @param[in] pCtx  The encoding context to add the double to.
620  * @param[in] dNum  The double-precision number to add.
621  *
622  * This encodes and outputs a floating-point number. CBOR major type 7
623  * is used.
624  *
625  * This implements preferred serialization, selectively encoding the
626  * double-precision floating-point number as either double-precision,
627  * single-precision or half-precision. Infinity, NaN and 0 are always
628  * encoded as half-precision. If no precision will be lost in the
629  * conversion to half-precision, then it will be converted and
630  * encoded. If not and no precision will be lost in conversion to
631  * single-precision, then it will be converted and encoded. If not,
632  * then no conversion is performed, and it encoded as a
633  * double-precision.
634  *
635  * Half-precision floating-point numbers take up 2 bytes, half that of
636  * single-precision, one quarter of double-precision
637  *
638  * This automatically reduces the size of encoded CBOR, maybe even by
639  * four if most of values are 0, infinity or NaN.
640  *
641  * When decoded, QCBOR will usually return these values as
642  * double-precision.
643  *
644  * It is possible to disable this preferred serialization when compiling
645  * QCBOR. In that case, this functions the same as
646  * QCBOREncode_AddDoubleNoPreferred().
647  *
648  * Error handling is the same as QCBOREncode_AddInt64().
649  *
650  * See also QCBOREncode_AddDoubleNoPreferred(), QCBOREncode_AddFloat()
651  * and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
652  */
653 static void
654 QCBOREncode_AddDouble(QCBOREncodeContext *pCtx, double dNum);
655 
656 static void
657 QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
658 
659 static void
660 QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
661 
662 
663 /**
664  * @brief Add a single-precision floating-point number to the encoded output.
665  *
666  * @param[in] pCtx  The encoding context to add the double to.
667  * @param[in] fNum  The single-precision number to add.
668  *
669  * This is identical to QCBOREncode_AddDouble() except the input is
670  * single-precision.
671  *
672  * See also QCBOREncode_AddDouble(), QCBOREncode_AddDoubleNoPreferred(),
673  * and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
674  */
675 static void
676 QCBOREncode_AddFloat(QCBOREncodeContext *pCtx, float fNum);
677 
678 static void
679 QCBOREncode_AddFloatToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
680 
681 static void
682 QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float dNum);
683 
684 
685 /**
686  * @brief Add a double-precision floating-point number without preferred encoding.
687  *
688  * @param[in] pCtx  The encoding context to add the double to.
689  * @param[in] dNum  The double-precision number to add.
690  *
691  * This always outputs the number as a 64-bit double-precision.
692  * Preferred serialization is not used.
693  *
694  * Error handling is the same as QCBOREncode_AddInt64().
695  *
696  * See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
697  * QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
698  */
699 static void
700 QCBOREncode_AddDoubleNoPreferred(QCBOREncodeContext *pCtx, double dNum);
701 
702 static void
703 QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
704 
705 static void
706 QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
707 
708 
709 /**
710  * @brief Add a single-precision floating-point number without preferred encoding.
711  *
712  * @param[in] pCtx  The encoding context to add the double to.
713  * @param[in] fNum  The single-precision number to add.
714  *
715  * This always outputs the number as a 32-bit single-precision.
716  * Preferred serialization is not used.
717  *
718  * Error handling is the same as QCBOREncode_AddInt64().
719  *
720  * See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
721  * QCBOREncode_AddDoubleNoPreferred() and @ref Floating-Point.
722  */
723 static void
724 QCBOREncode_AddFloatNoPreferred(QCBOREncodeContext *pCtx, float fNum);
725 
726 static void
727 QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
728 
729 static void
730 QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float fNum);
731 #endif /* USEFULBUF_DISABLE_ALL_FLOAT */
732 
733 
734 /**
735  * @brief Add an optional tag.
736  *
737  * @param[in] pCtx  The encoding context to add the tag to.
738  * @param[in] uTag  The tag to add
739  *
740  * This outputs a CBOR major type 6 item that tags the next data item
741  * that is output usually to indicate it is some new data type.
742  *
743  * For many of the common standard tags, a function to encode data
744  * using it is provided and this is not needed. For example,
745  * QCBOREncode_AddDateEpoch() already exists to output integers
746  * representing dates with the right tag.
747  *
748  * The tag is applied to the next data item added to the encoded
749  * output. That data item that is to be tagged can be of any major
750  * CBOR type. Any number of tags can be added to a data item by
751  * calling this multiple times before the data item is added.
752  *
753  * See @ref Tags-Overview for discussion of creating new non-standard
754  * tags. See QCBORDecode_GetNext() for discussion of decoding custom
755  * tags.
756  */
757 static void
758 QCBOREncode_AddTag(QCBOREncodeContext *pCtx, uint64_t uTag);
759 
760 
761 /**
762  * @brief  Add an epoch-based date.
763  *
764  * @param[in] pCtx             The encoding context to add the date to.
765  * @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or
766  *                             @ref QCBOR_ENCODE_AS_BORROWED.
767  * @param[in] nDate            Number of seconds since 1970-01-01T00:00Z
768  *                             in UTC time.
769  *
770  * As per RFC 8949 this is similar to UNIX/Linux/POSIX dates. This is
771  * the most compact way to specify a date and time in CBOR. Note that
772  * this is always UTC and does not include the time zone.  Use
773  * QCBOREncode_AddDateString() if you want to include the time zone.
774  *
775  * The preferred integer serialization rules apply here so the date will be
776  * encoded in a minimal number of bytes. Until about the year 2106
777  * these dates will encode in 6 bytes -- one byte for the tag, one
778  * byte for the type and 4 bytes for the integer. After that it will
779  * encode to 10 bytes.
780  *
781  * Negative values are supported for dates before 1970.
782  *
783  * If you care about leap-seconds and that level of accuracy, make sure
784  * the system you are running this code on does it correctly. This code
785  * just takes the value passed in.
786  *
787  * This implementation cannot encode fractional seconds using float or
788  * double even though that is allowed by CBOR, but you can encode them
789  * if you want to by calling QCBOREncode_AddTag() and QCBOREncode_AddDouble().
790  *
791  * Error handling is the same as QCBOREncode_AddInt64().
792  *
793  * See also QCBOREncode_AddTDaysEpoch().
794  */
795 static void
796 QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pCtx,
797                           uint8_t             uTagRequirement,
798                           int64_t             nDate);
799 
800 static void
801 QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pCtx,
802                                  const char         *szLabel,
803                                  uint8_t             uTagRequirement,
804                                  int64_t             nDate);
805 
806 static void
807 QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pCtx,
808                                 int64_t             nLabel,
809                                 uint8_t             uTagRequirement,
810                                 int64_t             nDate);
811 
812 
813 static void
814 QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx,
815                          int64_t             nDate);
816 
817 static void
818 QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx,
819                               const char         *szLabel,
820                               int64_t             nDate);
821 
822 static void
823 QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx,
824                                int64_t             nLabel,
825                                int64_t             nDate);
826 
827 
828 
829 /**
830  *  @brief  Add an epoch-based day-count date.
831  *
832  *  @param[in] pCtx             The encoding context to add the date to.
833  *  @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or
834  *                              @ref QCBOR_ENCODE_AS_BORROWED.
835  *  @param[in] nDays            Number of days before or after 1970-01-0.
836  *
837  * This date format is described in
838  * [RFC 8943] (https://tools.ietf.org/html/rfc8943).
839  *
840  * The preferred integer serialization rules apply here so the date
841  * will be encoded in a minimal number of bytes. Until about the year
842  * 2149 these dates will encode in 4 bytes -- one byte for the tag,
843  * one byte for the type and 2 bytes for the integer.
844  *
845  * See also QCBOREncode_AddTDateEpoch().
846  */
847 static void
848 QCBOREncode_AddTDaysEpoch(QCBOREncodeContext *pCtx,
849                           uint8_t             uTagRequirement,
850                           int64_t             nDays);
851 
852 static void
853 QCBOREncode_AddTDaysEpochToMapSZ(QCBOREncodeContext *pCtx,
854                                  const char         *szLabel,
855                                  uint8_t             uTagRequirement,
856                                  int64_t             nDays);
857 
858 static void
859 QCBOREncode_AddTDaysEpochToMapN(QCBOREncodeContext *pCtx,
860                                 int64_t             nLabel,
861                                 uint8_t             uTagRequirement,
862                                 int64_t             nDays);
863 
864 
865 
866 
867 /**
868  * @brief Add a byte string to the encoded output.
869  *
870  * @param[in] pCtx   The encoding context to add the bytes to.
871  * @param[in] Bytes  Pointer and length of the input data.
872  *
873  * Simply adds the bytes to the encoded output as CBOR major type 2.
874  *
875  * If called with @c Bytes.len equal to 0, an empty string will be
876  * added. When @c Bytes.len is 0, @c Bytes.ptr may be @c NULL.
877  *
878  * Error handling is the same as QCBOREncode_AddInt64().
879  */
880 static void
881 QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
882 
883 static void
884 QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
885 
886 static void
887 QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
888 
889 
890 /**
891  * @brief Set up to write a byte string value directly to encoded output.
892  *
893  * @param[in] pCtx     The encoding context to add the bytes to.
894  * @param[out] pPlace  Pointer and length of place to write byte string value.
895  *
896  * QCBOREncode_AddBytes() is the normal way to encode a byte string.
897  * This is for special cases and by passes some of the pointer safety.
898  *
899  * The purpose of this is to output the bytes that make up a byte
900  * string value directly to the QCBOR output buffer so you don't need
901  * to have a copy of it in memory. This is particularly useful if the
902  * byte string is large, for example, the encrypted payload of a
903  * COSE_Encrypt message. The payload encryption algorithm can output
904  * directly to the encoded CBOR buffer, perhaps by making it the
905  * output buffer for some function (e.g. symmetric encryption) or by
906  * multiple writes.
907  *
908  * The pointer in @c pPlace is where to start writing. Writing is just
909  * copying bytes to the location by the pointer in \c pPlace.  Writing
910  * past the length in @c pPlace will be writing off the end of the
911  * output buffer.
912  *
913  * If there is no room in the output buffer @ref NULLUsefulBuf will be
914  * returned and there is no need to call QCBOREncode_CloseBytes().
915  *
916  * The byte string must be closed by calling QCBOREncode_CloseBytes().
917  *
918  * Warning: this bypasses some of the usual checks provided by QCBOR
919  * against writing off the end of the encoded output buffer.
920  */
921 void
922 QCBOREncode_OpenBytes(QCBOREncodeContext *pCtx, UsefulBuf *pPlace);
923 
924 static void
925 QCBOREncode_OpenBytesInMapSZ(QCBOREncodeContext *pCtx,
926                              const char         *szLabel,
927                              UsefulBuf          *pPlace);
928 
929 static void
930 QCBOREncode_OpenBytesInMapN(QCBOREncodeContext *pCtx,
931                             int64_t             nLabel,
932                             UsefulBuf          *pPlace);
933 
934 
935 /**
936  *  @brief Close out a byte string written directly to encoded output.
937  *
938  *  @param[in] pCtx      The encoding context to add the bytes to.
939  *  @param[out] uAmount  The number of bytes written, the length of the
940  *                       byte string.
941  *
942  * This closes out a call to QCBOREncode_OpenBytes().  This inserts a
943  * CBOR header at the front of the byte string value to make it a
944  * well-formed byte string.
945  *
946  * If there was no call to QCBOREncode_OpenBytes() then @ref
947  * QCBOR_ERR_TOO_MANY_CLOSES is set.
948  */
949 void
950 QCBOREncode_CloseBytes(QCBOREncodeContext *pCtx, size_t uAmount);
951 
952 
953 /**
954  * @brief Add a binary UUID to the encoded output.
955  *
956  * @param[in] pCtx             The encoding context to add the UUID to.
957  * @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or
958  *                             @ref QCBOR_ENCODE_AS_BORROWED.
959  * @param[in] Bytes            Pointer and length of the binary UUID.
960  *
961  * A binary UUID as defined in [RFC 4122]
962  * (https://tools.ietf.org/html/rfc4122) is added to the output.
963  *
964  * It is output as CBOR major type 2, a binary string, with tag @ref
965  * CBOR_TAG_BIN_UUID indicating the binary string is a UUID.
966  */
967 static void
968 QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pCtx,
969                            uint8_t             uTagRequirement,
970                            UsefulBufC          Bytes);
971 
972 static void
973 QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pCtx,
974                                   const char         *szLabel,
975                                   uint8_t             uTagRequirement,
976                                   UsefulBufC          Bytes);
977 
978 static void
979 QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pCtx,
980                                  int64_t             nLabel,
981                                  uint8_t             uTagRequirement,
982                                  UsefulBufC          Bytes);
983 
984 
985 static void
986 QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
987 
988 static void
989 QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
990 
991 static void
992 QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
993 
994 
995 /**
996  * @brief Add a positive big number to the encoded output.
997  *
998  * @param[in] pCtx             The encoding context to add the big number to.
999  * @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or
1000  *                             @ref QCBOR_ENCODE_AS_BORROWED.
1001  * @param[in] Bytes            Pointer and length of the big number.
1002  *
1003  * Big numbers are integers larger than 64-bits. Their format is
1004  * described in [RFC 8949] (https://tools.ietf.org/html/rfc8949).
1005  *
1006  * It is output as CBOR major type 2, a binary string, with tag
1007  * @ref CBOR_TAG_POS_BIGNUM indicating the binary string is a positive
1008  * big number.
1009  *
1010  * Often big numbers are used to represent cryptographic keys,
1011  * however, COSE which defines representations for keys chose not to
1012  * use this particular type.
1013  */
1014 static void
1015 QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pCtx,
1016                                uint8_t             uTagRequirement,
1017                                UsefulBufC          Bytes);
1018 
1019 static void
1020 QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pCtx,
1021                                       const char         *szLabel,
1022                                       uint8_t             uTagRequirement,
1023                                       UsefulBufC          Bytes);
1024 
1025 static void
1026 QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pCtx,
1027                                      int64_t             nLabel,
1028                                      uint8_t             uTagRequirement,
1029                                      UsefulBufC          Bytes);
1030 
1031 
1032 static void
1033 QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx,
1034                              UsefulBufC          Bytes);
1035 
1036 static void
1037 QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx,
1038                                    const char         *szLabel,
1039                                    UsefulBufC          Bytes);
1040 
1041 static void
1042 QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx,
1043                                     int64_t             nLabel,
1044                                     UsefulBufC          Bytes);
1045 
1046 
1047 /**
1048  * @brief Add a negative big number to the encoded output.
1049  *
1050  * @param[in] pCtx             The encoding context to add the big number to.
1051  * @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or
1052  *                             @ref QCBOR_ENCODE_AS_BORROWED.
1053  * @param[in] Bytes            Pointer and length of the big number.
1054  *
1055  * Big numbers are integers larger than 64-bits. Their format is
1056  * described in [RFC 8949] (https://tools.ietf.org/html/rfc8949).
1057  *
1058  * It is output as CBOR major type 2, a binary string, with tag
1059  * @ref CBOR_TAG_NEG_BIGNUM indicating the binary string is a negative
1060  * big number.
1061  *
1062  * Often big numbers are used to represent cryptographic keys,
1063  * however, COSE which defines representations for keys chose not to
1064  * use this particular type.
1065  */
1066 static void
1067 QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pCtx,
1068                                uint8_t             uTagRequirement,
1069                                UsefulBufC          Bytes);
1070 
1071 static void
1072 QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pCtx,
1073                                       const char         *szLabel,
1074                                       uint8_t             uTagRequirement,
1075                                       UsefulBufC          Bytes);
1076 
1077 static void
1078 QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pCtx,
1079                                      int64_t             nLabel,
1080                                      uint8_t             uTagRequirement,
1081                                      UsefulBufC          Bytes);
1082 
1083 
1084 static void
1085 QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx,
1086                               UsefulBufC          Bytes);
1087 
1088 static void
1089 QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx,
1090                                    const char         *szLabel,
1091                                    UsefulBufC          Bytes);
1092 
1093 static void
1094 QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx,
1095                                     int64_t             nLabel,
1096                                     UsefulBufC          Bytes);
1097 
1098 
1099 #ifndef QCBOR_DISABLE_EXP_AND_MANTISSA
1100 /**
1101  * @brief Add a decimal fraction to the encoded output.
1102  *
1103  * @param[in] pCtx             Encoding context to add the decimal fraction to.
1104  * @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or
1105  *                             @ref QCBOR_ENCODE_AS_BORROWED.
1106  * @param[in] nMantissa        The mantissa.
1107  * @param[in] nBase10Exponent  The exponent.
1108  *
1109  * The value is nMantissa * 10 ^ nBase10Exponent.
1110  *
1111  * A decimal fraction is good for exact representation of some values
1112  * that can't be represented exactly with standard C (IEEE 754)
1113  * floating-point numbers.  Much larger and much smaller numbers can
1114  * also be represented than floating-point because of the larger
1115  * number of bits in the exponent.
1116  *
1117  * The decimal fraction is conveyed as two integers, a mantissa and a
1118  * base-10 scaling factor.
1119  *
1120  * For example, 273.15 is represented by the two integers 27315 and -2.
1121  *
1122  * The exponent and mantissa have the range from @c INT64_MIN to
1123  * @c INT64_MAX for both encoding and decoding (CBOR allows
1124  * @c -UINT64_MAX to @c UINT64_MAX, but this implementation doesn't
1125  * support this range to reduce code size and interface complexity a
1126  * little).
1127  *
1128  * CBOR Preferred serialization of the integers is used, thus they
1129  * will be encoded in the smallest number of bytes possible.
1130  *
1131  * See also QCBOREncode_AddDecimalFractionBigNum() for a decimal
1132  * fraction with arbitrarily large precision and
1133  * QCBOREncode_AddBigFloat().
1134  *
1135  * There is no representation of positive or negative infinity or NaN
1136  * (Not a Number). Use QCBOREncode_AddDouble() to encode them.
1137  *
1138  * See @ref expAndMantissa for decoded representation.
1139  */
1140 static void
1141 QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pCtx,
1142                                 uint8_t             uTagRequirement,
1143                                 int64_t             nMantissa,
1144                                 int64_t             nBase10Exponent);
1145 
1146 static void
1147 QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pCtx,
1148                                        const char         *szLabel,
1149                                        uint8_t             uTagRequirement,
1150                                        int64_t             nMantissa,
1151                                        int64_t             nBase10Exponent);
1152 
1153 static void
1154 QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pCtx,
1155                                       int64_t             nLabel,
1156                                       uint8_t             uTagRequirement,
1157                                       int64_t             nMantissa,
1158                                       int64_t             nBase10Exponent);
1159 
1160 
1161 static void
1162 QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pCtx,
1163                                int64_t             nMantissa,
1164                                int64_t             nBase10Exponent);
1165 
1166 static void
1167 QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pCtx,
1168                                     const char         *szLabel,
1169                                     int64_t             nMantissa,
1170                                     int64_t             nBase10Exponent);
1171 
1172 static void
1173 QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pCtx,
1174                                      int64_t             nLabel,
1175                                      int64_t             nMantissa,
1176                                      int64_t             nBase10Exponent);
1177 
1178 
1179 /**
1180  * @brief Add a decimal fraction with a big number mantissa to the encoded output.
1181  *
1182  * @param[in] pCtx             Encoding context to add the decimal fraction to.
1183  * @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or
1184  *                             @ref QCBOR_ENCODE_AS_BORROWED.
1185  * @param[in] Mantissa         The mantissa.
1186  * @param[in] bIsNegative      false if mantissa is positive, true if negative.
1187  * @param[in] nBase10Exponent  The exponent.
1188  *
1189  * This is the same as QCBOREncode_AddDecimalFraction() except the
1190  * mantissa is a big number (See QCBOREncode_AddPositiveBignum())
1191  * allowing for arbitrarily large precision.
1192  *
1193  * See @ref expAndMantissa for decoded representation.
1194  */
1195 static void
1196 QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pCtx,
1197                                       uint8_t             uTagRequirement,
1198                                       UsefulBufC          Mantissa,
1199                                       bool                bIsNegative,
1200                                       int64_t             nBase10Exponent);
1201 
1202 static void
1203 QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
1204                                              const char         *szLabel,
1205                                              uint8_t             uTagRequirement,
1206                                              UsefulBufC          Mantissa,
1207                                              bool                bIsNegative,
1208                                              int64_t             nBase10Exponent);
1209 
1210 static void
1211 QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
1212                                             int64_t             nLabel,
1213                                             uint8_t             uTagRequirement,
1214                                             UsefulBufC          Mantissa,
1215                                             bool                bIsNegative,
1216                                             int64_t             nBase10Exponent);
1217 
1218 
1219 static void
1220 QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pCtx,
1221                                      UsefulBufC          Mantissa,
1222                                      bool                bIsNegative,
1223                                      int64_t             nBase10Exponent);
1224 
1225 static void
1226 QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
1227                                             const char         *szLabel,
1228                                             UsefulBufC          Mantissa,
1229                                             bool                bIsNegative,
1230                                             int64_t             nBase10Exponent);
1231 
1232 static void
1233 QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
1234                                            int64_t             nLabel,
1235                                            UsefulBufC          Mantissa,
1236                                            bool                bIsNegative,
1237                                            int64_t             nBase10Exponent);
1238 
1239 /**
1240  * @brief Add a big floating-point number to the encoded output.
1241  *
1242  * @param[in] pCtx             The encoding context to add the bigfloat to.
1243  * @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or
1244  *                             @ref QCBOR_ENCODE_AS_BORROWED.
1245  * @param[in] nMantissa        The mantissa.
1246  * @param[in] nBase2Exponent   The exponent.
1247  *
1248  * The value is nMantissa * 2 ^ nBase2Exponent.
1249  *
1250  * "Bigfloats", as CBOR terms them, are similar to IEEE floating-point
1251  * numbers in having a mantissa and base-2 exponent, but they are not
1252  * supported by hardware or encoded the same. They explicitly use two
1253  * CBOR-encoded integers to convey the mantissa and exponent, each of
1254  * which can be 8, 16, 32 or 64 bits. With both the mantissa and
1255  * exponent 64 bits they can express more precision and a larger range
1256  * than an IEEE double floating-point number. See
1257  * QCBOREncode_AddBigFloatBigNum() for even more precision.
1258  *
1259  * For example, 1.5 would be represented by a mantissa of 3 and an
1260  * exponent of -1.
1261  *
1262  * The exponent and mantissa have the range from @c INT64_MIN to
1263  * @c INT64_MAX for both encoding and decoding (CBOR allows @c
1264  * -UINT64_MAX to @c UINT64_MAX, but this implementation doesn't
1265  * support this range to reduce code size and interface complexity a
1266  * little).
1267  *
1268  * CBOR preferred serialization of the integers is used, thus they will
1269  * be encoded in the smallest number of bytes possible.
1270  *
1271  * This can also be used to represent floating-point numbers in
1272  * environments that don't support IEEE 754.
1273  *
1274  * See @ref expAndMantissa for decoded representation.
1275  */
1276 static void
1277 QCBOREncode_AddTBigFloat(QCBOREncodeContext *pCtx,
1278                          uint8_t             uTagRequirement,
1279                          int64_t             nMantissa,
1280                          int64_t             nBase2Exponent);
1281 
1282 static void
1283 QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pCtx,
1284                                 const char         *szLabel,
1285                                 uint8_t             uTagRequirement,
1286                                 int64_t             nMantissa,
1287                                 int64_t             nBase2Exponent);
1288 
1289 static void
1290 QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pCtx,
1291                                int64_t             nLabel,
1292                                uint8_t             uTagRequirement,
1293                                int64_t             nMantissa,
1294                                int64_t             nBase2Exponent);
1295 
1296 
1297 static void
1298 QCBOREncode_AddBigFloat(QCBOREncodeContext *pCtx,
1299                         int64_t             nMantissa,
1300                         int64_t             nBase2Exponent);
1301 
1302 static void
1303 QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pCtx,
1304                              const char         *szLabel,
1305                              int64_t             nMantissa,
1306                              int64_t             nBase2Exponent);
1307 
1308 static void
1309 QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pCtx,
1310                               int64_t             nLabel,
1311                               int64_t             nMantissa,
1312                               int64_t             nBase2Exponent);
1313 
1314 /**
1315  * @brief Add a big floating-point number with a big number mantissa to
1316  *        the encoded output.
1317  *
1318  * @param[in] pCtx             The encoding context to add the bigfloat to.
1319  * @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or
1320  *                             @ref QCBOR_ENCODE_AS_BORROWED.
1321  * @param[in] Mantissa         The mantissa.
1322  * @param[in] bIsNegative      false if mantissa is positive, true if negative.
1323  * @param[in] nBase2Exponent   The exponent.
1324  *
1325  * This is the same as QCBOREncode_AddBigFloat() except the mantissa
1326  * is a big number (See QCBOREncode_AddPositiveBignum()) allowing for
1327  * arbitrary precision.
1328  *
1329  * See @ref expAndMantissa for decoded representation.
1330  */
1331 static void
1332 QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pCtx,
1333                                uint8_t             uTagRequirement,
1334                                UsefulBufC          Mantissa,
1335                                bool                bIsNegative,
1336                                int64_t             nBase2Exponent);
1337 
1338 static void
1339 QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pCtx,
1340                                       const char         *szLabel,
1341                                       uint8_t             uTagRequirement,
1342                                       UsefulBufC          Mantissa,
1343                                       bool                bIsNegative,
1344                                       int64_t             nBase2Exponent);
1345 
1346 static void
1347 QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1348                                      int64_t             nLabel,
1349                                      uint8_t             uTagRequirement,
1350                                      UsefulBufC          Mantissa,
1351                                      bool                bIsNegative,
1352                                      int64_t             nBase2Exponent);
1353 
1354 
1355 static void
1356 QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pCtx,
1357                               UsefulBufC          Mantissa,
1358                               bool                bIsNegative,
1359                               int64_t             nBase2Exponent);
1360 
1361 static void
1362 QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pCtx,
1363                                    const char         *szLabel,
1364                                    UsefulBufC          Mantissa,
1365                                    bool                bIsNegative,
1366                                    int64_t             nBase2Exponent);
1367 
1368 static void
1369 QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1370                                     int64_t             nLabel,
1371                                     UsefulBufC          Mantissa,
1372                                     bool                bIsNegative,
1373                                     int64_t             nBase2Exponent);
1374 #endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
1375 
1376 
1377 /**
1378  * @brief Add a text URI to the encoded output.
1379  *
1380  * @param[in] pCtx             The encoding context to add the URI to.
1381  * @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or
1382  *                             @ref QCBOR_ENCODE_AS_BORROWED.
1383  * @param[in] URI              Pointer and length of the URI.
1384  *
1385  * The format of URI must be per [RFC 3986]
1386  * (https://tools.ietf.org/html/rfc3986).
1387  *
1388  * It is output as CBOR major type 3, a text string, with tag @ref
1389  * CBOR_TAG_URI indicating the text string is a URI.
1390  *
1391  * A URI in a NULL-terminated string, @c szURI, can be easily added with
1392  * this code:
1393  *
1394  *      QCBOREncode_AddURI(pCtx, UsefulBuf_FromSZ(szURI));
1395  */
1396 static void
1397 QCBOREncode_AddTURI(QCBOREncodeContext *pCtx,
1398                     uint8_t             uTagRequirement,
1399                     UsefulBufC          URI);
1400 
1401 static void
1402 QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pCtx,
1403                            const char         *szLabel,
1404                            uint8_t             uTagRequirement,
1405                            UsefulBufC          URI);
1406 
1407 static void
1408 QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pCtx,
1409                           int64_t             nLabel,
1410                           uint8_t             uTagRequirement,
1411                           UsefulBufC          URI);
1412 
1413 
1414 static void
1415 QCBOREncode_AddURI(QCBOREncodeContext *pCtx,
1416                    UsefulBufC          URI);
1417 
1418 static void
1419 QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx,
1420                         const char         *szLabel,
1421                         UsefulBufC          URI);
1422 
1423 static void
1424 QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx,
1425                          int64_t             nLabel,
1426                          UsefulBufC          URI);
1427 
1428 
1429 /**
1430  * @brief Add Base64-encoded text to encoded output.
1431  *
1432  * @param[in] pCtx             The encoding context to add the base-64 text to.
1433  * @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or
1434  *                             @ref QCBOR_ENCODE_AS_BORROWED.
1435  * @param[in] B64Text          Pointer and length of the base-64 encoded text.
1436  *
1437  * The text content is Base64 encoded data per [RFC 4648]
1438  * (https://tools.ietf.org/html/rfc4648).
1439  *
1440  * It is output as CBOR major type 3, a text string, with tag @ref
1441  * CBOR_TAG_B64 indicating the text string is Base64 encoded.
1442  */
1443 static void
1444 QCBOREncode_AddTB64Text(QCBOREncodeContext *pCtx,
1445                         uint8_t             uTagRequirement,
1446                                     UsefulBufC          B64Text);
1447 
1448 static void
1449 QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pCtx,
1450                                const char         *szLabel,
1451                                uint8_t             uTagRequirement,
1452                                UsefulBufC          B64Text);
1453 
1454 static void
1455 QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pCtx,
1456                               int64_t nLabel,
1457                               uint8_t uTagRequirement,
1458                               UsefulBufC B64Text);
1459 
1460 
1461 static void
1462 QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx,
1463                        UsefulBufC          B64Text);
1464 
1465 static void
1466 QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx,
1467                             const char         *szLabel,
1468                             UsefulBufC          B64Text);
1469 
1470 static void
1471 QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx,
1472                              int64_t             nLabel,
1473                              UsefulBufC          B64Text);
1474 
1475 
1476 
1477 /**
1478  * @brief Add base64url encoded data to encoded output.
1479  *
1480  * @param[in] pCtx             The encoding context to add the base64url to.
1481  * @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or
1482  *                             @ref QCBOR_ENCODE_AS_BORROWED.
1483  * @param[in] B64Text          Pointer and length of the base64url encoded text.
1484  *
1485  * The text content is base64URL encoded text as per [RFC 4648]
1486  * (https://tools.ietf.org/html/rfc4648).
1487  *
1488  * It is output as CBOR major type 3, a text string, with tag
1489  * @ref CBOR_TAG_B64URL indicating the text string is a Base64url
1490  * encoded.
1491  */
1492 static void
1493 QCBOREncode_AddTB64URLText(QCBOREncodeContext *pCtx,
1494                            uint8_t             uTagRequirement,
1495                            UsefulBufC          B64Text);
1496 
1497 static void
1498 QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pCtx,
1499                                   const char         *szLabel,
1500                                   uint8_t             uTagRequirement,
1501                                   UsefulBufC          B64Text);
1502 
1503 static void
1504 QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pCtx,
1505                                  int64_t             nLabel,
1506                                  uint8_t             uTagRequirement,
1507                                  UsefulBufC          B64Text);
1508 
1509 
1510 static void
1511 QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx,
1512                           UsefulBufC          B64Text);
1513 
1514 static void
1515 QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx,
1516                                const char         *szLabel,
1517                                UsefulBufC          B64Text);
1518 
1519 static void
1520 QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx,
1521                                 int64_t             nLabel,
1522                                 UsefulBufC          B64Text);
1523 
1524 
1525 /**
1526  * @brief Add Perl Compatible Regular Expression.
1527  *
1528  * @param[in] pCtx             Encoding context to add the regular expression to.
1529  * @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or
1530  *                             @ref QCBOR_ENCODE_AS_BORROWED.
1531  * @param[in] Regex            Pointer and length of the regular expression.
1532  *
1533  * The text content is Perl Compatible Regular
1534  * Expressions (PCRE) / JavaScript syntax [ECMA262].
1535  *
1536  * It is output as CBOR major type 3, a text string, with tag @ref
1537  * CBOR_TAG_REGEX indicating the text string is a regular expression.
1538  */
1539 static void
1540 QCBOREncode_AddTRegex(QCBOREncodeContext *pCtx,
1541                       uint8_t            uTagRequirement,
1542                       UsefulBufC         Regex);
1543 
1544 static void
1545 QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pCtx,
1546                              const char         *szLabel,
1547                              uint8_t             uTagRequirement,
1548                              UsefulBufC          Regex);
1549 
1550 static void
1551 QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pCtx,
1552                             int64_t             nLabel,
1553                             uint8_t             uTagRequirement,
1554                             UsefulBufC          Regex);
1555 
1556 
1557 static void
1558 QCBOREncode_AddRegex(QCBOREncodeContext *pCtx,
1559                      UsefulBufC          Regex);
1560 
1561 static void
1562 QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx,
1563                           const char         *szLabel,
1564                           UsefulBufC          Regex);
1565 
1566 static void
1567 QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx,
1568                            int64_t             nLabel,
1569                            UsefulBufC          Regex);
1570 
1571 
1572 /**
1573  * @brief MIME encoded data to the encoded output.
1574  *
1575  * @param[in] pCtx             The encoding context to add the MIME data to.
1576  * @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or
1577  *                             @ref QCBOR_ENCODE_AS_BORROWED.
1578  * @param[in] MIMEData         Pointer and length of the MIME data.
1579  *
1580  * The text content is in MIME format per [RFC 2045]
1581  * (https://tools.ietf.org/html/rfc2045) including the headers.
1582  *
1583  * It is output as CBOR major type 2, a binary string, with tag
1584  * @ref CBOR_TAG_BINARY_MIME indicating the string is MIME data.  This
1585  * outputs tag 257, not tag 36, as it can carry any type of MIME
1586  * binary, 7-bit, 8-bit, quoted-printable and base64 where tag 36
1587  * cannot.
1588  *
1589  * Previous versions of QCBOR, those before spiffy decode, output tag
1590  * 36. Decoding supports both tag 36 and 257.  (if the old behavior
1591  * with tag 36 is needed, copy the inline functions below and change
1592  * the tag number).
1593  *
1594  * See also QCBORDecode_GetMIMEMessage() and
1595  * @ref QCBOR_TYPE_BINARY_MIME.
1596  *
1597  * This does no translation of line endings. See QCBOREncode_AddText()
1598  * for a discussion of line endings in CBOR.
1599  */
1600 static void
1601 QCBOREncode_AddTMIMEData(QCBOREncodeContext *pCtx,
1602                          uint8_t             uTagRequirement,
1603                          UsefulBufC          MIMEData);
1604 
1605 static void
1606 QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pCtx,
1607                                 const char         *szLabel,
1608                                 uint8_t             uTagRequirement,
1609                                 UsefulBufC          MIMEData);
1610 
1611 static void
1612 QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pCtx,
1613                                int64_t             nLabel,
1614                                uint8_t             uTagRequirement,
1615                                UsefulBufC          MIMEData);
1616 
1617 
1618 static void
1619 QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx,
1620                         UsefulBufC          MIMEData);
1621 
1622 static void
1623 QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx,
1624                              const char         *szLabel,
1625                              UsefulBufC          MIMEData);
1626 
1627 static void
1628 QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx,
1629                               int64_t             nLabel,
1630                               UsefulBufC          MIMEData);
1631 
1632 
1633 /**
1634  * @brief  Add an RFC 3339 date string
1635  *
1636  * @param[in] pCtx             The encoding context to add the date to.
1637  * @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or
1638  *                             @ref QCBOR_ENCODE_AS_BORROWED.
1639  * @param[in] szDate           Null-terminated string with date to add.
1640  *
1641  * The string szDate should be in the form of [RFC 3339]
1642  * (https://tools.ietf.org/html/rfc3339) as defined by section 3.3 in
1643  * [RFC 4287] (https://tools.ietf.org/html/rfc4287). This is as
1644  * described in section 3.4.1 in [RFC 8949]
1645  * (https://tools.ietf.org/html/rfc8949).
1646  *
1647  * Note that this function doesn't validate the format of the date
1648  * string at all. If you add an incorrect format date string, the
1649  * generated CBOR will be incorrect and the receiver may not be able
1650  * to handle it.
1651  *
1652  * Error handling is the same as QCBOREncode_AddInt64().
1653  *
1654  * See also QCBOREncode_AddTDayString().
1655  */
1656 static void
1657 QCBOREncode_AddTDateString(QCBOREncodeContext *pCtx,
1658                            uint8_t             uTagRequirement,
1659                            const char         *szDate);
1660 
1661 static void
1662 QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pCtx,
1663                                   const char         *szLabel,
1664                                   uint8_t             uTagRequirement,
1665                                   const char         *szDate);
1666 
1667 static void
1668 QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pCtx,
1669                                  int64_t             nLabel,
1670                                  uint8_t             uTagRequirement,
1671                                  const char         *szDate);
1672 
1673 
1674 static void
1675 QCBOREncode_AddDateString(QCBOREncodeContext *pCtx,
1676                           const char         *szDate);
1677 
1678 static void
1679 QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx,
1680                                const char         *szLabel,
1681                                const char         *szDate);
1682 
1683 static void
1684 QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx,
1685                                 int64_t             nLabel,
1686                                 const char         *szDate);
1687 
1688 
1689 /**
1690  * @brief  Add a date-only string.
1691  *
1692  * @param[in] pCtx             The encoding context to add the date to.
1693  * @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or
1694  *                             @ref QCBOR_ENCODE_AS_BORROWED.
1695  * @param[in] szDate           Null-terminated string with date to add.
1696  *
1697  * This date format is described in
1698  * [RFC 8943] (https://tools.ietf.org/html/rfc8943), but that mainly
1699  * references RFC 3339.  The string szDate must be in the forrm
1700  * specified the ABNF for a full-date in
1701  * [RFC 3339] (https://tools.ietf.org/html/rfc3339). Examples of this
1702  * are "1985-04-12" and "1937-01-01".  The time and the time zone are
1703  * never included.
1704  *
1705  * Note that this function doesn't validate the format of the date
1706  * string at all. If you add an incorrect format date string, the
1707  * generated CBOR will be incorrect and the receiver may not be able
1708  * to handle it.
1709  *
1710  * Error handling is the same as QCBOREncode_AddInt64().
1711  *
1712  * See also QCBOREncode_AddTDateString().
1713  */
1714 static void
1715 QCBOREncode_AddTDaysString(QCBOREncodeContext *pCtx,
1716                            uint8_t             uTagRequirement,
1717                            const char         *szDate);
1718 
1719 static void
1720 QCBOREncode_AddTDaysStringToMapSZ(QCBOREncodeContext *pCtx,
1721                                   const char         *szLabel,
1722                                   uint8_t             uTagRequirement,
1723                                   const char         *szDate);
1724 
1725 static void
1726 QCBOREncode_AddTDaysStringToMapN(QCBOREncodeContext *pCtx,
1727                                  int64_t             nLabel,
1728                                  uint8_t             uTagRequirement,
1729                                  const char         *szDate);
1730 
1731 
1732 /**
1733  * @brief  Add a standard Boolean.
1734  *
1735  * @param[in] pCtx  The encoding context to add the Boolean to.
1736  * @param[in] b     true or false from @c <stdbool.h>.
1737  *
1738  * Adds a Boolean value as CBOR major type 7.
1739  *
1740  * Error handling is the same as QCBOREncode_AddInt64().
1741  */
1742 static void
1743 QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b);
1744 
1745 static void
1746 QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b);
1747 
1748 static void
1749 QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b);
1750 
1751 
1752 /**
1753  * @brief  Add a NULL to the encoded output.
1754  *
1755  * @param[in] pCtx  The encoding context to add the NULL to.
1756  *
1757  * Adds the NULL value as CBOR major type 7.
1758  *
1759  * This NULL doesn't have any special meaning in CBOR such as a
1760  * terminating value for a string or an empty value.
1761  *
1762  * Error handling is the same as QCBOREncode_AddInt64().
1763  */
1764 static void
1765 QCBOREncode_AddNULL(QCBOREncodeContext *pCtx);
1766 
1767 static void
1768 QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1769 
1770 static void
1771 QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1772 
1773 
1774 /**
1775  * @brief  Add an "undef" to the encoded output.
1776  *
1777  * @param[in] pCtx  The encoding context to add the "undef" to.
1778  *
1779  * Adds the undef value as CBOR major type 7.
1780  *
1781  * Note that this value will not translate to JSON.
1782  *
1783  * This Undef doesn't have any special meaning in CBOR such as a
1784  * terminating value for a string or an empty value.
1785  *
1786  * Error handling is the same as QCBOREncode_AddInt64().
1787  */
1788 static void
1789 QCBOREncode_AddUndef(QCBOREncodeContext *pCtx);
1790 
1791 static void
1792 QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1793 
1794 static void
1795 QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1796 
1797 
1798 /**
1799  * @brief Add a simple value.
1800  *
1801  * @param[in] pMe    The encode context.
1802  * @param[in] uNum   The simple value.
1803  *
1804  * QCBOREncode_AddBool(), QCBOREncode_AddUndef() and
1805  * QCBOREncode_AddNull() are preferred to this for the simple values
1806  * defined in RFC 8949, but this can be used for them too.
1807  *
1808  * The main purpose of this is to add simple values beyond those in
1809  * defined RFC 8949. Note that simple values must be registered with
1810  * IANA. Those in the range of 0 to 19 must be standardized.  Those in
1811  * the range of 32 to 255 do not require a standard, but must be
1812  * publically specified. There is no range of values for proprietary
1813  * use. See
1814  * https://www.iana.org/assignments/cbor-simple-values/cbor-simple-values.xhtml
1815  */
1816 static void
1817 QCBOREncode_AddSimple(QCBOREncodeContext *pMe, const uint8_t uNum);
1818 
1819 static void
1820 QCBOREncode_AddSimpleToMap(QCBOREncodeContext *pMe,
1821                            const char         *szLabel,
1822                            const uint8_t       uSimple);
1823 
1824 static void
1825 QCBOREncode_AddSimpleToMapN(QCBOREncodeContext *pMe,
1826                             const int64_t       nLabel,
1827                             const uint8_t       uSimple);
1828 
1829 
1830 /**
1831  * @brief  Indicates that the next items added are in an array.
1832  *
1833  * @param[in] pCtx The encoding context to open the array in.
1834  *
1835  * Arrays are the basic CBOR aggregate or structure type. Call this
1836  * function to start or open an array. Then call the various
1837  * @c QCBOREncode_AddXxx() functions to add the items that go into the
1838  * array. Then call QCBOREncode_CloseArray() when all items have been
1839  * added. The data items in the array can be of any type and can be of
1840  * mixed types.
1841  *
1842  * Nesting of arrays and maps is allowed and supported just by calling
1843  * QCBOREncode_OpenArray() again before calling
1844  * QCBOREncode_CloseArray().  While CBOR has no limit on nesting, this
1845  * implementation does in order to keep it smaller and simpler.  The
1846  * limit is @ref QCBOR_MAX_ARRAY_NESTING. This is the max number of
1847  * times this can be called without calling
1848  * QCBOREncode_CloseArray(). QCBOREncode_Finish() will return
1849  * @ref QCBOR_ERR_ARRAY_NESTING_TOO_DEEP when it is called as this
1850  * function just sets an error state and returns no value when this
1851  * occurs.
1852  *
1853  * If you try to add more than @ref QCBOR_MAX_ITEMS_IN_ARRAY items to
1854  * a single array or map, @ref QCBOR_ERR_ARRAY_TOO_LONG will be
1855  * returned when QCBOREncode_Finish() is called.
1856  *
1857  * An array itself must have a label if it is being added to a map.
1858  * Note that array elements do not have labels (but map elements do).
1859  *
1860  * An array itself may be tagged by calling QCBOREncode_AddTag()
1861  * before this call.
1862  */
1863 static void
1864 QCBOREncode_OpenArray(QCBOREncodeContext *pCtx);
1865 
1866 static void
1867 QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1868 
1869 static void
1870 QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx,  int64_t nLabel);
1871 
1872 
1873 /**
1874  * @brief Close an open array.
1875  *
1876  * @param[in] pCtx The encoding context to close the array in.
1877  *
1878  * The closes an array opened by QCBOREncode_OpenArray(). It reduces
1879  * nesting level by one. All arrays (and maps) must be closed before
1880  * calling QCBOREncode_Finish().
1881  *
1882  * When an error occurs as a result of this call, the encoder records
1883  * the error and enters the error state. The error will be returned
1884  * when QCBOREncode_Finish() is called.
1885  *
1886  * If this has been called more times than QCBOREncode_OpenArray(), then
1887  * @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when QCBOREncode_Finish()
1888  * is called.
1889  *
1890  * If this is called and it is not an array that is currently open,
1891  * @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
1892  * QCBOREncode_Finish() is called.
1893  */
1894 static void
1895 QCBOREncode_CloseArray(QCBOREncodeContext *pCtx);
1896 
1897 
1898 
1899 
1900 /**
1901  * @brief  Indicates that the next items added are in a map.
1902  *
1903  * @param[in] pCtx The encoding context to open the map in.
1904  *
1905  * See QCBOREncode_OpenArray() for more information, particularly
1906  * error handling.
1907  *
1908  * CBOR maps are an aggregate type where each item in the map consists
1909  * of a label and a value. They are similar to JSON objects.
1910  *
1911  * The value can be any CBOR type including another map.
1912  *
1913  * The label can also be any CBOR type, but in practice they are
1914  * typically, integers as this gives the most compact output. They
1915  * might also be text strings which gives readability and translation
1916  * to JSON.
1917  *
1918  * Every @c QCBOREncode_AddXxx() call has one version that ends with
1919  * @c InMap for adding items to maps with string labels and one that
1920  * ends with @c InMapN that is for adding with integer labels.
1921  *
1922  * RFC 8949 uses the term "key" instead of "label".
1923  *
1924  * If you wish to use map labels that are neither integer labels nor
1925  * text strings, then just call the QCBOREncode_AddXxx() function
1926  * explicitly to add the label. Then call it again to add the value.
1927  *
1928  * See the [RFC 8949] (https://tools.ietf.org/html/rfc8949) for a lot
1929  * more information on creating maps.
1930  */
1931 static void
1932 QCBOREncode_OpenMap(QCBOREncodeContext *pCtx);
1933 
1934 static void
1935 QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1936 
1937 static void
1938 QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1939 
1940 
1941 /**
1942  * @brief Close an open map.
1943  *
1944  * @param[in] pCtx The encoding context to close the map in.
1945  *
1946  * This closes a map opened by QCBOREncode_OpenMap(). It reduces
1947  * nesting level by one.
1948  *
1949  * When an error occurs as a result of this call, the encoder records
1950  * the error and enters the error state. The error will be returned
1951  * when QCBOREncode_Finish() is called.
1952  *
1953  * If this has been called more times than QCBOREncode_OpenMap(), then
1954  * @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1955  * QCBOREncode_Finish() is called.
1956  *
1957  * If this is called and it is not a map that is currently open,
1958  * @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
1959  * QCBOREncode_Finish() is called.
1960  */
1961 static void
1962 QCBOREncode_CloseMap(QCBOREncodeContext *pCtx);
1963 
1964 
1965 /**
1966  * @brief Indicates that the next items added are in an indefinite length array.
1967  *
1968  * @param[in] pCtx The encoding context to open the array in.
1969  *
1970  * This is the same as QCBOREncode_OpenArray() except the array is
1971  * indefinite length.
1972  *
1973  * This must be closed with QCBOREncode_CloseArrayIndefiniteLength().
1974  */
1975 static void
1976 QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pCtx);
1977 
1978 static void
1979 QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pCtx,
1980                                            const char         *szLabel);
1981 
1982 static void
1983 QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pCtx,
1984                                             int64_t            nLabel);
1985 
1986 
1987 /**
1988  * @brief Close an open indefinite length array.
1989  *
1990  * @param[in] pCtx The encoding context to close the array in.
1991  *
1992  * This is the same as QCBOREncode_CloseArray(), but the open array
1993  * that is being close must be of indefinite length.
1994  */
1995 static void
1996 QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pCtx);
1997 
1998 
1999 /**
2000  * @brief Indicates that the next items added are in an indefinite length map.
2001  *
2002  * @param[in] pCtx The encoding context to open the map in.
2003  *
2004  * This is the same as QCBOREncode_OpenMap() except the array is
2005  * indefinite length.
2006  *
2007  * This must be closed with QCBOREncode_CloseMapIndefiniteLength().
2008  */
2009 static void
2010 QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pCtx);
2011 
2012 static void
2013 QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pCtx,
2014                                          const char         *szLabel);
2015 
2016 static void
2017 QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pCtx,
2018                                           int64_t            nLabel);
2019 
2020 
2021 /**
2022  * @brief Close an open indefinite length map.
2023  *
2024  * @param[in] pCtx The encoding context to close the map in.
2025  *
2026  * This is the same as QCBOREncode_CloseMap(), but the open map that
2027  * is being close must be of indefinite length.
2028  */
2029 static  void
2030 QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pCtx);
2031 
2032 
2033 
2034 
2035 /**
2036  * @brief Indicate start of encoded CBOR to be wrapped in a bstr.
2037  *
2038  * @param[in] pCtx The encoding context to open the bstr-wrapped CBOR in.
2039  *
2040  * All added encoded items between this call and a call to
2041  * QCBOREncode_CloseBstrWrap2() will be wrapped in a bstr. They will
2042  * appear in the final output as a byte string.  That byte string will
2043  * contain encoded CBOR. This increases nesting level by one.
2044  *
2045  * The typical use case is for encoded CBOR that is to be
2046  * cryptographically hashed, as part of a [RFC 8152, COSE]
2047  * (https://tools.ietf.org/html/rfc8152) implementation. The wrapping
2048  * byte string is taken as input by the hash function (which is why it
2049  * is returned by QCBOREncode_CloseBstrWrap2()).  It is also easy to
2050  * recover on decoding with standard CBOR decoders.
2051  *
2052  * Using QCBOREncode_BstrWrap() and QCBOREncode_CloseBstrWrap2()
2053  * avoids having to encode the items first in one buffer (e.g., the
2054  * COSE payload) and then add that buffer as a bstr to another
2055  * encoding (e.g. the COSE to-be-signed bytes, the @c Sig_structure)
2056  * potentially halving the memory needed.
2057  *
2058  * CBOR by nature must be decoded item by item in order from the
2059  * start.  By wrapping some CBOR in a byte string, the decoding of
2060  * that wrapped CBOR can be skipped. This is another use of wrapping,
2061  * perhaps because the CBOR is large and deeply nested. Perhaps APIs
2062  * for handling one defined CBOR message that is being embedded in
2063  * another only take input as a byte string. Perhaps the desire is to
2064  * be able to decode the out layer even in the wrapped has errors.
2065  */
2066 static void
2067 QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx);
2068 
2069 static void
2070 QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
2071 
2072 static void
2073 QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
2074 
2075 
2076 /**
2077  * @brief Close a wrapping bstr.
2078  *
2079  * @param[in] pCtx              The encoding context to close of bstr wrapping in.
2080  * @param[in] bIncludeCBORHead  Include the encoded CBOR head of the bstr
2081  *                              as well as the bytes in @c pWrappedCBOR.
2082  * @param[out] pWrappedCBOR     A @ref UsefulBufC containing wrapped bytes.
2083  *
2084  * The closes a wrapping bstr opened by QCBOREncode_BstrWrap(). It reduces
2085  * nesting level by one.
2086  *
2087  * A pointer and length of the enclosed encoded CBOR is returned in @c
2088  * *pWrappedCBOR if it is not @c NULL. The main purpose of this is so
2089  * this data can be hashed (e.g., with SHA-256) as part of a [RFC
2090  * 8152, COSE] (https://tools.ietf.org/html/rfc8152)
2091  * implementation. **WARNING**, this pointer and length should be used
2092  * right away before any other calls to @c QCBOREncode_CloseXxx() as
2093  * they will move data around and the pointer and length will no
2094  * longer be to the correct encoded CBOR.
2095  *
2096  * When an error occurs as a result of this call, the encoder records
2097  * the error and enters the error state. The error will be returned
2098  * when QCBOREncode_Finish() is called.
2099  *
2100  * If this has been called more times than QCBOREncode_BstrWrap(),
2101  * then @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
2102  * QCBOREncode_Finish() is called.
2103  *
2104  * If this is called and it is not a wrapping bstr that is currently
2105  * open, @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
2106  * QCBOREncode_Finish() is called.
2107  *
2108  * QCBOREncode_CloseBstrWrap() is a deprecated version of this function
2109  * that is equivalent to the call with @c bIncludeCBORHead @c true.
2110  */
2111 void
2112 QCBOREncode_CloseBstrWrap2(QCBOREncodeContext *pCtx, bool bIncludeCBORHead, UsefulBufC *pWrappedCBOR);
2113 
2114 static void
2115 QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR);
2116 
2117 
2118 /**
2119  * @brief Cancel byte string wrapping.
2120  *
2121  * @param[in] pCtx       The encoding context.
2122  *
2123  * This cancels QCBOREncode_BstrWrap() making tghe encoding as if it
2124  * were never called.
2125  *
2126  * WARNING: This does not work on QCBOREncode_BstrWrapInMap()
2127  * or QCBOREncode_BstrWrapInMapN() and there is no error detection
2128  * of an attempt at their use.
2129  *
2130  * This only works if nothing has been added into the wrapped byte
2131  * string.  If something has been added, this sets the error
2132  * @ref QCBOR_ERR_CANNOT_CANCEL.
2133  */
2134 void
2135 QCBOREncode_CancelBstrWrap(QCBOREncodeContext *pCtx);
2136 
2137 
2138 /**
2139  * @brief Add some already-encoded CBOR bytes.
2140  *
2141  * @param[in] pCtx     The encoding context to add the already-encode CBOR to.
2142  * @param[in] Encoded  The already-encoded CBOR to add to the context.
2143  *
2144  * The encoded CBOR being added must be fully conforming CBOR. It must
2145  * be complete with no arrays or maps that are incomplete. While this
2146  * encoder doesn't ever produce indefinite lengths, it is OK for the
2147  * raw CBOR added here to have indefinite lengths.
2148  *
2149  * The raw CBOR added here is not checked in anyway. If it is not
2150  * conforming or has open arrays or such, the final encoded CBOR
2151  * will probably be wrong or not what was intended.
2152  *
2153  * If the encoded CBOR being added here contains multiple items, they
2154  * must be enclosed in a map or array. At the top level the raw
2155  * CBOR must be a single data item.
2156  */
2157 void
2158 QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded);
2159 
2160 static void
2161 QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded);
2162 
2163 static void
2164 QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded);
2165 
2166 
2167 /**
2168  * @brief Get the encoded result.
2169  *
2170  * @param[in] pCtx           The context to finish encoding with.
2171  * @param[out] pEncodedCBOR  Structure in which the pointer and length of
2172  *                           the encoded CBOR is returned.
2173  *
2174  * @retval QCBOR_SUCCESS                     Encoded CBOR is returned.
2175  *
2176  * @retval QCBOR_ERR_TOO_MANY_CLOSES         Nesting error
2177  *
2178  * @retval QCBOR_ERR_CLOSE_MISMATCH          Nesting error
2179  *
2180  * @retval QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN Nesting error
2181  *
2182  * @retval QCBOR_ERR_BUFFER_TOO_LARGE        Encoded output buffer size
2183  *
2184  * @retval QCBOR_ERR_BUFFER_TOO_SMALL        Encoded output buffer size
2185  *
2186  * @retval QCBOR_ERR_ARRAY_NESTING_TOO_DEEP  Implementation limit
2187  *
2188  * @retval QCBOR_ERR_ARRAY_TOO_LONG          Implementation limit
2189  *
2190  * On success, the pointer and length of the encoded CBOR are returned
2191  * in @c *pEncodedCBOR. The pointer is the same pointer that was passed
2192  * in to QCBOREncode_Init(). Note that it is not const when passed to
2193  * QCBOREncode_Init(), but it is const when returned here.  The length
2194  * will be smaller than or equal to the length passed in when
2195  * QCBOREncode_Init() as this is the length of the actual result, not
2196  * the size of the buffer it was written to.
2197  *
2198  * If a @c NULL was passed for @c Storage.ptr when QCBOREncode_Init()
2199  * was called, @c NULL will be returned here, but the length will be
2200  * that of the CBOR that would have been encoded.
2201  *
2202  * Encoding errors primarily manifest here as most other encoding function
2203  * do no return an error. They just set the error state in the encode
2204  * context after which no encoding function does anything.
2205  *
2206  * Three types of errors manifest here. The first type are nesting
2207  * errors where the number of @c QCBOREncode_OpenXxx() calls do not
2208  * match the number @c QCBOREncode_CloseXxx() calls. The solution is to
2209  * fix the calling code.
2210  *
2211  * The second type of error is because the buffer given is either too
2212  * small or too large. The remedy is to give a correctly sized buffer.
2213  *
2214  * The third type are due to limits in this implementation.
2215  * @ref QCBOR_ERR_ARRAY_NESTING_TOO_DEEP can be worked around by
2216  * encoding the CBOR in two (or more) phases and adding the CBOR from
2217  * the first phase to the second with @c QCBOREncode_AddEncoded().
2218  *
2219  * If an error is returned, the buffer may have partially encoded
2220  * incorrect CBOR in it and it should not be used. Likewise, the length
2221  * may be incorrect and should not be used.
2222  *
2223  * Note that the error could have occurred in one of the many
2224  * @c QCBOREncode_AddXxx() calls long before QCBOREncode_Finish() was
2225  * called. This error handling reduces the CBOR implementation size
2226  * but makes debugging harder.
2227  *
2228  * This may be called multiple times. It will always return the
2229  * same. It can also be interleaved with calls to
2230  * QCBOREncode_FinishGetSize().
2231  *
2232  * QCBOREncode_GetErrorState() can be called to get the current
2233  * error state in order to abort encoding early as an optimization, but
2234  * calling it is is never required.
2235  */
2236 QCBORError
2237 QCBOREncode_Finish(QCBOREncodeContext *pCtx, UsefulBufC *pEncodedCBOR);
2238 
2239 
2240 /**
2241  * @brief Get the encoded CBOR and error status.
2242  *
2243  * @param[in] pCtx          The context to finish encoding with.
2244  * @param[out] uEncodedLen  The length of the encoded or potentially
2245  *                          encoded CBOR in bytes.
2246  *
2247  * @return The same errors as QCBOREncode_Finish().
2248  *
2249  * This functions the same as QCBOREncode_Finish(), but only returns the
2250  * size of the encoded output.
2251  */
2252 QCBORError
2253 QCBOREncode_FinishGetSize(QCBOREncodeContext *pCtx, size_t *uEncodedLen);
2254 
2255 
2256 /**
2257  * @brief Indicate whether output buffer is NULL or not.
2258  *
2259  * @param[in] pCtx  The encoding context.
2260  *
2261  * @return 1 if the output buffer is @c NULL.
2262  *
2263  * Sometimes a @c NULL input buffer is given to QCBOREncode_Init() so
2264  * that the size of the generated CBOR can be calculated without
2265  * allocating a buffer for it. This returns 1 when the output buffer
2266  * is @c NULL and 0 when it is not.
2267  */
2268 static int
2269 QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx);
2270 
2271 
2272 /**
2273  * @brief Get the encoding error state.
2274  *
2275  * @param[in] pCtx  The encoding context.
2276  *
2277  * @return One of @ref QCBORError. See return values from
2278  *         QCBOREncode_Finish()
2279  *
2280  * Normally encoding errors need only be handled at the end of
2281  * encoding when QCBOREncode_Finish() is called. This can be called to
2282  * get the error result before finish should there be a need to halt
2283  * encoding before QCBOREncode_Finish() is called.
2284  */
2285 static QCBORError
2286 QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx);
2287 
2288 
2289 /**
2290  * Encode the "head" of a CBOR data item.
2291  *
2292  * @param Buffer       Buffer to output the encoded head to; must be
2293  *                     @ref QCBOR_HEAD_BUFFER_SIZE bytes in size.
2294  * @param uMajorType   One of CBOR_MAJOR_TYPE_XX.
2295  * @param uMinLen      The minimum number of bytes to encode uNumber. Almost
2296  *                     always this is 0 to use preferred
2297  *                     serialization. If this is 4, then even the
2298  *                     values 0xffff and smaller will be encoded in 4
2299  *                     bytes. This is used primarily when encoding a
2300  *                     float or double put into uNumber as the leading
2301  *                     zero bytes for them must be encoded.
2302  * @param uNumber      The numeric argument part of the CBOR head.
2303  * @return             Pointer and length of the encoded head or
2304  *                     @ref NULLUsefulBufC if the output buffer is too small.
2305  *
2306  * Callers do not to need to call this for normal CBOR encoding. Note
2307  * that it doesn't even take a @ref QCBOREncodeContext argument.
2308  *
2309  * This encodes the major type and argument part of a data item. The
2310  * argument is an integer that is usually either the value or the length
2311  * of the data item.
2312  *
2313  * This is exposed in the public interface to allow hashing of some CBOR
2314  * data types, bstr in particular, a chunk at a time so the full CBOR
2315  * doesn't have to be encoded in a contiguous buffer.
2316  *
2317  * For example, if you have a 100,000 byte binary blob in a buffer that
2318  * needs to be a bstr encoded and then hashed. You could allocate a
2319  * 100,010 byte buffer and encode it normally. Alternatively, you can
2320  * encode the head in a 10 byte buffer with this function, hash that and
2321  * then hash the 100,000 bytes using the same hash context.
2322  */
2323 UsefulBufC
2324 QCBOREncode_EncodeHead(UsefulBuf Buffer,
2325                        uint8_t   uMajorType,
2326                        uint8_t   uMinLen,
2327                        uint64_t  uNumber);
2328 
2329 
2330 
2331 
2332 /* =========================================================================
2333      BEGINNING OF PRIVATE IMPLEMENTATION
2334    ========================================================================= */
2335 
2336 /* Semi-private funcion used by public inline functions. See qcbor_encode.c */
2337 void QCBOREncode_Private_AppendCBORHead(QCBOREncodeContext *pMe,
2338                                         const uint8_t       uMajorType,
2339                                         const uint64_t      uArgument,
2340                                         const uint8_t       uMinLen);
2341 
2342 
2343 /* Semi-private funcion used by public inline functions. See qcbor_encode.c */
2344 void
2345 QCBOREncode_Private_AddBuffer(QCBOREncodeContext *pCtx,
2346                               uint8_t             uMajorType,
2347                               UsefulBufC          Bytes);
2348 
2349 
2350 /* Semi-private function for adding a double with preferred encoding. See qcbor_encode.c */
2351 void
2352 QCBOREncode_Private_AddPreferredDouble(QCBOREncodeContext *pMe, const double dNum);
2353 
2354 
2355 /* Semi-private function for adding a float with preferred encoding. See qcbor_encode.c */
2356 void
2357 QCBOREncode_Private_AddPreferredFloat(QCBOREncodeContext *pMe, const float fNum);
2358 
2359 
2360 /* Semi-private funcion used by public inline functions. See qcbor_encode.c */
2361 void
2362 QCBOREncode_Private_OpenMapOrArray(QCBOREncodeContext *pCtx,
2363                                    uint8_t             uMajorType);
2364 
2365 
2366 /* Semi-private funcion used by public inline functions. See qcbor_encode.c */
2367 void
2368 QCBOREncode_Private_OpenMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx,
2369                                                    uint8_t             uMajorType);
2370 
2371 
2372 /* Semi-private funcion used by public inline functions. See qcbor_encode.c */
2373 void
2374 QCBOREncode_Private_CloseMapOrArray(QCBOREncodeContext *pCtx,
2375                                     uint8_t             uMajorType);
2376 
2377 
2378 /* Semi-private funcion used by public inline functions. See qcbor_encode.c */
2379 void
2380 QCBOREncode_Private_CloseMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx,
2381                                                     uint8_t             uMajorType);
2382 
2383 
2384 /* Semi-private funcion used by public inline functions. See qcbor_encode.c */
2385 void
2386 QCBOREncode_Private_AddExpMantissa(QCBOREncodeContext *pCtx,
2387                                    uint64_t            uTag,
2388                                    UsefulBufC          BigNumMantissa,
2389                                    bool                bBigNumIsNegative,
2390                                    int64_t             nMantissa,
2391                                    int64_t             nExponent);
2392 
2393 
2394 /**
2395  * @brief  Semi-private method to add simple items and floating-point.
2396  *
2397  * @param[in] pMe        The encoding context.
2398  * @param[in] uMinLen    Minimum encoding size for uNum. Usually 0.
2399  * @param[in] uArgument  The value to add.
2400  *
2401  * This is used to add simple types like true and false and float-point
2402  * values, both of which are type 7.
2403  *
2404  * Call QCBOREncode_AddBool(), QCBOREncode_AddNULL(),
2405  * QCBOREncode_AddUndef() QCBOREncode_AddDouble() instead of this.
2406  *
2407  * Error handling is the same as QCBOREncode_AddInt64().
2408  */
2409 static inline void
QCBOREncode_Private_AddType7(QCBOREncodeContext * pMe,const uint8_t uMinLen,const uint64_t uArgument)2410 QCBOREncode_Private_AddType7(QCBOREncodeContext *pMe,
2411                              const uint8_t       uMinLen,
2412                              const uint64_t      uArgument)
2413 {
2414    QCBOREncode_Private_AppendCBORHead(pMe, CBOR_MAJOR_TYPE_SIMPLE, uArgument, uMinLen);
2415 }
2416 
2417 
2418 /**
2419  * @brief Semi-private method to add only the type and length of a byte string.
2420  *
2421  * @param[in] pCtx    The context to initialize.
2422  * @param[in] Bytes   Pointer and length of the input data.
2423  *
2424  * This will be removed in QCBOR 2.0. It was never a public function.
2425  *
2426  * This is the same as QCBOREncode_AddBytes() except it only adds the
2427  * CBOR encoding for the type and the length. It doesn't actually add
2428  * the bytes. You can't actually produce correct CBOR with this and
2429  * the rest of this API. It is only used for a special case where the
2430  * valid CBOR is created manually by putting this type and length in
2431  * and then adding the actual bytes. In particular, when only a hash
2432  * of the encoded CBOR is needed, where the type and header are hashed
2433  * separately and then the bytes is hashed. This makes it possible to
2434  * implement COSE Sign1 with only one copy of the payload in the
2435  * output buffer, rather than two, roughly cutting memory use in half.
2436  *
2437  * This is only used for this odd case, but this is a supported
2438  * tested function for QCBOR 1.0.
2439  *
2440  * See also QCBOREncode_EncodeHead().
2441  */
2442 static void
2443 QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pCtx,
2444                             UsefulBufC          Bytes);
2445 
2446 static void
2447 QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pCtx,
2448                                  const char         *szLabel,
2449                                  UsefulBufC          Bytes);
2450 
2451 static void
2452 QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pCtx,
2453                                  int64_t              nLabel,
2454                                  UsefulBufC           Bytes);
2455 
2456 
2457 /* Forward declaration */
2458 static void
2459 QCBOREncode_AddSZString(QCBOREncodeContext *pMe, const char *szString);
2460 
2461 
2462 
2463 
2464 static inline void
QCBOREncode_AddInt64ToMap(QCBOREncodeContext * pMe,const char * szLabel,const int64_t uNum)2465 QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pMe,
2466                           const char        *szLabel,
2467                           const int64_t      uNum)
2468 {
2469    QCBOREncode_AddSZString(pMe, szLabel);
2470    QCBOREncode_AddInt64(pMe, uNum);
2471 }
2472 
2473 static inline void
QCBOREncode_AddInt64ToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const int64_t uNum)2474 QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pMe,
2475                            const int64_t       nLabel,
2476                            const int64_t       uNum)
2477 {
2478    QCBOREncode_AddInt64(pMe, nLabel);
2479    QCBOREncode_AddInt64(pMe, uNum);
2480 }
2481 
2482 
2483 static inline void
QCBOREncode_AddUInt64(QCBOREncodeContext * pMe,const uint64_t uValue)2484 QCBOREncode_AddUInt64(QCBOREncodeContext *pMe, const uint64_t uValue)
2485 {
2486    QCBOREncode_Private_AppendCBORHead(pMe, CBOR_MAJOR_TYPE_POSITIVE_INT, uValue, 0);
2487 }
2488 
2489 
2490 static inline void
QCBOREncode_AddUInt64ToMap(QCBOREncodeContext * pMe,const char * szLabel,const uint64_t uNum)2491 QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pMe,
2492                            const char         *szLabel,
2493                            const uint64_t      uNum)
2494 {
2495    QCBOREncode_AddSZString(pMe, szLabel);
2496    QCBOREncode_AddUInt64(pMe, uNum);
2497 }
2498 
2499 static inline void
QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint64_t uNum)2500 QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pMe,
2501                             const int64_t       nLabel,
2502                             const uint64_t      uNum)
2503 {
2504    QCBOREncode_AddInt64(pMe, nLabel);
2505    QCBOREncode_AddUInt64(pMe, uNum);
2506 }
2507 
2508 
2509 static inline void
QCBOREncode_AddText(QCBOREncodeContext * pMe,const UsefulBufC Text)2510 QCBOREncode_AddText(QCBOREncodeContext *pMe, const UsefulBufC Text)
2511 {
2512    QCBOREncode_Private_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, Text);
2513 }
2514 
2515 static inline void
QCBOREncode_AddTextToMap(QCBOREncodeContext * pMe,const char * szLabel,const UsefulBufC Text)2516 QCBOREncode_AddTextToMap(QCBOREncodeContext *pMe,
2517                          const char         *szLabel,
2518                          const UsefulBufC    Text)
2519 {
2520    QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szLabel));
2521    QCBOREncode_AddText(pMe, Text);
2522 }
2523 
2524 static inline void
QCBOREncode_AddTextToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const UsefulBufC Text)2525 QCBOREncode_AddTextToMapN(QCBOREncodeContext *pMe,
2526                           const int64_t       nLabel,
2527                           const UsefulBufC    Text)
2528 {
2529    QCBOREncode_AddInt64(pMe, nLabel);
2530    QCBOREncode_AddText(pMe, Text);
2531 }
2532 
2533 
2534 inline static void
QCBOREncode_AddSZString(QCBOREncodeContext * pMe,const char * szString)2535 QCBOREncode_AddSZString(QCBOREncodeContext *pMe, const char *szString)
2536 {
2537    QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szString));
2538 }
2539 
2540 static inline void
QCBOREncode_AddSZStringToMap(QCBOREncodeContext * pMe,const char * szLabel,const char * szString)2541 QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pMe,
2542                              const char         *szLabel,
2543                              const char         *szString)
2544 {
2545    QCBOREncode_AddSZString(pMe, szLabel);
2546    QCBOREncode_AddSZString(pMe, szString);
2547 }
2548 
2549 static inline void
QCBOREncode_AddSZStringToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const char * szString)2550 QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pMe,
2551                               const int64_t       nLabel,
2552                               const char         *szString)
2553 {
2554    QCBOREncode_AddInt64(pMe, nLabel);
2555    QCBOREncode_AddSZString(pMe, szString);
2556 }
2557 
2558 
2559 
2560 /*
2561  * Public functions for adding a tag. See qcbor/qcbor_encode.h
2562  */
2563 static inline void
QCBOREncode_AddTag(QCBOREncodeContext * pMe,const uint64_t uTag)2564 QCBOREncode_AddTag(QCBOREncodeContext *pMe, const uint64_t uTag)
2565 {
2566    QCBOREncode_Private_AppendCBORHead(pMe, CBOR_MAJOR_TYPE_TAG, uTag, 0);
2567 }
2568 
2569 
2570 
2571 #ifndef USEFULBUF_DISABLE_ALL_FLOAT
2572 
2573 static inline void
QCBOREncode_AddDoubleNoPreferred(QCBOREncodeContext * pMe,const double dNum)2574 QCBOREncode_AddDoubleNoPreferred(QCBOREncodeContext *pMe, const double dNum)
2575 {
2576    QCBOREncode_Private_AddType7(pMe,
2577                                 sizeof(uint64_t),
2578                                 UsefulBufUtil_CopyDoubleToUint64(dNum));
2579 }
2580 
2581 static inline void
QCBOREncode_AddFloatNoPreferred(QCBOREncodeContext * pMe,const float fNum)2582 QCBOREncode_AddFloatNoPreferred(QCBOREncodeContext *pMe, const float fNum)
2583 {
2584    QCBOREncode_Private_AddType7(pMe,
2585                                 sizeof(uint32_t),
2586                                 UsefulBufUtil_CopyFloatToUint32(fNum));
2587 }
2588 
2589 
2590 static inline void
QCBOREncode_AddDouble(QCBOREncodeContext * pMe,const double dNum)2591 QCBOREncode_AddDouble(QCBOREncodeContext *pMe, const double dNum)
2592 {
2593 #ifndef QCBOR_DISABLE_PREFERRED_FLOAT
2594    QCBOREncode_Private_AddPreferredDouble(pMe, dNum);
2595 #else /* QCBOR_DISABLE_PREFERRED_FLOAT */
2596    QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
2597 #endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
2598 }
2599 
2600 static inline void
QCBOREncode_AddDoubleToMap(QCBOREncodeContext * pMe,const char * szLabel,const double dNum)2601 QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pMe,
2602                            const char         *szLabel,
2603                            const double        dNum)
2604 {
2605    QCBOREncode_AddSZString(pMe, szLabel);
2606    QCBOREncode_AddDouble(pMe, dNum);
2607 }
2608 
2609 static inline void
QCBOREncode_AddDoubleToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const double dNum)2610 QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pMe,
2611                             const int64_t       nLabel,
2612                             const double        dNum)
2613 {
2614    QCBOREncode_AddInt64(pMe, nLabel);
2615    QCBOREncode_AddDouble(pMe, dNum);
2616 }
2617 
2618 
2619 static inline void
QCBOREncode_AddFloat(QCBOREncodeContext * pMe,const float fNum)2620 QCBOREncode_AddFloat(QCBOREncodeContext *pMe, const float fNum)
2621 {
2622 #ifndef QCBOR_DISABLE_PREFERRED_FLOAT
2623    QCBOREncode_Private_AddPreferredFloat(pMe, fNum);
2624 #else /* QCBOR_DISABLE_PREFERRED_FLOAT */
2625    QCBOREncode_AddFloatNoPreferred(pMe, fNum);
2626 #endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
2627 }
2628 
2629 static inline void
QCBOREncode_AddFloatToMap(QCBOREncodeContext * pMe,const char * szLabel,const float dNum)2630 QCBOREncode_AddFloatToMap(QCBOREncodeContext *pMe,
2631                           const char         *szLabel,
2632                           const float         dNum)
2633 {
2634    QCBOREncode_AddSZString(pMe, szLabel);
2635    QCBOREncode_AddFloat(pMe, dNum);
2636 }
2637 
2638 static inline void
QCBOREncode_AddFloatToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const float fNum)2639 QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pMe,
2640                            const int64_t       nLabel,
2641                            const float         fNum)
2642 {
2643    QCBOREncode_AddInt64(pMe, nLabel);
2644    QCBOREncode_AddFloat(pMe, fNum);
2645 }
2646 
2647 static inline void
QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext * pMe,const char * szLabel,const double dNum)2648 QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pMe,
2649                                       const char         *szLabel,
2650                                       const double        dNum)
2651 {
2652    QCBOREncode_AddSZString(pMe, szLabel);
2653    QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
2654 }
2655 
2656 static inline void
QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const double dNum)2657 QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pMe,
2658                                        const int64_t       nLabel,
2659                                        const double        dNum)
2660 {
2661    QCBOREncode_AddInt64(pMe, nLabel);
2662    QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
2663 }
2664 
2665 static inline void
QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext * pMe,const char * szLabel,const float dNum)2666 QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pMe,
2667                                      const char         *szLabel,
2668                                      const float         dNum)
2669 {
2670    QCBOREncode_AddSZString(pMe, szLabel);
2671    QCBOREncode_AddFloatNoPreferred(pMe, dNum);
2672 }
2673 
2674 static inline void
QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const float dNum)2675 QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pMe,
2676                                       const int64_t       nLabel,
2677                                       const float         dNum)
2678 {
2679    QCBOREncode_AddInt64(pMe, nLabel);
2680    QCBOREncode_AddFloatNoPreferred(pMe, dNum);
2681 }
2682 #endif /* USEFULBUF_DISABLE_ALL_FLOAT */
2683 
2684 
2685 
2686 
2687 
2688 static inline void
QCBOREncode_AddTDateEpoch(QCBOREncodeContext * pMe,const uint8_t uTag,const int64_t nDate)2689 QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pMe,
2690                           const uint8_t       uTag,
2691                           const int64_t       nDate)
2692 {
2693    if(uTag == QCBOR_ENCODE_AS_TAG) {
2694       QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_EPOCH);
2695    }
2696    QCBOREncode_AddInt64(pMe, nDate);
2697 }
2698 
2699 static inline void
QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTag,const int64_t nDate)2700 QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pMe,
2701                                  const char         *szLabel,
2702                                  const uint8_t       uTag,
2703                                  const int64_t       nDate)
2704 {
2705    QCBOREncode_AddSZString(pMe, szLabel);
2706    QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
2707 }
2708 
2709 static inline void
QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTag,const int64_t nDate)2710 QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pMe,
2711                                 const int64_t       nLabel,
2712                                 const uint8_t       uTag,
2713                                 const int64_t       nDate)
2714 {
2715    QCBOREncode_AddInt64(pMe, nLabel);
2716    QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
2717 }
2718 
2719 static inline void
QCBOREncode_AddDateEpoch(QCBOREncodeContext * pMe,const int64_t nDate)2720 QCBOREncode_AddDateEpoch(QCBOREncodeContext *pMe,
2721                          const int64_t       nDate)
2722 {
2723    QCBOREncode_AddTDateEpoch(pMe, QCBOR_ENCODE_AS_TAG, nDate);
2724 }
2725 
2726 static inline void
QCBOREncode_AddDateEpochToMap(QCBOREncodeContext * pMe,const char * szLabel,const int64_t nDate)2727 QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pMe,
2728                               const char         *szLabel,
2729                               const int64_t       nDate)
2730 {
2731    QCBOREncode_AddSZString(pMe, szLabel);
2732    QCBOREncode_AddDateEpoch(pMe, nDate);
2733 }
2734 
2735 static inline void
QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const int64_t nDate)2736 QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pMe,
2737                                const int64_t       nLabel,
2738                                const int64_t       nDate)
2739 {
2740    QCBOREncode_AddInt64(pMe, nLabel);
2741    QCBOREncode_AddDateEpoch(pMe, nDate);
2742 }
2743 
2744 
2745 static inline void
QCBOREncode_AddTDaysEpoch(QCBOREncodeContext * pMe,const uint8_t uTag,const int64_t nDays)2746 QCBOREncode_AddTDaysEpoch(QCBOREncodeContext *pMe,
2747                           const uint8_t       uTag,
2748                           const int64_t       nDays)
2749 {
2750    if(uTag == QCBOR_ENCODE_AS_TAG) {
2751       QCBOREncode_AddTag(pMe, CBOR_TAG_DAYS_EPOCH);
2752    }
2753    QCBOREncode_AddInt64(pMe, nDays);
2754 }
2755 
2756 static inline void
QCBOREncode_AddTDaysEpochToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTag,const int64_t nDays)2757 QCBOREncode_AddTDaysEpochToMapSZ(QCBOREncodeContext *pMe,
2758                                  const char         *szLabel,
2759                                  const uint8_t       uTag,
2760                                  const int64_t       nDays)
2761 {
2762    QCBOREncode_AddSZString(pMe, szLabel);
2763    QCBOREncode_AddTDaysEpoch(pMe, uTag, nDays);
2764 }
2765 
2766 static inline void
QCBOREncode_AddTDaysEpochToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTag,const int64_t nDays)2767 QCBOREncode_AddTDaysEpochToMapN(QCBOREncodeContext *pMe,
2768                                 const int64_t       nLabel,
2769                                 const uint8_t       uTag,
2770                                 const int64_t       nDays)
2771 {
2772    QCBOREncode_AddInt64(pMe, nLabel);
2773    QCBOREncode_AddTDaysEpoch(pMe, uTag, nDays);
2774 }
2775 
2776 
2777 static inline void
QCBOREncode_AddBytes(QCBOREncodeContext * pMe,const UsefulBufC Bytes)2778 QCBOREncode_AddBytes(QCBOREncodeContext *pMe,
2779                      const UsefulBufC    Bytes)
2780 {
2781    QCBOREncode_Private_AddBuffer(pMe, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes);
2782 }
2783 
2784 static inline void
QCBOREncode_AddBytesToMap(QCBOREncodeContext * pMe,const char * szLabel,const UsefulBufC Bytes)2785 QCBOREncode_AddBytesToMap(QCBOREncodeContext *pMe,
2786                           const char         *szLabel,
2787                           const UsefulBufC    Bytes)
2788 {
2789    QCBOREncode_AddSZString(pMe, szLabel);
2790    QCBOREncode_AddBytes(pMe, Bytes);
2791 }
2792 
2793 static inline void
QCBOREncode_AddBytesToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const UsefulBufC Bytes)2794 QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pMe,
2795                            const int64_t       nLabel,
2796                            const UsefulBufC    Bytes)
2797 {
2798    QCBOREncode_AddInt64(pMe, nLabel);
2799    QCBOREncode_AddBytes(pMe, Bytes);
2800 }
2801 
2802 static inline void
QCBOREncode_OpenBytesInMapSZ(QCBOREncodeContext * pMe,const char * szLabel,UsefulBuf * pPlace)2803 QCBOREncode_OpenBytesInMapSZ(QCBOREncodeContext *pMe,
2804                              const char         *szLabel,
2805                              UsefulBuf          *pPlace)
2806 {
2807    QCBOREncode_AddSZString(pMe, szLabel);
2808    QCBOREncode_OpenBytes(pMe, pPlace);
2809 }
2810 
2811 static inline void
QCBOREncode_OpenBytesInMapN(QCBOREncodeContext * pMe,const int64_t nLabel,UsefulBuf * pPlace)2812 QCBOREncode_OpenBytesInMapN(QCBOREncodeContext *pMe,
2813                             const int64_t       nLabel,
2814                             UsefulBuf          *pPlace)
2815 {
2816    QCBOREncode_AddInt64(pMe, nLabel);
2817    QCBOREncode_OpenBytes(pMe, pPlace);
2818 }
2819 
2820 
2821 /*
2822  * Public functions for adding only a byte string length. See qcbor/qcbor_encode.h
2823  */
2824 static inline void
QCBOREncode_AddBytesLenOnly(QCBOREncodeContext * pMe,const UsefulBufC Bytes)2825 QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
2826 {
2827    QCBOREncode_Private_AppendCBORHead(pMe, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes.len, 0);
2828 }
2829 
2830 
2831 static inline void
QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext * pMe,const char * szLabel,const UsefulBufC Bytes)2832 QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pMe,
2833                                  const char         *szLabel,
2834                                  const UsefulBufC    Bytes)
2835 {
2836     QCBOREncode_AddSZString(pMe, szLabel);
2837     QCBOREncode_AddBytesLenOnly(pMe, Bytes);
2838 }
2839 
2840 static inline void
QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const UsefulBufC Bytes)2841 QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pMe,
2842                                   const int64_t       nLabel,
2843                                   const UsefulBufC    Bytes)
2844 {
2845     QCBOREncode_AddInt64(pMe, nLabel);
2846     QCBOREncode_AddBytesLenOnly(pMe, Bytes);
2847 }
2848 
2849 
2850 static inline void
QCBOREncode_AddTBinaryUUID(QCBOREncodeContext * pMe,const uint8_t uTagRequirement,const UsefulBufC Bytes)2851 QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pMe,
2852                            const uint8_t       uTagRequirement,
2853                            const UsefulBufC    Bytes)
2854 {
2855    if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2856       QCBOREncode_AddTag(pMe, CBOR_TAG_BIN_UUID);
2857    }
2858    QCBOREncode_AddBytes(pMe, Bytes);
2859 }
2860 
2861 static inline void
QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,const UsefulBufC Bytes)2862 QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pMe,
2863                                   const char         *szLabel,
2864                                   const uint8_t       uTagRequirement,
2865                                   const UsefulBufC    Bytes)
2866 {
2867    QCBOREncode_AddSZString(pMe, szLabel);
2868    QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
2869 }
2870 
2871 static inline void
QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,const UsefulBufC Bytes)2872 QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pMe,
2873                                  const int64_t       nLabel,
2874                                  const uint8_t       uTagRequirement,
2875                                  const UsefulBufC    Bytes)
2876 {
2877    QCBOREncode_AddInt64(pMe, nLabel);
2878    QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
2879 }
2880 
2881 static inline void
QCBOREncode_AddBinaryUUID(QCBOREncodeContext * pMe,const UsefulBufC Bytes)2882 QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
2883 {
2884    QCBOREncode_AddTBinaryUUID(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2885 }
2886 
2887 static inline void
QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext * pMe,const char * szLabel,const UsefulBufC Bytes)2888 QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pMe,
2889                                const char         *szLabel,
2890                                const UsefulBufC    Bytes)
2891 {
2892    QCBOREncode_AddTBinaryUUIDToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2893 }
2894 
2895 static inline void
QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const UsefulBufC Bytes)2896 QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pMe,
2897                                 const int64_t       nLabel,
2898                                 const UsefulBufC    Bytes)
2899 {
2900    QCBOREncode_AddTBinaryUUIDToMapN(pMe,
2901                                     nLabel,
2902                                     QCBOR_ENCODE_AS_TAG,
2903                                     Bytes);
2904 }
2905 
2906 
2907 static inline void
QCBOREncode_AddTPositiveBignum(QCBOREncodeContext * pMe,const uint8_t uTagRequirement,const UsefulBufC Bytes)2908 QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pMe,
2909                                const uint8_t       uTagRequirement,
2910                                const UsefulBufC    Bytes)
2911 {
2912    if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2913       QCBOREncode_AddTag(pMe, CBOR_TAG_POS_BIGNUM);
2914    }
2915    QCBOREncode_AddBytes(pMe, Bytes);
2916 }
2917 
2918 static inline void
QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,const UsefulBufC Bytes)2919 QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pMe,
2920                                       const char         *szLabel,
2921                                       const uint8_t       uTagRequirement,
2922                                       const UsefulBufC    Bytes)
2923 {
2924    QCBOREncode_AddSZString(pMe, szLabel);
2925    QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
2926 }
2927 
2928 static inline void
QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,const UsefulBufC Bytes)2929 QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pMe,
2930                                      const int64_t       nLabel,
2931                                      const uint8_t       uTagRequirement,
2932                                      const UsefulBufC    Bytes)
2933 {
2934    QCBOREncode_AddInt64(pMe, nLabel);
2935    QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
2936 }
2937 
2938 static inline void
QCBOREncode_AddPositiveBignum(QCBOREncodeContext * pMe,const UsefulBufC Bytes)2939 QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
2940 {
2941    QCBOREncode_AddTPositiveBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2942 }
2943 
2944 static inline void
QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext * pMe,const char * szLabel,const UsefulBufC Bytes)2945 QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pMe,
2946                                    const char         *szLabel,
2947                                    const UsefulBufC    Bytes)
2948 {
2949    QCBOREncode_AddTPositiveBignumToMapSZ(pMe,
2950                                          szLabel,
2951                                          QCBOR_ENCODE_AS_TAG,
2952                                          Bytes);
2953 }
2954 
2955 static inline void
QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const UsefulBufC Bytes)2956 QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pMe,
2957                                     const int64_t       nLabel,
2958                                     const UsefulBufC    Bytes)
2959 {
2960    QCBOREncode_AddTPositiveBignumToMapN(pMe,
2961                                         nLabel,
2962                                         QCBOR_ENCODE_AS_TAG,
2963                                         Bytes);
2964 }
2965 
2966 
2967 static inline void
QCBOREncode_AddTNegativeBignum(QCBOREncodeContext * pMe,const uint8_t uTagRequirement,const UsefulBufC Bytes)2968 QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pMe,
2969                                const uint8_t       uTagRequirement,
2970                                const UsefulBufC    Bytes)
2971 {
2972    if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2973       QCBOREncode_AddTag(pMe, CBOR_TAG_NEG_BIGNUM);
2974    }
2975    QCBOREncode_AddBytes(pMe, Bytes);
2976 }
2977 
2978 static inline void
QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,const UsefulBufC Bytes)2979 QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pMe,
2980                                       const char         *szLabel,
2981                                       const uint8_t       uTagRequirement,
2982                                       const UsefulBufC    Bytes)
2983 {
2984    QCBOREncode_AddSZString(pMe, szLabel);
2985    QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2986 }
2987 
2988 static inline void
QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,const UsefulBufC Bytes)2989 QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pMe,
2990                                      const int64_t       nLabel,
2991                                      const uint8_t       uTagRequirement,
2992                                      const UsefulBufC    Bytes)
2993 {
2994    QCBOREncode_AddInt64(pMe, nLabel);
2995    QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2996 }
2997 
2998 static inline void
QCBOREncode_AddNegativeBignum(QCBOREncodeContext * pMe,const UsefulBufC Bytes)2999 QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
3000 {
3001    QCBOREncode_AddTNegativeBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
3002 }
3003 
3004 static inline void
QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext * pMe,const char * szLabel,const UsefulBufC Bytes)3005 QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pMe,
3006                                    const char         *szLabel,
3007                                    const UsefulBufC    Bytes)
3008 {
3009    QCBOREncode_AddTNegativeBignumToMapSZ(pMe,
3010                                          szLabel,
3011                                          QCBOR_ENCODE_AS_TAG,
3012                                          Bytes);
3013 }
3014 
3015 static inline void
QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const UsefulBufC Bytes)3016 QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pMe,
3017                                     const int64_t       nLabel,
3018                                     const UsefulBufC    Bytes)
3019 {
3020    QCBOREncode_AddTNegativeBignumToMapN(pMe,
3021                                         nLabel,
3022                                         QCBOR_ENCODE_AS_TAG,
3023                                         Bytes);
3024 }
3025 
3026 
3027 
3028 #ifndef QCBOR_DISABLE_EXP_AND_MANTISSA
3029 
3030 static inline void
QCBOREncode_AddTDecimalFraction(QCBOREncodeContext * pMe,const uint8_t uTagRequirement,const int64_t nMantissa,const int64_t nBase10Exponent)3031 QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pMe,
3032                                 const uint8_t       uTagRequirement,
3033                                 const int64_t       nMantissa,
3034                                 const int64_t       nBase10Exponent)
3035 {
3036    uint64_t uTag;
3037    if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3038       uTag = CBOR_TAG_DECIMAL_FRACTION;
3039    } else {
3040       uTag = CBOR_TAG_INVALID64;
3041    }
3042    QCBOREncode_Private_AddExpMantissa(pMe,
3043                                       uTag,
3044                                       NULLUsefulBufC,
3045                                       false,
3046                                       nMantissa,
3047                                       nBase10Exponent);
3048 }
3049 
3050 static inline void
QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,const int64_t nMantissa,const int64_t nBase10Exponent)3051 QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pMe,
3052                                        const char         *szLabel,
3053                                        const uint8_t       uTagRequirement,
3054                                        const int64_t       nMantissa,
3055                                        const int64_t       nBase10Exponent)
3056 {
3057    QCBOREncode_AddSZString(pMe, szLabel);
3058    QCBOREncode_AddTDecimalFraction(pMe,
3059                                    uTagRequirement,
3060                                    nMantissa,
3061                                    nBase10Exponent);
3062 }
3063 
3064 static inline void
QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,const int64_t nMantissa,const int64_t nBase10Exponent)3065 QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pMe,
3066                                       const int64_t       nLabel,
3067                                       const uint8_t       uTagRequirement,
3068                                       const int64_t       nMantissa,
3069                                       const int64_t       nBase10Exponent)
3070 {
3071    QCBOREncode_AddInt64(pMe, nLabel);
3072    QCBOREncode_AddTDecimalFraction(pMe,
3073                                    uTagRequirement,
3074                                    nMantissa,
3075                                    nBase10Exponent);
3076 }
3077 
3078 static inline void
QCBOREncode_AddDecimalFraction(QCBOREncodeContext * pMe,const int64_t nMantissa,const int64_t nBase10Exponent)3079 QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pMe,
3080                                const int64_t       nMantissa,
3081                                const int64_t       nBase10Exponent)
3082 {
3083    QCBOREncode_AddTDecimalFraction(pMe,
3084                                    QCBOR_ENCODE_AS_TAG,
3085                                    nMantissa,
3086                                    nBase10Exponent);
3087 }
3088 
3089 static inline void
QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext * pMe,const char * szLabel,const int64_t nMantissa,const int64_t nBase10Exponent)3090 QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pMe,
3091                                     const char         *szLabel,
3092                                     const int64_t       nMantissa,
3093                                     const int64_t       nBase10Exponent)
3094 {
3095    QCBOREncode_AddTDecimalFractionToMapSZ(pMe,
3096                                           szLabel,
3097                                           QCBOR_ENCODE_AS_TAG,
3098                                           nMantissa,
3099                                           nBase10Exponent);
3100 }
3101 
3102 static inline void
QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const int64_t nMantissa,const int64_t nBase10Exponent)3103 QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pMe,
3104                                      const int64_t       nLabel,
3105                                      const int64_t       nMantissa,
3106                                      const int64_t       nBase10Exponent)
3107 {
3108    QCBOREncode_AddTDecimalFractionToMapN(pMe,
3109                                          nLabel,
3110                                          QCBOR_ENCODE_AS_TAG,
3111                                          nMantissa,
3112                                          nBase10Exponent);
3113 }
3114 
3115 
3116 
3117 static inline void
QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext * pMe,const uint8_t uTagRequirement,const UsefulBufC Mantissa,const bool bIsNegative,const int64_t nBase10Exponent)3118 QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pMe,
3119                                       const uint8_t       uTagRequirement,
3120                                       const UsefulBufC    Mantissa,
3121                                       const bool          bIsNegative,
3122                                       const int64_t       nBase10Exponent)
3123 {
3124    uint64_t uTag;
3125    if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3126       uTag = CBOR_TAG_DECIMAL_FRACTION;
3127    } else {
3128       uTag = CBOR_TAG_INVALID64;
3129    }
3130    QCBOREncode_Private_AddExpMantissa(pMe,
3131                                       uTag,
3132                                       Mantissa,
3133                                       bIsNegative,
3134                                       0,
3135                                       nBase10Exponent);
3136 }
3137 
3138 static inline void
QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,const UsefulBufC Mantissa,const bool bIsNegative,const int64_t nBase10Exponent)3139 QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
3140                                              const char         *szLabel,
3141                                              const uint8_t       uTagRequirement,
3142                                              const UsefulBufC    Mantissa,
3143                                              const bool          bIsNegative,
3144                                              const int64_t       nBase10Exponent)
3145 {
3146    QCBOREncode_AddSZString(pMe, szLabel);
3147    QCBOREncode_AddTDecimalFractionBigNum(pMe,
3148                                          uTagRequirement,
3149                                          Mantissa,
3150                                          bIsNegative,
3151                                          nBase10Exponent);
3152 }
3153 
3154 static inline void
QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,const UsefulBufC Mantissa,const bool bIsNegative,const int64_t nBase10Exponent)3155 QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
3156                                             const int64_t       nLabel,
3157                                             const uint8_t       uTagRequirement,
3158                                             const UsefulBufC    Mantissa,
3159                                             const bool          bIsNegative,
3160                                             const int64_t       nBase10Exponent)
3161 {
3162    QCBOREncode_AddInt64(pMe, nLabel);
3163    QCBOREncode_AddTDecimalFractionBigNum(pMe,
3164                                          uTagRequirement,
3165                                          Mantissa,
3166                                          bIsNegative,
3167                                          nBase10Exponent);
3168 }
3169 
3170 static inline void
QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext * pMe,const UsefulBufC Mantissa,const bool bIsNegative,const int64_t nBase10Exponent)3171 QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pMe,
3172                                      const UsefulBufC    Mantissa,
3173                                      const bool          bIsNegative,
3174                                      const int64_t       nBase10Exponent)
3175 {
3176    QCBOREncode_AddTDecimalFractionBigNum(pMe,
3177                                          QCBOR_ENCODE_AS_TAG,
3178                                          Mantissa,
3179                                          bIsNegative,
3180                                          nBase10Exponent);
3181 }
3182 
3183 static inline void
QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const UsefulBufC Mantissa,const bool bIsNegative,const int64_t nBase10Exponent)3184 QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
3185                                             const char         *szLabel,
3186                                             const UsefulBufC    Mantissa,
3187                                             const bool          bIsNegative,
3188                                             const int64_t       nBase10Exponent)
3189 {
3190    QCBOREncode_AddTDecimalFractionBigNumToMapSZ(pMe,
3191                                                 szLabel,
3192                                                 QCBOR_ENCODE_AS_TAG,
3193                                                 Mantissa,
3194                                                 bIsNegative,
3195                                                 nBase10Exponent);
3196 }
3197 
3198 static inline void
QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const UsefulBufC Mantissa,const bool bIsNegative,const int64_t nBase2Exponent)3199 QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
3200                                            const int64_t       nLabel,
3201                                            const UsefulBufC    Mantissa,
3202                                            const bool          bIsNegative,
3203                                            const int64_t       nBase2Exponent)
3204 {
3205    QCBOREncode_AddTDecimalFractionBigNumToMapN(pMe,
3206                                                nLabel,
3207                                                QCBOR_ENCODE_AS_TAG,
3208                                                Mantissa,
3209                                                bIsNegative,
3210                                                nBase2Exponent);
3211 }
3212 
3213 
3214 
3215 
3216 
3217 static inline void
QCBOREncode_AddTBigFloat(QCBOREncodeContext * pMe,const uint8_t uTagRequirement,const int64_t nMantissa,const int64_t nBase2Exponent)3218 QCBOREncode_AddTBigFloat(QCBOREncodeContext *pMe,
3219                          const uint8_t       uTagRequirement,
3220                          const int64_t       nMantissa,
3221                          const int64_t       nBase2Exponent)
3222 {
3223    uint64_t uTag;
3224    if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3225       uTag = CBOR_TAG_BIGFLOAT;
3226    } else {
3227       uTag = CBOR_TAG_INVALID64;
3228    }
3229    QCBOREncode_Private_AddExpMantissa(pMe,
3230                                       uTag,
3231                                       NULLUsefulBufC,
3232                                       false,
3233                                       nMantissa,
3234                                       nBase2Exponent);
3235 }
3236 
3237 static inline void
QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,const int64_t nMantissa,const int64_t nBase2Exponent)3238 QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pMe,
3239                                 const char         *szLabel,
3240                                 const uint8_t       uTagRequirement,
3241                                 const int64_t       nMantissa,
3242                                 const int64_t       nBase2Exponent)
3243 {
3244    QCBOREncode_AddSZString(pMe, szLabel);
3245    QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
3246 }
3247 
3248 static inline void
QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,const int64_t nMantissa,const int64_t nBase2Exponent)3249 QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pMe,
3250                                const int64_t       nLabel,
3251                                const uint8_t       uTagRequirement,
3252                                const int64_t       nMantissa,
3253                                const int64_t       nBase2Exponent)
3254 {
3255    QCBOREncode_AddInt64(pMe, nLabel);
3256    QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
3257 }
3258 
3259 static inline void
QCBOREncode_AddBigFloat(QCBOREncodeContext * pMe,const int64_t nMantissa,const int64_t nBase2Exponent)3260 QCBOREncode_AddBigFloat(QCBOREncodeContext *pMe,
3261                         const int64_t       nMantissa,
3262                         const int64_t       nBase2Exponent)
3263 {
3264    QCBOREncode_AddTBigFloat(pMe,
3265                             QCBOR_ENCODE_AS_TAG,
3266                             nMantissa,
3267                             nBase2Exponent);
3268 }
3269 
3270 static inline void
QCBOREncode_AddBigFloatToMap(QCBOREncodeContext * pMe,const char * szLabel,const int64_t nMantissa,const int64_t nBase2Exponent)3271 QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pMe,
3272                              const char         *szLabel,
3273                              const int64_t       nMantissa,
3274                              const int64_t       nBase2Exponent)
3275 {
3276    QCBOREncode_AddTBigFloatToMapSZ(pMe,
3277                                    szLabel,
3278                                    QCBOR_ENCODE_AS_TAG,
3279                                    nMantissa,
3280                                    nBase2Exponent);
3281 }
3282 
3283 static inline void
QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const int64_t nMantissa,const int64_t nBase2Exponent)3284 QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pMe,
3285                               const int64_t       nLabel,
3286                               const int64_t       nMantissa,
3287                               const int64_t       nBase2Exponent)
3288 {
3289    QCBOREncode_AddTBigFloatToMapN(pMe,
3290                                   nLabel,
3291                                   QCBOR_ENCODE_AS_TAG,
3292                                   nMantissa,
3293                                   nBase2Exponent);
3294 }
3295 
3296 
3297 
3298 static inline void
QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext * pMe,const uint8_t uTagRequirement,const UsefulBufC Mantissa,const bool bIsNegative,const int64_t nBase2Exponent)3299 QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pMe,
3300                                const uint8_t       uTagRequirement,
3301                                const UsefulBufC    Mantissa,
3302                                const bool          bIsNegative,
3303                                const int64_t       nBase2Exponent)
3304 {
3305    uint64_t uTag;
3306    if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3307       uTag = CBOR_TAG_BIGFLOAT;
3308    } else {
3309       uTag = CBOR_TAG_INVALID64;
3310    }
3311    QCBOREncode_Private_AddExpMantissa(pMe,
3312                                       uTag,
3313                                       Mantissa,
3314                                       bIsNegative,
3315                                       0,
3316                                       nBase2Exponent);
3317 }
3318 
3319 static inline void
QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,const UsefulBufC Mantissa,const bool bIsNegative,const int64_t nBase2Exponent)3320 QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pMe,
3321                                       const char         *szLabel,
3322                                       const uint8_t       uTagRequirement,
3323                                       const UsefulBufC    Mantissa,
3324                                       const bool          bIsNegative,
3325                                       const int64_t       nBase2Exponent)
3326 {
3327    QCBOREncode_AddSZString(pMe, szLabel);
3328    QCBOREncode_AddTBigFloatBigNum(pMe,
3329                                   uTagRequirement,
3330                                   Mantissa,
3331                                   bIsNegative,
3332                                   nBase2Exponent);
3333 }
3334 
3335 static inline void
QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,const UsefulBufC Mantissa,const bool bIsNegative,const int64_t nBase2Exponent)3336 QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
3337                                      const int64_t       nLabel,
3338                                      const uint8_t       uTagRequirement,
3339                                      const UsefulBufC    Mantissa,
3340                                      const bool          bIsNegative,
3341                                      const int64_t       nBase2Exponent)
3342 {
3343    QCBOREncode_AddInt64(pMe, nLabel);
3344    QCBOREncode_AddTBigFloatBigNum(pMe,
3345                                   uTagRequirement,
3346                                   Mantissa,
3347                                   bIsNegative,
3348                                   nBase2Exponent);
3349 }
3350 
3351 
3352 static inline void
QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext * pMe,const UsefulBufC Mantissa,const bool bIsNegative,const int64_t nBase2Exponent)3353 QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pMe,
3354                               const UsefulBufC    Mantissa,
3355                               const bool          bIsNegative,
3356                               const int64_t       nBase2Exponent)
3357 {
3358    QCBOREncode_AddTBigFloatBigNum(pMe,
3359                                   QCBOR_ENCODE_AS_TAG,
3360                                   Mantissa, bIsNegative,
3361                                   nBase2Exponent);
3362 }
3363 
3364 static inline void
QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext * pMe,const char * szLabel,const UsefulBufC Mantissa,const bool bIsNegative,const int64_t nBase2Exponent)3365 QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pMe,
3366                                    const char         *szLabel,
3367                                    const UsefulBufC    Mantissa,
3368                                    const bool          bIsNegative,
3369                                    const int64_t       nBase2Exponent)
3370 {
3371    QCBOREncode_AddTBigFloatBigNumToMapSZ(pMe,
3372                                          szLabel,
3373                                          QCBOR_ENCODE_AS_TAG,
3374                                          Mantissa,
3375                                          bIsNegative,
3376                                          nBase2Exponent);
3377 }
3378 
3379 static inline void
QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const UsefulBufC Mantissa,const bool bIsNegative,const int64_t nBase2Exponent)3380 QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
3381                                     const int64_t       nLabel,
3382                                     const UsefulBufC    Mantissa,
3383                                     const bool          bIsNegative,
3384                                     const int64_t       nBase2Exponent)
3385 {
3386    QCBOREncode_AddTBigFloatBigNumToMapN(pMe,
3387                                         nLabel,
3388                                         QCBOR_ENCODE_AS_TAG,
3389                                         Mantissa,
3390                                         bIsNegative,
3391                                         nBase2Exponent);
3392 }
3393 #endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
3394 
3395 
3396 static inline void
QCBOREncode_AddTURI(QCBOREncodeContext * pMe,const uint8_t uTagRequirement,const UsefulBufC URI)3397 QCBOREncode_AddTURI(QCBOREncodeContext *pMe,
3398                     const uint8_t       uTagRequirement,
3399                     const UsefulBufC    URI)
3400 {
3401    if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3402       QCBOREncode_AddTag(pMe, CBOR_TAG_URI);
3403    }
3404    QCBOREncode_AddText(pMe, URI);
3405 }
3406 
3407 static inline void
QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,const UsefulBufC URI)3408 QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pMe,
3409                            const char         *szLabel,
3410                            const uint8_t       uTagRequirement,
3411                            const UsefulBufC    URI)
3412 {
3413    QCBOREncode_AddSZString(pMe, szLabel);
3414    QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
3415 }
3416 
3417 static inline void
QCBOREncode_AddTURIToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,const UsefulBufC URI)3418 QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pMe,
3419                           const int64_t       nLabel,
3420                           const uint8_t       uTagRequirement,
3421                           const UsefulBufC    URI)
3422 {
3423    QCBOREncode_AddInt64(pMe, nLabel);
3424    QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
3425 }
3426 
3427 static inline void
QCBOREncode_AddURI(QCBOREncodeContext * pMe,const UsefulBufC URI)3428 QCBOREncode_AddURI(QCBOREncodeContext *pMe, const UsefulBufC URI)
3429 {
3430    QCBOREncode_AddTURI(pMe, QCBOR_ENCODE_AS_TAG, URI);
3431 }
3432 
3433 static inline void
QCBOREncode_AddURIToMap(QCBOREncodeContext * pMe,const char * szLabel,const UsefulBufC URI)3434 QCBOREncode_AddURIToMap(QCBOREncodeContext *pMe,
3435                         const char         *szLabel,
3436                         const UsefulBufC    URI)
3437 {
3438    QCBOREncode_AddTURIToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, URI);
3439 }
3440 
3441 static inline void
QCBOREncode_AddURIToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const UsefulBufC URI)3442 QCBOREncode_AddURIToMapN(QCBOREncodeContext *pMe,
3443                          const int64_t       nLabel,
3444                          const UsefulBufC    URI)
3445 {
3446    QCBOREncode_AddTURIToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, URI);
3447 }
3448 
3449 
3450 
3451 static inline void
QCBOREncode_AddTB64Text(QCBOREncodeContext * pMe,const uint8_t uTagRequirement,const UsefulBufC B64Text)3452 QCBOREncode_AddTB64Text(QCBOREncodeContext *pMe,
3453                         const uint8_t       uTagRequirement,
3454                         const UsefulBufC    B64Text)
3455 {
3456    if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3457       QCBOREncode_AddTag(pMe, CBOR_TAG_B64);
3458    }
3459    QCBOREncode_AddText(pMe, B64Text);
3460 }
3461 
3462 static inline void
QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,const UsefulBufC B64Text)3463 QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pMe,
3464                                const char         *szLabel,
3465                                const uint8_t       uTagRequirement,
3466                                const UsefulBufC    B64Text)
3467 {
3468    QCBOREncode_AddSZString(pMe, szLabel);
3469    QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
3470 }
3471 
3472 static inline void
QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,const UsefulBufC B64Text)3473 QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pMe,
3474                               const int64_t       nLabel,
3475                               const uint8_t       uTagRequirement,
3476                               const UsefulBufC    B64Text)
3477 {
3478    QCBOREncode_AddInt64(pMe, nLabel);
3479    QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
3480 }
3481 
3482 static inline void
QCBOREncode_AddB64Text(QCBOREncodeContext * pMe,const UsefulBufC B64Text)3483 QCBOREncode_AddB64Text(QCBOREncodeContext *pMe, const UsefulBufC B64Text)
3484 {
3485    QCBOREncode_AddTB64Text(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
3486 }
3487 
3488 static inline void
QCBOREncode_AddB64TextToMap(QCBOREncodeContext * pMe,const char * szLabel,const UsefulBufC B64Text)3489 QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pMe,
3490                             const char         *szLabel,
3491                             const UsefulBufC    B64Text)
3492 {
3493    QCBOREncode_AddTB64TextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
3494 }
3495 
3496 static inline void
QCBOREncode_AddB64TextToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const UsefulBufC B64Text)3497 QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pMe,
3498                              const int64_t       nLabel,
3499                              const UsefulBufC    B64Text)
3500 {
3501    QCBOREncode_AddTB64TextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
3502 }
3503 
3504 
3505 
3506 static inline void
QCBOREncode_AddTB64URLText(QCBOREncodeContext * pMe,const uint8_t uTagRequirement,const UsefulBufC B64Text)3507 QCBOREncode_AddTB64URLText(QCBOREncodeContext *pMe,
3508                            const uint8_t       uTagRequirement,
3509                            const UsefulBufC    B64Text)
3510 {
3511    if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3512       QCBOREncode_AddTag(pMe, CBOR_TAG_B64URL);
3513    }
3514    QCBOREncode_AddText(pMe, B64Text);
3515 }
3516 
3517 static inline void
QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,const UsefulBufC B64Text)3518 QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pMe,
3519                                   const char         *szLabel,
3520                                   const uint8_t       uTagRequirement,
3521                                   const UsefulBufC    B64Text)
3522 {
3523    QCBOREncode_AddSZString(pMe, szLabel);
3524    QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
3525 }
3526 
3527 static inline void
QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,const UsefulBufC B64Text)3528 QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pMe,
3529                                  const int64_t       nLabel,
3530                                  const uint8_t       uTagRequirement,
3531                                  const UsefulBufC    B64Text)
3532 {
3533    QCBOREncode_AddInt64(pMe, nLabel);
3534    QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
3535 }
3536 
3537 static inline void
QCBOREncode_AddB64URLText(QCBOREncodeContext * pMe,const UsefulBufC B64Text)3538 QCBOREncode_AddB64URLText(QCBOREncodeContext *pMe, const UsefulBufC B64Text)
3539 {
3540    QCBOREncode_AddTB64URLText(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
3541 }
3542 
3543 static inline void
QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext * pMe,const char * szLabel,const UsefulBufC B64Text)3544 QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pMe,
3545                                const char         *szLabel,
3546                                const UsefulBufC    B64Text)
3547 {
3548    QCBOREncode_AddTB64URLTextToMapSZ(pMe,
3549                                      szLabel,
3550                                      QCBOR_ENCODE_AS_TAG,
3551                                      B64Text);
3552 }
3553 
3554 static inline void
QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const UsefulBufC B64Text)3555 QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pMe,
3556                                 const int64_t       nLabel,
3557                                 const UsefulBufC    B64Text)
3558 {
3559    QCBOREncode_AddTB64URLTextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
3560 }
3561 
3562 
3563 
3564 static inline void
QCBOREncode_AddTRegex(QCBOREncodeContext * pMe,const uint8_t uTagRequirement,const UsefulBufC Bytes)3565 QCBOREncode_AddTRegex(QCBOREncodeContext *pMe,
3566                       const uint8_t       uTagRequirement,
3567                       const UsefulBufC    Bytes)
3568 {
3569    if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3570       QCBOREncode_AddTag(pMe, CBOR_TAG_REGEX);
3571    }
3572    QCBOREncode_AddText(pMe, Bytes);
3573 }
3574 
3575 static inline void
QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,const UsefulBufC Bytes)3576 QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pMe,
3577                              const char         *szLabel,
3578                              const uint8_t       uTagRequirement,
3579                              const UsefulBufC    Bytes)
3580 {
3581    QCBOREncode_AddSZString(pMe, szLabel);
3582    QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
3583 }
3584 
3585 static inline void
QCBOREncode_AddTRegexToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,const UsefulBufC Bytes)3586 QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pMe,
3587                             const int64_t       nLabel,
3588                             const uint8_t       uTagRequirement,
3589                             const UsefulBufC    Bytes)
3590 {
3591    QCBOREncode_AddInt64(pMe, nLabel);
3592    QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
3593 }
3594 
3595 static inline void
QCBOREncode_AddRegex(QCBOREncodeContext * pMe,const UsefulBufC Bytes)3596 QCBOREncode_AddRegex(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
3597 {
3598    QCBOREncode_AddTRegex(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
3599 }
3600 
3601 static inline void
QCBOREncode_AddRegexToMap(QCBOREncodeContext * pMe,const char * szLabel,const UsefulBufC Bytes)3602 QCBOREncode_AddRegexToMap(QCBOREncodeContext *pMe,
3603                           const char         *szLabel,
3604                           const UsefulBufC    Bytes)
3605 {
3606    QCBOREncode_AddTRegexToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
3607 }
3608 
3609 static inline void
QCBOREncode_AddRegexToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const UsefulBufC Bytes)3610 QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pMe,
3611                            const int64_t       nLabel,
3612                            const UsefulBufC    Bytes)
3613 {
3614    QCBOREncode_AddTRegexToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
3615 
3616 }
3617 
3618 
3619 static inline void
QCBOREncode_AddTMIMEData(QCBOREncodeContext * pMe,const uint8_t uTagRequirement,const UsefulBufC MIMEData)3620 QCBOREncode_AddTMIMEData(QCBOREncodeContext *pMe,
3621                          const uint8_t       uTagRequirement,
3622                          const UsefulBufC    MIMEData)
3623 {
3624    if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3625       QCBOREncode_AddTag(pMe, CBOR_TAG_BINARY_MIME);
3626    }
3627    QCBOREncode_AddBytes(pMe, MIMEData);
3628 }
3629 
3630 static inline void
QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,const UsefulBufC MIMEData)3631 QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pMe,
3632                                 const char         *szLabel,
3633                                 const uint8_t       uTagRequirement,
3634                                 const UsefulBufC    MIMEData)
3635 {
3636    QCBOREncode_AddSZString(pMe, szLabel);
3637    QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
3638 }
3639 
3640 static inline void
QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,const UsefulBufC MIMEData)3641 QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pMe,
3642                                const int64_t       nLabel,
3643                                const uint8_t       uTagRequirement,
3644                                const UsefulBufC    MIMEData)
3645 {
3646    QCBOREncode_AddInt64(pMe, nLabel);
3647    QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
3648 }
3649 
3650 static inline void
QCBOREncode_AddMIMEData(QCBOREncodeContext * pMe,UsefulBufC MIMEData)3651 QCBOREncode_AddMIMEData(QCBOREncodeContext *pMe, UsefulBufC MIMEData)
3652 {
3653    QCBOREncode_AddTMIMEData(pMe, QCBOR_ENCODE_AS_TAG, MIMEData);
3654 }
3655 
3656 static inline void
QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext * pMe,const char * szLabel,const UsefulBufC MIMEData)3657 QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pMe,
3658                              const char         *szLabel,
3659                              const UsefulBufC    MIMEData)
3660 {
3661    QCBOREncode_AddTMIMEDataToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
3662 }
3663 
3664 static inline void
QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const UsefulBufC MIMEData)3665 QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pMe,
3666                               const int64_t       nLabel,
3667                               const UsefulBufC    MIMEData)
3668 {
3669    QCBOREncode_AddTMIMEDataToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
3670 }
3671 
3672 
3673 static inline void
QCBOREncode_AddTDateString(QCBOREncodeContext * pMe,const uint8_t uTagRequirement,const char * szDate)3674 QCBOREncode_AddTDateString(QCBOREncodeContext *pMe,
3675                            const uint8_t       uTagRequirement,
3676                            const char         *szDate)
3677 {
3678    if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3679       QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_STRING);
3680    }
3681    QCBOREncode_AddSZString(pMe, szDate);
3682 }
3683 
3684 static inline void
QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,const char * szDate)3685 QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pMe,
3686                                   const char         *szLabel,
3687                                   const uint8_t       uTagRequirement,
3688                                   const char         *szDate)
3689 {
3690    QCBOREncode_AddSZString(pMe, szLabel);
3691    QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
3692 }
3693 
3694 static inline void
QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,const char * szDate)3695 QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pMe,
3696                                  const int64_t       nLabel,
3697                                  const uint8_t       uTagRequirement,
3698                                  const char         *szDate)
3699 {
3700    QCBOREncode_AddInt64(pMe, nLabel);
3701    QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
3702 }
3703 
3704 static inline void
QCBOREncode_AddDateString(QCBOREncodeContext * pMe,const char * szDate)3705 QCBOREncode_AddDateString(QCBOREncodeContext *pMe, const char *szDate)
3706 {
3707    QCBOREncode_AddTDateString(pMe, QCBOR_ENCODE_AS_TAG, szDate);
3708 }
3709 
3710 static inline void
QCBOREncode_AddDateStringToMap(QCBOREncodeContext * pMe,const char * szLabel,const char * szDate)3711 QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pMe,
3712                                const char         *szLabel,
3713                                const char         *szDate)
3714 {
3715    QCBOREncode_AddTDateStringToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, szDate);
3716 }
3717 
3718 static inline void
QCBOREncode_AddDateStringToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const char * szDate)3719 QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pMe,
3720                                 const int64_t       nLabel,
3721                                 const char         *szDate)
3722 {
3723    QCBOREncode_AddTDateStringToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, szDate);
3724 }
3725 
3726 
3727 static inline void
QCBOREncode_AddTDaysString(QCBOREncodeContext * pMe,const uint8_t uTagRequirement,const char * szDate)3728 QCBOREncode_AddTDaysString(QCBOREncodeContext *pMe,
3729                            const uint8_t       uTagRequirement,
3730                            const char         *szDate)
3731 {
3732    if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3733       QCBOREncode_AddTag(pMe, CBOR_TAG_DAYS_STRING);
3734    }
3735    QCBOREncode_AddSZString(pMe, szDate);
3736 }
3737 
3738 static inline void
QCBOREncode_AddTDaysStringToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,const char * szDate)3739 QCBOREncode_AddTDaysStringToMapSZ(QCBOREncodeContext *pMe,
3740                                   const char         *szLabel,
3741                                   const uint8_t       uTagRequirement,
3742                                   const char         *szDate)
3743 {
3744    QCBOREncode_AddSZString(pMe, szLabel);
3745    QCBOREncode_AddTDaysString(pMe, uTagRequirement, szDate);
3746 }
3747 
3748 static inline void
QCBOREncode_AddTDaysStringToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,const char * szDate)3749 QCBOREncode_AddTDaysStringToMapN(QCBOREncodeContext *pMe,
3750                                  const int64_t       nLabel,
3751                                  const uint8_t       uTagRequirement,
3752                                  const char         *szDate)
3753 {
3754    QCBOREncode_AddInt64(pMe, nLabel);
3755    QCBOREncode_AddTDaysString(pMe, uTagRequirement, szDate);
3756 }
3757 
3758 
3759 static inline void
QCBOREncode_AddSimple(QCBOREncodeContext * pMe,const uint8_t uNum)3760 QCBOREncode_AddSimple(QCBOREncodeContext *pMe, const uint8_t uNum)
3761 {
3762    /* This check often is optimized out because uNum is known at compile time. */
3763 #ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
3764    if(uNum >= CBOR_SIMPLEV_RESERVED_START && uNum <= CBOR_SIMPLEV_RESERVED_END) {
3765       pMe->uError = QCBOR_ERR_ENCODE_UNSUPPORTED;
3766       return;
3767    }
3768 #endif /* !QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
3769 
3770    QCBOREncode_Private_AddType7(pMe, 0, uNum);
3771 }
3772 
3773 static inline void
QCBOREncode_AddSimpleToMap(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uSimple)3774 QCBOREncode_AddSimpleToMap(QCBOREncodeContext *pMe,
3775                            const char         *szLabel,
3776                            const uint8_t       uSimple)
3777 {
3778    QCBOREncode_AddSZString(pMe, szLabel);
3779    QCBOREncode_AddSimple(pMe, uSimple);
3780 }
3781 
3782 static inline void
QCBOREncode_AddSimpleToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uSimple)3783 QCBOREncode_AddSimpleToMapN(QCBOREncodeContext *pMe,
3784                             const int64_t       nLabel,
3785                             const uint8_t       uSimple)
3786 {
3787    QCBOREncode_AddInt64(pMe, nLabel);
3788    QCBOREncode_AddSimple(pMe, uSimple);
3789 }
3790 
3791 
3792 static inline void
QCBOREncode_AddBool(QCBOREncodeContext * pMe,const bool b)3793 QCBOREncode_AddBool(QCBOREncodeContext *pMe, const bool b)
3794 {
3795    uint8_t uSimple = CBOR_SIMPLEV_FALSE;
3796    if(b) {
3797       uSimple = CBOR_SIMPLEV_TRUE;
3798    }
3799    QCBOREncode_AddSimple(pMe, uSimple);
3800 }
3801 
3802 static inline void
QCBOREncode_AddBoolToMap(QCBOREncodeContext * pMe,const char * szLabel,const bool b)3803 QCBOREncode_AddBoolToMap(QCBOREncodeContext *pMe, const char *szLabel, const bool b)
3804 {
3805    QCBOREncode_AddSZString(pMe, szLabel);
3806    QCBOREncode_AddBool(pMe, b);
3807 }
3808 
3809 static inline void
QCBOREncode_AddBoolToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const bool b)3810 QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pMe, const int64_t nLabel, const bool b)
3811 {
3812    QCBOREncode_AddInt64(pMe, nLabel);
3813    QCBOREncode_AddBool(pMe, b);
3814 }
3815 
3816 
3817 static inline void
QCBOREncode_AddNULL(QCBOREncodeContext * pMe)3818 QCBOREncode_AddNULL(QCBOREncodeContext *pMe)
3819 {
3820    QCBOREncode_AddSimple(pMe, CBOR_SIMPLEV_NULL);
3821 }
3822 
3823 static inline void
QCBOREncode_AddNULLToMap(QCBOREncodeContext * pMe,const char * szLabel)3824 QCBOREncode_AddNULLToMap(QCBOREncodeContext *pMe, const char *szLabel)
3825 {
3826    QCBOREncode_AddSZString(pMe, szLabel);
3827    QCBOREncode_AddNULL(pMe);
3828 }
3829 
3830 static inline void
QCBOREncode_AddNULLToMapN(QCBOREncodeContext * pMe,const int64_t nLabel)3831 QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
3832 {
3833    QCBOREncode_AddInt64(pMe, nLabel);
3834    QCBOREncode_AddNULL(pMe);
3835 }
3836 
3837 
3838 static inline void
QCBOREncode_AddUndef(QCBOREncodeContext * pMe)3839 QCBOREncode_AddUndef(QCBOREncodeContext *pMe)
3840 {
3841    QCBOREncode_AddSimple(pMe, CBOR_SIMPLEV_UNDEF);
3842 }
3843 
3844 static inline void
QCBOREncode_AddUndefToMap(QCBOREncodeContext * pMe,const char * szLabel)3845 QCBOREncode_AddUndefToMap(QCBOREncodeContext *pMe, const char *szLabel)
3846 {
3847    QCBOREncode_AddSZString(pMe, szLabel);
3848    QCBOREncode_AddUndef(pMe);
3849 }
3850 
3851 static inline void
QCBOREncode_AddUndefToMapN(QCBOREncodeContext * pMe,const int64_t nLabel)3852 QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
3853 {
3854    QCBOREncode_AddInt64(pMe, nLabel);
3855    QCBOREncode_AddUndef(pMe);
3856 }
3857 
3858 
3859 static inline void
QCBOREncode_OpenArray(QCBOREncodeContext * pMe)3860 QCBOREncode_OpenArray(QCBOREncodeContext *pMe)
3861 {
3862    QCBOREncode_Private_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
3863 }
3864 
3865 static inline void
QCBOREncode_OpenArrayInMap(QCBOREncodeContext * pMe,const char * szLabel)3866 QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pMe, const char *szLabel)
3867 {
3868    QCBOREncode_AddSZString(pMe, szLabel);
3869    QCBOREncode_OpenArray(pMe);
3870 }
3871 
3872 static inline void
QCBOREncode_OpenArrayInMapN(QCBOREncodeContext * pMe,const int64_t nLabel)3873 QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pMe,  const int64_t nLabel)
3874 {
3875    QCBOREncode_AddInt64(pMe, nLabel);
3876    QCBOREncode_OpenArray(pMe);
3877 }
3878 
3879 static inline void
QCBOREncode_CloseArray(QCBOREncodeContext * pMe)3880 QCBOREncode_CloseArray(QCBOREncodeContext *pMe)
3881 {
3882    QCBOREncode_Private_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
3883 }
3884 
3885 
3886 static inline void
QCBOREncode_OpenMap(QCBOREncodeContext * pMe)3887 QCBOREncode_OpenMap(QCBOREncodeContext *pMe)
3888 {
3889    QCBOREncode_Private_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
3890 }
3891 
3892 static inline void
QCBOREncode_OpenMapInMap(QCBOREncodeContext * pMe,const char * szLabel)3893 QCBOREncode_OpenMapInMap(QCBOREncodeContext *pMe, const char *szLabel)
3894 {
3895    QCBOREncode_AddSZString(pMe, szLabel);
3896    QCBOREncode_OpenMap(pMe);
3897 }
3898 
3899 static inline void
QCBOREncode_OpenMapInMapN(QCBOREncodeContext * pMe,const int64_t nLabel)3900 QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
3901 {
3902    QCBOREncode_AddInt64(pMe, nLabel);
3903    QCBOREncode_OpenMap(pMe);
3904 }
3905 
3906 static inline void
QCBOREncode_CloseMap(QCBOREncodeContext * pMe)3907 QCBOREncode_CloseMap(QCBOREncodeContext *pMe)
3908 {
3909    QCBOREncode_Private_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
3910 }
3911 
3912 static inline void
QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext * pMe)3913 QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pMe)
3914 {
3915    QCBOREncode_Private_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
3916 }
3917 
3918 static inline void
QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext * pMe,const char * szLabel)3919 QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pMe,
3920                                            const char         *szLabel)
3921 {
3922    QCBOREncode_AddSZString(pMe, szLabel);
3923    QCBOREncode_OpenArrayIndefiniteLength(pMe);
3924 }
3925 
3926 static inline void
QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext * pMe,const int64_t nLabel)3927 QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pMe,
3928                                             const int64_t       nLabel)
3929 {
3930    QCBOREncode_AddInt64(pMe, nLabel);
3931    QCBOREncode_OpenArrayIndefiniteLength(pMe);
3932 }
3933 
3934 static inline void
QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext * pMe)3935 QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pMe)
3936 {
3937    QCBOREncode_Private_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
3938 }
3939 
3940 
3941 static inline void
QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext * pMe)3942 QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pMe)
3943 {
3944    QCBOREncode_Private_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
3945 }
3946 
3947 static inline void
QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext * pMe,const char * szLabel)3948 QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pMe,
3949                                          const char         *szLabel)
3950 {
3951    QCBOREncode_AddSZString(pMe, szLabel);
3952    QCBOREncode_OpenMapIndefiniteLength(pMe);
3953 }
3954 
3955 static inline void
QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext * pMe,const int64_t nLabel)3956 QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pMe,
3957                                           const int64_t       nLabel)
3958 {
3959    QCBOREncode_AddInt64(pMe, nLabel);
3960    QCBOREncode_OpenMapIndefiniteLength(pMe);
3961 }
3962 
3963 static inline void
QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext * pMe)3964 QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pMe)
3965 {
3966    QCBOREncode_Private_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
3967 }
3968 
3969 
3970 static inline void
QCBOREncode_BstrWrap(QCBOREncodeContext * pMe)3971 QCBOREncode_BstrWrap(QCBOREncodeContext *pMe)
3972 {
3973    QCBOREncode_Private_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_BYTE_STRING);
3974 }
3975 
3976 static inline void
QCBOREncode_BstrWrapInMap(QCBOREncodeContext * pMe,const char * szLabel)3977 QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pMe, const char *szLabel)
3978 {
3979    QCBOREncode_AddSZString(pMe, szLabel);
3980    QCBOREncode_BstrWrap(pMe);
3981 }
3982 
3983 static inline void
QCBOREncode_BstrWrapInMapN(QCBOREncodeContext * pMe,const int64_t nLabel)3984 QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
3985 {
3986    QCBOREncode_AddInt64(pMe, nLabel);
3987    QCBOREncode_BstrWrap(pMe);
3988 }
3989 
3990 static inline void
QCBOREncode_CloseBstrWrap(QCBOREncodeContext * pMe,UsefulBufC * pWrappedCBOR)3991 QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pMe, UsefulBufC *pWrappedCBOR)
3992 {
3993    QCBOREncode_CloseBstrWrap2(pMe, true, pWrappedCBOR);
3994 }
3995 
3996 
3997 
3998 static inline void
QCBOREncode_AddEncodedToMap(QCBOREncodeContext * pMe,const char * szLabel,const UsefulBufC Encoded)3999 QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pMe,
4000                             const char         *szLabel,
4001                             const UsefulBufC    Encoded)
4002 {
4003    QCBOREncode_AddSZString(pMe, szLabel);
4004    QCBOREncode_AddEncoded(pMe, Encoded);
4005 }
4006 
4007 static inline void
QCBOREncode_AddEncodedToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const UsefulBufC Encoded)4008 QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pMe,
4009                              const int64_t       nLabel,
4010                              const UsefulBufC    Encoded)
4011 {
4012    QCBOREncode_AddInt64(pMe, nLabel);
4013    QCBOREncode_AddEncoded(pMe, Encoded);
4014 }
4015 
4016 
4017 static inline int
QCBOREncode_IsBufferNULL(QCBOREncodeContext * pMe)4018 QCBOREncode_IsBufferNULL(QCBOREncodeContext *pMe)
4019 {
4020    return UsefulOutBuf_IsBufferNULL(&(pMe->OutBuf));
4021 }
4022 
4023 static inline QCBORError
QCBOREncode_GetErrorState(QCBOREncodeContext * pMe)4024 QCBOREncode_GetErrorState(QCBOREncodeContext *pMe)
4025 {
4026    if(UsefulOutBuf_GetError(&(pMe->OutBuf))) {
4027       /* Items didn't fit in the buffer. This check catches this
4028        * condition for all the appends and inserts so checks aren't
4029        * needed when the appends and inserts are performed.  And of
4030        * course UsefulBuf will never overrun the input buffer given to
4031        * it. No complex analysis of the error handling in this file is
4032        * needed to know that is true. Just read the UsefulBuf code.
4033        */
4034       pMe->uError = QCBOR_ERR_BUFFER_TOO_SMALL;
4035       /* QCBOR_ERR_BUFFER_TOO_SMALL masks other errors, but that is
4036        * OK. Once the caller fixes this, they'll be unmasked.
4037        */
4038    }
4039 
4040    return (QCBORError)pMe->uError;
4041 }
4042 
4043 
4044 /* ========================================================================
4045      END OF PRIVATE INLINE IMPLEMENTATION
4046    ======================================================================== */
4047 
4048 #ifdef __cplusplus
4049 }
4050 #endif
4051 
4052 #endif /* qcbor_encode_h */
4053