blob: 008ee91a9455880d85954352367df2101f21416b [file] [log] [blame]
Laurence Lundblade3eead482023-12-16 20:53:22 -07001/* ===========================================================================
2 * Copyright (c) 2016-2018, The Linux Foundation.
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003 * Copyright (c) 2018-2024, Laurence Lundblade.
Laurence Lundblade3eead482023-12-16 20:53:22 -07004 * Copyright (c) 2021, Arm Limited.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials provided
15 * with the distribution.
16 * * Neither the name of The Linux Foundation nor the names of its
17 * contributors, nor the name "Laurence Lundblade" may be used to
18 * endorse or promote products derived from this software without
19 * specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
22 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
30 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
31 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * ========================================================================= */
Michael Eckel5c531332020-03-02 01:35:30 +010033
34
Laurence Lundblade844bb5c2020-03-01 17:27:25 -080035#ifndef qcbor_encode_h
36#define qcbor_encode_h
Michael Eckel5c531332020-03-02 01:35:30 +010037
38
Laurence Lundblade844bb5c2020-03-01 17:27:25 -080039#include "qcbor/qcbor_common.h"
40#include "qcbor/qcbor_private.h"
Michael Eckel5c531332020-03-02 01:35:30 +010041#include <stdbool.h>
Laurence Lundblade844bb5c2020-03-01 17:27:25 -080042
Michael Eckel5c531332020-03-02 01:35:30 +010043
44#ifdef __cplusplus
45extern "C" {
Dave Thaler12b23752020-03-27 01:23:08 -070046#if 0
Michael Eckel5c531332020-03-02 01:35:30 +010047} // Keep editor indention formatting happy
48#endif
49#endif
50
Michael Eckel5c531332020-03-02 01:35:30 +010051
52/**
Laurence Lundblade3eead482023-12-16 20:53:22 -070053 * @file qcbor_encode.h
54 *
55 * @anchor Overview
56 *
57 * # QCBOR Overview
58 *
59 * This implements CBOR -- Concise Binary Object Representation as
60 * defined in [RFC 8949] (https://tools.ietf.org/html/rfc8949). More
61 * information is at http://cbor.io. This is a near-complete implementation of
62 * the specification. [RFC 8742] (https://tools.ietf.org/html/rfc8742) CBOR
63 * Sequences is also supported. Limitations are listed further down.
64 *
65 * See @ref Encoding for general discussion on encoding,
66 * @ref BasicDecode for general discussion on the basic decode features
67 * and @ref SpiffyDecode for general discussion on the easier-to-use
68 * decoder functions.
69 *
70 * CBOR is intentionally designed to be translatable to JSON, but not
71 * all CBOR can convert to JSON. See RFC 8949 for more info on how to
72 * construct CBOR that is the most JSON friendly.
73 *
74 * The memory model for encoding and decoding is that encoded CBOR must
75 * be in a contiguous buffer in memory. During encoding the caller must
76 * supply an output buffer and if the encoding would go off the end of
77 * the buffer an error is returned. During decoding the caller supplies
78 * the encoded CBOR in a contiguous buffer and the decoder returns
79 * pointers and lengths into that buffer for strings.
80 *
81 * This implementation does not require malloc. All data structures
82 * passed in/out of the APIs can fit on the stack.
83 *
84 * Decoding of indefinite-length strings is a special case that requires
85 * a "string allocator" to allocate memory into which the segments of
86 * the string are coalesced. Without this, decoding will error out if an
87 * indefinite-length string is encountered (indefinite-length maps and
88 * arrays do not require the string allocator). A simple string
89 * allocator called MemPool is built-in and will work if supplied with a
90 * block of memory to allocate. The string allocator can optionally use
91 * malloc() or some other custom scheme.
92 *
93 * Here are some terms and definitions:
94 *
95 * - "Item", "Data Item": An integer or string or such. The basic "thing" that
96 * CBOR is about. An array is an item itself that contains some items.
97 *
98 * - "Array": An ordered sequence of items, the same as JSON.
99 *
100 * - "Map": A collection of label/value pairs. Each pair is a data
101 * item. A JSON "object" is the same as a CBOR "map".
102 *
103 * - "Label": The data item in a pair in a map that names or identifies
104 * the pair, not the value. This implementation refers to it as a
105 * "label". JSON refers to it as the "name". The CBOR RFC refers to it
106 * this as a "key". This implementation chooses label instead because
107 * key is too easily confused with a cryptographic key. The COSE
108 * standard, which uses CBOR, has also chosen to use the term "label"
109 * rather than "key" for this same reason.
110 *
111 * - "Key": See "Label" above.
112 *
113 * - "Tag": A data item that is an explicitly labeled new data
114 * type made up of the tagging integer and the tag content.
115 * See @ref Tags-Overview and @ref Tag-Usage.
116 *
117 * - "Initial Byte": The first byte of an encoded item. Encoding and
118 * decoding of this byte is taken care of by the implementation.
119 *
120 * - "Additional Info": In addition to the major type, all data items
121 * have some other info. This is usually the length of the data but can
122 * be several other things. Encoding and decoding of this is taken care
123 * of by the implementation.
124 *
125 * CBOR has two mechanisms for tagging and labeling the data values like
126 * integers and strings. For example, an integer that represents
127 * someone's birthday in epoch seconds since Jan 1, 1970 could be
128 * encoded like this:
129 *
130 * - First it is CBOR_MAJOR_TYPE_POSITIVE_INT (@ref QCBOR_TYPE_INT64),
131 * the primitive positive integer.
132 *
133 * - Next it has a "tag" @ref CBOR_TAG_DATE_EPOCH indicating the integer
134 * represents a date in the form of the number of seconds since Jan 1,
135 * 1970.
136 *
137 * - Last it has a string "label" like "BirthDate" indicating the
138 * meaning of the data.
139 *
140 * The encoded binary looks like this:
141 *
142 * a1 # Map of 1 item
143 * 69 # Indicates text string of 9 bytes
144 * 426972746844617465 # The text "BirthDate"
145 * c1 # Tags next integer as epoch date
146 * 1a # Indicates a 4-byte integer
147 * 580d4172 # unsigned integer date 1477263730
148 *
149 * Implementors using this API will primarily work with
150 * labels. Generally, tags are only needed for making up new data
151 * types. This implementation covers most of the data types defined in
152 * the RFC using tags. It also, allows for the use of custom tags if
153 * necessary.
154 *
155 * This implementation explicitly supports labels that are text strings
156 * and integers. Text strings translate nicely into JSON objects and are
157 * very readable. Integer labels are much less readable but can be very
158 * compact. If they are in the range of 0 to 23, they take up only one
159 * byte.
160 *
161 * CBOR allows a label to be any type of data including an array or a
162 * map. It is possible to use this API to construct and parse such
163 * labels, but it is not explicitly supported.
164 *
165 * @anchor Encoding
166 *
167 * ## Encoding
168 *
169 * A common encoding usage mode is to invoke the encoding twice. First
170 * with the output buffer as @ref SizeCalculateUsefulBuf to compute the
171 * length of the needed output buffer. The correct sized output buffer
172 * is allocated. The encoder is invoked a second time with the allocated
173 * output buffer.
174 *
175 * The double invocation is not required if the maximum output buffer
176 * size can be predicted. This is usually possible for simple CBOR
177 * structures.
178 *
179 * If a buffer too small to hold the encoded output is given, the error
180 * @ref QCBOR_ERR_BUFFER_TOO_SMALL will be returned. Data will never be
181 * written off the end of the output buffer no matter which functions
182 * here are called or what parameters are passed to them.
183 *
184 * The encoding error handling is simple. The only possible errors are
185 * trying to encode structures that are too large or too complex. There
186 * are no internal malloc calls so there will be no failures for out of
187 * memory. The error state is tracked internally, so there is no need
188 * to check for errors when encoding. Only the return code from
189 * QCBOREncode_Finish() need be checked as once an error happens, the
190 * encoder goes into an error state and calls to it to add more data
191 * will do nothing. An error check is not needed after every data item
192 * is added.
193 *
194 * Encoding generally proceeds by calling QCBOREncode_Init(), calling
195 * lots of @c QCBOREncode_AddXxx() functions and calling
196 * QCBOREncode_Finish(). There are many @c QCBOREncode_AddXxx()
197 * functions for various data types. The input buffers need only to be
198 * valid during the @c QCBOREncode_AddXxx() calls as the data is copied
199 * into the output buffer.
200 *
201 * There are three `Add` functions for each data type. The first / main
202 * one for the type is for adding the data item to an array. The second
203 * one's name ends in `ToMap`, is used for adding data items to maps and
204 * takes a string argument that is its label in the map. The third one
205 * ends in `ToMapN`, is also used for adding data items to maps, and
206 * takes an integer argument that is its label in the map.
207 *
208 * The simplest aggregate type is an array, which is a simple ordered
209 * set of items without labels the same as JSON arrays. Call
210 * QCBOREncode_OpenArray() to open a new array, then various @c
211 * QCBOREncode_AddXxx() functions to put items in the array and then
212 * QCBOREncode_CloseArray(). Nesting to the limit @ref
213 * QCBOR_MAX_ARRAY_NESTING is allowed. All opens must be matched by
214 * closes or an encoding error will be returned.
215 *
216 * The other aggregate type is a map which does use labels. The `Add`
217 * functions that end in `ToMap` and `ToMapN` are convenient ways to add
218 * labeled data items to a map. You can also call any type of `Add`
219 * function once to add a label of any type and then call any type of
220 * `Add` again to add its value.
221 *
222 * Note that when you nest arrays or maps in a map, the nested array or
223 * map has a label.
224 *
225 * Many CBOR-based protocols start with an array or map. This makes them
226 * self-delimiting. No external length or end marker is needed to know
227 * the end. It is also possible not start this way, in which case this
228 * it is usually called a CBOR sequence which is described in
229 * [RFC 8742] (https://tools.ietf.org/html/rfc8742). This encoder supports
230 * either just by whether the first item added is an array, map or other.
231 *
232 * If QCBOR is compiled with QCBOR_DISABLE_ENCODE_USAGE_GUARDS defined,
233 * the errors QCBOR_ERR_CLOSE_MISMATCH, QCBOR_ERR_ARRAY_TOO_LONG,
234 * QCBOR_ERR_TOO_MANY_CLOSES, QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN, and
235 * QCBOR_ERR_ENCODE_UNSUPPORTED will never be returned. It is up to the
236 * caller to make sure that opened maps, arrays and byte-string wrapping
237 * is closed correctly and that QCBOREncode_AddType7() is called
238 * correctly. With this defined, it is easier to make a mistake when
239 * authoring the encoding of a protocol that will output not well formed
240 * CBOR, but as long as the calling code is correct, it is safe to
241 * disable these checks. Bounds checking that prevents security issues
242 * in the code is still enforced. This define reduces the size of
243 * encoding object code by about 150 bytes.
244 *
245 * @anchor Tags-Overview
246 *
247 * ## Tags Overview
248 *
249 * Any CBOR data item can be made into a tag to add semantics, define a
250 * new data type or such. Some tags are fully standardized and some are
251 * just registered. Others are not registered and used in a proprietary
252 * way.
253 *
254 * Encoding and decoding of many of the registered tags is fully
255 * implemented by QCBOR. It is also possible to encode and decode tags
256 * that are not directly supported. For many use cases the built-in tag
257 * support should be adequate.
258 *
259 * For example, the registered epoch date tag is supported in encoding
260 * by QCBOREncode_AddDateEpoch() and in decoding by @ref
261 * QCBOR_TYPE_DATE_EPOCH and the @c epochDate member of @ref
262 * QCBORItem. This is typical of the built-in tag support. There is an
263 * API to encode data for it and a @c QCBOR_TYPE_XXX when it is decoded.
264 *
265 * Tags are registered in the [IANA CBOR Tags Registry]
266 * (https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml). There
267 * are roughly three options to create a new tag. First, a public
268 * specification can be created and the new tag registered with IANA.
269 * This is the most formal. Second, the new tag can be registered with
270 * IANA with just a short description rather than a full specification.
271 * These tags must be greater than 256. Third, a tag can be used without
272 * any IANA registration, though the registry should be checked to see
273 * that the new value doesn't collide with one that is registered. The
274 * value of these tags must be 256 or larger.
275 *
276 * See also @ref CBORTags and @ref Tag-Usage
277 *
278 * The encoding side of tags not built-in is handled by
279 * QCBOREncode_AddTag() and is relatively simple. Tag decoding is more
280 * complex and mainly handled by QCBORDecode_GetNext(). Decoding of the
281 * structure of tagged data not built-in (if there is any) has to be
282 * implemented by the caller.
283 *
284 * @anchor Floating-Point
285 *
286 * ## Floating-Point
287 *
288 * By default QCBOR fully supports IEEE 754 floating-point:
289 * - Encode/decode of double, single and half-precision
290 * - CBOR preferred serialization of floating-point
291 * - Floating-point epoch dates
292 *
293 * For the most part, the type double is used in the interface for
294 * floating-point values. In the default configuration, all decoded
295 * floating-point values are returned as a double.
296 *
297 * With CBOR preferred serialization, the encoder outputs the smallest
298 * representation of the double or float that preserves precision. Zero,
299 * NaN and infinity are always output as a half-precision, each taking
300 * just 2 bytes. This reduces the number of bytes needed to encode
301 * double and single-precision, especially if zero, NaN and infinity are
302 * frequently used.
303 *
304 * To avoid use of preferred serialization in the standard configuration
305 * when encoding, use QCBOREncode_AddDoubleNoPreferred() or
306 * QCBOREncode_AddFloatNoPreferred().
307 *
308 * This implementation of preferred floating-point serialization and
309 * half-precision does not depend on the CPU having floating-point HW or
310 * the compiler bringing in a (sometimes large) library to compensate
311 * for lack of CPU support. This implementation uses shifts and masks
312 * rather than floating-point functions.
313 *
314 * To reduce overall object code by about 900 bytes, define
315 * QCBOR_DISABLE_PREFERRED_FLOAT. This will eliminate all support for
316 * preferred serialization and half-precision. An error will be returned
317 * when attempting to decode half-precision. A float will always be
318 * encoded and decoded as 32-bits and a double will always be encoded
319 * and decoded as 64 bits.
320 *
321 * Note that even if QCBOR_DISABLE_PREFERRED_FLOAT is not defined all
322 * the float-point encoding object code can be avoided by never calling
323 * any functions that encode double or float. Just not calling
324 * floating-point functions will reduce object code by about 500 bytes.
325 *
326 * On CPUs that have no floating-point hardware,
327 * QCBOR_DISABLE_FLOAT_HW_USE should be defined in most cases. If it is
328 * not, then the compiler will bring in possibly large software
329 * libraries to compensate. Defining QCBOR_DISABLE_FLOAT_HW_USE reduces
330 * object code size on CPUs with floating-point hardware by a tiny
331 * amount and eliminates the need for <math.h>
332 *
333 * When QCBOR_DISABLE_FLOAT_HW_USE is defined, trying to decoding
334 * floating-point dates will give error
335 * @ref QCBOR_ERR_FLOAT_DATE_DISABLED and decoded single-precision
336 * numbers will be returned as @ref QCBOR_TYPE_FLOAT instead of
337 * converting them to double as usual.
338 *
339 * If both QCBOR_DISABLE_FLOAT_HW_USE and QCBOR_DISABLE_PREFERRED_FLOAT
340 * are defined, then the only thing QCBOR can do is encode/decode a C
341 * float type as 32-bits and a C double type as 64-bits. Floating-point
342 * epoch dates will be unsupported.
343 *
Laurence Lundblade475c2722024-05-08 11:17:47 -0700344 * If USEFULBUF_DISABLE_ALL_FLOAT is defined, then floating point
Laurence Lundblade3eead482023-12-16 20:53:22 -0700345 * support is completely disabled. Decoding functions return
346 * @ref QCBOR_ERR_ALL_FLOAT_DISABLED if a floating point value is
347 * encountered during decoding. Functions that are encoding floating
348 * point values are not available.
349 *
350 * ## Limitations
351 *
Laurence Lundblade475c2722024-05-08 11:17:47 -0700352 * Summary limitations:
Laurence Lundblade3eead482023-12-16 20:53:22 -0700353 * - The entire encoded CBOR must fit into contiguous memory.
Laurence Lundblade475c2722024-05-08 11:17:47 -0700354 * - Max size of encoded CBOR data is a few bytes less than
355 * @c UINT32_MAX (4GB).
356 * - Max array / map nesting level when encoding or decoding is
Laurence Lundblade3eead482023-12-16 20:53:22 -0700357 * @ref QCBOR_MAX_ARRAY_NESTING (this is typically 15).
Laurence Lundblade475c2722024-05-08 11:17:47 -0700358 * - Max items in an array or map when encoding or decoding is
Laurence Lundblade3eead482023-12-16 20:53:22 -0700359 * @ref QCBOR_MAX_ITEMS_IN_ARRAY (typically 65,536).
360 * - Does not directly support labels in maps other than text strings & integers.
Laurence Lundblade475c2722024-05-08 11:17:47 -0700361 * - Does not directly support integer labels beyond whats fits in @c int64_t
362 * or @c uint64_t.
Laurence Lundblade3eead482023-12-16 20:53:22 -0700363 * - Epoch dates limited to @c INT64_MAX (+/- 292 billion years).
Laurence Lundblade475c2722024-05-08 11:17:47 -0700364 * - Exponents for bigfloats and decimal integers are limited to whats fits in
365 * @c int64_t.
Laurence Lundblade3eead482023-12-16 20:53:22 -0700366 * - Tags on labels are ignored during decoding.
367 * - The maximum tag nesting is @c QCBOR_MAX_TAGS_PER_ITEM (typically 4).
Laurence Lundblade475c2722024-05-08 11:17:47 -0700368 * - Works only on 32- and 64-bit CPUs.
Laurence Lundblade31fddb72024-05-13 13:03:35 -0700369 * - QCBORDecode_EnterBstrWrapped() doesn't work on indefinite-length strings.
Laurence Lundblade3eead482023-12-16 20:53:22 -0700370 *
371 * The public interface uses @c size_t for all lengths. Internally the
372 * implementation uses 32-bit lengths by design to use less memory and
373 * fit structures on the stack. This limits the encoded CBOR it can
Laurence Lundblade475c2722024-05-08 11:17:47 -0700374 * work with to size @c UINT32_MAX (4GB).
Laurence Lundblade3eead482023-12-16 20:53:22 -0700375 *
Laurence Lundblade475c2722024-05-08 11:17:47 -0700376 * This implementation requires two's compliment integers. While
377 * C doesn't require two's compliment, <stdint.h> does. Other
378 * parts of this implementation may also require two's compliment.
Michael Eckel5c531332020-03-02 01:35:30 +0100379 */
380
381
Laurence Lundblade825164e2020-10-22 20:18:06 -0700382/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700383 * The size of the buffer to be passed to QCBOREncode_EncodeHead(). It
384 * is one byte larger than sizeof(uint64_t) + 1, the actual maximum
385 * size of the head of a CBOR data item because
386 * QCBOREncode_EncodeHead() needs one extra byte to work.
Michael Eckel5c531332020-03-02 01:35:30 +0100387 */
388#define QCBOR_HEAD_BUFFER_SIZE (sizeof(uint64_t) + 2)
389
Michael Eckel5c531332020-03-02 01:35:30 +0100390
Laurence Lundblade9b334962020-08-27 10:55:53 -0700391/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700392 * Output the full CBOR tag. See @ref CBORTags, @ref Tag-Usage and
393 * @ref Tags-Overview.
Laurence Lundblade9b334962020-08-27 10:55:53 -0700394 */
395#define QCBOR_ENCODE_AS_TAG 0
396
397/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700398 * Output only the 'borrowed' content format for the relevant tag.
399 * See @ref CBORTags, @ref Tag-Usage and @ref Tags-Overview.
Laurence Lundblade9b334962020-08-27 10:55:53 -0700400 */
401#define QCBOR_ENCODE_AS_BORROWED 1
402
Michael Eckel5c531332020-03-02 01:35:30 +0100403
404/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700405 * QCBOREncodeContext is the data type that holds context for all the
406 * encoding functions. It is less than 200 bytes, so it can go on the
407 * stack. The contents are opaque, and the caller should not access
408 * internal members. A context may be re used serially as long as it is
409 * re initialized.
Michael Eckel5c531332020-03-02 01:35:30 +0100410 */
411typedef struct _QCBOREncodeContext QCBOREncodeContext;
412
413
414/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700415 * Initialize the encoder to prepare to encode some CBOR.
416 *
417 * @param[in,out] pCtx The encoder context to initialize.
418 * @param[in] Storage The buffer into which the encoded result
419 * will be written.
420 *
421 * Call this once at the start of an encoding of some CBOR. Then call
422 * the many functions like QCBOREncode_AddInt64() and
423 * QCBOREncode_AddText() to add the different data items. Finally,
424 * call QCBOREncode_Finish() to get the pointer and length of the
425 * encoded result.
426 *
427 * The primary purpose of this function is to give the pointer and
428 * length of the output buffer into which the encoded CBOR will be
429 * written. This is done with a @ref UsefulBuf structure, which is
430 * just a pointer and length (it is equivalent to two parameters, one
431 * a pointer and one a length, but a little prettier).
432 *
433 * The output buffer can be allocated any way (malloc, stack,
434 * static). It is just some memory that QCBOR writes to. The length
435 * must be the length of the allocated buffer. QCBOR will never write
436 * past that length, but might write up to that length. If the buffer
437 * is too small, encoding will go into an error state and not write
438 * anything further.
439 *
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -0800440 * If allocating on the stack, the convenience macro
Laurence Lundblade3eead482023-12-16 20:53:22 -0700441 * UsefulBuf_MAKE_STACK_UB() can be used, but its use is not required.
442 *
443 * Since there is no reallocation or such, the output buffer must be
444 * correctly sized when passed in here. It is OK, but wasteful if it
445 * is too large. One way to pick the size is to figure out the maximum
446 * size that will ever be needed and hard code a buffer of that size.
447 *
448 * Another way to do it is to have QCBOR calculate it for you. To do
449 * this, pass @ref SizeCalculateUsefulBuf for @c Storage. Then call
450 * all the functions to add the CBOR exactly as if encoding for
451 * real. Finally, call QCBOREncode_FinishGetSize(). Once the length
452 * is obtained, allocate a buffer of that size, call
453 * QCBOREncode_Init() again with the real buffer. Call all the add
454 * functions again and finally, QCBOREncode_Finish() to obtain the
455 * final result. This uses twice the CPU time, but that is usually not
456 * an issue.
457 *
458 * See QCBOREncode_Finish() for how the pointer and length for the
459 * encoded CBOR is returned.
460 *
461 * For practical purposes QCBOR can't output encoded CBOR larger than
462 * @c UINT32_MAX (4GB) even on 64-bit CPUs because the internal
463 * offsets used to track the start of an array/map are 32 bits to
464 * reduce the size of the encoding context.
465 *
466 * A @ref QCBOREncodeContext can be reused over and over as long as
467 * QCBOREncode_Init() is called before each use.
Michael Eckel5c531332020-03-02 01:35:30 +0100468 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700469void
470QCBOREncode_Init(QCBOREncodeContext *pCtx, UsefulBuf Storage);
Michael Eckel5c531332020-03-02 01:35:30 +0100471
472
473/**
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -0800474 * @brief Select preferred serialization mode.
475 *
476 * @param[in] pCtx The encoding context for mode set.
477 *
478 * Setting this mode will cause QCBOR to return an error if an attempt
479 * is made to use one of the methods that produce non-preferred
480 * serialization. It doesn't change anything else as QCBOR produces
481 * preferred serialization by default.
482 *
483 * The non-preferred methods are: QCBOREncode_AddFloatNoPreferred(),
484 * QCBOREncode_AddDoubleNoPreferred(),
485 * QCBOREncode_OpenArrayIndefiniteLength(),
486 * QCBOREncode_CloseArrayIndefiniteLength(),
487 * QCBOREncode_OpenMapIndefiniteLength(),
488 * QCBOREncode_CloseMapIndefiniteLength(), plus those derived from the
489 * above listed.
490 *
491 * This mode is just a user guard to prevent accidentally calling
492 * something that produces non-preferred serialization. It doesn't do
493 * anything but causes errors to occur on attempts to call the above
494 * listed functions. This does nothing if the library is compiled
495 * QCBOR_DISABLE_ENCODE_USAGE_GUARDS.
496 *
497 * See @ref Serialization. It is usually not necessary to set this
498 * mode, but there is usually no disadvantage to setting it. Preferred
499 * Serialization is defined in RFC 8949, section 4.1.
500 */
501static void
502QCBOREncode_SerializationPreferred(QCBOREncodeContext *pCtx);
503
504
505/**
506 * @brief Select CBOR deterministic encoding mode.
507 *
508 * @param[in] pCtx The encoding context for mode set.
509
510 * This causes QCBOR to produce CBOR Deterministic Encoding (CDE).
511 * With CDE, two distant unrelated CBOR encoders will produce exactly
512 * the same encoded CBOR for a given input.
513 *
514 * In addition to doing everything
515 * QCBOREncode_SerializationPreferred() does (including exclusion of
516 * indefinite lengths), this causes maps to be sorted. The map is
517 * sorted automatically when QCBOREncode_CloseMap() is called.
518 * QCBOREncode_CloseMap() becomes equivalent to
519 * QCBOREncode_CloseAndSortMap().
520 *
521 * Note that linking this function causese about 30% more code from
522 * the QCBOR library to be linked. Also, QCBOREncode_CloseMap() runs
523 * slower, but this is probably only of consequence in very
524 * constrained environments.
525 *
526 * See @ref Serialization. It is usually not necessary to set this
527 * mode as determinism is very rarely needed. However it will
528 * usually work with most protocols. CDE is defined in
529 * draft-ietf-cbor-cde.
530 */
531static void
532QCBOREncode_SerializationCDE(QCBOREncodeContext *pCtx);
533
534
535/**
536 * @brief Select "dCBOR" encoding mode.
537 *
538 * @param[in] pCtx The encoding context for mode set.
539 *
540 * This is a superset of CDE. This function does everything
541 * QCBOREncode_SerializationCDE() does. Also it is a super set of
542 * preferred serialization and does everything
543 * QCBOREncode_SerializationPreferred() does.
544 *
545 * The main feature of dCBOR is that there is only one way to serialize a
546 * particular numeric value. This changes the behavior of functions
547 * that add floating-point numbers. If the floating-point number is
548 * whole, it will be encoded as an integer, not a floating-point number.
549 * 0.000 will be encoded as 0x00. Precision is never lost in this
550 * conversion.
551 *
552 * dCBOR also disallows NaN payloads. QCBOR will allow NaN payloads if
553 * you pass a NaN to one of the floating-point encoding functions.
554 * This mode forces all NaNs to the half-precision queit NaN. Also see
555 * QCBOREncode_Allow().
556 *
557 * dCBOR also disallows 65-bit negative integers.
558 *
559 * dCBOR disallows use of any simple type other than true, false and
560 * NULL. In particular it disallows use of "undef" produced by
561 * QCBOREncode_AddUndef().
562 *
563 * See @ref Serialization. Set this mode only if the protocol you are
564 * implementing requires dCBOR. This mode is usually not compatible
565 * with protocols that don't use dCBOR. dCBOR is defined in
566 * draft-mcnally-deterministic-cbor.
567 */
568static void
569QCBOREncode_SerializationdCBOR(QCBOREncodeContext *pCtx);
570
571
572
573
574/** Bit flag to be passed to QCBOREncode_Allow() to allow NaN payloads
575 * to be output by QCBOREncode_AddDouble(),
576 * QCBOREncode_AddDoubleNoPreferred(), QCBORENcode_AddFloat() and
577 * QCBOREncode_AddSingleleNoPreferred. */
578#define QCBOR_ENCODE_ALLOW_NAN_PAYLOAD 0x01
579
580/** Bit flag to be passed to QCBOREncode_Allow() to allow use of
581 * QCBOREncode_AddNegativeUInt64(). */
582#define QCBOR_ENCODE_ALLOW_65_BIG_NEG 0x02
583
584/** Bit flag to be passed to QCBOREncode_Allow() output of less
585 * interoperable values. See @ref QCBOR_ENCODE_ALLOW_NAN_PAYLOAD, and
586 * @ref QCBOR_ENCODE_ALLOW_65_BIG_NEG. */
587#define QCBOR_ENCODE_ALLOW_ALL 0xFF
588
589
590/**
591 * @brief Allow encoding of less-interoperable values.
592 *
593 * @param[in] pCtx The encoding context.
594 * @param[in] uAllow Bit flags indicating what to allow.
595 *
596 * There are a few things in the CBOR standard that are often not
597 * supported and are thus not very interoperable. By default QCBOR
598 * will error if you attempt to output them. This disables that
599 * error.
600 *
601 * See @ref QCBOR_ENCODE_ALLOW_NAN_PAYLOAD and
602 * @ref QCBOR_ENCODE_ALLOW_65_BIG_NEG.
603 *
604 * This does nothing if the library is compiled
605 * QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
606static void
607QCBOREncode_Allow(QCBOREncodeContext *pCtx, uint8_t uAllow);
608
609
610
611/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700612 * @brief Add a signed 64-bit integer to the encoded output.
613 *
614 * @param[in] pCtx The encoding context to add the integer to.
615 * @param[in] nNum The integer to add.
616 *
617 * The integer will be encoded and added to the CBOR output.
618 *
619 * This function figures out the size and the sign and encodes in the
620 * correct minimal CBOR. Specifically, it will select CBOR major type
621 * 0 or 1 based on sign and will encode to 1, 2, 4 or 8 bytes
622 * depending on the value of the integer. Values less than 24
623 * effectively encode to one byte because they are encoded in with the
624 * CBOR major type. This is a neat and efficient characteristic of
625 * CBOR that can be taken advantage of when designing CBOR-based
626 * protocols. If integers like tags can be kept between -23 and 23
627 * they will be encoded in one byte including the major type.
628 *
629 * If you pass a smaller int, say an @c int16_t or a small value, say
630 * 100, the encoding will still be CBOR's most compact that can
631 * represent the value. For example, CBOR always encodes the value 0
632 * as one byte, 0x00. The representation as 0x00 includes
633 * identification of the type as an integer too as the major type for
634 * an integer is 0. See [RFC 8949]
635 * (https://tools.ietf.org/html/rfc8949) Appendix A for more examples
636 * of CBOR encoding. This compact encoding is also preferred
637 * serialization CBOR as per section 34.1 in RFC 8949.
638 *
639 * There are no functions to add @c int16_t or @c int32_t because they
640 * are not necessary because this always encodes to the smallest
641 * number of bytes based on the value (If this code is running on a
642 * 32-bit machine having a way to add 32-bit integers would reduce
643 * code size some).
644 *
645 * If the encoding context is in an error state, this will do
646 * nothing. If an error occurs when adding this integer, the internal
647 * error flag will be set, and the error will be returned when
648 * QCBOREncode_Finish() is called.
649 *
650 * See also QCBOREncode_AddUInt64().
Michael Eckel5c531332020-03-02 01:35:30 +0100651 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700652void
653QCBOREncode_AddInt64(QCBOREncodeContext *pCtx, int64_t nNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100654
Laurence Lundblade3eead482023-12-16 20:53:22 -0700655static void
656QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100657
Laurence Lundblade3eead482023-12-16 20:53:22 -0700658static void
659QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100660
661
662/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700663 * @brief Add an unsigned 64-bit integer to the encoded output.
664 *
665 * @param[in] pCtx The encoding context to add the integer to.
666 * @param[in] uNum The integer to add.
667 *
668 * The integer will be encoded and added to the CBOR output.
669 *
670 * The only reason so use this function is for integers larger than
671 * @c INT64_MAX and smaller than @c UINT64_MAX. Otherwise
672 * QCBOREncode_AddInt64() will work fine.
673 *
674 * Error handling is the same as for QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +0100675 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700676void
677QCBOREncode_AddUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100678
Laurence Lundblade3eead482023-12-16 20:53:22 -0700679static void
680QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100681
Laurence Lundblade3eead482023-12-16 20:53:22 -0700682static void
683QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100684
685
686/**
Laurence Lundblade2d493002024-02-01 11:09:17 -0700687 * @brief Add a negative 64-bit integer to encoded output
688 *
689 * @param[in] pCtx The encoding context to add the integer to.
690 * @param[in] uNum The integer to add.
691 *
692 * QCBOREncode_AddInt64() is much better to encode negative integers
693 * than this. What this can do is add integers with one more
694 * significant bit than an int64_t (a "65-bit" integer if you count
695 * the sign as a bit) which is possible because CBOR happens to
696 * support such integers.
697 *
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -0800698 * Because use of this is discouraged. It must be explicitly allowed
699 * by passing @ref QCBOR_ENCODE_ALLOW_65_BIG_NEG to a call to
700 * QCBOREncode_Allow().
701 *
Laurence Lundblade2d493002024-02-01 11:09:17 -0700702 * The actual value encoded is -uNum - 1. That is, give 0 for uNum to
703 * transmit -1, give 1 to transmit -2 and give UINT64_MAX to transmit
704 * -UINT64_MAX-1 (18446744073709551616). The interface is odd like
705 * this so all negative values CBOR can represent can be encoded by
706 * QCBOR (making this a complete CBOR implementation).
707 *
708 * The most negative value QCBOREncode_AddInt64() can encode is
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -0800709 * -9223372036854775808 which is -2^63 or negative 0x800000000000.
710 * This can encode from -9223372036854775809 to -18446744073709551616
711 * or -2^63 - 1 to -2^64. Note that it is not possible to represent
712 * positive or negative 18446744073709551616 in any standard C data
713 * type.
Laurence Lundblade2d493002024-02-01 11:09:17 -0700714 *
715 * Negative integers are normally decoded in QCBOR with type
716 * @ref QCBOR_TYPE_INT64. Integers in the range of -9223372036854775809
717 * to -18446744073709551616 are returned as @ref QCBOR_TYPE_65BIT_NEG_INT.
718 *
719 * WARNING: some CBOR decoders will be unable to decode -2^63 - 1 to
720 * -2^64. Also, most CPUs do not have registers that can represent
721 * this range. If you need 65-bit negative integers, you likely need
722 * negative 66, 67 and 68-bit negative integers so it is likely better
723 * to use CBOR big numbers where you can have any number of bits. See
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -0800724 * QCBOREncode_AddTNegativeBignum() and @ref Serialization.
Laurence Lundblade2d493002024-02-01 11:09:17 -0700725 */
726void
727QCBOREncode_AddNegativeUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
728
729static void
730QCBOREncode_AddNegativeUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum);
731
732static void
733QCBOREncode_AddNegativeUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum);
734
735/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700736 * @brief Add a UTF-8 text string to the encoded output.
737 *
738 * @param[in] pCtx The encoding context to add the text to.
739 * @param[in] Text Pointer and length of text to add.
740 *
741 * The text passed in must be unencoded UTF-8 according to [RFC 3629]
742 * (https://tools.ietf.org/html/rfc3629). There is no NULL
743 * termination. The text is added as CBOR major type 3.
744 *
745 * If called with @c nBytesLen equal to 0, an empty string will be
746 * added. When @c nBytesLen is 0, @c pBytes may be @c NULL.
747 *
748 * Note that the restriction of the buffer length to a @c uint32_t is
749 * entirely intentional as this encoder is not capable of encoding
750 * lengths greater. This limit to 4GB for a text string should not be
751 * a problem.
752 *
753 * Text lines in Internet protocols (on the wire) are delimited by
754 * either a CRLF or just an LF. Officially many protocols specify
755 * CRLF, but implementations often work with either. CBOR type 3 text
756 * can be either line ending, even a mixture of both.
757 *
758 * Operating systems usually have a line end convention. Windows uses
759 * CRLF. Linux and MacOS use LF. Some applications on a given OS may
760 * work with either and some may not.
761 *
762 * The majority of use cases and CBOR protocols using type 3 text will
763 * work with either line ending. However, some use cases or protocols
764 * may not work with either in which case translation to and/or from
765 * the local line end convention, typically that of the OS, is
766 * necessary.
767 *
768 * QCBOR does no line ending translation for type 3 text when encoding
769 * and decoding.
770 *
771 * Error handling is the same as QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +0100772 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700773static void
774QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text);
Michael Eckel5c531332020-03-02 01:35:30 +0100775
Laurence Lundblade3eead482023-12-16 20:53:22 -0700776static void
777QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text);
Michael Eckel5c531332020-03-02 01:35:30 +0100778
Laurence Lundblade3eead482023-12-16 20:53:22 -0700779static void
780QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text);
Michael Eckel5c531332020-03-02 01:35:30 +0100781
782
783/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700784 * @brief Add a UTF-8 text string to the encoded output.
785 *
786 * @param[in] pCtx The encoding context to add the text to.
787 * @param[in] szString Null-terminated text to add.
788 *
789 * This works the same as QCBOREncode_AddText().
Michael Eckel5c531332020-03-02 01:35:30 +0100790 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700791static void
792QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString);
Michael Eckel5c531332020-03-02 01:35:30 +0100793
Laurence Lundblade3eead482023-12-16 20:53:22 -0700794static void
795QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString);
Michael Eckel5c531332020-03-02 01:35:30 +0100796
Laurence Lundblade3eead482023-12-16 20:53:22 -0700797static void
798QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString);
Michael Eckel5c531332020-03-02 01:35:30 +0100799
800
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200801#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Michael Eckel5c531332020-03-02 01:35:30 +0100802/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700803 * @brief Add a double-precision floating-point number to the encoded output.
804 *
805 * @param[in] pCtx The encoding context to add the double to.
806 * @param[in] dNum The double-precision number to add.
807 *
808 * This encodes and outputs a floating-point number. CBOR major type 7
809 * is used.
810 *
811 * This implements preferred serialization, selectively encoding the
812 * double-precision floating-point number as either double-precision,
813 * single-precision or half-precision. Infinity, NaN and 0 are always
814 * encoded as half-precision. If no precision will be lost in the
815 * conversion to half-precision, then it will be converted and
816 * encoded. If not and no precision will be lost in conversion to
817 * single-precision, then it will be converted and encoded. If not,
818 * then no conversion is performed, and it encoded as a
819 * double-precision.
820 *
821 * Half-precision floating-point numbers take up 2 bytes, half that of
822 * single-precision, one quarter of double-precision
823 *
824 * This automatically reduces the size of encoded CBOR, maybe even by
825 * four if most of values are 0, infinity or NaN.
826 *
827 * When decoded, QCBOR will usually return these values as
828 * double-precision.
829 *
830 * It is possible to disable this preferred serialization when compiling
831 * QCBOR. In that case, this functions the same as
832 * QCBOREncode_AddDoubleNoPreferred().
833 *
834 * Error handling is the same as QCBOREncode_AddInt64().
835 *
836 * See also QCBOREncode_AddDoubleNoPreferred(), QCBOREncode_AddFloat()
837 * and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -0800838 *
839 * By default, this will error out on an attempt to encode a NaN with
840 * a payload. See QCBOREncode_Allow() and @ref QCBOR_ENCODE_ALLOW_NAN_PAYLOAD.
Michael Eckel5c531332020-03-02 01:35:30 +0100841 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700842void
843QCBOREncode_AddDouble(QCBOREncodeContext *pCtx, double dNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100844
Laurence Lundblade3eead482023-12-16 20:53:22 -0700845static void
846QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100847
Laurence Lundblade3eead482023-12-16 20:53:22 -0700848static void
849QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100850
851
852/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700853 * @brief Add a single-precision floating-point number to the encoded output.
854 *
855 * @param[in] pCtx The encoding context to add the double to.
856 * @param[in] fNum The single-precision number to add.
857 *
858 * This is identical to QCBOREncode_AddDouble() except the input is
859 * single-precision.
860 *
861 * See also QCBOREncode_AddDouble(), QCBOREncode_AddDoubleNoPreferred(),
862 * and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
863 */
864void
865QCBOREncode_AddFloat(QCBOREncodeContext *pCtx, float fNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700866
Laurence Lundblade3eead482023-12-16 20:53:22 -0700867static void
868QCBOREncode_AddFloatToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700869
Laurence Lundblade3eead482023-12-16 20:53:22 -0700870static void
871QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700872
873
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700874/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700875 * @brief Add a double-precision floating-point number without preferred encoding.
876 *
877 * @param[in] pCtx The encoding context to add the double to.
878 * @param[in] dNum The double-precision number to add.
879 *
880 * This always outputs the number as a 64-bit double-precision.
881 * Preferred serialization is not used.
882 *
883 * Error handling is the same as QCBOREncode_AddInt64().
884 *
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -0800885 * By default, this will error out on an attempt to encode a NaN with
886 * a payload. See QCBOREncode_Allow() and @ref QCBOR_ENCODE_ALLOW_NAN_PAYLOAD.
887 *
Laurence Lundblade3eead482023-12-16 20:53:22 -0700888 * See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
889 * QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
890 */
891void
892QCBOREncode_AddDoubleNoPreferred(QCBOREncodeContext *pCtx, double dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700893
Laurence Lundblade3eead482023-12-16 20:53:22 -0700894static void
895QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700896
Laurence Lundblade3eead482023-12-16 20:53:22 -0700897static void
898QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700899
900
901/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700902 * @brief Add a single-precision floating-point number without preferred encoding.
903 *
904 * @param[in] pCtx The encoding context to add the double to.
905 * @param[in] fNum The single-precision number to add.
906 *
907 * This always outputs the number as a 32-bit single-precision.
908 * Preferred serialization is not used.
909 *
910 * Error handling is the same as QCBOREncode_AddInt64().
911 *
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -0800912 * By default, this will error out on an attempt to encode a NaN with
913 * a payload. See QCBOREncode_Allow() and @ref QCBOR_ENCODE_ALLOW_NAN_PAYLOAD.
914 *
Laurence Lundblade3eead482023-12-16 20:53:22 -0700915 * See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
916 * QCBOREncode_AddDoubleNoPreferred() and @ref Floating-Point.
917 */
918void
919QCBOREncode_AddFloatNoPreferred(QCBOREncodeContext *pCtx, float fNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700920
Laurence Lundblade3eead482023-12-16 20:53:22 -0700921static void
922QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700923
Laurence Lundblade3eead482023-12-16 20:53:22 -0700924static void
925QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float fNum);
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200926#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700927
928
Michael Eckel5c531332020-03-02 01:35:30 +0100929/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700930 * @brief Add an optional tag.
931 *
932 * @param[in] pCtx The encoding context to add the tag to.
933 * @param[in] uTag The tag to add
934 *
935 * This outputs a CBOR major type 6 item that tags the next data item
936 * that is output usually to indicate it is some new data type.
937 *
938 * For many of the common standard tags, a function to encode data
939 * using it is provided and this is not needed. For example,
940 * QCBOREncode_AddDateEpoch() already exists to output integers
941 * representing dates with the right tag.
942 *
943 * The tag is applied to the next data item added to the encoded
944 * output. That data item that is to be tagged can be of any major
945 * CBOR type. Any number of tags can be added to a data item by
946 * calling this multiple times before the data item is added.
947 *
948 * See @ref Tags-Overview for discussion of creating new non-standard
949 * tags. See QCBORDecode_GetNext() for discussion of decoding custom
950 * tags.
Michael Eckel5c531332020-03-02 01:35:30 +0100951 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700952void
953QCBOREncode_AddTag(QCBOREncodeContext *pCtx, uint64_t uTag);
Laurence Lundblade46d63e92021-05-13 11:37:10 -0700954
955
Michael Eckel5c531332020-03-02 01:35:30 +0100956/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700957 * @brief Add an epoch-based date.
958 *
959 * @param[in] pCtx The encoding context to add the date to.
960 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
961 * @ref QCBOR_ENCODE_AS_BORROWED.
962 * @param[in] nDate Number of seconds since 1970-01-01T00:00Z
963 * in UTC time.
964 *
965 * As per RFC 8949 this is similar to UNIX/Linux/POSIX dates. This is
966 * the most compact way to specify a date and time in CBOR. Note that
967 * this is always UTC and does not include the time zone. Use
968 * QCBOREncode_AddDateString() if you want to include the time zone.
969 *
970 * The preferred integer serialization rules apply here so the date will be
971 * encoded in a minimal number of bytes. Until about the year 2106
972 * these dates will encode in 6 bytes -- one byte for the tag, one
973 * byte for the type and 4 bytes for the integer. After that it will
974 * encode to 10 bytes.
975 *
976 * Negative values are supported for dates before 1970.
977 *
978 * If you care about leap-seconds and that level of accuracy, make sure
979 * the system you are running this code on does it correctly. This code
980 * just takes the value passed in.
981 *
982 * This implementation cannot encode fractional seconds using float or
983 * double even though that is allowed by CBOR, but you can encode them
984 * if you want to by calling QCBOREncode_AddTag() and QCBOREncode_AddDouble().
985 *
986 * Error handling is the same as QCBOREncode_AddInt64().
987 *
988 * See also QCBOREncode_AddTDaysEpoch().
Michael Eckel5c531332020-03-02 01:35:30 +0100989 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700990static void
991QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pCtx,
992 uint8_t uTagRequirement,
993 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100994
Laurence Lundblade3eead482023-12-16 20:53:22 -0700995static void
996QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pCtx,
997 const char *szLabel,
998 uint8_t uTagRequirement,
999 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001000
Laurence Lundblade3eead482023-12-16 20:53:22 -07001001static void
1002QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pCtx,
1003 int64_t nLabel,
1004 uint8_t uTagRequirement,
1005 int64_t nDate);
1006
1007
1008static void
1009QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx,
1010 int64_t nDate);
1011
1012static void
1013QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx,
1014 const char *szLabel,
1015 int64_t nDate);
1016
1017static void
1018QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx,
1019 int64_t nLabel,
1020 int64_t nDate);
1021
Michael Eckel5c531332020-03-02 01:35:30 +01001022
1023
Michael Eckel5c531332020-03-02 01:35:30 +01001024/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001025 * @brief Add an epoch-based day-count date.
1026 *
1027 * @param[in] pCtx The encoding context to add the date to.
1028 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1029 * @ref QCBOR_ENCODE_AS_BORROWED.
1030 * @param[in] nDays Number of days before or after 1970-01-0.
1031 *
1032 * This date format is described in
1033 * [RFC 8943] (https://tools.ietf.org/html/rfc8943).
1034 *
1035 * The preferred integer serialization rules apply here so the date
1036 * will be encoded in a minimal number of bytes. Until about the year
1037 * 2149 these dates will encode in 4 bytes -- one byte for the tag,
1038 * one byte for the type and 2 bytes for the integer.
1039 *
1040 * See also QCBOREncode_AddTDateEpoch().
1041 */
1042static void
1043QCBOREncode_AddTDaysEpoch(QCBOREncodeContext *pCtx,
1044 uint8_t uTagRequirement,
1045 int64_t nDays);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001046
Laurence Lundblade3eead482023-12-16 20:53:22 -07001047static void
1048QCBOREncode_AddTDaysEpochToMapSZ(QCBOREncodeContext *pCtx,
1049 const char *szLabel,
1050 uint8_t uTagRequirement,
1051 int64_t nDays);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001052
Laurence Lundblade3eead482023-12-16 20:53:22 -07001053static void
1054QCBOREncode_AddTDaysEpochToMapN(QCBOREncodeContext *pCtx,
1055 int64_t nLabel,
1056 uint8_t uTagRequirement,
1057 int64_t nDays);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001058
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001059
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001060
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001061
Laurence Lundblade3eead482023-12-16 20:53:22 -07001062/**
1063 * @brief Add a byte string to the encoded output.
1064 *
1065 * @param[in] pCtx The encoding context to add the bytes to.
1066 * @param[in] Bytes Pointer and length of the input data.
1067 *
1068 * Simply adds the bytes to the encoded output as CBOR major type 2.
1069 *
1070 * If called with @c Bytes.len equal to 0, an empty string will be
1071 * added. When @c Bytes.len is 0, @c Bytes.ptr may be @c NULL.
1072 *
1073 * Error handling is the same as QCBOREncode_AddInt64().
1074 */
1075static void
1076QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001077
Laurence Lundblade3eead482023-12-16 20:53:22 -07001078static void
1079QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
1080
1081static void
1082QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
1083
1084
1085/**
1086 * @brief Set up to write a byte string value directly to encoded output.
1087 *
1088 * @param[in] pCtx The encoding context to add the bytes to.
1089 * @param[out] pPlace Pointer and length of place to write byte string value.
1090 *
1091 * QCBOREncode_AddBytes() is the normal way to encode a byte string.
1092 * This is for special cases and by passes some of the pointer safety.
1093 *
1094 * The purpose of this is to output the bytes that make up a byte
1095 * string value directly to the QCBOR output buffer so you don't need
1096 * to have a copy of it in memory. This is particularly useful if the
1097 * byte string is large, for example, the encrypted payload of a
1098 * COSE_Encrypt message. The payload encryption algorithm can output
1099 * directly to the encoded CBOR buffer, perhaps by making it the
1100 * output buffer for some function (e.g. symmetric encryption) or by
1101 * multiple writes.
1102 *
1103 * The pointer in @c pPlace is where to start writing. Writing is just
1104 * copying bytes to the location by the pointer in \c pPlace. Writing
1105 * past the length in @c pPlace will be writing off the end of the
1106 * output buffer.
1107 *
1108 * If there is no room in the output buffer @ref NULLUsefulBuf will be
1109 * returned and there is no need to call QCBOREncode_CloseBytes().
1110 *
1111 * The byte string must be closed by calling QCBOREncode_CloseBytes().
1112 *
1113 * Warning: this bypasses some of the usual checks provided by QCBOR
1114 * against writing off the end of the encoded output buffer.
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001115 */
1116void
1117QCBOREncode_OpenBytes(QCBOREncodeContext *pCtx, UsefulBuf *pPlace);
1118
1119static void
Laurence Lundblade3eead482023-12-16 20:53:22 -07001120QCBOREncode_OpenBytesInMapSZ(QCBOREncodeContext *pCtx,
1121 const char *szLabel,
1122 UsefulBuf *pPlace);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001123
1124static void
Laurence Lundblade3eead482023-12-16 20:53:22 -07001125QCBOREncode_OpenBytesInMapN(QCBOREncodeContext *pCtx,
1126 int64_t nLabel,
1127 UsefulBuf *pPlace);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001128
1129
1130/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001131 * @brief Close out a byte string written directly to encoded output.
1132 *
1133 * @param[in] pCtx The encoding context to add the bytes to.
1134 * @param[out] uAmount The number of bytes written, the length of the
1135 * byte string.
1136 *
1137 * This closes out a call to QCBOREncode_OpenBytes(). This inserts a
1138 * CBOR header at the front of the byte string value to make it a
1139 * well-formed byte string.
1140 *
1141 * If there was no call to QCBOREncode_OpenBytes() then @ref
1142 * QCBOR_ERR_TOO_MANY_CLOSES is set.
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001143 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001144void
1145QCBOREncode_CloseBytes(QCBOREncodeContext *pCtx, size_t uAmount);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001146
1147
1148/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001149 * @brief Add a binary UUID to the encoded output.
1150 *
1151 * @param[in] pCtx The encoding context to add the UUID to.
1152 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1153 * @ref QCBOR_ENCODE_AS_BORROWED.
1154 * @param[in] Bytes Pointer and length of the binary UUID.
1155 *
1156 * A binary UUID as defined in [RFC 4122]
1157 * (https://tools.ietf.org/html/rfc4122) is added to the output.
1158 *
1159 * It is output as CBOR major type 2, a binary string, with tag @ref
1160 * CBOR_TAG_BIN_UUID indicating the binary string is a UUID.
Michael Eckel5c531332020-03-02 01:35:30 +01001161 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001162static void
1163QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pCtx,
1164 uint8_t uTagRequirement,
1165 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001166
Laurence Lundblade3eead482023-12-16 20:53:22 -07001167static void
1168QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pCtx,
1169 const char *szLabel,
1170 uint8_t uTagRequirement,
1171 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001172
Laurence Lundblade3eead482023-12-16 20:53:22 -07001173static void
1174QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pCtx,
1175 int64_t nLabel,
1176 uint8_t uTagRequirement,
1177 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001178
1179
Laurence Lundblade3eead482023-12-16 20:53:22 -07001180static void
1181QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001182
Laurence Lundblade3eead482023-12-16 20:53:22 -07001183static void
1184QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001185
Laurence Lundblade3eead482023-12-16 20:53:22 -07001186static void
1187QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001188
1189
1190/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001191 * @brief Add a positive big number to the encoded output.
1192 *
1193 * @param[in] pCtx The encoding context to add the big number to.
1194 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1195 * @ref QCBOR_ENCODE_AS_BORROWED.
1196 * @param[in] Bytes Pointer and length of the big number.
1197 *
1198 * Big numbers are integers larger than 64-bits. Their format is
1199 * described in [RFC 8949] (https://tools.ietf.org/html/rfc8949).
1200 *
1201 * It is output as CBOR major type 2, a binary string, with tag
1202 * @ref CBOR_TAG_POS_BIGNUM indicating the binary string is a positive
1203 * big number.
1204 *
1205 * Often big numbers are used to represent cryptographic keys,
1206 * however, COSE which defines representations for keys chose not to
1207 * use this particular type.
Michael Eckel5c531332020-03-02 01:35:30 +01001208 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001209static void
1210QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pCtx,
1211 uint8_t uTagRequirement,
1212 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001213
Laurence Lundblade3eead482023-12-16 20:53:22 -07001214static void
1215QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pCtx,
1216 const char *szLabel,
1217 uint8_t uTagRequirement,
1218 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001219
Laurence Lundblade3eead482023-12-16 20:53:22 -07001220static void
1221QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pCtx,
1222 int64_t nLabel,
1223 uint8_t uTagRequirement,
1224 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001225
1226
Laurence Lundblade3eead482023-12-16 20:53:22 -07001227static void
1228QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx,
1229 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001230
Laurence Lundblade3eead482023-12-16 20:53:22 -07001231static void
1232QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx,
1233 const char *szLabel,
1234 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001235
Laurence Lundblade3eead482023-12-16 20:53:22 -07001236static void
1237QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx,
1238 int64_t nLabel,
1239 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001240
1241
1242/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001243 * @brief Add a negative big number to the encoded output.
1244 *
1245 * @param[in] pCtx The encoding context to add the big number to.
1246 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1247 * @ref QCBOR_ENCODE_AS_BORROWED.
1248 * @param[in] Bytes Pointer and length of the big number.
1249 *
1250 * Big numbers are integers larger than 64-bits. Their format is
1251 * described in [RFC 8949] (https://tools.ietf.org/html/rfc8949).
1252 *
1253 * It is output as CBOR major type 2, a binary string, with tag
1254 * @ref CBOR_TAG_NEG_BIGNUM indicating the binary string is a negative
1255 * big number.
1256 *
1257 * Often big numbers are used to represent cryptographic keys,
1258 * however, COSE which defines representations for keys chose not to
1259 * use this particular type.
Michael Eckel5c531332020-03-02 01:35:30 +01001260 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001261static void
1262QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pCtx,
1263 uint8_t uTagRequirement,
1264 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001265
Laurence Lundblade3eead482023-12-16 20:53:22 -07001266static void
1267QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pCtx,
1268 const char *szLabel,
1269 uint8_t uTagRequirement,
1270 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001271
Laurence Lundblade3eead482023-12-16 20:53:22 -07001272static void
1273QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pCtx,
1274 int64_t nLabel,
1275 uint8_t uTagRequirement,
1276 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001277
1278
Laurence Lundblade3eead482023-12-16 20:53:22 -07001279static void
1280QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx,
1281 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001282
Laurence Lundblade3eead482023-12-16 20:53:22 -07001283static void
1284QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx,
1285 const char *szLabel,
1286 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001287
Laurence Lundblade3eead482023-12-16 20:53:22 -07001288static void
1289QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx,
1290 int64_t nLabel,
1291 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001292
1293
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07001294#ifndef QCBOR_DISABLE_EXP_AND_MANTISSA
Michael Eckel5c531332020-03-02 01:35:30 +01001295/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001296 * @brief Add a decimal fraction to the encoded output.
1297 *
1298 * @param[in] pCtx Encoding context to add the decimal fraction to.
1299 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1300 * @ref QCBOR_ENCODE_AS_BORROWED.
1301 * @param[in] nMantissa The mantissa.
1302 * @param[in] nBase10Exponent The exponent.
1303 *
1304 * The value is nMantissa * 10 ^ nBase10Exponent.
1305 *
1306 * A decimal fraction is good for exact representation of some values
1307 * that can't be represented exactly with standard C (IEEE 754)
1308 * floating-point numbers. Much larger and much smaller numbers can
1309 * also be represented than floating-point because of the larger
1310 * number of bits in the exponent.
1311 *
1312 * The decimal fraction is conveyed as two integers, a mantissa and a
1313 * base-10 scaling factor.
1314 *
1315 * For example, 273.15 is represented by the two integers 27315 and -2.
1316 *
1317 * The exponent and mantissa have the range from @c INT64_MIN to
1318 * @c INT64_MAX for both encoding and decoding (CBOR allows
1319 * @c -UINT64_MAX to @c UINT64_MAX, but this implementation doesn't
1320 * support this range to reduce code size and interface complexity a
1321 * little).
1322 *
1323 * CBOR Preferred serialization of the integers is used, thus they
1324 * will be encoded in the smallest number of bytes possible.
1325 *
1326 * See also QCBOREncode_AddDecimalFractionBigNum() for a decimal
1327 * fraction with arbitrarily large precision and
1328 * QCBOREncode_AddBigFloat().
1329 *
1330 * There is no representation of positive or negative infinity or NaN
1331 * (Not a Number). Use QCBOREncode_AddDouble() to encode them.
1332 *
1333 * See @ref expAndMantissa for decoded representation.
Michael Eckel5c531332020-03-02 01:35:30 +01001334 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001335static void
1336QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pCtx,
1337 uint8_t uTagRequirement,
1338 int64_t nMantissa,
1339 int64_t nBase10Exponent);
1340
1341static void
1342QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pCtx,
1343 const char *szLabel,
1344 uint8_t uTagRequirement,
1345 int64_t nMantissa,
1346 int64_t nBase10Exponent);
1347
1348static void
1349QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pCtx,
1350 int64_t nLabel,
1351 uint8_t uTagRequirement,
1352 int64_t nMantissa,
1353 int64_t nBase10Exponent);
1354
1355
1356static void
1357QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pCtx,
1358 int64_t nMantissa,
1359 int64_t nBase10Exponent);
1360
1361static void
1362QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pCtx,
1363 const char *szLabel,
1364 int64_t nMantissa,
1365 int64_t nBase10Exponent);
1366
1367static void
1368QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pCtx,
1369 int64_t nLabel,
1370 int64_t nMantissa,
1371 int64_t nBase10Exponent);
1372
1373
1374/**
1375 * @brief Add a decimal fraction with a big number mantissa to the encoded output.
1376 *
1377 * @param[in] pCtx Encoding context to add the decimal fraction to.
1378 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1379 * @ref QCBOR_ENCODE_AS_BORROWED.
1380 * @param[in] Mantissa The mantissa.
1381 * @param[in] bIsNegative false if mantissa is positive, true if negative.
1382 * @param[in] nBase10Exponent The exponent.
1383 *
1384 * This is the same as QCBOREncode_AddDecimalFraction() except the
1385 * mantissa is a big number (See QCBOREncode_AddPositiveBignum())
1386 * allowing for arbitrarily large precision.
1387 *
1388 * See @ref expAndMantissa for decoded representation.
1389 */
1390static void
1391QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pCtx,
1392 uint8_t uTagRequirement,
1393 UsefulBufC Mantissa,
1394 bool bIsNegative,
1395 int64_t nBase10Exponent);
1396
1397static void
1398QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
1399 const char *szLabel,
1400 uint8_t uTagRequirement,
1401 UsefulBufC Mantissa,
1402 bool bIsNegative,
1403 int64_t nBase10Exponent);
1404
1405static void
1406QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
1407 int64_t nLabel,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001408 uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07001409 UsefulBufC Mantissa,
1410 bool bIsNegative,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001411 int64_t nBase10Exponent);
1412
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001413
Laurence Lundblade3eead482023-12-16 20:53:22 -07001414static void
1415QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pCtx,
1416 UsefulBufC Mantissa,
1417 bool bIsNegative,
1418 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001419
Laurence Lundblade3eead482023-12-16 20:53:22 -07001420static void
1421QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001422 const char *szLabel,
Laurence Lundblade3eead482023-12-16 20:53:22 -07001423 UsefulBufC Mantissa,
1424 bool bIsNegative,
1425 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001426
Laurence Lundblade3eead482023-12-16 20:53:22 -07001427static void
1428QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001429 int64_t nLabel,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001430 UsefulBufC Mantissa,
1431 bool bIsNegative,
Laurence Lundblade3eead482023-12-16 20:53:22 -07001432 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001433
Laurence Lundblade3eead482023-12-16 20:53:22 -07001434/**
1435 * @brief Add a big floating-point number to the encoded output.
1436 *
1437 * @param[in] pCtx The encoding context to add the bigfloat to.
1438 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1439 * @ref QCBOR_ENCODE_AS_BORROWED.
1440 * @param[in] nMantissa The mantissa.
1441 * @param[in] nBase2Exponent The exponent.
1442 *
1443 * The value is nMantissa * 2 ^ nBase2Exponent.
1444 *
1445 * "Bigfloats", as CBOR terms them, are similar to IEEE floating-point
1446 * numbers in having a mantissa and base-2 exponent, but they are not
1447 * supported by hardware or encoded the same. They explicitly use two
1448 * CBOR-encoded integers to convey the mantissa and exponent, each of
1449 * which can be 8, 16, 32 or 64 bits. With both the mantissa and
1450 * exponent 64 bits they can express more precision and a larger range
1451 * than an IEEE double floating-point number. See
1452 * QCBOREncode_AddBigFloatBigNum() for even more precision.
1453 *
1454 * For example, 1.5 would be represented by a mantissa of 3 and an
1455 * exponent of -1.
1456 *
1457 * The exponent and mantissa have the range from @c INT64_MIN to
1458 * @c INT64_MAX for both encoding and decoding (CBOR allows @c
1459 * -UINT64_MAX to @c UINT64_MAX, but this implementation doesn't
1460 * support this range to reduce code size and interface complexity a
1461 * little).
1462 *
1463 * CBOR preferred serialization of the integers is used, thus they will
1464 * be encoded in the smallest number of bytes possible.
1465 *
1466 * This can also be used to represent floating-point numbers in
1467 * environments that don't support IEEE 754.
1468 *
1469 * See @ref expAndMantissa for decoded representation.
1470 */
1471static void
1472QCBOREncode_AddTBigFloat(QCBOREncodeContext *pCtx,
1473 uint8_t uTagRequirement,
1474 int64_t nMantissa,
1475 int64_t nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001476
Laurence Lundblade3eead482023-12-16 20:53:22 -07001477static void
1478QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pCtx,
1479 const char *szLabel,
1480 uint8_t uTagRequirement,
1481 int64_t nMantissa,
1482 int64_t nBase2Exponent);
1483
1484static void
1485QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pCtx,
1486 int64_t nLabel,
1487 uint8_t uTagRequirement,
1488 int64_t nMantissa,
1489 int64_t nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001490
1491
Laurence Lundblade3eead482023-12-16 20:53:22 -07001492static void
1493QCBOREncode_AddBigFloat(QCBOREncodeContext *pCtx,
1494 int64_t nMantissa,
1495 int64_t nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01001496
Laurence Lundblade3eead482023-12-16 20:53:22 -07001497static void
1498QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pCtx,
1499 const char *szLabel,
1500 int64_t nMantissa,
1501 int64_t nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01001502
Laurence Lundblade3eead482023-12-16 20:53:22 -07001503static void
1504QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pCtx,
1505 int64_t nLabel,
1506 int64_t nMantissa,
1507 int64_t nBase2Exponent);
1508
1509/**
1510 * @brief Add a big floating-point number with a big number mantissa to
1511 * the encoded output.
1512 *
1513 * @param[in] pCtx The encoding context to add the bigfloat to.
1514 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1515 * @ref QCBOR_ENCODE_AS_BORROWED.
1516 * @param[in] Mantissa The mantissa.
1517 * @param[in] bIsNegative false if mantissa is positive, true if negative.
1518 * @param[in] nBase2Exponent The exponent.
1519 *
1520 * This is the same as QCBOREncode_AddBigFloat() except the mantissa
1521 * is a big number (See QCBOREncode_AddPositiveBignum()) allowing for
1522 * arbitrary precision.
1523 *
1524 * See @ref expAndMantissa for decoded representation.
1525 */
1526static void
1527QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pCtx,
1528 uint8_t uTagRequirement,
1529 UsefulBufC Mantissa,
1530 bool bIsNegative,
1531 int64_t nBase2Exponent);
1532
1533static void
1534QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pCtx,
1535 const char *szLabel,
1536 uint8_t uTagRequirement,
1537 UsefulBufC Mantissa,
1538 bool bIsNegative,
1539 int64_t nBase2Exponent);
1540
1541static void
1542QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1543 int64_t nLabel,
1544 uint8_t uTagRequirement,
1545 UsefulBufC Mantissa,
1546 bool bIsNegative,
1547 int64_t nBase2Exponent);
1548
1549
1550static void
1551QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pCtx,
1552 UsefulBufC Mantissa,
1553 bool bIsNegative,
1554 int64_t nBase2Exponent);
1555
1556static void
1557QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pCtx,
1558 const char *szLabel,
1559 UsefulBufC Mantissa,
1560 bool bIsNegative,
1561 int64_t nBase2Exponent);
1562
1563static void
1564QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1565 int64_t nLabel,
1566 UsefulBufC Mantissa,
1567 bool bIsNegative,
1568 int64_t nBase2Exponent);
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07001569#endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
Michael Eckel5c531332020-03-02 01:35:30 +01001570
1571
1572/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001573 * @brief Add a text URI to the encoded output.
1574 *
1575 * @param[in] pCtx The encoding context to add the URI to.
1576 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1577 * @ref QCBOR_ENCODE_AS_BORROWED.
1578 * @param[in] URI Pointer and length of the URI.
1579 *
1580 * The format of URI must be per [RFC 3986]
1581 * (https://tools.ietf.org/html/rfc3986).
1582 *
1583 * It is output as CBOR major type 3, a text string, with tag @ref
1584 * CBOR_TAG_URI indicating the text string is a URI.
1585 *
1586 * A URI in a NULL-terminated string, @c szURI, can be easily added with
1587 * this code:
1588 *
1589 * QCBOREncode_AddURI(pCtx, UsefulBuf_FromSZ(szURI));
Michael Eckel5c531332020-03-02 01:35:30 +01001590 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001591static void
1592QCBOREncode_AddTURI(QCBOREncodeContext *pCtx,
1593 uint8_t uTagRequirement,
1594 UsefulBufC URI);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001595
Laurence Lundblade3eead482023-12-16 20:53:22 -07001596static void
1597QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pCtx,
1598 const char *szLabel,
1599 uint8_t uTagRequirement,
1600 UsefulBufC URI);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001601
Laurence Lundblade3eead482023-12-16 20:53:22 -07001602static void
1603QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pCtx,
1604 int64_t nLabel,
1605 uint8_t uTagRequirement,
1606 UsefulBufC URI);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001607
1608
Laurence Lundblade3eead482023-12-16 20:53:22 -07001609static void
1610QCBOREncode_AddURI(QCBOREncodeContext *pCtx,
1611 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001612
Laurence Lundblade3eead482023-12-16 20:53:22 -07001613static void
1614QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx,
1615 const char *szLabel,
1616 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001617
Laurence Lundblade3eead482023-12-16 20:53:22 -07001618static void
1619QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx,
1620 int64_t nLabel,
1621 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001622
1623
1624/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001625 * @brief Add Base64-encoded text to encoded output.
1626 *
1627 * @param[in] pCtx The encoding context to add the base-64 text to.
1628 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1629 * @ref QCBOR_ENCODE_AS_BORROWED.
1630 * @param[in] B64Text Pointer and length of the base-64 encoded text.
1631 *
1632 * The text content is Base64 encoded data per [RFC 4648]
1633 * (https://tools.ietf.org/html/rfc4648).
1634 *
1635 * It is output as CBOR major type 3, a text string, with tag @ref
1636 * CBOR_TAG_B64 indicating the text string is Base64 encoded.
Michael Eckel5c531332020-03-02 01:35:30 +01001637 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001638static void
1639QCBOREncode_AddTB64Text(QCBOREncodeContext *pCtx,
1640 uint8_t uTagRequirement,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001641 UsefulBufC B64Text);
1642
Laurence Lundblade3eead482023-12-16 20:53:22 -07001643static void
1644QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pCtx,
1645 const char *szLabel,
1646 uint8_t uTagRequirement,
1647 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001648
Laurence Lundblade3eead482023-12-16 20:53:22 -07001649static void
1650QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pCtx,
1651 int64_t nLabel,
1652 uint8_t uTagRequirement,
1653 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001654
1655
Laurence Lundblade3eead482023-12-16 20:53:22 -07001656static void
1657QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx,
1658 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001659
Laurence Lundblade3eead482023-12-16 20:53:22 -07001660static void
1661QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx,
1662 const char *szLabel,
1663 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001664
Laurence Lundblade3eead482023-12-16 20:53:22 -07001665static void
1666QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx,
1667 int64_t nLabel,
1668 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001669
1670
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001671
Michael Eckel5c531332020-03-02 01:35:30 +01001672/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001673 * @brief Add base64url encoded data to encoded output.
1674 *
1675 * @param[in] pCtx The encoding context to add the base64url to.
1676 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1677 * @ref QCBOR_ENCODE_AS_BORROWED.
1678 * @param[in] B64Text Pointer and length of the base64url encoded text.
1679 *
1680 * The text content is base64URL encoded text as per [RFC 4648]
1681 * (https://tools.ietf.org/html/rfc4648).
1682 *
1683 * It is output as CBOR major type 3, a text string, with tag
1684 * @ref CBOR_TAG_B64URL indicating the text string is a Base64url
1685 * encoded.
Michael Eckel5c531332020-03-02 01:35:30 +01001686 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001687static void
1688QCBOREncode_AddTB64URLText(QCBOREncodeContext *pCtx,
1689 uint8_t uTagRequirement,
1690 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001691
Laurence Lundblade3eead482023-12-16 20:53:22 -07001692static void
1693QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pCtx,
1694 const char *szLabel,
1695 uint8_t uTagRequirement,
1696 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001697
Laurence Lundblade3eead482023-12-16 20:53:22 -07001698static void
1699QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pCtx,
1700 int64_t nLabel,
1701 uint8_t uTagRequirement,
1702 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001703
1704
Laurence Lundblade3eead482023-12-16 20:53:22 -07001705static void
1706QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx,
1707 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001708
Laurence Lundblade3eead482023-12-16 20:53:22 -07001709static void
1710QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx,
1711 const char *szLabel,
1712 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001713
Laurence Lundblade3eead482023-12-16 20:53:22 -07001714static void
1715QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx,
1716 int64_t nLabel,
1717 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001718
1719
1720/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001721 * @brief Add Perl Compatible Regular Expression.
1722 *
1723 * @param[in] pCtx Encoding context to add the regular expression to.
1724 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1725 * @ref QCBOR_ENCODE_AS_BORROWED.
1726 * @param[in] Regex Pointer and length of the regular expression.
1727 *
1728 * The text content is Perl Compatible Regular
1729 * Expressions (PCRE) / JavaScript syntax [ECMA262].
1730 *
1731 * It is output as CBOR major type 3, a text string, with tag @ref
1732 * CBOR_TAG_REGEX indicating the text string is a regular expression.
Michael Eckel5c531332020-03-02 01:35:30 +01001733 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001734static void
1735QCBOREncode_AddTRegex(QCBOREncodeContext *pCtx,
1736 uint8_t uTagRequirement,
1737 UsefulBufC Regex);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001738
Laurence Lundblade3eead482023-12-16 20:53:22 -07001739static void
1740QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pCtx,
1741 const char *szLabel,
1742 uint8_t uTagRequirement,
1743 UsefulBufC Regex);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001744
Laurence Lundblade3eead482023-12-16 20:53:22 -07001745static void
1746QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pCtx,
1747 int64_t nLabel,
1748 uint8_t uTagRequirement,
1749 UsefulBufC Regex);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001750
1751
Laurence Lundblade3eead482023-12-16 20:53:22 -07001752static void
1753QCBOREncode_AddRegex(QCBOREncodeContext *pCtx,
1754 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001755
Laurence Lundblade3eead482023-12-16 20:53:22 -07001756static void
1757QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx,
1758 const char *szLabel,
1759 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001760
Laurence Lundblade3eead482023-12-16 20:53:22 -07001761static void
1762QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx,
1763 int64_t nLabel,
1764 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001765
1766
1767/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001768 * @brief MIME encoded data to the encoded output.
1769 *
1770 * @param[in] pCtx The encoding context to add the MIME data to.
1771 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1772 * @ref QCBOR_ENCODE_AS_BORROWED.
1773 * @param[in] MIMEData Pointer and length of the MIME data.
1774 *
1775 * The text content is in MIME format per [RFC 2045]
1776 * (https://tools.ietf.org/html/rfc2045) including the headers.
1777 *
1778 * It is output as CBOR major type 2, a binary string, with tag
1779 * @ref CBOR_TAG_BINARY_MIME indicating the string is MIME data. This
1780 * outputs tag 257, not tag 36, as it can carry any type of MIME
1781 * binary, 7-bit, 8-bit, quoted-printable and base64 where tag 36
1782 * cannot.
1783 *
1784 * Previous versions of QCBOR, those before spiffy decode, output tag
1785 * 36. Decoding supports both tag 36 and 257. (if the old behavior
1786 * with tag 36 is needed, copy the inline functions below and change
1787 * the tag number).
1788 *
1789 * See also QCBORDecode_GetMIMEMessage() and
1790 * @ref QCBOR_TYPE_BINARY_MIME.
1791 *
1792 * This does no translation of line endings. See QCBOREncode_AddText()
1793 * for a discussion of line endings in CBOR.
Michael Eckel5c531332020-03-02 01:35:30 +01001794 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001795static void
1796QCBOREncode_AddTMIMEData(QCBOREncodeContext *pCtx,
1797 uint8_t uTagRequirement,
1798 UsefulBufC MIMEData);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001799
Laurence Lundblade3eead482023-12-16 20:53:22 -07001800static void
1801QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pCtx,
1802 const char *szLabel,
1803 uint8_t uTagRequirement,
1804 UsefulBufC MIMEData);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001805
Laurence Lundblade3eead482023-12-16 20:53:22 -07001806static void
1807QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pCtx,
1808 int64_t nLabel,
1809 uint8_t uTagRequirement,
1810 UsefulBufC MIMEData);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001811
1812
Laurence Lundblade3eead482023-12-16 20:53:22 -07001813static void
1814QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx,
1815 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001816
Laurence Lundblade3eead482023-12-16 20:53:22 -07001817static void
1818QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx,
1819 const char *szLabel,
1820 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001821
Laurence Lundblade3eead482023-12-16 20:53:22 -07001822static void
1823QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx,
1824 int64_t nLabel,
1825 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001826
1827
1828/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001829 * @brief Add an RFC 3339 date string
1830 *
1831 * @param[in] pCtx The encoding context to add the date to.
1832 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1833 * @ref QCBOR_ENCODE_AS_BORROWED.
1834 * @param[in] szDate Null-terminated string with date to add.
1835 *
1836 * The string szDate should be in the form of [RFC 3339]
1837 * (https://tools.ietf.org/html/rfc3339) as defined by section 3.3 in
1838 * [RFC 4287] (https://tools.ietf.org/html/rfc4287). This is as
1839 * described in section 3.4.1 in [RFC 8949]
1840 * (https://tools.ietf.org/html/rfc8949).
1841 *
1842 * Note that this function doesn't validate the format of the date
1843 * string at all. If you add an incorrect format date string, the
1844 * generated CBOR will be incorrect and the receiver may not be able
1845 * to handle it.
1846 *
1847 * Error handling is the same as QCBOREncode_AddInt64().
1848 *
1849 * See also QCBOREncode_AddTDayString().
Michael Eckel5c531332020-03-02 01:35:30 +01001850 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001851static void
1852QCBOREncode_AddTDateString(QCBOREncodeContext *pCtx,
1853 uint8_t uTagRequirement,
1854 const char *szDate);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001855
Laurence Lundblade3eead482023-12-16 20:53:22 -07001856static void
1857QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pCtx,
1858 const char *szLabel,
1859 uint8_t uTagRequirement,
1860 const char *szDate);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001861
Laurence Lundblade3eead482023-12-16 20:53:22 -07001862static void
1863QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pCtx,
1864 int64_t nLabel,
1865 uint8_t uTagRequirement,
1866 const char *szDate);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001867
1868
Laurence Lundblade3eead482023-12-16 20:53:22 -07001869static void
1870QCBOREncode_AddDateString(QCBOREncodeContext *pCtx,
1871 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001872
Laurence Lundblade3eead482023-12-16 20:53:22 -07001873static void
1874QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx,
1875 const char *szLabel,
1876 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001877
Laurence Lundblade3eead482023-12-16 20:53:22 -07001878static void
1879QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx,
1880 int64_t nLabel,
1881 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001882
Laurence Lundblade46d63e92021-05-13 11:37:10 -07001883
1884/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001885 * @brief Add a date-only string.
1886 *
1887 * @param[in] pCtx The encoding context to add the date to.
1888 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1889 * @ref QCBOR_ENCODE_AS_BORROWED.
1890 * @param[in] szDate Null-terminated string with date to add.
1891 *
1892 * This date format is described in
1893 * [RFC 8943] (https://tools.ietf.org/html/rfc8943), but that mainly
1894 * references RFC 3339. The string szDate must be in the forrm
1895 * specified the ABNF for a full-date in
1896 * [RFC 3339] (https://tools.ietf.org/html/rfc3339). Examples of this
1897 * are "1985-04-12" and "1937-01-01". The time and the time zone are
1898 * never included.
1899 *
1900 * Note that this function doesn't validate the format of the date
1901 * string at all. If you add an incorrect format date string, the
1902 * generated CBOR will be incorrect and the receiver may not be able
1903 * to handle it.
1904 *
1905 * Error handling is the same as QCBOREncode_AddInt64().
1906 *
1907 * See also QCBOREncode_AddTDateString().
Laurence Lundblade46d63e92021-05-13 11:37:10 -07001908 */
1909static void
1910QCBOREncode_AddTDaysString(QCBOREncodeContext *pCtx,
1911 uint8_t uTagRequirement,
1912 const char *szDate);
1913
1914static void
1915QCBOREncode_AddTDaysStringToMapSZ(QCBOREncodeContext *pCtx,
1916 const char *szLabel,
1917 uint8_t uTagRequirement,
1918 const char *szDate);
1919
1920static void
1921QCBOREncode_AddTDaysStringToMapN(QCBOREncodeContext *pCtx,
1922 int64_t nLabel,
1923 uint8_t uTagRequirement,
1924 const char *szDate);
1925
1926
Michael Eckel5c531332020-03-02 01:35:30 +01001927/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001928 * @brief Add a standard Boolean.
1929 *
1930 * @param[in] pCtx The encoding context to add the Boolean to.
1931 * @param[in] b true or false from @c <stdbool.h>.
1932 *
1933 * Adds a Boolean value as CBOR major type 7.
1934 *
1935 * Error handling is the same as QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +01001936 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001937static void
1938QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b);
Michael Eckel5c531332020-03-02 01:35:30 +01001939
Laurence Lundblade3eead482023-12-16 20:53:22 -07001940static void
1941QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b);
Michael Eckel5c531332020-03-02 01:35:30 +01001942
Laurence Lundblade3eead482023-12-16 20:53:22 -07001943static void
1944QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b);
Michael Eckel5c531332020-03-02 01:35:30 +01001945
1946
1947
1948/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001949 * @brief Add a NULL to the encoded output.
1950 *
1951 * @param[in] pCtx The encoding context to add the NULL to.
1952 *
1953 * Adds the NULL value as CBOR major type 7.
1954 *
1955 * This NULL doesn't have any special meaning in CBOR such as a
1956 * terminating value for a string or an empty value.
1957 *
1958 * Error handling is the same as QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +01001959 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001960static void
1961QCBOREncode_AddNULL(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01001962
Laurence Lundblade3eead482023-12-16 20:53:22 -07001963static void
1964QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001965
Laurence Lundblade3eead482023-12-16 20:53:22 -07001966static void
1967QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001968
1969
1970/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001971 * @brief Add an "undef" to the encoded output.
1972 *
1973 * @param[in] pCtx The encoding context to add the "undef" to.
1974 *
1975 * Adds the undef value as CBOR major type 7.
1976 *
1977 * Note that this value will not translate to JSON.
1978 *
1979 * This Undef doesn't have any special meaning in CBOR such as a
1980 * terminating value for a string or an empty value.
1981 *
1982 * Error handling is the same as QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +01001983 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001984static void
1985QCBOREncode_AddUndef(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01001986
Laurence Lundblade3eead482023-12-16 20:53:22 -07001987static void
1988QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001989
Laurence Lundblade3eead482023-12-16 20:53:22 -07001990static void
1991QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001992
1993
1994/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001995 * @brief Indicates that the next items added are in an array.
1996 *
1997 * @param[in] pCtx The encoding context to open the array in.
1998 *
1999 * Arrays are the basic CBOR aggregate or structure type. Call this
2000 * function to start or open an array. Then call the various
2001 * @c QCBOREncode_AddXxx() functions to add the items that go into the
2002 * array. Then call QCBOREncode_CloseArray() when all items have been
2003 * added. The data items in the array can be of any type and can be of
2004 * mixed types.
2005 *
2006 * Nesting of arrays and maps is allowed and supported just by calling
2007 * QCBOREncode_OpenArray() again before calling
2008 * QCBOREncode_CloseArray(). While CBOR has no limit on nesting, this
2009 * implementation does in order to keep it smaller and simpler. The
2010 * limit is @ref QCBOR_MAX_ARRAY_NESTING. This is the max number of
2011 * times this can be called without calling
2012 * QCBOREncode_CloseArray(). QCBOREncode_Finish() will return
2013 * @ref QCBOR_ERR_ARRAY_NESTING_TOO_DEEP when it is called as this
2014 * function just sets an error state and returns no value when this
2015 * occurs.
2016 *
2017 * If you try to add more than @ref QCBOR_MAX_ITEMS_IN_ARRAY items to
2018 * a single array or map, @ref QCBOR_ERR_ARRAY_TOO_LONG will be
2019 * returned when QCBOREncode_Finish() is called.
2020 *
2021 * An array itself must have a label if it is being added to a map.
2022 * Note that array elements do not have labels (but map elements do).
2023 *
2024 * An array itself may be tagged by calling QCBOREncode_AddTag()
2025 * before this call.
Michael Eckel5c531332020-03-02 01:35:30 +01002026 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002027static void
2028QCBOREncode_OpenArray(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01002029
Laurence Lundblade3eead482023-12-16 20:53:22 -07002030static void
2031QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01002032
Laurence Lundblade3eead482023-12-16 20:53:22 -07002033static void
2034QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01002035
2036
2037/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002038 * @brief Close an open array.
2039 *
2040 * @param[in] pCtx The encoding context to close the array in.
2041 *
2042 * The closes an array opened by QCBOREncode_OpenArray(). It reduces
2043 * nesting level by one. All arrays (and maps) must be closed before
2044 * calling QCBOREncode_Finish().
2045 *
2046 * When an error occurs as a result of this call, the encoder records
2047 * the error and enters the error state. The error will be returned
2048 * when QCBOREncode_Finish() is called.
2049 *
2050 * If this has been called more times than QCBOREncode_OpenArray(), then
2051 * @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when QCBOREncode_Finish()
2052 * is called.
2053 *
2054 * If this is called and it is not an array that is currently open,
2055 * @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
2056 * QCBOREncode_Finish() is called.
Michael Eckel5c531332020-03-02 01:35:30 +01002057 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002058static void
2059QCBOREncode_CloseArray(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01002060
2061
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07002062
2063
Michael Eckel5c531332020-03-02 01:35:30 +01002064/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002065 * @brief Indicates that the next items added are in a map.
2066 *
2067 * @param[in] pCtx The encoding context to open the map in.
2068 *
2069 * See QCBOREncode_OpenArray() for more information, particularly
2070 * error handling.
2071 *
2072 * CBOR maps are an aggregate type where each item in the map consists
2073 * of a label and a value. They are similar to JSON objects.
2074 *
2075 * The value can be any CBOR type including another map.
2076 *
2077 * The label can also be any CBOR type, but in practice they are
2078 * typically, integers as this gives the most compact output. They
2079 * might also be text strings which gives readability and translation
2080 * to JSON.
2081 *
2082 * Every @c QCBOREncode_AddXxx() call has one version that ends with
2083 * @c InMap for adding items to maps with string labels and one that
2084 * ends with @c InMapN that is for adding with integer labels.
2085 *
2086 * RFC 8949 uses the term "key" instead of "label".
2087 *
2088 * If you wish to use map labels that are neither integer labels nor
2089 * text strings, then just call the QCBOREncode_AddXxx() function
2090 * explicitly to add the label. Then call it again to add the value.
2091 *
2092 * See the [RFC 8949] (https://tools.ietf.org/html/rfc8949) for a lot
2093 * more information on creating maps.
Michael Eckel5c531332020-03-02 01:35:30 +01002094 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002095static void
2096QCBOREncode_OpenMap(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01002097
Laurence Lundblade3eead482023-12-16 20:53:22 -07002098static void
2099QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01002100
Laurence Lundblade3eead482023-12-16 20:53:22 -07002101static void
2102QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01002103
2104
Michael Eckel5c531332020-03-02 01:35:30 +01002105/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002106 * @brief Close an open map.
2107 *
2108 * @param[in] pCtx The encoding context to close the map in.
2109 *
2110 * This closes a map opened by QCBOREncode_OpenMap(). It reduces
2111 * nesting level by one.
2112 *
2113 * When an error occurs as a result of this call, the encoder records
2114 * the error and enters the error state. The error will be returned
2115 * when QCBOREncode_Finish() is called.
2116 *
2117 * If this has been called more times than QCBOREncode_OpenMap(), then
2118 * @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
2119 * QCBOREncode_Finish() is called.
2120 *
2121 * If this is called and it is not a map that is currently open,
2122 * @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
2123 * QCBOREncode_Finish() is called.
Michael Eckel5c531332020-03-02 01:35:30 +01002124 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002125static void
2126QCBOREncode_CloseMap(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01002127
2128
2129/**
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07002130 * @brief Indicates that the next items added are in an indefinite length array.
2131 *
2132 * @param[in] pCtx The encoding context to open the array in.
2133 *
2134 * This is the same as QCBOREncode_OpenArray() except the array is
2135 * indefinite length.
2136 *
2137 * This must be closed with QCBOREncode_CloseArrayIndefiniteLength().
2138 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002139static void
2140QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pCtx);
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07002141
Laurence Lundblade3eead482023-12-16 20:53:22 -07002142static void
2143QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pCtx,
2144 const char *szLabel);
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07002145
2146static void
2147QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pCtx,
2148 int64_t nLabel);
2149
2150
2151/**
2152 * @brief Close an open indefinite length array.
2153 *
2154 * @param[in] pCtx The encoding context to close the array in.
2155 *
2156 * This is the same as QCBOREncode_CloseArray(), but the open array
2157 * that is being close must be of indefinite length.
2158 */
2159static void
2160QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pCtx);
2161
2162
2163/**
2164 * @brief Indicates that the next items added are in an indefinite length map.
2165 *
2166 * @param[in] pCtx The encoding context to open the map in.
2167 *
2168 * This is the same as QCBOREncode_OpenMap() except the array is
2169 * indefinite length.
2170 *
2171 * This must be closed with QCBOREncode_CloseMapIndefiniteLength().
2172 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002173static void
2174QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pCtx);
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07002175
Laurence Lundblade3eead482023-12-16 20:53:22 -07002176static void
2177QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pCtx,
2178 const char *szLabel);
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07002179
2180static void
2181QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pCtx,
2182 int64_t nLabel);
2183
2184
2185/**
2186 * @brief Close an open indefinite length map.
2187 *
2188 * @param[in] pCtx The encoding context to close the map in.
2189 *
2190 * This is the same as QCBOREncode_CloseMap(), but the open map that
2191 * is being close must be of indefinite length.
2192 */
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07002193static void
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07002194QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pCtx);
2195
2196
Laurence Lundbladec92e4162023-11-27 21:51:26 -07002197/**
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -08002198 * @brief Close and sort an open map.
Laurence Lundbladed6e13022023-11-26 10:14:02 -07002199 *
2200 * @param[in] pCtx The encoding context to close the map in .
2201 *
2202 * This is the same as QCBOREncode_CloseMap() except it sorts the map
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07002203 * per RFC 8949 Section 4.2.1 and checks for duplicate map keys. This
2204 * sort is lexicographic of the CBOR-encoded map labels.
Laurence Lundbladed6e13022023-11-26 10:14:02 -07002205 *
2206 * This is more expensive than most things in the encoder. It uses
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07002207 * bubble sort which runs in n-squared time where @c n is the number
2208 * of map items. Sorting large maps on slow CPUs might be slow. This
2209 * is also increases the object code size of the encoder by about 30%
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -08002210 * (500-1000 bytes).
Laurence Lundbladed6e13022023-11-26 10:14:02 -07002211 *
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07002212 * Bubble sort was selected so as to not need require configuration of
2213 * a buffer to track map item offsets. Bubble sort works well even
2214 * though map items are not all the same size because it always swaps
2215 * adjacent items.
Laurence Lundbladed6e13022023-11-26 10:14:02 -07002216 */
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07002217void
2218QCBOREncode_CloseAndSortMap(QCBOREncodeContext *pCtx);
Laurence Lundbladed6e13022023-11-26 10:14:02 -07002219
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07002220void
2221QCBOREncode_CloseAndSortMapIndef(QCBOREncodeContext *pCtx);
Laurence Lundbladed6e13022023-11-26 10:14:02 -07002222
2223
2224/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002225 * @brief Indicate start of encoded CBOR to be wrapped in a bstr.
2226 *
2227 * @param[in] pCtx The encoding context to open the bstr-wrapped CBOR in.
2228 *
2229 * All added encoded items between this call and a call to
2230 * QCBOREncode_CloseBstrWrap2() will be wrapped in a bstr. They will
2231 * appear in the final output as a byte string. That byte string will
2232 * contain encoded CBOR. This increases nesting level by one.
2233 *
2234 * The typical use case is for encoded CBOR that is to be
2235 * cryptographically hashed, as part of a [RFC 8152, COSE]
2236 * (https://tools.ietf.org/html/rfc8152) implementation. The wrapping
2237 * byte string is taken as input by the hash function (which is why it
2238 * is returned by QCBOREncode_CloseBstrWrap2()). It is also easy to
2239 * recover on decoding with standard CBOR decoders.
2240 *
2241 * Using QCBOREncode_BstrWrap() and QCBOREncode_CloseBstrWrap2()
2242 * avoids having to encode the items first in one buffer (e.g., the
2243 * COSE payload) and then add that buffer as a bstr to another
2244 * encoding (e.g. the COSE to-be-signed bytes, the @c Sig_structure)
2245 * potentially halving the memory needed.
2246 *
2247 * CBOR by nature must be decoded item by item in order from the
2248 * start. By wrapping some CBOR in a byte string, the decoding of
2249 * that wrapped CBOR can be skipped. This is another use of wrapping,
2250 * perhaps because the CBOR is large and deeply nested. Perhaps APIs
2251 * for handling one defined CBOR message that is being embedded in
2252 * another only take input as a byte string. Perhaps the desire is to
2253 * be able to decode the out layer even in the wrapped has errors.
Michael Eckel5c531332020-03-02 01:35:30 +01002254 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002255static void
2256QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01002257
Laurence Lundblade3eead482023-12-16 20:53:22 -07002258static void
2259QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01002260
Laurence Lundblade3eead482023-12-16 20:53:22 -07002261static void
2262QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01002263
2264
2265/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002266 * @brief Close a wrapping bstr.
2267 *
2268 * @param[in] pCtx The encoding context to close of bstr wrapping in.
2269 * @param[in] bIncludeCBORHead Include the encoded CBOR head of the bstr
2270 * as well as the bytes in @c pWrappedCBOR.
2271 * @param[out] pWrappedCBOR A @ref UsefulBufC containing wrapped bytes.
2272 *
2273 * The closes a wrapping bstr opened by QCBOREncode_BstrWrap(). It reduces
2274 * nesting level by one.
2275 *
2276 * A pointer and length of the enclosed encoded CBOR is returned in @c
2277 * *pWrappedCBOR if it is not @c NULL. The main purpose of this is so
2278 * this data can be hashed (e.g., with SHA-256) as part of a [RFC
2279 * 8152, COSE] (https://tools.ietf.org/html/rfc8152)
2280 * implementation. **WARNING**, this pointer and length should be used
2281 * right away before any other calls to @c QCBOREncode_CloseXxx() as
2282 * they will move data around and the pointer and length will no
2283 * longer be to the correct encoded CBOR.
2284 *
2285 * When an error occurs as a result of this call, the encoder records
2286 * the error and enters the error state. The error will be returned
2287 * when QCBOREncode_Finish() is called.
2288 *
2289 * If this has been called more times than QCBOREncode_BstrWrap(),
2290 * then @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
2291 * QCBOREncode_Finish() is called.
2292 *
2293 * If this is called and it is not a wrapping bstr that is currently
2294 * open, @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
2295 * QCBOREncode_Finish() is called.
2296 *
2297 * QCBOREncode_CloseBstrWrap() is a deprecated version of this function
2298 * that is equivalent to the call with @c bIncludeCBORHead @c true.
Michael Eckel5c531332020-03-02 01:35:30 +01002299 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002300void
2301QCBOREncode_CloseBstrWrap2(QCBOREncodeContext *pCtx, bool bIncludeCBORHead, UsefulBufC *pWrappedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01002302
Laurence Lundblade3eead482023-12-16 20:53:22 -07002303static void
2304QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01002305
2306
2307/**
Laurence Lundblade8d3b8552021-06-10 11:11:54 -07002308 * @brief Cancel byte string wrapping.
2309 *
2310 * @param[in] pCtx The encoding context.
2311 *
2312 * This cancels QCBOREncode_BstrWrap() making tghe encoding as if it
2313 * were never called.
2314 *
2315 * WARNING: This does not work on QCBOREncode_BstrWrapInMap()
2316 * or QCBOREncode_BstrWrapInMapN() and there is no error detection
2317 * of an attempt at their use.
2318 *
2319 * This only works if nothing has been added into the wrapped byte
2320 * string. If something has been added, this sets the error
2321 * @ref QCBOR_ERR_CANNOT_CANCEL.
2322 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002323void
2324QCBOREncode_CancelBstrWrap(QCBOREncodeContext *pCtx);
Laurence Lundblade8d3b8552021-06-10 11:11:54 -07002325
2326
2327/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002328 * @brief Add some already-encoded CBOR bytes.
2329 *
2330 * @param[in] pCtx The encoding context to add the already-encode CBOR to.
2331 * @param[in] Encoded The already-encoded CBOR to add to the context.
2332 *
2333 * The encoded CBOR being added must be fully conforming CBOR. It must
2334 * be complete with no arrays or maps that are incomplete. While this
2335 * encoder doesn't ever produce indefinite lengths, it is OK for the
2336 * raw CBOR added here to have indefinite lengths.
2337 *
2338 * The raw CBOR added here is not checked in anyway. If it is not
2339 * conforming or has open arrays or such, the final encoded CBOR
2340 * will probably be wrong or not what was intended.
2341 *
2342 * If the encoded CBOR being added here contains multiple items, they
2343 * must be enclosed in a map or array. At the top level the raw
2344 * CBOR must be a single data item.
Michael Eckel5c531332020-03-02 01:35:30 +01002345 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002346static void
2347QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01002348
Laurence Lundblade3eead482023-12-16 20:53:22 -07002349static void
2350QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01002351
Laurence Lundblade3eead482023-12-16 20:53:22 -07002352static void
2353QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01002354
2355
2356/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002357 * @brief Get the encoded result.
2358 *
2359 * @param[in] pCtx The context to finish encoding with.
2360 * @param[out] pEncodedCBOR Structure in which the pointer and length of
2361 * the encoded CBOR is returned.
2362 *
2363 * @retval QCBOR_SUCCESS Encoded CBOR is returned.
2364 *
2365 * @retval QCBOR_ERR_TOO_MANY_CLOSES Nesting error
2366 *
2367 * @retval QCBOR_ERR_CLOSE_MISMATCH Nesting error
2368 *
2369 * @retval QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN Nesting error
2370 *
2371 * @retval QCBOR_ERR_BUFFER_TOO_LARGE Encoded output buffer size
2372 *
2373 * @retval QCBOR_ERR_BUFFER_TOO_SMALL Encoded output buffer size
2374 *
2375 * @retval QCBOR_ERR_ARRAY_NESTING_TOO_DEEP Implementation limit
2376 *
2377 * @retval QCBOR_ERR_ARRAY_TOO_LONG Implementation limit
2378 *
2379 * On success, the pointer and length of the encoded CBOR are returned
2380 * in @c *pEncodedCBOR. The pointer is the same pointer that was passed
2381 * in to QCBOREncode_Init(). Note that it is not const when passed to
2382 * QCBOREncode_Init(), but it is const when returned here. The length
2383 * will be smaller than or equal to the length passed in when
2384 * QCBOREncode_Init() as this is the length of the actual result, not
2385 * the size of the buffer it was written to.
2386 *
2387 * If a @c NULL was passed for @c Storage.ptr when QCBOREncode_Init()
2388 * was called, @c NULL will be returned here, but the length will be
2389 * that of the CBOR that would have been encoded.
2390 *
2391 * Encoding errors primarily manifest here as most other encoding function
2392 * do no return an error. They just set the error state in the encode
2393 * context after which no encoding function does anything.
2394 *
2395 * Three types of errors manifest here. The first type are nesting
2396 * errors where the number of @c QCBOREncode_OpenXxx() calls do not
2397 * match the number @c QCBOREncode_CloseXxx() calls. The solution is to
2398 * fix the calling code.
2399 *
2400 * The second type of error is because the buffer given is either too
2401 * small or too large. The remedy is to give a correctly sized buffer.
2402 *
2403 * The third type are due to limits in this implementation.
2404 * @ref QCBOR_ERR_ARRAY_NESTING_TOO_DEEP can be worked around by
2405 * encoding the CBOR in two (or more) phases and adding the CBOR from
2406 * the first phase to the second with @c QCBOREncode_AddEncoded().
2407 *
2408 * If an error is returned, the buffer may have partially encoded
2409 * incorrect CBOR in it and it should not be used. Likewise, the length
2410 * may be incorrect and should not be used.
2411 *
2412 * Note that the error could have occurred in one of the many
2413 * @c QCBOREncode_AddXxx() calls long before QCBOREncode_Finish() was
2414 * called. This error handling reduces the CBOR implementation size
2415 * but makes debugging harder.
2416 *
2417 * This may be called multiple times. It will always return the
2418 * same. It can also be interleaved with calls to
2419 * QCBOREncode_FinishGetSize().
2420 *
2421 * QCBOREncode_GetErrorState() can be called to get the current
2422 * error state in order to abort encoding early as an optimization, but
2423 * calling it is is never required.
Michael Eckel5c531332020-03-02 01:35:30 +01002424 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002425QCBORError
2426QCBOREncode_Finish(QCBOREncodeContext *pCtx, UsefulBufC *pEncodedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01002427
2428
2429/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002430 * @brief Get the encoded CBOR and error status.
2431 *
2432 * @param[in] pCtx The context to finish encoding with.
2433 * @param[out] uEncodedLen The length of the encoded or potentially
2434 * encoded CBOR in bytes.
2435 *
2436 * @return The same errors as QCBOREncode_Finish().
2437 *
2438 * This functions the same as QCBOREncode_Finish(), but only returns the
2439 * size of the encoded output.
Michael Eckel5c531332020-03-02 01:35:30 +01002440 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002441QCBORError
2442QCBOREncode_FinishGetSize(QCBOREncodeContext *pCtx, size_t *uEncodedLen);
Michael Eckel5c531332020-03-02 01:35:30 +01002443
2444
2445/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002446 * @brief Indicate whether output buffer is NULL or not.
2447 *
2448 * @param[in] pCtx The encoding context.
2449 *
2450 * @return 1 if the output buffer is @c NULL.
2451 *
2452 * Sometimes a @c NULL input buffer is given to QCBOREncode_Init() so
2453 * that the size of the generated CBOR can be calculated without
2454 * allocating a buffer for it. This returns 1 when the output buffer
2455 * is @c NULL and 0 when it is not.
Michael Eckel5c531332020-03-02 01:35:30 +01002456 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002457static int
2458QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx);
2459
2460
2461/**
2462 * @brief Get the encoding error state.
2463 *
2464 * @param[in] pCtx The encoding context.
2465 *
2466 * @return One of @ref QCBORError. See return values from
2467 * QCBOREncode_Finish()
2468 *
2469 * Normally encoding errors need only be handled at the end of
2470 * encoding when QCBOREncode_Finish() is called. This can be called to
2471 * get the error result before finish should there be a need to halt
2472 * encoding before QCBOREncode_Finish() is called.
2473 */
2474static QCBORError
2475QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx);
2476
2477
2478/**
2479 * Encode the "head" of a CBOR data item.
2480 *
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002481 * @param Buffer Buffer to output the encoded head to; must be
Laurence Lundblade3eead482023-12-16 20:53:22 -07002482 * @ref QCBOR_HEAD_BUFFER_SIZE bytes in size.
2483 * @param uMajorType One of CBOR_MAJOR_TYPE_XX.
2484 * @param uMinLen The minimum number of bytes to encode uNumber. Almost
2485 * always this is 0 to use preferred
2486 * serialization. If this is 4, then even the
2487 * values 0xffff and smaller will be encoded in 4
2488 * bytes. This is used primarily when encoding a
2489 * float or double put into uNumber as the leading
2490 * zero bytes for them must be encoded.
2491 * @param uNumber The numeric argument part of the CBOR head.
2492 * @return Pointer and length of the encoded head or
2493 * @ref NULLUsefulBufC if the output buffer is too small.
2494 *
2495 * Callers do not to need to call this for normal CBOR encoding. Note
2496 * that it doesn't even take a @ref QCBOREncodeContext argument.
2497 *
2498 * This encodes the major type and argument part of a data item. The
2499 * argument is an integer that is usually either the value or the length
2500 * of the data item.
2501 *
2502 * This is exposed in the public interface to allow hashing of some CBOR
2503 * data types, bstr in particular, a chunk at a time so the full CBOR
2504 * doesn't have to be encoded in a contiguous buffer.
2505 *
2506 * For example, if you have a 100,000 byte binary blob in a buffer that
2507 * needs to be a bstr encoded and then hashed. You could allocate a
2508 * 100,010 byte buffer and encode it normally. Alternatively, you can
2509 * encode the head in a 10 byte buffer with this function, hash that and
2510 * then hash the 100,000 bytes using the same hash context.
Laurence Lundblade3eead482023-12-16 20:53:22 -07002511 */
2512UsefulBufC
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002513QCBOREncode_EncodeHead(UsefulBuf Buffer,
Laurence Lundblade3eead482023-12-16 20:53:22 -07002514 uint8_t uMajorType,
2515 uint8_t uMinLen,
2516 uint64_t uNumber);
Michael Eckel5c531332020-03-02 01:35:30 +01002517
2518
Michael Eckel5c531332020-03-02 01:35:30 +01002519
2520
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002521/* =========================================================================
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002522 BEGINNING OF PRIVATE IMPLEMENTATION
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002523 ========================================================================= */
Michael Eckel5c531332020-03-02 01:35:30 +01002524
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002525/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002526void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002527QCBOREncode_Private_AddBuffer(QCBOREncodeContext *pCtx,
2528 uint8_t uMajorType,
2529 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002530
2531
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002532/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002533void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002534QCBOREncode_Private_OpenMapOrArray(QCBOREncodeContext *pCtx,
2535 uint8_t uMajorType);
Michael Eckel5c531332020-03-02 01:35:30 +01002536
2537
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002538/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002539void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002540QCBOREncode_Private_OpenMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx,
2541 uint8_t uMajorType);
Michael Eckel5c531332020-03-02 01:35:30 +01002542
2543
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002544/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002545void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002546QCBOREncode_Private_CloseMapOrArray(QCBOREncodeContext *pCtx,
2547 uint8_t uMajorType);
Michael Eckel5c531332020-03-02 01:35:30 +01002548
2549
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002550/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002551void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002552QCBOREncode_Private_CloseMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx,
2553 uint8_t uMajorType);
Michael Eckel5c531332020-03-02 01:35:30 +01002554
2555
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002556/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002557void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002558QCBOREncode_Private_AddType7(QCBOREncodeContext *pCtx,
2559 uint8_t uMinLen,
2560 uint64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002561
2562
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002563/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002564void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002565QCBOREncode_Private_AddExpMantissa(QCBOREncodeContext *pCtx,
Laurence Lundblade3eead482023-12-16 20:53:22 -07002566 uint64_t uTag,
2567 UsefulBufC BigNumMantissa,
2568 bool bBigNumIsNegative,
2569 int64_t nMantissa,
2570 int64_t nExponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002571
Michael Eckel5c531332020-03-02 01:35:30 +01002572
2573
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -08002574
2575static inline void
2576QCBOREncode_SerializationCDE(QCBOREncodeContext *pMe)
2577{
2578 /* The use of a function pointer here is a little trick to reduce
2579 * code linked for the common use cases that don't sort. If this
2580 * function is never linked, then QCBOREncode_CloseAndSortMap() is
2581 * never linked and the amount of code pulled in is small. If the
2582 * mode switch between sorting and not sorting were an if
2583 * statement, then QCBOREncode_CloseAndSortMap() would always be
2584 * linked even when not used. */
2585 pMe->pfnCloseMap = QCBOREncode_CloseAndSortMap;
2586 pMe->uMode = QCBOR_ENCODE_MODE_CDE;
2587}
2588
2589static inline void
2590QCBOREncode_SerializationdCBOR(QCBOREncodeContext *pMe)
2591{
2592 pMe->pfnCloseMap = QCBOREncode_CloseAndSortMap;
2593 pMe->uMode = QCBOR_ENCODE_MODE_DCBOR;
2594}
2595
2596static inline void
2597QCBOREncode_SerializationPreferred(QCBOREncodeContext *pMe)
2598{
2599 pMe->uMode = QCBOR_ENCODE_MODE_PREFERRED;
2600}
2601
2602static inline void
2603QCBOREncode_Allow(QCBOREncodeContext *pMe, const uint8_t uAllow)
2604{
2605#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
2606 pMe->uAllow = uAllow;
2607#else
2608 (void)uAllow;
2609 (void)pMe;
2610#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
2611}
2612
2613
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002614static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002615QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pMe,
2616 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002617 const int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002618{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002619 /* Use _AddBuffer() because _AddSZString() is defined below, not above */
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002620 QCBOREncode_Private_AddBuffer(pMe,
2621 CBOR_MAJOR_TYPE_TEXT_STRING,
2622 UsefulBuf_FromSZ(szLabel));
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002623 QCBOREncode_AddInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002624}
2625
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002626static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002627QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002628 const int64_t nLabel,
2629 const int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002630{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002631 QCBOREncode_AddInt64(pMe, nLabel);
2632 QCBOREncode_AddInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002633}
2634
2635
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002636static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002637QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pMe,
2638 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002639 const uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002640{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002641 /* Use _AddBuffer() because _AddSZString() is defined below, not above */
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002642 QCBOREncode_Private_AddBuffer(pMe,
2643 CBOR_MAJOR_TYPE_TEXT_STRING,
2644 UsefulBuf_FromSZ(szLabel));
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002645 QCBOREncode_AddUInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002646}
2647
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002648static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002649QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002650 const int64_t nLabel,
2651 const uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002652{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002653 QCBOREncode_AddInt64(pMe, nLabel);
2654 QCBOREncode_AddUInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002655}
2656
2657
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002658static inline void
Laurence Lundblade2d493002024-02-01 11:09:17 -07002659QCBOREncode_AddNegativeUInt64ToMap(QCBOREncodeContext *pMe, const char *szLabel, uint64_t uNum)
2660{
2661 /* Use _AddBuffer() because _AddSZString() is defined below, not above */
2662 QCBOREncode_Private_AddBuffer(pMe,
2663 CBOR_MAJOR_TYPE_TEXT_STRING,
2664 UsefulBuf_FromSZ(szLabel));
2665 QCBOREncode_AddNegativeUInt64(pMe, uNum);
2666}
2667
2668static inline void
2669QCBOREncode_AddNegativeUInt64ToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint64_t uNum)
2670{
2671 QCBOREncode_AddInt64(pMe, nLabel);
2672 QCBOREncode_AddNegativeUInt64(pMe, uNum);
2673}
2674
2675
2676static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002677QCBOREncode_AddText(QCBOREncodeContext *pMe, const UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002678{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002679 QCBOREncode_Private_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002680}
2681
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002682static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002683QCBOREncode_AddTextToMap(QCBOREncodeContext *pMe,
2684 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002685 const UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002686{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002687 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szLabel));
2688 QCBOREncode_AddText(pMe, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002689}
2690
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002691static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002692QCBOREncode_AddTextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002693 const int64_t nLabel,
2694 const UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002695{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002696 QCBOREncode_AddInt64(pMe, nLabel);
2697 QCBOREncode_AddText(pMe, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002698}
2699
2700
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002701inline static void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002702QCBOREncode_AddSZString(QCBOREncodeContext *pMe, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002703{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002704 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szString));
Michael Eckel5c531332020-03-02 01:35:30 +01002705}
2706
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002707static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002708QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pMe,
2709 const char *szLabel,
2710 const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002711{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002712 QCBOREncode_AddSZString(pMe, szLabel);
2713 QCBOREncode_AddSZString(pMe, szString);
Michael Eckel5c531332020-03-02 01:35:30 +01002714}
2715
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002716static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002717QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002718 const int64_t nLabel,
Laurence Lundblade3eead482023-12-16 20:53:22 -07002719 const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002720{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002721 QCBOREncode_AddInt64(pMe, nLabel);
2722 QCBOREncode_AddSZString(pMe, szString);
Michael Eckel5c531332020-03-02 01:35:30 +01002723}
2724
2725
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +02002726#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002727static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002728QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pMe,
2729 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002730 const double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002731{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002732 QCBOREncode_AddSZString(pMe, szLabel);
2733 QCBOREncode_AddDouble(pMe, dNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002734}
2735
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002736static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002737QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002738 const int64_t nLabel,
2739 const double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002740{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002741 QCBOREncode_AddInt64(pMe, nLabel);
2742 QCBOREncode_AddDouble(pMe, dNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002743}
2744
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002745static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002746QCBOREncode_AddFloatToMap(QCBOREncodeContext *pMe,
2747 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002748 const float dNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002749{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002750 QCBOREncode_AddSZString(pMe, szLabel);
2751 QCBOREncode_AddFloat(pMe, dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002752}
2753
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002754static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002755QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pMe,
2756 const int64_t nLabel,
2757 const float fNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002758{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002759 QCBOREncode_AddInt64(pMe, nLabel);
2760 QCBOREncode_AddFloat(pMe, fNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002761}
2762
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002763static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002764QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pMe,
2765 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002766 const double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002767{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002768 QCBOREncode_AddSZString(pMe, szLabel);
2769 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002770}
2771
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002772static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002773QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002774 const int64_t nLabel,
2775 const double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002776{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002777 QCBOREncode_AddInt64(pMe, nLabel);
2778 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002779}
2780
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002781static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002782QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pMe,
2783 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002784 const float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002785{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002786 QCBOREncode_AddSZString(pMe, szLabel);
2787 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002788}
2789
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002790static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002791QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002792 const int64_t nLabel,
2793 const float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002794{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002795 QCBOREncode_AddInt64(pMe, nLabel);
2796 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002797}
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +02002798#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002799
Michael Eckel5c531332020-03-02 01:35:30 +01002800
Laurence Lundblade9b334962020-08-27 10:55:53 -07002801
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002802static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002803QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pMe,
2804 const uint8_t uTag,
2805 const int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002806{
2807 if(uTag == QCBOR_ENCODE_AS_TAG) {
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002808 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_EPOCH);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002809 }
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002810 QCBOREncode_AddInt64(pMe, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002811}
2812
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002813static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002814QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pMe,
2815 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002816 const uint8_t uTag,
2817 const int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002818{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002819 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002820 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002821}
2822
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002823static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002824QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002825 const int64_t nLabel,
2826 const uint8_t uTag,
2827 const int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002828{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002829 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002830 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002831}
2832
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002833static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002834QCBOREncode_AddDateEpoch(QCBOREncodeContext *pMe,
2835 const int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002836{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002837 QCBOREncode_AddTDateEpoch(pMe, QCBOR_ENCODE_AS_TAG, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002838}
2839
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002840static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002841QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pMe,
2842 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002843 const int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002844{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002845 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002846 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002847}
2848
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002849static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002850QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002851 const int64_t nLabel,
2852 const int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002853{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002854 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002855 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002856}
2857
2858
Laurence Lundblade46d63e92021-05-13 11:37:10 -07002859static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002860QCBOREncode_AddTDaysEpoch(QCBOREncodeContext *pMe,
2861 const uint8_t uTag,
2862 const int64_t nDays)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07002863{
2864 if(uTag == QCBOR_ENCODE_AS_TAG) {
2865 QCBOREncode_AddTag(pMe, CBOR_TAG_DAYS_EPOCH);
2866 }
2867 QCBOREncode_AddInt64(pMe, nDays);
2868}
2869
2870static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002871QCBOREncode_AddTDaysEpochToMapSZ(QCBOREncodeContext *pMe,
2872 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002873 const uint8_t uTag,
2874 const int64_t nDays)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07002875{
2876 QCBOREncode_AddSZString(pMe, szLabel);
2877 QCBOREncode_AddTDaysEpoch(pMe, uTag, nDays);
2878}
2879
2880static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002881QCBOREncode_AddTDaysEpochToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002882 const int64_t nLabel,
2883 const uint8_t uTag,
2884 const int64_t nDays)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07002885{
2886 QCBOREncode_AddInt64(pMe, nLabel);
2887 QCBOREncode_AddTDaysEpoch(pMe, uTag, nDays);
2888}
2889
Laurence Lundblade9b334962020-08-27 10:55:53 -07002890
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002891static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002892QCBOREncode_AddBytes(QCBOREncodeContext *pMe,
2893 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002894{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002895 QCBOREncode_Private_AddBuffer(pMe, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002896}
2897
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002898static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002899QCBOREncode_AddBytesToMap(QCBOREncodeContext *pMe,
2900 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002901 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002902{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002903 QCBOREncode_AddSZString(pMe, szLabel);
2904 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002905}
2906
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002907static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002908QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002909 const int64_t nLabel,
2910 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002911{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002912 QCBOREncode_AddInt64(pMe, nLabel);
2913 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002914}
2915
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002916static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002917QCBOREncode_OpenBytesInMapSZ(QCBOREncodeContext *pMe,
2918 const char *szLabel,
2919 UsefulBuf *pPlace)
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06002920{
2921 QCBOREncode_AddSZString(pMe, szLabel);
2922 QCBOREncode_OpenBytes(pMe, pPlace);
2923}
2924
2925static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002926QCBOREncode_OpenBytesInMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002927 const int64_t nLabel,
Laurence Lundblade3eead482023-12-16 20:53:22 -07002928 UsefulBuf *pPlace)
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06002929{
2930 QCBOREncode_AddInt64(pMe, nLabel);
2931 QCBOREncode_OpenBytes(pMe, pPlace);
2932}
2933
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002934
2935static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002936QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002937 const uint8_t uTagRequirement,
2938 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002939{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002940 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2941 QCBOREncode_AddTag(pMe, CBOR_TAG_BIN_UUID);
2942 }
2943 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002944}
2945
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002946static inline void
2947QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pMe,
2948 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002949 const uint8_t uTagRequirement,
2950 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002951{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002952 QCBOREncode_AddSZString(pMe, szLabel);
2953 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002954}
2955
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002956static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002957QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002958 const int64_t nLabel,
2959 const uint8_t uTagRequirement,
2960 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002961{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002962 QCBOREncode_AddInt64(pMe, nLabel);
2963 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002964}
2965
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002966static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002967QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002968{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002969 QCBOREncode_AddTBinaryUUID(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002970}
2971
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002972static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002973QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pMe,
2974 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002975 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002976{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002977 QCBOREncode_AddTBinaryUUIDToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002978}
2979
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002980static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002981QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002982 const int64_t nLabel,
2983 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002984{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002985 QCBOREncode_AddTBinaryUUIDToMapN(pMe,
2986 nLabel,
2987 QCBOR_ENCODE_AS_TAG,
2988 Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002989}
2990
2991
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002992static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002993QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002994 const uint8_t uTagRequirement,
2995 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002996{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002997 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2998 QCBOREncode_AddTag(pMe, CBOR_TAG_POS_BIGNUM);
2999 }
3000 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01003001}
3002
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003003static inline void
3004QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pMe,
3005 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003006 const uint8_t uTagRequirement,
3007 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003008{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003009 QCBOREncode_AddSZString(pMe, szLabel);
3010 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01003011}
3012
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003013static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003014QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003015 const int64_t nLabel,
3016 const uint8_t uTagRequirement,
3017 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003018{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003019 QCBOREncode_AddInt64(pMe, nLabel);
3020 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01003021}
3022
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003023static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003024QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003025{
3026 QCBOREncode_AddTPositiveBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
3027}
3028
3029static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003030QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pMe,
3031 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003032 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003033{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003034 QCBOREncode_AddTPositiveBignumToMapSZ(pMe,
3035 szLabel,
3036 QCBOR_ENCODE_AS_TAG,
3037 Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003038}
3039
3040static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003041QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003042 const int64_t nLabel,
3043 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003044{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003045 QCBOREncode_AddTPositiveBignumToMapN(pMe,
3046 nLabel,
3047 QCBOR_ENCODE_AS_TAG,
3048 Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003049}
3050
3051
3052static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003053QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003054 const uint8_t uTagRequirement,
3055 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003056{
3057 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3058 QCBOREncode_AddTag(pMe, CBOR_TAG_NEG_BIGNUM);
3059 }
3060 QCBOREncode_AddBytes(pMe, Bytes);
3061}
3062
3063static inline void
3064QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pMe,
3065 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003066 const uint8_t uTagRequirement,
3067 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003068{
3069 QCBOREncode_AddSZString(pMe, szLabel);
3070 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
3071}
3072
3073static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003074QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003075 const int64_t nLabel,
3076 const uint8_t uTagRequirement,
3077 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003078{
3079 QCBOREncode_AddInt64(pMe, nLabel);
3080 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
3081}
3082
3083static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003084QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003085{
3086 QCBOREncode_AddTNegativeBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
3087}
3088
3089static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003090QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pMe,
3091 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003092 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003093{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003094 QCBOREncode_AddTNegativeBignumToMapSZ(pMe,
3095 szLabel,
3096 QCBOR_ENCODE_AS_TAG,
3097 Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003098}
3099
3100static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003101QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003102 const int64_t nLabel,
3103 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003104{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003105 QCBOREncode_AddTNegativeBignumToMapN(pMe,
3106 nLabel,
3107 QCBOR_ENCODE_AS_TAG,
3108 Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003109}
3110
3111
Michael Eckel5c531332020-03-02 01:35:30 +01003112
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07003113#ifndef QCBOR_DISABLE_EXP_AND_MANTISSA
Michael Eckel5c531332020-03-02 01:35:30 +01003114
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003115static inline void
3116QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003117 const uint8_t uTagRequirement,
3118 const int64_t nMantissa,
3119 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003120{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003121 uint64_t uTag;
3122 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3123 uTag = CBOR_TAG_DECIMAL_FRACTION;
3124 } else {
3125 uTag = CBOR_TAG_INVALID64;
3126 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003127 QCBOREncode_Private_AddExpMantissa(pMe,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003128 uTag,
Michael Eckel5c531332020-03-02 01:35:30 +01003129 NULLUsefulBufC,
3130 false,
3131 nMantissa,
3132 nBase10Exponent);
3133}
3134
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003135static inline void
3136QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pMe,
3137 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003138 const uint8_t uTagRequirement,
3139 const int64_t nMantissa,
3140 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003141{
3142 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003143 QCBOREncode_AddTDecimalFraction(pMe,
3144 uTagRequirement,
3145 nMantissa,
3146 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003147}
3148
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003149static inline void
3150QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003151 const int64_t nLabel,
3152 const uint8_t uTagRequirement,
3153 const int64_t nMantissa,
3154 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003155{
3156 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003157 QCBOREncode_AddTDecimalFraction(pMe,
3158 uTagRequirement,
3159 nMantissa,
3160 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003161}
3162
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003163static inline void
3164QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003165 const int64_t nMantissa,
3166 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003167{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003168 QCBOREncode_AddTDecimalFraction(pMe,
3169 QCBOR_ENCODE_AS_TAG,
3170 nMantissa,
3171 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003172}
3173
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003174static inline void
3175QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pMe,
3176 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003177 const int64_t nMantissa,
3178 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003179{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003180 QCBOREncode_AddTDecimalFractionToMapSZ(pMe,
3181 szLabel,
3182 QCBOR_ENCODE_AS_TAG,
3183 nMantissa,
3184 nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003185}
3186
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003187static inline void
3188QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003189 const int64_t nLabel,
3190 const int64_t nMantissa,
3191 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003192{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003193 QCBOREncode_AddTDecimalFractionToMapN(pMe,
3194 nLabel,
3195 QCBOR_ENCODE_AS_TAG,
3196 nMantissa,
3197 nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003198}
3199
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003200
3201
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003202static inline void
3203QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003204 const uint8_t uTagRequirement,
3205 const UsefulBufC Mantissa,
3206 const bool bIsNegative,
3207 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003208{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003209 uint64_t uTag;
3210 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3211 uTag = CBOR_TAG_DECIMAL_FRACTION;
3212 } else {
3213 uTag = CBOR_TAG_INVALID64;
3214 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003215 QCBOREncode_Private_AddExpMantissa(pMe,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003216 uTag,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003217 Mantissa,
3218 bIsNegative,
Michael Eckel5c531332020-03-02 01:35:30 +01003219 0,
3220 nBase10Exponent);
3221}
3222
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003223static inline void
3224QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
3225 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003226 const uint8_t uTagRequirement,
3227 const UsefulBufC Mantissa,
3228 const bool bIsNegative,
3229 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003230{
3231 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003232 QCBOREncode_AddTDecimalFractionBigNum(pMe,
3233 uTagRequirement,
3234 Mantissa,
3235 bIsNegative,
3236 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003237}
3238
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003239static inline void
3240QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003241 const int64_t nLabel,
3242 const uint8_t uTagRequirement,
3243 const UsefulBufC Mantissa,
3244 const bool bIsNegative,
3245 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003246{
3247 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003248 QCBOREncode_AddTDecimalFractionBigNum(pMe,
3249 uTagRequirement,
3250 Mantissa,
3251 bIsNegative,
3252 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003253}
3254
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003255static inline void
3256QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003257 const UsefulBufC Mantissa,
3258 const bool bIsNegative,
3259 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003260{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003261 QCBOREncode_AddTDecimalFractionBigNum(pMe,
3262 QCBOR_ENCODE_AS_TAG,
3263 Mantissa,
3264 bIsNegative,
3265 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003266}
3267
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003268static inline void
3269QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
3270 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003271 const UsefulBufC Mantissa,
3272 const bool bIsNegative,
3273 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003274{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003275 QCBOREncode_AddTDecimalFractionBigNumToMapSZ(pMe,
3276 szLabel,
3277 QCBOR_ENCODE_AS_TAG,
3278 Mantissa,
3279 bIsNegative,
3280 nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003281}
3282
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003283static inline void
3284QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003285 const int64_t nLabel,
3286 const UsefulBufC Mantissa,
3287 const bool bIsNegative,
3288 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003289{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003290 QCBOREncode_AddTDecimalFractionBigNumToMapN(pMe,
3291 nLabel,
3292 QCBOR_ENCODE_AS_TAG,
3293 Mantissa,
3294 bIsNegative,
3295 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003296}
3297
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003298
3299
3300
3301
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003302static inline void
3303QCBOREncode_AddTBigFloat(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003304 const uint8_t uTagRequirement,
3305 const int64_t nMantissa,
3306 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003307{
3308 uint64_t uTag;
3309 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3310 uTag = CBOR_TAG_BIGFLOAT;
3311 } else {
3312 uTag = CBOR_TAG_INVALID64;
3313 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003314 QCBOREncode_Private_AddExpMantissa(pMe,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003315 uTag,
3316 NULLUsefulBufC,
3317 false,
3318 nMantissa,
3319 nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003320}
3321
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003322static inline void
3323QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pMe,
3324 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003325 const uint8_t uTagRequirement,
3326 const int64_t nMantissa,
3327 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003328{
3329 QCBOREncode_AddSZString(pMe, szLabel);
3330 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
3331}
3332
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003333static inline void
3334QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003335 const int64_t nLabel,
3336 const uint8_t uTagRequirement,
3337 const int64_t nMantissa,
3338 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003339{
3340 QCBOREncode_AddInt64(pMe, nLabel);
3341 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
3342}
3343
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003344static inline void
3345QCBOREncode_AddBigFloat(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003346 const int64_t nMantissa,
3347 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003348{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003349 QCBOREncode_AddTBigFloat(pMe,
3350 QCBOR_ENCODE_AS_TAG,
3351 nMantissa,
3352 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003353}
3354
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003355static inline void
3356QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pMe,
3357 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003358 const int64_t nMantissa,
3359 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003360{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003361 QCBOREncode_AddTBigFloatToMapSZ(pMe,
3362 szLabel,
3363 QCBOR_ENCODE_AS_TAG,
3364 nMantissa,
3365 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003366}
3367
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003368static inline void
3369QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003370 const int64_t nLabel,
3371 const int64_t nMantissa,
3372 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003373{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003374 QCBOREncode_AddTBigFloatToMapN(pMe,
3375 nLabel,
3376 QCBOR_ENCODE_AS_TAG,
3377 nMantissa,
3378 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003379}
3380
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003381
3382
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003383static inline void
3384QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003385 const uint8_t uTagRequirement,
3386 const UsefulBufC Mantissa,
3387 const bool bIsNegative,
3388 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003389{
3390 uint64_t uTag;
3391 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3392 uTag = CBOR_TAG_BIGFLOAT;
3393 } else {
3394 uTag = CBOR_TAG_INVALID64;
3395 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003396 QCBOREncode_Private_AddExpMantissa(pMe,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003397 uTag,
3398 Mantissa,
3399 bIsNegative,
3400 0,
3401 nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003402}
3403
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003404static inline void
3405QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pMe,
3406 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003407 const uint8_t uTagRequirement,
3408 const UsefulBufC Mantissa,
3409 const bool bIsNegative,
3410 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003411{
3412 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003413 QCBOREncode_AddTBigFloatBigNum(pMe,
3414 uTagRequirement,
3415 Mantissa,
3416 bIsNegative,
3417 nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003418}
3419
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003420static inline void
3421QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003422 const int64_t nLabel,
3423 const uint8_t uTagRequirement,
3424 const UsefulBufC Mantissa,
3425 const bool bIsNegative,
3426 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003427{
3428 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003429 QCBOREncode_AddTBigFloatBigNum(pMe,
3430 uTagRequirement,
3431 Mantissa,
3432 bIsNegative,
3433 nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003434}
3435
3436
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003437static inline void
3438QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003439 const UsefulBufC Mantissa,
3440 const bool bIsNegative,
3441 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003442{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003443 QCBOREncode_AddTBigFloatBigNum(pMe,
3444 QCBOR_ENCODE_AS_TAG,
3445 Mantissa, bIsNegative,
3446 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003447}
3448
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003449static inline void
3450QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pMe,
3451 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003452 const UsefulBufC Mantissa,
3453 const bool bIsNegative,
3454 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003455{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003456 QCBOREncode_AddTBigFloatBigNumToMapSZ(pMe,
3457 szLabel,
3458 QCBOR_ENCODE_AS_TAG,
3459 Mantissa,
3460 bIsNegative,
3461 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003462}
3463
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003464static inline void
3465QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003466 const int64_t nLabel,
3467 const UsefulBufC Mantissa,
3468 const bool bIsNegative,
3469 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003470{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003471 QCBOREncode_AddTBigFloatBigNumToMapN(pMe,
3472 nLabel,
3473 QCBOR_ENCODE_AS_TAG,
3474 Mantissa,
3475 bIsNegative,
3476 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003477}
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07003478#endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
Michael Eckel5c531332020-03-02 01:35:30 +01003479
3480
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003481static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003482QCBOREncode_AddTURI(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003483 const uint8_t uTagRequirement,
3484 const UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01003485{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003486 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3487 QCBOREncode_AddTag(pMe, CBOR_TAG_URI);
3488 }
3489 QCBOREncode_AddText(pMe, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01003490}
3491
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003492static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003493QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pMe,
3494 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003495 const uint8_t uTagRequirement,
3496 const UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01003497{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003498 QCBOREncode_AddSZString(pMe, szLabel);
3499 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01003500}
3501
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003502static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003503QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003504 const int64_t nLabel,
3505 const uint8_t uTagRequirement,
3506 const UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01003507{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003508 QCBOREncode_AddInt64(pMe, nLabel);
3509 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
3510}
3511
3512static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003513QCBOREncode_AddURI(QCBOREncodeContext *pMe, const UsefulBufC URI)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003514{
3515 QCBOREncode_AddTURI(pMe, QCBOR_ENCODE_AS_TAG, URI);
3516}
3517
3518static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003519QCBOREncode_AddURIToMap(QCBOREncodeContext *pMe,
3520 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003521 const UsefulBufC URI)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003522{
3523 QCBOREncode_AddTURIToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, URI);
3524}
3525
3526static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003527QCBOREncode_AddURIToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003528 const int64_t nLabel,
3529 const UsefulBufC URI)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003530{
3531 QCBOREncode_AddTURIToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01003532}
3533
3534
3535
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003536static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003537QCBOREncode_AddTB64Text(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003538 const uint8_t uTagRequirement,
3539 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003540{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003541 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3542 QCBOREncode_AddTag(pMe, CBOR_TAG_B64);
3543 }
3544 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003545}
3546
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003547static inline void
3548QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pMe,
3549 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003550 const uint8_t uTagRequirement,
3551 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003552{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003553 QCBOREncode_AddSZString(pMe, szLabel);
3554 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003555}
3556
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003557static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003558QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003559 const int64_t nLabel,
3560 const uint8_t uTagRequirement,
3561 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003562{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003563 QCBOREncode_AddInt64(pMe, nLabel);
3564 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
3565}
3566
3567static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003568QCBOREncode_AddB64Text(QCBOREncodeContext *pMe, const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003569{
3570 QCBOREncode_AddTB64Text(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
3571}
3572
3573static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003574QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pMe,
3575 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003576 const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003577{
3578 QCBOREncode_AddTB64TextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
3579}
3580
3581static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003582QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003583 const int64_t nLabel,
3584 const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003585{
3586 QCBOREncode_AddTB64TextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003587}
3588
3589
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003590
3591static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003592QCBOREncode_AddTB64URLText(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003593 const uint8_t uTagRequirement,
3594 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003595{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003596 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3597 QCBOREncode_AddTag(pMe, CBOR_TAG_B64URL);
3598 }
3599 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003600}
3601
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003602static inline void
3603QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pMe,
3604 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003605 const uint8_t uTagRequirement,
3606 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003607{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003608 QCBOREncode_AddSZString(pMe, szLabel);
3609 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003610}
3611
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003612static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003613QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003614 const int64_t nLabel,
3615 const uint8_t uTagRequirement,
3616 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003617{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003618 QCBOREncode_AddInt64(pMe, nLabel);
3619 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
3620}
3621
3622static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003623QCBOREncode_AddB64URLText(QCBOREncodeContext *pMe, const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003624{
3625 QCBOREncode_AddTB64URLText(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
3626}
3627
3628static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003629QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pMe,
3630 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003631 const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003632{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003633 QCBOREncode_AddTB64URLTextToMapSZ(pMe,
3634 szLabel,
3635 QCBOR_ENCODE_AS_TAG,
3636 B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003637}
3638
3639static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003640QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003641 const int64_t nLabel,
3642 const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003643{
3644 QCBOREncode_AddTB64URLTextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003645}
3646
3647
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003648
3649static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003650QCBOREncode_AddTRegex(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003651 const uint8_t uTagRequirement,
3652 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003653{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003654 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3655 QCBOREncode_AddTag(pMe, CBOR_TAG_REGEX);
3656 }
3657 QCBOREncode_AddText(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01003658}
3659
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003660static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003661QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pMe,
3662 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003663 const uint8_t uTagRequirement,
3664 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003665{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003666 QCBOREncode_AddSZString(pMe, szLabel);
3667 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01003668}
3669
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003670static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003671QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003672 const int64_t nLabel,
3673 const uint8_t uTagRequirement,
3674 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003675{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003676 QCBOREncode_AddInt64(pMe, nLabel);
3677 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
3678}
3679
3680static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003681QCBOREncode_AddRegex(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003682{
3683 QCBOREncode_AddTRegex(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
3684}
3685
3686static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003687QCBOREncode_AddRegexToMap(QCBOREncodeContext *pMe,
3688 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003689 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003690{
3691 QCBOREncode_AddTRegexToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
3692}
3693
3694static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003695QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003696 const int64_t nLabel,
3697 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003698{
3699 QCBOREncode_AddTRegexToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
3700
Michael Eckel5c531332020-03-02 01:35:30 +01003701}
3702
3703
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003704static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003705QCBOREncode_AddTMIMEData(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003706 const uint8_t uTagRequirement,
3707 const UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01003708{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003709 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
Laurence Lundblade4982f412020-09-18 23:02:18 -07003710 QCBOREncode_AddTag(pMe, CBOR_TAG_BINARY_MIME);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003711 }
Laurence Lundblade4982f412020-09-18 23:02:18 -07003712 QCBOREncode_AddBytes(pMe, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01003713}
3714
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003715static inline void
3716QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pMe,
3717 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003718 const uint8_t uTagRequirement,
3719 const UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01003720{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003721 QCBOREncode_AddSZString(pMe, szLabel);
3722 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01003723}
3724
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003725static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003726QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003727 const int64_t nLabel,
3728 const uint8_t uTagRequirement,
3729 const UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01003730{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003731 QCBOREncode_AddInt64(pMe, nLabel);
3732 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
3733}
3734
3735static inline void
3736QCBOREncode_AddMIMEData(QCBOREncodeContext *pMe, UsefulBufC MIMEData)
3737{
3738 QCBOREncode_AddTMIMEData(pMe, QCBOR_ENCODE_AS_TAG, MIMEData);
3739}
3740
3741static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003742QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pMe,
3743 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003744 const UsefulBufC MIMEData)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003745{
3746 QCBOREncode_AddTMIMEDataToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
3747}
3748
3749static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003750QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003751 const int64_t nLabel,
3752 const UsefulBufC MIMEData)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003753{
3754 QCBOREncode_AddTMIMEDataToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01003755}
3756
3757
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003758static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003759QCBOREncode_AddTDateString(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003760 const uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003761 const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01003762{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003763 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3764 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_STRING);
3765 }
3766 QCBOREncode_AddSZString(pMe, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01003767}
3768
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003769static inline void
3770QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pMe,
3771 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003772 const uint8_t uTagRequirement,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003773 const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01003774{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003775 QCBOREncode_AddSZString(pMe, szLabel);
3776 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01003777}
3778
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003779static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003780QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003781 const int64_t nLabel,
3782 const uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003783 const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01003784{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003785 QCBOREncode_AddInt64(pMe, nLabel);
3786 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
3787}
3788
3789static inline void
3790QCBOREncode_AddDateString(QCBOREncodeContext *pMe, const char *szDate)
3791{
3792 QCBOREncode_AddTDateString(pMe, QCBOR_ENCODE_AS_TAG, szDate);
3793}
3794
3795static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003796QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pMe,
3797 const char *szLabel,
3798 const char *szDate)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003799{
3800 QCBOREncode_AddTDateStringToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, szDate);
3801}
3802
3803static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003804QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003805 const int64_t nLabel,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003806 const char *szDate)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003807{
3808 QCBOREncode_AddTDateStringToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01003809}
3810
3811
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003812static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003813QCBOREncode_AddTDaysString(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003814 const uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003815 const char *szDate)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07003816{
3817 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3818 QCBOREncode_AddTag(pMe, CBOR_TAG_DAYS_STRING);
3819 }
3820 QCBOREncode_AddSZString(pMe, szDate);
3821}
3822
3823static inline void
3824QCBOREncode_AddTDaysStringToMapSZ(QCBOREncodeContext *pMe,
3825 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003826 const uint8_t uTagRequirement,
Laurence Lundblade46d63e92021-05-13 11:37:10 -07003827 const char *szDate)
3828{
3829 QCBOREncode_AddSZString(pMe, szLabel);
3830 QCBOREncode_AddTDaysString(pMe, uTagRequirement, szDate);
3831}
3832
3833static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003834QCBOREncode_AddTDaysStringToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003835 const int64_t nLabel,
3836 const uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003837 const char *szDate)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07003838{
3839 QCBOREncode_AddInt64(pMe, nLabel);
3840 QCBOREncode_AddTDaysString(pMe, uTagRequirement, szDate);
3841}
3842
3843
3844
3845static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003846QCBOREncode_Private_AddSimple(QCBOREncodeContext *pMe, const uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01003847{
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -08003848#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
3849 if(pMe->uMode >= QCBOR_ENCODE_MODE_DCBOR) {
3850 if(uNum < CBOR_SIMPLEV_FALSE ||
3851 uNum > CBOR_SIMPLEV_NULL) {
3852 pMe->uError = QCBOR_ERR_NOT_PREFERRED;
3853 return;
3854 }
3855 }
3856#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
3857
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003858 QCBOREncode_Private_AddType7(pMe, 0, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01003859}
3860
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003861static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003862QCBOREncode_Private_AddSimpleToMap(QCBOREncodeContext *pMe,
3863 const char *szLabel,
3864 const uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01003865{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003866 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003867 QCBOREncode_Private_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01003868}
3869
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003870static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003871QCBOREncode_Private_AddSimpleToMapN(QCBOREncodeContext *pMe,
3872 const int64_t nLabel,
3873 const uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01003874{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003875 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003876 QCBOREncode_Private_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01003877}
3878
3879
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003880static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003881QCBOREncode_AddBool(QCBOREncodeContext *pMe, const bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01003882{
3883 uint8_t uSimple = CBOR_SIMPLEV_FALSE;
3884 if(b) {
3885 uSimple = CBOR_SIMPLEV_TRUE;
3886 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003887 QCBOREncode_Private_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01003888}
3889
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003890static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003891QCBOREncode_AddBoolToMap(QCBOREncodeContext *pMe, const char *szLabel, const bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01003892{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003893 QCBOREncode_AddSZString(pMe, szLabel);
3894 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01003895}
3896
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003897static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003898QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pMe, const int64_t nLabel, const bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01003899{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003900 QCBOREncode_AddInt64(pMe, nLabel);
3901 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01003902}
3903
3904
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003905static inline void
3906QCBOREncode_AddNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003907{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003908 QCBOREncode_Private_AddSimple(pMe, CBOR_SIMPLEV_NULL);
Michael Eckel5c531332020-03-02 01:35:30 +01003909}
3910
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003911static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003912QCBOREncode_AddNULLToMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003913{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003914 QCBOREncode_AddSZString(pMe, szLabel);
3915 QCBOREncode_AddNULL(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003916}
3917
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003918static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003919QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003920{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003921 QCBOREncode_AddInt64(pMe, nLabel);
3922 QCBOREncode_AddNULL(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003923}
3924
3925
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003926static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003927QCBOREncode_AddUndef(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003928{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003929 QCBOREncode_Private_AddSimple(pMe, CBOR_SIMPLEV_UNDEF);
Michael Eckel5c531332020-03-02 01:35:30 +01003930}
3931
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003932static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003933QCBOREncode_AddUndefToMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003934{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003935 QCBOREncode_AddSZString(pMe, szLabel);
3936 QCBOREncode_AddUndef(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003937}
3938
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003939static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003940QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003941{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003942 QCBOREncode_AddInt64(pMe, nLabel);
3943 QCBOREncode_AddUndef(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003944}
3945
3946
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003947static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003948QCBOREncode_OpenArray(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003949{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003950 QCBOREncode_Private_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
Michael Eckel5c531332020-03-02 01:35:30 +01003951}
3952
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003953static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003954QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003955{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003956 QCBOREncode_AddSZString(pMe, szLabel);
3957 QCBOREncode_OpenArray(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003958}
3959
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003960static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003961QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003962{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003963 QCBOREncode_AddInt64(pMe, nLabel);
3964 QCBOREncode_OpenArray(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003965}
3966
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -08003967
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003968static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003969QCBOREncode_CloseArray(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003970{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003971 QCBOREncode_Private_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
Michael Eckel5c531332020-03-02 01:35:30 +01003972}
3973
3974
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003975static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003976QCBOREncode_OpenMap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003977{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003978 QCBOREncode_Private_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
Michael Eckel5c531332020-03-02 01:35:30 +01003979}
3980
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003981static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003982QCBOREncode_OpenMapInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003983{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003984 QCBOREncode_AddSZString(pMe, szLabel);
3985 QCBOREncode_OpenMap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003986}
3987
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003988static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003989QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003990{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003991 QCBOREncode_AddInt64(pMe, nLabel);
3992 QCBOREncode_OpenMap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003993}
3994
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003995static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003996QCBOREncode_CloseMap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003997{
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -08003998 (pMe->pfnCloseMap)(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003999}
4000
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004001static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004002QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01004003{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004004 QCBOREncode_Private_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01004005}
4006
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004007static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07004008QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pMe,
4009 const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01004010{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004011 QCBOREncode_AddSZString(pMe, szLabel);
4012 QCBOREncode_OpenArrayIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01004013}
4014
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004015static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07004016QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004017 const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01004018{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004019 QCBOREncode_AddInt64(pMe, nLabel);
4020 QCBOREncode_OpenArrayIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01004021}
4022
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004023static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004024QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01004025{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004026 QCBOREncode_Private_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01004027}
4028
4029
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004030static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004031QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01004032{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004033 QCBOREncode_Private_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01004034}
4035
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004036static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07004037QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pMe,
4038 const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01004039{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004040 QCBOREncode_AddSZString(pMe, szLabel);
4041 QCBOREncode_OpenMapIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01004042}
4043
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004044static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07004045QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004046 const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01004047{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004048 QCBOREncode_AddInt64(pMe, nLabel);
4049 QCBOREncode_OpenMapIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01004050}
4051
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004052static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004053QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01004054{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004055 QCBOREncode_Private_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01004056}
4057
4058
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004059static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004060QCBOREncode_BstrWrap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01004061{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004062 QCBOREncode_Private_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_BYTE_STRING);
Michael Eckel5c531332020-03-02 01:35:30 +01004063}
4064
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004065static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004066QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01004067{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004068 QCBOREncode_AddSZString(pMe, szLabel);
4069 QCBOREncode_BstrWrap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01004070}
4071
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004072static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004073QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01004074{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004075 QCBOREncode_AddInt64(pMe, nLabel);
4076 QCBOREncode_BstrWrap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01004077}
4078
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004079static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004080QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pMe, UsefulBufC *pWrappedCBOR)
Michael Eckel5c531332020-03-02 01:35:30 +01004081{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004082 QCBOREncode_CloseBstrWrap2(pMe, true, pWrappedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01004083}
4084
4085
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004086static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004087QCBOREncode_AddEncoded(QCBOREncodeContext *pMe, const UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01004088{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004089 QCBOREncode_Private_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_RAW, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01004090}
4091
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004092static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07004093QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pMe,
4094 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004095 const UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01004096{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004097 QCBOREncode_AddSZString(pMe, szLabel);
4098 QCBOREncode_AddEncoded(pMe, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01004099}
4100
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004101static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07004102QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004103 const int64_t nLabel,
4104 const UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01004105{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004106 QCBOREncode_AddInt64(pMe, nLabel);
4107 QCBOREncode_AddEncoded(pMe, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01004108}
4109
4110
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004111static inline int
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004112QCBOREncode_IsBufferNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01004113{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004114 return UsefulOutBuf_IsBufferNULL(&(pMe->OutBuf));
Michael Eckel5c531332020-03-02 01:35:30 +01004115}
4116
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004117static inline QCBORError
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004118QCBOREncode_GetErrorState(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01004119{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004120 if(UsefulOutBuf_GetError(&(pMe->OutBuf))) {
Laurence Lundbladef2f0c3f2024-04-12 13:01:54 -07004121 /* Items didn't fit in the buffer. This check catches this
4122 * condition for all the appends and inserts so checks aren't
4123 * needed when the appends and inserts are performed. And of
4124 * course UsefulBuf will never overrun the input buffer given to
4125 * it. No complex analysis of the error handling in this file is
4126 * needed to know that is true. Just read the UsefulBuf code.
4127 */
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004128 pMe->uError = QCBOR_ERR_BUFFER_TOO_SMALL;
Laurence Lundbladef2f0c3f2024-04-12 13:01:54 -07004129 /* QCBOR_ERR_BUFFER_TOO_SMALL masks other errors, but that is
4130 * OK. Once the caller fixes this, they'll be unmasked.
4131 */
Michael Eckel5c531332020-03-02 01:35:30 +01004132 }
4133
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004134 return (QCBORError)pMe->uError;
Michael Eckel5c531332020-03-02 01:35:30 +01004135}
4136
4137
Laurence Lundblade45d5e482020-09-15 21:15:15 -07004138/* ========================================================================
4139 END OF PRIVATE INLINE IMPLEMENTATION
4140 ======================================================================== */
Michael Eckel5c531332020-03-02 01:35:30 +01004141
4142#ifdef __cplusplus
4143}
4144#endif
4145
Laurence Lundblade844bb5c2020-03-01 17:27:25 -08004146#endif /* qcbor_encode_h */