blob: 694c2a38f6d88f03bc475afc979dbbb3d1ca18f5 [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 *
344 * If USEFULBUF_DISABLE_ALL_FLOATis defined, then floating point
345 * 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 *
352 * Summary Limits of this implementation:
353 * - The entire encoded CBOR must fit into contiguous memory.
354 * - Max size of encoded / decoded CBOR data is a few bytes less than @c UINT32_MAX (4GB).
355 * - Max array / map nesting level when encoding / decoding is
356 * @ref QCBOR_MAX_ARRAY_NESTING (this is typically 15).
357 * - Max items in an array or map when encoding / decoding is
358 * @ref QCBOR_MAX_ITEMS_IN_ARRAY (typically 65,536).
359 * - Does not directly support labels in maps other than text strings & integers.
360 * - Does not directly support integer labels greater than @c INT64_MAX.
361 * - Epoch dates limited to @c INT64_MAX (+/- 292 billion years).
362 * - Exponents for bigfloats and decimal integers are limited to @c INT64_MAX.
363 * - Tags on labels are ignored during decoding.
364 * - The maximum tag nesting is @c QCBOR_MAX_TAGS_PER_ITEM (typically 4).
365 * - Works only on 32- and 64-bit CPUs (modifications could make it work
366 * on 16-bit CPUs).
367 *
368 * The public interface uses @c size_t for all lengths. Internally the
369 * implementation uses 32-bit lengths by design to use less memory and
370 * fit structures on the stack. This limits the encoded CBOR it can
371 * work with to size @c UINT32_MAX (4GB) which should be enough.
372 *
373 * This implementation assumes two's compliment integer machines.
374 * @c <stdint.h> also requires this. It is possible to modify this
375 * implementation for another integer representation, but all modern
376 * machines seem to be two's compliment.
Michael Eckel5c531332020-03-02 01:35:30 +0100377 */
378
379
Laurence Lundblade825164e2020-10-22 20:18:06 -0700380/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700381 * The size of the buffer to be passed to QCBOREncode_EncodeHead(). It
382 * is one byte larger than sizeof(uint64_t) + 1, the actual maximum
383 * size of the head of a CBOR data item because
384 * QCBOREncode_EncodeHead() needs one extra byte to work.
Michael Eckel5c531332020-03-02 01:35:30 +0100385 */
386#define QCBOR_HEAD_BUFFER_SIZE (sizeof(uint64_t) + 2)
387
Michael Eckel5c531332020-03-02 01:35:30 +0100388
Laurence Lundblade9b334962020-08-27 10:55:53 -0700389/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700390 * Output the full CBOR tag. See @ref CBORTags, @ref Tag-Usage and
391 * @ref Tags-Overview.
Laurence Lundblade9b334962020-08-27 10:55:53 -0700392 */
393#define QCBOR_ENCODE_AS_TAG 0
394
395/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700396 * Output only the 'borrowed' content format for the relevant tag.
397 * See @ref CBORTags, @ref Tag-Usage and @ref Tags-Overview.
Laurence Lundblade9b334962020-08-27 10:55:53 -0700398 */
399#define QCBOR_ENCODE_AS_BORROWED 1
400
Michael Eckel5c531332020-03-02 01:35:30 +0100401
402/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700403 * QCBOREncodeContext is the data type that holds context for all the
404 * encoding functions. It is less than 200 bytes, so it can go on the
405 * stack. The contents are opaque, and the caller should not access
406 * internal members. A context may be re used serially as long as it is
407 * re initialized.
Michael Eckel5c531332020-03-02 01:35:30 +0100408 */
409typedef struct _QCBOREncodeContext QCBOREncodeContext;
410
411
412/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700413 * Initialize the encoder to prepare to encode some CBOR.
414 *
415 * @param[in,out] pCtx The encoder context to initialize.
416 * @param[in] Storage The buffer into which the encoded result
417 * will be written.
418 *
419 * Call this once at the start of an encoding of some CBOR. Then call
420 * the many functions like QCBOREncode_AddInt64() and
421 * QCBOREncode_AddText() to add the different data items. Finally,
422 * call QCBOREncode_Finish() to get the pointer and length of the
423 * encoded result.
424 *
425 * The primary purpose of this function is to give the pointer and
426 * length of the output buffer into which the encoded CBOR will be
427 * written. This is done with a @ref UsefulBuf structure, which is
428 * just a pointer and length (it is equivalent to two parameters, one
429 * a pointer and one a length, but a little prettier).
430 *
431 * The output buffer can be allocated any way (malloc, stack,
432 * static). It is just some memory that QCBOR writes to. The length
433 * must be the length of the allocated buffer. QCBOR will never write
434 * past that length, but might write up to that length. If the buffer
435 * is too small, encoding will go into an error state and not write
436 * anything further.
437 *
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -0800438 * If allocating on the stack, the convenience macro
Laurence Lundblade3eead482023-12-16 20:53:22 -0700439 * UsefulBuf_MAKE_STACK_UB() can be used, but its use is not required.
440 *
441 * Since there is no reallocation or such, the output buffer must be
442 * correctly sized when passed in here. It is OK, but wasteful if it
443 * is too large. One way to pick the size is to figure out the maximum
444 * size that will ever be needed and hard code a buffer of that size.
445 *
446 * Another way to do it is to have QCBOR calculate it for you. To do
447 * this, pass @ref SizeCalculateUsefulBuf for @c Storage. Then call
448 * all the functions to add the CBOR exactly as if encoding for
449 * real. Finally, call QCBOREncode_FinishGetSize(). Once the length
450 * is obtained, allocate a buffer of that size, call
451 * QCBOREncode_Init() again with the real buffer. Call all the add
452 * functions again and finally, QCBOREncode_Finish() to obtain the
453 * final result. This uses twice the CPU time, but that is usually not
454 * an issue.
455 *
456 * See QCBOREncode_Finish() for how the pointer and length for the
457 * encoded CBOR is returned.
458 *
459 * For practical purposes QCBOR can't output encoded CBOR larger than
460 * @c UINT32_MAX (4GB) even on 64-bit CPUs because the internal
461 * offsets used to track the start of an array/map are 32 bits to
462 * reduce the size of the encoding context.
463 *
464 * A @ref QCBOREncodeContext can be reused over and over as long as
465 * QCBOREncode_Init() is called before each use.
Michael Eckel5c531332020-03-02 01:35:30 +0100466 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700467void
468QCBOREncode_Init(QCBOREncodeContext *pCtx, UsefulBuf Storage);
Michael Eckel5c531332020-03-02 01:35:30 +0100469
470
471/**
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -0800472 * @brief Select preferred serialization mode.
473 *
474 * @param[in] pCtx The encoding context for mode set.
475 *
476 * Setting this mode will cause QCBOR to return an error if an attempt
477 * is made to use one of the methods that produce non-preferred
478 * serialization. It doesn't change anything else as QCBOR produces
479 * preferred serialization by default.
480 *
481 * The non-preferred methods are: QCBOREncode_AddFloatNoPreferred(),
482 * QCBOREncode_AddDoubleNoPreferred(),
483 * QCBOREncode_OpenArrayIndefiniteLength(),
484 * QCBOREncode_CloseArrayIndefiniteLength(),
485 * QCBOREncode_OpenMapIndefiniteLength(),
486 * QCBOREncode_CloseMapIndefiniteLength(), plus those derived from the
487 * above listed.
488 *
489 * This mode is just a user guard to prevent accidentally calling
490 * something that produces non-preferred serialization. It doesn't do
491 * anything but causes errors to occur on attempts to call the above
492 * listed functions. This does nothing if the library is compiled
493 * QCBOR_DISABLE_ENCODE_USAGE_GUARDS.
494 *
495 * See @ref Serialization. It is usually not necessary to set this
496 * mode, but there is usually no disadvantage to setting it. Preferred
497 * Serialization is defined in RFC 8949, section 4.1.
498 */
499static void
500QCBOREncode_SerializationPreferred(QCBOREncodeContext *pCtx);
501
502
503/**
504 * @brief Select CBOR deterministic encoding mode.
505 *
506 * @param[in] pCtx The encoding context for mode set.
507
508 * This causes QCBOR to produce CBOR Deterministic Encoding (CDE).
509 * With CDE, two distant unrelated CBOR encoders will produce exactly
510 * the same encoded CBOR for a given input.
511 *
512 * In addition to doing everything
513 * QCBOREncode_SerializationPreferred() does (including exclusion of
514 * indefinite lengths), this causes maps to be sorted. The map is
515 * sorted automatically when QCBOREncode_CloseMap() is called.
516 * QCBOREncode_CloseMap() becomes equivalent to
517 * QCBOREncode_CloseAndSortMap().
518 *
519 * Note that linking this function causese about 30% more code from
520 * the QCBOR library to be linked. Also, QCBOREncode_CloseMap() runs
521 * slower, but this is probably only of consequence in very
522 * constrained environments.
523 *
524 * See @ref Serialization. It is usually not necessary to set this
525 * mode as determinism is very rarely needed. However it will
526 * usually work with most protocols. CDE is defined in
527 * draft-ietf-cbor-cde.
528 */
529static void
530QCBOREncode_SerializationCDE(QCBOREncodeContext *pCtx);
531
532
533/**
534 * @brief Select "dCBOR" encoding mode.
535 *
536 * @param[in] pCtx The encoding context for mode set.
537 *
538 * This is a superset of CDE. This function does everything
539 * QCBOREncode_SerializationCDE() does. Also it is a super set of
540 * preferred serialization and does everything
541 * QCBOREncode_SerializationPreferred() does.
542 *
543 * The main feature of dCBOR is that there is only one way to serialize a
544 * particular numeric value. This changes the behavior of functions
545 * that add floating-point numbers. If the floating-point number is
546 * whole, it will be encoded as an integer, not a floating-point number.
547 * 0.000 will be encoded as 0x00. Precision is never lost in this
548 * conversion.
549 *
550 * dCBOR also disallows NaN payloads. QCBOR will allow NaN payloads if
551 * you pass a NaN to one of the floating-point encoding functions.
552 * This mode forces all NaNs to the half-precision queit NaN. Also see
553 * QCBOREncode_Allow().
554 *
555 * dCBOR also disallows 65-bit negative integers.
556 *
557 * dCBOR disallows use of any simple type other than true, false and
558 * NULL. In particular it disallows use of "undef" produced by
559 * QCBOREncode_AddUndef().
560 *
561 * See @ref Serialization. Set this mode only if the protocol you are
562 * implementing requires dCBOR. This mode is usually not compatible
563 * with protocols that don't use dCBOR. dCBOR is defined in
564 * draft-mcnally-deterministic-cbor.
565 */
566static void
567QCBOREncode_SerializationdCBOR(QCBOREncodeContext *pCtx);
568
569
570
571
572/** Bit flag to be passed to QCBOREncode_Allow() to allow NaN payloads
573 * to be output by QCBOREncode_AddDouble(),
574 * QCBOREncode_AddDoubleNoPreferred(), QCBORENcode_AddFloat() and
575 * QCBOREncode_AddSingleleNoPreferred. */
576#define QCBOR_ENCODE_ALLOW_NAN_PAYLOAD 0x01
577
578/** Bit flag to be passed to QCBOREncode_Allow() to allow use of
579 * QCBOREncode_AddNegativeUInt64(). */
580#define QCBOR_ENCODE_ALLOW_65_BIG_NEG 0x02
581
582/** Bit flag to be passed to QCBOREncode_Allow() output of less
583 * interoperable values. See @ref QCBOR_ENCODE_ALLOW_NAN_PAYLOAD, and
584 * @ref QCBOR_ENCODE_ALLOW_65_BIG_NEG. */
585#define QCBOR_ENCODE_ALLOW_ALL 0xFF
586
587
588/**
589 * @brief Allow encoding of less-interoperable values.
590 *
591 * @param[in] pCtx The encoding context.
592 * @param[in] uAllow Bit flags indicating what to allow.
593 *
594 * There are a few things in the CBOR standard that are often not
595 * supported and are thus not very interoperable. By default QCBOR
596 * will error if you attempt to output them. This disables that
597 * error.
598 *
599 * See @ref QCBOR_ENCODE_ALLOW_NAN_PAYLOAD and
600 * @ref QCBOR_ENCODE_ALLOW_65_BIG_NEG.
601 *
602 * This does nothing if the library is compiled
603 * QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
604static void
605QCBOREncode_Allow(QCBOREncodeContext *pCtx, uint8_t uAllow);
606
607
608
609/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700610 * @brief Add a signed 64-bit integer to the encoded output.
611 *
612 * @param[in] pCtx The encoding context to add the integer to.
613 * @param[in] nNum The integer to add.
614 *
615 * The integer will be encoded and added to the CBOR output.
616 *
617 * This function figures out the size and the sign and encodes in the
618 * correct minimal CBOR. Specifically, it will select CBOR major type
619 * 0 or 1 based on sign and will encode to 1, 2, 4 or 8 bytes
620 * depending on the value of the integer. Values less than 24
621 * effectively encode to one byte because they are encoded in with the
622 * CBOR major type. This is a neat and efficient characteristic of
623 * CBOR that can be taken advantage of when designing CBOR-based
624 * protocols. If integers like tags can be kept between -23 and 23
625 * they will be encoded in one byte including the major type.
626 *
627 * If you pass a smaller int, say an @c int16_t or a small value, say
628 * 100, the encoding will still be CBOR's most compact that can
629 * represent the value. For example, CBOR always encodes the value 0
630 * as one byte, 0x00. The representation as 0x00 includes
631 * identification of the type as an integer too as the major type for
632 * an integer is 0. See [RFC 8949]
633 * (https://tools.ietf.org/html/rfc8949) Appendix A for more examples
634 * of CBOR encoding. This compact encoding is also preferred
635 * serialization CBOR as per section 34.1 in RFC 8949.
636 *
637 * There are no functions to add @c int16_t or @c int32_t because they
638 * are not necessary because this always encodes to the smallest
639 * number of bytes based on the value (If this code is running on a
640 * 32-bit machine having a way to add 32-bit integers would reduce
641 * code size some).
642 *
643 * If the encoding context is in an error state, this will do
644 * nothing. If an error occurs when adding this integer, the internal
645 * error flag will be set, and the error will be returned when
646 * QCBOREncode_Finish() is called.
647 *
648 * See also QCBOREncode_AddUInt64().
Michael Eckel5c531332020-03-02 01:35:30 +0100649 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700650void
651QCBOREncode_AddInt64(QCBOREncodeContext *pCtx, int64_t nNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100652
Laurence Lundblade3eead482023-12-16 20:53:22 -0700653static void
654QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100655
Laurence Lundblade3eead482023-12-16 20:53:22 -0700656static void
657QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100658
659
660/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700661 * @brief Add an unsigned 64-bit integer to the encoded output.
662 *
663 * @param[in] pCtx The encoding context to add the integer to.
664 * @param[in] uNum The integer to add.
665 *
666 * The integer will be encoded and added to the CBOR output.
667 *
668 * The only reason so use this function is for integers larger than
669 * @c INT64_MAX and smaller than @c UINT64_MAX. Otherwise
670 * QCBOREncode_AddInt64() will work fine.
671 *
672 * Error handling is the same as for QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +0100673 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700674void
675QCBOREncode_AddUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100676
Laurence Lundblade3eead482023-12-16 20:53:22 -0700677static void
678QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100679
Laurence Lundblade3eead482023-12-16 20:53:22 -0700680static void
681QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100682
683
684/**
Laurence Lundblade2d493002024-02-01 11:09:17 -0700685 * @brief Add a negative 64-bit integer to encoded output
686 *
687 * @param[in] pCtx The encoding context to add the integer to.
688 * @param[in] uNum The integer to add.
689 *
690 * QCBOREncode_AddInt64() is much better to encode negative integers
691 * than this. What this can do is add integers with one more
692 * significant bit than an int64_t (a "65-bit" integer if you count
693 * the sign as a bit) which is possible because CBOR happens to
694 * support such integers.
695 *
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -0800696 * Because use of this is discouraged. It must be explicitly allowed
697 * by passing @ref QCBOR_ENCODE_ALLOW_65_BIG_NEG to a call to
698 * QCBOREncode_Allow().
699 *
Laurence Lundblade2d493002024-02-01 11:09:17 -0700700 * The actual value encoded is -uNum - 1. That is, give 0 for uNum to
701 * transmit -1, give 1 to transmit -2 and give UINT64_MAX to transmit
702 * -UINT64_MAX-1 (18446744073709551616). The interface is odd like
703 * this so all negative values CBOR can represent can be encoded by
704 * QCBOR (making this a complete CBOR implementation).
705 *
706 * The most negative value QCBOREncode_AddInt64() can encode is
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -0800707 * -9223372036854775808 which is -2^63 or negative 0x800000000000.
708 * This can encode from -9223372036854775809 to -18446744073709551616
709 * or -2^63 - 1 to -2^64. Note that it is not possible to represent
710 * positive or negative 18446744073709551616 in any standard C data
711 * type.
Laurence Lundblade2d493002024-02-01 11:09:17 -0700712 *
713 * Negative integers are normally decoded in QCBOR with type
714 * @ref QCBOR_TYPE_INT64. Integers in the range of -9223372036854775809
715 * to -18446744073709551616 are returned as @ref QCBOR_TYPE_65BIT_NEG_INT.
716 *
717 * WARNING: some CBOR decoders will be unable to decode -2^63 - 1 to
718 * -2^64. Also, most CPUs do not have registers that can represent
719 * this range. If you need 65-bit negative integers, you likely need
720 * negative 66, 67 and 68-bit negative integers so it is likely better
721 * to use CBOR big numbers where you can have any number of bits. See
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -0800722 * QCBOREncode_AddTNegativeBignum() and @ref Serialization.
Laurence Lundblade2d493002024-02-01 11:09:17 -0700723 */
724void
725QCBOREncode_AddNegativeUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
726
727static void
728QCBOREncode_AddNegativeUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum);
729
730static void
731QCBOREncode_AddNegativeUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum);
732
733/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700734 * @brief Add a UTF-8 text string to the encoded output.
735 *
736 * @param[in] pCtx The encoding context to add the text to.
737 * @param[in] Text Pointer and length of text to add.
738 *
739 * The text passed in must be unencoded UTF-8 according to [RFC 3629]
740 * (https://tools.ietf.org/html/rfc3629). There is no NULL
741 * termination. The text is added as CBOR major type 3.
742 *
743 * If called with @c nBytesLen equal to 0, an empty string will be
744 * added. When @c nBytesLen is 0, @c pBytes may be @c NULL.
745 *
746 * Note that the restriction of the buffer length to a @c uint32_t is
747 * entirely intentional as this encoder is not capable of encoding
748 * lengths greater. This limit to 4GB for a text string should not be
749 * a problem.
750 *
751 * Text lines in Internet protocols (on the wire) are delimited by
752 * either a CRLF or just an LF. Officially many protocols specify
753 * CRLF, but implementations often work with either. CBOR type 3 text
754 * can be either line ending, even a mixture of both.
755 *
756 * Operating systems usually have a line end convention. Windows uses
757 * CRLF. Linux and MacOS use LF. Some applications on a given OS may
758 * work with either and some may not.
759 *
760 * The majority of use cases and CBOR protocols using type 3 text will
761 * work with either line ending. However, some use cases or protocols
762 * may not work with either in which case translation to and/or from
763 * the local line end convention, typically that of the OS, is
764 * necessary.
765 *
766 * QCBOR does no line ending translation for type 3 text when encoding
767 * and decoding.
768 *
769 * Error handling is the same as QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +0100770 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700771static void
772QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text);
Michael Eckel5c531332020-03-02 01:35:30 +0100773
Laurence Lundblade3eead482023-12-16 20:53:22 -0700774static void
775QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text);
Michael Eckel5c531332020-03-02 01:35:30 +0100776
Laurence Lundblade3eead482023-12-16 20:53:22 -0700777static void
778QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text);
Michael Eckel5c531332020-03-02 01:35:30 +0100779
780
781/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700782 * @brief Add a UTF-8 text string to the encoded output.
783 *
784 * @param[in] pCtx The encoding context to add the text to.
785 * @param[in] szString Null-terminated text to add.
786 *
787 * This works the same as QCBOREncode_AddText().
Michael Eckel5c531332020-03-02 01:35:30 +0100788 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700789static void
790QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString);
Michael Eckel5c531332020-03-02 01:35:30 +0100791
Laurence Lundblade3eead482023-12-16 20:53:22 -0700792static void
793QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString);
Michael Eckel5c531332020-03-02 01:35:30 +0100794
Laurence Lundblade3eead482023-12-16 20:53:22 -0700795static void
796QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString);
Michael Eckel5c531332020-03-02 01:35:30 +0100797
798
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200799#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Michael Eckel5c531332020-03-02 01:35:30 +0100800/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700801 * @brief Add a double-precision floating-point number to the encoded output.
802 *
803 * @param[in] pCtx The encoding context to add the double to.
804 * @param[in] dNum The double-precision number to add.
805 *
806 * This encodes and outputs a floating-point number. CBOR major type 7
807 * is used.
808 *
809 * This implements preferred serialization, selectively encoding the
810 * double-precision floating-point number as either double-precision,
811 * single-precision or half-precision. Infinity, NaN and 0 are always
812 * encoded as half-precision. If no precision will be lost in the
813 * conversion to half-precision, then it will be converted and
814 * encoded. If not and no precision will be lost in conversion to
815 * single-precision, then it will be converted and encoded. If not,
816 * then no conversion is performed, and it encoded as a
817 * double-precision.
818 *
819 * Half-precision floating-point numbers take up 2 bytes, half that of
820 * single-precision, one quarter of double-precision
821 *
822 * This automatically reduces the size of encoded CBOR, maybe even by
823 * four if most of values are 0, infinity or NaN.
824 *
825 * When decoded, QCBOR will usually return these values as
826 * double-precision.
827 *
828 * It is possible to disable this preferred serialization when compiling
829 * QCBOR. In that case, this functions the same as
830 * QCBOREncode_AddDoubleNoPreferred().
831 *
832 * Error handling is the same as QCBOREncode_AddInt64().
833 *
834 * See also QCBOREncode_AddDoubleNoPreferred(), QCBOREncode_AddFloat()
835 * and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -0800836 *
837 * By default, this will error out on an attempt to encode a NaN with
838 * a payload. See QCBOREncode_Allow() and @ref QCBOR_ENCODE_ALLOW_NAN_PAYLOAD.
Michael Eckel5c531332020-03-02 01:35:30 +0100839 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700840void
841QCBOREncode_AddDouble(QCBOREncodeContext *pCtx, double dNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100842
Laurence Lundblade3eead482023-12-16 20:53:22 -0700843static void
844QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100845
Laurence Lundblade3eead482023-12-16 20:53:22 -0700846static void
847QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100848
849
850/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700851 * @brief Add a single-precision floating-point number to the encoded output.
852 *
853 * @param[in] pCtx The encoding context to add the double to.
854 * @param[in] fNum The single-precision number to add.
855 *
856 * This is identical to QCBOREncode_AddDouble() except the input is
857 * single-precision.
858 *
859 * See also QCBOREncode_AddDouble(), QCBOREncode_AddDoubleNoPreferred(),
860 * and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
861 */
862void
863QCBOREncode_AddFloat(QCBOREncodeContext *pCtx, float fNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700864
Laurence Lundblade3eead482023-12-16 20:53:22 -0700865static void
866QCBOREncode_AddFloatToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700867
Laurence Lundblade3eead482023-12-16 20:53:22 -0700868static void
869QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700870
871
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700872/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700873 * @brief Add a double-precision floating-point number without preferred encoding.
874 *
875 * @param[in] pCtx The encoding context to add the double to.
876 * @param[in] dNum The double-precision number to add.
877 *
878 * This always outputs the number as a 64-bit double-precision.
879 * Preferred serialization is not used.
880 *
881 * Error handling is the same as QCBOREncode_AddInt64().
882 *
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -0800883 * By default, this will error out on an attempt to encode a NaN with
884 * a payload. See QCBOREncode_Allow() and @ref QCBOR_ENCODE_ALLOW_NAN_PAYLOAD.
885 *
Laurence Lundblade3eead482023-12-16 20:53:22 -0700886 * See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
887 * QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
888 */
889void
890QCBOREncode_AddDoubleNoPreferred(QCBOREncodeContext *pCtx, double dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700891
Laurence Lundblade3eead482023-12-16 20:53:22 -0700892static void
893QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700894
Laurence Lundblade3eead482023-12-16 20:53:22 -0700895static void
896QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700897
898
899/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700900 * @brief Add a single-precision floating-point number without preferred encoding.
901 *
902 * @param[in] pCtx The encoding context to add the double to.
903 * @param[in] fNum The single-precision number to add.
904 *
905 * This always outputs the number as a 32-bit single-precision.
906 * Preferred serialization is not used.
907 *
908 * Error handling is the same as QCBOREncode_AddInt64().
909 *
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -0800910 * By default, this will error out on an attempt to encode a NaN with
911 * a payload. See QCBOREncode_Allow() and @ref QCBOR_ENCODE_ALLOW_NAN_PAYLOAD.
912 *
Laurence Lundblade3eead482023-12-16 20:53:22 -0700913 * See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
914 * QCBOREncode_AddDoubleNoPreferred() and @ref Floating-Point.
915 */
916void
917QCBOREncode_AddFloatNoPreferred(QCBOREncodeContext *pCtx, float fNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700918
Laurence Lundblade3eead482023-12-16 20:53:22 -0700919static void
920QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700921
Laurence Lundblade3eead482023-12-16 20:53:22 -0700922static void
923QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float fNum);
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200924#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700925
926
Michael Eckel5c531332020-03-02 01:35:30 +0100927/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700928 * @brief Add an optional tag.
929 *
930 * @param[in] pCtx The encoding context to add the tag to.
931 * @param[in] uTag The tag to add
932 *
933 * This outputs a CBOR major type 6 item that tags the next data item
934 * that is output usually to indicate it is some new data type.
935 *
936 * For many of the common standard tags, a function to encode data
937 * using it is provided and this is not needed. For example,
938 * QCBOREncode_AddDateEpoch() already exists to output integers
939 * representing dates with the right tag.
940 *
941 * The tag is applied to the next data item added to the encoded
942 * output. That data item that is to be tagged can be of any major
943 * CBOR type. Any number of tags can be added to a data item by
944 * calling this multiple times before the data item is added.
945 *
946 * See @ref Tags-Overview for discussion of creating new non-standard
947 * tags. See QCBORDecode_GetNext() for discussion of decoding custom
948 * tags.
Michael Eckel5c531332020-03-02 01:35:30 +0100949 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700950void
951QCBOREncode_AddTag(QCBOREncodeContext *pCtx, uint64_t uTag);
Laurence Lundblade46d63e92021-05-13 11:37:10 -0700952
953
Michael Eckel5c531332020-03-02 01:35:30 +0100954/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700955 * @brief Add an epoch-based date.
956 *
957 * @param[in] pCtx The encoding context to add the date to.
958 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
959 * @ref QCBOR_ENCODE_AS_BORROWED.
960 * @param[in] nDate Number of seconds since 1970-01-01T00:00Z
961 * in UTC time.
962 *
963 * As per RFC 8949 this is similar to UNIX/Linux/POSIX dates. This is
964 * the most compact way to specify a date and time in CBOR. Note that
965 * this is always UTC and does not include the time zone. Use
966 * QCBOREncode_AddDateString() if you want to include the time zone.
967 *
968 * The preferred integer serialization rules apply here so the date will be
969 * encoded in a minimal number of bytes. Until about the year 2106
970 * these dates will encode in 6 bytes -- one byte for the tag, one
971 * byte for the type and 4 bytes for the integer. After that it will
972 * encode to 10 bytes.
973 *
974 * Negative values are supported for dates before 1970.
975 *
976 * If you care about leap-seconds and that level of accuracy, make sure
977 * the system you are running this code on does it correctly. This code
978 * just takes the value passed in.
979 *
980 * This implementation cannot encode fractional seconds using float or
981 * double even though that is allowed by CBOR, but you can encode them
982 * if you want to by calling QCBOREncode_AddTag() and QCBOREncode_AddDouble().
983 *
984 * Error handling is the same as QCBOREncode_AddInt64().
985 *
986 * See also QCBOREncode_AddTDaysEpoch().
Michael Eckel5c531332020-03-02 01:35:30 +0100987 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700988static void
989QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pCtx,
990 uint8_t uTagRequirement,
991 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100992
Laurence Lundblade3eead482023-12-16 20:53:22 -0700993static void
994QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pCtx,
995 const char *szLabel,
996 uint8_t uTagRequirement,
997 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100998
Laurence Lundblade3eead482023-12-16 20:53:22 -0700999static void
1000QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pCtx,
1001 int64_t nLabel,
1002 uint8_t uTagRequirement,
1003 int64_t nDate);
1004
1005
1006static void
1007QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx,
1008 int64_t nDate);
1009
1010static void
1011QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx,
1012 const char *szLabel,
1013 int64_t nDate);
1014
1015static void
1016QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx,
1017 int64_t nLabel,
1018 int64_t nDate);
1019
Michael Eckel5c531332020-03-02 01:35:30 +01001020
1021
Michael Eckel5c531332020-03-02 01:35:30 +01001022/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001023 * @brief Add an epoch-based day-count date.
1024 *
1025 * @param[in] pCtx The encoding context to add the date to.
1026 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1027 * @ref QCBOR_ENCODE_AS_BORROWED.
1028 * @param[in] nDays Number of days before or after 1970-01-0.
1029 *
1030 * This date format is described in
1031 * [RFC 8943] (https://tools.ietf.org/html/rfc8943).
1032 *
1033 * The preferred integer serialization rules apply here so the date
1034 * will be encoded in a minimal number of bytes. Until about the year
1035 * 2149 these dates will encode in 4 bytes -- one byte for the tag,
1036 * one byte for the type and 2 bytes for the integer.
1037 *
1038 * See also QCBOREncode_AddTDateEpoch().
1039 */
1040static void
1041QCBOREncode_AddTDaysEpoch(QCBOREncodeContext *pCtx,
1042 uint8_t uTagRequirement,
1043 int64_t nDays);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001044
Laurence Lundblade3eead482023-12-16 20:53:22 -07001045static void
1046QCBOREncode_AddTDaysEpochToMapSZ(QCBOREncodeContext *pCtx,
1047 const char *szLabel,
1048 uint8_t uTagRequirement,
1049 int64_t nDays);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001050
Laurence Lundblade3eead482023-12-16 20:53:22 -07001051static void
1052QCBOREncode_AddTDaysEpochToMapN(QCBOREncodeContext *pCtx,
1053 int64_t nLabel,
1054 uint8_t uTagRequirement,
1055 int64_t nDays);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001056
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001057
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001058
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001059
Laurence Lundblade3eead482023-12-16 20:53:22 -07001060/**
1061 * @brief Add a byte string to the encoded output.
1062 *
1063 * @param[in] pCtx The encoding context to add the bytes to.
1064 * @param[in] Bytes Pointer and length of the input data.
1065 *
1066 * Simply adds the bytes to the encoded output as CBOR major type 2.
1067 *
1068 * If called with @c Bytes.len equal to 0, an empty string will be
1069 * added. When @c Bytes.len is 0, @c Bytes.ptr may be @c NULL.
1070 *
1071 * Error handling is the same as QCBOREncode_AddInt64().
1072 */
1073static void
1074QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001075
Laurence Lundblade3eead482023-12-16 20:53:22 -07001076static void
1077QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
1078
1079static void
1080QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
1081
1082
1083/**
1084 * @brief Set up to write a byte string value directly to encoded output.
1085 *
1086 * @param[in] pCtx The encoding context to add the bytes to.
1087 * @param[out] pPlace Pointer and length of place to write byte string value.
1088 *
1089 * QCBOREncode_AddBytes() is the normal way to encode a byte string.
1090 * This is for special cases and by passes some of the pointer safety.
1091 *
1092 * The purpose of this is to output the bytes that make up a byte
1093 * string value directly to the QCBOR output buffer so you don't need
1094 * to have a copy of it in memory. This is particularly useful if the
1095 * byte string is large, for example, the encrypted payload of a
1096 * COSE_Encrypt message. The payload encryption algorithm can output
1097 * directly to the encoded CBOR buffer, perhaps by making it the
1098 * output buffer for some function (e.g. symmetric encryption) or by
1099 * multiple writes.
1100 *
1101 * The pointer in @c pPlace is where to start writing. Writing is just
1102 * copying bytes to the location by the pointer in \c pPlace. Writing
1103 * past the length in @c pPlace will be writing off the end of the
1104 * output buffer.
1105 *
1106 * If there is no room in the output buffer @ref NULLUsefulBuf will be
1107 * returned and there is no need to call QCBOREncode_CloseBytes().
1108 *
1109 * The byte string must be closed by calling QCBOREncode_CloseBytes().
1110 *
1111 * Warning: this bypasses some of the usual checks provided by QCBOR
1112 * against writing off the end of the encoded output buffer.
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001113 */
1114void
1115QCBOREncode_OpenBytes(QCBOREncodeContext *pCtx, UsefulBuf *pPlace);
1116
1117static void
Laurence Lundblade3eead482023-12-16 20:53:22 -07001118QCBOREncode_OpenBytesInMapSZ(QCBOREncodeContext *pCtx,
1119 const char *szLabel,
1120 UsefulBuf *pPlace);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001121
1122static void
Laurence Lundblade3eead482023-12-16 20:53:22 -07001123QCBOREncode_OpenBytesInMapN(QCBOREncodeContext *pCtx,
1124 int64_t nLabel,
1125 UsefulBuf *pPlace);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001126
1127
1128/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001129 * @brief Close out a byte string written directly to encoded output.
1130 *
1131 * @param[in] pCtx The encoding context to add the bytes to.
1132 * @param[out] uAmount The number of bytes written, the length of the
1133 * byte string.
1134 *
1135 * This closes out a call to QCBOREncode_OpenBytes(). This inserts a
1136 * CBOR header at the front of the byte string value to make it a
1137 * well-formed byte string.
1138 *
1139 * If there was no call to QCBOREncode_OpenBytes() then @ref
1140 * QCBOR_ERR_TOO_MANY_CLOSES is set.
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001141 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001142void
1143QCBOREncode_CloseBytes(QCBOREncodeContext *pCtx, size_t uAmount);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001144
1145
1146/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001147 * @brief Add a binary UUID to the encoded output.
1148 *
1149 * @param[in] pCtx The encoding context to add the UUID to.
1150 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1151 * @ref QCBOR_ENCODE_AS_BORROWED.
1152 * @param[in] Bytes Pointer and length of the binary UUID.
1153 *
1154 * A binary UUID as defined in [RFC 4122]
1155 * (https://tools.ietf.org/html/rfc4122) is added to the output.
1156 *
1157 * It is output as CBOR major type 2, a binary string, with tag @ref
1158 * CBOR_TAG_BIN_UUID indicating the binary string is a UUID.
Michael Eckel5c531332020-03-02 01:35:30 +01001159 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001160static void
1161QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pCtx,
1162 uint8_t uTagRequirement,
1163 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001164
Laurence Lundblade3eead482023-12-16 20:53:22 -07001165static void
1166QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pCtx,
1167 const char *szLabel,
1168 uint8_t uTagRequirement,
1169 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001170
Laurence Lundblade3eead482023-12-16 20:53:22 -07001171static void
1172QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pCtx,
1173 int64_t nLabel,
1174 uint8_t uTagRequirement,
1175 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001176
1177
Laurence Lundblade3eead482023-12-16 20:53:22 -07001178static void
1179QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001180
Laurence Lundblade3eead482023-12-16 20:53:22 -07001181static void
1182QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001183
Laurence Lundblade3eead482023-12-16 20:53:22 -07001184static void
1185QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001186
1187
1188/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001189 * @brief Add a positive big number to the encoded output.
1190 *
1191 * @param[in] pCtx The encoding context to add the big number to.
1192 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1193 * @ref QCBOR_ENCODE_AS_BORROWED.
1194 * @param[in] Bytes Pointer and length of the big number.
1195 *
1196 * Big numbers are integers larger than 64-bits. Their format is
1197 * described in [RFC 8949] (https://tools.ietf.org/html/rfc8949).
1198 *
1199 * It is output as CBOR major type 2, a binary string, with tag
1200 * @ref CBOR_TAG_POS_BIGNUM indicating the binary string is a positive
1201 * big number.
1202 *
1203 * Often big numbers are used to represent cryptographic keys,
1204 * however, COSE which defines representations for keys chose not to
1205 * use this particular type.
Michael Eckel5c531332020-03-02 01:35:30 +01001206 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001207static void
1208QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pCtx,
1209 uint8_t uTagRequirement,
1210 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001211
Laurence Lundblade3eead482023-12-16 20:53:22 -07001212static void
1213QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pCtx,
1214 const char *szLabel,
1215 uint8_t uTagRequirement,
1216 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001217
Laurence Lundblade3eead482023-12-16 20:53:22 -07001218static void
1219QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pCtx,
1220 int64_t nLabel,
1221 uint8_t uTagRequirement,
1222 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001223
1224
Laurence Lundblade3eead482023-12-16 20:53:22 -07001225static void
1226QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx,
1227 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001228
Laurence Lundblade3eead482023-12-16 20:53:22 -07001229static void
1230QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx,
1231 const char *szLabel,
1232 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001233
Laurence Lundblade3eead482023-12-16 20:53:22 -07001234static void
1235QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx,
1236 int64_t nLabel,
1237 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001238
1239
1240/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001241 * @brief Add a negative big number to the encoded output.
1242 *
1243 * @param[in] pCtx The encoding context to add the big number to.
1244 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1245 * @ref QCBOR_ENCODE_AS_BORROWED.
1246 * @param[in] Bytes Pointer and length of the big number.
1247 *
1248 * Big numbers are integers larger than 64-bits. Their format is
1249 * described in [RFC 8949] (https://tools.ietf.org/html/rfc8949).
1250 *
1251 * It is output as CBOR major type 2, a binary string, with tag
1252 * @ref CBOR_TAG_NEG_BIGNUM indicating the binary string is a negative
1253 * big number.
1254 *
1255 * Often big numbers are used to represent cryptographic keys,
1256 * however, COSE which defines representations for keys chose not to
1257 * use this particular type.
Michael Eckel5c531332020-03-02 01:35:30 +01001258 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001259static void
1260QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pCtx,
1261 uint8_t uTagRequirement,
1262 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001263
Laurence Lundblade3eead482023-12-16 20:53:22 -07001264static void
1265QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pCtx,
1266 const char *szLabel,
1267 uint8_t uTagRequirement,
1268 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001269
Laurence Lundblade3eead482023-12-16 20:53:22 -07001270static void
1271QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pCtx,
1272 int64_t nLabel,
1273 uint8_t uTagRequirement,
1274 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001275
1276
Laurence Lundblade3eead482023-12-16 20:53:22 -07001277static void
1278QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx,
1279 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001280
Laurence Lundblade3eead482023-12-16 20:53:22 -07001281static void
1282QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx,
1283 const char *szLabel,
1284 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001285
Laurence Lundblade3eead482023-12-16 20:53:22 -07001286static void
1287QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx,
1288 int64_t nLabel,
1289 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001290
1291
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07001292#ifndef QCBOR_DISABLE_EXP_AND_MANTISSA
Michael Eckel5c531332020-03-02 01:35:30 +01001293/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001294 * @brief Add a decimal fraction to the encoded output.
1295 *
1296 * @param[in] pCtx Encoding context to add the decimal fraction to.
1297 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1298 * @ref QCBOR_ENCODE_AS_BORROWED.
1299 * @param[in] nMantissa The mantissa.
1300 * @param[in] nBase10Exponent The exponent.
1301 *
1302 * The value is nMantissa * 10 ^ nBase10Exponent.
1303 *
1304 * A decimal fraction is good for exact representation of some values
1305 * that can't be represented exactly with standard C (IEEE 754)
1306 * floating-point numbers. Much larger and much smaller numbers can
1307 * also be represented than floating-point because of the larger
1308 * number of bits in the exponent.
1309 *
1310 * The decimal fraction is conveyed as two integers, a mantissa and a
1311 * base-10 scaling factor.
1312 *
1313 * For example, 273.15 is represented by the two integers 27315 and -2.
1314 *
1315 * The exponent and mantissa have the range from @c INT64_MIN to
1316 * @c INT64_MAX for both encoding and decoding (CBOR allows
1317 * @c -UINT64_MAX to @c UINT64_MAX, but this implementation doesn't
1318 * support this range to reduce code size and interface complexity a
1319 * little).
1320 *
1321 * CBOR Preferred serialization of the integers is used, thus they
1322 * will be encoded in the smallest number of bytes possible.
1323 *
1324 * See also QCBOREncode_AddDecimalFractionBigNum() for a decimal
1325 * fraction with arbitrarily large precision and
1326 * QCBOREncode_AddBigFloat().
1327 *
1328 * There is no representation of positive or negative infinity or NaN
1329 * (Not a Number). Use QCBOREncode_AddDouble() to encode them.
1330 *
1331 * See @ref expAndMantissa for decoded representation.
Michael Eckel5c531332020-03-02 01:35:30 +01001332 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001333static void
1334QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pCtx,
1335 uint8_t uTagRequirement,
1336 int64_t nMantissa,
1337 int64_t nBase10Exponent);
1338
1339static void
1340QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pCtx,
1341 const char *szLabel,
1342 uint8_t uTagRequirement,
1343 int64_t nMantissa,
1344 int64_t nBase10Exponent);
1345
1346static void
1347QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pCtx,
1348 int64_t nLabel,
1349 uint8_t uTagRequirement,
1350 int64_t nMantissa,
1351 int64_t nBase10Exponent);
1352
1353
1354static void
1355QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pCtx,
1356 int64_t nMantissa,
1357 int64_t nBase10Exponent);
1358
1359static void
1360QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pCtx,
1361 const char *szLabel,
1362 int64_t nMantissa,
1363 int64_t nBase10Exponent);
1364
1365static void
1366QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pCtx,
1367 int64_t nLabel,
1368 int64_t nMantissa,
1369 int64_t nBase10Exponent);
1370
1371
1372/**
1373 * @brief Add a decimal fraction with a big number mantissa to the encoded output.
1374 *
1375 * @param[in] pCtx Encoding context to add the decimal fraction to.
1376 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1377 * @ref QCBOR_ENCODE_AS_BORROWED.
1378 * @param[in] Mantissa The mantissa.
1379 * @param[in] bIsNegative false if mantissa is positive, true if negative.
1380 * @param[in] nBase10Exponent The exponent.
1381 *
1382 * This is the same as QCBOREncode_AddDecimalFraction() except the
1383 * mantissa is a big number (See QCBOREncode_AddPositiveBignum())
1384 * allowing for arbitrarily large precision.
1385 *
1386 * See @ref expAndMantissa for decoded representation.
1387 */
1388static void
1389QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pCtx,
1390 uint8_t uTagRequirement,
1391 UsefulBufC Mantissa,
1392 bool bIsNegative,
1393 int64_t nBase10Exponent);
1394
1395static void
1396QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
1397 const char *szLabel,
1398 uint8_t uTagRequirement,
1399 UsefulBufC Mantissa,
1400 bool bIsNegative,
1401 int64_t nBase10Exponent);
1402
1403static void
1404QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
1405 int64_t nLabel,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001406 uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07001407 UsefulBufC Mantissa,
1408 bool bIsNegative,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001409 int64_t nBase10Exponent);
1410
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001411
Laurence Lundblade3eead482023-12-16 20:53:22 -07001412static void
1413QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pCtx,
1414 UsefulBufC Mantissa,
1415 bool bIsNegative,
1416 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001417
Laurence Lundblade3eead482023-12-16 20:53:22 -07001418static void
1419QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001420 const char *szLabel,
Laurence Lundblade3eead482023-12-16 20:53:22 -07001421 UsefulBufC Mantissa,
1422 bool bIsNegative,
1423 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001424
Laurence Lundblade3eead482023-12-16 20:53:22 -07001425static void
1426QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001427 int64_t nLabel,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001428 UsefulBufC Mantissa,
1429 bool bIsNegative,
Laurence Lundblade3eead482023-12-16 20:53:22 -07001430 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001431
Laurence Lundblade3eead482023-12-16 20:53:22 -07001432/**
1433 * @brief Add a big floating-point number to the encoded output.
1434 *
1435 * @param[in] pCtx The encoding context to add the bigfloat to.
1436 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1437 * @ref QCBOR_ENCODE_AS_BORROWED.
1438 * @param[in] nMantissa The mantissa.
1439 * @param[in] nBase2Exponent The exponent.
1440 *
1441 * The value is nMantissa * 2 ^ nBase2Exponent.
1442 *
1443 * "Bigfloats", as CBOR terms them, are similar to IEEE floating-point
1444 * numbers in having a mantissa and base-2 exponent, but they are not
1445 * supported by hardware or encoded the same. They explicitly use two
1446 * CBOR-encoded integers to convey the mantissa and exponent, each of
1447 * which can be 8, 16, 32 or 64 bits. With both the mantissa and
1448 * exponent 64 bits they can express more precision and a larger range
1449 * than an IEEE double floating-point number. See
1450 * QCBOREncode_AddBigFloatBigNum() for even more precision.
1451 *
1452 * For example, 1.5 would be represented by a mantissa of 3 and an
1453 * exponent of -1.
1454 *
1455 * The exponent and mantissa have the range from @c INT64_MIN to
1456 * @c INT64_MAX for both encoding and decoding (CBOR allows @c
1457 * -UINT64_MAX to @c UINT64_MAX, but this implementation doesn't
1458 * support this range to reduce code size and interface complexity a
1459 * little).
1460 *
1461 * CBOR preferred serialization of the integers is used, thus they will
1462 * be encoded in the smallest number of bytes possible.
1463 *
1464 * This can also be used to represent floating-point numbers in
1465 * environments that don't support IEEE 754.
1466 *
1467 * See @ref expAndMantissa for decoded representation.
1468 */
1469static void
1470QCBOREncode_AddTBigFloat(QCBOREncodeContext *pCtx,
1471 uint8_t uTagRequirement,
1472 int64_t nMantissa,
1473 int64_t nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001474
Laurence Lundblade3eead482023-12-16 20:53:22 -07001475static void
1476QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pCtx,
1477 const char *szLabel,
1478 uint8_t uTagRequirement,
1479 int64_t nMantissa,
1480 int64_t nBase2Exponent);
1481
1482static void
1483QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pCtx,
1484 int64_t nLabel,
1485 uint8_t uTagRequirement,
1486 int64_t nMantissa,
1487 int64_t nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001488
1489
Laurence Lundblade3eead482023-12-16 20:53:22 -07001490static void
1491QCBOREncode_AddBigFloat(QCBOREncodeContext *pCtx,
1492 int64_t nMantissa,
1493 int64_t nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01001494
Laurence Lundblade3eead482023-12-16 20:53:22 -07001495static void
1496QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pCtx,
1497 const char *szLabel,
1498 int64_t nMantissa,
1499 int64_t nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01001500
Laurence Lundblade3eead482023-12-16 20:53:22 -07001501static void
1502QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pCtx,
1503 int64_t nLabel,
1504 int64_t nMantissa,
1505 int64_t nBase2Exponent);
1506
1507/**
1508 * @brief Add a big floating-point number with a big number mantissa to
1509 * the encoded output.
1510 *
1511 * @param[in] pCtx The encoding context to add the bigfloat to.
1512 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1513 * @ref QCBOR_ENCODE_AS_BORROWED.
1514 * @param[in] Mantissa The mantissa.
1515 * @param[in] bIsNegative false if mantissa is positive, true if negative.
1516 * @param[in] nBase2Exponent The exponent.
1517 *
1518 * This is the same as QCBOREncode_AddBigFloat() except the mantissa
1519 * is a big number (See QCBOREncode_AddPositiveBignum()) allowing for
1520 * arbitrary precision.
1521 *
1522 * See @ref expAndMantissa for decoded representation.
1523 */
1524static void
1525QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pCtx,
1526 uint8_t uTagRequirement,
1527 UsefulBufC Mantissa,
1528 bool bIsNegative,
1529 int64_t nBase2Exponent);
1530
1531static void
1532QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pCtx,
1533 const char *szLabel,
1534 uint8_t uTagRequirement,
1535 UsefulBufC Mantissa,
1536 bool bIsNegative,
1537 int64_t nBase2Exponent);
1538
1539static void
1540QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1541 int64_t nLabel,
1542 uint8_t uTagRequirement,
1543 UsefulBufC Mantissa,
1544 bool bIsNegative,
1545 int64_t nBase2Exponent);
1546
1547
1548static void
1549QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pCtx,
1550 UsefulBufC Mantissa,
1551 bool bIsNegative,
1552 int64_t nBase2Exponent);
1553
1554static void
1555QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pCtx,
1556 const char *szLabel,
1557 UsefulBufC Mantissa,
1558 bool bIsNegative,
1559 int64_t nBase2Exponent);
1560
1561static void
1562QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1563 int64_t nLabel,
1564 UsefulBufC Mantissa,
1565 bool bIsNegative,
1566 int64_t nBase2Exponent);
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07001567#endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
Michael Eckel5c531332020-03-02 01:35:30 +01001568
1569
1570/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001571 * @brief Add a text URI to the encoded output.
1572 *
1573 * @param[in] pCtx The encoding context to add the URI to.
1574 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1575 * @ref QCBOR_ENCODE_AS_BORROWED.
1576 * @param[in] URI Pointer and length of the URI.
1577 *
1578 * The format of URI must be per [RFC 3986]
1579 * (https://tools.ietf.org/html/rfc3986).
1580 *
1581 * It is output as CBOR major type 3, a text string, with tag @ref
1582 * CBOR_TAG_URI indicating the text string is a URI.
1583 *
1584 * A URI in a NULL-terminated string, @c szURI, can be easily added with
1585 * this code:
1586 *
1587 * QCBOREncode_AddURI(pCtx, UsefulBuf_FromSZ(szURI));
Michael Eckel5c531332020-03-02 01:35:30 +01001588 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001589static void
1590QCBOREncode_AddTURI(QCBOREncodeContext *pCtx,
1591 uint8_t uTagRequirement,
1592 UsefulBufC URI);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001593
Laurence Lundblade3eead482023-12-16 20:53:22 -07001594static void
1595QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pCtx,
1596 const char *szLabel,
1597 uint8_t uTagRequirement,
1598 UsefulBufC URI);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001599
Laurence Lundblade3eead482023-12-16 20:53:22 -07001600static void
1601QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pCtx,
1602 int64_t nLabel,
1603 uint8_t uTagRequirement,
1604 UsefulBufC URI);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001605
1606
Laurence Lundblade3eead482023-12-16 20:53:22 -07001607static void
1608QCBOREncode_AddURI(QCBOREncodeContext *pCtx,
1609 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001610
Laurence Lundblade3eead482023-12-16 20:53:22 -07001611static void
1612QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx,
1613 const char *szLabel,
1614 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001615
Laurence Lundblade3eead482023-12-16 20:53:22 -07001616static void
1617QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx,
1618 int64_t nLabel,
1619 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001620
1621
1622/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001623 * @brief Add Base64-encoded text to encoded output.
1624 *
1625 * @param[in] pCtx The encoding context to add the base-64 text to.
1626 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1627 * @ref QCBOR_ENCODE_AS_BORROWED.
1628 * @param[in] B64Text Pointer and length of the base-64 encoded text.
1629 *
1630 * The text content is Base64 encoded data per [RFC 4648]
1631 * (https://tools.ietf.org/html/rfc4648).
1632 *
1633 * It is output as CBOR major type 3, a text string, with tag @ref
1634 * CBOR_TAG_B64 indicating the text string is Base64 encoded.
Michael Eckel5c531332020-03-02 01:35:30 +01001635 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001636static void
1637QCBOREncode_AddTB64Text(QCBOREncodeContext *pCtx,
1638 uint8_t uTagRequirement,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001639 UsefulBufC B64Text);
1640
Laurence Lundblade3eead482023-12-16 20:53:22 -07001641static void
1642QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pCtx,
1643 const char *szLabel,
1644 uint8_t uTagRequirement,
1645 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001646
Laurence Lundblade3eead482023-12-16 20:53:22 -07001647static void
1648QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pCtx,
1649 int64_t nLabel,
1650 uint8_t uTagRequirement,
1651 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001652
1653
Laurence Lundblade3eead482023-12-16 20:53:22 -07001654static void
1655QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx,
1656 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001657
Laurence Lundblade3eead482023-12-16 20:53:22 -07001658static void
1659QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx,
1660 const char *szLabel,
1661 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001662
Laurence Lundblade3eead482023-12-16 20:53:22 -07001663static void
1664QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx,
1665 int64_t nLabel,
1666 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001667
1668
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001669
Michael Eckel5c531332020-03-02 01:35:30 +01001670/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001671 * @brief Add base64url encoded data to encoded output.
1672 *
1673 * @param[in] pCtx The encoding context to add the base64url to.
1674 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1675 * @ref QCBOR_ENCODE_AS_BORROWED.
1676 * @param[in] B64Text Pointer and length of the base64url encoded text.
1677 *
1678 * The text content is base64URL encoded text as per [RFC 4648]
1679 * (https://tools.ietf.org/html/rfc4648).
1680 *
1681 * It is output as CBOR major type 3, a text string, with tag
1682 * @ref CBOR_TAG_B64URL indicating the text string is a Base64url
1683 * encoded.
Michael Eckel5c531332020-03-02 01:35:30 +01001684 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001685static void
1686QCBOREncode_AddTB64URLText(QCBOREncodeContext *pCtx,
1687 uint8_t uTagRequirement,
1688 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001689
Laurence Lundblade3eead482023-12-16 20:53:22 -07001690static void
1691QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pCtx,
1692 const char *szLabel,
1693 uint8_t uTagRequirement,
1694 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001695
Laurence Lundblade3eead482023-12-16 20:53:22 -07001696static void
1697QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pCtx,
1698 int64_t nLabel,
1699 uint8_t uTagRequirement,
1700 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001701
1702
Laurence Lundblade3eead482023-12-16 20:53:22 -07001703static void
1704QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx,
1705 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001706
Laurence Lundblade3eead482023-12-16 20:53:22 -07001707static void
1708QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx,
1709 const char *szLabel,
1710 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001711
Laurence Lundblade3eead482023-12-16 20:53:22 -07001712static void
1713QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx,
1714 int64_t nLabel,
1715 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001716
1717
1718/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001719 * @brief Add Perl Compatible Regular Expression.
1720 *
1721 * @param[in] pCtx Encoding context to add the regular expression to.
1722 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1723 * @ref QCBOR_ENCODE_AS_BORROWED.
1724 * @param[in] Regex Pointer and length of the regular expression.
1725 *
1726 * The text content is Perl Compatible Regular
1727 * Expressions (PCRE) / JavaScript syntax [ECMA262].
1728 *
1729 * It is output as CBOR major type 3, a text string, with tag @ref
1730 * CBOR_TAG_REGEX indicating the text string is a regular expression.
Michael Eckel5c531332020-03-02 01:35:30 +01001731 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001732static void
1733QCBOREncode_AddTRegex(QCBOREncodeContext *pCtx,
1734 uint8_t uTagRequirement,
1735 UsefulBufC Regex);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001736
Laurence Lundblade3eead482023-12-16 20:53:22 -07001737static void
1738QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pCtx,
1739 const char *szLabel,
1740 uint8_t uTagRequirement,
1741 UsefulBufC Regex);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001742
Laurence Lundblade3eead482023-12-16 20:53:22 -07001743static void
1744QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pCtx,
1745 int64_t nLabel,
1746 uint8_t uTagRequirement,
1747 UsefulBufC Regex);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001748
1749
Laurence Lundblade3eead482023-12-16 20:53:22 -07001750static void
1751QCBOREncode_AddRegex(QCBOREncodeContext *pCtx,
1752 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001753
Laurence Lundblade3eead482023-12-16 20:53:22 -07001754static void
1755QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx,
1756 const char *szLabel,
1757 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001758
Laurence Lundblade3eead482023-12-16 20:53:22 -07001759static void
1760QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx,
1761 int64_t nLabel,
1762 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001763
1764
1765/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001766 * @brief MIME encoded data to the encoded output.
1767 *
1768 * @param[in] pCtx The encoding context to add the MIME data to.
1769 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1770 * @ref QCBOR_ENCODE_AS_BORROWED.
1771 * @param[in] MIMEData Pointer and length of the MIME data.
1772 *
1773 * The text content is in MIME format per [RFC 2045]
1774 * (https://tools.ietf.org/html/rfc2045) including the headers.
1775 *
1776 * It is output as CBOR major type 2, a binary string, with tag
1777 * @ref CBOR_TAG_BINARY_MIME indicating the string is MIME data. This
1778 * outputs tag 257, not tag 36, as it can carry any type of MIME
1779 * binary, 7-bit, 8-bit, quoted-printable and base64 where tag 36
1780 * cannot.
1781 *
1782 * Previous versions of QCBOR, those before spiffy decode, output tag
1783 * 36. Decoding supports both tag 36 and 257. (if the old behavior
1784 * with tag 36 is needed, copy the inline functions below and change
1785 * the tag number).
1786 *
1787 * See also QCBORDecode_GetMIMEMessage() and
1788 * @ref QCBOR_TYPE_BINARY_MIME.
1789 *
1790 * This does no translation of line endings. See QCBOREncode_AddText()
1791 * for a discussion of line endings in CBOR.
Michael Eckel5c531332020-03-02 01:35:30 +01001792 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001793static void
1794QCBOREncode_AddTMIMEData(QCBOREncodeContext *pCtx,
1795 uint8_t uTagRequirement,
1796 UsefulBufC MIMEData);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001797
Laurence Lundblade3eead482023-12-16 20:53:22 -07001798static void
1799QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pCtx,
1800 const char *szLabel,
1801 uint8_t uTagRequirement,
1802 UsefulBufC MIMEData);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001803
Laurence Lundblade3eead482023-12-16 20:53:22 -07001804static void
1805QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pCtx,
1806 int64_t nLabel,
1807 uint8_t uTagRequirement,
1808 UsefulBufC MIMEData);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001809
1810
Laurence Lundblade3eead482023-12-16 20:53:22 -07001811static void
1812QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx,
1813 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001814
Laurence Lundblade3eead482023-12-16 20:53:22 -07001815static void
1816QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx,
1817 const char *szLabel,
1818 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001819
Laurence Lundblade3eead482023-12-16 20:53:22 -07001820static void
1821QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx,
1822 int64_t nLabel,
1823 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001824
1825
1826/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001827 * @brief Add an RFC 3339 date string
1828 *
1829 * @param[in] pCtx The encoding context to add the date to.
1830 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1831 * @ref QCBOR_ENCODE_AS_BORROWED.
1832 * @param[in] szDate Null-terminated string with date to add.
1833 *
1834 * The string szDate should be in the form of [RFC 3339]
1835 * (https://tools.ietf.org/html/rfc3339) as defined by section 3.3 in
1836 * [RFC 4287] (https://tools.ietf.org/html/rfc4287). This is as
1837 * described in section 3.4.1 in [RFC 8949]
1838 * (https://tools.ietf.org/html/rfc8949).
1839 *
1840 * Note that this function doesn't validate the format of the date
1841 * string at all. If you add an incorrect format date string, the
1842 * generated CBOR will be incorrect and the receiver may not be able
1843 * to handle it.
1844 *
1845 * Error handling is the same as QCBOREncode_AddInt64().
1846 *
1847 * See also QCBOREncode_AddTDayString().
Michael Eckel5c531332020-03-02 01:35:30 +01001848 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001849static void
1850QCBOREncode_AddTDateString(QCBOREncodeContext *pCtx,
1851 uint8_t uTagRequirement,
1852 const char *szDate);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001853
Laurence Lundblade3eead482023-12-16 20:53:22 -07001854static void
1855QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pCtx,
1856 const char *szLabel,
1857 uint8_t uTagRequirement,
1858 const char *szDate);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001859
Laurence Lundblade3eead482023-12-16 20:53:22 -07001860static void
1861QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pCtx,
1862 int64_t nLabel,
1863 uint8_t uTagRequirement,
1864 const char *szDate);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001865
1866
Laurence Lundblade3eead482023-12-16 20:53:22 -07001867static void
1868QCBOREncode_AddDateString(QCBOREncodeContext *pCtx,
1869 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001870
Laurence Lundblade3eead482023-12-16 20:53:22 -07001871static void
1872QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx,
1873 const char *szLabel,
1874 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001875
Laurence Lundblade3eead482023-12-16 20:53:22 -07001876static void
1877QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx,
1878 int64_t nLabel,
1879 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001880
Laurence Lundblade46d63e92021-05-13 11:37:10 -07001881
1882/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001883 * @brief Add a date-only string.
1884 *
1885 * @param[in] pCtx The encoding context to add the date to.
1886 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1887 * @ref QCBOR_ENCODE_AS_BORROWED.
1888 * @param[in] szDate Null-terminated string with date to add.
1889 *
1890 * This date format is described in
1891 * [RFC 8943] (https://tools.ietf.org/html/rfc8943), but that mainly
1892 * references RFC 3339. The string szDate must be in the forrm
1893 * specified the ABNF for a full-date in
1894 * [RFC 3339] (https://tools.ietf.org/html/rfc3339). Examples of this
1895 * are "1985-04-12" and "1937-01-01". The time and the time zone are
1896 * never included.
1897 *
1898 * Note that this function doesn't validate the format of the date
1899 * string at all. If you add an incorrect format date string, the
1900 * generated CBOR will be incorrect and the receiver may not be able
1901 * to handle it.
1902 *
1903 * Error handling is the same as QCBOREncode_AddInt64().
1904 *
1905 * See also QCBOREncode_AddTDateString().
Laurence Lundblade46d63e92021-05-13 11:37:10 -07001906 */
1907static void
1908QCBOREncode_AddTDaysString(QCBOREncodeContext *pCtx,
1909 uint8_t uTagRequirement,
1910 const char *szDate);
1911
1912static void
1913QCBOREncode_AddTDaysStringToMapSZ(QCBOREncodeContext *pCtx,
1914 const char *szLabel,
1915 uint8_t uTagRequirement,
1916 const char *szDate);
1917
1918static void
1919QCBOREncode_AddTDaysStringToMapN(QCBOREncodeContext *pCtx,
1920 int64_t nLabel,
1921 uint8_t uTagRequirement,
1922 const char *szDate);
1923
1924
Michael Eckel5c531332020-03-02 01:35:30 +01001925/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001926 * @brief Add a standard Boolean.
1927 *
1928 * @param[in] pCtx The encoding context to add the Boolean to.
1929 * @param[in] b true or false from @c <stdbool.h>.
1930 *
1931 * Adds a Boolean value as CBOR major type 7.
1932 *
1933 * Error handling is the same as QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +01001934 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001935static void
1936QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b);
Michael Eckel5c531332020-03-02 01:35:30 +01001937
Laurence Lundblade3eead482023-12-16 20:53:22 -07001938static void
1939QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b);
Michael Eckel5c531332020-03-02 01:35:30 +01001940
Laurence Lundblade3eead482023-12-16 20:53:22 -07001941static void
1942QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b);
Michael Eckel5c531332020-03-02 01:35:30 +01001943
1944
1945
1946/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001947 * @brief Add a NULL to the encoded output.
1948 *
1949 * @param[in] pCtx The encoding context to add the NULL to.
1950 *
1951 * Adds the NULL value as CBOR major type 7.
1952 *
1953 * This NULL doesn't have any special meaning in CBOR such as a
1954 * terminating value for a string or an empty value.
1955 *
1956 * Error handling is the same as QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +01001957 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001958static void
1959QCBOREncode_AddNULL(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01001960
Laurence Lundblade3eead482023-12-16 20:53:22 -07001961static void
1962QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001963
Laurence Lundblade3eead482023-12-16 20:53:22 -07001964static void
1965QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001966
1967
1968/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001969 * @brief Add an "undef" to the encoded output.
1970 *
1971 * @param[in] pCtx The encoding context to add the "undef" to.
1972 *
1973 * Adds the undef value as CBOR major type 7.
1974 *
1975 * Note that this value will not translate to JSON.
1976 *
1977 * This Undef doesn't have any special meaning in CBOR such as a
1978 * terminating value for a string or an empty value.
1979 *
1980 * Error handling is the same as QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +01001981 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001982static void
1983QCBOREncode_AddUndef(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01001984
Laurence Lundblade3eead482023-12-16 20:53:22 -07001985static void
1986QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001987
Laurence Lundblade3eead482023-12-16 20:53:22 -07001988static void
1989QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001990
1991
1992/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001993 * @brief Indicates that the next items added are in an array.
1994 *
1995 * @param[in] pCtx The encoding context to open the array in.
1996 *
1997 * Arrays are the basic CBOR aggregate or structure type. Call this
1998 * function to start or open an array. Then call the various
1999 * @c QCBOREncode_AddXxx() functions to add the items that go into the
2000 * array. Then call QCBOREncode_CloseArray() when all items have been
2001 * added. The data items in the array can be of any type and can be of
2002 * mixed types.
2003 *
2004 * Nesting of arrays and maps is allowed and supported just by calling
2005 * QCBOREncode_OpenArray() again before calling
2006 * QCBOREncode_CloseArray(). While CBOR has no limit on nesting, this
2007 * implementation does in order to keep it smaller and simpler. The
2008 * limit is @ref QCBOR_MAX_ARRAY_NESTING. This is the max number of
2009 * times this can be called without calling
2010 * QCBOREncode_CloseArray(). QCBOREncode_Finish() will return
2011 * @ref QCBOR_ERR_ARRAY_NESTING_TOO_DEEP when it is called as this
2012 * function just sets an error state and returns no value when this
2013 * occurs.
2014 *
2015 * If you try to add more than @ref QCBOR_MAX_ITEMS_IN_ARRAY items to
2016 * a single array or map, @ref QCBOR_ERR_ARRAY_TOO_LONG will be
2017 * returned when QCBOREncode_Finish() is called.
2018 *
2019 * An array itself must have a label if it is being added to a map.
2020 * Note that array elements do not have labels (but map elements do).
2021 *
2022 * An array itself may be tagged by calling QCBOREncode_AddTag()
2023 * before this call.
Michael Eckel5c531332020-03-02 01:35:30 +01002024 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002025static void
2026QCBOREncode_OpenArray(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01002027
Laurence Lundblade3eead482023-12-16 20:53:22 -07002028static void
2029QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01002030
Laurence Lundblade3eead482023-12-16 20:53:22 -07002031static void
2032QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01002033
2034
2035/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002036 * @brief Close an open array.
2037 *
2038 * @param[in] pCtx The encoding context to close the array in.
2039 *
2040 * The closes an array opened by QCBOREncode_OpenArray(). It reduces
2041 * nesting level by one. All arrays (and maps) must be closed before
2042 * calling QCBOREncode_Finish().
2043 *
2044 * When an error occurs as a result of this call, the encoder records
2045 * the error and enters the error state. The error will be returned
2046 * when QCBOREncode_Finish() is called.
2047 *
2048 * If this has been called more times than QCBOREncode_OpenArray(), then
2049 * @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when QCBOREncode_Finish()
2050 * is called.
2051 *
2052 * If this is called and it is not an array that is currently open,
2053 * @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
2054 * QCBOREncode_Finish() is called.
Michael Eckel5c531332020-03-02 01:35:30 +01002055 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002056static void
2057QCBOREncode_CloseArray(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01002058
2059
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07002060
2061
Michael Eckel5c531332020-03-02 01:35:30 +01002062/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002063 * @brief Indicates that the next items added are in a map.
2064 *
2065 * @param[in] pCtx The encoding context to open the map in.
2066 *
2067 * See QCBOREncode_OpenArray() for more information, particularly
2068 * error handling.
2069 *
2070 * CBOR maps are an aggregate type where each item in the map consists
2071 * of a label and a value. They are similar to JSON objects.
2072 *
2073 * The value can be any CBOR type including another map.
2074 *
2075 * The label can also be any CBOR type, but in practice they are
2076 * typically, integers as this gives the most compact output. They
2077 * might also be text strings which gives readability and translation
2078 * to JSON.
2079 *
2080 * Every @c QCBOREncode_AddXxx() call has one version that ends with
2081 * @c InMap for adding items to maps with string labels and one that
2082 * ends with @c InMapN that is for adding with integer labels.
2083 *
2084 * RFC 8949 uses the term "key" instead of "label".
2085 *
2086 * If you wish to use map labels that are neither integer labels nor
2087 * text strings, then just call the QCBOREncode_AddXxx() function
2088 * explicitly to add the label. Then call it again to add the value.
2089 *
2090 * See the [RFC 8949] (https://tools.ietf.org/html/rfc8949) for a lot
2091 * more information on creating maps.
Michael Eckel5c531332020-03-02 01:35:30 +01002092 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002093static void
2094QCBOREncode_OpenMap(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01002095
Laurence Lundblade3eead482023-12-16 20:53:22 -07002096static void
2097QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01002098
Laurence Lundblade3eead482023-12-16 20:53:22 -07002099static void
2100QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01002101
2102
Michael Eckel5c531332020-03-02 01:35:30 +01002103/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002104 * @brief Close an open map.
2105 *
2106 * @param[in] pCtx The encoding context to close the map in.
2107 *
2108 * This closes a map opened by QCBOREncode_OpenMap(). It reduces
2109 * nesting level by one.
2110 *
2111 * When an error occurs as a result of this call, the encoder records
2112 * the error and enters the error state. The error will be returned
2113 * when QCBOREncode_Finish() is called.
2114 *
2115 * If this has been called more times than QCBOREncode_OpenMap(), then
2116 * @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
2117 * QCBOREncode_Finish() is called.
2118 *
2119 * If this is called and it is not a map that is currently open,
2120 * @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
2121 * QCBOREncode_Finish() is called.
Michael Eckel5c531332020-03-02 01:35:30 +01002122 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002123static void
2124QCBOREncode_CloseMap(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01002125
2126
2127/**
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07002128 * @brief Indicates that the next items added are in an indefinite length array.
2129 *
2130 * @param[in] pCtx The encoding context to open the array in.
2131 *
2132 * This is the same as QCBOREncode_OpenArray() except the array is
2133 * indefinite length.
2134 *
2135 * This must be closed with QCBOREncode_CloseArrayIndefiniteLength().
2136 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002137static void
2138QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pCtx);
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07002139
Laurence Lundblade3eead482023-12-16 20:53:22 -07002140static void
2141QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pCtx,
2142 const char *szLabel);
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07002143
2144static void
2145QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pCtx,
2146 int64_t nLabel);
2147
2148
2149/**
2150 * @brief Close an open indefinite length array.
2151 *
2152 * @param[in] pCtx The encoding context to close the array in.
2153 *
2154 * This is the same as QCBOREncode_CloseArray(), but the open array
2155 * that is being close must be of indefinite length.
2156 */
2157static void
2158QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pCtx);
2159
2160
2161/**
2162 * @brief Indicates that the next items added are in an indefinite length map.
2163 *
2164 * @param[in] pCtx The encoding context to open the map in.
2165 *
2166 * This is the same as QCBOREncode_OpenMap() except the array is
2167 * indefinite length.
2168 *
2169 * This must be closed with QCBOREncode_CloseMapIndefiniteLength().
2170 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002171static void
2172QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pCtx);
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07002173
Laurence Lundblade3eead482023-12-16 20:53:22 -07002174static void
2175QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pCtx,
2176 const char *szLabel);
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07002177
2178static void
2179QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pCtx,
2180 int64_t nLabel);
2181
2182
2183/**
2184 * @brief Close an open indefinite length map.
2185 *
2186 * @param[in] pCtx The encoding context to close the map in.
2187 *
2188 * This is the same as QCBOREncode_CloseMap(), but the open map that
2189 * is being close must be of indefinite length.
2190 */
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07002191static void
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07002192QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pCtx);
2193
2194
Laurence Lundbladec92e4162023-11-27 21:51:26 -07002195/**
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -08002196 * @brief Close and sort an open map.
Laurence Lundbladed6e13022023-11-26 10:14:02 -07002197 *
2198 * @param[in] pCtx The encoding context to close the map in .
2199 *
2200 * This is the same as QCBOREncode_CloseMap() except it sorts the map
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07002201 * per RFC 8949 Section 4.2.1 and checks for duplicate map keys. This
2202 * sort is lexicographic of the CBOR-encoded map labels.
Laurence Lundbladed6e13022023-11-26 10:14:02 -07002203 *
2204 * This is more expensive than most things in the encoder. It uses
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07002205 * bubble sort which runs in n-squared time where @c n is the number
2206 * of map items. Sorting large maps on slow CPUs might be slow. This
2207 * is also increases the object code size of the encoder by about 30%
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -08002208 * (500-1000 bytes).
Laurence Lundbladed6e13022023-11-26 10:14:02 -07002209 *
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07002210 * Bubble sort was selected so as to not need require configuration of
2211 * a buffer to track map item offsets. Bubble sort works well even
2212 * though map items are not all the same size because it always swaps
2213 * adjacent items.
Laurence Lundbladed6e13022023-11-26 10:14:02 -07002214 */
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07002215void
2216QCBOREncode_CloseAndSortMap(QCBOREncodeContext *pCtx);
Laurence Lundbladed6e13022023-11-26 10:14:02 -07002217
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07002218void
2219QCBOREncode_CloseAndSortMapIndef(QCBOREncodeContext *pCtx);
Laurence Lundbladed6e13022023-11-26 10:14:02 -07002220
2221
2222/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002223 * @brief Indicate start of encoded CBOR to be wrapped in a bstr.
2224 *
2225 * @param[in] pCtx The encoding context to open the bstr-wrapped CBOR in.
2226 *
2227 * All added encoded items between this call and a call to
2228 * QCBOREncode_CloseBstrWrap2() will be wrapped in a bstr. They will
2229 * appear in the final output as a byte string. That byte string will
2230 * contain encoded CBOR. This increases nesting level by one.
2231 *
2232 * The typical use case is for encoded CBOR that is to be
2233 * cryptographically hashed, as part of a [RFC 8152, COSE]
2234 * (https://tools.ietf.org/html/rfc8152) implementation. The wrapping
2235 * byte string is taken as input by the hash function (which is why it
2236 * is returned by QCBOREncode_CloseBstrWrap2()). It is also easy to
2237 * recover on decoding with standard CBOR decoders.
2238 *
2239 * Using QCBOREncode_BstrWrap() and QCBOREncode_CloseBstrWrap2()
2240 * avoids having to encode the items first in one buffer (e.g., the
2241 * COSE payload) and then add that buffer as a bstr to another
2242 * encoding (e.g. the COSE to-be-signed bytes, the @c Sig_structure)
2243 * potentially halving the memory needed.
2244 *
2245 * CBOR by nature must be decoded item by item in order from the
2246 * start. By wrapping some CBOR in a byte string, the decoding of
2247 * that wrapped CBOR can be skipped. This is another use of wrapping,
2248 * perhaps because the CBOR is large and deeply nested. Perhaps APIs
2249 * for handling one defined CBOR message that is being embedded in
2250 * another only take input as a byte string. Perhaps the desire is to
2251 * be able to decode the out layer even in the wrapped has errors.
Michael Eckel5c531332020-03-02 01:35:30 +01002252 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002253static void
2254QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01002255
Laurence Lundblade3eead482023-12-16 20:53:22 -07002256static void
2257QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01002258
Laurence Lundblade3eead482023-12-16 20:53:22 -07002259static void
2260QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01002261
2262
2263/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002264 * @brief Close a wrapping bstr.
2265 *
2266 * @param[in] pCtx The encoding context to close of bstr wrapping in.
2267 * @param[in] bIncludeCBORHead Include the encoded CBOR head of the bstr
2268 * as well as the bytes in @c pWrappedCBOR.
2269 * @param[out] pWrappedCBOR A @ref UsefulBufC containing wrapped bytes.
2270 *
2271 * The closes a wrapping bstr opened by QCBOREncode_BstrWrap(). It reduces
2272 * nesting level by one.
2273 *
2274 * A pointer and length of the enclosed encoded CBOR is returned in @c
2275 * *pWrappedCBOR if it is not @c NULL. The main purpose of this is so
2276 * this data can be hashed (e.g., with SHA-256) as part of a [RFC
2277 * 8152, COSE] (https://tools.ietf.org/html/rfc8152)
2278 * implementation. **WARNING**, this pointer and length should be used
2279 * right away before any other calls to @c QCBOREncode_CloseXxx() as
2280 * they will move data around and the pointer and length will no
2281 * longer be to the correct encoded CBOR.
2282 *
2283 * When an error occurs as a result of this call, the encoder records
2284 * the error and enters the error state. The error will be returned
2285 * when QCBOREncode_Finish() is called.
2286 *
2287 * If this has been called more times than QCBOREncode_BstrWrap(),
2288 * then @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
2289 * QCBOREncode_Finish() is called.
2290 *
2291 * If this is called and it is not a wrapping bstr that is currently
2292 * open, @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
2293 * QCBOREncode_Finish() is called.
2294 *
2295 * QCBOREncode_CloseBstrWrap() is a deprecated version of this function
2296 * that is equivalent to the call with @c bIncludeCBORHead @c true.
Michael Eckel5c531332020-03-02 01:35:30 +01002297 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002298void
2299QCBOREncode_CloseBstrWrap2(QCBOREncodeContext *pCtx, bool bIncludeCBORHead, UsefulBufC *pWrappedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01002300
Laurence Lundblade3eead482023-12-16 20:53:22 -07002301static void
2302QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01002303
2304
2305/**
Laurence Lundblade8d3b8552021-06-10 11:11:54 -07002306 * @brief Cancel byte string wrapping.
2307 *
2308 * @param[in] pCtx The encoding context.
2309 *
2310 * This cancels QCBOREncode_BstrWrap() making tghe encoding as if it
2311 * were never called.
2312 *
2313 * WARNING: This does not work on QCBOREncode_BstrWrapInMap()
2314 * or QCBOREncode_BstrWrapInMapN() and there is no error detection
2315 * of an attempt at their use.
2316 *
2317 * This only works if nothing has been added into the wrapped byte
2318 * string. If something has been added, this sets the error
2319 * @ref QCBOR_ERR_CANNOT_CANCEL.
2320 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002321void
2322QCBOREncode_CancelBstrWrap(QCBOREncodeContext *pCtx);
Laurence Lundblade8d3b8552021-06-10 11:11:54 -07002323
2324
2325/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002326 * @brief Add some already-encoded CBOR bytes.
2327 *
2328 * @param[in] pCtx The encoding context to add the already-encode CBOR to.
2329 * @param[in] Encoded The already-encoded CBOR to add to the context.
2330 *
2331 * The encoded CBOR being added must be fully conforming CBOR. It must
2332 * be complete with no arrays or maps that are incomplete. While this
2333 * encoder doesn't ever produce indefinite lengths, it is OK for the
2334 * raw CBOR added here to have indefinite lengths.
2335 *
2336 * The raw CBOR added here is not checked in anyway. If it is not
2337 * conforming or has open arrays or such, the final encoded CBOR
2338 * will probably be wrong or not what was intended.
2339 *
2340 * If the encoded CBOR being added here contains multiple items, they
2341 * must be enclosed in a map or array. At the top level the raw
2342 * CBOR must be a single data item.
Michael Eckel5c531332020-03-02 01:35:30 +01002343 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002344static void
2345QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01002346
Laurence Lundblade3eead482023-12-16 20:53:22 -07002347static void
2348QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01002349
Laurence Lundblade3eead482023-12-16 20:53:22 -07002350static void
2351QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01002352
2353
2354/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002355 * @brief Get the encoded result.
2356 *
2357 * @param[in] pCtx The context to finish encoding with.
2358 * @param[out] pEncodedCBOR Structure in which the pointer and length of
2359 * the encoded CBOR is returned.
2360 *
2361 * @retval QCBOR_SUCCESS Encoded CBOR is returned.
2362 *
2363 * @retval QCBOR_ERR_TOO_MANY_CLOSES Nesting error
2364 *
2365 * @retval QCBOR_ERR_CLOSE_MISMATCH Nesting error
2366 *
2367 * @retval QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN Nesting error
2368 *
2369 * @retval QCBOR_ERR_BUFFER_TOO_LARGE Encoded output buffer size
2370 *
2371 * @retval QCBOR_ERR_BUFFER_TOO_SMALL Encoded output buffer size
2372 *
2373 * @retval QCBOR_ERR_ARRAY_NESTING_TOO_DEEP Implementation limit
2374 *
2375 * @retval QCBOR_ERR_ARRAY_TOO_LONG Implementation limit
2376 *
2377 * On success, the pointer and length of the encoded CBOR are returned
2378 * in @c *pEncodedCBOR. The pointer is the same pointer that was passed
2379 * in to QCBOREncode_Init(). Note that it is not const when passed to
2380 * QCBOREncode_Init(), but it is const when returned here. The length
2381 * will be smaller than or equal to the length passed in when
2382 * QCBOREncode_Init() as this is the length of the actual result, not
2383 * the size of the buffer it was written to.
2384 *
2385 * If a @c NULL was passed for @c Storage.ptr when QCBOREncode_Init()
2386 * was called, @c NULL will be returned here, but the length will be
2387 * that of the CBOR that would have been encoded.
2388 *
2389 * Encoding errors primarily manifest here as most other encoding function
2390 * do no return an error. They just set the error state in the encode
2391 * context after which no encoding function does anything.
2392 *
2393 * Three types of errors manifest here. The first type are nesting
2394 * errors where the number of @c QCBOREncode_OpenXxx() calls do not
2395 * match the number @c QCBOREncode_CloseXxx() calls. The solution is to
2396 * fix the calling code.
2397 *
2398 * The second type of error is because the buffer given is either too
2399 * small or too large. The remedy is to give a correctly sized buffer.
2400 *
2401 * The third type are due to limits in this implementation.
2402 * @ref QCBOR_ERR_ARRAY_NESTING_TOO_DEEP can be worked around by
2403 * encoding the CBOR in two (or more) phases and adding the CBOR from
2404 * the first phase to the second with @c QCBOREncode_AddEncoded().
2405 *
2406 * If an error is returned, the buffer may have partially encoded
2407 * incorrect CBOR in it and it should not be used. Likewise, the length
2408 * may be incorrect and should not be used.
2409 *
2410 * Note that the error could have occurred in one of the many
2411 * @c QCBOREncode_AddXxx() calls long before QCBOREncode_Finish() was
2412 * called. This error handling reduces the CBOR implementation size
2413 * but makes debugging harder.
2414 *
2415 * This may be called multiple times. It will always return the
2416 * same. It can also be interleaved with calls to
2417 * QCBOREncode_FinishGetSize().
2418 *
2419 * QCBOREncode_GetErrorState() can be called to get the current
2420 * error state in order to abort encoding early as an optimization, but
2421 * calling it is is never required.
Michael Eckel5c531332020-03-02 01:35:30 +01002422 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002423QCBORError
2424QCBOREncode_Finish(QCBOREncodeContext *pCtx, UsefulBufC *pEncodedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01002425
2426
2427/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002428 * @brief Get the encoded CBOR and error status.
2429 *
2430 * @param[in] pCtx The context to finish encoding with.
2431 * @param[out] uEncodedLen The length of the encoded or potentially
2432 * encoded CBOR in bytes.
2433 *
2434 * @return The same errors as QCBOREncode_Finish().
2435 *
2436 * This functions the same as QCBOREncode_Finish(), but only returns the
2437 * size of the encoded output.
Michael Eckel5c531332020-03-02 01:35:30 +01002438 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002439QCBORError
2440QCBOREncode_FinishGetSize(QCBOREncodeContext *pCtx, size_t *uEncodedLen);
Michael Eckel5c531332020-03-02 01:35:30 +01002441
2442
2443/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002444 * @brief Indicate whether output buffer is NULL or not.
2445 *
2446 * @param[in] pCtx The encoding context.
2447 *
2448 * @return 1 if the output buffer is @c NULL.
2449 *
2450 * Sometimes a @c NULL input buffer is given to QCBOREncode_Init() so
2451 * that the size of the generated CBOR can be calculated without
2452 * allocating a buffer for it. This returns 1 when the output buffer
2453 * is @c NULL and 0 when it is not.
Michael Eckel5c531332020-03-02 01:35:30 +01002454 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002455static int
2456QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx);
2457
2458
2459/**
2460 * @brief Get the encoding error state.
2461 *
2462 * @param[in] pCtx The encoding context.
2463 *
2464 * @return One of @ref QCBORError. See return values from
2465 * QCBOREncode_Finish()
2466 *
2467 * Normally encoding errors need only be handled at the end of
2468 * encoding when QCBOREncode_Finish() is called. This can be called to
2469 * get the error result before finish should there be a need to halt
2470 * encoding before QCBOREncode_Finish() is called.
2471 */
2472static QCBORError
2473QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx);
2474
2475
2476/**
2477 * Encode the "head" of a CBOR data item.
2478 *
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002479 * @param Buffer Buffer to output the encoded head to; must be
Laurence Lundblade3eead482023-12-16 20:53:22 -07002480 * @ref QCBOR_HEAD_BUFFER_SIZE bytes in size.
2481 * @param uMajorType One of CBOR_MAJOR_TYPE_XX.
2482 * @param uMinLen The minimum number of bytes to encode uNumber. Almost
2483 * always this is 0 to use preferred
2484 * serialization. If this is 4, then even the
2485 * values 0xffff and smaller will be encoded in 4
2486 * bytes. This is used primarily when encoding a
2487 * float or double put into uNumber as the leading
2488 * zero bytes for them must be encoded.
2489 * @param uNumber The numeric argument part of the CBOR head.
2490 * @return Pointer and length of the encoded head or
2491 * @ref NULLUsefulBufC if the output buffer is too small.
2492 *
2493 * Callers do not to need to call this for normal CBOR encoding. Note
2494 * that it doesn't even take a @ref QCBOREncodeContext argument.
2495 *
2496 * This encodes the major type and argument part of a data item. The
2497 * argument is an integer that is usually either the value or the length
2498 * of the data item.
2499 *
2500 * This is exposed in the public interface to allow hashing of some CBOR
2501 * data types, bstr in particular, a chunk at a time so the full CBOR
2502 * doesn't have to be encoded in a contiguous buffer.
2503 *
2504 * For example, if you have a 100,000 byte binary blob in a buffer that
2505 * needs to be a bstr encoded and then hashed. You could allocate a
2506 * 100,010 byte buffer and encode it normally. Alternatively, you can
2507 * encode the head in a 10 byte buffer with this function, hash that and
2508 * then hash the 100,000 bytes using the same hash context.
Laurence Lundblade3eead482023-12-16 20:53:22 -07002509 */
2510UsefulBufC
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002511QCBOREncode_EncodeHead(UsefulBuf Buffer,
Laurence Lundblade3eead482023-12-16 20:53:22 -07002512 uint8_t uMajorType,
2513 uint8_t uMinLen,
2514 uint64_t uNumber);
Michael Eckel5c531332020-03-02 01:35:30 +01002515
2516
Michael Eckel5c531332020-03-02 01:35:30 +01002517
2518
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002519/* =========================================================================
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002520 BEGINNING OF PRIVATE IMPLEMENTATION
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002521 ========================================================================= */
Michael Eckel5c531332020-03-02 01:35:30 +01002522
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002523/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002524void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002525QCBOREncode_Private_AddBuffer(QCBOREncodeContext *pCtx,
2526 uint8_t uMajorType,
2527 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002528
2529
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002530/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002531void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002532QCBOREncode_Private_OpenMapOrArray(QCBOREncodeContext *pCtx,
2533 uint8_t uMajorType);
Michael Eckel5c531332020-03-02 01:35:30 +01002534
2535
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002536/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002537void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002538QCBOREncode_Private_OpenMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx,
2539 uint8_t uMajorType);
Michael Eckel5c531332020-03-02 01:35:30 +01002540
2541
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002542/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002543void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002544QCBOREncode_Private_CloseMapOrArray(QCBOREncodeContext *pCtx,
2545 uint8_t uMajorType);
Michael Eckel5c531332020-03-02 01:35:30 +01002546
2547
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002548/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002549void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002550QCBOREncode_Private_CloseMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx,
2551 uint8_t uMajorType);
Michael Eckel5c531332020-03-02 01:35:30 +01002552
2553
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002554/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002555void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002556QCBOREncode_Private_AddType7(QCBOREncodeContext *pCtx,
2557 uint8_t uMinLen,
2558 uint64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002559
2560
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002561/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002562void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002563QCBOREncode_Private_AddExpMantissa(QCBOREncodeContext *pCtx,
Laurence Lundblade3eead482023-12-16 20:53:22 -07002564 uint64_t uTag,
2565 UsefulBufC BigNumMantissa,
2566 bool bBigNumIsNegative,
2567 int64_t nMantissa,
2568 int64_t nExponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002569
Michael Eckel5c531332020-03-02 01:35:30 +01002570
2571
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -08002572
2573static inline void
2574QCBOREncode_SerializationCDE(QCBOREncodeContext *pMe)
2575{
2576 /* The use of a function pointer here is a little trick to reduce
2577 * code linked for the common use cases that don't sort. If this
2578 * function is never linked, then QCBOREncode_CloseAndSortMap() is
2579 * never linked and the amount of code pulled in is small. If the
2580 * mode switch between sorting and not sorting were an if
2581 * statement, then QCBOREncode_CloseAndSortMap() would always be
2582 * linked even when not used. */
2583 pMe->pfnCloseMap = QCBOREncode_CloseAndSortMap;
2584 pMe->uMode = QCBOR_ENCODE_MODE_CDE;
2585}
2586
2587static inline void
2588QCBOREncode_SerializationdCBOR(QCBOREncodeContext *pMe)
2589{
2590 pMe->pfnCloseMap = QCBOREncode_CloseAndSortMap;
2591 pMe->uMode = QCBOR_ENCODE_MODE_DCBOR;
2592}
2593
2594static inline void
2595QCBOREncode_SerializationPreferred(QCBOREncodeContext *pMe)
2596{
2597 pMe->uMode = QCBOR_ENCODE_MODE_PREFERRED;
2598}
2599
2600static inline void
2601QCBOREncode_Allow(QCBOREncodeContext *pMe, const uint8_t uAllow)
2602{
2603#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
2604 pMe->uAllow = uAllow;
2605#else
2606 (void)uAllow;
2607 (void)pMe;
2608#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
2609}
2610
2611
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002612static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002613QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pMe,
2614 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002615 const int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002616{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002617 /* Use _AddBuffer() because _AddSZString() is defined below, not above */
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002618 QCBOREncode_Private_AddBuffer(pMe,
2619 CBOR_MAJOR_TYPE_TEXT_STRING,
2620 UsefulBuf_FromSZ(szLabel));
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002621 QCBOREncode_AddInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002622}
2623
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002624static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002625QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002626 const int64_t nLabel,
2627 const int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002628{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002629 QCBOREncode_AddInt64(pMe, nLabel);
2630 QCBOREncode_AddInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002631}
2632
2633
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002634static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002635QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pMe,
2636 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002637 const uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002638{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002639 /* Use _AddBuffer() because _AddSZString() is defined below, not above */
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002640 QCBOREncode_Private_AddBuffer(pMe,
2641 CBOR_MAJOR_TYPE_TEXT_STRING,
2642 UsefulBuf_FromSZ(szLabel));
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002643 QCBOREncode_AddUInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002644}
2645
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002646static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002647QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002648 const int64_t nLabel,
2649 const uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002650{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002651 QCBOREncode_AddInt64(pMe, nLabel);
2652 QCBOREncode_AddUInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002653}
2654
2655
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002656static inline void
Laurence Lundblade2d493002024-02-01 11:09:17 -07002657QCBOREncode_AddNegativeUInt64ToMap(QCBOREncodeContext *pMe, const char *szLabel, uint64_t uNum)
2658{
2659 /* Use _AddBuffer() because _AddSZString() is defined below, not above */
2660 QCBOREncode_Private_AddBuffer(pMe,
2661 CBOR_MAJOR_TYPE_TEXT_STRING,
2662 UsefulBuf_FromSZ(szLabel));
2663 QCBOREncode_AddNegativeUInt64(pMe, uNum);
2664}
2665
2666static inline void
2667QCBOREncode_AddNegativeUInt64ToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint64_t uNum)
2668{
2669 QCBOREncode_AddInt64(pMe, nLabel);
2670 QCBOREncode_AddNegativeUInt64(pMe, uNum);
2671}
2672
2673
2674static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002675QCBOREncode_AddText(QCBOREncodeContext *pMe, const UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002676{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002677 QCBOREncode_Private_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002678}
2679
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002680static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002681QCBOREncode_AddTextToMap(QCBOREncodeContext *pMe,
2682 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002683 const UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002684{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002685 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szLabel));
2686 QCBOREncode_AddText(pMe, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002687}
2688
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002689static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002690QCBOREncode_AddTextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002691 const int64_t nLabel,
2692 const UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002693{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002694 QCBOREncode_AddInt64(pMe, nLabel);
2695 QCBOREncode_AddText(pMe, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002696}
2697
2698
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002699inline static void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002700QCBOREncode_AddSZString(QCBOREncodeContext *pMe, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002701{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002702 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szString));
Michael Eckel5c531332020-03-02 01:35:30 +01002703}
2704
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002705static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002706QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pMe,
2707 const char *szLabel,
2708 const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002709{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002710 QCBOREncode_AddSZString(pMe, szLabel);
2711 QCBOREncode_AddSZString(pMe, szString);
Michael Eckel5c531332020-03-02 01:35:30 +01002712}
2713
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002714static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002715QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002716 const int64_t nLabel,
Laurence Lundblade3eead482023-12-16 20:53:22 -07002717 const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002718{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002719 QCBOREncode_AddInt64(pMe, nLabel);
2720 QCBOREncode_AddSZString(pMe, szString);
Michael Eckel5c531332020-03-02 01:35:30 +01002721}
2722
2723
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +02002724#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002725static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002726QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pMe,
2727 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002728 const double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002729{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002730 QCBOREncode_AddSZString(pMe, szLabel);
2731 QCBOREncode_AddDouble(pMe, dNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002732}
2733
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002734static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002735QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002736 const int64_t nLabel,
2737 const double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002738{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002739 QCBOREncode_AddInt64(pMe, nLabel);
2740 QCBOREncode_AddDouble(pMe, dNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002741}
2742
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002743static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002744QCBOREncode_AddFloatToMap(QCBOREncodeContext *pMe,
2745 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002746 const float dNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002747{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002748 QCBOREncode_AddSZString(pMe, szLabel);
2749 QCBOREncode_AddFloat(pMe, dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002750}
2751
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002752static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002753QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pMe,
2754 const int64_t nLabel,
2755 const float fNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002756{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002757 QCBOREncode_AddInt64(pMe, nLabel);
2758 QCBOREncode_AddFloat(pMe, fNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002759}
2760
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002761static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002762QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pMe,
2763 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002764 const double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002765{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002766 QCBOREncode_AddSZString(pMe, szLabel);
2767 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002768}
2769
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002770static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002771QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002772 const int64_t nLabel,
2773 const double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002774{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002775 QCBOREncode_AddInt64(pMe, nLabel);
2776 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002777}
2778
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002779static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002780QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pMe,
2781 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002782 const float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002783{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002784 QCBOREncode_AddSZString(pMe, szLabel);
2785 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002786}
2787
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002788static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002789QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002790 const int64_t nLabel,
2791 const float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002792{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002793 QCBOREncode_AddInt64(pMe, nLabel);
2794 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002795}
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +02002796#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002797
Michael Eckel5c531332020-03-02 01:35:30 +01002798
Laurence Lundblade9b334962020-08-27 10:55:53 -07002799
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002800static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002801QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pMe,
2802 const uint8_t uTag,
2803 const int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002804{
2805 if(uTag == QCBOR_ENCODE_AS_TAG) {
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002806 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_EPOCH);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002807 }
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002808 QCBOREncode_AddInt64(pMe, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002809}
2810
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002811static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002812QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pMe,
2813 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002814 const uint8_t uTag,
2815 const int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002816{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002817 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002818 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002819}
2820
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002821static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002822QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002823 const int64_t nLabel,
2824 const uint8_t uTag,
2825 const int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002826{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002827 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002828 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002829}
2830
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002831static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002832QCBOREncode_AddDateEpoch(QCBOREncodeContext *pMe,
2833 const int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002834{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002835 QCBOREncode_AddTDateEpoch(pMe, QCBOR_ENCODE_AS_TAG, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002836}
2837
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002838static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002839QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pMe,
2840 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002841 const int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002842{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002843 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002844 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002845}
2846
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002847static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002848QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002849 const int64_t nLabel,
2850 const int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002851{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002852 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002853 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002854}
2855
2856
Laurence Lundblade46d63e92021-05-13 11:37:10 -07002857static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002858QCBOREncode_AddTDaysEpoch(QCBOREncodeContext *pMe,
2859 const uint8_t uTag,
2860 const int64_t nDays)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07002861{
2862 if(uTag == QCBOR_ENCODE_AS_TAG) {
2863 QCBOREncode_AddTag(pMe, CBOR_TAG_DAYS_EPOCH);
2864 }
2865 QCBOREncode_AddInt64(pMe, nDays);
2866}
2867
2868static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002869QCBOREncode_AddTDaysEpochToMapSZ(QCBOREncodeContext *pMe,
2870 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002871 const uint8_t uTag,
2872 const int64_t nDays)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07002873{
2874 QCBOREncode_AddSZString(pMe, szLabel);
2875 QCBOREncode_AddTDaysEpoch(pMe, uTag, nDays);
2876}
2877
2878static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002879QCBOREncode_AddTDaysEpochToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002880 const int64_t nLabel,
2881 const uint8_t uTag,
2882 const int64_t nDays)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07002883{
2884 QCBOREncode_AddInt64(pMe, nLabel);
2885 QCBOREncode_AddTDaysEpoch(pMe, uTag, nDays);
2886}
2887
Laurence Lundblade9b334962020-08-27 10:55:53 -07002888
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002889static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002890QCBOREncode_AddBytes(QCBOREncodeContext *pMe,
2891 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002892{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002893 QCBOREncode_Private_AddBuffer(pMe, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002894}
2895
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002896static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002897QCBOREncode_AddBytesToMap(QCBOREncodeContext *pMe,
2898 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002899 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002900{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002901 QCBOREncode_AddSZString(pMe, szLabel);
2902 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002903}
2904
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002905static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002906QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002907 const int64_t nLabel,
2908 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002909{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002910 QCBOREncode_AddInt64(pMe, nLabel);
2911 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002912}
2913
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002914static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002915QCBOREncode_OpenBytesInMapSZ(QCBOREncodeContext *pMe,
2916 const char *szLabel,
2917 UsefulBuf *pPlace)
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06002918{
2919 QCBOREncode_AddSZString(pMe, szLabel);
2920 QCBOREncode_OpenBytes(pMe, pPlace);
2921}
2922
2923static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002924QCBOREncode_OpenBytesInMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002925 const int64_t nLabel,
Laurence Lundblade3eead482023-12-16 20:53:22 -07002926 UsefulBuf *pPlace)
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06002927{
2928 QCBOREncode_AddInt64(pMe, nLabel);
2929 QCBOREncode_OpenBytes(pMe, pPlace);
2930}
2931
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002932
2933static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002934QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002935 const uint8_t uTagRequirement,
2936 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002937{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002938 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2939 QCBOREncode_AddTag(pMe, CBOR_TAG_BIN_UUID);
2940 }
2941 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002942}
2943
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002944static inline void
2945QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pMe,
2946 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002947 const uint8_t uTagRequirement,
2948 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002949{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002950 QCBOREncode_AddSZString(pMe, szLabel);
2951 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002952}
2953
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002954static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002955QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002956 const int64_t nLabel,
2957 const uint8_t uTagRequirement,
2958 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002959{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002960 QCBOREncode_AddInt64(pMe, nLabel);
2961 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002962}
2963
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002964static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002965QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002966{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002967 QCBOREncode_AddTBinaryUUID(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002968}
2969
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002970static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002971QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pMe,
2972 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002973 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002974{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002975 QCBOREncode_AddTBinaryUUIDToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002976}
2977
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002978static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002979QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002980 const int64_t nLabel,
2981 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002982{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002983 QCBOREncode_AddTBinaryUUIDToMapN(pMe,
2984 nLabel,
2985 QCBOR_ENCODE_AS_TAG,
2986 Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002987}
2988
2989
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002990static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002991QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002992 const uint8_t uTagRequirement,
2993 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002994{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002995 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2996 QCBOREncode_AddTag(pMe, CBOR_TAG_POS_BIGNUM);
2997 }
2998 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002999}
3000
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003001static inline void
3002QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pMe,
3003 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003004 const uint8_t uTagRequirement,
3005 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003006{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003007 QCBOREncode_AddSZString(pMe, szLabel);
3008 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01003009}
3010
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003011static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003012QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003013 const int64_t nLabel,
3014 const uint8_t uTagRequirement,
3015 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003016{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003017 QCBOREncode_AddInt64(pMe, nLabel);
3018 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01003019}
3020
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003021static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003022QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003023{
3024 QCBOREncode_AddTPositiveBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
3025}
3026
3027static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003028QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pMe,
3029 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003030 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003031{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003032 QCBOREncode_AddTPositiveBignumToMapSZ(pMe,
3033 szLabel,
3034 QCBOR_ENCODE_AS_TAG,
3035 Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003036}
3037
3038static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003039QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003040 const int64_t nLabel,
3041 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003042{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003043 QCBOREncode_AddTPositiveBignumToMapN(pMe,
3044 nLabel,
3045 QCBOR_ENCODE_AS_TAG,
3046 Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003047}
3048
3049
3050static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003051QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003052 const uint8_t uTagRequirement,
3053 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003054{
3055 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3056 QCBOREncode_AddTag(pMe, CBOR_TAG_NEG_BIGNUM);
3057 }
3058 QCBOREncode_AddBytes(pMe, Bytes);
3059}
3060
3061static inline void
3062QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pMe,
3063 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003064 const uint8_t uTagRequirement,
3065 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003066{
3067 QCBOREncode_AddSZString(pMe, szLabel);
3068 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
3069}
3070
3071static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003072QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003073 const int64_t nLabel,
3074 const uint8_t uTagRequirement,
3075 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003076{
3077 QCBOREncode_AddInt64(pMe, nLabel);
3078 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
3079}
3080
3081static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003082QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003083{
3084 QCBOREncode_AddTNegativeBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
3085}
3086
3087static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003088QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pMe,
3089 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003090 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003091{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003092 QCBOREncode_AddTNegativeBignumToMapSZ(pMe,
3093 szLabel,
3094 QCBOR_ENCODE_AS_TAG,
3095 Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003096}
3097
3098static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003099QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003100 const int64_t nLabel,
3101 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003102{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003103 QCBOREncode_AddTNegativeBignumToMapN(pMe,
3104 nLabel,
3105 QCBOR_ENCODE_AS_TAG,
3106 Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003107}
3108
3109
Michael Eckel5c531332020-03-02 01:35:30 +01003110
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07003111#ifndef QCBOR_DISABLE_EXP_AND_MANTISSA
Michael Eckel5c531332020-03-02 01:35:30 +01003112
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003113static inline void
3114QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003115 const uint8_t uTagRequirement,
3116 const int64_t nMantissa,
3117 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003118{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003119 uint64_t uTag;
3120 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3121 uTag = CBOR_TAG_DECIMAL_FRACTION;
3122 } else {
3123 uTag = CBOR_TAG_INVALID64;
3124 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003125 QCBOREncode_Private_AddExpMantissa(pMe,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003126 uTag,
Michael Eckel5c531332020-03-02 01:35:30 +01003127 NULLUsefulBufC,
3128 false,
3129 nMantissa,
3130 nBase10Exponent);
3131}
3132
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003133static inline void
3134QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pMe,
3135 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003136 const uint8_t uTagRequirement,
3137 const int64_t nMantissa,
3138 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003139{
3140 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003141 QCBOREncode_AddTDecimalFraction(pMe,
3142 uTagRequirement,
3143 nMantissa,
3144 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003145}
3146
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003147static inline void
3148QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003149 const int64_t nLabel,
3150 const uint8_t uTagRequirement,
3151 const int64_t nMantissa,
3152 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003153{
3154 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003155 QCBOREncode_AddTDecimalFraction(pMe,
3156 uTagRequirement,
3157 nMantissa,
3158 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003159}
3160
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003161static inline void
3162QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003163 const int64_t nMantissa,
3164 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003165{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003166 QCBOREncode_AddTDecimalFraction(pMe,
3167 QCBOR_ENCODE_AS_TAG,
3168 nMantissa,
3169 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003170}
3171
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003172static inline void
3173QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pMe,
3174 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003175 const int64_t nMantissa,
3176 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003177{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003178 QCBOREncode_AddTDecimalFractionToMapSZ(pMe,
3179 szLabel,
3180 QCBOR_ENCODE_AS_TAG,
3181 nMantissa,
3182 nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003183}
3184
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003185static inline void
3186QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003187 const int64_t nLabel,
3188 const int64_t nMantissa,
3189 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003190{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003191 QCBOREncode_AddTDecimalFractionToMapN(pMe,
3192 nLabel,
3193 QCBOR_ENCODE_AS_TAG,
3194 nMantissa,
3195 nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003196}
3197
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003198
3199
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003200static inline void
3201QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003202 const uint8_t uTagRequirement,
3203 const UsefulBufC Mantissa,
3204 const bool bIsNegative,
3205 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003206{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003207 uint64_t uTag;
3208 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3209 uTag = CBOR_TAG_DECIMAL_FRACTION;
3210 } else {
3211 uTag = CBOR_TAG_INVALID64;
3212 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003213 QCBOREncode_Private_AddExpMantissa(pMe,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003214 uTag,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003215 Mantissa,
3216 bIsNegative,
Michael Eckel5c531332020-03-02 01:35:30 +01003217 0,
3218 nBase10Exponent);
3219}
3220
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003221static inline void
3222QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
3223 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003224 const uint8_t uTagRequirement,
3225 const UsefulBufC Mantissa,
3226 const bool bIsNegative,
3227 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003228{
3229 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003230 QCBOREncode_AddTDecimalFractionBigNum(pMe,
3231 uTagRequirement,
3232 Mantissa,
3233 bIsNegative,
3234 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003235}
3236
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003237static inline void
3238QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003239 const int64_t nLabel,
3240 const uint8_t uTagRequirement,
3241 const UsefulBufC Mantissa,
3242 const bool bIsNegative,
3243 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003244{
3245 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003246 QCBOREncode_AddTDecimalFractionBigNum(pMe,
3247 uTagRequirement,
3248 Mantissa,
3249 bIsNegative,
3250 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003251}
3252
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003253static inline void
3254QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003255 const UsefulBufC Mantissa,
3256 const bool bIsNegative,
3257 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003258{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003259 QCBOREncode_AddTDecimalFractionBigNum(pMe,
3260 QCBOR_ENCODE_AS_TAG,
3261 Mantissa,
3262 bIsNegative,
3263 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003264}
3265
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003266static inline void
3267QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
3268 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003269 const UsefulBufC Mantissa,
3270 const bool bIsNegative,
3271 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003272{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003273 QCBOREncode_AddTDecimalFractionBigNumToMapSZ(pMe,
3274 szLabel,
3275 QCBOR_ENCODE_AS_TAG,
3276 Mantissa,
3277 bIsNegative,
3278 nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003279}
3280
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003281static inline void
3282QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003283 const int64_t nLabel,
3284 const UsefulBufC Mantissa,
3285 const bool bIsNegative,
3286 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003287{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003288 QCBOREncode_AddTDecimalFractionBigNumToMapN(pMe,
3289 nLabel,
3290 QCBOR_ENCODE_AS_TAG,
3291 Mantissa,
3292 bIsNegative,
3293 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003294}
3295
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003296
3297
3298
3299
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003300static inline void
3301QCBOREncode_AddTBigFloat(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003302 const uint8_t uTagRequirement,
3303 const int64_t nMantissa,
3304 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003305{
3306 uint64_t uTag;
3307 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3308 uTag = CBOR_TAG_BIGFLOAT;
3309 } else {
3310 uTag = CBOR_TAG_INVALID64;
3311 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003312 QCBOREncode_Private_AddExpMantissa(pMe,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003313 uTag,
3314 NULLUsefulBufC,
3315 false,
3316 nMantissa,
3317 nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003318}
3319
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003320static inline void
3321QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pMe,
3322 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003323 const uint8_t uTagRequirement,
3324 const int64_t nMantissa,
3325 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003326{
3327 QCBOREncode_AddSZString(pMe, szLabel);
3328 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
3329}
3330
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003331static inline void
3332QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003333 const int64_t nLabel,
3334 const uint8_t uTagRequirement,
3335 const int64_t nMantissa,
3336 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003337{
3338 QCBOREncode_AddInt64(pMe, nLabel);
3339 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
3340}
3341
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003342static inline void
3343QCBOREncode_AddBigFloat(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003344 const int64_t nMantissa,
3345 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003346{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003347 QCBOREncode_AddTBigFloat(pMe,
3348 QCBOR_ENCODE_AS_TAG,
3349 nMantissa,
3350 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003351}
3352
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003353static inline void
3354QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pMe,
3355 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003356 const int64_t nMantissa,
3357 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003358{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003359 QCBOREncode_AddTBigFloatToMapSZ(pMe,
3360 szLabel,
3361 QCBOR_ENCODE_AS_TAG,
3362 nMantissa,
3363 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003364}
3365
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003366static inline void
3367QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003368 const int64_t nLabel,
3369 const int64_t nMantissa,
3370 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003371{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003372 QCBOREncode_AddTBigFloatToMapN(pMe,
3373 nLabel,
3374 QCBOR_ENCODE_AS_TAG,
3375 nMantissa,
3376 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003377}
3378
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003379
3380
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003381static inline void
3382QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003383 const uint8_t uTagRequirement,
3384 const UsefulBufC Mantissa,
3385 const bool bIsNegative,
3386 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003387{
3388 uint64_t uTag;
3389 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3390 uTag = CBOR_TAG_BIGFLOAT;
3391 } else {
3392 uTag = CBOR_TAG_INVALID64;
3393 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003394 QCBOREncode_Private_AddExpMantissa(pMe,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003395 uTag,
3396 Mantissa,
3397 bIsNegative,
3398 0,
3399 nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003400}
3401
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003402static inline void
3403QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pMe,
3404 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003405 const uint8_t uTagRequirement,
3406 const UsefulBufC Mantissa,
3407 const bool bIsNegative,
3408 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003409{
3410 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003411 QCBOREncode_AddTBigFloatBigNum(pMe,
3412 uTagRequirement,
3413 Mantissa,
3414 bIsNegative,
3415 nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003416}
3417
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003418static inline void
3419QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003420 const int64_t nLabel,
3421 const uint8_t uTagRequirement,
3422 const UsefulBufC Mantissa,
3423 const bool bIsNegative,
3424 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003425{
3426 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003427 QCBOREncode_AddTBigFloatBigNum(pMe,
3428 uTagRequirement,
3429 Mantissa,
3430 bIsNegative,
3431 nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003432}
3433
3434
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003435static inline void
3436QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003437 const UsefulBufC Mantissa,
3438 const bool bIsNegative,
3439 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003440{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003441 QCBOREncode_AddTBigFloatBigNum(pMe,
3442 QCBOR_ENCODE_AS_TAG,
3443 Mantissa, bIsNegative,
3444 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003445}
3446
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003447static inline void
3448QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pMe,
3449 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003450 const UsefulBufC Mantissa,
3451 const bool bIsNegative,
3452 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003453{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003454 QCBOREncode_AddTBigFloatBigNumToMapSZ(pMe,
3455 szLabel,
3456 QCBOR_ENCODE_AS_TAG,
3457 Mantissa,
3458 bIsNegative,
3459 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003460}
3461
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003462static inline void
3463QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003464 const int64_t nLabel,
3465 const UsefulBufC Mantissa,
3466 const bool bIsNegative,
3467 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003468{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003469 QCBOREncode_AddTBigFloatBigNumToMapN(pMe,
3470 nLabel,
3471 QCBOR_ENCODE_AS_TAG,
3472 Mantissa,
3473 bIsNegative,
3474 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003475}
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07003476#endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
Michael Eckel5c531332020-03-02 01:35:30 +01003477
3478
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003479static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003480QCBOREncode_AddTURI(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003481 const uint8_t uTagRequirement,
3482 const UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01003483{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003484 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3485 QCBOREncode_AddTag(pMe, CBOR_TAG_URI);
3486 }
3487 QCBOREncode_AddText(pMe, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01003488}
3489
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003490static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003491QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pMe,
3492 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003493 const uint8_t uTagRequirement,
3494 const UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01003495{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003496 QCBOREncode_AddSZString(pMe, szLabel);
3497 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01003498}
3499
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003500static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003501QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003502 const int64_t nLabel,
3503 const uint8_t uTagRequirement,
3504 const UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01003505{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003506 QCBOREncode_AddInt64(pMe, nLabel);
3507 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
3508}
3509
3510static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003511QCBOREncode_AddURI(QCBOREncodeContext *pMe, const UsefulBufC URI)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003512{
3513 QCBOREncode_AddTURI(pMe, QCBOR_ENCODE_AS_TAG, URI);
3514}
3515
3516static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003517QCBOREncode_AddURIToMap(QCBOREncodeContext *pMe,
3518 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003519 const UsefulBufC URI)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003520{
3521 QCBOREncode_AddTURIToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, URI);
3522}
3523
3524static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003525QCBOREncode_AddURIToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003526 const int64_t nLabel,
3527 const UsefulBufC URI)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003528{
3529 QCBOREncode_AddTURIToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01003530}
3531
3532
3533
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003534static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003535QCBOREncode_AddTB64Text(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003536 const uint8_t uTagRequirement,
3537 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003538{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003539 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3540 QCBOREncode_AddTag(pMe, CBOR_TAG_B64);
3541 }
3542 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003543}
3544
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003545static inline void
3546QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pMe,
3547 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003548 const uint8_t uTagRequirement,
3549 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003550{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003551 QCBOREncode_AddSZString(pMe, szLabel);
3552 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003553}
3554
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003555static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003556QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003557 const int64_t nLabel,
3558 const uint8_t uTagRequirement,
3559 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003560{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003561 QCBOREncode_AddInt64(pMe, nLabel);
3562 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
3563}
3564
3565static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003566QCBOREncode_AddB64Text(QCBOREncodeContext *pMe, const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003567{
3568 QCBOREncode_AddTB64Text(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
3569}
3570
3571static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003572QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pMe,
3573 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003574 const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003575{
3576 QCBOREncode_AddTB64TextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
3577}
3578
3579static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003580QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003581 const int64_t nLabel,
3582 const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003583{
3584 QCBOREncode_AddTB64TextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003585}
3586
3587
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003588
3589static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003590QCBOREncode_AddTB64URLText(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003591 const uint8_t uTagRequirement,
3592 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003593{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003594 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3595 QCBOREncode_AddTag(pMe, CBOR_TAG_B64URL);
3596 }
3597 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003598}
3599
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003600static inline void
3601QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pMe,
3602 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003603 const uint8_t uTagRequirement,
3604 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003605{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003606 QCBOREncode_AddSZString(pMe, szLabel);
3607 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003608}
3609
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003610static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003611QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003612 const int64_t nLabel,
3613 const uint8_t uTagRequirement,
3614 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003615{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003616 QCBOREncode_AddInt64(pMe, nLabel);
3617 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
3618}
3619
3620static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003621QCBOREncode_AddB64URLText(QCBOREncodeContext *pMe, const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003622{
3623 QCBOREncode_AddTB64URLText(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
3624}
3625
3626static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003627QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pMe,
3628 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003629 const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003630{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003631 QCBOREncode_AddTB64URLTextToMapSZ(pMe,
3632 szLabel,
3633 QCBOR_ENCODE_AS_TAG,
3634 B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003635}
3636
3637static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003638QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003639 const int64_t nLabel,
3640 const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003641{
3642 QCBOREncode_AddTB64URLTextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003643}
3644
3645
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003646
3647static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003648QCBOREncode_AddTRegex(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003649 const uint8_t uTagRequirement,
3650 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003651{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003652 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3653 QCBOREncode_AddTag(pMe, CBOR_TAG_REGEX);
3654 }
3655 QCBOREncode_AddText(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01003656}
3657
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003658static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003659QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pMe,
3660 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003661 const uint8_t uTagRequirement,
3662 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003663{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003664 QCBOREncode_AddSZString(pMe, szLabel);
3665 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01003666}
3667
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003668static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003669QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003670 const int64_t nLabel,
3671 const uint8_t uTagRequirement,
3672 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003673{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003674 QCBOREncode_AddInt64(pMe, nLabel);
3675 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
3676}
3677
3678static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003679QCBOREncode_AddRegex(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003680{
3681 QCBOREncode_AddTRegex(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
3682}
3683
3684static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003685QCBOREncode_AddRegexToMap(QCBOREncodeContext *pMe,
3686 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003687 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003688{
3689 QCBOREncode_AddTRegexToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
3690}
3691
3692static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003693QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003694 const int64_t nLabel,
3695 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003696{
3697 QCBOREncode_AddTRegexToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
3698
Michael Eckel5c531332020-03-02 01:35:30 +01003699}
3700
3701
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003702static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003703QCBOREncode_AddTMIMEData(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003704 const uint8_t uTagRequirement,
3705 const UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01003706{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003707 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
Laurence Lundblade4982f412020-09-18 23:02:18 -07003708 QCBOREncode_AddTag(pMe, CBOR_TAG_BINARY_MIME);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003709 }
Laurence Lundblade4982f412020-09-18 23:02:18 -07003710 QCBOREncode_AddBytes(pMe, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01003711}
3712
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003713static inline void
3714QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pMe,
3715 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003716 const uint8_t uTagRequirement,
3717 const UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01003718{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003719 QCBOREncode_AddSZString(pMe, szLabel);
3720 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01003721}
3722
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003723static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003724QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003725 const int64_t nLabel,
3726 const uint8_t uTagRequirement,
3727 const UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01003728{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003729 QCBOREncode_AddInt64(pMe, nLabel);
3730 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
3731}
3732
3733static inline void
3734QCBOREncode_AddMIMEData(QCBOREncodeContext *pMe, UsefulBufC MIMEData)
3735{
3736 QCBOREncode_AddTMIMEData(pMe, QCBOR_ENCODE_AS_TAG, MIMEData);
3737}
3738
3739static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003740QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pMe,
3741 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003742 const UsefulBufC MIMEData)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003743{
3744 QCBOREncode_AddTMIMEDataToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
3745}
3746
3747static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003748QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003749 const int64_t nLabel,
3750 const UsefulBufC MIMEData)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003751{
3752 QCBOREncode_AddTMIMEDataToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01003753}
3754
3755
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003756static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003757QCBOREncode_AddTDateString(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003758 const uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003759 const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01003760{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003761 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3762 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_STRING);
3763 }
3764 QCBOREncode_AddSZString(pMe, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01003765}
3766
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003767static inline void
3768QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pMe,
3769 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003770 const uint8_t uTagRequirement,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003771 const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01003772{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003773 QCBOREncode_AddSZString(pMe, szLabel);
3774 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01003775}
3776
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003777static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003778QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003779 const int64_t nLabel,
3780 const uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003781 const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01003782{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003783 QCBOREncode_AddInt64(pMe, nLabel);
3784 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
3785}
3786
3787static inline void
3788QCBOREncode_AddDateString(QCBOREncodeContext *pMe, const char *szDate)
3789{
3790 QCBOREncode_AddTDateString(pMe, QCBOR_ENCODE_AS_TAG, szDate);
3791}
3792
3793static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003794QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pMe,
3795 const char *szLabel,
3796 const char *szDate)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003797{
3798 QCBOREncode_AddTDateStringToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, szDate);
3799}
3800
3801static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003802QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003803 const int64_t nLabel,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003804 const char *szDate)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003805{
3806 QCBOREncode_AddTDateStringToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01003807}
3808
3809
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003810static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003811QCBOREncode_AddTDaysString(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003812 const uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003813 const char *szDate)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07003814{
3815 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3816 QCBOREncode_AddTag(pMe, CBOR_TAG_DAYS_STRING);
3817 }
3818 QCBOREncode_AddSZString(pMe, szDate);
3819}
3820
3821static inline void
3822QCBOREncode_AddTDaysStringToMapSZ(QCBOREncodeContext *pMe,
3823 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003824 const uint8_t uTagRequirement,
Laurence Lundblade46d63e92021-05-13 11:37:10 -07003825 const char *szDate)
3826{
3827 QCBOREncode_AddSZString(pMe, szLabel);
3828 QCBOREncode_AddTDaysString(pMe, uTagRequirement, szDate);
3829}
3830
3831static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003832QCBOREncode_AddTDaysStringToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003833 const int64_t nLabel,
3834 const uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003835 const char *szDate)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07003836{
3837 QCBOREncode_AddInt64(pMe, nLabel);
3838 QCBOREncode_AddTDaysString(pMe, uTagRequirement, szDate);
3839}
3840
3841
3842
3843static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003844QCBOREncode_Private_AddSimple(QCBOREncodeContext *pMe, const uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01003845{
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -08003846#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
3847 if(pMe->uMode >= QCBOR_ENCODE_MODE_DCBOR) {
3848 if(uNum < CBOR_SIMPLEV_FALSE ||
3849 uNum > CBOR_SIMPLEV_NULL) {
3850 pMe->uError = QCBOR_ERR_NOT_PREFERRED;
3851 return;
3852 }
3853 }
3854#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
3855
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003856 QCBOREncode_Private_AddType7(pMe, 0, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01003857}
3858
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003859static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003860QCBOREncode_Private_AddSimpleToMap(QCBOREncodeContext *pMe,
3861 const char *szLabel,
3862 const uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01003863{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003864 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003865 QCBOREncode_Private_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01003866}
3867
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003868static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003869QCBOREncode_Private_AddSimpleToMapN(QCBOREncodeContext *pMe,
3870 const int64_t nLabel,
3871 const uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01003872{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003873 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003874 QCBOREncode_Private_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01003875}
3876
3877
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003878static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003879QCBOREncode_AddBool(QCBOREncodeContext *pMe, const bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01003880{
3881 uint8_t uSimple = CBOR_SIMPLEV_FALSE;
3882 if(b) {
3883 uSimple = CBOR_SIMPLEV_TRUE;
3884 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003885 QCBOREncode_Private_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01003886}
3887
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003888static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003889QCBOREncode_AddBoolToMap(QCBOREncodeContext *pMe, const char *szLabel, const bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01003890{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003891 QCBOREncode_AddSZString(pMe, szLabel);
3892 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01003893}
3894
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003895static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003896QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pMe, const int64_t nLabel, const bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01003897{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003898 QCBOREncode_AddInt64(pMe, nLabel);
3899 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01003900}
3901
3902
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003903static inline void
3904QCBOREncode_AddNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003905{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003906 QCBOREncode_Private_AddSimple(pMe, CBOR_SIMPLEV_NULL);
Michael Eckel5c531332020-03-02 01:35:30 +01003907}
3908
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003909static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003910QCBOREncode_AddNULLToMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003911{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003912 QCBOREncode_AddSZString(pMe, szLabel);
3913 QCBOREncode_AddNULL(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003914}
3915
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003916static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003917QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003918{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003919 QCBOREncode_AddInt64(pMe, nLabel);
3920 QCBOREncode_AddNULL(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003921}
3922
3923
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003924static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003925QCBOREncode_AddUndef(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003926{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003927 QCBOREncode_Private_AddSimple(pMe, CBOR_SIMPLEV_UNDEF);
Michael Eckel5c531332020-03-02 01:35:30 +01003928}
3929
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003930static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003931QCBOREncode_AddUndefToMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003932{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003933 QCBOREncode_AddSZString(pMe, szLabel);
3934 QCBOREncode_AddUndef(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003935}
3936
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003937static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003938QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003939{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003940 QCBOREncode_AddInt64(pMe, nLabel);
3941 QCBOREncode_AddUndef(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003942}
3943
3944
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003945static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003946QCBOREncode_OpenArray(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003947{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003948 QCBOREncode_Private_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
Michael Eckel5c531332020-03-02 01:35:30 +01003949}
3950
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003951static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003952QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003953{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003954 QCBOREncode_AddSZString(pMe, szLabel);
3955 QCBOREncode_OpenArray(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003956}
3957
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003958static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003959QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003960{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003961 QCBOREncode_AddInt64(pMe, nLabel);
3962 QCBOREncode_OpenArray(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003963}
3964
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -08003965
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003966static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003967QCBOREncode_CloseArray(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003968{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003969 QCBOREncode_Private_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
Michael Eckel5c531332020-03-02 01:35:30 +01003970}
3971
3972
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003973static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003974QCBOREncode_OpenMap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003975{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003976 QCBOREncode_Private_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
Michael Eckel5c531332020-03-02 01:35:30 +01003977}
3978
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003979static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003980QCBOREncode_OpenMapInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003981{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003982 QCBOREncode_AddSZString(pMe, szLabel);
3983 QCBOREncode_OpenMap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003984}
3985
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003986static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003987QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003988{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003989 QCBOREncode_AddInt64(pMe, nLabel);
3990 QCBOREncode_OpenMap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003991}
3992
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003993static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003994QCBOREncode_CloseMap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003995{
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -08003996 (pMe->pfnCloseMap)(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003997}
3998
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003999static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004000QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01004001{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004002 QCBOREncode_Private_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01004003}
4004
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004005static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07004006QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pMe,
4007 const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01004008{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004009 QCBOREncode_AddSZString(pMe, szLabel);
4010 QCBOREncode_OpenArrayIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01004011}
4012
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004013static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07004014QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004015 const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01004016{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004017 QCBOREncode_AddInt64(pMe, nLabel);
4018 QCBOREncode_OpenArrayIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01004019}
4020
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004021static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004022QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01004023{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004024 QCBOREncode_Private_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01004025}
4026
4027
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004028static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004029QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01004030{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004031 QCBOREncode_Private_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01004032}
4033
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004034static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07004035QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pMe,
4036 const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01004037{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004038 QCBOREncode_AddSZString(pMe, szLabel);
4039 QCBOREncode_OpenMapIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01004040}
4041
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004042static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07004043QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004044 const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01004045{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004046 QCBOREncode_AddInt64(pMe, nLabel);
4047 QCBOREncode_OpenMapIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01004048}
4049
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004050static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004051QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01004052{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004053 QCBOREncode_Private_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01004054}
4055
4056
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004057static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004058QCBOREncode_BstrWrap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01004059{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004060 QCBOREncode_Private_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_BYTE_STRING);
Michael Eckel5c531332020-03-02 01:35:30 +01004061}
4062
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004063static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004064QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01004065{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004066 QCBOREncode_AddSZString(pMe, szLabel);
4067 QCBOREncode_BstrWrap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01004068}
4069
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004070static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004071QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01004072{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004073 QCBOREncode_AddInt64(pMe, nLabel);
4074 QCBOREncode_BstrWrap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01004075}
4076
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004077static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004078QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pMe, UsefulBufC *pWrappedCBOR)
Michael Eckel5c531332020-03-02 01:35:30 +01004079{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004080 QCBOREncode_CloseBstrWrap2(pMe, true, pWrappedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01004081}
4082
4083
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004084static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004085QCBOREncode_AddEncoded(QCBOREncodeContext *pMe, const UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01004086{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004087 QCBOREncode_Private_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_RAW, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01004088}
4089
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004090static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07004091QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pMe,
4092 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004093 const UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01004094{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004095 QCBOREncode_AddSZString(pMe, szLabel);
4096 QCBOREncode_AddEncoded(pMe, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01004097}
4098
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004099static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07004100QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004101 const int64_t nLabel,
4102 const UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01004103{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004104 QCBOREncode_AddInt64(pMe, nLabel);
4105 QCBOREncode_AddEncoded(pMe, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01004106}
4107
4108
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004109static inline int
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004110QCBOREncode_IsBufferNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01004111{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004112 return UsefulOutBuf_IsBufferNULL(&(pMe->OutBuf));
Michael Eckel5c531332020-03-02 01:35:30 +01004113}
4114
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004115static inline QCBORError
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004116QCBOREncode_GetErrorState(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01004117{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004118 if(UsefulOutBuf_GetError(&(pMe->OutBuf))) {
Michael Eckel5c531332020-03-02 01:35:30 +01004119 // Items didn't fit in the buffer.
4120 // This check catches this condition for all the appends and inserts
4121 // so checks aren't needed when the appends and inserts are performed.
4122 // And of course UsefulBuf will never overrun the input buffer given
4123 // to it. No complex analysis of the error handling in this file is
4124 // needed to know that is true. Just read the UsefulBuf code.
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004125 pMe->uError = QCBOR_ERR_BUFFER_TOO_SMALL;
Michael Eckel5c531332020-03-02 01:35:30 +01004126 // QCBOR_ERR_BUFFER_TOO_SMALL masks other errors, but that is
4127 // OK. Once the caller fixes this, they'll be unmasked.
4128 }
4129
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004130 return (QCBORError)pMe->uError;
Michael Eckel5c531332020-03-02 01:35:30 +01004131}
4132
4133
Laurence Lundblade45d5e482020-09-15 21:15:15 -07004134/* ========================================================================
4135 END OF PRIVATE INLINE IMPLEMENTATION
4136 ======================================================================== */
Michael Eckel5c531332020-03-02 01:35:30 +01004137
4138#ifdef __cplusplus
4139}
4140#endif
4141
Laurence Lundblade844bb5c2020-03-01 17:27:25 -08004142#endif /* qcbor_encode_h */