blob: 6012b255d0cf13c62fe3bc5bd9163625917f1e94 [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 Lundblade3eead482023-12-16 20:53:22 -0700547 * @brief Add a UTF-8 text string to the encoded output.
548 *
549 * @param[in] pCtx The encoding context to add the text to.
550 * @param[in] Text Pointer and length of text to add.
551 *
552 * The text passed in must be unencoded UTF-8 according to [RFC 3629]
553 * (https://tools.ietf.org/html/rfc3629). There is no NULL
554 * termination. The text is added as CBOR major type 3.
555 *
556 * If called with @c nBytesLen equal to 0, an empty string will be
557 * added. When @c nBytesLen is 0, @c pBytes may be @c NULL.
558 *
559 * Note that the restriction of the buffer length to a @c uint32_t is
560 * entirely intentional as this encoder is not capable of encoding
561 * lengths greater. This limit to 4GB for a text string should not be
562 * a problem.
563 *
564 * Text lines in Internet protocols (on the wire) are delimited by
565 * either a CRLF or just an LF. Officially many protocols specify
566 * CRLF, but implementations often work with either. CBOR type 3 text
567 * can be either line ending, even a mixture of both.
568 *
569 * Operating systems usually have a line end convention. Windows uses
570 * CRLF. Linux and MacOS use LF. Some applications on a given OS may
571 * work with either and some may not.
572 *
573 * The majority of use cases and CBOR protocols using type 3 text will
574 * work with either line ending. However, some use cases or protocols
575 * may not work with either in which case translation to and/or from
576 * the local line end convention, typically that of the OS, is
577 * necessary.
578 *
579 * QCBOR does no line ending translation for type 3 text when encoding
580 * and decoding.
581 *
582 * Error handling is the same as QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +0100583 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700584static void
585QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text);
Michael Eckel5c531332020-03-02 01:35:30 +0100586
Laurence Lundblade3eead482023-12-16 20:53:22 -0700587static void
588QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text);
Michael Eckel5c531332020-03-02 01:35:30 +0100589
Laurence Lundblade3eead482023-12-16 20:53:22 -0700590static void
591QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text);
Michael Eckel5c531332020-03-02 01:35:30 +0100592
593
594/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700595 * @brief Add a UTF-8 text string to the encoded output.
596 *
597 * @param[in] pCtx The encoding context to add the text to.
598 * @param[in] szString Null-terminated text to add.
599 *
600 * This works the same as QCBOREncode_AddText().
Michael Eckel5c531332020-03-02 01:35:30 +0100601 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700602static void
603QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString);
Michael Eckel5c531332020-03-02 01:35:30 +0100604
Laurence Lundblade3eead482023-12-16 20:53:22 -0700605static void
606QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString);
Michael Eckel5c531332020-03-02 01:35:30 +0100607
Laurence Lundblade3eead482023-12-16 20:53:22 -0700608static void
609QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString);
Michael Eckel5c531332020-03-02 01:35:30 +0100610
611
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200612#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Michael Eckel5c531332020-03-02 01:35:30 +0100613/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700614 * @brief Add a double-precision floating-point number to the encoded output.
615 *
616 * @param[in] pCtx The encoding context to add the double to.
617 * @param[in] dNum The double-precision number to add.
618 *
619 * This encodes and outputs a floating-point number. CBOR major type 7
620 * is used.
621 *
622 * This implements preferred serialization, selectively encoding the
623 * double-precision floating-point number as either double-precision,
624 * single-precision or half-precision. Infinity, NaN and 0 are always
625 * encoded as half-precision. If no precision will be lost in the
626 * conversion to half-precision, then it will be converted and
627 * encoded. If not and no precision will be lost in conversion to
628 * single-precision, then it will be converted and encoded. If not,
629 * then no conversion is performed, and it encoded as a
630 * double-precision.
631 *
632 * Half-precision floating-point numbers take up 2 bytes, half that of
633 * single-precision, one quarter of double-precision
634 *
635 * This automatically reduces the size of encoded CBOR, maybe even by
636 * four if most of values are 0, infinity or NaN.
637 *
638 * When decoded, QCBOR will usually return these values as
639 * double-precision.
640 *
641 * It is possible to disable this preferred serialization when compiling
642 * QCBOR. In that case, this functions the same as
643 * QCBOREncode_AddDoubleNoPreferred().
644 *
645 * Error handling is the same as QCBOREncode_AddInt64().
646 *
647 * See also QCBOREncode_AddDoubleNoPreferred(), QCBOREncode_AddFloat()
648 * and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
Michael Eckel5c531332020-03-02 01:35:30 +0100649 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700650void
651QCBOREncode_AddDouble(QCBOREncodeContext *pCtx, double dNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100652
Laurence Lundblade3eead482023-12-16 20:53:22 -0700653static void
654QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100655
Laurence Lundblade3eead482023-12-16 20:53:22 -0700656static void
657QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100658
659
660/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700661 * @brief Add a single-precision floating-point number to the encoded output.
662 *
663 * @param[in] pCtx The encoding context to add the double to.
664 * @param[in] fNum The single-precision number to add.
665 *
666 * This is identical to QCBOREncode_AddDouble() except the input is
667 * single-precision.
668 *
669 * See also QCBOREncode_AddDouble(), QCBOREncode_AddDoubleNoPreferred(),
670 * and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
671 */
672void
673QCBOREncode_AddFloat(QCBOREncodeContext *pCtx, float fNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700674
Laurence Lundblade3eead482023-12-16 20:53:22 -0700675static void
676QCBOREncode_AddFloatToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700677
Laurence Lundblade3eead482023-12-16 20:53:22 -0700678static void
679QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700680
681
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700682/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700683 * @brief Add a double-precision floating-point number without preferred encoding.
684 *
685 * @param[in] pCtx The encoding context to add the double to.
686 * @param[in] dNum The double-precision number to add.
687 *
688 * This always outputs the number as a 64-bit double-precision.
689 * Preferred serialization is not used.
690 *
691 * Error handling is the same as QCBOREncode_AddInt64().
692 *
693 * See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
694 * QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
695 */
696void
697QCBOREncode_AddDoubleNoPreferred(QCBOREncodeContext *pCtx, double dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700698
Laurence Lundblade3eead482023-12-16 20:53:22 -0700699static void
700QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700701
Laurence Lundblade3eead482023-12-16 20:53:22 -0700702static void
703QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700704
705
706/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700707 * @brief Add a single-precision floating-point number without preferred encoding.
708 *
709 * @param[in] pCtx The encoding context to add the double to.
710 * @param[in] fNum The single-precision number to add.
711 *
712 * This always outputs the number as a 32-bit single-precision.
713 * Preferred serialization is not used.
714 *
715 * Error handling is the same as QCBOREncode_AddInt64().
716 *
717 * See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
718 * QCBOREncode_AddDoubleNoPreferred() and @ref Floating-Point.
719 */
720void
721QCBOREncode_AddFloatNoPreferred(QCBOREncodeContext *pCtx, float fNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700722
Laurence Lundblade3eead482023-12-16 20:53:22 -0700723static void
724QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700725
Laurence Lundblade3eead482023-12-16 20:53:22 -0700726static void
727QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float fNum);
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200728#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700729
730
Michael Eckel5c531332020-03-02 01:35:30 +0100731/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700732 * @brief Add an optional tag.
733 *
734 * @param[in] pCtx The encoding context to add the tag to.
735 * @param[in] uTag The tag to add
736 *
737 * This outputs a CBOR major type 6 item that tags the next data item
738 * that is output usually to indicate it is some new data type.
739 *
740 * For many of the common standard tags, a function to encode data
741 * using it is provided and this is not needed. For example,
742 * QCBOREncode_AddDateEpoch() already exists to output integers
743 * representing dates with the right tag.
744 *
745 * The tag is applied to the next data item added to the encoded
746 * output. That data item that is to be tagged can be of any major
747 * CBOR type. Any number of tags can be added to a data item by
748 * calling this multiple times before the data item is added.
749 *
750 * See @ref Tags-Overview for discussion of creating new non-standard
751 * tags. See QCBORDecode_GetNext() for discussion of decoding custom
752 * tags.
Michael Eckel5c531332020-03-02 01:35:30 +0100753 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700754void
755QCBOREncode_AddTag(QCBOREncodeContext *pCtx, uint64_t uTag);
Laurence Lundblade46d63e92021-05-13 11:37:10 -0700756
757
Michael Eckel5c531332020-03-02 01:35:30 +0100758/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700759 * @brief Add an epoch-based date.
760 *
761 * @param[in] pCtx The encoding context to add the date to.
762 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
763 * @ref QCBOR_ENCODE_AS_BORROWED.
764 * @param[in] nDate Number of seconds since 1970-01-01T00:00Z
765 * in UTC time.
766 *
767 * As per RFC 8949 this is similar to UNIX/Linux/POSIX dates. This is
768 * the most compact way to specify a date and time in CBOR. Note that
769 * this is always UTC and does not include the time zone. Use
770 * QCBOREncode_AddDateString() if you want to include the time zone.
771 *
772 * The preferred integer serialization rules apply here so the date will be
773 * encoded in a minimal number of bytes. Until about the year 2106
774 * these dates will encode in 6 bytes -- one byte for the tag, one
775 * byte for the type and 4 bytes for the integer. After that it will
776 * encode to 10 bytes.
777 *
778 * Negative values are supported for dates before 1970.
779 *
780 * If you care about leap-seconds and that level of accuracy, make sure
781 * the system you are running this code on does it correctly. This code
782 * just takes the value passed in.
783 *
784 * This implementation cannot encode fractional seconds using float or
785 * double even though that is allowed by CBOR, but you can encode them
786 * if you want to by calling QCBOREncode_AddTag() and QCBOREncode_AddDouble().
787 *
788 * Error handling is the same as QCBOREncode_AddInt64().
789 *
790 * See also QCBOREncode_AddTDaysEpoch().
Michael Eckel5c531332020-03-02 01:35:30 +0100791 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700792static void
793QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pCtx,
794 uint8_t uTagRequirement,
795 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100796
Laurence Lundblade3eead482023-12-16 20:53:22 -0700797static void
798QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pCtx,
799 const char *szLabel,
800 uint8_t uTagRequirement,
801 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100802
Laurence Lundblade3eead482023-12-16 20:53:22 -0700803static void
804QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pCtx,
805 int64_t nLabel,
806 uint8_t uTagRequirement,
807 int64_t nDate);
808
809
810static void
811QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx,
812 int64_t nDate);
813
814static void
815QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx,
816 const char *szLabel,
817 int64_t nDate);
818
819static void
820QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx,
821 int64_t nLabel,
822 int64_t nDate);
823
Michael Eckel5c531332020-03-02 01:35:30 +0100824
825
Michael Eckel5c531332020-03-02 01:35:30 +0100826/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700827 * @brief Add an epoch-based day-count date.
828 *
829 * @param[in] pCtx The encoding context to add the date to.
830 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
831 * @ref QCBOR_ENCODE_AS_BORROWED.
832 * @param[in] nDays Number of days before or after 1970-01-0.
833 *
834 * This date format is described in
835 * [RFC 8943] (https://tools.ietf.org/html/rfc8943).
836 *
837 * The preferred integer serialization rules apply here so the date
838 * will be encoded in a minimal number of bytes. Until about the year
839 * 2149 these dates will encode in 4 bytes -- one byte for the tag,
840 * one byte for the type and 2 bytes for the integer.
841 *
842 * See also QCBOREncode_AddTDateEpoch().
843 */
844static void
845QCBOREncode_AddTDaysEpoch(QCBOREncodeContext *pCtx,
846 uint8_t uTagRequirement,
847 int64_t nDays);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600848
Laurence Lundblade3eead482023-12-16 20:53:22 -0700849static void
850QCBOREncode_AddTDaysEpochToMapSZ(QCBOREncodeContext *pCtx,
851 const char *szLabel,
852 uint8_t uTagRequirement,
853 int64_t nDays);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600854
Laurence Lundblade3eead482023-12-16 20:53:22 -0700855static void
856QCBOREncode_AddTDaysEpochToMapN(QCBOREncodeContext *pCtx,
857 int64_t nLabel,
858 uint8_t uTagRequirement,
859 int64_t nDays);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600860
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600861
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600862
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600863
Laurence Lundblade3eead482023-12-16 20:53:22 -0700864/**
865 * @brief Add a byte string to the encoded output.
866 *
867 * @param[in] pCtx The encoding context to add the bytes to.
868 * @param[in] Bytes Pointer and length of the input data.
869 *
870 * Simply adds the bytes to the encoded output as CBOR major type 2.
871 *
872 * If called with @c Bytes.len equal to 0, an empty string will be
873 * added. When @c Bytes.len is 0, @c Bytes.ptr may be @c NULL.
874 *
875 * Error handling is the same as QCBOREncode_AddInt64().
876 */
877static void
878QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600879
Laurence Lundblade3eead482023-12-16 20:53:22 -0700880static void
881QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
882
883static void
884QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
885
886
887/**
888 * @brief Set up to write a byte string value directly to encoded output.
889 *
890 * @param[in] pCtx The encoding context to add the bytes to.
891 * @param[out] pPlace Pointer and length of place to write byte string value.
892 *
893 * QCBOREncode_AddBytes() is the normal way to encode a byte string.
894 * This is for special cases and by passes some of the pointer safety.
895 *
896 * The purpose of this is to output the bytes that make up a byte
897 * string value directly to the QCBOR output buffer so you don't need
898 * to have a copy of it in memory. This is particularly useful if the
899 * byte string is large, for example, the encrypted payload of a
900 * COSE_Encrypt message. The payload encryption algorithm can output
901 * directly to the encoded CBOR buffer, perhaps by making it the
902 * output buffer for some function (e.g. symmetric encryption) or by
903 * multiple writes.
904 *
905 * The pointer in @c pPlace is where to start writing. Writing is just
906 * copying bytes to the location by the pointer in \c pPlace. Writing
907 * past the length in @c pPlace will be writing off the end of the
908 * output buffer.
909 *
910 * If there is no room in the output buffer @ref NULLUsefulBuf will be
911 * returned and there is no need to call QCBOREncode_CloseBytes().
912 *
913 * The byte string must be closed by calling QCBOREncode_CloseBytes().
914 *
915 * Warning: this bypasses some of the usual checks provided by QCBOR
916 * against writing off the end of the encoded output buffer.
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600917 */
918void
919QCBOREncode_OpenBytes(QCBOREncodeContext *pCtx, UsefulBuf *pPlace);
920
921static void
Laurence Lundblade3eead482023-12-16 20:53:22 -0700922QCBOREncode_OpenBytesInMapSZ(QCBOREncodeContext *pCtx,
923 const char *szLabel,
924 UsefulBuf *pPlace);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600925
926static void
Laurence Lundblade3eead482023-12-16 20:53:22 -0700927QCBOREncode_OpenBytesInMapN(QCBOREncodeContext *pCtx,
928 int64_t nLabel,
929 UsefulBuf *pPlace);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600930
931
932/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700933 * @brief Close out a byte string written directly to encoded output.
934 *
935 * @param[in] pCtx The encoding context to add the bytes to.
936 * @param[out] uAmount The number of bytes written, the length of the
937 * byte string.
938 *
939 * This closes out a call to QCBOREncode_OpenBytes(). This inserts a
940 * CBOR header at the front of the byte string value to make it a
941 * well-formed byte string.
942 *
943 * If there was no call to QCBOREncode_OpenBytes() then @ref
944 * QCBOR_ERR_TOO_MANY_CLOSES is set.
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600945 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700946void
947QCBOREncode_CloseBytes(QCBOREncodeContext *pCtx, size_t uAmount);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600948
949
950/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700951 * @brief Add a binary UUID to the encoded output.
952 *
953 * @param[in] pCtx The encoding context to add the UUID to.
954 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
955 * @ref QCBOR_ENCODE_AS_BORROWED.
956 * @param[in] Bytes Pointer and length of the binary UUID.
957 *
958 * A binary UUID as defined in [RFC 4122]
959 * (https://tools.ietf.org/html/rfc4122) is added to the output.
960 *
961 * It is output as CBOR major type 2, a binary string, with tag @ref
962 * CBOR_TAG_BIN_UUID indicating the binary string is a UUID.
Michael Eckel5c531332020-03-02 01:35:30 +0100963 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700964static void
965QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pCtx,
966 uint8_t uTagRequirement,
967 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700968
Laurence Lundblade3eead482023-12-16 20:53:22 -0700969static void
970QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pCtx,
971 const char *szLabel,
972 uint8_t uTagRequirement,
973 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700974
Laurence Lundblade3eead482023-12-16 20:53:22 -0700975static void
976QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pCtx,
977 int64_t nLabel,
978 uint8_t uTagRequirement,
979 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700980
981
Laurence Lundblade3eead482023-12-16 20:53:22 -0700982static void
983QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100984
Laurence Lundblade3eead482023-12-16 20:53:22 -0700985static void
986QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100987
Laurence Lundblade3eead482023-12-16 20:53:22 -0700988static void
989QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100990
991
992/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700993 * @brief Add a positive big number to the encoded output.
994 *
995 * @param[in] pCtx The encoding context to add the big number to.
996 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
997 * @ref QCBOR_ENCODE_AS_BORROWED.
998 * @param[in] Bytes Pointer and length of the big number.
999 *
1000 * Big numbers are integers larger than 64-bits. Their format is
1001 * described in [RFC 8949] (https://tools.ietf.org/html/rfc8949).
1002 *
1003 * It is output as CBOR major type 2, a binary string, with tag
1004 * @ref CBOR_TAG_POS_BIGNUM indicating the binary string is a positive
1005 * big number.
1006 *
1007 * Often big numbers are used to represent cryptographic keys,
1008 * however, COSE which defines representations for keys chose not to
1009 * use this particular type.
Michael Eckel5c531332020-03-02 01:35:30 +01001010 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001011static void
1012QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pCtx,
1013 uint8_t uTagRequirement,
1014 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001015
Laurence Lundblade3eead482023-12-16 20:53:22 -07001016static void
1017QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pCtx,
1018 const char *szLabel,
1019 uint8_t uTagRequirement,
1020 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001021
Laurence Lundblade3eead482023-12-16 20:53:22 -07001022static void
1023QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pCtx,
1024 int64_t nLabel,
1025 uint8_t uTagRequirement,
1026 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001027
1028
Laurence Lundblade3eead482023-12-16 20:53:22 -07001029static void
1030QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx,
1031 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001032
Laurence Lundblade3eead482023-12-16 20:53:22 -07001033static void
1034QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx,
1035 const char *szLabel,
1036 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001037
Laurence Lundblade3eead482023-12-16 20:53:22 -07001038static void
1039QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx,
1040 int64_t nLabel,
1041 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001042
1043
1044/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001045 * @brief Add a negative big number to the encoded output.
1046 *
1047 * @param[in] pCtx The encoding context to add the big number to.
1048 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1049 * @ref QCBOR_ENCODE_AS_BORROWED.
1050 * @param[in] Bytes Pointer and length of the big number.
1051 *
1052 * Big numbers are integers larger than 64-bits. Their format is
1053 * described in [RFC 8949] (https://tools.ietf.org/html/rfc8949).
1054 *
1055 * It is output as CBOR major type 2, a binary string, with tag
1056 * @ref CBOR_TAG_NEG_BIGNUM indicating the binary string is a negative
1057 * big number.
1058 *
1059 * Often big numbers are used to represent cryptographic keys,
1060 * however, COSE which defines representations for keys chose not to
1061 * use this particular type.
Michael Eckel5c531332020-03-02 01:35:30 +01001062 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001063static void
1064QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pCtx,
1065 uint8_t uTagRequirement,
1066 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001067
Laurence Lundblade3eead482023-12-16 20:53:22 -07001068static void
1069QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pCtx,
1070 const char *szLabel,
1071 uint8_t uTagRequirement,
1072 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001073
Laurence Lundblade3eead482023-12-16 20:53:22 -07001074static void
1075QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pCtx,
1076 int64_t nLabel,
1077 uint8_t uTagRequirement,
1078 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001079
1080
Laurence Lundblade3eead482023-12-16 20:53:22 -07001081static void
1082QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx,
1083 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001084
Laurence Lundblade3eead482023-12-16 20:53:22 -07001085static void
1086QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx,
1087 const char *szLabel,
1088 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001089
Laurence Lundblade3eead482023-12-16 20:53:22 -07001090static void
1091QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx,
1092 int64_t nLabel,
1093 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001094
1095
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07001096#ifndef QCBOR_DISABLE_EXP_AND_MANTISSA
Michael Eckel5c531332020-03-02 01:35:30 +01001097/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001098 * @brief Add a decimal fraction to the encoded output.
1099 *
1100 * @param[in] pCtx Encoding context to add the decimal fraction to.
1101 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1102 * @ref QCBOR_ENCODE_AS_BORROWED.
1103 * @param[in] nMantissa The mantissa.
1104 * @param[in] nBase10Exponent The exponent.
1105 *
1106 * The value is nMantissa * 10 ^ nBase10Exponent.
1107 *
1108 * A decimal fraction is good for exact representation of some values
1109 * that can't be represented exactly with standard C (IEEE 754)
1110 * floating-point numbers. Much larger and much smaller numbers can
1111 * also be represented than floating-point because of the larger
1112 * number of bits in the exponent.
1113 *
1114 * The decimal fraction is conveyed as two integers, a mantissa and a
1115 * base-10 scaling factor.
1116 *
1117 * For example, 273.15 is represented by the two integers 27315 and -2.
1118 *
1119 * The exponent and mantissa have the range from @c INT64_MIN to
1120 * @c INT64_MAX for both encoding and decoding (CBOR allows
1121 * @c -UINT64_MAX to @c UINT64_MAX, but this implementation doesn't
1122 * support this range to reduce code size and interface complexity a
1123 * little).
1124 *
1125 * CBOR Preferred serialization of the integers is used, thus they
1126 * will be encoded in the smallest number of bytes possible.
1127 *
1128 * See also QCBOREncode_AddDecimalFractionBigNum() for a decimal
1129 * fraction with arbitrarily large precision and
1130 * QCBOREncode_AddBigFloat().
1131 *
1132 * There is no representation of positive or negative infinity or NaN
1133 * (Not a Number). Use QCBOREncode_AddDouble() to encode them.
1134 *
1135 * See @ref expAndMantissa for decoded representation.
Michael Eckel5c531332020-03-02 01:35:30 +01001136 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001137static void
1138QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pCtx,
1139 uint8_t uTagRequirement,
1140 int64_t nMantissa,
1141 int64_t nBase10Exponent);
1142
1143static void
1144QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pCtx,
1145 const char *szLabel,
1146 uint8_t uTagRequirement,
1147 int64_t nMantissa,
1148 int64_t nBase10Exponent);
1149
1150static void
1151QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pCtx,
1152 int64_t nLabel,
1153 uint8_t uTagRequirement,
1154 int64_t nMantissa,
1155 int64_t nBase10Exponent);
1156
1157
1158static void
1159QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pCtx,
1160 int64_t nMantissa,
1161 int64_t nBase10Exponent);
1162
1163static void
1164QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pCtx,
1165 const char *szLabel,
1166 int64_t nMantissa,
1167 int64_t nBase10Exponent);
1168
1169static void
1170QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pCtx,
1171 int64_t nLabel,
1172 int64_t nMantissa,
1173 int64_t nBase10Exponent);
1174
1175
1176/**
1177 * @brief Add a decimal fraction with a big number mantissa to the encoded output.
1178 *
1179 * @param[in] pCtx Encoding context to add the decimal fraction to.
1180 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1181 * @ref QCBOR_ENCODE_AS_BORROWED.
1182 * @param[in] Mantissa The mantissa.
1183 * @param[in] bIsNegative false if mantissa is positive, true if negative.
1184 * @param[in] nBase10Exponent The exponent.
1185 *
1186 * This is the same as QCBOREncode_AddDecimalFraction() except the
1187 * mantissa is a big number (See QCBOREncode_AddPositiveBignum())
1188 * allowing for arbitrarily large precision.
1189 *
1190 * See @ref expAndMantissa for decoded representation.
1191 */
1192static void
1193QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pCtx,
1194 uint8_t uTagRequirement,
1195 UsefulBufC Mantissa,
1196 bool bIsNegative,
1197 int64_t nBase10Exponent);
1198
1199static void
1200QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
1201 const char *szLabel,
1202 uint8_t uTagRequirement,
1203 UsefulBufC Mantissa,
1204 bool bIsNegative,
1205 int64_t nBase10Exponent);
1206
1207static void
1208QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
1209 int64_t nLabel,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001210 uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07001211 UsefulBufC Mantissa,
1212 bool bIsNegative,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001213 int64_t nBase10Exponent);
1214
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001215
Laurence Lundblade3eead482023-12-16 20:53:22 -07001216static void
1217QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pCtx,
1218 UsefulBufC Mantissa,
1219 bool bIsNegative,
1220 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001221
Laurence Lundblade3eead482023-12-16 20:53:22 -07001222static void
1223QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001224 const char *szLabel,
Laurence Lundblade3eead482023-12-16 20:53:22 -07001225 UsefulBufC Mantissa,
1226 bool bIsNegative,
1227 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001228
Laurence Lundblade3eead482023-12-16 20:53:22 -07001229static void
1230QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001231 int64_t nLabel,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001232 UsefulBufC Mantissa,
1233 bool bIsNegative,
Laurence Lundblade3eead482023-12-16 20:53:22 -07001234 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001235
Laurence Lundblade3eead482023-12-16 20:53:22 -07001236/**
1237 * @brief Add a big floating-point number to the encoded output.
1238 *
1239 * @param[in] pCtx The encoding context to add the bigfloat to.
1240 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1241 * @ref QCBOR_ENCODE_AS_BORROWED.
1242 * @param[in] nMantissa The mantissa.
1243 * @param[in] nBase2Exponent The exponent.
1244 *
1245 * The value is nMantissa * 2 ^ nBase2Exponent.
1246 *
1247 * "Bigfloats", as CBOR terms them, are similar to IEEE floating-point
1248 * numbers in having a mantissa and base-2 exponent, but they are not
1249 * supported by hardware or encoded the same. They explicitly use two
1250 * CBOR-encoded integers to convey the mantissa and exponent, each of
1251 * which can be 8, 16, 32 or 64 bits. With both the mantissa and
1252 * exponent 64 bits they can express more precision and a larger range
1253 * than an IEEE double floating-point number. See
1254 * QCBOREncode_AddBigFloatBigNum() for even more precision.
1255 *
1256 * For example, 1.5 would be represented by a mantissa of 3 and an
1257 * exponent of -1.
1258 *
1259 * The exponent and mantissa have the range from @c INT64_MIN to
1260 * @c INT64_MAX for both encoding and decoding (CBOR allows @c
1261 * -UINT64_MAX to @c UINT64_MAX, but this implementation doesn't
1262 * support this range to reduce code size and interface complexity a
1263 * little).
1264 *
1265 * CBOR preferred serialization of the integers is used, thus they will
1266 * be encoded in the smallest number of bytes possible.
1267 *
1268 * This can also be used to represent floating-point numbers in
1269 * environments that don't support IEEE 754.
1270 *
1271 * See @ref expAndMantissa for decoded representation.
1272 */
1273static void
1274QCBOREncode_AddTBigFloat(QCBOREncodeContext *pCtx,
1275 uint8_t uTagRequirement,
1276 int64_t nMantissa,
1277 int64_t nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001278
Laurence Lundblade3eead482023-12-16 20:53:22 -07001279static void
1280QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pCtx,
1281 const char *szLabel,
1282 uint8_t uTagRequirement,
1283 int64_t nMantissa,
1284 int64_t nBase2Exponent);
1285
1286static void
1287QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pCtx,
1288 int64_t nLabel,
1289 uint8_t uTagRequirement,
1290 int64_t nMantissa,
1291 int64_t nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001292
1293
Laurence Lundblade3eead482023-12-16 20:53:22 -07001294static void
1295QCBOREncode_AddBigFloat(QCBOREncodeContext *pCtx,
1296 int64_t nMantissa,
1297 int64_t nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01001298
Laurence Lundblade3eead482023-12-16 20:53:22 -07001299static void
1300QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pCtx,
1301 const char *szLabel,
1302 int64_t nMantissa,
1303 int64_t nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01001304
Laurence Lundblade3eead482023-12-16 20:53:22 -07001305static void
1306QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pCtx,
1307 int64_t nLabel,
1308 int64_t nMantissa,
1309 int64_t nBase2Exponent);
1310
1311/**
1312 * @brief Add a big floating-point number with a big number mantissa to
1313 * the encoded output.
1314 *
1315 * @param[in] pCtx The encoding context to add the bigfloat to.
1316 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1317 * @ref QCBOR_ENCODE_AS_BORROWED.
1318 * @param[in] Mantissa The mantissa.
1319 * @param[in] bIsNegative false if mantissa is positive, true if negative.
1320 * @param[in] nBase2Exponent The exponent.
1321 *
1322 * This is the same as QCBOREncode_AddBigFloat() except the mantissa
1323 * is a big number (See QCBOREncode_AddPositiveBignum()) allowing for
1324 * arbitrary precision.
1325 *
1326 * See @ref expAndMantissa for decoded representation.
1327 */
1328static void
1329QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pCtx,
1330 uint8_t uTagRequirement,
1331 UsefulBufC Mantissa,
1332 bool bIsNegative,
1333 int64_t nBase2Exponent);
1334
1335static void
1336QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pCtx,
1337 const char *szLabel,
1338 uint8_t uTagRequirement,
1339 UsefulBufC Mantissa,
1340 bool bIsNegative,
1341 int64_t nBase2Exponent);
1342
1343static void
1344QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1345 int64_t nLabel,
1346 uint8_t uTagRequirement,
1347 UsefulBufC Mantissa,
1348 bool bIsNegative,
1349 int64_t nBase2Exponent);
1350
1351
1352static void
1353QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pCtx,
1354 UsefulBufC Mantissa,
1355 bool bIsNegative,
1356 int64_t nBase2Exponent);
1357
1358static void
1359QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pCtx,
1360 const char *szLabel,
1361 UsefulBufC Mantissa,
1362 bool bIsNegative,
1363 int64_t nBase2Exponent);
1364
1365static void
1366QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1367 int64_t nLabel,
1368 UsefulBufC Mantissa,
1369 bool bIsNegative,
1370 int64_t nBase2Exponent);
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07001371#endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
Michael Eckel5c531332020-03-02 01:35:30 +01001372
1373
1374/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001375 * @brief Add a text URI to the encoded output.
1376 *
1377 * @param[in] pCtx The encoding context to add the URI to.
1378 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1379 * @ref QCBOR_ENCODE_AS_BORROWED.
1380 * @param[in] URI Pointer and length of the URI.
1381 *
1382 * The format of URI must be per [RFC 3986]
1383 * (https://tools.ietf.org/html/rfc3986).
1384 *
1385 * It is output as CBOR major type 3, a text string, with tag @ref
1386 * CBOR_TAG_URI indicating the text string is a URI.
1387 *
1388 * A URI in a NULL-terminated string, @c szURI, can be easily added with
1389 * this code:
1390 *
1391 * QCBOREncode_AddURI(pCtx, UsefulBuf_FromSZ(szURI));
Michael Eckel5c531332020-03-02 01:35:30 +01001392 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001393static void
1394QCBOREncode_AddTURI(QCBOREncodeContext *pCtx,
1395 uint8_t uTagRequirement,
1396 UsefulBufC URI);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001397
Laurence Lundblade3eead482023-12-16 20:53:22 -07001398static void
1399QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pCtx,
1400 const char *szLabel,
1401 uint8_t uTagRequirement,
1402 UsefulBufC URI);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001403
Laurence Lundblade3eead482023-12-16 20:53:22 -07001404static void
1405QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pCtx,
1406 int64_t nLabel,
1407 uint8_t uTagRequirement,
1408 UsefulBufC URI);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001409
1410
Laurence Lundblade3eead482023-12-16 20:53:22 -07001411static void
1412QCBOREncode_AddURI(QCBOREncodeContext *pCtx,
1413 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001414
Laurence Lundblade3eead482023-12-16 20:53:22 -07001415static void
1416QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx,
1417 const char *szLabel,
1418 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001419
Laurence Lundblade3eead482023-12-16 20:53:22 -07001420static void
1421QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx,
1422 int64_t nLabel,
1423 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001424
1425
1426/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001427 * @brief Add Base64-encoded text to encoded output.
1428 *
1429 * @param[in] pCtx The encoding context to add the base-64 text to.
1430 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1431 * @ref QCBOR_ENCODE_AS_BORROWED.
1432 * @param[in] B64Text Pointer and length of the base-64 encoded text.
1433 *
1434 * The text content is Base64 encoded data per [RFC 4648]
1435 * (https://tools.ietf.org/html/rfc4648).
1436 *
1437 * It is output as CBOR major type 3, a text string, with tag @ref
1438 * CBOR_TAG_B64 indicating the text string is Base64 encoded.
Michael Eckel5c531332020-03-02 01:35:30 +01001439 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001440static void
1441QCBOREncode_AddTB64Text(QCBOREncodeContext *pCtx,
1442 uint8_t uTagRequirement,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001443 UsefulBufC B64Text);
1444
Laurence Lundblade3eead482023-12-16 20:53:22 -07001445static void
1446QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pCtx,
1447 const char *szLabel,
1448 uint8_t uTagRequirement,
1449 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001450
Laurence Lundblade3eead482023-12-16 20:53:22 -07001451static void
1452QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pCtx,
1453 int64_t nLabel,
1454 uint8_t uTagRequirement,
1455 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001456
1457
Laurence Lundblade3eead482023-12-16 20:53:22 -07001458static void
1459QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx,
1460 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001461
Laurence Lundblade3eead482023-12-16 20:53:22 -07001462static void
1463QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx,
1464 const char *szLabel,
1465 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001466
Laurence Lundblade3eead482023-12-16 20:53:22 -07001467static void
1468QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx,
1469 int64_t nLabel,
1470 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001471
1472
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001473
Michael Eckel5c531332020-03-02 01:35:30 +01001474/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001475 * @brief Add base64url encoded data to encoded output.
1476 *
1477 * @param[in] pCtx The encoding context to add the base64url to.
1478 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1479 * @ref QCBOR_ENCODE_AS_BORROWED.
1480 * @param[in] B64Text Pointer and length of the base64url encoded text.
1481 *
1482 * The text content is base64URL encoded text as per [RFC 4648]
1483 * (https://tools.ietf.org/html/rfc4648).
1484 *
1485 * It is output as CBOR major type 3, a text string, with tag
1486 * @ref CBOR_TAG_B64URL indicating the text string is a Base64url
1487 * encoded.
Michael Eckel5c531332020-03-02 01:35:30 +01001488 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001489static void
1490QCBOREncode_AddTB64URLText(QCBOREncodeContext *pCtx,
1491 uint8_t uTagRequirement,
1492 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001493
Laurence Lundblade3eead482023-12-16 20:53:22 -07001494static void
1495QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pCtx,
1496 const char *szLabel,
1497 uint8_t uTagRequirement,
1498 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001499
Laurence Lundblade3eead482023-12-16 20:53:22 -07001500static void
1501QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pCtx,
1502 int64_t nLabel,
1503 uint8_t uTagRequirement,
1504 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001505
1506
Laurence Lundblade3eead482023-12-16 20:53:22 -07001507static void
1508QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx,
1509 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001510
Laurence Lundblade3eead482023-12-16 20:53:22 -07001511static void
1512QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx,
1513 const char *szLabel,
1514 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001515
Laurence Lundblade3eead482023-12-16 20:53:22 -07001516static void
1517QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx,
1518 int64_t nLabel,
1519 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001520
1521
1522/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001523 * @brief Add Perl Compatible Regular Expression.
1524 *
1525 * @param[in] pCtx Encoding context to add the regular expression to.
1526 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1527 * @ref QCBOR_ENCODE_AS_BORROWED.
1528 * @param[in] Regex Pointer and length of the regular expression.
1529 *
1530 * The text content is Perl Compatible Regular
1531 * Expressions (PCRE) / JavaScript syntax [ECMA262].
1532 *
1533 * It is output as CBOR major type 3, a text string, with tag @ref
1534 * CBOR_TAG_REGEX indicating the text string is a regular expression.
Michael Eckel5c531332020-03-02 01:35:30 +01001535 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001536static void
1537QCBOREncode_AddTRegex(QCBOREncodeContext *pCtx,
1538 uint8_t uTagRequirement,
1539 UsefulBufC Regex);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001540
Laurence Lundblade3eead482023-12-16 20:53:22 -07001541static void
1542QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pCtx,
1543 const char *szLabel,
1544 uint8_t uTagRequirement,
1545 UsefulBufC Regex);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001546
Laurence Lundblade3eead482023-12-16 20:53:22 -07001547static void
1548QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pCtx,
1549 int64_t nLabel,
1550 uint8_t uTagRequirement,
1551 UsefulBufC Regex);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001552
1553
Laurence Lundblade3eead482023-12-16 20:53:22 -07001554static void
1555QCBOREncode_AddRegex(QCBOREncodeContext *pCtx,
1556 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001557
Laurence Lundblade3eead482023-12-16 20:53:22 -07001558static void
1559QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx,
1560 const char *szLabel,
1561 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001562
Laurence Lundblade3eead482023-12-16 20:53:22 -07001563static void
1564QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx,
1565 int64_t nLabel,
1566 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001567
1568
1569/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001570 * @brief MIME encoded data to the encoded output.
1571 *
1572 * @param[in] pCtx The encoding context to add the MIME data to.
1573 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1574 * @ref QCBOR_ENCODE_AS_BORROWED.
1575 * @param[in] MIMEData Pointer and length of the MIME data.
1576 *
1577 * The text content is in MIME format per [RFC 2045]
1578 * (https://tools.ietf.org/html/rfc2045) including the headers.
1579 *
1580 * It is output as CBOR major type 2, a binary string, with tag
1581 * @ref CBOR_TAG_BINARY_MIME indicating the string is MIME data. This
1582 * outputs tag 257, not tag 36, as it can carry any type of MIME
1583 * binary, 7-bit, 8-bit, quoted-printable and base64 where tag 36
1584 * cannot.
1585 *
1586 * Previous versions of QCBOR, those before spiffy decode, output tag
1587 * 36. Decoding supports both tag 36 and 257. (if the old behavior
1588 * with tag 36 is needed, copy the inline functions below and change
1589 * the tag number).
1590 *
1591 * See also QCBORDecode_GetMIMEMessage() and
1592 * @ref QCBOR_TYPE_BINARY_MIME.
1593 *
1594 * This does no translation of line endings. See QCBOREncode_AddText()
1595 * for a discussion of line endings in CBOR.
Michael Eckel5c531332020-03-02 01:35:30 +01001596 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001597static void
1598QCBOREncode_AddTMIMEData(QCBOREncodeContext *pCtx,
1599 uint8_t uTagRequirement,
1600 UsefulBufC MIMEData);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001601
Laurence Lundblade3eead482023-12-16 20:53:22 -07001602static void
1603QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pCtx,
1604 const char *szLabel,
1605 uint8_t uTagRequirement,
1606 UsefulBufC MIMEData);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001607
Laurence Lundblade3eead482023-12-16 20:53:22 -07001608static void
1609QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pCtx,
1610 int64_t nLabel,
1611 uint8_t uTagRequirement,
1612 UsefulBufC MIMEData);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001613
1614
Laurence Lundblade3eead482023-12-16 20:53:22 -07001615static void
1616QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx,
1617 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001618
Laurence Lundblade3eead482023-12-16 20:53:22 -07001619static void
1620QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx,
1621 const char *szLabel,
1622 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001623
Laurence Lundblade3eead482023-12-16 20:53:22 -07001624static void
1625QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx,
1626 int64_t nLabel,
1627 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001628
1629
1630/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001631 * @brief Add an RFC 3339 date string
1632 *
1633 * @param[in] pCtx The encoding context to add the date to.
1634 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1635 * @ref QCBOR_ENCODE_AS_BORROWED.
1636 * @param[in] szDate Null-terminated string with date to add.
1637 *
1638 * The string szDate should be in the form of [RFC 3339]
1639 * (https://tools.ietf.org/html/rfc3339) as defined by section 3.3 in
1640 * [RFC 4287] (https://tools.ietf.org/html/rfc4287). This is as
1641 * described in section 3.4.1 in [RFC 8949]
1642 * (https://tools.ietf.org/html/rfc8949).
1643 *
1644 * Note that this function doesn't validate the format of the date
1645 * string at all. If you add an incorrect format date string, the
1646 * generated CBOR will be incorrect and the receiver may not be able
1647 * to handle it.
1648 *
1649 * Error handling is the same as QCBOREncode_AddInt64().
1650 *
1651 * See also QCBOREncode_AddTDayString().
Michael Eckel5c531332020-03-02 01:35:30 +01001652 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001653static void
1654QCBOREncode_AddTDateString(QCBOREncodeContext *pCtx,
1655 uint8_t uTagRequirement,
1656 const char *szDate);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001657
Laurence Lundblade3eead482023-12-16 20:53:22 -07001658static void
1659QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pCtx,
1660 const char *szLabel,
1661 uint8_t uTagRequirement,
1662 const char *szDate);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001663
Laurence Lundblade3eead482023-12-16 20:53:22 -07001664static void
1665QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pCtx,
1666 int64_t nLabel,
1667 uint8_t uTagRequirement,
1668 const char *szDate);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001669
1670
Laurence Lundblade3eead482023-12-16 20:53:22 -07001671static void
1672QCBOREncode_AddDateString(QCBOREncodeContext *pCtx,
1673 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001674
Laurence Lundblade3eead482023-12-16 20:53:22 -07001675static void
1676QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx,
1677 const char *szLabel,
1678 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001679
Laurence Lundblade3eead482023-12-16 20:53:22 -07001680static void
1681QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx,
1682 int64_t nLabel,
1683 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001684
Laurence Lundblade46d63e92021-05-13 11:37:10 -07001685
1686/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001687 * @brief Add a date-only string.
1688 *
1689 * @param[in] pCtx The encoding context to add the date to.
1690 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1691 * @ref QCBOR_ENCODE_AS_BORROWED.
1692 * @param[in] szDate Null-terminated string with date to add.
1693 *
1694 * This date format is described in
1695 * [RFC 8943] (https://tools.ietf.org/html/rfc8943), but that mainly
1696 * references RFC 3339. The string szDate must be in the forrm
1697 * specified the ABNF for a full-date in
1698 * [RFC 3339] (https://tools.ietf.org/html/rfc3339). Examples of this
1699 * are "1985-04-12" and "1937-01-01". The time and the time zone are
1700 * never included.
1701 *
1702 * Note that this function doesn't validate the format of the date
1703 * string at all. If you add an incorrect format date string, the
1704 * generated CBOR will be incorrect and the receiver may not be able
1705 * to handle it.
1706 *
1707 * Error handling is the same as QCBOREncode_AddInt64().
1708 *
1709 * See also QCBOREncode_AddTDateString().
Laurence Lundblade46d63e92021-05-13 11:37:10 -07001710 */
1711static void
1712QCBOREncode_AddTDaysString(QCBOREncodeContext *pCtx,
1713 uint8_t uTagRequirement,
1714 const char *szDate);
1715
1716static void
1717QCBOREncode_AddTDaysStringToMapSZ(QCBOREncodeContext *pCtx,
1718 const char *szLabel,
1719 uint8_t uTagRequirement,
1720 const char *szDate);
1721
1722static void
1723QCBOREncode_AddTDaysStringToMapN(QCBOREncodeContext *pCtx,
1724 int64_t nLabel,
1725 uint8_t uTagRequirement,
1726 const char *szDate);
1727
1728
Michael Eckel5c531332020-03-02 01:35:30 +01001729/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001730 * @brief Add a standard Boolean.
1731 *
1732 * @param[in] pCtx The encoding context to add the Boolean to.
1733 * @param[in] b true or false from @c <stdbool.h>.
1734 *
1735 * Adds a Boolean value as CBOR major type 7.
1736 *
1737 * Error handling is the same as QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +01001738 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001739static void
1740QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b);
Michael Eckel5c531332020-03-02 01:35:30 +01001741
Laurence Lundblade3eead482023-12-16 20:53:22 -07001742static void
1743QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b);
Michael Eckel5c531332020-03-02 01:35:30 +01001744
Laurence Lundblade3eead482023-12-16 20:53:22 -07001745static void
1746QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b);
Michael Eckel5c531332020-03-02 01:35:30 +01001747
1748
1749
1750/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001751 * @brief Add a NULL to the encoded output.
1752 *
1753 * @param[in] pCtx The encoding context to add the NULL to.
1754 *
1755 * Adds the NULL value as CBOR major type 7.
1756 *
1757 * This NULL doesn't have any special meaning in CBOR such as a
1758 * terminating value for a string or an empty value.
1759 *
1760 * Error handling is the same as QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +01001761 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001762static void
1763QCBOREncode_AddNULL(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01001764
Laurence Lundblade3eead482023-12-16 20:53:22 -07001765static void
1766QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001767
Laurence Lundblade3eead482023-12-16 20:53:22 -07001768static void
1769QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001770
1771
1772/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001773 * @brief Add an "undef" to the encoded output.
1774 *
1775 * @param[in] pCtx The encoding context to add the "undef" to.
1776 *
1777 * Adds the undef value as CBOR major type 7.
1778 *
1779 * Note that this value will not translate to JSON.
1780 *
1781 * This Undef doesn't have any special meaning in CBOR such as a
1782 * terminating value for a string or an empty value.
1783 *
1784 * Error handling is the same as QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +01001785 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001786static void
1787QCBOREncode_AddUndef(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01001788
Laurence Lundblade3eead482023-12-16 20:53:22 -07001789static void
1790QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001791
Laurence Lundblade3eead482023-12-16 20:53:22 -07001792static void
1793QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001794
1795
1796/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001797 * @brief Indicates that the next items added are in an array.
1798 *
1799 * @param[in] pCtx The encoding context to open the array in.
1800 *
1801 * Arrays are the basic CBOR aggregate or structure type. Call this
1802 * function to start or open an array. Then call the various
1803 * @c QCBOREncode_AddXxx() functions to add the items that go into the
1804 * array. Then call QCBOREncode_CloseArray() when all items have been
1805 * added. The data items in the array can be of any type and can be of
1806 * mixed types.
1807 *
1808 * Nesting of arrays and maps is allowed and supported just by calling
1809 * QCBOREncode_OpenArray() again before calling
1810 * QCBOREncode_CloseArray(). While CBOR has no limit on nesting, this
1811 * implementation does in order to keep it smaller and simpler. The
1812 * limit is @ref QCBOR_MAX_ARRAY_NESTING. This is the max number of
1813 * times this can be called without calling
1814 * QCBOREncode_CloseArray(). QCBOREncode_Finish() will return
1815 * @ref QCBOR_ERR_ARRAY_NESTING_TOO_DEEP when it is called as this
1816 * function just sets an error state and returns no value when this
1817 * occurs.
1818 *
1819 * If you try to add more than @ref QCBOR_MAX_ITEMS_IN_ARRAY items to
1820 * a single array or map, @ref QCBOR_ERR_ARRAY_TOO_LONG will be
1821 * returned when QCBOREncode_Finish() is called.
1822 *
1823 * An array itself must have a label if it is being added to a map.
1824 * Note that array elements do not have labels (but map elements do).
1825 *
1826 * An array itself may be tagged by calling QCBOREncode_AddTag()
1827 * before this call.
Michael Eckel5c531332020-03-02 01:35:30 +01001828 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001829static void
1830QCBOREncode_OpenArray(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01001831
Laurence Lundblade3eead482023-12-16 20:53:22 -07001832static void
1833QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001834
Laurence Lundblade3eead482023-12-16 20:53:22 -07001835static void
1836QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001837
1838
1839/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001840 * @brief Close an open array.
1841 *
1842 * @param[in] pCtx The encoding context to close the array in.
1843 *
1844 * The closes an array opened by QCBOREncode_OpenArray(). It reduces
1845 * nesting level by one. All arrays (and maps) must be closed before
1846 * calling QCBOREncode_Finish().
1847 *
1848 * When an error occurs as a result of this call, the encoder records
1849 * the error and enters the error state. The error will be returned
1850 * when QCBOREncode_Finish() is called.
1851 *
1852 * If this has been called more times than QCBOREncode_OpenArray(), then
1853 * @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when QCBOREncode_Finish()
1854 * is called.
1855 *
1856 * If this is called and it is not an array that is currently open,
1857 * @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
1858 * QCBOREncode_Finish() is called.
Michael Eckel5c531332020-03-02 01:35:30 +01001859 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001860static void
1861QCBOREncode_CloseArray(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01001862
1863
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07001864
1865
Michael Eckel5c531332020-03-02 01:35:30 +01001866/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001867 * @brief Indicates that the next items added are in a map.
1868 *
1869 * @param[in] pCtx The encoding context to open the map in.
1870 *
1871 * See QCBOREncode_OpenArray() for more information, particularly
1872 * error handling.
1873 *
1874 * CBOR maps are an aggregate type where each item in the map consists
1875 * of a label and a value. They are similar to JSON objects.
1876 *
1877 * The value can be any CBOR type including another map.
1878 *
1879 * The label can also be any CBOR type, but in practice they are
1880 * typically, integers as this gives the most compact output. They
1881 * might also be text strings which gives readability and translation
1882 * to JSON.
1883 *
1884 * Every @c QCBOREncode_AddXxx() call has one version that ends with
1885 * @c InMap for adding items to maps with string labels and one that
1886 * ends with @c InMapN that is for adding with integer labels.
1887 *
1888 * RFC 8949 uses the term "key" instead of "label".
1889 *
1890 * If you wish to use map labels that are neither integer labels nor
1891 * text strings, then just call the QCBOREncode_AddXxx() function
1892 * explicitly to add the label. Then call it again to add the value.
1893 *
1894 * See the [RFC 8949] (https://tools.ietf.org/html/rfc8949) for a lot
1895 * more information on creating maps.
Michael Eckel5c531332020-03-02 01:35:30 +01001896 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001897static void
1898QCBOREncode_OpenMap(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01001899
Laurence Lundblade3eead482023-12-16 20:53:22 -07001900static void
1901QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001902
Laurence Lundblade3eead482023-12-16 20:53:22 -07001903static void
1904QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001905
1906
Michael Eckel5c531332020-03-02 01:35:30 +01001907/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001908 * @brief Close an open map.
1909 *
1910 * @param[in] pCtx The encoding context to close the map in.
1911 *
1912 * This closes a map opened by QCBOREncode_OpenMap(). It reduces
1913 * nesting level by one.
1914 *
1915 * When an error occurs as a result of this call, the encoder records
1916 * the error and enters the error state. The error will be returned
1917 * when QCBOREncode_Finish() is called.
1918 *
1919 * If this has been called more times than QCBOREncode_OpenMap(), then
1920 * @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1921 * QCBOREncode_Finish() is called.
1922 *
1923 * If this is called and it is not a map that is currently open,
1924 * @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
1925 * QCBOREncode_Finish() is called.
Michael Eckel5c531332020-03-02 01:35:30 +01001926 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001927static void
1928QCBOREncode_CloseMap(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01001929
1930
1931/**
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07001932 * @brief Indicates that the next items added are in an indefinite length array.
1933 *
1934 * @param[in] pCtx The encoding context to open the array in.
1935 *
1936 * This is the same as QCBOREncode_OpenArray() except the array is
1937 * indefinite length.
1938 *
1939 * This must be closed with QCBOREncode_CloseArrayIndefiniteLength().
1940 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001941static void
1942QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pCtx);
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07001943
Laurence Lundblade3eead482023-12-16 20:53:22 -07001944static void
1945QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pCtx,
1946 const char *szLabel);
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07001947
1948static void
1949QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pCtx,
1950 int64_t nLabel);
1951
1952
1953/**
1954 * @brief Close an open indefinite length array.
1955 *
1956 * @param[in] pCtx The encoding context to close the array in.
1957 *
1958 * This is the same as QCBOREncode_CloseArray(), but the open array
1959 * that is being close must be of indefinite length.
1960 */
1961static void
1962QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pCtx);
1963
1964
1965/**
1966 * @brief Indicates that the next items added are in an indefinite length map.
1967 *
1968 * @param[in] pCtx The encoding context to open the map in.
1969 *
1970 * This is the same as QCBOREncode_OpenMap() except the array is
1971 * indefinite length.
1972 *
1973 * This must be closed with QCBOREncode_CloseMapIndefiniteLength().
1974 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001975static void
1976QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pCtx);
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07001977
Laurence Lundblade3eead482023-12-16 20:53:22 -07001978static void
1979QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pCtx,
1980 const char *szLabel);
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07001981
1982static void
1983QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pCtx,
1984 int64_t nLabel);
1985
1986
1987/**
1988 * @brief Close an open indefinite length map.
1989 *
1990 * @param[in] pCtx The encoding context to close the map in.
1991 *
1992 * This is the same as QCBOREncode_CloseMap(), but the open map that
1993 * is being close must be of indefinite length.
1994 */
1995static void
1996QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pCtx);
1997
1998
Laurence Lundbladec92e4162023-11-27 21:51:26 -07001999/**
Laurence Lundbladed6e13022023-11-26 10:14:02 -07002000 * @brief Close and sort an open map.
2001 *
2002 * @param[in] pCtx The encoding context to close the map in .
2003 *
2004 * This is the same as QCBOREncode_CloseMap() except it sorts the map
2005 * per RFC 8949 Section 4.2.1. This sort is lexicographic of the CBOR-
2006 * encoded map labels.
2007 *
2008 * This is more expensive than most things in the encoder. It uses
2009 * bubble sort which runs in n-squared time where n is the number of
2010 * map items. Sorting large maps on slow CPUs might be slow. This is
2011 * also increases the object code size of the encoder by about 30%.
2012 *
2013 * Bubble sort was selected so as to not need an extra buffer to track
2014 * map item offsets. Bubble sort works well even though map items are
2015 * not all the same size because it always swaps adjacent items.
2016 */
2017void QCBOREncode_CloseAndSortMap(QCBOREncodeContext *pCtx);
2018
2019void QCBOREncode_CloseAndSortMapIndef(QCBOREncodeContext *pCtx);
2020
2021
2022/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002023 * @brief Indicate start of encoded CBOR to be wrapped in a bstr.
2024 *
2025 * @param[in] pCtx The encoding context to open the bstr-wrapped CBOR in.
2026 *
2027 * All added encoded items between this call and a call to
2028 * QCBOREncode_CloseBstrWrap2() will be wrapped in a bstr. They will
2029 * appear in the final output as a byte string. That byte string will
2030 * contain encoded CBOR. This increases nesting level by one.
2031 *
2032 * The typical use case is for encoded CBOR that is to be
2033 * cryptographically hashed, as part of a [RFC 8152, COSE]
2034 * (https://tools.ietf.org/html/rfc8152) implementation. The wrapping
2035 * byte string is taken as input by the hash function (which is why it
2036 * is returned by QCBOREncode_CloseBstrWrap2()). It is also easy to
2037 * recover on decoding with standard CBOR decoders.
2038 *
2039 * Using QCBOREncode_BstrWrap() and QCBOREncode_CloseBstrWrap2()
2040 * avoids having to encode the items first in one buffer (e.g., the
2041 * COSE payload) and then add that buffer as a bstr to another
2042 * encoding (e.g. the COSE to-be-signed bytes, the @c Sig_structure)
2043 * potentially halving the memory needed.
2044 *
2045 * CBOR by nature must be decoded item by item in order from the
2046 * start. By wrapping some CBOR in a byte string, the decoding of
2047 * that wrapped CBOR can be skipped. This is another use of wrapping,
2048 * perhaps because the CBOR is large and deeply nested. Perhaps APIs
2049 * for handling one defined CBOR message that is being embedded in
2050 * another only take input as a byte string. Perhaps the desire is to
2051 * be able to decode the out layer even in the wrapped has errors.
Michael Eckel5c531332020-03-02 01:35:30 +01002052 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002053static void
2054QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01002055
Laurence Lundblade3eead482023-12-16 20:53:22 -07002056static void
2057QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01002058
Laurence Lundblade3eead482023-12-16 20:53:22 -07002059static void
2060QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01002061
2062
2063/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002064 * @brief Close a wrapping bstr.
2065 *
2066 * @param[in] pCtx The encoding context to close of bstr wrapping in.
2067 * @param[in] bIncludeCBORHead Include the encoded CBOR head of the bstr
2068 * as well as the bytes in @c pWrappedCBOR.
2069 * @param[out] pWrappedCBOR A @ref UsefulBufC containing wrapped bytes.
2070 *
2071 * The closes a wrapping bstr opened by QCBOREncode_BstrWrap(). It reduces
2072 * nesting level by one.
2073 *
2074 * A pointer and length of the enclosed encoded CBOR is returned in @c
2075 * *pWrappedCBOR if it is not @c NULL. The main purpose of this is so
2076 * this data can be hashed (e.g., with SHA-256) as part of a [RFC
2077 * 8152, COSE] (https://tools.ietf.org/html/rfc8152)
2078 * implementation. **WARNING**, this pointer and length should be used
2079 * right away before any other calls to @c QCBOREncode_CloseXxx() as
2080 * they will move data around and the pointer and length will no
2081 * longer be to the correct encoded CBOR.
2082 *
2083 * When an error occurs as a result of this call, the encoder records
2084 * the error and enters the error state. The error will be returned
2085 * when QCBOREncode_Finish() is called.
2086 *
2087 * If this has been called more times than QCBOREncode_BstrWrap(),
2088 * then @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
2089 * QCBOREncode_Finish() is called.
2090 *
2091 * If this is called and it is not a wrapping bstr that is currently
2092 * open, @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
2093 * QCBOREncode_Finish() is called.
2094 *
2095 * QCBOREncode_CloseBstrWrap() is a deprecated version of this function
2096 * that is equivalent to the call with @c bIncludeCBORHead @c true.
Michael Eckel5c531332020-03-02 01:35:30 +01002097 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002098void
2099QCBOREncode_CloseBstrWrap2(QCBOREncodeContext *pCtx, bool bIncludeCBORHead, UsefulBufC *pWrappedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01002100
Laurence Lundblade3eead482023-12-16 20:53:22 -07002101static void
2102QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01002103
2104
2105/**
Laurence Lundblade8d3b8552021-06-10 11:11:54 -07002106 * @brief Cancel byte string wrapping.
2107 *
2108 * @param[in] pCtx The encoding context.
2109 *
2110 * This cancels QCBOREncode_BstrWrap() making tghe encoding as if it
2111 * were never called.
2112 *
2113 * WARNING: This does not work on QCBOREncode_BstrWrapInMap()
2114 * or QCBOREncode_BstrWrapInMapN() and there is no error detection
2115 * of an attempt at their use.
2116 *
2117 * This only works if nothing has been added into the wrapped byte
2118 * string. If something has been added, this sets the error
2119 * @ref QCBOR_ERR_CANNOT_CANCEL.
2120 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002121void
2122QCBOREncode_CancelBstrWrap(QCBOREncodeContext *pCtx);
Laurence Lundblade8d3b8552021-06-10 11:11:54 -07002123
2124
2125/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002126 * @brief Add some already-encoded CBOR bytes.
2127 *
2128 * @param[in] pCtx The encoding context to add the already-encode CBOR to.
2129 * @param[in] Encoded The already-encoded CBOR to add to the context.
2130 *
2131 * The encoded CBOR being added must be fully conforming CBOR. It must
2132 * be complete with no arrays or maps that are incomplete. While this
2133 * encoder doesn't ever produce indefinite lengths, it is OK for the
2134 * raw CBOR added here to have indefinite lengths.
2135 *
2136 * The raw CBOR added here is not checked in anyway. If it is not
2137 * conforming or has open arrays or such, the final encoded CBOR
2138 * will probably be wrong or not what was intended.
2139 *
2140 * If the encoded CBOR being added here contains multiple items, they
2141 * must be enclosed in a map or array. At the top level the raw
2142 * CBOR must be a single data item.
Michael Eckel5c531332020-03-02 01:35:30 +01002143 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002144static void
2145QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01002146
Laurence Lundblade3eead482023-12-16 20:53:22 -07002147static void
2148QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01002149
Laurence Lundblade3eead482023-12-16 20:53:22 -07002150static void
2151QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01002152
2153
2154/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002155 * @brief Get the encoded result.
2156 *
2157 * @param[in] pCtx The context to finish encoding with.
2158 * @param[out] pEncodedCBOR Structure in which the pointer and length of
2159 * the encoded CBOR is returned.
2160 *
2161 * @retval QCBOR_SUCCESS Encoded CBOR is returned.
2162 *
2163 * @retval QCBOR_ERR_TOO_MANY_CLOSES Nesting error
2164 *
2165 * @retval QCBOR_ERR_CLOSE_MISMATCH Nesting error
2166 *
2167 * @retval QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN Nesting error
2168 *
2169 * @retval QCBOR_ERR_BUFFER_TOO_LARGE Encoded output buffer size
2170 *
2171 * @retval QCBOR_ERR_BUFFER_TOO_SMALL Encoded output buffer size
2172 *
2173 * @retval QCBOR_ERR_ARRAY_NESTING_TOO_DEEP Implementation limit
2174 *
2175 * @retval QCBOR_ERR_ARRAY_TOO_LONG Implementation limit
2176 *
2177 * On success, the pointer and length of the encoded CBOR are returned
2178 * in @c *pEncodedCBOR. The pointer is the same pointer that was passed
2179 * in to QCBOREncode_Init(). Note that it is not const when passed to
2180 * QCBOREncode_Init(), but it is const when returned here. The length
2181 * will be smaller than or equal to the length passed in when
2182 * QCBOREncode_Init() as this is the length of the actual result, not
2183 * the size of the buffer it was written to.
2184 *
2185 * If a @c NULL was passed for @c Storage.ptr when QCBOREncode_Init()
2186 * was called, @c NULL will be returned here, but the length will be
2187 * that of the CBOR that would have been encoded.
2188 *
2189 * Encoding errors primarily manifest here as most other encoding function
2190 * do no return an error. They just set the error state in the encode
2191 * context after which no encoding function does anything.
2192 *
2193 * Three types of errors manifest here. The first type are nesting
2194 * errors where the number of @c QCBOREncode_OpenXxx() calls do not
2195 * match the number @c QCBOREncode_CloseXxx() calls. The solution is to
2196 * fix the calling code.
2197 *
2198 * The second type of error is because the buffer given is either too
2199 * small or too large. The remedy is to give a correctly sized buffer.
2200 *
2201 * The third type are due to limits in this implementation.
2202 * @ref QCBOR_ERR_ARRAY_NESTING_TOO_DEEP can be worked around by
2203 * encoding the CBOR in two (or more) phases and adding the CBOR from
2204 * the first phase to the second with @c QCBOREncode_AddEncoded().
2205 *
2206 * If an error is returned, the buffer may have partially encoded
2207 * incorrect CBOR in it and it should not be used. Likewise, the length
2208 * may be incorrect and should not be used.
2209 *
2210 * Note that the error could have occurred in one of the many
2211 * @c QCBOREncode_AddXxx() calls long before QCBOREncode_Finish() was
2212 * called. This error handling reduces the CBOR implementation size
2213 * but makes debugging harder.
2214 *
2215 * This may be called multiple times. It will always return the
2216 * same. It can also be interleaved with calls to
2217 * QCBOREncode_FinishGetSize().
2218 *
2219 * QCBOREncode_GetErrorState() can be called to get the current
2220 * error state in order to abort encoding early as an optimization, but
2221 * calling it is is never required.
Michael Eckel5c531332020-03-02 01:35:30 +01002222 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002223QCBORError
2224QCBOREncode_Finish(QCBOREncodeContext *pCtx, UsefulBufC *pEncodedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01002225
2226
2227/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002228 * @brief Get the encoded CBOR and error status.
2229 *
2230 * @param[in] pCtx The context to finish encoding with.
2231 * @param[out] uEncodedLen The length of the encoded or potentially
2232 * encoded CBOR in bytes.
2233 *
2234 * @return The same errors as QCBOREncode_Finish().
2235 *
2236 * This functions the same as QCBOREncode_Finish(), but only returns the
2237 * size of the encoded output.
Michael Eckel5c531332020-03-02 01:35:30 +01002238 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002239QCBORError
2240QCBOREncode_FinishGetSize(QCBOREncodeContext *pCtx, size_t *uEncodedLen);
Michael Eckel5c531332020-03-02 01:35:30 +01002241
2242
2243/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002244 * @brief Indicate whether output buffer is NULL or not.
2245 *
2246 * @param[in] pCtx The encoding context.
2247 *
2248 * @return 1 if the output buffer is @c NULL.
2249 *
2250 * Sometimes a @c NULL input buffer is given to QCBOREncode_Init() so
2251 * that the size of the generated CBOR can be calculated without
2252 * allocating a buffer for it. This returns 1 when the output buffer
2253 * is @c NULL and 0 when it is not.
Michael Eckel5c531332020-03-02 01:35:30 +01002254 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002255static int
2256QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx);
2257
2258
2259/**
2260 * @brief Get the encoding error state.
2261 *
2262 * @param[in] pCtx The encoding context.
2263 *
2264 * @return One of @ref QCBORError. See return values from
2265 * QCBOREncode_Finish()
2266 *
2267 * Normally encoding errors need only be handled at the end of
2268 * encoding when QCBOREncode_Finish() is called. This can be called to
2269 * get the error result before finish should there be a need to halt
2270 * encoding before QCBOREncode_Finish() is called.
2271 */
2272static QCBORError
2273QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx);
2274
2275
2276/**
2277 * Encode the "head" of a CBOR data item.
2278 *
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002279 * @param Buffer Buffer to output the encoded head to; must be
Laurence Lundblade3eead482023-12-16 20:53:22 -07002280 * @ref QCBOR_HEAD_BUFFER_SIZE bytes in size.
2281 * @param uMajorType One of CBOR_MAJOR_TYPE_XX.
2282 * @param uMinLen The minimum number of bytes to encode uNumber. Almost
2283 * always this is 0 to use preferred
2284 * serialization. If this is 4, then even the
2285 * values 0xffff and smaller will be encoded in 4
2286 * bytes. This is used primarily when encoding a
2287 * float or double put into uNumber as the leading
2288 * zero bytes for them must be encoded.
2289 * @param uNumber The numeric argument part of the CBOR head.
2290 * @return Pointer and length of the encoded head or
2291 * @ref NULLUsefulBufC if the output buffer is too small.
2292 *
2293 * Callers do not to need to call this for normal CBOR encoding. Note
2294 * that it doesn't even take a @ref QCBOREncodeContext argument.
2295 *
2296 * This encodes the major type and argument part of a data item. The
2297 * argument is an integer that is usually either the value or the length
2298 * of the data item.
2299 *
2300 * This is exposed in the public interface to allow hashing of some CBOR
2301 * data types, bstr in particular, a chunk at a time so the full CBOR
2302 * doesn't have to be encoded in a contiguous buffer.
2303 *
2304 * For example, if you have a 100,000 byte binary blob in a buffer that
2305 * needs to be a bstr encoded and then hashed. You could allocate a
2306 * 100,010 byte buffer and encode it normally. Alternatively, you can
2307 * encode the head in a 10 byte buffer with this function, hash that and
2308 * then hash the 100,000 bytes using the same hash context.
2309 *
2310 * See also QCBOREncode_AddBytesLenOnly();
2311 */
2312UsefulBufC
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002313QCBOREncode_EncodeHead(UsefulBuf Buffer,
Laurence Lundblade3eead482023-12-16 20:53:22 -07002314 uint8_t uMajorType,
2315 uint8_t uMinLen,
2316 uint64_t uNumber);
Michael Eckel5c531332020-03-02 01:35:30 +01002317
2318
Michael Eckel5c531332020-03-02 01:35:30 +01002319
2320
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002321/* =========================================================================
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002322 BEGINNING OF PRIVATE IMPLEMENTATION
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002323 ========================================================================= */
Michael Eckel5c531332020-03-02 01:35:30 +01002324
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002325/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002326void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002327QCBOREncode_Private_AddBuffer(QCBOREncodeContext *pCtx,
2328 uint8_t uMajorType,
2329 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002330
2331
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002332/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002333void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002334QCBOREncode_Private_OpenMapOrArray(QCBOREncodeContext *pCtx,
2335 uint8_t uMajorType);
Michael Eckel5c531332020-03-02 01:35:30 +01002336
2337
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002338/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002339void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002340QCBOREncode_Private_OpenMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx,
2341 uint8_t uMajorType);
Michael Eckel5c531332020-03-02 01:35:30 +01002342
2343
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002344/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002345void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002346QCBOREncode_Private_CloseMapOrArray(QCBOREncodeContext *pCtx,
2347 uint8_t uMajorType);
Michael Eckel5c531332020-03-02 01:35:30 +01002348
2349
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002350/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002351void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002352QCBOREncode_Private_CloseMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx,
2353 uint8_t uMajorType);
Michael Eckel5c531332020-03-02 01:35:30 +01002354
2355
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002356/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002357void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002358QCBOREncode_Private_AddType7(QCBOREncodeContext *pCtx,
2359 uint8_t uMinLen,
2360 uint64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002361
2362
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002363/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002364void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002365QCBOREncode_Private_AddExpMantissa(QCBOREncodeContext *pCtx,
Laurence Lundblade3eead482023-12-16 20:53:22 -07002366 uint64_t uTag,
2367 UsefulBufC BigNumMantissa,
2368 bool bBigNumIsNegative,
2369 int64_t nMantissa,
2370 int64_t nExponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002371
2372/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002373 * @brief Semi-private method to add only the type and length of a byte string.
2374 *
2375 * @param[in] pCtx The context to initialize.
2376 * @param[in] Bytes Pointer and length of the input data.
2377 *
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002378 * This will be removed in QCBOR 2.0. It was never a public function.
2379 *
Laurence Lundblade3eead482023-12-16 20:53:22 -07002380 * This is the same as QCBOREncode_AddBytes() except it only adds the
2381 * CBOR encoding for the type and the length. It doesn't actually add
2382 * the bytes. You can't actually produce correct CBOR with this and
2383 * the rest of this API. It is only used for a special case where the
2384 * valid CBOR is created manually by putting this type and length in
2385 * and then adding the actual bytes. In particular, when only a hash
2386 * of the encoded CBOR is needed, where the type and header are hashed
2387 * separately and then the bytes is hashed. This makes it possible to
2388 * implement COSE Sign1 with only one copy of the payload in the
2389 * output buffer, rather than two, roughly cutting memory use in half.
2390 *
2391 * This is only used for this odd case, but this is a supported
2392 * tested function.
2393 *
2394 * See also QCBOREncode_EncodeHead().
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002395 *
2396 * TODO: remove this in QCBOR 2.0
2397 */
2398static void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002399QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pCtx,
2400 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002401
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002402static void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002403QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pCtx,
2404 const char *szLabel,
2405 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002406
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002407static void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002408QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pCtx,
2409 int64_t nLabel,
2410 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002411
2412
2413
2414
2415
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002416static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002417QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pMe,
2418 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002419 const int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002420{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002421 /* Use _AddBuffer() because _AddSZString() is defined below, not above */
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002422 QCBOREncode_Private_AddBuffer(pMe,
2423 CBOR_MAJOR_TYPE_TEXT_STRING,
2424 UsefulBuf_FromSZ(szLabel));
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002425 QCBOREncode_AddInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002426}
2427
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002428static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002429QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002430 const int64_t nLabel,
2431 const int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002432{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002433 QCBOREncode_AddInt64(pMe, nLabel);
2434 QCBOREncode_AddInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002435}
2436
2437
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002438static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002439QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pMe,
2440 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002441 const uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002442{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002443 /* Use _AddBuffer() because _AddSZString() is defined below, not above */
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002444 QCBOREncode_Private_AddBuffer(pMe,
2445 CBOR_MAJOR_TYPE_TEXT_STRING,
2446 UsefulBuf_FromSZ(szLabel));
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002447 QCBOREncode_AddUInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002448}
2449
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002450static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002451QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002452 const int64_t nLabel,
2453 const uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002454{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002455 QCBOREncode_AddInt64(pMe, nLabel);
2456 QCBOREncode_AddUInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002457}
2458
2459
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002460static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002461QCBOREncode_AddText(QCBOREncodeContext *pMe, const UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002462{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002463 QCBOREncode_Private_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002464}
2465
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002466static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002467QCBOREncode_AddTextToMap(QCBOREncodeContext *pMe,
2468 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002469 const UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002470{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002471 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szLabel));
2472 QCBOREncode_AddText(pMe, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002473}
2474
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002475static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002476QCBOREncode_AddTextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002477 const int64_t nLabel,
2478 const UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002479{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002480 QCBOREncode_AddInt64(pMe, nLabel);
2481 QCBOREncode_AddText(pMe, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002482}
2483
2484
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002485inline static void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002486QCBOREncode_AddSZString(QCBOREncodeContext *pMe, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002487{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002488 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szString));
Michael Eckel5c531332020-03-02 01:35:30 +01002489}
2490
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002491static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002492QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pMe,
2493 const char *szLabel,
2494 const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002495{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002496 QCBOREncode_AddSZString(pMe, szLabel);
2497 QCBOREncode_AddSZString(pMe, szString);
Michael Eckel5c531332020-03-02 01:35:30 +01002498}
2499
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002500static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002501QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002502 const int64_t nLabel,
Laurence Lundblade3eead482023-12-16 20:53:22 -07002503 const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002504{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002505 QCBOREncode_AddInt64(pMe, nLabel);
2506 QCBOREncode_AddSZString(pMe, szString);
Michael Eckel5c531332020-03-02 01:35:30 +01002507}
2508
2509
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +02002510#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002511static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002512QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pMe,
2513 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002514 const double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002515{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002516 QCBOREncode_AddSZString(pMe, szLabel);
2517 QCBOREncode_AddDouble(pMe, dNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002518}
2519
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002520static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002521QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002522 const int64_t nLabel,
2523 const double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002524{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002525 QCBOREncode_AddInt64(pMe, nLabel);
2526 QCBOREncode_AddDouble(pMe, dNum);
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_AddFloatToMap(QCBOREncodeContext *pMe,
2531 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002532 const float dNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002533{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002534 QCBOREncode_AddSZString(pMe, szLabel);
2535 QCBOREncode_AddFloat(pMe, dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002536}
2537
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002538static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002539QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pMe,
2540 const int64_t nLabel,
2541 const float fNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002542{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002543 QCBOREncode_AddInt64(pMe, nLabel);
2544 QCBOREncode_AddFloat(pMe, fNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002545}
2546
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002547static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002548QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pMe,
2549 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002550 const double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002551{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002552 QCBOREncode_AddSZString(pMe, szLabel);
2553 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002554}
2555
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002556static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002557QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002558 const int64_t nLabel,
2559 const double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002560{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002561 QCBOREncode_AddInt64(pMe, nLabel);
2562 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002563}
2564
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002565static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002566QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pMe,
2567 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002568 const float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002569{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002570 QCBOREncode_AddSZString(pMe, szLabel);
2571 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002572}
2573
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002574static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002575QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002576 const int64_t nLabel,
2577 const float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002578{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002579 QCBOREncode_AddInt64(pMe, nLabel);
2580 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002581}
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +02002582#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002583
Michael Eckel5c531332020-03-02 01:35:30 +01002584
Laurence Lundblade9b334962020-08-27 10:55:53 -07002585
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002586static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002587QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pMe,
2588 const uint8_t uTag,
2589 const int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002590{
2591 if(uTag == QCBOR_ENCODE_AS_TAG) {
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002592 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_EPOCH);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002593 }
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002594 QCBOREncode_AddInt64(pMe, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002595}
2596
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002597static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002598QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pMe,
2599 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002600 const uint8_t uTag,
2601 const int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002602{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002603 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002604 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002605}
2606
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002607static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002608QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002609 const int64_t nLabel,
2610 const uint8_t uTag,
2611 const int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002612{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002613 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002614 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002615}
2616
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002617static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002618QCBOREncode_AddDateEpoch(QCBOREncodeContext *pMe,
2619 const int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002620{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002621 QCBOREncode_AddTDateEpoch(pMe, QCBOR_ENCODE_AS_TAG, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002622}
2623
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002624static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002625QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pMe,
2626 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002627 const int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002628{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002629 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002630 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002631}
2632
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002633static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002634QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002635 const int64_t nLabel,
2636 const int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002637{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002638 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002639 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002640}
2641
2642
Laurence Lundblade46d63e92021-05-13 11:37:10 -07002643static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002644QCBOREncode_AddTDaysEpoch(QCBOREncodeContext *pMe,
2645 const uint8_t uTag,
2646 const int64_t nDays)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07002647{
2648 if(uTag == QCBOR_ENCODE_AS_TAG) {
2649 QCBOREncode_AddTag(pMe, CBOR_TAG_DAYS_EPOCH);
2650 }
2651 QCBOREncode_AddInt64(pMe, nDays);
2652}
2653
2654static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002655QCBOREncode_AddTDaysEpochToMapSZ(QCBOREncodeContext *pMe,
2656 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002657 const uint8_t uTag,
2658 const int64_t nDays)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07002659{
2660 QCBOREncode_AddSZString(pMe, szLabel);
2661 QCBOREncode_AddTDaysEpoch(pMe, uTag, nDays);
2662}
2663
2664static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002665QCBOREncode_AddTDaysEpochToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002666 const int64_t nLabel,
2667 const uint8_t uTag,
2668 const int64_t nDays)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07002669{
2670 QCBOREncode_AddInt64(pMe, nLabel);
2671 QCBOREncode_AddTDaysEpoch(pMe, uTag, nDays);
2672}
2673
Laurence Lundblade9b334962020-08-27 10:55:53 -07002674
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002675static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002676QCBOREncode_AddBytes(QCBOREncodeContext *pMe,
2677 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002678{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002679 QCBOREncode_Private_AddBuffer(pMe, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002680}
2681
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002682static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002683QCBOREncode_AddBytesToMap(QCBOREncodeContext *pMe,
2684 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002685 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002686{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002687 QCBOREncode_AddSZString(pMe, szLabel);
2688 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002689}
2690
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002691static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002692QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002693 const int64_t nLabel,
2694 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002695{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002696 QCBOREncode_AddInt64(pMe, nLabel);
2697 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002698}
2699
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002700static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002701QCBOREncode_OpenBytesInMapSZ(QCBOREncodeContext *pMe,
2702 const char *szLabel,
2703 UsefulBuf *pPlace)
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06002704{
2705 QCBOREncode_AddSZString(pMe, szLabel);
2706 QCBOREncode_OpenBytes(pMe, pPlace);
2707}
2708
2709static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002710QCBOREncode_OpenBytesInMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002711 const int64_t nLabel,
Laurence Lundblade3eead482023-12-16 20:53:22 -07002712 UsefulBuf *pPlace)
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06002713{
2714 QCBOREncode_AddInt64(pMe, nLabel);
2715 QCBOREncode_OpenBytes(pMe, pPlace);
2716}
2717
2718static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002719QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002720{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002721 QCBOREncode_Private_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002722}
2723
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002724static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002725QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pMe,
2726 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002727 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002728{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002729 QCBOREncode_AddSZString(pMe, szLabel);
2730 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002731}
2732
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002733static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002734QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002735 const int64_t nLabel,
2736 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002737{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002738 QCBOREncode_AddInt64(pMe, nLabel);
2739 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002740}
2741
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002742
2743static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002744QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002745 const uint8_t uTagRequirement,
2746 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002747{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002748 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2749 QCBOREncode_AddTag(pMe, CBOR_TAG_BIN_UUID);
2750 }
2751 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002752}
2753
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002754static inline void
2755QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pMe,
2756 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002757 const uint8_t uTagRequirement,
2758 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002759{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002760 QCBOREncode_AddSZString(pMe, szLabel);
2761 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002762}
2763
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002764static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002765QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002766 const int64_t nLabel,
2767 const uint8_t uTagRequirement,
2768 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002769{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002770 QCBOREncode_AddInt64(pMe, nLabel);
2771 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002772}
2773
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002774static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002775QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002776{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002777 QCBOREncode_AddTBinaryUUID(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002778}
2779
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002780static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002781QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pMe,
2782 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002783 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002784{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002785 QCBOREncode_AddTBinaryUUIDToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002786}
2787
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002788static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002789QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002790 const int64_t nLabel,
2791 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002792{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002793 QCBOREncode_AddTBinaryUUIDToMapN(pMe,
2794 nLabel,
2795 QCBOR_ENCODE_AS_TAG,
2796 Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002797}
2798
2799
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002800static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002801QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002802 const uint8_t uTagRequirement,
2803 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002804{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002805 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2806 QCBOREncode_AddTag(pMe, CBOR_TAG_POS_BIGNUM);
2807 }
2808 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002809}
2810
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002811static inline void
2812QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pMe,
2813 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002814 const uint8_t uTagRequirement,
2815 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002816{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002817 QCBOREncode_AddSZString(pMe, szLabel);
2818 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002819}
2820
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002821static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002822QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002823 const int64_t nLabel,
2824 const uint8_t uTagRequirement,
2825 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002826{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002827 QCBOREncode_AddInt64(pMe, nLabel);
2828 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002829}
2830
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002831static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002832QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002833{
2834 QCBOREncode_AddTPositiveBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2835}
2836
2837static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002838QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pMe,
2839 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002840 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002841{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002842 QCBOREncode_AddTPositiveBignumToMapSZ(pMe,
2843 szLabel,
2844 QCBOR_ENCODE_AS_TAG,
2845 Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002846}
2847
2848static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002849QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002850 const int64_t nLabel,
2851 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002852{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002853 QCBOREncode_AddTPositiveBignumToMapN(pMe,
2854 nLabel,
2855 QCBOR_ENCODE_AS_TAG,
2856 Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002857}
2858
2859
2860static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002861QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002862 const uint8_t uTagRequirement,
2863 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002864{
2865 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2866 QCBOREncode_AddTag(pMe, CBOR_TAG_NEG_BIGNUM);
2867 }
2868 QCBOREncode_AddBytes(pMe, Bytes);
2869}
2870
2871static inline void
2872QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pMe,
2873 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002874 const uint8_t uTagRequirement,
2875 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002876{
2877 QCBOREncode_AddSZString(pMe, szLabel);
2878 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2879}
2880
2881static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002882QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002883 const int64_t nLabel,
2884 const uint8_t uTagRequirement,
2885 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002886{
2887 QCBOREncode_AddInt64(pMe, nLabel);
2888 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2889}
2890
2891static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002892QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002893{
2894 QCBOREncode_AddTNegativeBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2895}
2896
2897static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002898QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pMe,
2899 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002900 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002901{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002902 QCBOREncode_AddTNegativeBignumToMapSZ(pMe,
2903 szLabel,
2904 QCBOR_ENCODE_AS_TAG,
2905 Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002906}
2907
2908static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002909QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002910 const int64_t nLabel,
2911 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002912{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002913 QCBOREncode_AddTNegativeBignumToMapN(pMe,
2914 nLabel,
2915 QCBOR_ENCODE_AS_TAG,
2916 Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002917}
2918
2919
Michael Eckel5c531332020-03-02 01:35:30 +01002920
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07002921#ifndef QCBOR_DISABLE_EXP_AND_MANTISSA
Michael Eckel5c531332020-03-02 01:35:30 +01002922
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002923static inline void
2924QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002925 const uint8_t uTagRequirement,
2926 const int64_t nMantissa,
2927 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002928{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002929 uint64_t uTag;
2930 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2931 uTag = CBOR_TAG_DECIMAL_FRACTION;
2932 } else {
2933 uTag = CBOR_TAG_INVALID64;
2934 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002935 QCBOREncode_Private_AddExpMantissa(pMe,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002936 uTag,
Michael Eckel5c531332020-03-02 01:35:30 +01002937 NULLUsefulBufC,
2938 false,
2939 nMantissa,
2940 nBase10Exponent);
2941}
2942
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002943static inline void
2944QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pMe,
2945 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002946 const uint8_t uTagRequirement,
2947 const int64_t nMantissa,
2948 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002949{
2950 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07002951 QCBOREncode_AddTDecimalFraction(pMe,
2952 uTagRequirement,
2953 nMantissa,
2954 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002955}
2956
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002957static inline void
2958QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002959 const int64_t nLabel,
2960 const uint8_t uTagRequirement,
2961 const int64_t nMantissa,
2962 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002963{
2964 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07002965 QCBOREncode_AddTDecimalFraction(pMe,
2966 uTagRequirement,
2967 nMantissa,
2968 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002969}
2970
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002971static inline void
2972QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002973 const int64_t nMantissa,
2974 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002975{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002976 QCBOREncode_AddTDecimalFraction(pMe,
2977 QCBOR_ENCODE_AS_TAG,
2978 nMantissa,
2979 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002980}
2981
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002982static inline void
2983QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pMe,
2984 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002985 const int64_t nMantissa,
2986 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002987{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002988 QCBOREncode_AddTDecimalFractionToMapSZ(pMe,
2989 szLabel,
2990 QCBOR_ENCODE_AS_TAG,
2991 nMantissa,
2992 nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002993}
2994
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002995static inline void
2996QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002997 const int64_t nLabel,
2998 const int64_t nMantissa,
2999 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003000{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003001 QCBOREncode_AddTDecimalFractionToMapN(pMe,
3002 nLabel,
3003 QCBOR_ENCODE_AS_TAG,
3004 nMantissa,
3005 nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003006}
3007
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003008
3009
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003010static inline void
3011QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003012 const uint8_t uTagRequirement,
3013 const UsefulBufC Mantissa,
3014 const bool bIsNegative,
3015 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003016{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003017 uint64_t uTag;
3018 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3019 uTag = CBOR_TAG_DECIMAL_FRACTION;
3020 } else {
3021 uTag = CBOR_TAG_INVALID64;
3022 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003023 QCBOREncode_Private_AddExpMantissa(pMe,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003024 uTag,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003025 Mantissa,
3026 bIsNegative,
Michael Eckel5c531332020-03-02 01:35:30 +01003027 0,
3028 nBase10Exponent);
3029}
3030
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003031static inline void
3032QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
3033 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003034 const uint8_t uTagRequirement,
3035 const UsefulBufC Mantissa,
3036 const bool bIsNegative,
3037 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003038{
3039 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003040 QCBOREncode_AddTDecimalFractionBigNum(pMe,
3041 uTagRequirement,
3042 Mantissa,
3043 bIsNegative,
3044 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003045}
3046
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003047static inline void
3048QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003049 const int64_t nLabel,
3050 const uint8_t uTagRequirement,
3051 const UsefulBufC Mantissa,
3052 const bool bIsNegative,
3053 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003054{
3055 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003056 QCBOREncode_AddTDecimalFractionBigNum(pMe,
3057 uTagRequirement,
3058 Mantissa,
3059 bIsNegative,
3060 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003061}
3062
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003063static inline void
3064QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003065 const UsefulBufC Mantissa,
3066 const bool bIsNegative,
3067 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003068{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003069 QCBOREncode_AddTDecimalFractionBigNum(pMe,
3070 QCBOR_ENCODE_AS_TAG,
3071 Mantissa,
3072 bIsNegative,
3073 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003074}
3075
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003076static inline void
3077QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
3078 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003079 const UsefulBufC Mantissa,
3080 const bool bIsNegative,
3081 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003082{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003083 QCBOREncode_AddTDecimalFractionBigNumToMapSZ(pMe,
3084 szLabel,
3085 QCBOR_ENCODE_AS_TAG,
3086 Mantissa,
3087 bIsNegative,
3088 nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003089}
3090
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003091static inline void
3092QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003093 const int64_t nLabel,
3094 const UsefulBufC Mantissa,
3095 const bool bIsNegative,
3096 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003097{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003098 QCBOREncode_AddTDecimalFractionBigNumToMapN(pMe,
3099 nLabel,
3100 QCBOR_ENCODE_AS_TAG,
3101 Mantissa,
3102 bIsNegative,
3103 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003104}
3105
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003106
3107
3108
3109
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003110static inline void
3111QCBOREncode_AddTBigFloat(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003112 const uint8_t uTagRequirement,
3113 const int64_t nMantissa,
3114 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003115{
3116 uint64_t uTag;
3117 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3118 uTag = CBOR_TAG_BIGFLOAT;
3119 } else {
3120 uTag = CBOR_TAG_INVALID64;
3121 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003122 QCBOREncode_Private_AddExpMantissa(pMe,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003123 uTag,
3124 NULLUsefulBufC,
3125 false,
3126 nMantissa,
3127 nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003128}
3129
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003130static inline void
3131QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pMe,
3132 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003133 const uint8_t uTagRequirement,
3134 const int64_t nMantissa,
3135 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003136{
3137 QCBOREncode_AddSZString(pMe, szLabel);
3138 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
3139}
3140
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003141static inline void
3142QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003143 const int64_t nLabel,
3144 const uint8_t uTagRequirement,
3145 const int64_t nMantissa,
3146 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003147{
3148 QCBOREncode_AddInt64(pMe, nLabel);
3149 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
3150}
3151
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003152static inline void
3153QCBOREncode_AddBigFloat(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003154 const int64_t nMantissa,
3155 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003156{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003157 QCBOREncode_AddTBigFloat(pMe,
3158 QCBOR_ENCODE_AS_TAG,
3159 nMantissa,
3160 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003161}
3162
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003163static inline void
3164QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pMe,
3165 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003166 const int64_t nMantissa,
3167 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003168{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003169 QCBOREncode_AddTBigFloatToMapSZ(pMe,
3170 szLabel,
3171 QCBOR_ENCODE_AS_TAG,
3172 nMantissa,
3173 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003174}
3175
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003176static inline void
3177QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003178 const int64_t nLabel,
3179 const int64_t nMantissa,
3180 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003181{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003182 QCBOREncode_AddTBigFloatToMapN(pMe,
3183 nLabel,
3184 QCBOR_ENCODE_AS_TAG,
3185 nMantissa,
3186 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003187}
3188
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003189
3190
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003191static inline void
3192QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003193 const uint8_t uTagRequirement,
3194 const UsefulBufC Mantissa,
3195 const bool bIsNegative,
3196 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003197{
3198 uint64_t uTag;
3199 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3200 uTag = CBOR_TAG_BIGFLOAT;
3201 } else {
3202 uTag = CBOR_TAG_INVALID64;
3203 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003204 QCBOREncode_Private_AddExpMantissa(pMe,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003205 uTag,
3206 Mantissa,
3207 bIsNegative,
3208 0,
3209 nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003210}
3211
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003212static inline void
3213QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pMe,
3214 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003215 const uint8_t uTagRequirement,
3216 const UsefulBufC Mantissa,
3217 const bool bIsNegative,
3218 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003219{
3220 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003221 QCBOREncode_AddTBigFloatBigNum(pMe,
3222 uTagRequirement,
3223 Mantissa,
3224 bIsNegative,
3225 nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003226}
3227
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003228static inline void
3229QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003230 const int64_t nLabel,
3231 const uint8_t uTagRequirement,
3232 const UsefulBufC Mantissa,
3233 const bool bIsNegative,
3234 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003235{
3236 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003237 QCBOREncode_AddTBigFloatBigNum(pMe,
3238 uTagRequirement,
3239 Mantissa,
3240 bIsNegative,
3241 nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003242}
3243
3244
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003245static inline void
3246QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003247 const UsefulBufC Mantissa,
3248 const bool bIsNegative,
3249 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003250{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003251 QCBOREncode_AddTBigFloatBigNum(pMe,
3252 QCBOR_ENCODE_AS_TAG,
3253 Mantissa, bIsNegative,
3254 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003255}
3256
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003257static inline void
3258QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pMe,
3259 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003260 const UsefulBufC Mantissa,
3261 const bool bIsNegative,
3262 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003263{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003264 QCBOREncode_AddTBigFloatBigNumToMapSZ(pMe,
3265 szLabel,
3266 QCBOR_ENCODE_AS_TAG,
3267 Mantissa,
3268 bIsNegative,
3269 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003270}
3271
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003272static inline void
3273QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003274 const int64_t nLabel,
3275 const UsefulBufC Mantissa,
3276 const bool bIsNegative,
3277 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003278{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003279 QCBOREncode_AddTBigFloatBigNumToMapN(pMe,
3280 nLabel,
3281 QCBOR_ENCODE_AS_TAG,
3282 Mantissa,
3283 bIsNegative,
3284 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003285}
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07003286#endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
Michael Eckel5c531332020-03-02 01:35:30 +01003287
3288
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003289static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003290QCBOREncode_AddTURI(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003291 const uint8_t uTagRequirement,
3292 const UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01003293{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003294 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3295 QCBOREncode_AddTag(pMe, CBOR_TAG_URI);
3296 }
3297 QCBOREncode_AddText(pMe, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01003298}
3299
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003300static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003301QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pMe,
3302 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003303 const uint8_t uTagRequirement,
3304 const UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01003305{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003306 QCBOREncode_AddSZString(pMe, szLabel);
3307 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01003308}
3309
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003310static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003311QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003312 const int64_t nLabel,
3313 const uint8_t uTagRequirement,
3314 const UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01003315{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003316 QCBOREncode_AddInt64(pMe, nLabel);
3317 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
3318}
3319
3320static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003321QCBOREncode_AddURI(QCBOREncodeContext *pMe, const UsefulBufC URI)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003322{
3323 QCBOREncode_AddTURI(pMe, QCBOR_ENCODE_AS_TAG, URI);
3324}
3325
3326static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003327QCBOREncode_AddURIToMap(QCBOREncodeContext *pMe,
3328 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003329 const UsefulBufC URI)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003330{
3331 QCBOREncode_AddTURIToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, URI);
3332}
3333
3334static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003335QCBOREncode_AddURIToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003336 const int64_t nLabel,
3337 const UsefulBufC URI)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003338{
3339 QCBOREncode_AddTURIToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01003340}
3341
3342
3343
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003344static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003345QCBOREncode_AddTB64Text(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003346 const uint8_t uTagRequirement,
3347 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003348{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003349 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3350 QCBOREncode_AddTag(pMe, CBOR_TAG_B64);
3351 }
3352 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003353}
3354
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003355static inline void
3356QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pMe,
3357 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003358 const uint8_t uTagRequirement,
3359 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003360{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003361 QCBOREncode_AddSZString(pMe, szLabel);
3362 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003363}
3364
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003365static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003366QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003367 const int64_t nLabel,
3368 const uint8_t uTagRequirement,
3369 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003370{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003371 QCBOREncode_AddInt64(pMe, nLabel);
3372 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
3373}
3374
3375static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003376QCBOREncode_AddB64Text(QCBOREncodeContext *pMe, const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003377{
3378 QCBOREncode_AddTB64Text(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
3379}
3380
3381static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003382QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pMe,
3383 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003384 const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003385{
3386 QCBOREncode_AddTB64TextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
3387}
3388
3389static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003390QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003391 const int64_t nLabel,
3392 const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003393{
3394 QCBOREncode_AddTB64TextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003395}
3396
3397
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003398
3399static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003400QCBOREncode_AddTB64URLText(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003401 const uint8_t uTagRequirement,
3402 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003403{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003404 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3405 QCBOREncode_AddTag(pMe, CBOR_TAG_B64URL);
3406 }
3407 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003408}
3409
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003410static inline void
3411QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pMe,
3412 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003413 const uint8_t uTagRequirement,
3414 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003415{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003416 QCBOREncode_AddSZString(pMe, szLabel);
3417 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003418}
3419
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003420static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003421QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003422 const int64_t nLabel,
3423 const uint8_t uTagRequirement,
3424 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003425{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003426 QCBOREncode_AddInt64(pMe, nLabel);
3427 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
3428}
3429
3430static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003431QCBOREncode_AddB64URLText(QCBOREncodeContext *pMe, const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003432{
3433 QCBOREncode_AddTB64URLText(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
3434}
3435
3436static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003437QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pMe,
3438 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003439 const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003440{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003441 QCBOREncode_AddTB64URLTextToMapSZ(pMe,
3442 szLabel,
3443 QCBOR_ENCODE_AS_TAG,
3444 B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003445}
3446
3447static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003448QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003449 const int64_t nLabel,
3450 const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003451{
3452 QCBOREncode_AddTB64URLTextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003453}
3454
3455
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003456
3457static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003458QCBOREncode_AddTRegex(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003459 const uint8_t uTagRequirement,
3460 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003461{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003462 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3463 QCBOREncode_AddTag(pMe, CBOR_TAG_REGEX);
3464 }
3465 QCBOREncode_AddText(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01003466}
3467
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003468static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003469QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pMe,
3470 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003471 const uint8_t uTagRequirement,
3472 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003473{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003474 QCBOREncode_AddSZString(pMe, szLabel);
3475 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01003476}
3477
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003478static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003479QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003480 const int64_t nLabel,
3481 const uint8_t uTagRequirement,
3482 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003483{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003484 QCBOREncode_AddInt64(pMe, nLabel);
3485 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
3486}
3487
3488static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003489QCBOREncode_AddRegex(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003490{
3491 QCBOREncode_AddTRegex(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
3492}
3493
3494static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003495QCBOREncode_AddRegexToMap(QCBOREncodeContext *pMe,
3496 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003497 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003498{
3499 QCBOREncode_AddTRegexToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
3500}
3501
3502static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003503QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003504 const int64_t nLabel,
3505 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003506{
3507 QCBOREncode_AddTRegexToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
3508
Michael Eckel5c531332020-03-02 01:35:30 +01003509}
3510
3511
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003512static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003513QCBOREncode_AddTMIMEData(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003514 const uint8_t uTagRequirement,
3515 const UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01003516{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003517 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
Laurence Lundblade4982f412020-09-18 23:02:18 -07003518 QCBOREncode_AddTag(pMe, CBOR_TAG_BINARY_MIME);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003519 }
Laurence Lundblade4982f412020-09-18 23:02:18 -07003520 QCBOREncode_AddBytes(pMe, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01003521}
3522
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003523static inline void
3524QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pMe,
3525 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003526 const uint8_t uTagRequirement,
3527 const UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01003528{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003529 QCBOREncode_AddSZString(pMe, szLabel);
3530 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01003531}
3532
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003533static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003534QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003535 const int64_t nLabel,
3536 const uint8_t uTagRequirement,
3537 const UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01003538{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003539 QCBOREncode_AddInt64(pMe, nLabel);
3540 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
3541}
3542
3543static inline void
3544QCBOREncode_AddMIMEData(QCBOREncodeContext *pMe, UsefulBufC MIMEData)
3545{
3546 QCBOREncode_AddTMIMEData(pMe, QCBOR_ENCODE_AS_TAG, MIMEData);
3547}
3548
3549static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003550QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pMe,
3551 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003552 const UsefulBufC MIMEData)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003553{
3554 QCBOREncode_AddTMIMEDataToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
3555}
3556
3557static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003558QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003559 const int64_t nLabel,
3560 const UsefulBufC MIMEData)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003561{
3562 QCBOREncode_AddTMIMEDataToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01003563}
3564
3565
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003566static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003567QCBOREncode_AddTDateString(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003568 const uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003569 const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01003570{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003571 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3572 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_STRING);
3573 }
3574 QCBOREncode_AddSZString(pMe, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01003575}
3576
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003577static inline void
3578QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pMe,
3579 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003580 const uint8_t uTagRequirement,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003581 const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01003582{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003583 QCBOREncode_AddSZString(pMe, szLabel);
3584 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01003585}
3586
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003587static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003588QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003589 const int64_t nLabel,
3590 const uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003591 const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01003592{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003593 QCBOREncode_AddInt64(pMe, nLabel);
3594 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
3595}
3596
3597static inline void
3598QCBOREncode_AddDateString(QCBOREncodeContext *pMe, const char *szDate)
3599{
3600 QCBOREncode_AddTDateString(pMe, QCBOR_ENCODE_AS_TAG, szDate);
3601}
3602
3603static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003604QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pMe,
3605 const char *szLabel,
3606 const char *szDate)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003607{
3608 QCBOREncode_AddTDateStringToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, szDate);
3609}
3610
3611static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003612QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003613 const int64_t nLabel,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003614 const char *szDate)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003615{
3616 QCBOREncode_AddTDateStringToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01003617}
3618
3619
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003620static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003621QCBOREncode_AddTDaysString(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003622 const uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003623 const char *szDate)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07003624{
3625 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3626 QCBOREncode_AddTag(pMe, CBOR_TAG_DAYS_STRING);
3627 }
3628 QCBOREncode_AddSZString(pMe, szDate);
3629}
3630
3631static inline void
3632QCBOREncode_AddTDaysStringToMapSZ(QCBOREncodeContext *pMe,
3633 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003634 const uint8_t uTagRequirement,
Laurence Lundblade46d63e92021-05-13 11:37:10 -07003635 const char *szDate)
3636{
3637 QCBOREncode_AddSZString(pMe, szLabel);
3638 QCBOREncode_AddTDaysString(pMe, uTagRequirement, szDate);
3639}
3640
3641static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003642QCBOREncode_AddTDaysStringToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003643 const int64_t nLabel,
3644 const uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003645 const char *szDate)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07003646{
3647 QCBOREncode_AddInt64(pMe, nLabel);
3648 QCBOREncode_AddTDaysString(pMe, uTagRequirement, szDate);
3649}
3650
3651
3652
3653static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003654QCBOREncode_Private_AddSimple(QCBOREncodeContext *pMe, const uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01003655{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003656 QCBOREncode_Private_AddType7(pMe, 0, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01003657}
3658
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003659static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003660QCBOREncode_Private_AddSimpleToMap(QCBOREncodeContext *pMe,
3661 const char *szLabel,
3662 const uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01003663{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003664 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003665 QCBOREncode_Private_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01003666}
3667
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003668static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003669QCBOREncode_Private_AddSimpleToMapN(QCBOREncodeContext *pMe,
3670 const int64_t nLabel,
3671 const uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01003672{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003673 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003674 QCBOREncode_Private_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01003675}
3676
3677
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003678static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003679QCBOREncode_AddBool(QCBOREncodeContext *pMe, const bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01003680{
3681 uint8_t uSimple = CBOR_SIMPLEV_FALSE;
3682 if(b) {
3683 uSimple = CBOR_SIMPLEV_TRUE;
3684 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003685 QCBOREncode_Private_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01003686}
3687
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003688static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003689QCBOREncode_AddBoolToMap(QCBOREncodeContext *pMe, const char *szLabel, const bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01003690{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003691 QCBOREncode_AddSZString(pMe, szLabel);
3692 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01003693}
3694
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003695static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003696QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pMe, const int64_t nLabel, const bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01003697{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003698 QCBOREncode_AddInt64(pMe, nLabel);
3699 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01003700}
3701
3702
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003703static inline void
3704QCBOREncode_AddNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003705{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003706 QCBOREncode_Private_AddSimple(pMe, CBOR_SIMPLEV_NULL);
Michael Eckel5c531332020-03-02 01:35:30 +01003707}
3708
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003709static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003710QCBOREncode_AddNULLToMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003711{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003712 QCBOREncode_AddSZString(pMe, szLabel);
3713 QCBOREncode_AddNULL(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003714}
3715
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003716static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003717QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003718{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003719 QCBOREncode_AddInt64(pMe, nLabel);
3720 QCBOREncode_AddNULL(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003721}
3722
3723
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003724static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003725QCBOREncode_AddUndef(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003726{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003727 QCBOREncode_Private_AddSimple(pMe, CBOR_SIMPLEV_UNDEF);
Michael Eckel5c531332020-03-02 01:35:30 +01003728}
3729
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003730static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003731QCBOREncode_AddUndefToMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003732{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003733 QCBOREncode_AddSZString(pMe, szLabel);
3734 QCBOREncode_AddUndef(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003735}
3736
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003737static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003738QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003739{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003740 QCBOREncode_AddInt64(pMe, nLabel);
3741 QCBOREncode_AddUndef(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003742}
3743
3744
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003745static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003746QCBOREncode_OpenArray(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003747{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003748 QCBOREncode_Private_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
Michael Eckel5c531332020-03-02 01:35:30 +01003749}
3750
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003751static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003752QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003753{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003754 QCBOREncode_AddSZString(pMe, szLabel);
3755 QCBOREncode_OpenArray(pMe);
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_OpenArrayInMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003760{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003761 QCBOREncode_AddInt64(pMe, nLabel);
3762 QCBOREncode_OpenArray(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003763}
3764
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003765static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003766QCBOREncode_CloseArray(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003767{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003768 QCBOREncode_Private_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
Michael Eckel5c531332020-03-02 01:35:30 +01003769}
3770
3771
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003772static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003773QCBOREncode_OpenMap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003774{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003775 QCBOREncode_Private_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
Michael Eckel5c531332020-03-02 01:35:30 +01003776}
3777
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003778static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003779QCBOREncode_OpenMapInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003780{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003781 QCBOREncode_AddSZString(pMe, szLabel);
3782 QCBOREncode_OpenMap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003783}
3784
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003785static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003786QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003787{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003788 QCBOREncode_AddInt64(pMe, nLabel);
3789 QCBOREncode_OpenMap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003790}
3791
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003792static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003793QCBOREncode_CloseMap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003794{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003795 QCBOREncode_Private_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
Michael Eckel5c531332020-03-02 01:35:30 +01003796}
3797
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003798static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003799QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003800{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003801 QCBOREncode_Private_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003802}
3803
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003804static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003805QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pMe,
3806 const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003807{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003808 QCBOREncode_AddSZString(pMe, szLabel);
3809 QCBOREncode_OpenArrayIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003810}
3811
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003812static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003813QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003814 const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003815{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003816 QCBOREncode_AddInt64(pMe, nLabel);
3817 QCBOREncode_OpenArrayIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003818}
3819
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003820static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003821QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003822{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003823 QCBOREncode_Private_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003824}
3825
3826
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003827static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003828QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003829{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003830 QCBOREncode_Private_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003831}
3832
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003833static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003834QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pMe,
3835 const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003836{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003837 QCBOREncode_AddSZString(pMe, szLabel);
3838 QCBOREncode_OpenMapIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003839}
3840
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003841static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003842QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003843 const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003844{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003845 QCBOREncode_AddInt64(pMe, nLabel);
3846 QCBOREncode_OpenMapIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003847}
3848
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003849static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003850QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003851{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003852 QCBOREncode_Private_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003853}
3854
3855
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003856static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003857QCBOREncode_BstrWrap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003858{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003859 QCBOREncode_Private_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_BYTE_STRING);
Michael Eckel5c531332020-03-02 01:35:30 +01003860}
3861
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003862static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003863QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003864{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003865 QCBOREncode_AddSZString(pMe, szLabel);
3866 QCBOREncode_BstrWrap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003867}
3868
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003869static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003870QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003871{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003872 QCBOREncode_AddInt64(pMe, nLabel);
3873 QCBOREncode_BstrWrap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003874}
3875
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003876static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003877QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pMe, UsefulBufC *pWrappedCBOR)
Michael Eckel5c531332020-03-02 01:35:30 +01003878{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003879 QCBOREncode_CloseBstrWrap2(pMe, true, pWrappedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01003880}
3881
3882
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003883static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003884QCBOREncode_AddEncoded(QCBOREncodeContext *pMe, const UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003885{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003886 QCBOREncode_Private_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_RAW, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003887}
3888
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003889static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003890QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pMe,
3891 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003892 const UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003893{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003894 QCBOREncode_AddSZString(pMe, szLabel);
3895 QCBOREncode_AddEncoded(pMe, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003896}
3897
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003898static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003899QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003900 const int64_t nLabel,
3901 const UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003902{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003903 QCBOREncode_AddInt64(pMe, nLabel);
3904 QCBOREncode_AddEncoded(pMe, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003905}
3906
3907
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003908static inline int
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003909QCBOREncode_IsBufferNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003910{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003911 return UsefulOutBuf_IsBufferNULL(&(pMe->OutBuf));
Michael Eckel5c531332020-03-02 01:35:30 +01003912}
3913
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003914static inline QCBORError
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003915QCBOREncode_GetErrorState(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003916{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003917 if(UsefulOutBuf_GetError(&(pMe->OutBuf))) {
Michael Eckel5c531332020-03-02 01:35:30 +01003918 // Items didn't fit in the buffer.
3919 // This check catches this condition for all the appends and inserts
3920 // so checks aren't needed when the appends and inserts are performed.
3921 // And of course UsefulBuf will never overrun the input buffer given
3922 // to it. No complex analysis of the error handling in this file is
3923 // needed to know that is true. Just read the UsefulBuf code.
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003924 pMe->uError = QCBOR_ERR_BUFFER_TOO_SMALL;
Michael Eckel5c531332020-03-02 01:35:30 +01003925 // QCBOR_ERR_BUFFER_TOO_SMALL masks other errors, but that is
3926 // OK. Once the caller fixes this, they'll be unmasked.
3927 }
3928
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003929 return (QCBORError)pMe->uError;
Michael Eckel5c531332020-03-02 01:35:30 +01003930}
3931
3932
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003933/* ========================================================================
3934 END OF PRIVATE INLINE IMPLEMENTATION
3935 ======================================================================== */
Michael Eckel5c531332020-03-02 01:35:30 +01003936
3937#ifdef __cplusplus
3938}
3939#endif
3940
Laurence Lundblade844bb5c2020-03-01 17:27:25 -08003941#endif /* qcbor_encode_h */