blob: 0aa28f6e71127561bce02035cc3687959bdcd787 [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 *
438 * If allocating on the stack the convenience macro
439 * 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 Lundblade3eead482023-12-16 20:53:22 -0700472 * @brief Add a signed 64-bit integer to the encoded output.
473 *
474 * @param[in] pCtx The encoding context to add the integer to.
475 * @param[in] nNum The integer to add.
476 *
477 * The integer will be encoded and added to the CBOR output.
478 *
479 * This function figures out the size and the sign and encodes in the
480 * correct minimal CBOR. Specifically, it will select CBOR major type
481 * 0 or 1 based on sign and will encode to 1, 2, 4 or 8 bytes
482 * depending on the value of the integer. Values less than 24
483 * effectively encode to one byte because they are encoded in with the
484 * CBOR major type. This is a neat and efficient characteristic of
485 * CBOR that can be taken advantage of when designing CBOR-based
486 * protocols. If integers like tags can be kept between -23 and 23
487 * they will be encoded in one byte including the major type.
488 *
489 * If you pass a smaller int, say an @c int16_t or a small value, say
490 * 100, the encoding will still be CBOR's most compact that can
491 * represent the value. For example, CBOR always encodes the value 0
492 * as one byte, 0x00. The representation as 0x00 includes
493 * identification of the type as an integer too as the major type for
494 * an integer is 0. See [RFC 8949]
495 * (https://tools.ietf.org/html/rfc8949) Appendix A for more examples
496 * of CBOR encoding. This compact encoding is also preferred
497 * serialization CBOR as per section 34.1 in RFC 8949.
498 *
499 * There are no functions to add @c int16_t or @c int32_t because they
500 * are not necessary because this always encodes to the smallest
501 * number of bytes based on the value (If this code is running on a
502 * 32-bit machine having a way to add 32-bit integers would reduce
503 * code size some).
504 *
505 * If the encoding context is in an error state, this will do
506 * nothing. If an error occurs when adding this integer, the internal
507 * error flag will be set, and the error will be returned when
508 * QCBOREncode_Finish() is called.
509 *
510 * See also QCBOREncode_AddUInt64().
Michael Eckel5c531332020-03-02 01:35:30 +0100511 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700512void
513QCBOREncode_AddInt64(QCBOREncodeContext *pCtx, int64_t nNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100514
Laurence Lundblade3eead482023-12-16 20:53:22 -0700515static void
516QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100517
Laurence Lundblade3eead482023-12-16 20:53:22 -0700518static void
519QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100520
521
522/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700523 * @brief Add an unsigned 64-bit integer to the encoded output.
524 *
525 * @param[in] pCtx The encoding context to add the integer to.
526 * @param[in] uNum The integer to add.
527 *
528 * The integer will be encoded and added to the CBOR output.
529 *
530 * The only reason so use this function is for integers larger than
531 * @c INT64_MAX and smaller than @c UINT64_MAX. Otherwise
532 * QCBOREncode_AddInt64() will work fine.
533 *
534 * Error handling is the same as for QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +0100535 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700536void
537QCBOREncode_AddUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100538
Laurence Lundblade3eead482023-12-16 20:53:22 -0700539static void
540QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100541
Laurence Lundblade3eead482023-12-16 20:53:22 -0700542static void
543QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100544
545
546/**
Laurence Lundblade2d493002024-02-01 11:09:17 -0700547 * @brief Add a negative 64-bit integer to encoded output
548 *
549 * @param[in] pCtx The encoding context to add the integer to.
550 * @param[in] uNum The integer to add.
551 *
552 * QCBOREncode_AddInt64() is much better to encode negative integers
553 * than this. What this can do is add integers with one more
554 * significant bit than an int64_t (a "65-bit" integer if you count
555 * the sign as a bit) which is possible because CBOR happens to
556 * support such integers.
557 *
558 * The actual value encoded is -uNum - 1. That is, give 0 for uNum to
559 * transmit -1, give 1 to transmit -2 and give UINT64_MAX to transmit
560 * -UINT64_MAX-1 (18446744073709551616). The interface is odd like
561 * this so all negative values CBOR can represent can be encoded by
562 * QCBOR (making this a complete CBOR implementation).
563 *
564 * The most negative value QCBOREncode_AddInt64() can encode is
565 * -9223372036854775808 which is -2^63 or negative
566 * 0x800000000000. This can encode from -9223372036854775809 to
567 * -18446744073709551616 or -2^63 - 1 to -2^64. Note that
568 * it is not possible to represent plus or minus 18446744073709551616
569 * in any standard C data type.
570 *
571 * Negative integers are normally decoded in QCBOR with type
572 * @ref QCBOR_TYPE_INT64. Integers in the range of -9223372036854775809
573 * to -18446744073709551616 are returned as @ref QCBOR_TYPE_65BIT_NEG_INT.
574 *
575 * WARNING: some CBOR decoders will be unable to decode -2^63 - 1 to
576 * -2^64. Also, most CPUs do not have registers that can represent
577 * this range. If you need 65-bit negative integers, you likely need
578 * negative 66, 67 and 68-bit negative integers so it is likely better
579 * to use CBOR big numbers where you can have any number of bits. See
580 * QCBOREncode_AddTNegativeBignum() and TODO: also xxxx
581 */
582void
583QCBOREncode_AddNegativeUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
584
585static void
586QCBOREncode_AddNegativeUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum);
587
588static void
589QCBOREncode_AddNegativeUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum);
590
591/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700592 * @brief Add a UTF-8 text string to the encoded output.
593 *
594 * @param[in] pCtx The encoding context to add the text to.
595 * @param[in] Text Pointer and length of text to add.
596 *
597 * The text passed in must be unencoded UTF-8 according to [RFC 3629]
598 * (https://tools.ietf.org/html/rfc3629). There is no NULL
599 * termination. The text is added as CBOR major type 3.
600 *
601 * If called with @c nBytesLen equal to 0, an empty string will be
602 * added. When @c nBytesLen is 0, @c pBytes may be @c NULL.
603 *
604 * Note that the restriction of the buffer length to a @c uint32_t is
605 * entirely intentional as this encoder is not capable of encoding
606 * lengths greater. This limit to 4GB for a text string should not be
607 * a problem.
608 *
609 * Text lines in Internet protocols (on the wire) are delimited by
610 * either a CRLF or just an LF. Officially many protocols specify
611 * CRLF, but implementations often work with either. CBOR type 3 text
612 * can be either line ending, even a mixture of both.
613 *
614 * Operating systems usually have a line end convention. Windows uses
615 * CRLF. Linux and MacOS use LF. Some applications on a given OS may
616 * work with either and some may not.
617 *
618 * The majority of use cases and CBOR protocols using type 3 text will
619 * work with either line ending. However, some use cases or protocols
620 * may not work with either in which case translation to and/or from
621 * the local line end convention, typically that of the OS, is
622 * necessary.
623 *
624 * QCBOR does no line ending translation for type 3 text when encoding
625 * and decoding.
626 *
627 * Error handling is the same as QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +0100628 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700629static void
630QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text);
Michael Eckel5c531332020-03-02 01:35:30 +0100631
Laurence Lundblade3eead482023-12-16 20:53:22 -0700632static void
633QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text);
Michael Eckel5c531332020-03-02 01:35:30 +0100634
Laurence Lundblade3eead482023-12-16 20:53:22 -0700635static void
636QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text);
Michael Eckel5c531332020-03-02 01:35:30 +0100637
638
639/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700640 * @brief Add a UTF-8 text string to the encoded output.
641 *
642 * @param[in] pCtx The encoding context to add the text to.
643 * @param[in] szString Null-terminated text to add.
644 *
645 * This works the same as QCBOREncode_AddText().
Michael Eckel5c531332020-03-02 01:35:30 +0100646 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700647static void
648QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString);
Michael Eckel5c531332020-03-02 01:35:30 +0100649
Laurence Lundblade3eead482023-12-16 20:53:22 -0700650static void
651QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString);
Michael Eckel5c531332020-03-02 01:35:30 +0100652
Laurence Lundblade3eead482023-12-16 20:53:22 -0700653static void
654QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString);
Michael Eckel5c531332020-03-02 01:35:30 +0100655
656
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200657#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Michael Eckel5c531332020-03-02 01:35:30 +0100658/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700659 * @brief Add a double-precision floating-point number to the encoded output.
660 *
661 * @param[in] pCtx The encoding context to add the double to.
662 * @param[in] dNum The double-precision number to add.
663 *
664 * This encodes and outputs a floating-point number. CBOR major type 7
665 * is used.
666 *
667 * This implements preferred serialization, selectively encoding the
668 * double-precision floating-point number as either double-precision,
669 * single-precision or half-precision. Infinity, NaN and 0 are always
670 * encoded as half-precision. If no precision will be lost in the
671 * conversion to half-precision, then it will be converted and
672 * encoded. If not and no precision will be lost in conversion to
673 * single-precision, then it will be converted and encoded. If not,
674 * then no conversion is performed, and it encoded as a
675 * double-precision.
676 *
677 * Half-precision floating-point numbers take up 2 bytes, half that of
678 * single-precision, one quarter of double-precision
679 *
680 * This automatically reduces the size of encoded CBOR, maybe even by
681 * four if most of values are 0, infinity or NaN.
682 *
683 * When decoded, QCBOR will usually return these values as
684 * double-precision.
685 *
686 * It is possible to disable this preferred serialization when compiling
687 * QCBOR. In that case, this functions the same as
688 * QCBOREncode_AddDoubleNoPreferred().
689 *
690 * Error handling is the same as QCBOREncode_AddInt64().
691 *
692 * See also QCBOREncode_AddDoubleNoPreferred(), QCBOREncode_AddFloat()
693 * and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
Michael Eckel5c531332020-03-02 01:35:30 +0100694 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700695void
696QCBOREncode_AddDouble(QCBOREncodeContext *pCtx, double dNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100697
Laurence Lundblade3eead482023-12-16 20:53:22 -0700698static void
699QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100700
Laurence Lundblade3eead482023-12-16 20:53:22 -0700701static void
702QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100703
704
705/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700706 * @brief Add a single-precision floating-point number to the encoded output.
707 *
708 * @param[in] pCtx The encoding context to add the double to.
709 * @param[in] fNum The single-precision number to add.
710 *
711 * This is identical to QCBOREncode_AddDouble() except the input is
712 * single-precision.
713 *
714 * See also QCBOREncode_AddDouble(), QCBOREncode_AddDoubleNoPreferred(),
715 * and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
716 */
717void
718QCBOREncode_AddFloat(QCBOREncodeContext *pCtx, float fNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700719
Laurence Lundblade3eead482023-12-16 20:53:22 -0700720static void
721QCBOREncode_AddFloatToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700722
Laurence Lundblade3eead482023-12-16 20:53:22 -0700723static void
724QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700725
726
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700727/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700728 * @brief Add a double-precision floating-point number without preferred encoding.
729 *
730 * @param[in] pCtx The encoding context to add the double to.
731 * @param[in] dNum The double-precision number to add.
732 *
733 * This always outputs the number as a 64-bit double-precision.
734 * Preferred serialization is not used.
735 *
736 * Error handling is the same as QCBOREncode_AddInt64().
737 *
738 * See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
739 * QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
740 */
741void
742QCBOREncode_AddDoubleNoPreferred(QCBOREncodeContext *pCtx, double dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700743
Laurence Lundblade3eead482023-12-16 20:53:22 -0700744static void
745QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700746
Laurence Lundblade3eead482023-12-16 20:53:22 -0700747static void
748QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700749
750
751/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700752 * @brief Add a single-precision floating-point number without preferred encoding.
753 *
754 * @param[in] pCtx The encoding context to add the double to.
755 * @param[in] fNum The single-precision number to add.
756 *
757 * This always outputs the number as a 32-bit single-precision.
758 * Preferred serialization is not used.
759 *
760 * Error handling is the same as QCBOREncode_AddInt64().
761 *
762 * See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
763 * QCBOREncode_AddDoubleNoPreferred() and @ref Floating-Point.
764 */
765void
766QCBOREncode_AddFloatNoPreferred(QCBOREncodeContext *pCtx, float fNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700767
Laurence Lundblade3eead482023-12-16 20:53:22 -0700768static void
769QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700770
Laurence Lundblade3eead482023-12-16 20:53:22 -0700771static void
772QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float fNum);
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200773#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700774
775
Michael Eckel5c531332020-03-02 01:35:30 +0100776/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700777 * @brief Add an optional tag.
778 *
779 * @param[in] pCtx The encoding context to add the tag to.
780 * @param[in] uTag The tag to add
781 *
782 * This outputs a CBOR major type 6 item that tags the next data item
783 * that is output usually to indicate it is some new data type.
784 *
785 * For many of the common standard tags, a function to encode data
786 * using it is provided and this is not needed. For example,
787 * QCBOREncode_AddDateEpoch() already exists to output integers
788 * representing dates with the right tag.
789 *
790 * The tag is applied to the next data item added to the encoded
791 * output. That data item that is to be tagged can be of any major
792 * CBOR type. Any number of tags can be added to a data item by
793 * calling this multiple times before the data item is added.
794 *
795 * See @ref Tags-Overview for discussion of creating new non-standard
796 * tags. See QCBORDecode_GetNext() for discussion of decoding custom
797 * tags.
Michael Eckel5c531332020-03-02 01:35:30 +0100798 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700799void
800QCBOREncode_AddTag(QCBOREncodeContext *pCtx, uint64_t uTag);
Laurence Lundblade46d63e92021-05-13 11:37:10 -0700801
802
Michael Eckel5c531332020-03-02 01:35:30 +0100803/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700804 * @brief Add an epoch-based date.
805 *
806 * @param[in] pCtx The encoding context to add the date to.
807 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
808 * @ref QCBOR_ENCODE_AS_BORROWED.
809 * @param[in] nDate Number of seconds since 1970-01-01T00:00Z
810 * in UTC time.
811 *
812 * As per RFC 8949 this is similar to UNIX/Linux/POSIX dates. This is
813 * the most compact way to specify a date and time in CBOR. Note that
814 * this is always UTC and does not include the time zone. Use
815 * QCBOREncode_AddDateString() if you want to include the time zone.
816 *
817 * The preferred integer serialization rules apply here so the date will be
818 * encoded in a minimal number of bytes. Until about the year 2106
819 * these dates will encode in 6 bytes -- one byte for the tag, one
820 * byte for the type and 4 bytes for the integer. After that it will
821 * encode to 10 bytes.
822 *
823 * Negative values are supported for dates before 1970.
824 *
825 * If you care about leap-seconds and that level of accuracy, make sure
826 * the system you are running this code on does it correctly. This code
827 * just takes the value passed in.
828 *
829 * This implementation cannot encode fractional seconds using float or
830 * double even though that is allowed by CBOR, but you can encode them
831 * if you want to by calling QCBOREncode_AddTag() and QCBOREncode_AddDouble().
832 *
833 * Error handling is the same as QCBOREncode_AddInt64().
834 *
835 * See also QCBOREncode_AddTDaysEpoch().
Michael Eckel5c531332020-03-02 01:35:30 +0100836 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700837static void
838QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pCtx,
839 uint8_t uTagRequirement,
840 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100841
Laurence Lundblade3eead482023-12-16 20:53:22 -0700842static void
843QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pCtx,
844 const char *szLabel,
845 uint8_t uTagRequirement,
846 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100847
Laurence Lundblade3eead482023-12-16 20:53:22 -0700848static void
849QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pCtx,
850 int64_t nLabel,
851 uint8_t uTagRequirement,
852 int64_t nDate);
853
854
855static void
856QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx,
857 int64_t nDate);
858
859static void
860QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx,
861 const char *szLabel,
862 int64_t nDate);
863
864static void
865QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx,
866 int64_t nLabel,
867 int64_t nDate);
868
Michael Eckel5c531332020-03-02 01:35:30 +0100869
870
Michael Eckel5c531332020-03-02 01:35:30 +0100871/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700872 * @brief Add an epoch-based day-count date.
873 *
874 * @param[in] pCtx The encoding context to add the date to.
875 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
876 * @ref QCBOR_ENCODE_AS_BORROWED.
877 * @param[in] nDays Number of days before or after 1970-01-0.
878 *
879 * This date format is described in
880 * [RFC 8943] (https://tools.ietf.org/html/rfc8943).
881 *
882 * The preferred integer serialization rules apply here so the date
883 * will be encoded in a minimal number of bytes. Until about the year
884 * 2149 these dates will encode in 4 bytes -- one byte for the tag,
885 * one byte for the type and 2 bytes for the integer.
886 *
887 * See also QCBOREncode_AddTDateEpoch().
888 */
889static void
890QCBOREncode_AddTDaysEpoch(QCBOREncodeContext *pCtx,
891 uint8_t uTagRequirement,
892 int64_t nDays);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600893
Laurence Lundblade3eead482023-12-16 20:53:22 -0700894static void
895QCBOREncode_AddTDaysEpochToMapSZ(QCBOREncodeContext *pCtx,
896 const char *szLabel,
897 uint8_t uTagRequirement,
898 int64_t nDays);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600899
Laurence Lundblade3eead482023-12-16 20:53:22 -0700900static void
901QCBOREncode_AddTDaysEpochToMapN(QCBOREncodeContext *pCtx,
902 int64_t nLabel,
903 uint8_t uTagRequirement,
904 int64_t nDays);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600905
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600906
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600907
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600908
Laurence Lundblade3eead482023-12-16 20:53:22 -0700909/**
910 * @brief Add a byte string to the encoded output.
911 *
912 * @param[in] pCtx The encoding context to add the bytes to.
913 * @param[in] Bytes Pointer and length of the input data.
914 *
915 * Simply adds the bytes to the encoded output as CBOR major type 2.
916 *
917 * If called with @c Bytes.len equal to 0, an empty string will be
918 * added. When @c Bytes.len is 0, @c Bytes.ptr may be @c NULL.
919 *
920 * Error handling is the same as QCBOREncode_AddInt64().
921 */
922static void
923QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600924
Laurence Lundblade3eead482023-12-16 20:53:22 -0700925static void
926QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
927
928static void
929QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
930
931
932/**
933 * @brief Set up to write a byte string value directly to encoded output.
934 *
935 * @param[in] pCtx The encoding context to add the bytes to.
936 * @param[out] pPlace Pointer and length of place to write byte string value.
937 *
938 * QCBOREncode_AddBytes() is the normal way to encode a byte string.
939 * This is for special cases and by passes some of the pointer safety.
940 *
941 * The purpose of this is to output the bytes that make up a byte
942 * string value directly to the QCBOR output buffer so you don't need
943 * to have a copy of it in memory. This is particularly useful if the
944 * byte string is large, for example, the encrypted payload of a
945 * COSE_Encrypt message. The payload encryption algorithm can output
946 * directly to the encoded CBOR buffer, perhaps by making it the
947 * output buffer for some function (e.g. symmetric encryption) or by
948 * multiple writes.
949 *
950 * The pointer in @c pPlace is where to start writing. Writing is just
951 * copying bytes to the location by the pointer in \c pPlace. Writing
952 * past the length in @c pPlace will be writing off the end of the
953 * output buffer.
954 *
955 * If there is no room in the output buffer @ref NULLUsefulBuf will be
956 * returned and there is no need to call QCBOREncode_CloseBytes().
957 *
958 * The byte string must be closed by calling QCBOREncode_CloseBytes().
959 *
960 * Warning: this bypasses some of the usual checks provided by QCBOR
961 * against writing off the end of the encoded output buffer.
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600962 */
963void
964QCBOREncode_OpenBytes(QCBOREncodeContext *pCtx, UsefulBuf *pPlace);
965
966static void
Laurence Lundblade3eead482023-12-16 20:53:22 -0700967QCBOREncode_OpenBytesInMapSZ(QCBOREncodeContext *pCtx,
968 const char *szLabel,
969 UsefulBuf *pPlace);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600970
971static void
Laurence Lundblade3eead482023-12-16 20:53:22 -0700972QCBOREncode_OpenBytesInMapN(QCBOREncodeContext *pCtx,
973 int64_t nLabel,
974 UsefulBuf *pPlace);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600975
976
977/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700978 * @brief Close out a byte string written directly to encoded output.
979 *
980 * @param[in] pCtx The encoding context to add the bytes to.
981 * @param[out] uAmount The number of bytes written, the length of the
982 * byte string.
983 *
984 * This closes out a call to QCBOREncode_OpenBytes(). This inserts a
985 * CBOR header at the front of the byte string value to make it a
986 * well-formed byte string.
987 *
988 * If there was no call to QCBOREncode_OpenBytes() then @ref
989 * QCBOR_ERR_TOO_MANY_CLOSES is set.
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600990 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700991void
992QCBOREncode_CloseBytes(QCBOREncodeContext *pCtx, size_t uAmount);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600993
994
995/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700996 * @brief Add a binary UUID to the encoded output.
997 *
998 * @param[in] pCtx The encoding context to add the UUID to.
999 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1000 * @ref QCBOR_ENCODE_AS_BORROWED.
1001 * @param[in] Bytes Pointer and length of the binary UUID.
1002 *
1003 * A binary UUID as defined in [RFC 4122]
1004 * (https://tools.ietf.org/html/rfc4122) is added to the output.
1005 *
1006 * It is output as CBOR major type 2, a binary string, with tag @ref
1007 * CBOR_TAG_BIN_UUID indicating the binary string is a UUID.
Michael Eckel5c531332020-03-02 01:35:30 +01001008 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001009static void
1010QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pCtx,
1011 uint8_t uTagRequirement,
1012 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001013
Laurence Lundblade3eead482023-12-16 20:53:22 -07001014static void
1015QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pCtx,
1016 const char *szLabel,
1017 uint8_t uTagRequirement,
1018 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001019
Laurence Lundblade3eead482023-12-16 20:53:22 -07001020static void
1021QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pCtx,
1022 int64_t nLabel,
1023 uint8_t uTagRequirement,
1024 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001025
1026
Laurence Lundblade3eead482023-12-16 20:53:22 -07001027static void
1028QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001029
Laurence Lundblade3eead482023-12-16 20:53:22 -07001030static void
1031QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001032
Laurence Lundblade3eead482023-12-16 20:53:22 -07001033static void
1034QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001035
1036
1037/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001038 * @brief Add a positive big number to the encoded output.
1039 *
1040 * @param[in] pCtx The encoding context to add the big number to.
1041 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1042 * @ref QCBOR_ENCODE_AS_BORROWED.
1043 * @param[in] Bytes Pointer and length of the big number.
1044 *
1045 * Big numbers are integers larger than 64-bits. Their format is
1046 * described in [RFC 8949] (https://tools.ietf.org/html/rfc8949).
1047 *
1048 * It is output as CBOR major type 2, a binary string, with tag
1049 * @ref CBOR_TAG_POS_BIGNUM indicating the binary string is a positive
1050 * big number.
1051 *
1052 * Often big numbers are used to represent cryptographic keys,
1053 * however, COSE which defines representations for keys chose not to
1054 * use this particular type.
Michael Eckel5c531332020-03-02 01:35:30 +01001055 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001056static void
1057QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pCtx,
1058 uint8_t uTagRequirement,
1059 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001060
Laurence Lundblade3eead482023-12-16 20:53:22 -07001061static void
1062QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pCtx,
1063 const char *szLabel,
1064 uint8_t uTagRequirement,
1065 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001066
Laurence Lundblade3eead482023-12-16 20:53:22 -07001067static void
1068QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pCtx,
1069 int64_t nLabel,
1070 uint8_t uTagRequirement,
1071 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001072
1073
Laurence Lundblade3eead482023-12-16 20:53:22 -07001074static void
1075QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx,
1076 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001077
Laurence Lundblade3eead482023-12-16 20:53:22 -07001078static void
1079QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx,
1080 const char *szLabel,
1081 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001082
Laurence Lundblade3eead482023-12-16 20:53:22 -07001083static void
1084QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx,
1085 int64_t nLabel,
1086 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001087
1088
1089/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001090 * @brief Add a negative big number to the encoded output.
1091 *
1092 * @param[in] pCtx The encoding context to add the big number to.
1093 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1094 * @ref QCBOR_ENCODE_AS_BORROWED.
1095 * @param[in] Bytes Pointer and length of the big number.
1096 *
1097 * Big numbers are integers larger than 64-bits. Their format is
1098 * described in [RFC 8949] (https://tools.ietf.org/html/rfc8949).
1099 *
1100 * It is output as CBOR major type 2, a binary string, with tag
1101 * @ref CBOR_TAG_NEG_BIGNUM indicating the binary string is a negative
1102 * big number.
1103 *
1104 * Often big numbers are used to represent cryptographic keys,
1105 * however, COSE which defines representations for keys chose not to
1106 * use this particular type.
Michael Eckel5c531332020-03-02 01:35:30 +01001107 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001108static void
1109QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pCtx,
1110 uint8_t uTagRequirement,
1111 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001112
Laurence Lundblade3eead482023-12-16 20:53:22 -07001113static void
1114QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pCtx,
1115 const char *szLabel,
1116 uint8_t uTagRequirement,
1117 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001118
Laurence Lundblade3eead482023-12-16 20:53:22 -07001119static void
1120QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pCtx,
1121 int64_t nLabel,
1122 uint8_t uTagRequirement,
1123 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001124
1125
Laurence Lundblade3eead482023-12-16 20:53:22 -07001126static void
1127QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx,
1128 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001129
Laurence Lundblade3eead482023-12-16 20:53:22 -07001130static void
1131QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx,
1132 const char *szLabel,
1133 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001134
Laurence Lundblade3eead482023-12-16 20:53:22 -07001135static void
1136QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx,
1137 int64_t nLabel,
1138 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001139
1140
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07001141#ifndef QCBOR_DISABLE_EXP_AND_MANTISSA
Michael Eckel5c531332020-03-02 01:35:30 +01001142/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001143 * @brief Add a decimal fraction to the encoded output.
1144 *
1145 * @param[in] pCtx Encoding context to add the decimal fraction to.
1146 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1147 * @ref QCBOR_ENCODE_AS_BORROWED.
1148 * @param[in] nMantissa The mantissa.
1149 * @param[in] nBase10Exponent The exponent.
1150 *
1151 * The value is nMantissa * 10 ^ nBase10Exponent.
1152 *
1153 * A decimal fraction is good for exact representation of some values
1154 * that can't be represented exactly with standard C (IEEE 754)
1155 * floating-point numbers. Much larger and much smaller numbers can
1156 * also be represented than floating-point because of the larger
1157 * number of bits in the exponent.
1158 *
1159 * The decimal fraction is conveyed as two integers, a mantissa and a
1160 * base-10 scaling factor.
1161 *
1162 * For example, 273.15 is represented by the two integers 27315 and -2.
1163 *
1164 * The exponent and mantissa have the range from @c INT64_MIN to
1165 * @c INT64_MAX for both encoding and decoding (CBOR allows
1166 * @c -UINT64_MAX to @c UINT64_MAX, but this implementation doesn't
1167 * support this range to reduce code size and interface complexity a
1168 * little).
1169 *
1170 * CBOR Preferred serialization of the integers is used, thus they
1171 * will be encoded in the smallest number of bytes possible.
1172 *
1173 * See also QCBOREncode_AddDecimalFractionBigNum() for a decimal
1174 * fraction with arbitrarily large precision and
1175 * QCBOREncode_AddBigFloat().
1176 *
1177 * There is no representation of positive or negative infinity or NaN
1178 * (Not a Number). Use QCBOREncode_AddDouble() to encode them.
1179 *
1180 * See @ref expAndMantissa for decoded representation.
Michael Eckel5c531332020-03-02 01:35:30 +01001181 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001182static void
1183QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pCtx,
1184 uint8_t uTagRequirement,
1185 int64_t nMantissa,
1186 int64_t nBase10Exponent);
1187
1188static void
1189QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pCtx,
1190 const char *szLabel,
1191 uint8_t uTagRequirement,
1192 int64_t nMantissa,
1193 int64_t nBase10Exponent);
1194
1195static void
1196QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pCtx,
1197 int64_t nLabel,
1198 uint8_t uTagRequirement,
1199 int64_t nMantissa,
1200 int64_t nBase10Exponent);
1201
1202
1203static void
1204QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pCtx,
1205 int64_t nMantissa,
1206 int64_t nBase10Exponent);
1207
1208static void
1209QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pCtx,
1210 const char *szLabel,
1211 int64_t nMantissa,
1212 int64_t nBase10Exponent);
1213
1214static void
1215QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pCtx,
1216 int64_t nLabel,
1217 int64_t nMantissa,
1218 int64_t nBase10Exponent);
1219
1220
1221/**
1222 * @brief Add a decimal fraction with a big number mantissa to the encoded output.
1223 *
1224 * @param[in] pCtx Encoding context to add the decimal fraction to.
1225 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1226 * @ref QCBOR_ENCODE_AS_BORROWED.
1227 * @param[in] Mantissa The mantissa.
1228 * @param[in] bIsNegative false if mantissa is positive, true if negative.
1229 * @param[in] nBase10Exponent The exponent.
1230 *
1231 * This is the same as QCBOREncode_AddDecimalFraction() except the
1232 * mantissa is a big number (See QCBOREncode_AddPositiveBignum())
1233 * allowing for arbitrarily large precision.
1234 *
1235 * See @ref expAndMantissa for decoded representation.
1236 */
1237static void
1238QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pCtx,
1239 uint8_t uTagRequirement,
1240 UsefulBufC Mantissa,
1241 bool bIsNegative,
1242 int64_t nBase10Exponent);
1243
1244static void
1245QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
1246 const char *szLabel,
1247 uint8_t uTagRequirement,
1248 UsefulBufC Mantissa,
1249 bool bIsNegative,
1250 int64_t nBase10Exponent);
1251
1252static void
1253QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
1254 int64_t nLabel,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001255 uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07001256 UsefulBufC Mantissa,
1257 bool bIsNegative,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001258 int64_t nBase10Exponent);
1259
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001260
Laurence Lundblade3eead482023-12-16 20:53:22 -07001261static void
1262QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pCtx,
1263 UsefulBufC Mantissa,
1264 bool bIsNegative,
1265 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001266
Laurence Lundblade3eead482023-12-16 20:53:22 -07001267static void
1268QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001269 const char *szLabel,
Laurence Lundblade3eead482023-12-16 20:53:22 -07001270 UsefulBufC Mantissa,
1271 bool bIsNegative,
1272 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001273
Laurence Lundblade3eead482023-12-16 20:53:22 -07001274static void
1275QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001276 int64_t nLabel,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001277 UsefulBufC Mantissa,
1278 bool bIsNegative,
Laurence Lundblade3eead482023-12-16 20:53:22 -07001279 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001280
Laurence Lundblade3eead482023-12-16 20:53:22 -07001281/**
1282 * @brief Add a big floating-point number to the encoded output.
1283 *
1284 * @param[in] pCtx The encoding context to add the bigfloat to.
1285 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1286 * @ref QCBOR_ENCODE_AS_BORROWED.
1287 * @param[in] nMantissa The mantissa.
1288 * @param[in] nBase2Exponent The exponent.
1289 *
1290 * The value is nMantissa * 2 ^ nBase2Exponent.
1291 *
1292 * "Bigfloats", as CBOR terms them, are similar to IEEE floating-point
1293 * numbers in having a mantissa and base-2 exponent, but they are not
1294 * supported by hardware or encoded the same. They explicitly use two
1295 * CBOR-encoded integers to convey the mantissa and exponent, each of
1296 * which can be 8, 16, 32 or 64 bits. With both the mantissa and
1297 * exponent 64 bits they can express more precision and a larger range
1298 * than an IEEE double floating-point number. See
1299 * QCBOREncode_AddBigFloatBigNum() for even more precision.
1300 *
1301 * For example, 1.5 would be represented by a mantissa of 3 and an
1302 * exponent of -1.
1303 *
1304 * The exponent and mantissa have the range from @c INT64_MIN to
1305 * @c INT64_MAX for both encoding and decoding (CBOR allows @c
1306 * -UINT64_MAX to @c UINT64_MAX, but this implementation doesn't
1307 * support this range to reduce code size and interface complexity a
1308 * little).
1309 *
1310 * CBOR preferred serialization of the integers is used, thus they will
1311 * be encoded in the smallest number of bytes possible.
1312 *
1313 * This can also be used to represent floating-point numbers in
1314 * environments that don't support IEEE 754.
1315 *
1316 * See @ref expAndMantissa for decoded representation.
1317 */
1318static void
1319QCBOREncode_AddTBigFloat(QCBOREncodeContext *pCtx,
1320 uint8_t uTagRequirement,
1321 int64_t nMantissa,
1322 int64_t nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001323
Laurence Lundblade3eead482023-12-16 20:53:22 -07001324static void
1325QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pCtx,
1326 const char *szLabel,
1327 uint8_t uTagRequirement,
1328 int64_t nMantissa,
1329 int64_t nBase2Exponent);
1330
1331static void
1332QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pCtx,
1333 int64_t nLabel,
1334 uint8_t uTagRequirement,
1335 int64_t nMantissa,
1336 int64_t nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001337
1338
Laurence Lundblade3eead482023-12-16 20:53:22 -07001339static void
1340QCBOREncode_AddBigFloat(QCBOREncodeContext *pCtx,
1341 int64_t nMantissa,
1342 int64_t nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01001343
Laurence Lundblade3eead482023-12-16 20:53:22 -07001344static void
1345QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pCtx,
1346 const char *szLabel,
1347 int64_t nMantissa,
1348 int64_t nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01001349
Laurence Lundblade3eead482023-12-16 20:53:22 -07001350static void
1351QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pCtx,
1352 int64_t nLabel,
1353 int64_t nMantissa,
1354 int64_t nBase2Exponent);
1355
1356/**
1357 * @brief Add a big floating-point number with a big number mantissa to
1358 * the encoded output.
1359 *
1360 * @param[in] pCtx The encoding context to add the bigfloat to.
1361 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1362 * @ref QCBOR_ENCODE_AS_BORROWED.
1363 * @param[in] Mantissa The mantissa.
1364 * @param[in] bIsNegative false if mantissa is positive, true if negative.
1365 * @param[in] nBase2Exponent The exponent.
1366 *
1367 * This is the same as QCBOREncode_AddBigFloat() except the mantissa
1368 * is a big number (See QCBOREncode_AddPositiveBignum()) allowing for
1369 * arbitrary precision.
1370 *
1371 * See @ref expAndMantissa for decoded representation.
1372 */
1373static void
1374QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pCtx,
1375 uint8_t uTagRequirement,
1376 UsefulBufC Mantissa,
1377 bool bIsNegative,
1378 int64_t nBase2Exponent);
1379
1380static void
1381QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pCtx,
1382 const char *szLabel,
1383 uint8_t uTagRequirement,
1384 UsefulBufC Mantissa,
1385 bool bIsNegative,
1386 int64_t nBase2Exponent);
1387
1388static void
1389QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1390 int64_t nLabel,
1391 uint8_t uTagRequirement,
1392 UsefulBufC Mantissa,
1393 bool bIsNegative,
1394 int64_t nBase2Exponent);
1395
1396
1397static void
1398QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pCtx,
1399 UsefulBufC Mantissa,
1400 bool bIsNegative,
1401 int64_t nBase2Exponent);
1402
1403static void
1404QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pCtx,
1405 const char *szLabel,
1406 UsefulBufC Mantissa,
1407 bool bIsNegative,
1408 int64_t nBase2Exponent);
1409
1410static void
1411QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1412 int64_t nLabel,
1413 UsefulBufC Mantissa,
1414 bool bIsNegative,
1415 int64_t nBase2Exponent);
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07001416#endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
Michael Eckel5c531332020-03-02 01:35:30 +01001417
1418
1419/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001420 * @brief Add a text URI to the encoded output.
1421 *
1422 * @param[in] pCtx The encoding context to add the URI to.
1423 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1424 * @ref QCBOR_ENCODE_AS_BORROWED.
1425 * @param[in] URI Pointer and length of the URI.
1426 *
1427 * The format of URI must be per [RFC 3986]
1428 * (https://tools.ietf.org/html/rfc3986).
1429 *
1430 * It is output as CBOR major type 3, a text string, with tag @ref
1431 * CBOR_TAG_URI indicating the text string is a URI.
1432 *
1433 * A URI in a NULL-terminated string, @c szURI, can be easily added with
1434 * this code:
1435 *
1436 * QCBOREncode_AddURI(pCtx, UsefulBuf_FromSZ(szURI));
Michael Eckel5c531332020-03-02 01:35:30 +01001437 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001438static void
1439QCBOREncode_AddTURI(QCBOREncodeContext *pCtx,
1440 uint8_t uTagRequirement,
1441 UsefulBufC URI);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001442
Laurence Lundblade3eead482023-12-16 20:53:22 -07001443static void
1444QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pCtx,
1445 const char *szLabel,
1446 uint8_t uTagRequirement,
1447 UsefulBufC URI);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001448
Laurence Lundblade3eead482023-12-16 20:53:22 -07001449static void
1450QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pCtx,
1451 int64_t nLabel,
1452 uint8_t uTagRequirement,
1453 UsefulBufC URI);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001454
1455
Laurence Lundblade3eead482023-12-16 20:53:22 -07001456static void
1457QCBOREncode_AddURI(QCBOREncodeContext *pCtx,
1458 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001459
Laurence Lundblade3eead482023-12-16 20:53:22 -07001460static void
1461QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx,
1462 const char *szLabel,
1463 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001464
Laurence Lundblade3eead482023-12-16 20:53:22 -07001465static void
1466QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx,
1467 int64_t nLabel,
1468 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001469
1470
1471/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001472 * @brief Add Base64-encoded text to encoded output.
1473 *
1474 * @param[in] pCtx The encoding context to add the base-64 text to.
1475 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1476 * @ref QCBOR_ENCODE_AS_BORROWED.
1477 * @param[in] B64Text Pointer and length of the base-64 encoded text.
1478 *
1479 * The text content is Base64 encoded data per [RFC 4648]
1480 * (https://tools.ietf.org/html/rfc4648).
1481 *
1482 * It is output as CBOR major type 3, a text string, with tag @ref
1483 * CBOR_TAG_B64 indicating the text string is Base64 encoded.
Michael Eckel5c531332020-03-02 01:35:30 +01001484 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001485static void
1486QCBOREncode_AddTB64Text(QCBOREncodeContext *pCtx,
1487 uint8_t uTagRequirement,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001488 UsefulBufC B64Text);
1489
Laurence Lundblade3eead482023-12-16 20:53:22 -07001490static void
1491QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pCtx,
1492 const char *szLabel,
1493 uint8_t uTagRequirement,
1494 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001495
Laurence Lundblade3eead482023-12-16 20:53:22 -07001496static void
1497QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pCtx,
1498 int64_t nLabel,
1499 uint8_t uTagRequirement,
1500 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001501
1502
Laurence Lundblade3eead482023-12-16 20:53:22 -07001503static void
1504QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx,
1505 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001506
Laurence Lundblade3eead482023-12-16 20:53:22 -07001507static void
1508QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx,
1509 const char *szLabel,
1510 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001511
Laurence Lundblade3eead482023-12-16 20:53:22 -07001512static void
1513QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx,
1514 int64_t nLabel,
1515 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001516
1517
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001518
Michael Eckel5c531332020-03-02 01:35:30 +01001519/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001520 * @brief Add base64url encoded data to encoded output.
1521 *
1522 * @param[in] pCtx The encoding context to add the base64url to.
1523 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1524 * @ref QCBOR_ENCODE_AS_BORROWED.
1525 * @param[in] B64Text Pointer and length of the base64url encoded text.
1526 *
1527 * The text content is base64URL encoded text as per [RFC 4648]
1528 * (https://tools.ietf.org/html/rfc4648).
1529 *
1530 * It is output as CBOR major type 3, a text string, with tag
1531 * @ref CBOR_TAG_B64URL indicating the text string is a Base64url
1532 * encoded.
Michael Eckel5c531332020-03-02 01:35:30 +01001533 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001534static void
1535QCBOREncode_AddTB64URLText(QCBOREncodeContext *pCtx,
1536 uint8_t uTagRequirement,
1537 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001538
Laurence Lundblade3eead482023-12-16 20:53:22 -07001539static void
1540QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pCtx,
1541 const char *szLabel,
1542 uint8_t uTagRequirement,
1543 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001544
Laurence Lundblade3eead482023-12-16 20:53:22 -07001545static void
1546QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pCtx,
1547 int64_t nLabel,
1548 uint8_t uTagRequirement,
1549 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001550
1551
Laurence Lundblade3eead482023-12-16 20:53:22 -07001552static void
1553QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx,
1554 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001555
Laurence Lundblade3eead482023-12-16 20:53:22 -07001556static void
1557QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx,
1558 const char *szLabel,
1559 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001560
Laurence Lundblade3eead482023-12-16 20:53:22 -07001561static void
1562QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx,
1563 int64_t nLabel,
1564 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001565
1566
1567/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001568 * @brief Add Perl Compatible Regular Expression.
1569 *
1570 * @param[in] pCtx Encoding context to add the regular expression to.
1571 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1572 * @ref QCBOR_ENCODE_AS_BORROWED.
1573 * @param[in] Regex Pointer and length of the regular expression.
1574 *
1575 * The text content is Perl Compatible Regular
1576 * Expressions (PCRE) / JavaScript syntax [ECMA262].
1577 *
1578 * It is output as CBOR major type 3, a text string, with tag @ref
1579 * CBOR_TAG_REGEX indicating the text string is a regular expression.
Michael Eckel5c531332020-03-02 01:35:30 +01001580 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001581static void
1582QCBOREncode_AddTRegex(QCBOREncodeContext *pCtx,
1583 uint8_t uTagRequirement,
1584 UsefulBufC Regex);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001585
Laurence Lundblade3eead482023-12-16 20:53:22 -07001586static void
1587QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pCtx,
1588 const char *szLabel,
1589 uint8_t uTagRequirement,
1590 UsefulBufC Regex);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001591
Laurence Lundblade3eead482023-12-16 20:53:22 -07001592static void
1593QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pCtx,
1594 int64_t nLabel,
1595 uint8_t uTagRequirement,
1596 UsefulBufC Regex);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001597
1598
Laurence Lundblade3eead482023-12-16 20:53:22 -07001599static void
1600QCBOREncode_AddRegex(QCBOREncodeContext *pCtx,
1601 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001602
Laurence Lundblade3eead482023-12-16 20:53:22 -07001603static void
1604QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx,
1605 const char *szLabel,
1606 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001607
Laurence Lundblade3eead482023-12-16 20:53:22 -07001608static void
1609QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx,
1610 int64_t nLabel,
1611 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001612
1613
1614/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001615 * @brief MIME encoded data to the encoded output.
1616 *
1617 * @param[in] pCtx The encoding context to add the MIME data to.
1618 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1619 * @ref QCBOR_ENCODE_AS_BORROWED.
1620 * @param[in] MIMEData Pointer and length of the MIME data.
1621 *
1622 * The text content is in MIME format per [RFC 2045]
1623 * (https://tools.ietf.org/html/rfc2045) including the headers.
1624 *
1625 * It is output as CBOR major type 2, a binary string, with tag
1626 * @ref CBOR_TAG_BINARY_MIME indicating the string is MIME data. This
1627 * outputs tag 257, not tag 36, as it can carry any type of MIME
1628 * binary, 7-bit, 8-bit, quoted-printable and base64 where tag 36
1629 * cannot.
1630 *
1631 * Previous versions of QCBOR, those before spiffy decode, output tag
1632 * 36. Decoding supports both tag 36 and 257. (if the old behavior
1633 * with tag 36 is needed, copy the inline functions below and change
1634 * the tag number).
1635 *
1636 * See also QCBORDecode_GetMIMEMessage() and
1637 * @ref QCBOR_TYPE_BINARY_MIME.
1638 *
1639 * This does no translation of line endings. See QCBOREncode_AddText()
1640 * for a discussion of line endings in CBOR.
Michael Eckel5c531332020-03-02 01:35:30 +01001641 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001642static void
1643QCBOREncode_AddTMIMEData(QCBOREncodeContext *pCtx,
1644 uint8_t uTagRequirement,
1645 UsefulBufC MIMEData);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001646
Laurence Lundblade3eead482023-12-16 20:53:22 -07001647static void
1648QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pCtx,
1649 const char *szLabel,
1650 uint8_t uTagRequirement,
1651 UsefulBufC MIMEData);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001652
Laurence Lundblade3eead482023-12-16 20:53:22 -07001653static void
1654QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pCtx,
1655 int64_t nLabel,
1656 uint8_t uTagRequirement,
1657 UsefulBufC MIMEData);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001658
1659
Laurence Lundblade3eead482023-12-16 20:53:22 -07001660static void
1661QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx,
1662 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001663
Laurence Lundblade3eead482023-12-16 20:53:22 -07001664static void
1665QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx,
1666 const char *szLabel,
1667 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001668
Laurence Lundblade3eead482023-12-16 20:53:22 -07001669static void
1670QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx,
1671 int64_t nLabel,
1672 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001673
1674
1675/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001676 * @brief Add an RFC 3339 date string
1677 *
1678 * @param[in] pCtx The encoding context to add the date to.
1679 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1680 * @ref QCBOR_ENCODE_AS_BORROWED.
1681 * @param[in] szDate Null-terminated string with date to add.
1682 *
1683 * The string szDate should be in the form of [RFC 3339]
1684 * (https://tools.ietf.org/html/rfc3339) as defined by section 3.3 in
1685 * [RFC 4287] (https://tools.ietf.org/html/rfc4287). This is as
1686 * described in section 3.4.1 in [RFC 8949]
1687 * (https://tools.ietf.org/html/rfc8949).
1688 *
1689 * Note that this function doesn't validate the format of the date
1690 * string at all. If you add an incorrect format date string, the
1691 * generated CBOR will be incorrect and the receiver may not be able
1692 * to handle it.
1693 *
1694 * Error handling is the same as QCBOREncode_AddInt64().
1695 *
1696 * See also QCBOREncode_AddTDayString().
Michael Eckel5c531332020-03-02 01:35:30 +01001697 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001698static void
1699QCBOREncode_AddTDateString(QCBOREncodeContext *pCtx,
1700 uint8_t uTagRequirement,
1701 const char *szDate);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001702
Laurence Lundblade3eead482023-12-16 20:53:22 -07001703static void
1704QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pCtx,
1705 const char *szLabel,
1706 uint8_t uTagRequirement,
1707 const char *szDate);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001708
Laurence Lundblade3eead482023-12-16 20:53:22 -07001709static void
1710QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pCtx,
1711 int64_t nLabel,
1712 uint8_t uTagRequirement,
1713 const char *szDate);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001714
1715
Laurence Lundblade3eead482023-12-16 20:53:22 -07001716static void
1717QCBOREncode_AddDateString(QCBOREncodeContext *pCtx,
1718 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001719
Laurence Lundblade3eead482023-12-16 20:53:22 -07001720static void
1721QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx,
1722 const char *szLabel,
1723 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001724
Laurence Lundblade3eead482023-12-16 20:53:22 -07001725static void
1726QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx,
1727 int64_t nLabel,
1728 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001729
Laurence Lundblade46d63e92021-05-13 11:37:10 -07001730
1731/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001732 * @brief Add a date-only string.
1733 *
1734 * @param[in] pCtx The encoding context to add the date to.
1735 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1736 * @ref QCBOR_ENCODE_AS_BORROWED.
1737 * @param[in] szDate Null-terminated string with date to add.
1738 *
1739 * This date format is described in
1740 * [RFC 8943] (https://tools.ietf.org/html/rfc8943), but that mainly
1741 * references RFC 3339. The string szDate must be in the forrm
1742 * specified the ABNF for a full-date in
1743 * [RFC 3339] (https://tools.ietf.org/html/rfc3339). Examples of this
1744 * are "1985-04-12" and "1937-01-01". The time and the time zone are
1745 * never included.
1746 *
1747 * Note that this function doesn't validate the format of the date
1748 * string at all. If you add an incorrect format date string, the
1749 * generated CBOR will be incorrect and the receiver may not be able
1750 * to handle it.
1751 *
1752 * Error handling is the same as QCBOREncode_AddInt64().
1753 *
1754 * See also QCBOREncode_AddTDateString().
Laurence Lundblade46d63e92021-05-13 11:37:10 -07001755 */
1756static void
1757QCBOREncode_AddTDaysString(QCBOREncodeContext *pCtx,
1758 uint8_t uTagRequirement,
1759 const char *szDate);
1760
1761static void
1762QCBOREncode_AddTDaysStringToMapSZ(QCBOREncodeContext *pCtx,
1763 const char *szLabel,
1764 uint8_t uTagRequirement,
1765 const char *szDate);
1766
1767static void
1768QCBOREncode_AddTDaysStringToMapN(QCBOREncodeContext *pCtx,
1769 int64_t nLabel,
1770 uint8_t uTagRequirement,
1771 const char *szDate);
1772
1773
Michael Eckel5c531332020-03-02 01:35:30 +01001774/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001775 * @brief Add a standard Boolean.
1776 *
1777 * @param[in] pCtx The encoding context to add the Boolean to.
1778 * @param[in] b true or false from @c <stdbool.h>.
1779 *
1780 * Adds a Boolean value as CBOR major type 7.
1781 *
1782 * Error handling is the same as QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +01001783 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001784static void
1785QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b);
Michael Eckel5c531332020-03-02 01:35:30 +01001786
Laurence Lundblade3eead482023-12-16 20:53:22 -07001787static void
1788QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b);
Michael Eckel5c531332020-03-02 01:35:30 +01001789
Laurence Lundblade3eead482023-12-16 20:53:22 -07001790static void
1791QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b);
Michael Eckel5c531332020-03-02 01:35:30 +01001792
1793
1794
1795/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001796 * @brief Add a NULL to the encoded output.
1797 *
1798 * @param[in] pCtx The encoding context to add the NULL to.
1799 *
1800 * Adds the NULL value as CBOR major type 7.
1801 *
1802 * This NULL doesn't have any special meaning in CBOR such as a
1803 * terminating value for a string or an empty value.
1804 *
1805 * Error handling is the same as QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +01001806 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001807static void
1808QCBOREncode_AddNULL(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01001809
Laurence Lundblade3eead482023-12-16 20:53:22 -07001810static void
1811QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001812
Laurence Lundblade3eead482023-12-16 20:53:22 -07001813static void
1814QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001815
1816
1817/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001818 * @brief Add an "undef" to the encoded output.
1819 *
1820 * @param[in] pCtx The encoding context to add the "undef" to.
1821 *
1822 * Adds the undef value as CBOR major type 7.
1823 *
1824 * Note that this value will not translate to JSON.
1825 *
1826 * This Undef doesn't have any special meaning in CBOR such as a
1827 * terminating value for a string or an empty value.
1828 *
1829 * Error handling is the same as QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +01001830 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001831static void
1832QCBOREncode_AddUndef(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01001833
Laurence Lundblade3eead482023-12-16 20:53:22 -07001834static void
1835QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001836
Laurence Lundblade3eead482023-12-16 20:53:22 -07001837static void
1838QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001839
1840
1841/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001842 * @brief Indicates that the next items added are in an array.
1843 *
1844 * @param[in] pCtx The encoding context to open the array in.
1845 *
1846 * Arrays are the basic CBOR aggregate or structure type. Call this
1847 * function to start or open an array. Then call the various
1848 * @c QCBOREncode_AddXxx() functions to add the items that go into the
1849 * array. Then call QCBOREncode_CloseArray() when all items have been
1850 * added. The data items in the array can be of any type and can be of
1851 * mixed types.
1852 *
1853 * Nesting of arrays and maps is allowed and supported just by calling
1854 * QCBOREncode_OpenArray() again before calling
1855 * QCBOREncode_CloseArray(). While CBOR has no limit on nesting, this
1856 * implementation does in order to keep it smaller and simpler. The
1857 * limit is @ref QCBOR_MAX_ARRAY_NESTING. This is the max number of
1858 * times this can be called without calling
1859 * QCBOREncode_CloseArray(). QCBOREncode_Finish() will return
1860 * @ref QCBOR_ERR_ARRAY_NESTING_TOO_DEEP when it is called as this
1861 * function just sets an error state and returns no value when this
1862 * occurs.
1863 *
1864 * If you try to add more than @ref QCBOR_MAX_ITEMS_IN_ARRAY items to
1865 * a single array or map, @ref QCBOR_ERR_ARRAY_TOO_LONG will be
1866 * returned when QCBOREncode_Finish() is called.
1867 *
1868 * An array itself must have a label if it is being added to a map.
1869 * Note that array elements do not have labels (but map elements do).
1870 *
1871 * An array itself may be tagged by calling QCBOREncode_AddTag()
1872 * before this call.
Michael Eckel5c531332020-03-02 01:35:30 +01001873 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001874static void
1875QCBOREncode_OpenArray(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01001876
Laurence Lundblade3eead482023-12-16 20:53:22 -07001877static void
1878QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001879
Laurence Lundblade3eead482023-12-16 20:53:22 -07001880static void
1881QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001882
1883
1884/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001885 * @brief Close an open array.
1886 *
1887 * @param[in] pCtx The encoding context to close the array in.
1888 *
1889 * The closes an array opened by QCBOREncode_OpenArray(). It reduces
1890 * nesting level by one. All arrays (and maps) must be closed before
1891 * calling QCBOREncode_Finish().
1892 *
1893 * When an error occurs as a result of this call, the encoder records
1894 * the error and enters the error state. The error will be returned
1895 * when QCBOREncode_Finish() is called.
1896 *
1897 * If this has been called more times than QCBOREncode_OpenArray(), then
1898 * @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when QCBOREncode_Finish()
1899 * is called.
1900 *
1901 * If this is called and it is not an array that is currently open,
1902 * @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
1903 * QCBOREncode_Finish() is called.
Michael Eckel5c531332020-03-02 01:35:30 +01001904 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001905static void
1906QCBOREncode_CloseArray(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01001907
1908
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07001909
1910
Michael Eckel5c531332020-03-02 01:35:30 +01001911/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001912 * @brief Indicates that the next items added are in a map.
1913 *
1914 * @param[in] pCtx The encoding context to open the map in.
1915 *
1916 * See QCBOREncode_OpenArray() for more information, particularly
1917 * error handling.
1918 *
1919 * CBOR maps are an aggregate type where each item in the map consists
1920 * of a label and a value. They are similar to JSON objects.
1921 *
1922 * The value can be any CBOR type including another map.
1923 *
1924 * The label can also be any CBOR type, but in practice they are
1925 * typically, integers as this gives the most compact output. They
1926 * might also be text strings which gives readability and translation
1927 * to JSON.
1928 *
1929 * Every @c QCBOREncode_AddXxx() call has one version that ends with
1930 * @c InMap for adding items to maps with string labels and one that
1931 * ends with @c InMapN that is for adding with integer labels.
1932 *
1933 * RFC 8949 uses the term "key" instead of "label".
1934 *
1935 * If you wish to use map labels that are neither integer labels nor
1936 * text strings, then just call the QCBOREncode_AddXxx() function
1937 * explicitly to add the label. Then call it again to add the value.
1938 *
1939 * See the [RFC 8949] (https://tools.ietf.org/html/rfc8949) for a lot
1940 * more information on creating maps.
Michael Eckel5c531332020-03-02 01:35:30 +01001941 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001942static void
1943QCBOREncode_OpenMap(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01001944
Laurence Lundblade3eead482023-12-16 20:53:22 -07001945static void
1946QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001947
Laurence Lundblade3eead482023-12-16 20:53:22 -07001948static void
1949QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001950
1951
Michael Eckel5c531332020-03-02 01:35:30 +01001952/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001953 * @brief Close an open map.
1954 *
1955 * @param[in] pCtx The encoding context to close the map in.
1956 *
1957 * This closes a map opened by QCBOREncode_OpenMap(). It reduces
1958 * nesting level by one.
1959 *
1960 * When an error occurs as a result of this call, the encoder records
1961 * the error and enters the error state. The error will be returned
1962 * when QCBOREncode_Finish() is called.
1963 *
1964 * If this has been called more times than QCBOREncode_OpenMap(), then
1965 * @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1966 * QCBOREncode_Finish() is called.
1967 *
1968 * If this is called and it is not a map that is currently open,
1969 * @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
1970 * QCBOREncode_Finish() is called.
Michael Eckel5c531332020-03-02 01:35:30 +01001971 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001972static void
1973QCBOREncode_CloseMap(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01001974
1975
1976/**
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07001977 * @brief Indicates that the next items added are in an indefinite length array.
1978 *
1979 * @param[in] pCtx The encoding context to open the array in.
1980 *
1981 * This is the same as QCBOREncode_OpenArray() except the array is
1982 * indefinite length.
1983 *
1984 * This must be closed with QCBOREncode_CloseArrayIndefiniteLength().
1985 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001986static void
1987QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pCtx);
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07001988
Laurence Lundblade3eead482023-12-16 20:53:22 -07001989static void
1990QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pCtx,
1991 const char *szLabel);
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07001992
1993static void
1994QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pCtx,
1995 int64_t nLabel);
1996
1997
1998/**
1999 * @brief Close an open indefinite length array.
2000 *
2001 * @param[in] pCtx The encoding context to close the array in.
2002 *
2003 * This is the same as QCBOREncode_CloseArray(), but the open array
2004 * that is being close must be of indefinite length.
2005 */
2006static void
2007QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pCtx);
2008
2009
2010/**
2011 * @brief Indicates that the next items added are in an indefinite length map.
2012 *
2013 * @param[in] pCtx The encoding context to open the map in.
2014 *
2015 * This is the same as QCBOREncode_OpenMap() except the array is
2016 * indefinite length.
2017 *
2018 * This must be closed with QCBOREncode_CloseMapIndefiniteLength().
2019 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002020static void
2021QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pCtx);
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07002022
Laurence Lundblade3eead482023-12-16 20:53:22 -07002023static void
2024QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pCtx,
2025 const char *szLabel);
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07002026
2027static void
2028QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pCtx,
2029 int64_t nLabel);
2030
2031
2032/**
2033 * @brief Close an open indefinite length map.
2034 *
2035 * @param[in] pCtx The encoding context to close the map in.
2036 *
2037 * This is the same as QCBOREncode_CloseMap(), but the open map that
2038 * is being close must be of indefinite length.
2039 */
2040static void
2041QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pCtx);
2042
2043
Laurence Lundbladec92e4162023-11-27 21:51:26 -07002044/**
Laurence Lundbladed6e13022023-11-26 10:14:02 -07002045 * @brief Close and sort an open map.
2046 *
2047 * @param[in] pCtx The encoding context to close the map in .
2048 *
2049 * This is the same as QCBOREncode_CloseMap() except it sorts the map
2050 * per RFC 8949 Section 4.2.1. This sort is lexicographic of the CBOR-
2051 * encoded map labels.
2052 *
2053 * This is more expensive than most things in the encoder. It uses
2054 * bubble sort which runs in n-squared time where n is the number of
2055 * map items. Sorting large maps on slow CPUs might be slow. This is
2056 * also increases the object code size of the encoder by about 30%.
2057 *
2058 * Bubble sort was selected so as to not need an extra buffer to track
2059 * map item offsets. Bubble sort works well even though map items are
2060 * not all the same size because it always swaps adjacent items.
2061 */
2062void QCBOREncode_CloseAndSortMap(QCBOREncodeContext *pCtx);
2063
2064void QCBOREncode_CloseAndSortMapIndef(QCBOREncodeContext *pCtx);
2065
2066
2067/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002068 * @brief Indicate start of encoded CBOR to be wrapped in a bstr.
2069 *
2070 * @param[in] pCtx The encoding context to open the bstr-wrapped CBOR in.
2071 *
2072 * All added encoded items between this call and a call to
2073 * QCBOREncode_CloseBstrWrap2() will be wrapped in a bstr. They will
2074 * appear in the final output as a byte string. That byte string will
2075 * contain encoded CBOR. This increases nesting level by one.
2076 *
2077 * The typical use case is for encoded CBOR that is to be
2078 * cryptographically hashed, as part of a [RFC 8152, COSE]
2079 * (https://tools.ietf.org/html/rfc8152) implementation. The wrapping
2080 * byte string is taken as input by the hash function (which is why it
2081 * is returned by QCBOREncode_CloseBstrWrap2()). It is also easy to
2082 * recover on decoding with standard CBOR decoders.
2083 *
2084 * Using QCBOREncode_BstrWrap() and QCBOREncode_CloseBstrWrap2()
2085 * avoids having to encode the items first in one buffer (e.g., the
2086 * COSE payload) and then add that buffer as a bstr to another
2087 * encoding (e.g. the COSE to-be-signed bytes, the @c Sig_structure)
2088 * potentially halving the memory needed.
2089 *
2090 * CBOR by nature must be decoded item by item in order from the
2091 * start. By wrapping some CBOR in a byte string, the decoding of
2092 * that wrapped CBOR can be skipped. This is another use of wrapping,
2093 * perhaps because the CBOR is large and deeply nested. Perhaps APIs
2094 * for handling one defined CBOR message that is being embedded in
2095 * another only take input as a byte string. Perhaps the desire is to
2096 * be able to decode the out layer even in the wrapped has errors.
Michael Eckel5c531332020-03-02 01:35:30 +01002097 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002098static void
2099QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01002100
Laurence Lundblade3eead482023-12-16 20:53:22 -07002101static void
2102QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01002103
Laurence Lundblade3eead482023-12-16 20:53:22 -07002104static void
2105QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01002106
2107
2108/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002109 * @brief Close a wrapping bstr.
2110 *
2111 * @param[in] pCtx The encoding context to close of bstr wrapping in.
2112 * @param[in] bIncludeCBORHead Include the encoded CBOR head of the bstr
2113 * as well as the bytes in @c pWrappedCBOR.
2114 * @param[out] pWrappedCBOR A @ref UsefulBufC containing wrapped bytes.
2115 *
2116 * The closes a wrapping bstr opened by QCBOREncode_BstrWrap(). It reduces
2117 * nesting level by one.
2118 *
2119 * A pointer and length of the enclosed encoded CBOR is returned in @c
2120 * *pWrappedCBOR if it is not @c NULL. The main purpose of this is so
2121 * this data can be hashed (e.g., with SHA-256) as part of a [RFC
2122 * 8152, COSE] (https://tools.ietf.org/html/rfc8152)
2123 * implementation. **WARNING**, this pointer and length should be used
2124 * right away before any other calls to @c QCBOREncode_CloseXxx() as
2125 * they will move data around and the pointer and length will no
2126 * longer be to the correct encoded CBOR.
2127 *
2128 * When an error occurs as a result of this call, the encoder records
2129 * the error and enters the error state. The error will be returned
2130 * when QCBOREncode_Finish() is called.
2131 *
2132 * If this has been called more times than QCBOREncode_BstrWrap(),
2133 * then @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
2134 * QCBOREncode_Finish() is called.
2135 *
2136 * If this is called and it is not a wrapping bstr that is currently
2137 * open, @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
2138 * QCBOREncode_Finish() is called.
2139 *
2140 * QCBOREncode_CloseBstrWrap() is a deprecated version of this function
2141 * that is equivalent to the call with @c bIncludeCBORHead @c true.
Michael Eckel5c531332020-03-02 01:35:30 +01002142 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002143void
2144QCBOREncode_CloseBstrWrap2(QCBOREncodeContext *pCtx, bool bIncludeCBORHead, UsefulBufC *pWrappedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01002145
Laurence Lundblade3eead482023-12-16 20:53:22 -07002146static void
2147QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01002148
2149
2150/**
Laurence Lundblade8d3b8552021-06-10 11:11:54 -07002151 * @brief Cancel byte string wrapping.
2152 *
2153 * @param[in] pCtx The encoding context.
2154 *
2155 * This cancels QCBOREncode_BstrWrap() making tghe encoding as if it
2156 * were never called.
2157 *
2158 * WARNING: This does not work on QCBOREncode_BstrWrapInMap()
2159 * or QCBOREncode_BstrWrapInMapN() and there is no error detection
2160 * of an attempt at their use.
2161 *
2162 * This only works if nothing has been added into the wrapped byte
2163 * string. If something has been added, this sets the error
2164 * @ref QCBOR_ERR_CANNOT_CANCEL.
2165 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002166void
2167QCBOREncode_CancelBstrWrap(QCBOREncodeContext *pCtx);
Laurence Lundblade8d3b8552021-06-10 11:11:54 -07002168
2169
2170/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002171 * @brief Add some already-encoded CBOR bytes.
2172 *
2173 * @param[in] pCtx The encoding context to add the already-encode CBOR to.
2174 * @param[in] Encoded The already-encoded CBOR to add to the context.
2175 *
2176 * The encoded CBOR being added must be fully conforming CBOR. It must
2177 * be complete with no arrays or maps that are incomplete. While this
2178 * encoder doesn't ever produce indefinite lengths, it is OK for the
2179 * raw CBOR added here to have indefinite lengths.
2180 *
2181 * The raw CBOR added here is not checked in anyway. If it is not
2182 * conforming or has open arrays or such, the final encoded CBOR
2183 * will probably be wrong or not what was intended.
2184 *
2185 * If the encoded CBOR being added here contains multiple items, they
2186 * must be enclosed in a map or array. At the top level the raw
2187 * CBOR must be a single data item.
Michael Eckel5c531332020-03-02 01:35:30 +01002188 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002189static void
2190QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01002191
Laurence Lundblade3eead482023-12-16 20:53:22 -07002192static void
2193QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01002194
Laurence Lundblade3eead482023-12-16 20:53:22 -07002195static void
2196QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01002197
2198
2199/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002200 * @brief Get the encoded result.
2201 *
2202 * @param[in] pCtx The context to finish encoding with.
2203 * @param[out] pEncodedCBOR Structure in which the pointer and length of
2204 * the encoded CBOR is returned.
2205 *
2206 * @retval QCBOR_SUCCESS Encoded CBOR is returned.
2207 *
2208 * @retval QCBOR_ERR_TOO_MANY_CLOSES Nesting error
2209 *
2210 * @retval QCBOR_ERR_CLOSE_MISMATCH Nesting error
2211 *
2212 * @retval QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN Nesting error
2213 *
2214 * @retval QCBOR_ERR_BUFFER_TOO_LARGE Encoded output buffer size
2215 *
2216 * @retval QCBOR_ERR_BUFFER_TOO_SMALL Encoded output buffer size
2217 *
2218 * @retval QCBOR_ERR_ARRAY_NESTING_TOO_DEEP Implementation limit
2219 *
2220 * @retval QCBOR_ERR_ARRAY_TOO_LONG Implementation limit
2221 *
2222 * On success, the pointer and length of the encoded CBOR are returned
2223 * in @c *pEncodedCBOR. The pointer is the same pointer that was passed
2224 * in to QCBOREncode_Init(). Note that it is not const when passed to
2225 * QCBOREncode_Init(), but it is const when returned here. The length
2226 * will be smaller than or equal to the length passed in when
2227 * QCBOREncode_Init() as this is the length of the actual result, not
2228 * the size of the buffer it was written to.
2229 *
2230 * If a @c NULL was passed for @c Storage.ptr when QCBOREncode_Init()
2231 * was called, @c NULL will be returned here, but the length will be
2232 * that of the CBOR that would have been encoded.
2233 *
2234 * Encoding errors primarily manifest here as most other encoding function
2235 * do no return an error. They just set the error state in the encode
2236 * context after which no encoding function does anything.
2237 *
2238 * Three types of errors manifest here. The first type are nesting
2239 * errors where the number of @c QCBOREncode_OpenXxx() calls do not
2240 * match the number @c QCBOREncode_CloseXxx() calls. The solution is to
2241 * fix the calling code.
2242 *
2243 * The second type of error is because the buffer given is either too
2244 * small or too large. The remedy is to give a correctly sized buffer.
2245 *
2246 * The third type are due to limits in this implementation.
2247 * @ref QCBOR_ERR_ARRAY_NESTING_TOO_DEEP can be worked around by
2248 * encoding the CBOR in two (or more) phases and adding the CBOR from
2249 * the first phase to the second with @c QCBOREncode_AddEncoded().
2250 *
2251 * If an error is returned, the buffer may have partially encoded
2252 * incorrect CBOR in it and it should not be used. Likewise, the length
2253 * may be incorrect and should not be used.
2254 *
2255 * Note that the error could have occurred in one of the many
2256 * @c QCBOREncode_AddXxx() calls long before QCBOREncode_Finish() was
2257 * called. This error handling reduces the CBOR implementation size
2258 * but makes debugging harder.
2259 *
2260 * This may be called multiple times. It will always return the
2261 * same. It can also be interleaved with calls to
2262 * QCBOREncode_FinishGetSize().
2263 *
2264 * QCBOREncode_GetErrorState() can be called to get the current
2265 * error state in order to abort encoding early as an optimization, but
2266 * calling it is is never required.
Michael Eckel5c531332020-03-02 01:35:30 +01002267 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002268QCBORError
2269QCBOREncode_Finish(QCBOREncodeContext *pCtx, UsefulBufC *pEncodedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01002270
2271
2272/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002273 * @brief Get the encoded CBOR and error status.
2274 *
2275 * @param[in] pCtx The context to finish encoding with.
2276 * @param[out] uEncodedLen The length of the encoded or potentially
2277 * encoded CBOR in bytes.
2278 *
2279 * @return The same errors as QCBOREncode_Finish().
2280 *
2281 * This functions the same as QCBOREncode_Finish(), but only returns the
2282 * size of the encoded output.
Michael Eckel5c531332020-03-02 01:35:30 +01002283 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002284QCBORError
2285QCBOREncode_FinishGetSize(QCBOREncodeContext *pCtx, size_t *uEncodedLen);
Michael Eckel5c531332020-03-02 01:35:30 +01002286
2287
2288/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002289 * @brief Indicate whether output buffer is NULL or not.
2290 *
2291 * @param[in] pCtx The encoding context.
2292 *
2293 * @return 1 if the output buffer is @c NULL.
2294 *
2295 * Sometimes a @c NULL input buffer is given to QCBOREncode_Init() so
2296 * that the size of the generated CBOR can be calculated without
2297 * allocating a buffer for it. This returns 1 when the output buffer
2298 * is @c NULL and 0 when it is not.
Michael Eckel5c531332020-03-02 01:35:30 +01002299 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002300static int
2301QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx);
2302
2303
2304/**
2305 * @brief Get the encoding error state.
2306 *
2307 * @param[in] pCtx The encoding context.
2308 *
2309 * @return One of @ref QCBORError. See return values from
2310 * QCBOREncode_Finish()
2311 *
2312 * Normally encoding errors need only be handled at the end of
2313 * encoding when QCBOREncode_Finish() is called. This can be called to
2314 * get the error result before finish should there be a need to halt
2315 * encoding before QCBOREncode_Finish() is called.
2316 */
2317static QCBORError
2318QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx);
2319
2320
2321/**
2322 * Encode the "head" of a CBOR data item.
2323 *
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002324 * @param Buffer Buffer to output the encoded head to; must be
Laurence Lundblade3eead482023-12-16 20:53:22 -07002325 * @ref QCBOR_HEAD_BUFFER_SIZE bytes in size.
2326 * @param uMajorType One of CBOR_MAJOR_TYPE_XX.
2327 * @param uMinLen The minimum number of bytes to encode uNumber. Almost
2328 * always this is 0 to use preferred
2329 * serialization. If this is 4, then even the
2330 * values 0xffff and smaller will be encoded in 4
2331 * bytes. This is used primarily when encoding a
2332 * float or double put into uNumber as the leading
2333 * zero bytes for them must be encoded.
2334 * @param uNumber The numeric argument part of the CBOR head.
2335 * @return Pointer and length of the encoded head or
2336 * @ref NULLUsefulBufC if the output buffer is too small.
2337 *
2338 * Callers do not to need to call this for normal CBOR encoding. Note
2339 * that it doesn't even take a @ref QCBOREncodeContext argument.
2340 *
2341 * This encodes the major type and argument part of a data item. The
2342 * argument is an integer that is usually either the value or the length
2343 * of the data item.
2344 *
2345 * This is exposed in the public interface to allow hashing of some CBOR
2346 * data types, bstr in particular, a chunk at a time so the full CBOR
2347 * doesn't have to be encoded in a contiguous buffer.
2348 *
2349 * For example, if you have a 100,000 byte binary blob in a buffer that
2350 * needs to be a bstr encoded and then hashed. You could allocate a
2351 * 100,010 byte buffer and encode it normally. Alternatively, you can
2352 * encode the head in a 10 byte buffer with this function, hash that and
2353 * then hash the 100,000 bytes using the same hash context.
2354 *
2355 * See also QCBOREncode_AddBytesLenOnly();
2356 */
2357UsefulBufC
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002358QCBOREncode_EncodeHead(UsefulBuf Buffer,
Laurence Lundblade3eead482023-12-16 20:53:22 -07002359 uint8_t uMajorType,
2360 uint8_t uMinLen,
2361 uint64_t uNumber);
Michael Eckel5c531332020-03-02 01:35:30 +01002362
2363
Michael Eckel5c531332020-03-02 01:35:30 +01002364
2365
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002366/* =========================================================================
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002367 BEGINNING OF PRIVATE IMPLEMENTATION
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002368 ========================================================================= */
Michael Eckel5c531332020-03-02 01:35:30 +01002369
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002370/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002371void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002372QCBOREncode_Private_AddBuffer(QCBOREncodeContext *pCtx,
2373 uint8_t uMajorType,
2374 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002375
2376
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002377/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002378void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002379QCBOREncode_Private_OpenMapOrArray(QCBOREncodeContext *pCtx,
2380 uint8_t uMajorType);
Michael Eckel5c531332020-03-02 01:35:30 +01002381
2382
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002383/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002384void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002385QCBOREncode_Private_OpenMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx,
2386 uint8_t uMajorType);
Michael Eckel5c531332020-03-02 01:35:30 +01002387
2388
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002389/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002390void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002391QCBOREncode_Private_CloseMapOrArray(QCBOREncodeContext *pCtx,
2392 uint8_t uMajorType);
Michael Eckel5c531332020-03-02 01:35:30 +01002393
2394
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002395/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002396void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002397QCBOREncode_Private_CloseMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx,
2398 uint8_t uMajorType);
Michael Eckel5c531332020-03-02 01:35:30 +01002399
2400
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002401/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002402void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002403QCBOREncode_Private_AddType7(QCBOREncodeContext *pCtx,
2404 uint8_t uMinLen,
2405 uint64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002406
2407
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002408/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002409void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002410QCBOREncode_Private_AddExpMantissa(QCBOREncodeContext *pCtx,
Laurence Lundblade3eead482023-12-16 20:53:22 -07002411 uint64_t uTag,
2412 UsefulBufC BigNumMantissa,
2413 bool bBigNumIsNegative,
2414 int64_t nMantissa,
2415 int64_t nExponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002416
2417/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002418 * @brief Semi-private method to add only the type and length of a byte string.
2419 *
2420 * @param[in] pCtx The context to initialize.
2421 * @param[in] Bytes Pointer and length of the input data.
2422 *
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002423 * This will be removed in QCBOR 2.0. It was never a public function.
2424 *
Laurence Lundblade3eead482023-12-16 20:53:22 -07002425 * This is the same as QCBOREncode_AddBytes() except it only adds the
2426 * CBOR encoding for the type and the length. It doesn't actually add
2427 * the bytes. You can't actually produce correct CBOR with this and
2428 * the rest of this API. It is only used for a special case where the
2429 * valid CBOR is created manually by putting this type and length in
2430 * and then adding the actual bytes. In particular, when only a hash
2431 * of the encoded CBOR is needed, where the type and header are hashed
2432 * separately and then the bytes is hashed. This makes it possible to
2433 * implement COSE Sign1 with only one copy of the payload in the
2434 * output buffer, rather than two, roughly cutting memory use in half.
2435 *
2436 * This is only used for this odd case, but this is a supported
2437 * tested function.
2438 *
2439 * See also QCBOREncode_EncodeHead().
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002440 *
2441 * TODO: remove this in QCBOR 2.0
2442 */
2443static void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002444QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pCtx,
2445 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002446
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002447static void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002448QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pCtx,
2449 const char *szLabel,
2450 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002451
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002452static void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002453QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pCtx,
2454 int64_t nLabel,
2455 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002456
2457
2458
2459
2460
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002461static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002462QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pMe,
2463 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002464 const int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002465{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002466 /* Use _AddBuffer() because _AddSZString() is defined below, not above */
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002467 QCBOREncode_Private_AddBuffer(pMe,
2468 CBOR_MAJOR_TYPE_TEXT_STRING,
2469 UsefulBuf_FromSZ(szLabel));
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002470 QCBOREncode_AddInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002471}
2472
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002473static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002474QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002475 const int64_t nLabel,
2476 const int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002477{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002478 QCBOREncode_AddInt64(pMe, nLabel);
2479 QCBOREncode_AddInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002480}
2481
2482
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002483static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002484QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pMe,
2485 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002486 const uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002487{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002488 /* Use _AddBuffer() because _AddSZString() is defined below, not above */
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002489 QCBOREncode_Private_AddBuffer(pMe,
2490 CBOR_MAJOR_TYPE_TEXT_STRING,
2491 UsefulBuf_FromSZ(szLabel));
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002492 QCBOREncode_AddUInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002493}
2494
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002495static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002496QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002497 const int64_t nLabel,
2498 const uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002499{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002500 QCBOREncode_AddInt64(pMe, nLabel);
2501 QCBOREncode_AddUInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002502}
2503
2504
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002505static inline void
Laurence Lundblade2d493002024-02-01 11:09:17 -07002506QCBOREncode_AddNegativeUInt64ToMap(QCBOREncodeContext *pMe, const char *szLabel, uint64_t uNum)
2507{
2508 /* Use _AddBuffer() because _AddSZString() is defined below, not above */
2509 QCBOREncode_Private_AddBuffer(pMe,
2510 CBOR_MAJOR_TYPE_TEXT_STRING,
2511 UsefulBuf_FromSZ(szLabel));
2512 QCBOREncode_AddNegativeUInt64(pMe, uNum);
2513}
2514
2515static inline void
2516QCBOREncode_AddNegativeUInt64ToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint64_t uNum)
2517{
2518 QCBOREncode_AddInt64(pMe, nLabel);
2519 QCBOREncode_AddNegativeUInt64(pMe, uNum);
2520}
2521
2522
2523static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002524QCBOREncode_AddText(QCBOREncodeContext *pMe, const UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002525{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002526 QCBOREncode_Private_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002527}
2528
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002529static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002530QCBOREncode_AddTextToMap(QCBOREncodeContext *pMe,
2531 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002532 const UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002533{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002534 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szLabel));
2535 QCBOREncode_AddText(pMe, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002536}
2537
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002538static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002539QCBOREncode_AddTextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002540 const int64_t nLabel,
2541 const UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002542{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002543 QCBOREncode_AddInt64(pMe, nLabel);
2544 QCBOREncode_AddText(pMe, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002545}
2546
2547
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002548inline static void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002549QCBOREncode_AddSZString(QCBOREncodeContext *pMe, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002550{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002551 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szString));
Michael Eckel5c531332020-03-02 01:35:30 +01002552}
2553
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002554static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002555QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pMe,
2556 const char *szLabel,
2557 const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002558{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002559 QCBOREncode_AddSZString(pMe, szLabel);
2560 QCBOREncode_AddSZString(pMe, szString);
Michael Eckel5c531332020-03-02 01:35:30 +01002561}
2562
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002563static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002564QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002565 const int64_t nLabel,
Laurence Lundblade3eead482023-12-16 20:53:22 -07002566 const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002567{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002568 QCBOREncode_AddInt64(pMe, nLabel);
2569 QCBOREncode_AddSZString(pMe, szString);
Michael Eckel5c531332020-03-02 01:35:30 +01002570}
2571
2572
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +02002573#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002574static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002575QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pMe,
2576 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002577 const double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002578{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002579 QCBOREncode_AddSZString(pMe, szLabel);
2580 QCBOREncode_AddDouble(pMe, dNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002581}
2582
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002583static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002584QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002585 const int64_t nLabel,
2586 const double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002587{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002588 QCBOREncode_AddInt64(pMe, nLabel);
2589 QCBOREncode_AddDouble(pMe, dNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002590}
2591
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002592static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002593QCBOREncode_AddFloatToMap(QCBOREncodeContext *pMe,
2594 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002595 const float dNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002596{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002597 QCBOREncode_AddSZString(pMe, szLabel);
2598 QCBOREncode_AddFloat(pMe, dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002599}
2600
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002601static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002602QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pMe,
2603 const int64_t nLabel,
2604 const float fNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002605{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002606 QCBOREncode_AddInt64(pMe, nLabel);
2607 QCBOREncode_AddFloat(pMe, fNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002608}
2609
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002610static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002611QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pMe,
2612 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002613 const double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002614{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002615 QCBOREncode_AddSZString(pMe, szLabel);
2616 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002617}
2618
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002619static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002620QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002621 const int64_t nLabel,
2622 const double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002623{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002624 QCBOREncode_AddInt64(pMe, nLabel);
2625 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002626}
2627
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002628static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002629QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pMe,
2630 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002631 const float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002632{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002633 QCBOREncode_AddSZString(pMe, szLabel);
2634 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002635}
2636
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002637static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002638QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002639 const int64_t nLabel,
2640 const float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002641{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002642 QCBOREncode_AddInt64(pMe, nLabel);
2643 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002644}
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +02002645#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002646
Michael Eckel5c531332020-03-02 01:35:30 +01002647
Laurence Lundblade9b334962020-08-27 10:55:53 -07002648
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002649static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002650QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pMe,
2651 const uint8_t uTag,
2652 const int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002653{
2654 if(uTag == QCBOR_ENCODE_AS_TAG) {
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002655 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_EPOCH);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002656 }
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002657 QCBOREncode_AddInt64(pMe, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002658}
2659
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002660static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002661QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pMe,
2662 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002663 const uint8_t uTag,
2664 const int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002665{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002666 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002667 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002668}
2669
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002670static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002671QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002672 const int64_t nLabel,
2673 const uint8_t uTag,
2674 const int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002675{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002676 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002677 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002678}
2679
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002680static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002681QCBOREncode_AddDateEpoch(QCBOREncodeContext *pMe,
2682 const int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002683{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002684 QCBOREncode_AddTDateEpoch(pMe, QCBOR_ENCODE_AS_TAG, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002685}
2686
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002687static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002688QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pMe,
2689 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002690 const int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002691{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002692 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002693 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002694}
2695
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002696static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002697QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002698 const int64_t nLabel,
2699 const int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002700{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002701 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002702 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002703}
2704
2705
Laurence Lundblade46d63e92021-05-13 11:37:10 -07002706static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002707QCBOREncode_AddTDaysEpoch(QCBOREncodeContext *pMe,
2708 const uint8_t uTag,
2709 const int64_t nDays)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07002710{
2711 if(uTag == QCBOR_ENCODE_AS_TAG) {
2712 QCBOREncode_AddTag(pMe, CBOR_TAG_DAYS_EPOCH);
2713 }
2714 QCBOREncode_AddInt64(pMe, nDays);
2715}
2716
2717static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002718QCBOREncode_AddTDaysEpochToMapSZ(QCBOREncodeContext *pMe,
2719 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002720 const uint8_t uTag,
2721 const int64_t nDays)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07002722{
2723 QCBOREncode_AddSZString(pMe, szLabel);
2724 QCBOREncode_AddTDaysEpoch(pMe, uTag, nDays);
2725}
2726
2727static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002728QCBOREncode_AddTDaysEpochToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002729 const int64_t nLabel,
2730 const uint8_t uTag,
2731 const int64_t nDays)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07002732{
2733 QCBOREncode_AddInt64(pMe, nLabel);
2734 QCBOREncode_AddTDaysEpoch(pMe, uTag, nDays);
2735}
2736
Laurence Lundblade9b334962020-08-27 10:55:53 -07002737
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002738static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002739QCBOREncode_AddBytes(QCBOREncodeContext *pMe,
2740 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002741{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002742 QCBOREncode_Private_AddBuffer(pMe, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002743}
2744
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002745static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002746QCBOREncode_AddBytesToMap(QCBOREncodeContext *pMe,
2747 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002748 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002749{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002750 QCBOREncode_AddSZString(pMe, szLabel);
2751 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002752}
2753
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002754static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002755QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002756 const int64_t nLabel,
2757 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002758{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002759 QCBOREncode_AddInt64(pMe, nLabel);
2760 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002761}
2762
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002763static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002764QCBOREncode_OpenBytesInMapSZ(QCBOREncodeContext *pMe,
2765 const char *szLabel,
2766 UsefulBuf *pPlace)
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06002767{
2768 QCBOREncode_AddSZString(pMe, szLabel);
2769 QCBOREncode_OpenBytes(pMe, pPlace);
2770}
2771
2772static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002773QCBOREncode_OpenBytesInMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002774 const int64_t nLabel,
Laurence Lundblade3eead482023-12-16 20:53:22 -07002775 UsefulBuf *pPlace)
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06002776{
2777 QCBOREncode_AddInt64(pMe, nLabel);
2778 QCBOREncode_OpenBytes(pMe, pPlace);
2779}
2780
2781static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002782QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002783{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002784 QCBOREncode_Private_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002785}
2786
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002787static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002788QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pMe,
2789 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002790 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002791{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002792 QCBOREncode_AddSZString(pMe, szLabel);
2793 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002794}
2795
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002796static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002797QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002798 const int64_t nLabel,
2799 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002800{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002801 QCBOREncode_AddInt64(pMe, nLabel);
2802 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002803}
2804
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002805
2806static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002807QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002808 const uint8_t uTagRequirement,
2809 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002810{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002811 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2812 QCBOREncode_AddTag(pMe, CBOR_TAG_BIN_UUID);
2813 }
2814 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002815}
2816
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002817static inline void
2818QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pMe,
2819 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002820 const uint8_t uTagRequirement,
2821 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002822{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002823 QCBOREncode_AddSZString(pMe, szLabel);
2824 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002825}
2826
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002827static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002828QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002829 const int64_t nLabel,
2830 const uint8_t uTagRequirement,
2831 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002832{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002833 QCBOREncode_AddInt64(pMe, nLabel);
2834 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002835}
2836
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002837static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002838QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002839{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002840 QCBOREncode_AddTBinaryUUID(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002841}
2842
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002843static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002844QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pMe,
2845 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002846 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002847{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002848 QCBOREncode_AddTBinaryUUIDToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002849}
2850
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002851static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002852QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002853 const int64_t nLabel,
2854 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002855{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002856 QCBOREncode_AddTBinaryUUIDToMapN(pMe,
2857 nLabel,
2858 QCBOR_ENCODE_AS_TAG,
2859 Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002860}
2861
2862
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002863static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002864QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002865 const uint8_t uTagRequirement,
2866 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002867{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002868 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2869 QCBOREncode_AddTag(pMe, CBOR_TAG_POS_BIGNUM);
2870 }
2871 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002872}
2873
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002874static inline void
2875QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pMe,
2876 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002877 const uint8_t uTagRequirement,
2878 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002879{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002880 QCBOREncode_AddSZString(pMe, szLabel);
2881 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002882}
2883
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002884static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002885QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002886 const int64_t nLabel,
2887 const uint8_t uTagRequirement,
2888 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002889{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002890 QCBOREncode_AddInt64(pMe, nLabel);
2891 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002892}
2893
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002894static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002895QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002896{
2897 QCBOREncode_AddTPositiveBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2898}
2899
2900static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002901QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pMe,
2902 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002903 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002904{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002905 QCBOREncode_AddTPositiveBignumToMapSZ(pMe,
2906 szLabel,
2907 QCBOR_ENCODE_AS_TAG,
2908 Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002909}
2910
2911static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002912QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002913 const int64_t nLabel,
2914 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002915{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002916 QCBOREncode_AddTPositiveBignumToMapN(pMe,
2917 nLabel,
2918 QCBOR_ENCODE_AS_TAG,
2919 Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002920}
2921
2922
2923static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002924QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002925 const uint8_t uTagRequirement,
2926 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002927{
2928 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2929 QCBOREncode_AddTag(pMe, CBOR_TAG_NEG_BIGNUM);
2930 }
2931 QCBOREncode_AddBytes(pMe, Bytes);
2932}
2933
2934static inline void
2935QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pMe,
2936 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002937 const uint8_t uTagRequirement,
2938 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002939{
2940 QCBOREncode_AddSZString(pMe, szLabel);
2941 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2942}
2943
2944static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002945QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002946 const int64_t nLabel,
2947 const uint8_t uTagRequirement,
2948 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002949{
2950 QCBOREncode_AddInt64(pMe, nLabel);
2951 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2952}
2953
2954static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002955QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002956{
2957 QCBOREncode_AddTNegativeBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2958}
2959
2960static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002961QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pMe,
2962 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002963 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002964{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002965 QCBOREncode_AddTNegativeBignumToMapSZ(pMe,
2966 szLabel,
2967 QCBOR_ENCODE_AS_TAG,
2968 Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002969}
2970
2971static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002972QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002973 const int64_t nLabel,
2974 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002975{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002976 QCBOREncode_AddTNegativeBignumToMapN(pMe,
2977 nLabel,
2978 QCBOR_ENCODE_AS_TAG,
2979 Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002980}
2981
2982
Michael Eckel5c531332020-03-02 01:35:30 +01002983
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07002984#ifndef QCBOR_DISABLE_EXP_AND_MANTISSA
Michael Eckel5c531332020-03-02 01:35:30 +01002985
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002986static inline void
2987QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002988 const uint8_t uTagRequirement,
2989 const int64_t nMantissa,
2990 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002991{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002992 uint64_t uTag;
2993 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2994 uTag = CBOR_TAG_DECIMAL_FRACTION;
2995 } else {
2996 uTag = CBOR_TAG_INVALID64;
2997 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002998 QCBOREncode_Private_AddExpMantissa(pMe,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002999 uTag,
Michael Eckel5c531332020-03-02 01:35:30 +01003000 NULLUsefulBufC,
3001 false,
3002 nMantissa,
3003 nBase10Exponent);
3004}
3005
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003006static inline void
3007QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pMe,
3008 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003009 const uint8_t uTagRequirement,
3010 const int64_t nMantissa,
3011 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003012{
3013 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003014 QCBOREncode_AddTDecimalFraction(pMe,
3015 uTagRequirement,
3016 nMantissa,
3017 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003018}
3019
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003020static inline void
3021QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003022 const int64_t nLabel,
3023 const uint8_t uTagRequirement,
3024 const int64_t nMantissa,
3025 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003026{
3027 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003028 QCBOREncode_AddTDecimalFraction(pMe,
3029 uTagRequirement,
3030 nMantissa,
3031 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003032}
3033
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003034static inline void
3035QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003036 const int64_t nMantissa,
3037 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003038{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003039 QCBOREncode_AddTDecimalFraction(pMe,
3040 QCBOR_ENCODE_AS_TAG,
3041 nMantissa,
3042 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003043}
3044
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003045static inline void
3046QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pMe,
3047 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003048 const int64_t nMantissa,
3049 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003050{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003051 QCBOREncode_AddTDecimalFractionToMapSZ(pMe,
3052 szLabel,
3053 QCBOR_ENCODE_AS_TAG,
3054 nMantissa,
3055 nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003056}
3057
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003058static inline void
3059QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003060 const int64_t nLabel,
3061 const int64_t nMantissa,
3062 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003063{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003064 QCBOREncode_AddTDecimalFractionToMapN(pMe,
3065 nLabel,
3066 QCBOR_ENCODE_AS_TAG,
3067 nMantissa,
3068 nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003069}
3070
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003071
3072
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003073static inline void
3074QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003075 const uint8_t uTagRequirement,
3076 const UsefulBufC Mantissa,
3077 const bool bIsNegative,
3078 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003079{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003080 uint64_t uTag;
3081 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3082 uTag = CBOR_TAG_DECIMAL_FRACTION;
3083 } else {
3084 uTag = CBOR_TAG_INVALID64;
3085 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003086 QCBOREncode_Private_AddExpMantissa(pMe,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003087 uTag,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003088 Mantissa,
3089 bIsNegative,
Michael Eckel5c531332020-03-02 01:35:30 +01003090 0,
3091 nBase10Exponent);
3092}
3093
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003094static inline void
3095QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
3096 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003097 const uint8_t uTagRequirement,
3098 const UsefulBufC Mantissa,
3099 const bool bIsNegative,
3100 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003101{
3102 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003103 QCBOREncode_AddTDecimalFractionBigNum(pMe,
3104 uTagRequirement,
3105 Mantissa,
3106 bIsNegative,
3107 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003108}
3109
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003110static inline void
3111QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003112 const int64_t nLabel,
3113 const uint8_t uTagRequirement,
3114 const UsefulBufC Mantissa,
3115 const bool bIsNegative,
3116 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003117{
3118 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003119 QCBOREncode_AddTDecimalFractionBigNum(pMe,
3120 uTagRequirement,
3121 Mantissa,
3122 bIsNegative,
3123 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003124}
3125
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003126static inline void
3127QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003128 const UsefulBufC Mantissa,
3129 const bool bIsNegative,
3130 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003131{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003132 QCBOREncode_AddTDecimalFractionBigNum(pMe,
3133 QCBOR_ENCODE_AS_TAG,
3134 Mantissa,
3135 bIsNegative,
3136 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003137}
3138
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003139static inline void
3140QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
3141 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003142 const UsefulBufC Mantissa,
3143 const bool bIsNegative,
3144 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003145{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003146 QCBOREncode_AddTDecimalFractionBigNumToMapSZ(pMe,
3147 szLabel,
3148 QCBOR_ENCODE_AS_TAG,
3149 Mantissa,
3150 bIsNegative,
3151 nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003152}
3153
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003154static inline void
3155QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003156 const int64_t nLabel,
3157 const UsefulBufC Mantissa,
3158 const bool bIsNegative,
3159 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003160{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003161 QCBOREncode_AddTDecimalFractionBigNumToMapN(pMe,
3162 nLabel,
3163 QCBOR_ENCODE_AS_TAG,
3164 Mantissa,
3165 bIsNegative,
3166 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003167}
3168
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003169
3170
3171
3172
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003173static inline void
3174QCBOREncode_AddTBigFloat(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003175 const uint8_t uTagRequirement,
3176 const int64_t nMantissa,
3177 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003178{
3179 uint64_t uTag;
3180 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3181 uTag = CBOR_TAG_BIGFLOAT;
3182 } else {
3183 uTag = CBOR_TAG_INVALID64;
3184 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003185 QCBOREncode_Private_AddExpMantissa(pMe,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003186 uTag,
3187 NULLUsefulBufC,
3188 false,
3189 nMantissa,
3190 nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003191}
3192
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003193static inline void
3194QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pMe,
3195 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003196 const uint8_t uTagRequirement,
3197 const int64_t nMantissa,
3198 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003199{
3200 QCBOREncode_AddSZString(pMe, szLabel);
3201 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
3202}
3203
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003204static inline void
3205QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003206 const int64_t nLabel,
3207 const uint8_t uTagRequirement,
3208 const int64_t nMantissa,
3209 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003210{
3211 QCBOREncode_AddInt64(pMe, nLabel);
3212 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
3213}
3214
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003215static inline void
3216QCBOREncode_AddBigFloat(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003217 const int64_t nMantissa,
3218 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003219{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003220 QCBOREncode_AddTBigFloat(pMe,
3221 QCBOR_ENCODE_AS_TAG,
3222 nMantissa,
3223 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003224}
3225
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003226static inline void
3227QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pMe,
3228 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003229 const int64_t nMantissa,
3230 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003231{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003232 QCBOREncode_AddTBigFloatToMapSZ(pMe,
3233 szLabel,
3234 QCBOR_ENCODE_AS_TAG,
3235 nMantissa,
3236 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003237}
3238
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003239static inline void
3240QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003241 const int64_t nLabel,
3242 const int64_t nMantissa,
3243 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003244{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003245 QCBOREncode_AddTBigFloatToMapN(pMe,
3246 nLabel,
3247 QCBOR_ENCODE_AS_TAG,
3248 nMantissa,
3249 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003250}
3251
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003252
3253
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003254static inline void
3255QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003256 const uint8_t uTagRequirement,
3257 const UsefulBufC Mantissa,
3258 const bool bIsNegative,
3259 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003260{
3261 uint64_t uTag;
3262 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3263 uTag = CBOR_TAG_BIGFLOAT;
3264 } else {
3265 uTag = CBOR_TAG_INVALID64;
3266 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003267 QCBOREncode_Private_AddExpMantissa(pMe,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003268 uTag,
3269 Mantissa,
3270 bIsNegative,
3271 0,
3272 nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003273}
3274
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003275static inline void
3276QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pMe,
3277 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003278 const uint8_t uTagRequirement,
3279 const UsefulBufC Mantissa,
3280 const bool bIsNegative,
3281 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003282{
3283 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003284 QCBOREncode_AddTBigFloatBigNum(pMe,
3285 uTagRequirement,
3286 Mantissa,
3287 bIsNegative,
3288 nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003289}
3290
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003291static inline void
3292QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003293 const int64_t nLabel,
3294 const uint8_t uTagRequirement,
3295 const UsefulBufC Mantissa,
3296 const bool bIsNegative,
3297 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003298{
3299 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003300 QCBOREncode_AddTBigFloatBigNum(pMe,
3301 uTagRequirement,
3302 Mantissa,
3303 bIsNegative,
3304 nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003305}
3306
3307
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003308static inline void
3309QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003310 const UsefulBufC Mantissa,
3311 const bool bIsNegative,
3312 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003313{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003314 QCBOREncode_AddTBigFloatBigNum(pMe,
3315 QCBOR_ENCODE_AS_TAG,
3316 Mantissa, bIsNegative,
3317 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003318}
3319
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003320static inline void
3321QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pMe,
3322 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003323 const UsefulBufC Mantissa,
3324 const bool bIsNegative,
3325 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003326{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003327 QCBOREncode_AddTBigFloatBigNumToMapSZ(pMe,
3328 szLabel,
3329 QCBOR_ENCODE_AS_TAG,
3330 Mantissa,
3331 bIsNegative,
3332 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003333}
3334
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003335static inline void
3336QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003337 const int64_t nLabel,
3338 const UsefulBufC Mantissa,
3339 const bool bIsNegative,
3340 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003341{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003342 QCBOREncode_AddTBigFloatBigNumToMapN(pMe,
3343 nLabel,
3344 QCBOR_ENCODE_AS_TAG,
3345 Mantissa,
3346 bIsNegative,
3347 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003348}
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07003349#endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
Michael Eckel5c531332020-03-02 01:35:30 +01003350
3351
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003352static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003353QCBOREncode_AddTURI(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003354 const uint8_t uTagRequirement,
3355 const UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01003356{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003357 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3358 QCBOREncode_AddTag(pMe, CBOR_TAG_URI);
3359 }
3360 QCBOREncode_AddText(pMe, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01003361}
3362
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003363static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003364QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pMe,
3365 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003366 const uint8_t uTagRequirement,
3367 const UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01003368{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003369 QCBOREncode_AddSZString(pMe, szLabel);
3370 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01003371}
3372
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003373static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003374QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003375 const int64_t nLabel,
3376 const uint8_t uTagRequirement,
3377 const UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01003378{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003379 QCBOREncode_AddInt64(pMe, nLabel);
3380 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
3381}
3382
3383static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003384QCBOREncode_AddURI(QCBOREncodeContext *pMe, const UsefulBufC URI)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003385{
3386 QCBOREncode_AddTURI(pMe, QCBOR_ENCODE_AS_TAG, URI);
3387}
3388
3389static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003390QCBOREncode_AddURIToMap(QCBOREncodeContext *pMe,
3391 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003392 const UsefulBufC URI)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003393{
3394 QCBOREncode_AddTURIToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, URI);
3395}
3396
3397static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003398QCBOREncode_AddURIToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003399 const int64_t nLabel,
3400 const UsefulBufC URI)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003401{
3402 QCBOREncode_AddTURIToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01003403}
3404
3405
3406
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003407static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003408QCBOREncode_AddTB64Text(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003409 const uint8_t uTagRequirement,
3410 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003411{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003412 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3413 QCBOREncode_AddTag(pMe, CBOR_TAG_B64);
3414 }
3415 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003416}
3417
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003418static inline void
3419QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pMe,
3420 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003421 const uint8_t uTagRequirement,
3422 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003423{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003424 QCBOREncode_AddSZString(pMe, szLabel);
3425 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003426}
3427
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003428static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003429QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003430 const int64_t nLabel,
3431 const uint8_t uTagRequirement,
3432 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003433{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003434 QCBOREncode_AddInt64(pMe, nLabel);
3435 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
3436}
3437
3438static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003439QCBOREncode_AddB64Text(QCBOREncodeContext *pMe, const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003440{
3441 QCBOREncode_AddTB64Text(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
3442}
3443
3444static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003445QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pMe,
3446 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003447 const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003448{
3449 QCBOREncode_AddTB64TextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
3450}
3451
3452static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003453QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003454 const int64_t nLabel,
3455 const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003456{
3457 QCBOREncode_AddTB64TextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003458}
3459
3460
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003461
3462static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003463QCBOREncode_AddTB64URLText(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003464 const uint8_t uTagRequirement,
3465 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003466{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003467 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3468 QCBOREncode_AddTag(pMe, CBOR_TAG_B64URL);
3469 }
3470 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003471}
3472
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003473static inline void
3474QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pMe,
3475 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003476 const uint8_t uTagRequirement,
3477 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003478{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003479 QCBOREncode_AddSZString(pMe, szLabel);
3480 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003481}
3482
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003483static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003484QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003485 const int64_t nLabel,
3486 const uint8_t uTagRequirement,
3487 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003488{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003489 QCBOREncode_AddInt64(pMe, nLabel);
3490 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
3491}
3492
3493static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003494QCBOREncode_AddB64URLText(QCBOREncodeContext *pMe, const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003495{
3496 QCBOREncode_AddTB64URLText(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
3497}
3498
3499static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003500QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pMe,
3501 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003502 const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003503{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003504 QCBOREncode_AddTB64URLTextToMapSZ(pMe,
3505 szLabel,
3506 QCBOR_ENCODE_AS_TAG,
3507 B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003508}
3509
3510static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003511QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003512 const int64_t nLabel,
3513 const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003514{
3515 QCBOREncode_AddTB64URLTextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003516}
3517
3518
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003519
3520static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003521QCBOREncode_AddTRegex(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003522 const uint8_t uTagRequirement,
3523 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003524{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003525 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3526 QCBOREncode_AddTag(pMe, CBOR_TAG_REGEX);
3527 }
3528 QCBOREncode_AddText(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01003529}
3530
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003531static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003532QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pMe,
3533 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003534 const uint8_t uTagRequirement,
3535 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003536{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003537 QCBOREncode_AddSZString(pMe, szLabel);
3538 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01003539}
3540
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003541static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003542QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003543 const int64_t nLabel,
3544 const uint8_t uTagRequirement,
3545 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003546{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003547 QCBOREncode_AddInt64(pMe, nLabel);
3548 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
3549}
3550
3551static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003552QCBOREncode_AddRegex(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003553{
3554 QCBOREncode_AddTRegex(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
3555}
3556
3557static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003558QCBOREncode_AddRegexToMap(QCBOREncodeContext *pMe,
3559 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003560 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003561{
3562 QCBOREncode_AddTRegexToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
3563}
3564
3565static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003566QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003567 const int64_t nLabel,
3568 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003569{
3570 QCBOREncode_AddTRegexToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
3571
Michael Eckel5c531332020-03-02 01:35:30 +01003572}
3573
3574
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003575static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003576QCBOREncode_AddTMIMEData(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003577 const uint8_t uTagRequirement,
3578 const UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01003579{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003580 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
Laurence Lundblade4982f412020-09-18 23:02:18 -07003581 QCBOREncode_AddTag(pMe, CBOR_TAG_BINARY_MIME);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003582 }
Laurence Lundblade4982f412020-09-18 23:02:18 -07003583 QCBOREncode_AddBytes(pMe, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01003584}
3585
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003586static inline void
3587QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pMe,
3588 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003589 const uint8_t uTagRequirement,
3590 const UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01003591{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003592 QCBOREncode_AddSZString(pMe, szLabel);
3593 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01003594}
3595
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003596static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003597QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003598 const int64_t nLabel,
3599 const uint8_t uTagRequirement,
3600 const UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01003601{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003602 QCBOREncode_AddInt64(pMe, nLabel);
3603 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
3604}
3605
3606static inline void
3607QCBOREncode_AddMIMEData(QCBOREncodeContext *pMe, UsefulBufC MIMEData)
3608{
3609 QCBOREncode_AddTMIMEData(pMe, QCBOR_ENCODE_AS_TAG, MIMEData);
3610}
3611
3612static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003613QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pMe,
3614 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003615 const UsefulBufC MIMEData)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003616{
3617 QCBOREncode_AddTMIMEDataToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
3618}
3619
3620static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003621QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003622 const int64_t nLabel,
3623 const UsefulBufC MIMEData)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003624{
3625 QCBOREncode_AddTMIMEDataToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01003626}
3627
3628
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003629static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003630QCBOREncode_AddTDateString(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003631 const uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003632 const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01003633{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003634 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3635 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_STRING);
3636 }
3637 QCBOREncode_AddSZString(pMe, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01003638}
3639
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003640static inline void
3641QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pMe,
3642 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003643 const uint8_t uTagRequirement,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003644 const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01003645{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003646 QCBOREncode_AddSZString(pMe, szLabel);
3647 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01003648}
3649
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003650static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003651QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003652 const int64_t nLabel,
3653 const uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003654 const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01003655{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003656 QCBOREncode_AddInt64(pMe, nLabel);
3657 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
3658}
3659
3660static inline void
3661QCBOREncode_AddDateString(QCBOREncodeContext *pMe, const char *szDate)
3662{
3663 QCBOREncode_AddTDateString(pMe, QCBOR_ENCODE_AS_TAG, szDate);
3664}
3665
3666static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003667QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pMe,
3668 const char *szLabel,
3669 const char *szDate)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003670{
3671 QCBOREncode_AddTDateStringToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, szDate);
3672}
3673
3674static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003675QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003676 const int64_t nLabel,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003677 const char *szDate)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003678{
3679 QCBOREncode_AddTDateStringToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01003680}
3681
3682
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003683static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003684QCBOREncode_AddTDaysString(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003685 const uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003686 const char *szDate)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07003687{
3688 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3689 QCBOREncode_AddTag(pMe, CBOR_TAG_DAYS_STRING);
3690 }
3691 QCBOREncode_AddSZString(pMe, szDate);
3692}
3693
3694static inline void
3695QCBOREncode_AddTDaysStringToMapSZ(QCBOREncodeContext *pMe,
3696 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003697 const uint8_t uTagRequirement,
Laurence Lundblade46d63e92021-05-13 11:37:10 -07003698 const char *szDate)
3699{
3700 QCBOREncode_AddSZString(pMe, szLabel);
3701 QCBOREncode_AddTDaysString(pMe, uTagRequirement, szDate);
3702}
3703
3704static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003705QCBOREncode_AddTDaysStringToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003706 const int64_t nLabel,
3707 const uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003708 const char *szDate)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07003709{
3710 QCBOREncode_AddInt64(pMe, nLabel);
3711 QCBOREncode_AddTDaysString(pMe, uTagRequirement, szDate);
3712}
3713
3714
3715
3716static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003717QCBOREncode_Private_AddSimple(QCBOREncodeContext *pMe, const uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01003718{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003719 QCBOREncode_Private_AddType7(pMe, 0, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01003720}
3721
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003722static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003723QCBOREncode_Private_AddSimpleToMap(QCBOREncodeContext *pMe,
3724 const char *szLabel,
3725 const uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01003726{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003727 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003728 QCBOREncode_Private_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01003729}
3730
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003731static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003732QCBOREncode_Private_AddSimpleToMapN(QCBOREncodeContext *pMe,
3733 const int64_t nLabel,
3734 const uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01003735{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003736 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003737 QCBOREncode_Private_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01003738}
3739
3740
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003741static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003742QCBOREncode_AddBool(QCBOREncodeContext *pMe, const bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01003743{
3744 uint8_t uSimple = CBOR_SIMPLEV_FALSE;
3745 if(b) {
3746 uSimple = CBOR_SIMPLEV_TRUE;
3747 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003748 QCBOREncode_Private_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01003749}
3750
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003751static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003752QCBOREncode_AddBoolToMap(QCBOREncodeContext *pMe, const char *szLabel, const bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01003753{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003754 QCBOREncode_AddSZString(pMe, szLabel);
3755 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01003756}
3757
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003758static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003759QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pMe, const int64_t nLabel, const bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01003760{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003761 QCBOREncode_AddInt64(pMe, nLabel);
3762 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01003763}
3764
3765
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003766static inline void
3767QCBOREncode_AddNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003768{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003769 QCBOREncode_Private_AddSimple(pMe, CBOR_SIMPLEV_NULL);
Michael Eckel5c531332020-03-02 01:35:30 +01003770}
3771
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003772static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003773QCBOREncode_AddNULLToMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003774{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003775 QCBOREncode_AddSZString(pMe, szLabel);
3776 QCBOREncode_AddNULL(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003777}
3778
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003779static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003780QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003781{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003782 QCBOREncode_AddInt64(pMe, nLabel);
3783 QCBOREncode_AddNULL(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003784}
3785
3786
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003787static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003788QCBOREncode_AddUndef(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003789{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003790 QCBOREncode_Private_AddSimple(pMe, CBOR_SIMPLEV_UNDEF);
Michael Eckel5c531332020-03-02 01:35:30 +01003791}
3792
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003793static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003794QCBOREncode_AddUndefToMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003795{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003796 QCBOREncode_AddSZString(pMe, szLabel);
3797 QCBOREncode_AddUndef(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003798}
3799
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003800static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003801QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003802{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003803 QCBOREncode_AddInt64(pMe, nLabel);
3804 QCBOREncode_AddUndef(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003805}
3806
3807
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003808static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003809QCBOREncode_OpenArray(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003810{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003811 QCBOREncode_Private_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
Michael Eckel5c531332020-03-02 01:35:30 +01003812}
3813
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003814static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003815QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003816{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003817 QCBOREncode_AddSZString(pMe, szLabel);
3818 QCBOREncode_OpenArray(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003819}
3820
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003821static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003822QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003823{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003824 QCBOREncode_AddInt64(pMe, nLabel);
3825 QCBOREncode_OpenArray(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003826}
3827
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003828static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003829QCBOREncode_CloseArray(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003830{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003831 QCBOREncode_Private_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
Michael Eckel5c531332020-03-02 01:35:30 +01003832}
3833
3834
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003835static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003836QCBOREncode_OpenMap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003837{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003838 QCBOREncode_Private_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
Michael Eckel5c531332020-03-02 01:35:30 +01003839}
3840
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003841static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003842QCBOREncode_OpenMapInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003843{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003844 QCBOREncode_AddSZString(pMe, szLabel);
3845 QCBOREncode_OpenMap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003846}
3847
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003848static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003849QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003850{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003851 QCBOREncode_AddInt64(pMe, nLabel);
3852 QCBOREncode_OpenMap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003853}
3854
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003855static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003856QCBOREncode_CloseMap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003857{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003858 QCBOREncode_Private_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
Michael Eckel5c531332020-03-02 01:35:30 +01003859}
3860
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003861static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003862QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003863{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003864 QCBOREncode_Private_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003865}
3866
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003867static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003868QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pMe,
3869 const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003870{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003871 QCBOREncode_AddSZString(pMe, szLabel);
3872 QCBOREncode_OpenArrayIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003873}
3874
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003875static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003876QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003877 const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003878{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003879 QCBOREncode_AddInt64(pMe, nLabel);
3880 QCBOREncode_OpenArrayIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003881}
3882
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003883static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003884QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003885{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003886 QCBOREncode_Private_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003887}
3888
3889
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003890static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003891QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003892{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003893 QCBOREncode_Private_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003894}
3895
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003896static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003897QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pMe,
3898 const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003899{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003900 QCBOREncode_AddSZString(pMe, szLabel);
3901 QCBOREncode_OpenMapIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003902}
3903
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003904static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003905QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003906 const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003907{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003908 QCBOREncode_AddInt64(pMe, nLabel);
3909 QCBOREncode_OpenMapIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003910}
3911
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003912static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003913QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003914{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003915 QCBOREncode_Private_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003916}
3917
3918
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003919static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003920QCBOREncode_BstrWrap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003921{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003922 QCBOREncode_Private_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_BYTE_STRING);
Michael Eckel5c531332020-03-02 01:35:30 +01003923}
3924
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003925static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003926QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003927{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003928 QCBOREncode_AddSZString(pMe, szLabel);
3929 QCBOREncode_BstrWrap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003930}
3931
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003932static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003933QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003934{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003935 QCBOREncode_AddInt64(pMe, nLabel);
3936 QCBOREncode_BstrWrap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003937}
3938
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003939static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003940QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pMe, UsefulBufC *pWrappedCBOR)
Michael Eckel5c531332020-03-02 01:35:30 +01003941{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003942 QCBOREncode_CloseBstrWrap2(pMe, true, pWrappedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01003943}
3944
3945
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003946static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003947QCBOREncode_AddEncoded(QCBOREncodeContext *pMe, const UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003948{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003949 QCBOREncode_Private_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_RAW, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003950}
3951
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003952static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003953QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pMe,
3954 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003955 const UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003956{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003957 QCBOREncode_AddSZString(pMe, szLabel);
3958 QCBOREncode_AddEncoded(pMe, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003959}
3960
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003961static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003962QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003963 const int64_t nLabel,
3964 const UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003965{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003966 QCBOREncode_AddInt64(pMe, nLabel);
3967 QCBOREncode_AddEncoded(pMe, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003968}
3969
3970
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003971static inline int
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003972QCBOREncode_IsBufferNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003973{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003974 return UsefulOutBuf_IsBufferNULL(&(pMe->OutBuf));
Michael Eckel5c531332020-03-02 01:35:30 +01003975}
3976
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003977static inline QCBORError
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003978QCBOREncode_GetErrorState(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003979{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003980 if(UsefulOutBuf_GetError(&(pMe->OutBuf))) {
Michael Eckel5c531332020-03-02 01:35:30 +01003981 // Items didn't fit in the buffer.
3982 // This check catches this condition for all the appends and inserts
3983 // so checks aren't needed when the appends and inserts are performed.
3984 // And of course UsefulBuf will never overrun the input buffer given
3985 // to it. No complex analysis of the error handling in this file is
3986 // needed to know that is true. Just read the UsefulBuf code.
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003987 pMe->uError = QCBOR_ERR_BUFFER_TOO_SMALL;
Michael Eckel5c531332020-03-02 01:35:30 +01003988 // QCBOR_ERR_BUFFER_TOO_SMALL masks other errors, but that is
3989 // OK. Once the caller fixes this, they'll be unmasked.
3990 }
3991
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003992 return (QCBORError)pMe->uError;
Michael Eckel5c531332020-03-02 01:35:30 +01003993}
3994
3995
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003996/* ========================================================================
3997 END OF PRIVATE INLINE IMPLEMENTATION
3998 ======================================================================== */
Michael Eckel5c531332020-03-02 01:35:30 +01003999
4000#ifdef __cplusplus
4001}
4002#endif
4003
Laurence Lundblade844bb5c2020-03-01 17:27:25 -08004004#endif /* qcbor_encode_h */