blob: cf32f3cd5ed2decc00ffd08f9069af91fe724408 [file] [log] [blame]
Laurence Lundblade3eead482023-12-16 20:53:22 -07001/* ===========================================================================
2 * Copyright (c) 2016-2018, The Linux Foundation.
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003 * Copyright (c) 2018-2024, Laurence Lundblade.
Laurence Lundblade3eead482023-12-16 20:53:22 -07004 * Copyright (c) 2021, Arm Limited.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials provided
15 * with the distribution.
16 * * Neither the name of The Linux Foundation nor the names of its
17 * contributors, nor the name "Laurence Lundblade" may be used to
18 * endorse or promote products derived from this software without
19 * specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
22 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
30 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
31 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * ========================================================================= */
Michael Eckel5c531332020-03-02 01:35:30 +010033
34
Laurence Lundblade844bb5c2020-03-01 17:27:25 -080035#ifndef qcbor_encode_h
36#define qcbor_encode_h
Michael Eckel5c531332020-03-02 01:35:30 +010037
38
Laurence Lundblade844bb5c2020-03-01 17:27:25 -080039#include "qcbor/qcbor_common.h"
40#include "qcbor/qcbor_private.h"
Michael Eckel5c531332020-03-02 01:35:30 +010041#include <stdbool.h>
Laurence Lundblade844bb5c2020-03-01 17:27:25 -080042
Michael Eckel5c531332020-03-02 01:35:30 +010043
44#ifdef __cplusplus
45extern "C" {
Dave Thaler12b23752020-03-27 01:23:08 -070046#if 0
Michael Eckel5c531332020-03-02 01:35:30 +010047} // Keep editor indention formatting happy
48#endif
49#endif
50
Michael Eckel5c531332020-03-02 01:35:30 +010051
52/**
Laurence Lundblade3eead482023-12-16 20:53:22 -070053 * @file qcbor_encode.h
54 *
55 * @anchor Overview
56 *
57 * # QCBOR Overview
58 *
59 * This implements CBOR -- Concise Binary Object Representation as
60 * defined in [RFC 8949] (https://tools.ietf.org/html/rfc8949). More
61 * information is at http://cbor.io. This is a near-complete implementation of
62 * the specification. [RFC 8742] (https://tools.ietf.org/html/rfc8742) CBOR
63 * Sequences is also supported. Limitations are listed further down.
64 *
65 * See @ref Encoding for general discussion on encoding,
66 * @ref BasicDecode for general discussion on the basic decode features
67 * and @ref SpiffyDecode for general discussion on the easier-to-use
68 * decoder functions.
69 *
70 * CBOR is intentionally designed to be translatable to JSON, but not
71 * all CBOR can convert to JSON. See RFC 8949 for more info on how to
72 * construct CBOR that is the most JSON friendly.
73 *
74 * The memory model for encoding and decoding is that encoded CBOR must
75 * be in a contiguous buffer in memory. During encoding the caller must
76 * supply an output buffer and if the encoding would go off the end of
77 * the buffer an error is returned. During decoding the caller supplies
78 * the encoded CBOR in a contiguous buffer and the decoder returns
79 * pointers and lengths into that buffer for strings.
80 *
81 * This implementation does not require malloc. All data structures
82 * passed in/out of the APIs can fit on the stack.
83 *
84 * Decoding of indefinite-length strings is a special case that requires
85 * a "string allocator" to allocate memory into which the segments of
86 * the string are coalesced. Without this, decoding will error out if an
87 * indefinite-length string is encountered (indefinite-length maps and
88 * arrays do not require the string allocator). A simple string
89 * allocator called MemPool is built-in and will work if supplied with a
90 * block of memory to allocate. The string allocator can optionally use
91 * malloc() or some other custom scheme.
92 *
93 * Here are some terms and definitions:
94 *
95 * - "Item", "Data Item": An integer or string or such. The basic "thing" that
96 * CBOR is about. An array is an item itself that contains some items.
97 *
98 * - "Array": An ordered sequence of items, the same as JSON.
99 *
100 * - "Map": A collection of label/value pairs. Each pair is a data
101 * item. A JSON "object" is the same as a CBOR "map".
102 *
103 * - "Label": The data item in a pair in a map that names or identifies
104 * the pair, not the value. This implementation refers to it as a
105 * "label". JSON refers to it as the "name". The CBOR RFC refers to it
106 * this as a "key". This implementation chooses label instead because
107 * key is too easily confused with a cryptographic key. The COSE
108 * standard, which uses CBOR, has also chosen to use the term "label"
109 * rather than "key" for this same reason.
110 *
111 * - "Key": See "Label" above.
112 *
113 * - "Tag": A data item that is an explicitly labeled new data
114 * type made up of the tagging integer and the tag content.
115 * See @ref Tags-Overview and @ref Tag-Usage.
116 *
117 * - "Initial Byte": The first byte of an encoded item. Encoding and
118 * decoding of this byte is taken care of by the implementation.
119 *
120 * - "Additional Info": In addition to the major type, all data items
121 * have some other info. This is usually the length of the data but can
122 * be several other things. Encoding and decoding of this is taken care
123 * of by the implementation.
124 *
125 * CBOR has two mechanisms for tagging and labeling the data values like
126 * integers and strings. For example, an integer that represents
127 * someone's birthday in epoch seconds since Jan 1, 1970 could be
128 * encoded like this:
129 *
130 * - First it is CBOR_MAJOR_TYPE_POSITIVE_INT (@ref QCBOR_TYPE_INT64),
131 * the primitive positive integer.
132 *
133 * - Next it has a "tag" @ref CBOR_TAG_DATE_EPOCH indicating the integer
134 * represents a date in the form of the number of seconds since Jan 1,
135 * 1970.
136 *
137 * - Last it has a string "label" like "BirthDate" indicating the
138 * meaning of the data.
139 *
140 * The encoded binary looks like this:
141 *
142 * a1 # Map of 1 item
143 * 69 # Indicates text string of 9 bytes
144 * 426972746844617465 # The text "BirthDate"
145 * c1 # Tags next integer as epoch date
146 * 1a # Indicates a 4-byte integer
147 * 580d4172 # unsigned integer date 1477263730
148 *
149 * Implementors using this API will primarily work with
150 * labels. Generally, tags are only needed for making up new data
151 * types. This implementation covers most of the data types defined in
152 * the RFC using tags. It also, allows for the use of custom tags if
153 * necessary.
154 *
155 * This implementation explicitly supports labels that are text strings
156 * and integers. Text strings translate nicely into JSON objects and are
157 * very readable. Integer labels are much less readable but can be very
158 * compact. If they are in the range of 0 to 23, they take up only one
159 * byte.
160 *
161 * CBOR allows a label to be any type of data including an array or a
162 * map. It is possible to use this API to construct and parse such
163 * labels, but it is not explicitly supported.
164 *
165 * @anchor Encoding
166 *
167 * ## Encoding
168 *
169 * A common encoding usage mode is to invoke the encoding twice. First
170 * with the output buffer as @ref SizeCalculateUsefulBuf to compute the
171 * length of the needed output buffer. The correct sized output buffer
172 * is allocated. The encoder is invoked a second time with the allocated
173 * output buffer.
174 *
175 * The double invocation is not required if the maximum output buffer
176 * size can be predicted. This is usually possible for simple CBOR
177 * structures.
178 *
179 * If a buffer too small to hold the encoded output is given, the error
180 * @ref QCBOR_ERR_BUFFER_TOO_SMALL will be returned. Data will never be
181 * written off the end of the output buffer no matter which functions
182 * here are called or what parameters are passed to them.
183 *
184 * The encoding error handling is simple. The only possible errors are
185 * trying to encode structures that are too large or too complex. There
186 * are no internal malloc calls so there will be no failures for out of
187 * memory. The error state is tracked internally, so there is no need
188 * to check for errors when encoding. Only the return code from
189 * QCBOREncode_Finish() need be checked as once an error happens, the
190 * encoder goes into an error state and calls to it to add more data
191 * will do nothing. An error check is not needed after every data item
192 * is added.
193 *
194 * Encoding generally proceeds by calling QCBOREncode_Init(), calling
195 * lots of @c QCBOREncode_AddXxx() functions and calling
196 * QCBOREncode_Finish(). There are many @c QCBOREncode_AddXxx()
197 * functions for various data types. The input buffers need only to be
198 * valid during the @c QCBOREncode_AddXxx() calls as the data is copied
199 * into the output buffer.
200 *
201 * There are three `Add` functions for each data type. The first / main
202 * one for the type is for adding the data item to an array. The second
203 * one's name ends in `ToMap`, is used for adding data items to maps and
204 * takes a string argument that is its label in the map. The third one
205 * ends in `ToMapN`, is also used for adding data items to maps, and
206 * takes an integer argument that is its label in the map.
207 *
208 * The simplest aggregate type is an array, which is a simple ordered
209 * set of items without labels the same as JSON arrays. Call
210 * QCBOREncode_OpenArray() to open a new array, then various @c
211 * QCBOREncode_AddXxx() functions to put items in the array and then
212 * QCBOREncode_CloseArray(). Nesting to the limit @ref
213 * QCBOR_MAX_ARRAY_NESTING is allowed. All opens must be matched by
214 * closes or an encoding error will be returned.
215 *
216 * The other aggregate type is a map which does use labels. The `Add`
217 * functions that end in `ToMap` and `ToMapN` are convenient ways to add
218 * labeled data items to a map. You can also call any type of `Add`
219 * function once to add a label of any type and then call any type of
220 * `Add` again to add its value.
221 *
222 * Note that when you nest arrays or maps in a map, the nested array or
223 * map has a label.
224 *
225 * Many CBOR-based protocols start with an array or map. This makes them
226 * self-delimiting. No external length or end marker is needed to know
227 * the end. It is also possible not start this way, in which case this
228 * it is usually called a CBOR sequence which is described in
229 * [RFC 8742] (https://tools.ietf.org/html/rfc8742). This encoder supports
230 * either just by whether the first item added is an array, map or other.
231 *
232 * If QCBOR is compiled with QCBOR_DISABLE_ENCODE_USAGE_GUARDS defined,
233 * the errors QCBOR_ERR_CLOSE_MISMATCH, QCBOR_ERR_ARRAY_TOO_LONG,
234 * QCBOR_ERR_TOO_MANY_CLOSES, QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN, and
235 * QCBOR_ERR_ENCODE_UNSUPPORTED will never be returned. It is up to the
236 * caller to make sure that opened maps, arrays and byte-string wrapping
237 * is closed correctly and that QCBOREncode_AddType7() is called
238 * correctly. With this defined, it is easier to make a mistake when
239 * authoring the encoding of a protocol that will output not well formed
240 * CBOR, but as long as the calling code is correct, it is safe to
241 * disable these checks. Bounds checking that prevents security issues
242 * in the code is still enforced. This define reduces the size of
243 * encoding object code by about 150 bytes.
244 *
245 * @anchor Tags-Overview
246 *
247 * ## Tags Overview
248 *
249 * Any CBOR data item can be made into a tag to add semantics, define a
250 * new data type or such. Some tags are fully standardized and some are
251 * just registered. Others are not registered and used in a proprietary
252 * way.
253 *
254 * Encoding and decoding of many of the registered tags is fully
255 * implemented by QCBOR. It is also possible to encode and decode tags
256 * that are not directly supported. For many use cases the built-in tag
257 * support should be adequate.
258 *
259 * For example, the registered epoch date tag is supported in encoding
260 * by QCBOREncode_AddDateEpoch() and in decoding by @ref
261 * QCBOR_TYPE_DATE_EPOCH and the @c epochDate member of @ref
262 * QCBORItem. This is typical of the built-in tag support. There is an
263 * API to encode data for it and a @c QCBOR_TYPE_XXX when it is decoded.
264 *
265 * Tags are registered in the [IANA CBOR Tags Registry]
266 * (https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml). There
267 * are roughly three options to create a new tag. First, a public
268 * specification can be created and the new tag registered with IANA.
269 * This is the most formal. Second, the new tag can be registered with
270 * IANA with just a short description rather than a full specification.
271 * These tags must be greater than 256. Third, a tag can be used without
272 * any IANA registration, though the registry should be checked to see
273 * that the new value doesn't collide with one that is registered. The
274 * value of these tags must be 256 or larger.
275 *
276 * See also @ref CBORTags and @ref Tag-Usage
277 *
278 * The encoding side of tags not built-in is handled by
279 * QCBOREncode_AddTag() and is relatively simple. Tag decoding is more
280 * complex and mainly handled by QCBORDecode_GetNext(). Decoding of the
281 * structure of tagged data not built-in (if there is any) has to be
282 * implemented by the caller.
283 *
284 * @anchor Floating-Point
285 *
286 * ## Floating-Point
287 *
288 * By default QCBOR fully supports IEEE 754 floating-point:
289 * - Encode/decode of double, single and half-precision
290 * - CBOR preferred serialization of floating-point
291 * - Floating-point epoch dates
292 *
293 * For the most part, the type double is used in the interface for
294 * floating-point values. In the default configuration, all decoded
295 * floating-point values are returned as a double.
296 *
297 * With CBOR preferred serialization, the encoder outputs the smallest
298 * representation of the double or float that preserves precision. Zero,
299 * NaN and infinity are always output as a half-precision, each taking
300 * just 2 bytes. This reduces the number of bytes needed to encode
301 * double and single-precision, especially if zero, NaN and infinity are
302 * frequently used.
303 *
304 * To avoid use of preferred serialization in the standard configuration
305 * when encoding, use QCBOREncode_AddDoubleNoPreferred() or
306 * QCBOREncode_AddFloatNoPreferred().
307 *
308 * This implementation of preferred floating-point serialization and
309 * half-precision does not depend on the CPU having floating-point HW or
310 * the compiler bringing in a (sometimes large) library to compensate
311 * for lack of CPU support. This implementation uses shifts and masks
312 * rather than floating-point functions.
313 *
314 * To reduce overall object code by about 900 bytes, define
315 * QCBOR_DISABLE_PREFERRED_FLOAT. This will eliminate all support for
316 * preferred serialization and half-precision. An error will be returned
317 * when attempting to decode half-precision. A float will always be
318 * encoded and decoded as 32-bits and a double will always be encoded
319 * and decoded as 64 bits.
320 *
321 * Note that even if QCBOR_DISABLE_PREFERRED_FLOAT is not defined all
322 * the float-point encoding object code can be avoided by never calling
323 * any functions that encode double or float. Just not calling
324 * floating-point functions will reduce object code by about 500 bytes.
325 *
326 * On CPUs that have no floating-point hardware,
327 * QCBOR_DISABLE_FLOAT_HW_USE should be defined in most cases. If it is
328 * not, then the compiler will bring in possibly large software
329 * libraries to compensate. Defining QCBOR_DISABLE_FLOAT_HW_USE reduces
330 * object code size on CPUs with floating-point hardware by a tiny
331 * amount and eliminates the need for <math.h>
332 *
333 * When QCBOR_DISABLE_FLOAT_HW_USE is defined, trying to decoding
334 * floating-point dates will give error
335 * @ref QCBOR_ERR_FLOAT_DATE_DISABLED and decoded single-precision
336 * numbers will be returned as @ref QCBOR_TYPE_FLOAT instead of
337 * converting them to double as usual.
338 *
339 * If both QCBOR_DISABLE_FLOAT_HW_USE and QCBOR_DISABLE_PREFERRED_FLOAT
340 * are defined, then the only thing QCBOR can do is encode/decode a C
341 * float type as 32-bits and a C double type as 64-bits. Floating-point
342 * epoch dates will be unsupported.
343 *
Laurence Lundblade475c2722024-05-08 11:17:47 -0700344 * If USEFULBUF_DISABLE_ALL_FLOAT is defined, then floating point
Laurence Lundblade3eead482023-12-16 20:53:22 -0700345 * support is completely disabled. Decoding functions return
346 * @ref QCBOR_ERR_ALL_FLOAT_DISABLED if a floating point value is
347 * encountered during decoding. Functions that are encoding floating
348 * point values are not available.
349 *
350 * ## Limitations
351 *
Laurence Lundblade475c2722024-05-08 11:17:47 -0700352 * Summary limitations:
Laurence Lundblade3eead482023-12-16 20:53:22 -0700353 * - The entire encoded CBOR must fit into contiguous memory.
Laurence Lundblade475c2722024-05-08 11:17:47 -0700354 * - Max size of encoded CBOR data is a few bytes less than
355 * @c UINT32_MAX (4GB).
356 * - Max array / map nesting level when encoding or decoding is
Laurence Lundblade3eead482023-12-16 20:53:22 -0700357 * @ref QCBOR_MAX_ARRAY_NESTING (this is typically 15).
Laurence Lundblade475c2722024-05-08 11:17:47 -0700358 * - Max items in an array or map when encoding or decoding is
Laurence Lundblade3eead482023-12-16 20:53:22 -0700359 * @ref QCBOR_MAX_ITEMS_IN_ARRAY (typically 65,536).
360 * - Does not directly support labels in maps other than text strings & integers.
Laurence Lundblade475c2722024-05-08 11:17:47 -0700361 * - Does not directly support integer labels beyond whats fits in @c int64_t
362 * or @c uint64_t.
Laurence Lundblade3eead482023-12-16 20:53:22 -0700363 * - Epoch dates limited to @c INT64_MAX (+/- 292 billion years).
Laurence Lundblade475c2722024-05-08 11:17:47 -0700364 * - Exponents for bigfloats and decimal integers are limited to whats fits in
365 * @c int64_t.
Laurence Lundblade3eead482023-12-16 20:53:22 -0700366 * - Tags on labels are ignored during decoding.
367 * - The maximum tag nesting is @c QCBOR_MAX_TAGS_PER_ITEM (typically 4).
Laurence Lundblade475c2722024-05-08 11:17:47 -0700368 * - Works only on 32- and 64-bit CPUs.
Laurence Lundblade31fddb72024-05-13 13:03:35 -0700369 * - QCBORDecode_EnterBstrWrapped() doesn't work on indefinite-length strings.
Laurence Lundblade3eead482023-12-16 20:53:22 -0700370 *
371 * The public interface uses @c size_t for all lengths. Internally the
372 * implementation uses 32-bit lengths by design to use less memory and
373 * fit structures on the stack. This limits the encoded CBOR it can
Laurence Lundblade475c2722024-05-08 11:17:47 -0700374 * work with to size @c UINT32_MAX (4GB).
Laurence Lundblade3eead482023-12-16 20:53:22 -0700375 *
Laurence Lundblade475c2722024-05-08 11:17:47 -0700376 * This implementation requires two's compliment integers. While
377 * C doesn't require two's compliment, <stdint.h> does. Other
378 * parts of this implementation may also require two's compliment.
Michael Eckel5c531332020-03-02 01:35:30 +0100379 */
380
381
Laurence Lundblade825164e2020-10-22 20:18:06 -0700382/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700383 * The size of the buffer to be passed to QCBOREncode_EncodeHead(). It
384 * is one byte larger than sizeof(uint64_t) + 1, the actual maximum
385 * size of the head of a CBOR data item because
386 * QCBOREncode_EncodeHead() needs one extra byte to work.
Michael Eckel5c531332020-03-02 01:35:30 +0100387 */
388#define QCBOR_HEAD_BUFFER_SIZE (sizeof(uint64_t) + 2)
389
Michael Eckel5c531332020-03-02 01:35:30 +0100390
Laurence Lundblade9b334962020-08-27 10:55:53 -0700391/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700392 * Output the full CBOR tag. See @ref CBORTags, @ref Tag-Usage and
393 * @ref Tags-Overview.
Laurence Lundblade9b334962020-08-27 10:55:53 -0700394 */
395#define QCBOR_ENCODE_AS_TAG 0
396
397/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700398 * Output only the 'borrowed' content format for the relevant tag.
399 * See @ref CBORTags, @ref Tag-Usage and @ref Tags-Overview.
Laurence Lundblade9b334962020-08-27 10:55:53 -0700400 */
401#define QCBOR_ENCODE_AS_BORROWED 1
402
Michael Eckel5c531332020-03-02 01:35:30 +0100403
404/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700405 * QCBOREncodeContext is the data type that holds context for all the
406 * encoding functions. It is less than 200 bytes, so it can go on the
407 * stack. The contents are opaque, and the caller should not access
408 * internal members. A context may be re used serially as long as it is
409 * re initialized.
Michael Eckel5c531332020-03-02 01:35:30 +0100410 */
411typedef struct _QCBOREncodeContext QCBOREncodeContext;
412
413
414/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700415 * Initialize the encoder to prepare to encode some CBOR.
416 *
417 * @param[in,out] pCtx The encoder context to initialize.
418 * @param[in] Storage The buffer into which the encoded result
419 * will be written.
420 *
421 * Call this once at the start of an encoding of some CBOR. Then call
422 * the many functions like QCBOREncode_AddInt64() and
423 * QCBOREncode_AddText() to add the different data items. Finally,
424 * call QCBOREncode_Finish() to get the pointer and length of the
425 * encoded result.
426 *
427 * The primary purpose of this function is to give the pointer and
428 * length of the output buffer into which the encoded CBOR will be
429 * written. This is done with a @ref UsefulBuf structure, which is
430 * just a pointer and length (it is equivalent to two parameters, one
431 * a pointer and one a length, but a little prettier).
432 *
433 * The output buffer can be allocated any way (malloc, stack,
434 * static). It is just some memory that QCBOR writes to. The length
435 * must be the length of the allocated buffer. QCBOR will never write
436 * past that length, but might write up to that length. If the buffer
437 * is too small, encoding will go into an error state and not write
438 * anything further.
439 *
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -0800440 * If allocating on the stack, the convenience macro
Laurence Lundblade3eead482023-12-16 20:53:22 -0700441 * UsefulBuf_MAKE_STACK_UB() can be used, but its use is not required.
442 *
443 * Since there is no reallocation or such, the output buffer must be
444 * correctly sized when passed in here. It is OK, but wasteful if it
445 * is too large. One way to pick the size is to figure out the maximum
446 * size that will ever be needed and hard code a buffer of that size.
447 *
448 * Another way to do it is to have QCBOR calculate it for you. To do
449 * this, pass @ref SizeCalculateUsefulBuf for @c Storage. Then call
450 * all the functions to add the CBOR exactly as if encoding for
451 * real. Finally, call QCBOREncode_FinishGetSize(). Once the length
452 * is obtained, allocate a buffer of that size, call
453 * QCBOREncode_Init() again with the real buffer. Call all the add
454 * functions again and finally, QCBOREncode_Finish() to obtain the
455 * final result. This uses twice the CPU time, but that is usually not
456 * an issue.
457 *
458 * See QCBOREncode_Finish() for how the pointer and length for the
459 * encoded CBOR is returned.
460 *
461 * For practical purposes QCBOR can't output encoded CBOR larger than
462 * @c UINT32_MAX (4GB) even on 64-bit CPUs because the internal
463 * offsets used to track the start of an array/map are 32 bits to
464 * reduce the size of the encoding context.
465 *
466 * A @ref QCBOREncodeContext can be reused over and over as long as
467 * QCBOREncode_Init() is called before each use.
Michael Eckel5c531332020-03-02 01:35:30 +0100468 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700469void
470QCBOREncode_Init(QCBOREncodeContext *pCtx, UsefulBuf Storage);
Michael Eckel5c531332020-03-02 01:35:30 +0100471
472
473/**
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -0800474 * @brief Select preferred serialization mode.
475 *
476 * @param[in] pCtx The encoding context for mode set.
477 *
478 * Setting this mode will cause QCBOR to return an error if an attempt
479 * is made to use one of the methods that produce non-preferred
480 * serialization. It doesn't change anything else as QCBOR produces
481 * preferred serialization by default.
482 *
483 * The non-preferred methods are: QCBOREncode_AddFloatNoPreferred(),
484 * QCBOREncode_AddDoubleNoPreferred(),
485 * QCBOREncode_OpenArrayIndefiniteLength(),
486 * QCBOREncode_CloseArrayIndefiniteLength(),
487 * QCBOREncode_OpenMapIndefiniteLength(),
488 * QCBOREncode_CloseMapIndefiniteLength(), plus those derived from the
489 * above listed.
490 *
491 * This mode is just a user guard to prevent accidentally calling
492 * something that produces non-preferred serialization. It doesn't do
493 * anything but causes errors to occur on attempts to call the above
494 * listed functions. This does nothing if the library is compiled
495 * QCBOR_DISABLE_ENCODE_USAGE_GUARDS.
496 *
497 * See @ref Serialization. It is usually not necessary to set this
498 * mode, but there is usually no disadvantage to setting it. Preferred
499 * Serialization is defined in RFC 8949, section 4.1.
500 */
501static void
502QCBOREncode_SerializationPreferred(QCBOREncodeContext *pCtx);
503
504
505/**
506 * @brief Select CBOR deterministic encoding mode.
507 *
508 * @param[in] pCtx The encoding context for mode set.
509
510 * This causes QCBOR to produce CBOR Deterministic Encoding (CDE).
511 * With CDE, two distant unrelated CBOR encoders will produce exactly
512 * the same encoded CBOR for a given input.
513 *
514 * In addition to doing everything
515 * QCBOREncode_SerializationPreferred() does (including exclusion of
516 * indefinite lengths), this causes maps to be sorted. The map is
517 * sorted automatically when QCBOREncode_CloseMap() is called.
518 * QCBOREncode_CloseMap() becomes equivalent to
519 * QCBOREncode_CloseAndSortMap().
520 *
521 * Note that linking this function causese about 30% more code from
522 * the QCBOR library to be linked. Also, QCBOREncode_CloseMap() runs
523 * slower, but this is probably only of consequence in very
524 * constrained environments.
525 *
526 * See @ref Serialization. It is usually not necessary to set this
527 * mode as determinism is very rarely needed. However it will
528 * usually work with most protocols. CDE is defined in
529 * draft-ietf-cbor-cde.
530 */
531static void
532QCBOREncode_SerializationCDE(QCBOREncodeContext *pCtx);
533
534
535/**
536 * @brief Select "dCBOR" encoding mode.
537 *
538 * @param[in] pCtx The encoding context for mode set.
539 *
540 * This is a superset of CDE. This function does everything
541 * QCBOREncode_SerializationCDE() does. Also it is a super set of
542 * preferred serialization and does everything
543 * QCBOREncode_SerializationPreferred() does.
544 *
545 * The main feature of dCBOR is that there is only one way to serialize a
546 * particular numeric value. This changes the behavior of functions
547 * that add floating-point numbers. If the floating-point number is
548 * whole, it will be encoded as an integer, not a floating-point number.
549 * 0.000 will be encoded as 0x00. Precision is never lost in this
550 * conversion.
551 *
552 * dCBOR also disallows NaN payloads. QCBOR will allow NaN payloads if
553 * you pass a NaN to one of the floating-point encoding functions.
554 * This mode forces all NaNs to the half-precision queit NaN. Also see
555 * QCBOREncode_Allow().
556 *
557 * dCBOR also disallows 65-bit negative integers.
558 *
559 * dCBOR disallows use of any simple type other than true, false and
560 * NULL. In particular it disallows use of "undef" produced by
561 * QCBOREncode_AddUndef().
562 *
563 * See @ref Serialization. Set this mode only if the protocol you are
564 * implementing requires dCBOR. This mode is usually not compatible
565 * with protocols that don't use dCBOR. dCBOR is defined in
566 * draft-mcnally-deterministic-cbor.
567 */
568static void
569QCBOREncode_SerializationdCBOR(QCBOREncodeContext *pCtx);
570
571
572
573
574/** Bit flag to be passed to QCBOREncode_Allow() to allow NaN payloads
575 * to be output by QCBOREncode_AddDouble(),
576 * QCBOREncode_AddDoubleNoPreferred(), QCBORENcode_AddFloat() and
577 * QCBOREncode_AddSingleleNoPreferred. */
578#define QCBOR_ENCODE_ALLOW_NAN_PAYLOAD 0x01
579
580/** Bit flag to be passed to QCBOREncode_Allow() to allow use of
581 * QCBOREncode_AddNegativeUInt64(). */
582#define QCBOR_ENCODE_ALLOW_65_BIG_NEG 0x02
583
584/** Bit flag to be passed to QCBOREncode_Allow() output of less
585 * interoperable values. See @ref QCBOR_ENCODE_ALLOW_NAN_PAYLOAD, and
586 * @ref QCBOR_ENCODE_ALLOW_65_BIG_NEG. */
587#define QCBOR_ENCODE_ALLOW_ALL 0xFF
588
589
590/**
591 * @brief Allow encoding of less-interoperable values.
592 *
593 * @param[in] pCtx The encoding context.
594 * @param[in] uAllow Bit flags indicating what to allow.
595 *
596 * There are a few things in the CBOR standard that are often not
597 * supported and are thus not very interoperable. By default QCBOR
598 * will error if you attempt to output them. This disables that
599 * error.
600 *
601 * See @ref QCBOR_ENCODE_ALLOW_NAN_PAYLOAD and
602 * @ref QCBOR_ENCODE_ALLOW_65_BIG_NEG.
603 *
604 * This does nothing if the library is compiled
605 * QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
606static void
607QCBOREncode_Allow(QCBOREncodeContext *pCtx, uint8_t uAllow);
608
609
610
611/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700612 * @brief Add a signed 64-bit integer to the encoded output.
613 *
614 * @param[in] pCtx The encoding context to add the integer to.
615 * @param[in] nNum The integer to add.
616 *
617 * The integer will be encoded and added to the CBOR output.
618 *
619 * This function figures out the size and the sign and encodes in the
620 * correct minimal CBOR. Specifically, it will select CBOR major type
621 * 0 or 1 based on sign and will encode to 1, 2, 4 or 8 bytes
622 * depending on the value of the integer. Values less than 24
623 * effectively encode to one byte because they are encoded in with the
624 * CBOR major type. This is a neat and efficient characteristic of
625 * CBOR that can be taken advantage of when designing CBOR-based
626 * protocols. If integers like tags can be kept between -23 and 23
627 * they will be encoded in one byte including the major type.
628 *
629 * If you pass a smaller int, say an @c int16_t or a small value, say
630 * 100, the encoding will still be CBOR's most compact that can
631 * represent the value. For example, CBOR always encodes the value 0
632 * as one byte, 0x00. The representation as 0x00 includes
633 * identification of the type as an integer too as the major type for
634 * an integer is 0. See [RFC 8949]
635 * (https://tools.ietf.org/html/rfc8949) Appendix A for more examples
636 * of CBOR encoding. This compact encoding is also preferred
637 * serialization CBOR as per section 34.1 in RFC 8949.
638 *
639 * There are no functions to add @c int16_t or @c int32_t because they
640 * are not necessary because this always encodes to the smallest
641 * number of bytes based on the value (If this code is running on a
642 * 32-bit machine having a way to add 32-bit integers would reduce
643 * code size some).
644 *
645 * If the encoding context is in an error state, this will do
646 * nothing. If an error occurs when adding this integer, the internal
647 * error flag will be set, and the error will be returned when
648 * QCBOREncode_Finish() is called.
649 *
650 * See also QCBOREncode_AddUInt64().
Michael Eckel5c531332020-03-02 01:35:30 +0100651 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700652void
653QCBOREncode_AddInt64(QCBOREncodeContext *pCtx, int64_t nNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100654
Laurence Lundblade3eead482023-12-16 20:53:22 -0700655static void
656QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100657
Laurence Lundblade3eead482023-12-16 20:53:22 -0700658static void
659QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100660
661
662/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700663 * @brief Add an unsigned 64-bit integer to the encoded output.
664 *
665 * @param[in] pCtx The encoding context to add the integer to.
666 * @param[in] uNum The integer to add.
667 *
668 * The integer will be encoded and added to the CBOR output.
669 *
670 * The only reason so use this function is for integers larger than
671 * @c INT64_MAX and smaller than @c UINT64_MAX. Otherwise
672 * QCBOREncode_AddInt64() will work fine.
673 *
674 * Error handling is the same as for QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +0100675 */
Laurence Lundbladecbd7d132024-05-19 11:11:22 -0700676static void
Laurence Lundblade3eead482023-12-16 20:53:22 -0700677QCBOREncode_AddUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100678
Laurence Lundblade3eead482023-12-16 20:53:22 -0700679static void
680QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100681
Laurence Lundblade3eead482023-12-16 20:53:22 -0700682static void
683QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100684
685
686/**
Laurence Lundblade2d493002024-02-01 11:09:17 -0700687 * @brief Add a negative 64-bit integer to encoded output
688 *
689 * @param[in] pCtx The encoding context to add the integer to.
690 * @param[in] uNum The integer to add.
691 *
692 * QCBOREncode_AddInt64() is much better to encode negative integers
693 * than this. What this can do is add integers with one more
694 * significant bit than an int64_t (a "65-bit" integer if you count
695 * the sign as a bit) which is possible because CBOR happens to
696 * support such integers.
697 *
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -0800698 * Because use of this is discouraged. It must be explicitly allowed
699 * by passing @ref QCBOR_ENCODE_ALLOW_65_BIG_NEG to a call to
700 * QCBOREncode_Allow().
701 *
Laurence Lundblade2d493002024-02-01 11:09:17 -0700702 * The actual value encoded is -uNum - 1. That is, give 0 for uNum to
703 * transmit -1, give 1 to transmit -2 and give UINT64_MAX to transmit
704 * -UINT64_MAX-1 (18446744073709551616). The interface is odd like
705 * this so all negative values CBOR can represent can be encoded by
706 * QCBOR (making this a complete CBOR implementation).
707 *
708 * The most negative value QCBOREncode_AddInt64() can encode is
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -0800709 * -9223372036854775808 which is -2^63 or negative 0x800000000000.
710 * This can encode from -9223372036854775809 to -18446744073709551616
711 * or -2^63 - 1 to -2^64. Note that it is not possible to represent
712 * positive or negative 18446744073709551616 in any standard C data
713 * type.
Laurence Lundblade2d493002024-02-01 11:09:17 -0700714 *
715 * Negative integers are normally decoded in QCBOR with type
716 * @ref QCBOR_TYPE_INT64. Integers in the range of -9223372036854775809
717 * to -18446744073709551616 are returned as @ref QCBOR_TYPE_65BIT_NEG_INT.
718 *
719 * WARNING: some CBOR decoders will be unable to decode -2^63 - 1 to
720 * -2^64. Also, most CPUs do not have registers that can represent
721 * this range. If you need 65-bit negative integers, you likely need
722 * negative 66, 67 and 68-bit negative integers so it is likely better
723 * to use CBOR big numbers where you can have any number of bits. See
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -0800724 * QCBOREncode_AddTNegativeBignum() and @ref Serialization.
Laurence Lundblade2d493002024-02-01 11:09:17 -0700725 */
726void
727QCBOREncode_AddNegativeUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
728
729static void
730QCBOREncode_AddNegativeUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum);
731
732static void
733QCBOREncode_AddNegativeUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum);
734
735/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700736 * @brief Add a UTF-8 text string to the encoded output.
737 *
738 * @param[in] pCtx The encoding context to add the text to.
739 * @param[in] Text Pointer and length of text to add.
740 *
741 * The text passed in must be unencoded UTF-8 according to [RFC 3629]
742 * (https://tools.ietf.org/html/rfc3629). There is no NULL
743 * termination. The text is added as CBOR major type 3.
744 *
745 * If called with @c nBytesLen equal to 0, an empty string will be
746 * added. When @c nBytesLen is 0, @c pBytes may be @c NULL.
747 *
748 * Note that the restriction of the buffer length to a @c uint32_t is
749 * entirely intentional as this encoder is not capable of encoding
750 * lengths greater. This limit to 4GB for a text string should not be
751 * a problem.
752 *
753 * Text lines in Internet protocols (on the wire) are delimited by
754 * either a CRLF or just an LF. Officially many protocols specify
755 * CRLF, but implementations often work with either. CBOR type 3 text
756 * can be either line ending, even a mixture of both.
757 *
758 * Operating systems usually have a line end convention. Windows uses
759 * CRLF. Linux and MacOS use LF. Some applications on a given OS may
760 * work with either and some may not.
761 *
762 * The majority of use cases and CBOR protocols using type 3 text will
763 * work with either line ending. However, some use cases or protocols
764 * may not work with either in which case translation to and/or from
765 * the local line end convention, typically that of the OS, is
766 * necessary.
767 *
768 * QCBOR does no line ending translation for type 3 text when encoding
769 * and decoding.
770 *
771 * Error handling is the same as QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +0100772 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700773static void
774QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text);
Michael Eckel5c531332020-03-02 01:35:30 +0100775
Laurence Lundblade3eead482023-12-16 20:53:22 -0700776static void
777QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text);
Michael Eckel5c531332020-03-02 01:35:30 +0100778
Laurence Lundblade3eead482023-12-16 20:53:22 -0700779static void
780QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text);
Michael Eckel5c531332020-03-02 01:35:30 +0100781
782
783/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700784 * @brief Add a UTF-8 text string to the encoded output.
785 *
786 * @param[in] pCtx The encoding context to add the text to.
787 * @param[in] szString Null-terminated text to add.
788 *
789 * This works the same as QCBOREncode_AddText().
Michael Eckel5c531332020-03-02 01:35:30 +0100790 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700791static void
792QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString);
Michael Eckel5c531332020-03-02 01:35:30 +0100793
Laurence Lundblade3eead482023-12-16 20:53:22 -0700794static void
795QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString);
Michael Eckel5c531332020-03-02 01:35:30 +0100796
Laurence Lundblade3eead482023-12-16 20:53:22 -0700797static void
798QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString);
Michael Eckel5c531332020-03-02 01:35:30 +0100799
800
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200801#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Michael Eckel5c531332020-03-02 01:35:30 +0100802/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700803 * @brief Add a double-precision floating-point number to the encoded output.
804 *
805 * @param[in] pCtx The encoding context to add the double to.
806 * @param[in] dNum The double-precision number to add.
807 *
808 * This encodes and outputs a floating-point number. CBOR major type 7
809 * is used.
810 *
811 * This implements preferred serialization, selectively encoding the
812 * double-precision floating-point number as either double-precision,
813 * single-precision or half-precision. Infinity, NaN and 0 are always
814 * encoded as half-precision. If no precision will be lost in the
815 * conversion to half-precision, then it will be converted and
816 * encoded. If not and no precision will be lost in conversion to
817 * single-precision, then it will be converted and encoded. If not,
818 * then no conversion is performed, and it encoded as a
819 * double-precision.
820 *
821 * Half-precision floating-point numbers take up 2 bytes, half that of
822 * single-precision, one quarter of double-precision
823 *
824 * This automatically reduces the size of encoded CBOR, maybe even by
825 * four if most of values are 0, infinity or NaN.
826 *
827 * When decoded, QCBOR will usually return these values as
828 * double-precision.
829 *
830 * It is possible to disable this preferred serialization when compiling
831 * QCBOR. In that case, this functions the same as
832 * QCBOREncode_AddDoubleNoPreferred().
833 *
834 * Error handling is the same as QCBOREncode_AddInt64().
835 *
836 * See also QCBOREncode_AddDoubleNoPreferred(), QCBOREncode_AddFloat()
837 * and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -0800838 *
839 * By default, this will error out on an attempt to encode a NaN with
840 * a payload. See QCBOREncode_Allow() and @ref QCBOR_ENCODE_ALLOW_NAN_PAYLOAD.
Michael Eckel5c531332020-03-02 01:35:30 +0100841 */
Laurence Lundblade8d9e0cd2024-05-25 18:12:19 -0700842static void
Laurence Lundblade3eead482023-12-16 20:53:22 -0700843QCBOREncode_AddDouble(QCBOREncodeContext *pCtx, double dNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100844
Laurence Lundblade3eead482023-12-16 20:53:22 -0700845static void
846QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100847
Laurence Lundblade3eead482023-12-16 20:53:22 -0700848static void
849QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100850
851
852/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700853 * @brief Add a single-precision floating-point number to the encoded output.
854 *
855 * @param[in] pCtx The encoding context to add the double to.
856 * @param[in] fNum The single-precision number to add.
857 *
858 * This is identical to QCBOREncode_AddDouble() except the input is
859 * single-precision.
860 *
861 * See also QCBOREncode_AddDouble(), QCBOREncode_AddDoubleNoPreferred(),
862 * and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
863 */
Laurence Lundblade8d9e0cd2024-05-25 18:12:19 -0700864static void
Laurence Lundblade3eead482023-12-16 20:53:22 -0700865QCBOREncode_AddFloat(QCBOREncodeContext *pCtx, float fNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700866
Laurence Lundblade3eead482023-12-16 20:53:22 -0700867static void
868QCBOREncode_AddFloatToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700869
Laurence Lundblade3eead482023-12-16 20:53:22 -0700870static void
871QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700872
873
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700874/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700875 * @brief Add a double-precision floating-point number without preferred encoding.
876 *
877 * @param[in] pCtx The encoding context to add the double to.
878 * @param[in] dNum The double-precision number to add.
879 *
Laurence Lundblade70fc1252024-05-31 10:57:28 -0700880 * Output a double-precision float straight-through with no checking or
881 * processing for preferred serializtion, dCBOR or other.
Laurence Lundblade3eead482023-12-16 20:53:22 -0700882 *
883 * Error handling is the same as QCBOREncode_AddInt64().
884 *
885 * See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
886 * QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
887 */
Laurence Lundbladecbd7d132024-05-19 11:11:22 -0700888static void
Laurence Lundblade3eead482023-12-16 20:53:22 -0700889QCBOREncode_AddDoubleNoPreferred(QCBOREncodeContext *pCtx, double dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700890
Laurence Lundblade3eead482023-12-16 20:53:22 -0700891static void
892QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700893
Laurence Lundblade3eead482023-12-16 20:53:22 -0700894static void
895QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700896
897
898/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700899 * @brief Add a single-precision floating-point number without preferred encoding.
900 *
901 * @param[in] pCtx The encoding context to add the double to.
902 * @param[in] fNum The single-precision number to add.
903 *
Laurence Lundblade70fc1252024-05-31 10:57:28 -0700904 * Output a single-precision float straight-through with no checking or
905 * processing for preferred serializtion, dCBOR or other.
Laurence Lundblade3eead482023-12-16 20:53:22 -0700906 *
907 * Error handling is the same as QCBOREncode_AddInt64().
908 *
909 * See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
910 * QCBOREncode_AddDoubleNoPreferred() and @ref Floating-Point.
911 */
Laurence Lundbladecbd7d132024-05-19 11:11:22 -0700912static void
Laurence Lundblade3eead482023-12-16 20:53:22 -0700913QCBOREncode_AddFloatNoPreferred(QCBOREncodeContext *pCtx, float fNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700914
Laurence Lundblade3eead482023-12-16 20:53:22 -0700915static void
916QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700917
Laurence Lundblade3eead482023-12-16 20:53:22 -0700918static void
919QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float fNum);
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200920#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700921
922
Michael Eckel5c531332020-03-02 01:35:30 +0100923/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700924 * @brief Add an optional tag.
925 *
926 * @param[in] pCtx The encoding context to add the tag to.
927 * @param[in] uTag The tag to add
928 *
929 * This outputs a CBOR major type 6 item that tags the next data item
930 * that is output usually to indicate it is some new data type.
931 *
932 * For many of the common standard tags, a function to encode data
933 * using it is provided and this is not needed. For example,
934 * QCBOREncode_AddDateEpoch() already exists to output integers
935 * representing dates with the right tag.
936 *
937 * The tag is applied to the next data item added to the encoded
938 * output. That data item that is to be tagged can be of any major
939 * CBOR type. Any number of tags can be added to a data item by
940 * calling this multiple times before the data item is added.
941 *
942 * See @ref Tags-Overview for discussion of creating new non-standard
943 * tags. See QCBORDecode_GetNext() for discussion of decoding custom
944 * tags.
Michael Eckel5c531332020-03-02 01:35:30 +0100945 */
Laurence Lundbladecbd7d132024-05-19 11:11:22 -0700946static void
Laurence Lundblade3eead482023-12-16 20:53:22 -0700947QCBOREncode_AddTag(QCBOREncodeContext *pCtx, uint64_t uTag);
Laurence Lundblade46d63e92021-05-13 11:37:10 -0700948
949
Michael Eckel5c531332020-03-02 01:35:30 +0100950/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700951 * @brief Add an epoch-based date.
952 *
953 * @param[in] pCtx The encoding context to add the date to.
954 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
955 * @ref QCBOR_ENCODE_AS_BORROWED.
956 * @param[in] nDate Number of seconds since 1970-01-01T00:00Z
957 * in UTC time.
958 *
959 * As per RFC 8949 this is similar to UNIX/Linux/POSIX dates. This is
960 * the most compact way to specify a date and time in CBOR. Note that
961 * this is always UTC and does not include the time zone. Use
962 * QCBOREncode_AddDateString() if you want to include the time zone.
963 *
964 * The preferred integer serialization rules apply here so the date will be
965 * encoded in a minimal number of bytes. Until about the year 2106
966 * these dates will encode in 6 bytes -- one byte for the tag, one
967 * byte for the type and 4 bytes for the integer. After that it will
968 * encode to 10 bytes.
969 *
970 * Negative values are supported for dates before 1970.
971 *
972 * If you care about leap-seconds and that level of accuracy, make sure
973 * the system you are running this code on does it correctly. This code
974 * just takes the value passed in.
975 *
976 * This implementation cannot encode fractional seconds using float or
977 * double even though that is allowed by CBOR, but you can encode them
978 * if you want to by calling QCBOREncode_AddTag() and QCBOREncode_AddDouble().
979 *
980 * Error handling is the same as QCBOREncode_AddInt64().
981 *
982 * See also QCBOREncode_AddTDaysEpoch().
Michael Eckel5c531332020-03-02 01:35:30 +0100983 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700984static void
985QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pCtx,
986 uint8_t uTagRequirement,
987 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100988
Laurence Lundblade3eead482023-12-16 20:53:22 -0700989static void
990QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pCtx,
991 const char *szLabel,
992 uint8_t uTagRequirement,
993 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100994
Laurence Lundblade3eead482023-12-16 20:53:22 -0700995static void
996QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pCtx,
997 int64_t nLabel,
998 uint8_t uTagRequirement,
999 int64_t nDate);
1000
1001
1002static void
1003QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx,
1004 int64_t nDate);
1005
1006static void
1007QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx,
1008 const char *szLabel,
1009 int64_t nDate);
1010
1011static void
1012QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx,
1013 int64_t nLabel,
1014 int64_t nDate);
1015
Michael Eckel5c531332020-03-02 01:35:30 +01001016
1017
Michael Eckel5c531332020-03-02 01:35:30 +01001018/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001019 * @brief Add an epoch-based day-count date.
1020 *
1021 * @param[in] pCtx The encoding context to add the date to.
1022 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1023 * @ref QCBOR_ENCODE_AS_BORROWED.
1024 * @param[in] nDays Number of days before or after 1970-01-0.
1025 *
1026 * This date format is described in
1027 * [RFC 8943] (https://tools.ietf.org/html/rfc8943).
1028 *
1029 * The preferred integer serialization rules apply here so the date
1030 * will be encoded in a minimal number of bytes. Until about the year
1031 * 2149 these dates will encode in 4 bytes -- one byte for the tag,
1032 * one byte for the type and 2 bytes for the integer.
1033 *
1034 * See also QCBOREncode_AddTDateEpoch().
1035 */
1036static void
1037QCBOREncode_AddTDaysEpoch(QCBOREncodeContext *pCtx,
1038 uint8_t uTagRequirement,
1039 int64_t nDays);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001040
Laurence Lundblade3eead482023-12-16 20:53:22 -07001041static void
1042QCBOREncode_AddTDaysEpochToMapSZ(QCBOREncodeContext *pCtx,
1043 const char *szLabel,
1044 uint8_t uTagRequirement,
1045 int64_t nDays);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001046
Laurence Lundblade3eead482023-12-16 20:53:22 -07001047static void
1048QCBOREncode_AddTDaysEpochToMapN(QCBOREncodeContext *pCtx,
1049 int64_t nLabel,
1050 uint8_t uTagRequirement,
1051 int64_t nDays);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001052
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001053
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001054
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001055
Laurence Lundblade3eead482023-12-16 20:53:22 -07001056/**
1057 * @brief Add a byte string to the encoded output.
1058 *
1059 * @param[in] pCtx The encoding context to add the bytes to.
1060 * @param[in] Bytes Pointer and length of the input data.
1061 *
1062 * Simply adds the bytes to the encoded output as CBOR major type 2.
1063 *
1064 * If called with @c Bytes.len equal to 0, an empty string will be
1065 * added. When @c Bytes.len is 0, @c Bytes.ptr may be @c NULL.
1066 *
1067 * Error handling is the same as QCBOREncode_AddInt64().
1068 */
1069static void
1070QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001071
Laurence Lundblade3eead482023-12-16 20:53:22 -07001072static void
1073QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
1074
1075static void
1076QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
1077
1078
1079/**
1080 * @brief Set up to write a byte string value directly to encoded output.
1081 *
1082 * @param[in] pCtx The encoding context to add the bytes to.
1083 * @param[out] pPlace Pointer and length of place to write byte string value.
1084 *
1085 * QCBOREncode_AddBytes() is the normal way to encode a byte string.
1086 * This is for special cases and by passes some of the pointer safety.
1087 *
1088 * The purpose of this is to output the bytes that make up a byte
1089 * string value directly to the QCBOR output buffer so you don't need
1090 * to have a copy of it in memory. This is particularly useful if the
1091 * byte string is large, for example, the encrypted payload of a
1092 * COSE_Encrypt message. The payload encryption algorithm can output
1093 * directly to the encoded CBOR buffer, perhaps by making it the
1094 * output buffer for some function (e.g. symmetric encryption) or by
1095 * multiple writes.
1096 *
1097 * The pointer in @c pPlace is where to start writing. Writing is just
1098 * copying bytes to the location by the pointer in \c pPlace. Writing
1099 * past the length in @c pPlace will be writing off the end of the
1100 * output buffer.
1101 *
1102 * If there is no room in the output buffer @ref NULLUsefulBuf will be
1103 * returned and there is no need to call QCBOREncode_CloseBytes().
1104 *
1105 * The byte string must be closed by calling QCBOREncode_CloseBytes().
1106 *
1107 * Warning: this bypasses some of the usual checks provided by QCBOR
1108 * against writing off the end of the encoded output buffer.
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001109 */
1110void
1111QCBOREncode_OpenBytes(QCBOREncodeContext *pCtx, UsefulBuf *pPlace);
1112
1113static void
Laurence Lundblade3eead482023-12-16 20:53:22 -07001114QCBOREncode_OpenBytesInMapSZ(QCBOREncodeContext *pCtx,
1115 const char *szLabel,
1116 UsefulBuf *pPlace);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001117
1118static void
Laurence Lundblade3eead482023-12-16 20:53:22 -07001119QCBOREncode_OpenBytesInMapN(QCBOREncodeContext *pCtx,
1120 int64_t nLabel,
1121 UsefulBuf *pPlace);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001122
1123
1124/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001125 * @brief Close out a byte string written directly to encoded output.
1126 *
1127 * @param[in] pCtx The encoding context to add the bytes to.
1128 * @param[out] uAmount The number of bytes written, the length of the
1129 * byte string.
1130 *
1131 * This closes out a call to QCBOREncode_OpenBytes(). This inserts a
1132 * CBOR header at the front of the byte string value to make it a
1133 * well-formed byte string.
1134 *
1135 * If there was no call to QCBOREncode_OpenBytes() then @ref
1136 * QCBOR_ERR_TOO_MANY_CLOSES is set.
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001137 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001138void
1139QCBOREncode_CloseBytes(QCBOREncodeContext *pCtx, size_t uAmount);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06001140
1141
1142/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001143 * @brief Add a binary UUID to the encoded output.
1144 *
1145 * @param[in] pCtx The encoding context to add the UUID to.
1146 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1147 * @ref QCBOR_ENCODE_AS_BORROWED.
1148 * @param[in] Bytes Pointer and length of the binary UUID.
1149 *
1150 * A binary UUID as defined in [RFC 4122]
1151 * (https://tools.ietf.org/html/rfc4122) is added to the output.
1152 *
1153 * It is output as CBOR major type 2, a binary string, with tag @ref
1154 * CBOR_TAG_BIN_UUID indicating the binary string is a UUID.
Michael Eckel5c531332020-03-02 01:35:30 +01001155 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001156static void
1157QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pCtx,
1158 uint8_t uTagRequirement,
1159 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001160
Laurence Lundblade3eead482023-12-16 20:53:22 -07001161static void
1162QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pCtx,
1163 const char *szLabel,
1164 uint8_t uTagRequirement,
1165 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001166
Laurence Lundblade3eead482023-12-16 20:53:22 -07001167static void
1168QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pCtx,
1169 int64_t nLabel,
1170 uint8_t uTagRequirement,
1171 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001172
1173
Laurence Lundblade3eead482023-12-16 20:53:22 -07001174static void
1175QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001176
Laurence Lundblade3eead482023-12-16 20:53:22 -07001177static void
1178QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001179
Laurence Lundblade3eead482023-12-16 20:53:22 -07001180static void
1181QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001182
1183
1184/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001185 * @brief Add a positive big number to the encoded output.
1186 *
1187 * @param[in] pCtx The encoding context to add the big number to.
1188 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1189 * @ref QCBOR_ENCODE_AS_BORROWED.
1190 * @param[in] Bytes Pointer and length of the big number.
1191 *
1192 * Big numbers are integers larger than 64-bits. Their format is
1193 * described in [RFC 8949] (https://tools.ietf.org/html/rfc8949).
1194 *
1195 * It is output as CBOR major type 2, a binary string, with tag
1196 * @ref CBOR_TAG_POS_BIGNUM indicating the binary string is a positive
1197 * big number.
1198 *
1199 * Often big numbers are used to represent cryptographic keys,
1200 * however, COSE which defines representations for keys chose not to
1201 * use this particular type.
Michael Eckel5c531332020-03-02 01:35:30 +01001202 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001203static void
1204QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pCtx,
1205 uint8_t uTagRequirement,
1206 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001207
Laurence Lundblade3eead482023-12-16 20:53:22 -07001208static void
1209QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pCtx,
1210 const char *szLabel,
1211 uint8_t uTagRequirement,
1212 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001213
Laurence Lundblade3eead482023-12-16 20:53:22 -07001214static void
1215QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pCtx,
1216 int64_t nLabel,
1217 uint8_t uTagRequirement,
1218 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001219
1220
Laurence Lundblade3eead482023-12-16 20:53:22 -07001221static void
1222QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx,
1223 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001224
Laurence Lundblade3eead482023-12-16 20:53:22 -07001225static void
1226QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx,
1227 const char *szLabel,
1228 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001229
Laurence Lundblade3eead482023-12-16 20:53:22 -07001230static void
1231QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx,
1232 int64_t nLabel,
1233 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001234
1235
1236/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001237 * @brief Add a negative big number to the encoded output.
1238 *
1239 * @param[in] pCtx The encoding context to add the big number to.
1240 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1241 * @ref QCBOR_ENCODE_AS_BORROWED.
1242 * @param[in] Bytes Pointer and length of the big number.
1243 *
1244 * Big numbers are integers larger than 64-bits. Their format is
1245 * described in [RFC 8949] (https://tools.ietf.org/html/rfc8949).
1246 *
1247 * It is output as CBOR major type 2, a binary string, with tag
1248 * @ref CBOR_TAG_NEG_BIGNUM indicating the binary string is a negative
1249 * big number.
1250 *
1251 * Often big numbers are used to represent cryptographic keys,
1252 * however, COSE which defines representations for keys chose not to
1253 * use this particular type.
Michael Eckel5c531332020-03-02 01:35:30 +01001254 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001255static void
1256QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pCtx,
1257 uint8_t uTagRequirement,
1258 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001259
Laurence Lundblade3eead482023-12-16 20:53:22 -07001260static void
1261QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pCtx,
1262 const char *szLabel,
1263 uint8_t uTagRequirement,
1264 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001265
Laurence Lundblade3eead482023-12-16 20:53:22 -07001266static void
1267QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pCtx,
1268 int64_t nLabel,
1269 uint8_t uTagRequirement,
1270 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001271
1272
Laurence Lundblade3eead482023-12-16 20:53:22 -07001273static void
1274QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx,
1275 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001276
Laurence Lundblade3eead482023-12-16 20:53:22 -07001277static void
1278QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx,
1279 const char *szLabel,
1280 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001281
Laurence Lundblade3eead482023-12-16 20:53:22 -07001282static void
1283QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx,
1284 int64_t nLabel,
1285 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001286
1287
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07001288#ifndef QCBOR_DISABLE_EXP_AND_MANTISSA
Michael Eckel5c531332020-03-02 01:35:30 +01001289/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001290 * @brief Add a decimal fraction to the encoded output.
1291 *
1292 * @param[in] pCtx Encoding context to add the decimal fraction to.
1293 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1294 * @ref QCBOR_ENCODE_AS_BORROWED.
1295 * @param[in] nMantissa The mantissa.
1296 * @param[in] nBase10Exponent The exponent.
1297 *
1298 * The value is nMantissa * 10 ^ nBase10Exponent.
1299 *
1300 * A decimal fraction is good for exact representation of some values
1301 * that can't be represented exactly with standard C (IEEE 754)
1302 * floating-point numbers. Much larger and much smaller numbers can
1303 * also be represented than floating-point because of the larger
1304 * number of bits in the exponent.
1305 *
1306 * The decimal fraction is conveyed as two integers, a mantissa and a
1307 * base-10 scaling factor.
1308 *
1309 * For example, 273.15 is represented by the two integers 27315 and -2.
1310 *
1311 * The exponent and mantissa have the range from @c INT64_MIN to
1312 * @c INT64_MAX for both encoding and decoding (CBOR allows
1313 * @c -UINT64_MAX to @c UINT64_MAX, but this implementation doesn't
1314 * support this range to reduce code size and interface complexity a
1315 * little).
1316 *
1317 * CBOR Preferred serialization of the integers is used, thus they
1318 * will be encoded in the smallest number of bytes possible.
1319 *
1320 * See also QCBOREncode_AddDecimalFractionBigNum() for a decimal
1321 * fraction with arbitrarily large precision and
1322 * QCBOREncode_AddBigFloat().
1323 *
1324 * There is no representation of positive or negative infinity or NaN
1325 * (Not a Number). Use QCBOREncode_AddDouble() to encode them.
1326 *
1327 * See @ref expAndMantissa for decoded representation.
Michael Eckel5c531332020-03-02 01:35:30 +01001328 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001329static void
1330QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pCtx,
1331 uint8_t uTagRequirement,
1332 int64_t nMantissa,
1333 int64_t nBase10Exponent);
1334
1335static void
1336QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pCtx,
1337 const char *szLabel,
1338 uint8_t uTagRequirement,
1339 int64_t nMantissa,
1340 int64_t nBase10Exponent);
1341
1342static void
1343QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pCtx,
1344 int64_t nLabel,
1345 uint8_t uTagRequirement,
1346 int64_t nMantissa,
1347 int64_t nBase10Exponent);
1348
1349
1350static void
1351QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pCtx,
1352 int64_t nMantissa,
1353 int64_t nBase10Exponent);
1354
1355static void
1356QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pCtx,
1357 const char *szLabel,
1358 int64_t nMantissa,
1359 int64_t nBase10Exponent);
1360
1361static void
1362QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pCtx,
1363 int64_t nLabel,
1364 int64_t nMantissa,
1365 int64_t nBase10Exponent);
1366
1367
1368/**
1369 * @brief Add a decimal fraction with a big number mantissa to the encoded output.
1370 *
1371 * @param[in] pCtx Encoding context to add the decimal fraction to.
1372 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1373 * @ref QCBOR_ENCODE_AS_BORROWED.
1374 * @param[in] Mantissa The mantissa.
1375 * @param[in] bIsNegative false if mantissa is positive, true if negative.
1376 * @param[in] nBase10Exponent The exponent.
1377 *
1378 * This is the same as QCBOREncode_AddDecimalFraction() except the
1379 * mantissa is a big number (See QCBOREncode_AddPositiveBignum())
1380 * allowing for arbitrarily large precision.
1381 *
1382 * See @ref expAndMantissa for decoded representation.
1383 */
1384static void
1385QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pCtx,
1386 uint8_t uTagRequirement,
1387 UsefulBufC Mantissa,
1388 bool bIsNegative,
1389 int64_t nBase10Exponent);
1390
1391static void
1392QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
1393 const char *szLabel,
1394 uint8_t uTagRequirement,
1395 UsefulBufC Mantissa,
1396 bool bIsNegative,
1397 int64_t nBase10Exponent);
1398
1399static void
1400QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
1401 int64_t nLabel,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001402 uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07001403 UsefulBufC Mantissa,
1404 bool bIsNegative,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001405 int64_t nBase10Exponent);
1406
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001407
Laurence Lundblade3eead482023-12-16 20:53:22 -07001408static void
1409QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pCtx,
1410 UsefulBufC Mantissa,
1411 bool bIsNegative,
1412 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001413
Laurence Lundblade3eead482023-12-16 20:53:22 -07001414static void
1415QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001416 const char *szLabel,
Laurence Lundblade3eead482023-12-16 20:53:22 -07001417 UsefulBufC Mantissa,
1418 bool bIsNegative,
1419 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001420
Laurence Lundblade3eead482023-12-16 20:53:22 -07001421static void
1422QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001423 int64_t nLabel,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001424 UsefulBufC Mantissa,
1425 bool bIsNegative,
Laurence Lundblade3eead482023-12-16 20:53:22 -07001426 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001427
Laurence Lundblade3eead482023-12-16 20:53:22 -07001428/**
1429 * @brief Add a big floating-point number to the encoded output.
1430 *
1431 * @param[in] pCtx The encoding context to add the bigfloat to.
1432 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1433 * @ref QCBOR_ENCODE_AS_BORROWED.
1434 * @param[in] nMantissa The mantissa.
1435 * @param[in] nBase2Exponent The exponent.
1436 *
1437 * The value is nMantissa * 2 ^ nBase2Exponent.
1438 *
1439 * "Bigfloats", as CBOR terms them, are similar to IEEE floating-point
1440 * numbers in having a mantissa and base-2 exponent, but they are not
1441 * supported by hardware or encoded the same. They explicitly use two
1442 * CBOR-encoded integers to convey the mantissa and exponent, each of
1443 * which can be 8, 16, 32 or 64 bits. With both the mantissa and
1444 * exponent 64 bits they can express more precision and a larger range
1445 * than an IEEE double floating-point number. See
1446 * QCBOREncode_AddBigFloatBigNum() for even more precision.
1447 *
1448 * For example, 1.5 would be represented by a mantissa of 3 and an
1449 * exponent of -1.
1450 *
1451 * The exponent and mantissa have the range from @c INT64_MIN to
1452 * @c INT64_MAX for both encoding and decoding (CBOR allows @c
1453 * -UINT64_MAX to @c UINT64_MAX, but this implementation doesn't
1454 * support this range to reduce code size and interface complexity a
1455 * little).
1456 *
1457 * CBOR preferred serialization of the integers is used, thus they will
1458 * be encoded in the smallest number of bytes possible.
1459 *
1460 * This can also be used to represent floating-point numbers in
1461 * environments that don't support IEEE 754.
1462 *
1463 * See @ref expAndMantissa for decoded representation.
1464 */
1465static void
1466QCBOREncode_AddTBigFloat(QCBOREncodeContext *pCtx,
1467 uint8_t uTagRequirement,
1468 int64_t nMantissa,
1469 int64_t nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001470
Laurence Lundblade3eead482023-12-16 20:53:22 -07001471static void
1472QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pCtx,
1473 const char *szLabel,
1474 uint8_t uTagRequirement,
1475 int64_t nMantissa,
1476 int64_t nBase2Exponent);
1477
1478static void
1479QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pCtx,
1480 int64_t nLabel,
1481 uint8_t uTagRequirement,
1482 int64_t nMantissa,
1483 int64_t nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001484
1485
Laurence Lundblade3eead482023-12-16 20:53:22 -07001486static void
1487QCBOREncode_AddBigFloat(QCBOREncodeContext *pCtx,
1488 int64_t nMantissa,
1489 int64_t nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01001490
Laurence Lundblade3eead482023-12-16 20:53:22 -07001491static void
1492QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pCtx,
1493 const char *szLabel,
1494 int64_t nMantissa,
1495 int64_t nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01001496
Laurence Lundblade3eead482023-12-16 20:53:22 -07001497static void
1498QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pCtx,
1499 int64_t nLabel,
1500 int64_t nMantissa,
1501 int64_t nBase2Exponent);
1502
1503/**
1504 * @brief Add a big floating-point number with a big number mantissa to
1505 * the encoded output.
1506 *
1507 * @param[in] pCtx The encoding context to add the bigfloat to.
1508 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1509 * @ref QCBOR_ENCODE_AS_BORROWED.
1510 * @param[in] Mantissa The mantissa.
1511 * @param[in] bIsNegative false if mantissa is positive, true if negative.
1512 * @param[in] nBase2Exponent The exponent.
1513 *
1514 * This is the same as QCBOREncode_AddBigFloat() except the mantissa
1515 * is a big number (See QCBOREncode_AddPositiveBignum()) allowing for
1516 * arbitrary precision.
1517 *
1518 * See @ref expAndMantissa for decoded representation.
1519 */
1520static void
1521QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pCtx,
1522 uint8_t uTagRequirement,
1523 UsefulBufC Mantissa,
1524 bool bIsNegative,
1525 int64_t nBase2Exponent);
1526
1527static void
1528QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pCtx,
1529 const char *szLabel,
1530 uint8_t uTagRequirement,
1531 UsefulBufC Mantissa,
1532 bool bIsNegative,
1533 int64_t nBase2Exponent);
1534
1535static void
1536QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1537 int64_t nLabel,
1538 uint8_t uTagRequirement,
1539 UsefulBufC Mantissa,
1540 bool bIsNegative,
1541 int64_t nBase2Exponent);
1542
1543
1544static void
1545QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pCtx,
1546 UsefulBufC Mantissa,
1547 bool bIsNegative,
1548 int64_t nBase2Exponent);
1549
1550static void
1551QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pCtx,
1552 const char *szLabel,
1553 UsefulBufC Mantissa,
1554 bool bIsNegative,
1555 int64_t nBase2Exponent);
1556
1557static void
1558QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1559 int64_t nLabel,
1560 UsefulBufC Mantissa,
1561 bool bIsNegative,
1562 int64_t nBase2Exponent);
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07001563#endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
Michael Eckel5c531332020-03-02 01:35:30 +01001564
1565
1566/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001567 * @brief Add a text URI to the encoded output.
1568 *
1569 * @param[in] pCtx The encoding context to add the URI to.
1570 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1571 * @ref QCBOR_ENCODE_AS_BORROWED.
1572 * @param[in] URI Pointer and length of the URI.
1573 *
1574 * The format of URI must be per [RFC 3986]
1575 * (https://tools.ietf.org/html/rfc3986).
1576 *
1577 * It is output as CBOR major type 3, a text string, with tag @ref
1578 * CBOR_TAG_URI indicating the text string is a URI.
1579 *
1580 * A URI in a NULL-terminated string, @c szURI, can be easily added with
1581 * this code:
1582 *
1583 * QCBOREncode_AddURI(pCtx, UsefulBuf_FromSZ(szURI));
Michael Eckel5c531332020-03-02 01:35:30 +01001584 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001585static void
1586QCBOREncode_AddTURI(QCBOREncodeContext *pCtx,
1587 uint8_t uTagRequirement,
1588 UsefulBufC URI);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001589
Laurence Lundblade3eead482023-12-16 20:53:22 -07001590static void
1591QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pCtx,
1592 const char *szLabel,
1593 uint8_t uTagRequirement,
1594 UsefulBufC URI);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001595
Laurence Lundblade3eead482023-12-16 20:53:22 -07001596static void
1597QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pCtx,
1598 int64_t nLabel,
1599 uint8_t uTagRequirement,
1600 UsefulBufC URI);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001601
1602
Laurence Lundblade3eead482023-12-16 20:53:22 -07001603static void
1604QCBOREncode_AddURI(QCBOREncodeContext *pCtx,
1605 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001606
Laurence Lundblade3eead482023-12-16 20:53:22 -07001607static void
1608QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx,
1609 const char *szLabel,
1610 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001611
Laurence Lundblade3eead482023-12-16 20:53:22 -07001612static void
1613QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx,
1614 int64_t nLabel,
1615 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001616
1617
1618/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001619 * @brief Add Base64-encoded text to encoded output.
1620 *
1621 * @param[in] pCtx The encoding context to add the base-64 text to.
1622 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1623 * @ref QCBOR_ENCODE_AS_BORROWED.
1624 * @param[in] B64Text Pointer and length of the base-64 encoded text.
1625 *
1626 * The text content is Base64 encoded data per [RFC 4648]
1627 * (https://tools.ietf.org/html/rfc4648).
1628 *
1629 * It is output as CBOR major type 3, a text string, with tag @ref
1630 * CBOR_TAG_B64 indicating the text string is Base64 encoded.
Michael Eckel5c531332020-03-02 01:35:30 +01001631 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001632static void
1633QCBOREncode_AddTB64Text(QCBOREncodeContext *pCtx,
1634 uint8_t uTagRequirement,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001635 UsefulBufC B64Text);
1636
Laurence Lundblade3eead482023-12-16 20:53:22 -07001637static void
1638QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pCtx,
1639 const char *szLabel,
1640 uint8_t uTagRequirement,
1641 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001642
Laurence Lundblade3eead482023-12-16 20:53:22 -07001643static void
1644QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pCtx,
1645 int64_t nLabel,
1646 uint8_t uTagRequirement,
1647 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001648
1649
Laurence Lundblade3eead482023-12-16 20:53:22 -07001650static void
1651QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx,
1652 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001653
Laurence Lundblade3eead482023-12-16 20:53:22 -07001654static void
1655QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx,
1656 const char *szLabel,
1657 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001658
Laurence Lundblade3eead482023-12-16 20:53:22 -07001659static void
1660QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx,
1661 int64_t nLabel,
1662 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001663
1664
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001665
Michael Eckel5c531332020-03-02 01:35:30 +01001666/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001667 * @brief Add base64url encoded data to encoded output.
1668 *
1669 * @param[in] pCtx The encoding context to add the base64url to.
1670 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1671 * @ref QCBOR_ENCODE_AS_BORROWED.
1672 * @param[in] B64Text Pointer and length of the base64url encoded text.
1673 *
1674 * The text content is base64URL encoded text as per [RFC 4648]
1675 * (https://tools.ietf.org/html/rfc4648).
1676 *
1677 * It is output as CBOR major type 3, a text string, with tag
1678 * @ref CBOR_TAG_B64URL indicating the text string is a Base64url
1679 * encoded.
Michael Eckel5c531332020-03-02 01:35:30 +01001680 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001681static void
1682QCBOREncode_AddTB64URLText(QCBOREncodeContext *pCtx,
1683 uint8_t uTagRequirement,
1684 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001685
Laurence Lundblade3eead482023-12-16 20:53:22 -07001686static void
1687QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pCtx,
1688 const char *szLabel,
1689 uint8_t uTagRequirement,
1690 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001691
Laurence Lundblade3eead482023-12-16 20:53:22 -07001692static void
1693QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pCtx,
1694 int64_t nLabel,
1695 uint8_t uTagRequirement,
1696 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001697
1698
Laurence Lundblade3eead482023-12-16 20:53:22 -07001699static void
1700QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx,
1701 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001702
Laurence Lundblade3eead482023-12-16 20:53:22 -07001703static void
1704QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx,
1705 const char *szLabel,
1706 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001707
Laurence Lundblade3eead482023-12-16 20:53:22 -07001708static void
1709QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx,
1710 int64_t nLabel,
1711 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001712
1713
1714/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001715 * @brief Add Perl Compatible Regular Expression.
1716 *
1717 * @param[in] pCtx Encoding context to add the regular expression to.
1718 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1719 * @ref QCBOR_ENCODE_AS_BORROWED.
1720 * @param[in] Regex Pointer and length of the regular expression.
1721 *
1722 * The text content is Perl Compatible Regular
1723 * Expressions (PCRE) / JavaScript syntax [ECMA262].
1724 *
1725 * It is output as CBOR major type 3, a text string, with tag @ref
1726 * CBOR_TAG_REGEX indicating the text string is a regular expression.
Michael Eckel5c531332020-03-02 01:35:30 +01001727 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001728static void
1729QCBOREncode_AddTRegex(QCBOREncodeContext *pCtx,
1730 uint8_t uTagRequirement,
1731 UsefulBufC Regex);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001732
Laurence Lundblade3eead482023-12-16 20:53:22 -07001733static void
1734QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pCtx,
1735 const char *szLabel,
1736 uint8_t uTagRequirement,
1737 UsefulBufC Regex);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001738
Laurence Lundblade3eead482023-12-16 20:53:22 -07001739static void
1740QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pCtx,
1741 int64_t nLabel,
1742 uint8_t uTagRequirement,
1743 UsefulBufC Regex);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001744
1745
Laurence Lundblade3eead482023-12-16 20:53:22 -07001746static void
1747QCBOREncode_AddRegex(QCBOREncodeContext *pCtx,
1748 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001749
Laurence Lundblade3eead482023-12-16 20:53:22 -07001750static void
1751QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx,
1752 const char *szLabel,
1753 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001754
Laurence Lundblade3eead482023-12-16 20:53:22 -07001755static void
1756QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx,
1757 int64_t nLabel,
1758 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001759
1760
1761/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001762 * @brief MIME encoded data to the encoded output.
1763 *
1764 * @param[in] pCtx The encoding context to add the MIME data to.
1765 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1766 * @ref QCBOR_ENCODE_AS_BORROWED.
1767 * @param[in] MIMEData Pointer and length of the MIME data.
1768 *
1769 * The text content is in MIME format per [RFC 2045]
1770 * (https://tools.ietf.org/html/rfc2045) including the headers.
1771 *
1772 * It is output as CBOR major type 2, a binary string, with tag
1773 * @ref CBOR_TAG_BINARY_MIME indicating the string is MIME data. This
1774 * outputs tag 257, not tag 36, as it can carry any type of MIME
1775 * binary, 7-bit, 8-bit, quoted-printable and base64 where tag 36
1776 * cannot.
1777 *
1778 * Previous versions of QCBOR, those before spiffy decode, output tag
1779 * 36. Decoding supports both tag 36 and 257. (if the old behavior
1780 * with tag 36 is needed, copy the inline functions below and change
1781 * the tag number).
1782 *
1783 * See also QCBORDecode_GetMIMEMessage() and
1784 * @ref QCBOR_TYPE_BINARY_MIME.
1785 *
1786 * This does no translation of line endings. See QCBOREncode_AddText()
1787 * for a discussion of line endings in CBOR.
Michael Eckel5c531332020-03-02 01:35:30 +01001788 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001789static void
1790QCBOREncode_AddTMIMEData(QCBOREncodeContext *pCtx,
1791 uint8_t uTagRequirement,
1792 UsefulBufC MIMEData);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001793
Laurence Lundblade3eead482023-12-16 20:53:22 -07001794static void
1795QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pCtx,
1796 const char *szLabel,
1797 uint8_t uTagRequirement,
1798 UsefulBufC MIMEData);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001799
Laurence Lundblade3eead482023-12-16 20:53:22 -07001800static void
1801QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pCtx,
1802 int64_t nLabel,
1803 uint8_t uTagRequirement,
1804 UsefulBufC MIMEData);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001805
1806
Laurence Lundblade3eead482023-12-16 20:53:22 -07001807static void
1808QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx,
1809 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001810
Laurence Lundblade3eead482023-12-16 20:53:22 -07001811static void
1812QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx,
1813 const char *szLabel,
1814 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001815
Laurence Lundblade3eead482023-12-16 20:53:22 -07001816static void
1817QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx,
1818 int64_t nLabel,
1819 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001820
1821
1822/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001823 * @brief Add an RFC 3339 date string
1824 *
1825 * @param[in] pCtx The encoding context to add the date to.
1826 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1827 * @ref QCBOR_ENCODE_AS_BORROWED.
1828 * @param[in] szDate Null-terminated string with date to add.
1829 *
1830 * The string szDate should be in the form of [RFC 3339]
1831 * (https://tools.ietf.org/html/rfc3339) as defined by section 3.3 in
1832 * [RFC 4287] (https://tools.ietf.org/html/rfc4287). This is as
1833 * described in section 3.4.1 in [RFC 8949]
1834 * (https://tools.ietf.org/html/rfc8949).
1835 *
1836 * Note that this function doesn't validate the format of the date
1837 * string at all. If you add an incorrect format date string, the
1838 * generated CBOR will be incorrect and the receiver may not be able
1839 * to handle it.
1840 *
1841 * Error handling is the same as QCBOREncode_AddInt64().
1842 *
1843 * See also QCBOREncode_AddTDayString().
Michael Eckel5c531332020-03-02 01:35:30 +01001844 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001845static void
1846QCBOREncode_AddTDateString(QCBOREncodeContext *pCtx,
1847 uint8_t uTagRequirement,
1848 const char *szDate);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001849
Laurence Lundblade3eead482023-12-16 20:53:22 -07001850static void
1851QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pCtx,
1852 const char *szLabel,
1853 uint8_t uTagRequirement,
1854 const char *szDate);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001855
Laurence Lundblade3eead482023-12-16 20:53:22 -07001856static void
1857QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pCtx,
1858 int64_t nLabel,
1859 uint8_t uTagRequirement,
1860 const char *szDate);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001861
1862
Laurence Lundblade3eead482023-12-16 20:53:22 -07001863static void
1864QCBOREncode_AddDateString(QCBOREncodeContext *pCtx,
1865 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001866
Laurence Lundblade3eead482023-12-16 20:53:22 -07001867static void
1868QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx,
1869 const char *szLabel,
1870 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001871
Laurence Lundblade3eead482023-12-16 20:53:22 -07001872static void
1873QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx,
1874 int64_t nLabel,
1875 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001876
Laurence Lundblade46d63e92021-05-13 11:37:10 -07001877
1878/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001879 * @brief Add a date-only string.
1880 *
1881 * @param[in] pCtx The encoding context to add the date to.
1882 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1883 * @ref QCBOR_ENCODE_AS_BORROWED.
1884 * @param[in] szDate Null-terminated string with date to add.
1885 *
1886 * This date format is described in
1887 * [RFC 8943] (https://tools.ietf.org/html/rfc8943), but that mainly
1888 * references RFC 3339. The string szDate must be in the forrm
1889 * specified the ABNF for a full-date in
1890 * [RFC 3339] (https://tools.ietf.org/html/rfc3339). Examples of this
1891 * are "1985-04-12" and "1937-01-01". The time and the time zone are
1892 * never included.
1893 *
1894 * Note that this function doesn't validate the format of the date
1895 * string at all. If you add an incorrect format date string, the
1896 * generated CBOR will be incorrect and the receiver may not be able
1897 * to handle it.
1898 *
1899 * Error handling is the same as QCBOREncode_AddInt64().
1900 *
1901 * See also QCBOREncode_AddTDateString().
Laurence Lundblade46d63e92021-05-13 11:37:10 -07001902 */
1903static void
1904QCBOREncode_AddTDaysString(QCBOREncodeContext *pCtx,
1905 uint8_t uTagRequirement,
1906 const char *szDate);
1907
1908static void
1909QCBOREncode_AddTDaysStringToMapSZ(QCBOREncodeContext *pCtx,
1910 const char *szLabel,
1911 uint8_t uTagRequirement,
1912 const char *szDate);
1913
1914static void
1915QCBOREncode_AddTDaysStringToMapN(QCBOREncodeContext *pCtx,
1916 int64_t nLabel,
1917 uint8_t uTagRequirement,
1918 const char *szDate);
1919
1920
Michael Eckel5c531332020-03-02 01:35:30 +01001921/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001922 * @brief Add a standard Boolean.
1923 *
1924 * @param[in] pCtx The encoding context to add the Boolean to.
1925 * @param[in] b true or false from @c <stdbool.h>.
1926 *
1927 * Adds a Boolean value as CBOR major type 7.
1928 *
1929 * Error handling is the same as QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +01001930 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001931static void
1932QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b);
Michael Eckel5c531332020-03-02 01:35:30 +01001933
Laurence Lundblade3eead482023-12-16 20:53:22 -07001934static void
1935QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b);
Michael Eckel5c531332020-03-02 01:35:30 +01001936
Laurence Lundblade3eead482023-12-16 20:53:22 -07001937static void
1938QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b);
Michael Eckel5c531332020-03-02 01:35:30 +01001939
1940
Michael Eckel5c531332020-03-02 01:35:30 +01001941/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001942 * @brief Add a NULL to the encoded output.
1943 *
1944 * @param[in] pCtx The encoding context to add the NULL to.
1945 *
1946 * Adds the NULL value as CBOR major type 7.
1947 *
1948 * This NULL doesn't have any special meaning in CBOR such as a
1949 * terminating value for a string or an empty value.
1950 *
1951 * Error handling is the same as QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +01001952 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001953static void
1954QCBOREncode_AddNULL(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01001955
Laurence Lundblade3eead482023-12-16 20:53:22 -07001956static void
1957QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001958
Laurence Lundblade3eead482023-12-16 20:53:22 -07001959static void
1960QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001961
1962
1963/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001964 * @brief Add an "undef" to the encoded output.
1965 *
1966 * @param[in] pCtx The encoding context to add the "undef" to.
1967 *
1968 * Adds the undef value as CBOR major type 7.
1969 *
1970 * Note that this value will not translate to JSON.
1971 *
1972 * This Undef doesn't have any special meaning in CBOR such as a
1973 * terminating value for a string or an empty value.
1974 *
1975 * Error handling is the same as QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +01001976 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001977static void
1978QCBOREncode_AddUndef(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01001979
Laurence Lundblade3eead482023-12-16 20:53:22 -07001980static void
1981QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001982
Laurence Lundblade3eead482023-12-16 20:53:22 -07001983static void
1984QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001985
1986
1987/**
Laurence Lundbladecbd7d132024-05-19 11:11:22 -07001988 * @brief Add a simple value.
1989 *
1990 * @param[in] pMe The encode context.
1991 * @param[in] uNum The simple value.
1992 *
1993 * Use QCBOREncode_AddBool(), QCBOREncode_AddUndef()... instead of this.
1994 *
1995 * Use this to add simple values beyond those in defined RFC
1996 * 8949. Simple values must be registered with IANA. There is no range
1997 * of values for proprietary use.
1998 * https://www.iana.org/assignments/cbor-simple-values/cbor-simple-values.xhtml
1999 */
2000static void
2001QCBOREncode_AddSimple(QCBOREncodeContext *pMe, const uint64_t uNum);
2002
2003static void
2004QCBOREncode_AddSimpleToMap(QCBOREncodeContext *pMe,
2005 const char *szLabel,
2006 const uint8_t uSimple);
2007
2008static void
2009QCBOREncode_AddSimpleToMapN(QCBOREncodeContext *pMe,
2010 const int64_t nLabel,
2011 const uint8_t uSimple);
2012
2013
2014/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002015 * @brief Indicates that the next items added are in an array.
2016 *
2017 * @param[in] pCtx The encoding context to open the array in.
2018 *
2019 * Arrays are the basic CBOR aggregate or structure type. Call this
2020 * function to start or open an array. Then call the various
2021 * @c QCBOREncode_AddXxx() functions to add the items that go into the
2022 * array. Then call QCBOREncode_CloseArray() when all items have been
2023 * added. The data items in the array can be of any type and can be of
2024 * mixed types.
2025 *
2026 * Nesting of arrays and maps is allowed and supported just by calling
2027 * QCBOREncode_OpenArray() again before calling
2028 * QCBOREncode_CloseArray(). While CBOR has no limit on nesting, this
2029 * implementation does in order to keep it smaller and simpler. The
2030 * limit is @ref QCBOR_MAX_ARRAY_NESTING. This is the max number of
2031 * times this can be called without calling
2032 * QCBOREncode_CloseArray(). QCBOREncode_Finish() will return
2033 * @ref QCBOR_ERR_ARRAY_NESTING_TOO_DEEP when it is called as this
2034 * function just sets an error state and returns no value when this
2035 * occurs.
2036 *
2037 * If you try to add more than @ref QCBOR_MAX_ITEMS_IN_ARRAY items to
2038 * a single array or map, @ref QCBOR_ERR_ARRAY_TOO_LONG will be
2039 * returned when QCBOREncode_Finish() is called.
2040 *
2041 * An array itself must have a label if it is being added to a map.
2042 * Note that array elements do not have labels (but map elements do).
2043 *
2044 * An array itself may be tagged by calling QCBOREncode_AddTag()
2045 * before this call.
Michael Eckel5c531332020-03-02 01:35:30 +01002046 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002047static void
2048QCBOREncode_OpenArray(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01002049
Laurence Lundblade3eead482023-12-16 20:53:22 -07002050static void
2051QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01002052
Laurence Lundblade3eead482023-12-16 20:53:22 -07002053static void
2054QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01002055
2056
2057/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002058 * @brief Close an open array.
2059 *
2060 * @param[in] pCtx The encoding context to close the array in.
2061 *
2062 * The closes an array opened by QCBOREncode_OpenArray(). It reduces
2063 * nesting level by one. All arrays (and maps) must be closed before
2064 * calling QCBOREncode_Finish().
2065 *
2066 * When an error occurs as a result of this call, the encoder records
2067 * the error and enters the error state. The error will be returned
2068 * when QCBOREncode_Finish() is called.
2069 *
2070 * If this has been called more times than QCBOREncode_OpenArray(), then
2071 * @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when QCBOREncode_Finish()
2072 * is called.
2073 *
2074 * If this is called and it is not an array that is currently open,
2075 * @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
2076 * QCBOREncode_Finish() is called.
Michael Eckel5c531332020-03-02 01:35:30 +01002077 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002078static void
2079QCBOREncode_CloseArray(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01002080
2081
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07002082
2083
Michael Eckel5c531332020-03-02 01:35:30 +01002084/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002085 * @brief Indicates that the next items added are in a map.
2086 *
2087 * @param[in] pCtx The encoding context to open the map in.
2088 *
2089 * See QCBOREncode_OpenArray() for more information, particularly
2090 * error handling.
2091 *
2092 * CBOR maps are an aggregate type where each item in the map consists
2093 * of a label and a value. They are similar to JSON objects.
2094 *
2095 * The value can be any CBOR type including another map.
2096 *
2097 * The label can also be any CBOR type, but in practice they are
2098 * typically, integers as this gives the most compact output. They
2099 * might also be text strings which gives readability and translation
2100 * to JSON.
2101 *
2102 * Every @c QCBOREncode_AddXxx() call has one version that ends with
2103 * @c InMap for adding items to maps with string labels and one that
2104 * ends with @c InMapN that is for adding with integer labels.
2105 *
2106 * RFC 8949 uses the term "key" instead of "label".
2107 *
2108 * If you wish to use map labels that are neither integer labels nor
2109 * text strings, then just call the QCBOREncode_AddXxx() function
2110 * explicitly to add the label. Then call it again to add the value.
2111 *
2112 * See the [RFC 8949] (https://tools.ietf.org/html/rfc8949) for a lot
2113 * more information on creating maps.
Michael Eckel5c531332020-03-02 01:35:30 +01002114 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002115static void
2116QCBOREncode_OpenMap(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01002117
Laurence Lundblade3eead482023-12-16 20:53:22 -07002118static void
2119QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01002120
Laurence Lundblade3eead482023-12-16 20:53:22 -07002121static void
2122QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01002123
2124
Michael Eckel5c531332020-03-02 01:35:30 +01002125/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002126 * @brief Close an open map.
2127 *
2128 * @param[in] pCtx The encoding context to close the map in.
2129 *
2130 * This closes a map opened by QCBOREncode_OpenMap(). It reduces
2131 * nesting level by one.
2132 *
2133 * When an error occurs as a result of this call, the encoder records
2134 * the error and enters the error state. The error will be returned
2135 * when QCBOREncode_Finish() is called.
2136 *
2137 * If this has been called more times than QCBOREncode_OpenMap(), then
2138 * @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
2139 * QCBOREncode_Finish() is called.
2140 *
2141 * If this is called and it is not a map that is currently open,
2142 * @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
2143 * QCBOREncode_Finish() is called.
Michael Eckel5c531332020-03-02 01:35:30 +01002144 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002145static void
2146QCBOREncode_CloseMap(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01002147
2148
2149/**
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07002150 * @brief Indicates that the next items added are in an indefinite length array.
2151 *
2152 * @param[in] pCtx The encoding context to open the array in.
2153 *
2154 * This is the same as QCBOREncode_OpenArray() except the array is
2155 * indefinite length.
2156 *
2157 * This must be closed with QCBOREncode_CloseArrayIndefiniteLength().
2158 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002159static void
2160QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pCtx);
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07002161
Laurence Lundblade3eead482023-12-16 20:53:22 -07002162static void
2163QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pCtx,
2164 const char *szLabel);
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07002165
2166static void
2167QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pCtx,
2168 int64_t nLabel);
2169
2170
2171/**
2172 * @brief Close an open indefinite length array.
2173 *
2174 * @param[in] pCtx The encoding context to close the array in.
2175 *
2176 * This is the same as QCBOREncode_CloseArray(), but the open array
2177 * that is being close must be of indefinite length.
2178 */
2179static void
2180QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pCtx);
2181
2182
2183/**
2184 * @brief Indicates that the next items added are in an indefinite length map.
2185 *
2186 * @param[in] pCtx The encoding context to open the map in.
2187 *
2188 * This is the same as QCBOREncode_OpenMap() except the array is
2189 * indefinite length.
2190 *
2191 * This must be closed with QCBOREncode_CloseMapIndefiniteLength().
2192 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002193static void
2194QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pCtx);
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07002195
Laurence Lundblade3eead482023-12-16 20:53:22 -07002196static void
2197QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pCtx,
2198 const char *szLabel);
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07002199
2200static void
2201QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pCtx,
2202 int64_t nLabel);
2203
2204
2205/**
2206 * @brief Close an open indefinite length map.
2207 *
2208 * @param[in] pCtx The encoding context to close the map in.
2209 *
2210 * This is the same as QCBOREncode_CloseMap(), but the open map that
2211 * is being close must be of indefinite length.
2212 */
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07002213static void
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07002214QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pCtx);
2215
2216
Laurence Lundbladec92e4162023-11-27 21:51:26 -07002217/**
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -08002218 * @brief Close and sort an open map.
Laurence Lundbladed6e13022023-11-26 10:14:02 -07002219 *
2220 * @param[in] pCtx The encoding context to close the map in .
2221 *
2222 * This is the same as QCBOREncode_CloseMap() except it sorts the map
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07002223 * per RFC 8949 Section 4.2.1 and checks for duplicate map keys. This
2224 * sort is lexicographic of the CBOR-encoded map labels.
Laurence Lundbladed6e13022023-11-26 10:14:02 -07002225 *
2226 * This is more expensive than most things in the encoder. It uses
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07002227 * bubble sort which runs in n-squared time where @c n is the number
2228 * of map items. Sorting large maps on slow CPUs might be slow. This
2229 * is also increases the object code size of the encoder by about 30%
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -08002230 * (500-1000 bytes).
Laurence Lundbladed6e13022023-11-26 10:14:02 -07002231 *
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07002232 * Bubble sort was selected so as to not need require configuration of
2233 * a buffer to track map item offsets. Bubble sort works well even
2234 * though map items are not all the same size because it always swaps
2235 * adjacent items.
Laurence Lundbladed6e13022023-11-26 10:14:02 -07002236 */
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07002237void
2238QCBOREncode_CloseAndSortMap(QCBOREncodeContext *pCtx);
Laurence Lundbladed6e13022023-11-26 10:14:02 -07002239
Laurence Lundbladedee0d4e2024-03-03 13:46:33 -07002240void
2241QCBOREncode_CloseAndSortMapIndef(QCBOREncodeContext *pCtx);
Laurence Lundbladed6e13022023-11-26 10:14:02 -07002242
2243
2244/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002245 * @brief Indicate start of encoded CBOR to be wrapped in a bstr.
2246 *
2247 * @param[in] pCtx The encoding context to open the bstr-wrapped CBOR in.
2248 *
2249 * All added encoded items between this call and a call to
2250 * QCBOREncode_CloseBstrWrap2() will be wrapped in a bstr. They will
2251 * appear in the final output as a byte string. That byte string will
2252 * contain encoded CBOR. This increases nesting level by one.
2253 *
2254 * The typical use case is for encoded CBOR that is to be
2255 * cryptographically hashed, as part of a [RFC 8152, COSE]
2256 * (https://tools.ietf.org/html/rfc8152) implementation. The wrapping
2257 * byte string is taken as input by the hash function (which is why it
2258 * is returned by QCBOREncode_CloseBstrWrap2()). It is also easy to
2259 * recover on decoding with standard CBOR decoders.
2260 *
2261 * Using QCBOREncode_BstrWrap() and QCBOREncode_CloseBstrWrap2()
2262 * avoids having to encode the items first in one buffer (e.g., the
2263 * COSE payload) and then add that buffer as a bstr to another
2264 * encoding (e.g. the COSE to-be-signed bytes, the @c Sig_structure)
2265 * potentially halving the memory needed.
2266 *
2267 * CBOR by nature must be decoded item by item in order from the
2268 * start. By wrapping some CBOR in a byte string, the decoding of
2269 * that wrapped CBOR can be skipped. This is another use of wrapping,
2270 * perhaps because the CBOR is large and deeply nested. Perhaps APIs
2271 * for handling one defined CBOR message that is being embedded in
2272 * another only take input as a byte string. Perhaps the desire is to
2273 * be able to decode the out layer even in the wrapped has errors.
Michael Eckel5c531332020-03-02 01:35:30 +01002274 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002275static void
2276QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01002277
Laurence Lundblade3eead482023-12-16 20:53:22 -07002278static void
2279QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01002280
Laurence Lundblade3eead482023-12-16 20:53:22 -07002281static void
2282QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01002283
2284
2285/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002286 * @brief Close a wrapping bstr.
2287 *
2288 * @param[in] pCtx The encoding context to close of bstr wrapping in.
2289 * @param[in] bIncludeCBORHead Include the encoded CBOR head of the bstr
2290 * as well as the bytes in @c pWrappedCBOR.
2291 * @param[out] pWrappedCBOR A @ref UsefulBufC containing wrapped bytes.
2292 *
2293 * The closes a wrapping bstr opened by QCBOREncode_BstrWrap(). It reduces
2294 * nesting level by one.
2295 *
2296 * A pointer and length of the enclosed encoded CBOR is returned in @c
2297 * *pWrappedCBOR if it is not @c NULL. The main purpose of this is so
2298 * this data can be hashed (e.g., with SHA-256) as part of a [RFC
2299 * 8152, COSE] (https://tools.ietf.org/html/rfc8152)
2300 * implementation. **WARNING**, this pointer and length should be used
2301 * right away before any other calls to @c QCBOREncode_CloseXxx() as
2302 * they will move data around and the pointer and length will no
2303 * longer be to the correct encoded CBOR.
2304 *
2305 * When an error occurs as a result of this call, the encoder records
2306 * the error and enters the error state. The error will be returned
2307 * when QCBOREncode_Finish() is called.
2308 *
2309 * If this has been called more times than QCBOREncode_BstrWrap(),
2310 * then @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
2311 * QCBOREncode_Finish() is called.
2312 *
2313 * If this is called and it is not a wrapping bstr that is currently
2314 * open, @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
2315 * QCBOREncode_Finish() is called.
2316 *
2317 * QCBOREncode_CloseBstrWrap() is a deprecated version of this function
2318 * that is equivalent to the call with @c bIncludeCBORHead @c true.
Michael Eckel5c531332020-03-02 01:35:30 +01002319 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002320void
2321QCBOREncode_CloseBstrWrap2(QCBOREncodeContext *pCtx, bool bIncludeCBORHead, UsefulBufC *pWrappedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01002322
Laurence Lundblade3eead482023-12-16 20:53:22 -07002323static void
2324QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01002325
2326
2327/**
Laurence Lundblade8d3b8552021-06-10 11:11:54 -07002328 * @brief Cancel byte string wrapping.
2329 *
2330 * @param[in] pCtx The encoding context.
2331 *
2332 * This cancels QCBOREncode_BstrWrap() making tghe encoding as if it
2333 * were never called.
2334 *
2335 * WARNING: This does not work on QCBOREncode_BstrWrapInMap()
2336 * or QCBOREncode_BstrWrapInMapN() and there is no error detection
2337 * of an attempt at their use.
2338 *
2339 * This only works if nothing has been added into the wrapped byte
2340 * string. If something has been added, this sets the error
2341 * @ref QCBOR_ERR_CANNOT_CANCEL.
2342 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002343void
2344QCBOREncode_CancelBstrWrap(QCBOREncodeContext *pCtx);
Laurence Lundblade8d3b8552021-06-10 11:11:54 -07002345
2346
2347/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002348 * @brief Add some already-encoded CBOR bytes.
2349 *
2350 * @param[in] pCtx The encoding context to add the already-encode CBOR to.
2351 * @param[in] Encoded The already-encoded CBOR to add to the context.
2352 *
2353 * The encoded CBOR being added must be fully conforming CBOR. It must
2354 * be complete with no arrays or maps that are incomplete. While this
2355 * encoder doesn't ever produce indefinite lengths, it is OK for the
2356 * raw CBOR added here to have indefinite lengths.
2357 *
2358 * The raw CBOR added here is not checked in anyway. If it is not
2359 * conforming or has open arrays or such, the final encoded CBOR
2360 * will probably be wrong or not what was intended.
2361 *
2362 * If the encoded CBOR being added here contains multiple items, they
2363 * must be enclosed in a map or array. At the top level the raw
2364 * CBOR must be a single data item.
Michael Eckel5c531332020-03-02 01:35:30 +01002365 */
Laurence Lundbladecbd7d132024-05-19 11:11:22 -07002366void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002367QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01002368
Laurence Lundblade3eead482023-12-16 20:53:22 -07002369static void
2370QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01002371
Laurence Lundblade3eead482023-12-16 20:53:22 -07002372static void
2373QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01002374
2375
2376/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002377 * @brief Get the encoded result.
2378 *
2379 * @param[in] pCtx The context to finish encoding with.
2380 * @param[out] pEncodedCBOR Structure in which the pointer and length of
2381 * the encoded CBOR is returned.
2382 *
2383 * @retval QCBOR_SUCCESS Encoded CBOR is returned.
2384 *
2385 * @retval QCBOR_ERR_TOO_MANY_CLOSES Nesting error
2386 *
2387 * @retval QCBOR_ERR_CLOSE_MISMATCH Nesting error
2388 *
2389 * @retval QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN Nesting error
2390 *
2391 * @retval QCBOR_ERR_BUFFER_TOO_LARGE Encoded output buffer size
2392 *
2393 * @retval QCBOR_ERR_BUFFER_TOO_SMALL Encoded output buffer size
2394 *
2395 * @retval QCBOR_ERR_ARRAY_NESTING_TOO_DEEP Implementation limit
2396 *
2397 * @retval QCBOR_ERR_ARRAY_TOO_LONG Implementation limit
2398 *
2399 * On success, the pointer and length of the encoded CBOR are returned
2400 * in @c *pEncodedCBOR. The pointer is the same pointer that was passed
2401 * in to QCBOREncode_Init(). Note that it is not const when passed to
2402 * QCBOREncode_Init(), but it is const when returned here. The length
2403 * will be smaller than or equal to the length passed in when
2404 * QCBOREncode_Init() as this is the length of the actual result, not
2405 * the size of the buffer it was written to.
2406 *
2407 * If a @c NULL was passed for @c Storage.ptr when QCBOREncode_Init()
2408 * was called, @c NULL will be returned here, but the length will be
2409 * that of the CBOR that would have been encoded.
2410 *
2411 * Encoding errors primarily manifest here as most other encoding function
2412 * do no return an error. They just set the error state in the encode
2413 * context after which no encoding function does anything.
2414 *
2415 * Three types of errors manifest here. The first type are nesting
2416 * errors where the number of @c QCBOREncode_OpenXxx() calls do not
2417 * match the number @c QCBOREncode_CloseXxx() calls. The solution is to
2418 * fix the calling code.
2419 *
2420 * The second type of error is because the buffer given is either too
2421 * small or too large. The remedy is to give a correctly sized buffer.
2422 *
2423 * The third type are due to limits in this implementation.
2424 * @ref QCBOR_ERR_ARRAY_NESTING_TOO_DEEP can be worked around by
2425 * encoding the CBOR in two (or more) phases and adding the CBOR from
2426 * the first phase to the second with @c QCBOREncode_AddEncoded().
2427 *
2428 * If an error is returned, the buffer may have partially encoded
2429 * incorrect CBOR in it and it should not be used. Likewise, the length
2430 * may be incorrect and should not be used.
2431 *
2432 * Note that the error could have occurred in one of the many
2433 * @c QCBOREncode_AddXxx() calls long before QCBOREncode_Finish() was
2434 * called. This error handling reduces the CBOR implementation size
2435 * but makes debugging harder.
2436 *
2437 * This may be called multiple times. It will always return the
2438 * same. It can also be interleaved with calls to
2439 * QCBOREncode_FinishGetSize().
2440 *
2441 * QCBOREncode_GetErrorState() can be called to get the current
2442 * error state in order to abort encoding early as an optimization, but
2443 * calling it is is never required.
Michael Eckel5c531332020-03-02 01:35:30 +01002444 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002445QCBORError
2446QCBOREncode_Finish(QCBOREncodeContext *pCtx, UsefulBufC *pEncodedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01002447
2448
2449/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002450 * @brief Get the encoded CBOR and error status.
2451 *
2452 * @param[in] pCtx The context to finish encoding with.
2453 * @param[out] uEncodedLen The length of the encoded or potentially
2454 * encoded CBOR in bytes.
2455 *
2456 * @return The same errors as QCBOREncode_Finish().
2457 *
2458 * This functions the same as QCBOREncode_Finish(), but only returns the
2459 * size of the encoded output.
Michael Eckel5c531332020-03-02 01:35:30 +01002460 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002461QCBORError
2462QCBOREncode_FinishGetSize(QCBOREncodeContext *pCtx, size_t *uEncodedLen);
Michael Eckel5c531332020-03-02 01:35:30 +01002463
2464
2465/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002466 * @brief Indicate whether output buffer is NULL or not.
2467 *
2468 * @param[in] pCtx The encoding context.
2469 *
2470 * @return 1 if the output buffer is @c NULL.
2471 *
2472 * Sometimes a @c NULL input buffer is given to QCBOREncode_Init() so
2473 * that the size of the generated CBOR can be calculated without
2474 * allocating a buffer for it. This returns 1 when the output buffer
2475 * is @c NULL and 0 when it is not.
Michael Eckel5c531332020-03-02 01:35:30 +01002476 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002477static int
2478QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx);
2479
2480
2481/**
2482 * @brief Get the encoding error state.
2483 *
2484 * @param[in] pCtx The encoding context.
2485 *
2486 * @return One of @ref QCBORError. See return values from
2487 * QCBOREncode_Finish()
2488 *
2489 * Normally encoding errors need only be handled at the end of
2490 * encoding when QCBOREncode_Finish() is called. This can be called to
2491 * get the error result before finish should there be a need to halt
2492 * encoding before QCBOREncode_Finish() is called.
2493 */
2494static QCBORError
2495QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx);
2496
2497
2498/**
2499 * Encode the "head" of a CBOR data item.
2500 *
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002501 * @param Buffer Buffer to output the encoded head to; must be
Laurence Lundblade3eead482023-12-16 20:53:22 -07002502 * @ref QCBOR_HEAD_BUFFER_SIZE bytes in size.
2503 * @param uMajorType One of CBOR_MAJOR_TYPE_XX.
2504 * @param uMinLen The minimum number of bytes to encode uNumber. Almost
2505 * always this is 0 to use preferred
2506 * serialization. If this is 4, then even the
2507 * values 0xffff and smaller will be encoded in 4
2508 * bytes. This is used primarily when encoding a
2509 * float or double put into uNumber as the leading
2510 * zero bytes for them must be encoded.
2511 * @param uNumber The numeric argument part of the CBOR head.
2512 * @return Pointer and length of the encoded head or
2513 * @ref NULLUsefulBufC if the output buffer is too small.
2514 *
2515 * Callers do not to need to call this for normal CBOR encoding. Note
2516 * that it doesn't even take a @ref QCBOREncodeContext argument.
2517 *
2518 * This encodes the major type and argument part of a data item. The
2519 * argument is an integer that is usually either the value or the length
2520 * of the data item.
2521 *
2522 * This is exposed in the public interface to allow hashing of some CBOR
2523 * data types, bstr in particular, a chunk at a time so the full CBOR
2524 * doesn't have to be encoded in a contiguous buffer.
2525 *
2526 * For example, if you have a 100,000 byte binary blob in a buffer that
2527 * needs to be a bstr encoded and then hashed. You could allocate a
2528 * 100,010 byte buffer and encode it normally. Alternatively, you can
2529 * encode the head in a 10 byte buffer with this function, hash that and
2530 * then hash the 100,000 bytes using the same hash context.
Laurence Lundblade3eead482023-12-16 20:53:22 -07002531 */
2532UsefulBufC
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002533QCBOREncode_EncodeHead(UsefulBuf Buffer,
Laurence Lundblade3eead482023-12-16 20:53:22 -07002534 uint8_t uMajorType,
2535 uint8_t uMinLen,
2536 uint64_t uNumber);
Michael Eckel5c531332020-03-02 01:35:30 +01002537
2538
Michael Eckel5c531332020-03-02 01:35:30 +01002539
2540
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002541/* =========================================================================
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002542 BEGINNING OF PRIVATE IMPLEMENTATION
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002543 ========================================================================= */
Michael Eckel5c531332020-03-02 01:35:30 +01002544
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002545/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundbladecbd7d132024-05-19 11:11:22 -07002546void QCBOREncode_Private_AppendCBORHead(QCBOREncodeContext *pMe,
2547 const uint8_t uMajorType,
2548 const uint64_t uArgument,
2549 const uint8_t uMinLen);
2550
2551
2552/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002553void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002554QCBOREncode_Private_AddBuffer(QCBOREncodeContext *pCtx,
2555 uint8_t uMajorType,
2556 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002557
2558
Laurence Lundblade8d9e0cd2024-05-25 18:12:19 -07002559/* Semi-private function for adding a double with preferred encoding. See qcbor_encode.c */
2560void
2561QCBOREncode_Private_AddPreferredDouble(QCBOREncodeContext *pMe, const double dNum);
2562
2563
2564/* Semi-private function for adding a float with preferred encoding. See qcbor_encode.c */
2565void
2566QCBOREncode_Private_AddPreferredFloat(QCBOREncodeContext *pMe, const float fNum);
2567
2568
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002569/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002570void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002571QCBOREncode_Private_OpenMapOrArray(QCBOREncodeContext *pCtx,
2572 uint8_t uMajorType);
Michael Eckel5c531332020-03-02 01:35:30 +01002573
2574
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002575/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002576void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002577QCBOREncode_Private_OpenMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx,
2578 uint8_t uMajorType);
Michael Eckel5c531332020-03-02 01:35:30 +01002579
2580
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002581/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002582void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002583QCBOREncode_Private_CloseMapOrArray(QCBOREncodeContext *pCtx,
2584 uint8_t uMajorType);
Michael Eckel5c531332020-03-02 01:35:30 +01002585
2586
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002587/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002588void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002589QCBOREncode_Private_CloseMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx,
2590 uint8_t uMajorType);
Michael Eckel5c531332020-03-02 01:35:30 +01002591
2592
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002593/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002594void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002595QCBOREncode_Private_AddExpMantissa(QCBOREncodeContext *pCtx,
Laurence Lundblade3eead482023-12-16 20:53:22 -07002596 uint64_t uTag,
2597 UsefulBufC BigNumMantissa,
2598 bool bBigNumIsNegative,
2599 int64_t nMantissa,
2600 int64_t nExponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002601
Michael Eckel5c531332020-03-02 01:35:30 +01002602
2603
Laurence Lundbladecbd7d132024-05-19 11:11:22 -07002604/**
2605 * @brief Semi-private method to add simple items and floating-point.
2606 *
2607 * @param[in] pMe The encoding context.
2608 * @param[in] uMinLen Minimum encoding size for uNum. Usually 0.
2609 * @param[in] uArgument The value to add.
2610 *
2611 * This is used to add simple types like true and false and float-point
2612 * values, both of which are type 7.
2613 *
2614 * Call QCBOREncode_AddBool(), QCBOREncode_AddNULL(),
2615 * QCBOREncode_AddUndef() QCBOREncode_AddDouble() instead of this.
2616 *
2617 * Error handling is the same as QCBOREncode_AddInt64().
2618 */
2619static inline void
2620QCBOREncode_Private_AddType7(QCBOREncodeContext *pMe,
2621 const uint8_t uMinLen,
2622 const uint64_t uArgument)
2623{
2624 QCBOREncode_Private_AppendCBORHead(pMe, CBOR_MAJOR_TYPE_SIMPLE, uArgument, uMinLen);
2625}
2626
2627
Michael Eckel5c531332020-03-02 01:35:30 +01002628/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002629 * @brief Semi-private method to add only the type and length of a byte string.
2630 *
2631 * @param[in] pCtx The context to initialize.
2632 * @param[in] Bytes Pointer and length of the input data.
2633 *
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002634 * This will be removed in QCBOR 2.0. It was never a public function.
2635 *
Laurence Lundblade3eead482023-12-16 20:53:22 -07002636 * This is the same as QCBOREncode_AddBytes() except it only adds the
2637 * CBOR encoding for the type and the length. It doesn't actually add
2638 * the bytes. You can't actually produce correct CBOR with this and
2639 * the rest of this API. It is only used for a special case where the
2640 * valid CBOR is created manually by putting this type and length in
2641 * and then adding the actual bytes. In particular, when only a hash
2642 * of the encoded CBOR is needed, where the type and header are hashed
2643 * separately and then the bytes is hashed. This makes it possible to
2644 * implement COSE Sign1 with only one copy of the payload in the
2645 * output buffer, rather than two, roughly cutting memory use in half.
2646 *
2647 * This is only used for this odd case, but this is a supported
Laurence Lundbladecbd7d132024-05-19 11:11:22 -07002648 * tested function for QCBOR 1.0.
Laurence Lundblade3eead482023-12-16 20:53:22 -07002649 *
2650 * See also QCBOREncode_EncodeHead().
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002651 */
2652static void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002653QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pCtx,
2654 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002655
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002656static void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002657QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pCtx,
2658 const char *szLabel,
2659 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002660
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002661static void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002662QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pCtx,
2663 int64_t nLabel,
2664 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002665
2666
Laurence Lundbladecbd7d132024-05-19 11:11:22 -07002667/* Forward declaration */
2668static void
2669QCBOREncode_AddSZString(QCBOREncodeContext *pMe, const char *szString);
2670
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -08002671
2672static inline void
2673QCBOREncode_SerializationCDE(QCBOREncodeContext *pMe)
2674{
2675 /* The use of a function pointer here is a little trick to reduce
2676 * code linked for the common use cases that don't sort. If this
2677 * function is never linked, then QCBOREncode_CloseAndSortMap() is
2678 * never linked and the amount of code pulled in is small. If the
2679 * mode switch between sorting and not sorting were an if
2680 * statement, then QCBOREncode_CloseAndSortMap() would always be
2681 * linked even when not used. */
2682 pMe->pfnCloseMap = QCBOREncode_CloseAndSortMap;
2683 pMe->uMode = QCBOR_ENCODE_MODE_CDE;
2684}
2685
2686static inline void
2687QCBOREncode_SerializationdCBOR(QCBOREncodeContext *pMe)
2688{
2689 pMe->pfnCloseMap = QCBOREncode_CloseAndSortMap;
2690 pMe->uMode = QCBOR_ENCODE_MODE_DCBOR;
2691}
2692
2693static inline void
2694QCBOREncode_SerializationPreferred(QCBOREncodeContext *pMe)
2695{
2696 pMe->uMode = QCBOR_ENCODE_MODE_PREFERRED;
2697}
2698
2699static inline void
2700QCBOREncode_Allow(QCBOREncodeContext *pMe, const uint8_t uAllow)
2701{
2702#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
2703 pMe->uAllow = uAllow;
2704#else
2705 (void)uAllow;
2706 (void)pMe;
2707#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
2708}
2709
2710
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002711static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002712QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pMe,
2713 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002714 const int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002715{
Laurence Lundbladecbd7d132024-05-19 11:11:22 -07002716 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002717 QCBOREncode_AddInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002718}
2719
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002720static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002721QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002722 const int64_t nLabel,
2723 const int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002724{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002725 QCBOREncode_AddInt64(pMe, nLabel);
2726 QCBOREncode_AddInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002727}
2728
2729
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002730static inline void
Laurence Lundbladecbd7d132024-05-19 11:11:22 -07002731QCBOREncode_AddUInt64(QCBOREncodeContext *pMe, const uint64_t uValue)
2732{
2733 QCBOREncode_Private_AppendCBORHead(pMe, CBOR_MAJOR_TYPE_POSITIVE_INT, uValue, 0);
2734}
2735
2736
2737static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002738QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pMe,
2739 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002740 const uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002741{
Laurence Lundbladecbd7d132024-05-19 11:11:22 -07002742 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002743 QCBOREncode_AddUInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002744}
2745
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002746static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002747QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002748 const int64_t nLabel,
2749 const uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002750{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002751 QCBOREncode_AddInt64(pMe, nLabel);
2752 QCBOREncode_AddUInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002753}
2754
2755
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002756static inline void
Laurence Lundblade2d493002024-02-01 11:09:17 -07002757QCBOREncode_AddNegativeUInt64ToMap(QCBOREncodeContext *pMe, const char *szLabel, uint64_t uNum)
2758{
2759 /* Use _AddBuffer() because _AddSZString() is defined below, not above */
2760 QCBOREncode_Private_AddBuffer(pMe,
2761 CBOR_MAJOR_TYPE_TEXT_STRING,
2762 UsefulBuf_FromSZ(szLabel));
2763 QCBOREncode_AddNegativeUInt64(pMe, uNum);
2764}
2765
2766static inline void
2767QCBOREncode_AddNegativeUInt64ToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint64_t uNum)
2768{
2769 QCBOREncode_AddInt64(pMe, nLabel);
2770 QCBOREncode_AddNegativeUInt64(pMe, uNum);
2771}
2772
2773
2774static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002775QCBOREncode_AddText(QCBOREncodeContext *pMe, const UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002776{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002777 QCBOREncode_Private_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, Text);
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_AddTextToMap(QCBOREncodeContext *pMe,
2782 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002783 const UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002784{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002785 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szLabel));
2786 QCBOREncode_AddText(pMe, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002787}
2788
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002789static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002790QCBOREncode_AddTextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002791 const int64_t nLabel,
2792 const UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002793{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002794 QCBOREncode_AddInt64(pMe, nLabel);
2795 QCBOREncode_AddText(pMe, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002796}
2797
2798
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002799inline static void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002800QCBOREncode_AddSZString(QCBOREncodeContext *pMe, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002801{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002802 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szString));
Michael Eckel5c531332020-03-02 01:35:30 +01002803}
2804
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002805static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002806QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pMe,
2807 const char *szLabel,
2808 const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002809{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002810 QCBOREncode_AddSZString(pMe, szLabel);
2811 QCBOREncode_AddSZString(pMe, szString);
Michael Eckel5c531332020-03-02 01:35:30 +01002812}
2813
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002814static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002815QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002816 const int64_t nLabel,
Laurence Lundblade3eead482023-12-16 20:53:22 -07002817 const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002818{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002819 QCBOREncode_AddInt64(pMe, nLabel);
2820 QCBOREncode_AddSZString(pMe, szString);
Michael Eckel5c531332020-03-02 01:35:30 +01002821}
2822
2823
Laurence Lundbladecbd7d132024-05-19 11:11:22 -07002824
2825/*
2826 * Public functions for adding a tag. See qcbor/qcbor_encode.h
2827 */
2828static inline void
2829QCBOREncode_AddTag(QCBOREncodeContext *pMe, const uint64_t uTag)
2830{
2831 QCBOREncode_Private_AppendCBORHead(pMe, CBOR_MAJOR_TYPE_TAG, uTag, 0);
2832}
2833
2834
2835
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +02002836#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundbladecbd7d132024-05-19 11:11:22 -07002837
2838static inline void
2839QCBOREncode_AddDoubleNoPreferred(QCBOREncodeContext *pMe, const double dNum)
2840{
2841 QCBOREncode_Private_AddType7(pMe,
2842 sizeof(uint64_t),
2843 UsefulBufUtil_CopyDoubleToUint64(dNum));
2844}
2845
2846static inline void
2847QCBOREncode_AddFloatNoPreferred(QCBOREncodeContext *pMe, const float fNum)
2848{
2849 QCBOREncode_Private_AddType7(pMe,
2850 sizeof(uint32_t),
2851 UsefulBufUtil_CopyFloatToUint32(fNum));
2852}
2853
2854
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002855static inline void
Laurence Lundblade8d9e0cd2024-05-25 18:12:19 -07002856QCBOREncode_AddDouble(QCBOREncodeContext *pMe, const double dNum)
2857{
2858#ifndef QCBOR_DISABLE_PREFERRED_FLOAT
2859 QCBOREncode_Private_AddPreferredDouble(pMe, dNum);
2860#else /* QCBOR_DISABLE_PREFERRED_FLOAT */
2861 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
2862#endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
2863}
2864
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002865static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002866QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pMe,
2867 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002868 const double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002869{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002870 QCBOREncode_AddSZString(pMe, szLabel);
2871 QCBOREncode_AddDouble(pMe, dNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002872}
2873
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002874static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002875QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002876 const int64_t nLabel,
2877 const double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002878{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002879 QCBOREncode_AddInt64(pMe, nLabel);
2880 QCBOREncode_AddDouble(pMe, dNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002881}
2882
Laurence Lundblade8d9e0cd2024-05-25 18:12:19 -07002883
2884static inline void
2885QCBOREncode_AddFloat(QCBOREncodeContext *pMe, const float fNum)
2886{
2887#ifndef QCBOR_DISABLE_PREFERRED_FLOAT
2888 QCBOREncode_Private_AddPreferredFloat(pMe, fNum);
2889#else /* QCBOR_DISABLE_PREFERRED_FLOAT */
2890 QCBOREncode_AddFloatNoPreferred(pMe, fNum);
2891#endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
2892}
2893
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002894static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002895QCBOREncode_AddFloatToMap(QCBOREncodeContext *pMe,
2896 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002897 const float dNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002898{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002899 QCBOREncode_AddSZString(pMe, szLabel);
2900 QCBOREncode_AddFloat(pMe, dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002901}
2902
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002903static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002904QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pMe,
2905 const int64_t nLabel,
2906 const float fNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002907{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002908 QCBOREncode_AddInt64(pMe, nLabel);
2909 QCBOREncode_AddFloat(pMe, fNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002910}
2911
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002912static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002913QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pMe,
2914 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002915 const double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002916{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002917 QCBOREncode_AddSZString(pMe, szLabel);
2918 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002919}
2920
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002921static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002922QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002923 const int64_t nLabel,
2924 const double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002925{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002926 QCBOREncode_AddInt64(pMe, nLabel);
2927 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002928}
2929
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002930static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002931QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pMe,
2932 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002933 const float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002934{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002935 QCBOREncode_AddSZString(pMe, szLabel);
2936 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002937}
2938
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002939static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002940QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002941 const int64_t nLabel,
2942 const float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002943{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002944 QCBOREncode_AddInt64(pMe, nLabel);
2945 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002946}
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +02002947#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002948
Michael Eckel5c531332020-03-02 01:35:30 +01002949
Laurence Lundblade9b334962020-08-27 10:55:53 -07002950
Laurence Lundbladecbd7d132024-05-19 11:11:22 -07002951
2952
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002953static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002954QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pMe,
2955 const uint8_t uTag,
2956 const int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002957{
2958 if(uTag == QCBOR_ENCODE_AS_TAG) {
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002959 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_EPOCH);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002960 }
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002961 QCBOREncode_AddInt64(pMe, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002962}
2963
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002964static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002965QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pMe,
2966 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002967 const uint8_t uTag,
2968 const int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002969{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002970 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002971 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002972}
2973
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002974static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002975QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002976 const int64_t nLabel,
2977 const uint8_t uTag,
2978 const int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002979{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002980 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002981 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002982}
2983
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002984static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002985QCBOREncode_AddDateEpoch(QCBOREncodeContext *pMe,
2986 const int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002987{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002988 QCBOREncode_AddTDateEpoch(pMe, QCBOR_ENCODE_AS_TAG, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002989}
2990
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002991static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002992QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pMe,
2993 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002994 const int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002995{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002996 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002997 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002998}
2999
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003000static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003001QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003002 const int64_t nLabel,
3003 const int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01003004{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003005 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003006 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01003007}
3008
3009
Laurence Lundblade46d63e92021-05-13 11:37:10 -07003010static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003011QCBOREncode_AddTDaysEpoch(QCBOREncodeContext *pMe,
3012 const uint8_t uTag,
3013 const int64_t nDays)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07003014{
3015 if(uTag == QCBOR_ENCODE_AS_TAG) {
3016 QCBOREncode_AddTag(pMe, CBOR_TAG_DAYS_EPOCH);
3017 }
3018 QCBOREncode_AddInt64(pMe, nDays);
3019}
3020
3021static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003022QCBOREncode_AddTDaysEpochToMapSZ(QCBOREncodeContext *pMe,
3023 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003024 const uint8_t uTag,
3025 const int64_t nDays)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07003026{
3027 QCBOREncode_AddSZString(pMe, szLabel);
3028 QCBOREncode_AddTDaysEpoch(pMe, uTag, nDays);
3029}
3030
3031static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003032QCBOREncode_AddTDaysEpochToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003033 const int64_t nLabel,
3034 const uint8_t uTag,
3035 const int64_t nDays)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07003036{
3037 QCBOREncode_AddInt64(pMe, nLabel);
3038 QCBOREncode_AddTDaysEpoch(pMe, uTag, nDays);
3039}
3040
Laurence Lundblade9b334962020-08-27 10:55:53 -07003041
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003042static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003043QCBOREncode_AddBytes(QCBOREncodeContext *pMe,
3044 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003045{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003046 QCBOREncode_Private_AddBuffer(pMe, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01003047}
3048
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003049static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003050QCBOREncode_AddBytesToMap(QCBOREncodeContext *pMe,
3051 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003052 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003053{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003054 QCBOREncode_AddSZString(pMe, szLabel);
3055 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01003056}
3057
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003058static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003059QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003060 const int64_t nLabel,
3061 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003062{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003063 QCBOREncode_AddInt64(pMe, nLabel);
3064 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01003065}
3066
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003067static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003068QCBOREncode_OpenBytesInMapSZ(QCBOREncodeContext *pMe,
3069 const char *szLabel,
3070 UsefulBuf *pPlace)
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06003071{
3072 QCBOREncode_AddSZString(pMe, szLabel);
3073 QCBOREncode_OpenBytes(pMe, pPlace);
3074}
3075
3076static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003077QCBOREncode_OpenBytesInMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003078 const int64_t nLabel,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003079 UsefulBuf *pPlace)
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06003080{
3081 QCBOREncode_AddInt64(pMe, nLabel);
3082 QCBOREncode_OpenBytes(pMe, pPlace);
3083}
3084
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003085
Laurence Lundbladecbd7d132024-05-19 11:11:22 -07003086/*
3087 * Public functions for adding only a byte string length. See qcbor/qcbor_encode.h
3088 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003089static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003090QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003091{
Laurence Lundbladecbd7d132024-05-19 11:11:22 -07003092 QCBOREncode_Private_AppendCBORHead(pMe, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes.len, 0);
Michael Eckel5c531332020-03-02 01:35:30 +01003093}
3094
Laurence Lundbladecbd7d132024-05-19 11:11:22 -07003095
Michael Eckel5c531332020-03-02 01:35:30 +01003096static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003097QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pMe,
3098 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003099 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003100{
3101 QCBOREncode_AddSZString(pMe, szLabel);
3102 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
3103}
3104
3105static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003106QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003107 const int64_t nLabel,
3108 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003109{
3110 QCBOREncode_AddInt64(pMe, nLabel);
3111 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
3112}
3113
3114
3115static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003116QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003117 const uint8_t uTagRequirement,
3118 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003119{
3120 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3121 QCBOREncode_AddTag(pMe, CBOR_TAG_BIN_UUID);
3122 }
3123 QCBOREncode_AddBytes(pMe, Bytes);
3124}
3125
3126static inline void
3127QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pMe,
3128 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003129 const uint8_t uTagRequirement,
3130 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003131{
3132 QCBOREncode_AddSZString(pMe, szLabel);
3133 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
3134}
3135
3136static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003137QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003138 const int64_t nLabel,
3139 const uint8_t uTagRequirement,
3140 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003141{
3142 QCBOREncode_AddInt64(pMe, nLabel);
3143 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
3144}
3145
3146static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003147QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003148{
3149 QCBOREncode_AddTBinaryUUID(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
3150}
3151
3152static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003153QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pMe,
3154 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003155 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003156{
3157 QCBOREncode_AddTBinaryUUIDToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
3158}
3159
3160static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003161QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003162 const int64_t nLabel,
3163 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003164{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003165 QCBOREncode_AddTBinaryUUIDToMapN(pMe,
3166 nLabel,
3167 QCBOR_ENCODE_AS_TAG,
3168 Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01003169}
3170
3171
3172static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003173QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003174 const uint8_t uTagRequirement,
3175 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003176{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003177 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3178 QCBOREncode_AddTag(pMe, CBOR_TAG_POS_BIGNUM);
3179 }
3180 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01003181}
3182
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003183static inline void
3184QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pMe,
3185 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003186 const uint8_t uTagRequirement,
3187 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003188{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003189 QCBOREncode_AddSZString(pMe, szLabel);
3190 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01003191}
3192
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003193static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003194QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003195 const int64_t nLabel,
3196 const uint8_t uTagRequirement,
3197 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003198{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003199 QCBOREncode_AddInt64(pMe, nLabel);
3200 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01003201}
3202
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003203static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003204QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003205{
3206 QCBOREncode_AddTPositiveBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
3207}
3208
3209static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003210QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pMe,
3211 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003212 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003213{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003214 QCBOREncode_AddTPositiveBignumToMapSZ(pMe,
3215 szLabel,
3216 QCBOR_ENCODE_AS_TAG,
3217 Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003218}
3219
3220static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003221QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003222 const int64_t nLabel,
3223 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003224{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003225 QCBOREncode_AddTPositiveBignumToMapN(pMe,
3226 nLabel,
3227 QCBOR_ENCODE_AS_TAG,
3228 Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003229}
3230
3231
3232static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003233QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003234 const uint8_t uTagRequirement,
3235 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003236{
3237 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3238 QCBOREncode_AddTag(pMe, CBOR_TAG_NEG_BIGNUM);
3239 }
3240 QCBOREncode_AddBytes(pMe, Bytes);
3241}
3242
3243static inline void
3244QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pMe,
3245 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003246 const uint8_t uTagRequirement,
3247 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003248{
3249 QCBOREncode_AddSZString(pMe, szLabel);
3250 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
3251}
3252
3253static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003254QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003255 const int64_t nLabel,
3256 const uint8_t uTagRequirement,
3257 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003258{
3259 QCBOREncode_AddInt64(pMe, nLabel);
3260 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
3261}
3262
3263static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003264QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003265{
3266 QCBOREncode_AddTNegativeBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
3267}
3268
3269static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003270QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pMe,
3271 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003272 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003273{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003274 QCBOREncode_AddTNegativeBignumToMapSZ(pMe,
3275 szLabel,
3276 QCBOR_ENCODE_AS_TAG,
3277 Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003278}
3279
3280static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003281QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003282 const int64_t nLabel,
3283 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003284{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003285 QCBOREncode_AddTNegativeBignumToMapN(pMe,
3286 nLabel,
3287 QCBOR_ENCODE_AS_TAG,
3288 Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003289}
3290
3291
Michael Eckel5c531332020-03-02 01:35:30 +01003292
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07003293#ifndef QCBOR_DISABLE_EXP_AND_MANTISSA
Michael Eckel5c531332020-03-02 01:35:30 +01003294
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003295static inline void
3296QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003297 const uint8_t uTagRequirement,
3298 const int64_t nMantissa,
3299 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003300{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003301 uint64_t uTag;
3302 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3303 uTag = CBOR_TAG_DECIMAL_FRACTION;
3304 } else {
3305 uTag = CBOR_TAG_INVALID64;
3306 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003307 QCBOREncode_Private_AddExpMantissa(pMe,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003308 uTag,
Michael Eckel5c531332020-03-02 01:35:30 +01003309 NULLUsefulBufC,
3310 false,
3311 nMantissa,
3312 nBase10Exponent);
3313}
3314
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003315static inline void
3316QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pMe,
3317 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003318 const uint8_t uTagRequirement,
3319 const int64_t nMantissa,
3320 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003321{
3322 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003323 QCBOREncode_AddTDecimalFraction(pMe,
3324 uTagRequirement,
3325 nMantissa,
3326 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003327}
3328
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003329static inline void
3330QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003331 const int64_t nLabel,
3332 const uint8_t uTagRequirement,
3333 const int64_t nMantissa,
3334 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003335{
3336 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003337 QCBOREncode_AddTDecimalFraction(pMe,
3338 uTagRequirement,
3339 nMantissa,
3340 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003341}
3342
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003343static inline void
3344QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003345 const int64_t nMantissa,
3346 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003347{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003348 QCBOREncode_AddTDecimalFraction(pMe,
3349 QCBOR_ENCODE_AS_TAG,
3350 nMantissa,
3351 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003352}
3353
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003354static inline void
3355QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pMe,
3356 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003357 const int64_t nMantissa,
3358 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003359{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003360 QCBOREncode_AddTDecimalFractionToMapSZ(pMe,
3361 szLabel,
3362 QCBOR_ENCODE_AS_TAG,
3363 nMantissa,
3364 nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003365}
3366
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003367static inline void
3368QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003369 const int64_t nLabel,
3370 const int64_t nMantissa,
3371 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003372{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003373 QCBOREncode_AddTDecimalFractionToMapN(pMe,
3374 nLabel,
3375 QCBOR_ENCODE_AS_TAG,
3376 nMantissa,
3377 nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003378}
3379
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003380
3381
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003382static inline void
3383QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003384 const uint8_t uTagRequirement,
3385 const UsefulBufC Mantissa,
3386 const bool bIsNegative,
3387 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003388{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003389 uint64_t uTag;
3390 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3391 uTag = CBOR_TAG_DECIMAL_FRACTION;
3392 } else {
3393 uTag = CBOR_TAG_INVALID64;
3394 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003395 QCBOREncode_Private_AddExpMantissa(pMe,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003396 uTag,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003397 Mantissa,
3398 bIsNegative,
Michael Eckel5c531332020-03-02 01:35:30 +01003399 0,
3400 nBase10Exponent);
3401}
3402
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003403static inline void
3404QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
3405 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003406 const uint8_t uTagRequirement,
3407 const UsefulBufC Mantissa,
3408 const bool bIsNegative,
3409 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003410{
3411 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003412 QCBOREncode_AddTDecimalFractionBigNum(pMe,
3413 uTagRequirement,
3414 Mantissa,
3415 bIsNegative,
3416 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003417}
3418
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003419static inline void
3420QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003421 const int64_t nLabel,
3422 const uint8_t uTagRequirement,
3423 const UsefulBufC Mantissa,
3424 const bool bIsNegative,
3425 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003426{
3427 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003428 QCBOREncode_AddTDecimalFractionBigNum(pMe,
3429 uTagRequirement,
3430 Mantissa,
3431 bIsNegative,
3432 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003433}
3434
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003435static inline void
3436QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003437 const UsefulBufC Mantissa,
3438 const bool bIsNegative,
3439 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003440{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003441 QCBOREncode_AddTDecimalFractionBigNum(pMe,
3442 QCBOR_ENCODE_AS_TAG,
3443 Mantissa,
3444 bIsNegative,
3445 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003446}
3447
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003448static inline void
3449QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
3450 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003451 const UsefulBufC Mantissa,
3452 const bool bIsNegative,
3453 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003454{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003455 QCBOREncode_AddTDecimalFractionBigNumToMapSZ(pMe,
3456 szLabel,
3457 QCBOR_ENCODE_AS_TAG,
3458 Mantissa,
3459 bIsNegative,
3460 nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003461}
3462
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003463static inline void
3464QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003465 const int64_t nLabel,
3466 const UsefulBufC Mantissa,
3467 const bool bIsNegative,
3468 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003469{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003470 QCBOREncode_AddTDecimalFractionBigNumToMapN(pMe,
3471 nLabel,
3472 QCBOR_ENCODE_AS_TAG,
3473 Mantissa,
3474 bIsNegative,
3475 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003476}
3477
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003478
3479
3480
3481
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003482static inline void
3483QCBOREncode_AddTBigFloat(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003484 const uint8_t uTagRequirement,
3485 const int64_t nMantissa,
3486 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003487{
3488 uint64_t uTag;
3489 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3490 uTag = CBOR_TAG_BIGFLOAT;
3491 } else {
3492 uTag = CBOR_TAG_INVALID64;
3493 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003494 QCBOREncode_Private_AddExpMantissa(pMe,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003495 uTag,
3496 NULLUsefulBufC,
3497 false,
3498 nMantissa,
3499 nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003500}
3501
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003502static inline void
3503QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pMe,
3504 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003505 const uint8_t uTagRequirement,
3506 const int64_t nMantissa,
3507 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003508{
3509 QCBOREncode_AddSZString(pMe, szLabel);
3510 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
3511}
3512
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003513static inline void
3514QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003515 const int64_t nLabel,
3516 const uint8_t uTagRequirement,
3517 const int64_t nMantissa,
3518 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003519{
3520 QCBOREncode_AddInt64(pMe, nLabel);
3521 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
3522}
3523
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003524static inline void
3525QCBOREncode_AddBigFloat(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003526 const int64_t nMantissa,
3527 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003528{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003529 QCBOREncode_AddTBigFloat(pMe,
3530 QCBOR_ENCODE_AS_TAG,
3531 nMantissa,
3532 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003533}
3534
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003535static inline void
3536QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pMe,
3537 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003538 const int64_t nMantissa,
3539 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003540{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003541 QCBOREncode_AddTBigFloatToMapSZ(pMe,
3542 szLabel,
3543 QCBOR_ENCODE_AS_TAG,
3544 nMantissa,
3545 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003546}
3547
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003548static inline void
3549QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003550 const int64_t nLabel,
3551 const int64_t nMantissa,
3552 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003553{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003554 QCBOREncode_AddTBigFloatToMapN(pMe,
3555 nLabel,
3556 QCBOR_ENCODE_AS_TAG,
3557 nMantissa,
3558 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003559}
3560
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003561
3562
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003563static inline void
3564QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003565 const uint8_t uTagRequirement,
3566 const UsefulBufC Mantissa,
3567 const bool bIsNegative,
3568 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003569{
3570 uint64_t uTag;
3571 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3572 uTag = CBOR_TAG_BIGFLOAT;
3573 } else {
3574 uTag = CBOR_TAG_INVALID64;
3575 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003576 QCBOREncode_Private_AddExpMantissa(pMe,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003577 uTag,
3578 Mantissa,
3579 bIsNegative,
3580 0,
3581 nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003582}
3583
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003584static inline void
3585QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pMe,
3586 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003587 const uint8_t uTagRequirement,
3588 const UsefulBufC Mantissa,
3589 const bool bIsNegative,
3590 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003591{
3592 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003593 QCBOREncode_AddTBigFloatBigNum(pMe,
3594 uTagRequirement,
3595 Mantissa,
3596 bIsNegative,
3597 nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003598}
3599
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003600static inline void
3601QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003602 const int64_t nLabel,
3603 const uint8_t uTagRequirement,
3604 const UsefulBufC Mantissa,
3605 const bool bIsNegative,
3606 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003607{
3608 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003609 QCBOREncode_AddTBigFloatBigNum(pMe,
3610 uTagRequirement,
3611 Mantissa,
3612 bIsNegative,
3613 nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003614}
3615
3616
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003617static inline void
3618QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003619 const UsefulBufC Mantissa,
3620 const bool bIsNegative,
3621 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003622{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003623 QCBOREncode_AddTBigFloatBigNum(pMe,
3624 QCBOR_ENCODE_AS_TAG,
3625 Mantissa, bIsNegative,
3626 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003627}
3628
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003629static inline void
3630QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pMe,
3631 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003632 const UsefulBufC Mantissa,
3633 const bool bIsNegative,
3634 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003635{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003636 QCBOREncode_AddTBigFloatBigNumToMapSZ(pMe,
3637 szLabel,
3638 QCBOR_ENCODE_AS_TAG,
3639 Mantissa,
3640 bIsNegative,
3641 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003642}
3643
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003644static inline void
3645QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003646 const int64_t nLabel,
3647 const UsefulBufC Mantissa,
3648 const bool bIsNegative,
3649 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003650{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003651 QCBOREncode_AddTBigFloatBigNumToMapN(pMe,
3652 nLabel,
3653 QCBOR_ENCODE_AS_TAG,
3654 Mantissa,
3655 bIsNegative,
3656 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003657}
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07003658#endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
Michael Eckel5c531332020-03-02 01:35:30 +01003659
3660
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003661static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003662QCBOREncode_AddTURI(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003663 const uint8_t uTagRequirement,
3664 const UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01003665{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003666 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3667 QCBOREncode_AddTag(pMe, CBOR_TAG_URI);
3668 }
3669 QCBOREncode_AddText(pMe, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01003670}
3671
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003672static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003673QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pMe,
3674 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003675 const uint8_t uTagRequirement,
3676 const UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01003677{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003678 QCBOREncode_AddSZString(pMe, szLabel);
3679 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01003680}
3681
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003682static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003683QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003684 const int64_t nLabel,
3685 const uint8_t uTagRequirement,
3686 const UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01003687{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003688 QCBOREncode_AddInt64(pMe, nLabel);
3689 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
3690}
3691
3692static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003693QCBOREncode_AddURI(QCBOREncodeContext *pMe, const UsefulBufC URI)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003694{
3695 QCBOREncode_AddTURI(pMe, QCBOR_ENCODE_AS_TAG, URI);
3696}
3697
3698static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003699QCBOREncode_AddURIToMap(QCBOREncodeContext *pMe,
3700 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003701 const UsefulBufC URI)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003702{
3703 QCBOREncode_AddTURIToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, URI);
3704}
3705
3706static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003707QCBOREncode_AddURIToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003708 const int64_t nLabel,
3709 const UsefulBufC URI)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003710{
3711 QCBOREncode_AddTURIToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01003712}
3713
3714
3715
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003716static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003717QCBOREncode_AddTB64Text(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003718 const uint8_t uTagRequirement,
3719 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003720{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003721 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3722 QCBOREncode_AddTag(pMe, CBOR_TAG_B64);
3723 }
3724 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003725}
3726
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003727static inline void
3728QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pMe,
3729 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003730 const uint8_t uTagRequirement,
3731 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003732{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003733 QCBOREncode_AddSZString(pMe, szLabel);
3734 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003735}
3736
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003737static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003738QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003739 const int64_t nLabel,
3740 const uint8_t uTagRequirement,
3741 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003742{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003743 QCBOREncode_AddInt64(pMe, nLabel);
3744 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
3745}
3746
3747static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003748QCBOREncode_AddB64Text(QCBOREncodeContext *pMe, const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003749{
3750 QCBOREncode_AddTB64Text(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
3751}
3752
3753static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003754QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pMe,
3755 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003756 const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003757{
3758 QCBOREncode_AddTB64TextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
3759}
3760
3761static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003762QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003763 const int64_t nLabel,
3764 const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003765{
3766 QCBOREncode_AddTB64TextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003767}
3768
3769
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003770
3771static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003772QCBOREncode_AddTB64URLText(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003773 const uint8_t uTagRequirement,
3774 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003775{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003776 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3777 QCBOREncode_AddTag(pMe, CBOR_TAG_B64URL);
3778 }
3779 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003780}
3781
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003782static inline void
3783QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pMe,
3784 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003785 const uint8_t uTagRequirement,
3786 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003787{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003788 QCBOREncode_AddSZString(pMe, szLabel);
3789 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003790}
3791
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003792static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003793QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003794 const int64_t nLabel,
3795 const uint8_t uTagRequirement,
3796 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003797{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003798 QCBOREncode_AddInt64(pMe, nLabel);
3799 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
3800}
3801
3802static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003803QCBOREncode_AddB64URLText(QCBOREncodeContext *pMe, const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003804{
3805 QCBOREncode_AddTB64URLText(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
3806}
3807
3808static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003809QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pMe,
3810 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003811 const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003812{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003813 QCBOREncode_AddTB64URLTextToMapSZ(pMe,
3814 szLabel,
3815 QCBOR_ENCODE_AS_TAG,
3816 B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003817}
3818
3819static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003820QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003821 const int64_t nLabel,
3822 const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003823{
3824 QCBOREncode_AddTB64URLTextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003825}
3826
3827
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003828
3829static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003830QCBOREncode_AddTRegex(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003831 const uint8_t uTagRequirement,
3832 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003833{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003834 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3835 QCBOREncode_AddTag(pMe, CBOR_TAG_REGEX);
3836 }
3837 QCBOREncode_AddText(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01003838}
3839
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003840static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003841QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pMe,
3842 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003843 const uint8_t uTagRequirement,
3844 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003845{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003846 QCBOREncode_AddSZString(pMe, szLabel);
3847 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01003848}
3849
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003850static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003851QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003852 const int64_t nLabel,
3853 const uint8_t uTagRequirement,
3854 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003855{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003856 QCBOREncode_AddInt64(pMe, nLabel);
3857 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
3858}
3859
3860static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003861QCBOREncode_AddRegex(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003862{
3863 QCBOREncode_AddTRegex(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
3864}
3865
3866static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003867QCBOREncode_AddRegexToMap(QCBOREncodeContext *pMe,
3868 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003869 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003870{
3871 QCBOREncode_AddTRegexToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
3872}
3873
3874static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003875QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003876 const int64_t nLabel,
3877 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003878{
3879 QCBOREncode_AddTRegexToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
3880
Michael Eckel5c531332020-03-02 01:35:30 +01003881}
3882
3883
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003884static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003885QCBOREncode_AddTMIMEData(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003886 const uint8_t uTagRequirement,
3887 const UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01003888{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003889 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
Laurence Lundblade4982f412020-09-18 23:02:18 -07003890 QCBOREncode_AddTag(pMe, CBOR_TAG_BINARY_MIME);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003891 }
Laurence Lundblade4982f412020-09-18 23:02:18 -07003892 QCBOREncode_AddBytes(pMe, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01003893}
3894
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003895static inline void
3896QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pMe,
3897 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003898 const uint8_t uTagRequirement,
3899 const UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01003900{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003901 QCBOREncode_AddSZString(pMe, szLabel);
3902 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01003903}
3904
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003905static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003906QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003907 const int64_t nLabel,
3908 const uint8_t uTagRequirement,
3909 const UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01003910{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003911 QCBOREncode_AddInt64(pMe, nLabel);
3912 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
3913}
3914
3915static inline void
3916QCBOREncode_AddMIMEData(QCBOREncodeContext *pMe, UsefulBufC MIMEData)
3917{
3918 QCBOREncode_AddTMIMEData(pMe, QCBOR_ENCODE_AS_TAG, MIMEData);
3919}
3920
3921static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003922QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pMe,
3923 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003924 const UsefulBufC MIMEData)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003925{
3926 QCBOREncode_AddTMIMEDataToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
3927}
3928
3929static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003930QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003931 const int64_t nLabel,
3932 const UsefulBufC MIMEData)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003933{
3934 QCBOREncode_AddTMIMEDataToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01003935}
3936
3937
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003938static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003939QCBOREncode_AddTDateString(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003940 const uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003941 const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01003942{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003943 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3944 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_STRING);
3945 }
3946 QCBOREncode_AddSZString(pMe, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01003947}
3948
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003949static inline void
3950QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pMe,
3951 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003952 const uint8_t uTagRequirement,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003953 const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01003954{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003955 QCBOREncode_AddSZString(pMe, szLabel);
3956 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01003957}
3958
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003959static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003960QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003961 const int64_t nLabel,
3962 const uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003963 const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01003964{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003965 QCBOREncode_AddInt64(pMe, nLabel);
3966 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
3967}
3968
3969static inline void
3970QCBOREncode_AddDateString(QCBOREncodeContext *pMe, const char *szDate)
3971{
3972 QCBOREncode_AddTDateString(pMe, QCBOR_ENCODE_AS_TAG, szDate);
3973}
3974
3975static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003976QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pMe,
3977 const char *szLabel,
3978 const char *szDate)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003979{
3980 QCBOREncode_AddTDateStringToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, szDate);
3981}
3982
3983static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003984QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003985 const int64_t nLabel,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003986 const char *szDate)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003987{
3988 QCBOREncode_AddTDateStringToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01003989}
3990
3991
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003992static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003993QCBOREncode_AddTDaysString(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003994 const uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003995 const char *szDate)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07003996{
3997 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3998 QCBOREncode_AddTag(pMe, CBOR_TAG_DAYS_STRING);
3999 }
4000 QCBOREncode_AddSZString(pMe, szDate);
4001}
4002
4003static inline void
4004QCBOREncode_AddTDaysStringToMapSZ(QCBOREncodeContext *pMe,
4005 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004006 const uint8_t uTagRequirement,
Laurence Lundblade46d63e92021-05-13 11:37:10 -07004007 const char *szDate)
4008{
4009 QCBOREncode_AddSZString(pMe, szLabel);
4010 QCBOREncode_AddTDaysString(pMe, uTagRequirement, szDate);
4011}
4012
4013static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07004014QCBOREncode_AddTDaysStringToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004015 const int64_t nLabel,
4016 const uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07004017 const char *szDate)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07004018{
4019 QCBOREncode_AddInt64(pMe, nLabel);
4020 QCBOREncode_AddTDaysString(pMe, uTagRequirement, szDate);
4021}
4022
4023
Laurence Lundblade46d63e92021-05-13 11:37:10 -07004024static inline void
Laurence Lundbladecbd7d132024-05-19 11:11:22 -07004025QCBOREncode_AddSimple(QCBOREncodeContext *pMe, const uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01004026{
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -08004027#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
4028 if(pMe->uMode >= QCBOR_ENCODE_MODE_DCBOR) {
4029 if(uNum < CBOR_SIMPLEV_FALSE ||
4030 uNum > CBOR_SIMPLEV_NULL) {
4031 pMe->uError = QCBOR_ERR_NOT_PREFERRED;
4032 return;
4033 }
4034 }
Laurence Lundblade70fc1252024-05-31 10:57:28 -07004035 /* This check often is optimized out because uNum is known at compile time. */
Laurence Lundbladecbd7d132024-05-19 11:11:22 -07004036 if(uNum >= CBOR_SIMPLEV_RESERVED_START && uNum <= CBOR_SIMPLEV_RESERVED_END) {
4037 pMe->uError = QCBOR_ERR_ENCODE_UNSUPPORTED;
4038 return;
4039 }
4040#endif /* !QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -08004041
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004042 QCBOREncode_Private_AddType7(pMe, 0, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01004043}
4044
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004045static inline void
Laurence Lundbladecbd7d132024-05-19 11:11:22 -07004046QCBOREncode_AddSimpleToMap(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004047 const char *szLabel,
4048 const uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01004049{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004050 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundbladecbd7d132024-05-19 11:11:22 -07004051 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01004052}
4053
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004054static inline void
Laurence Lundbladecbd7d132024-05-19 11:11:22 -07004055QCBOREncode_AddSimpleToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004056 const int64_t nLabel,
4057 const uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01004058{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004059 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundbladecbd7d132024-05-19 11:11:22 -07004060 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01004061}
4062
4063
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004064static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004065QCBOREncode_AddBool(QCBOREncodeContext *pMe, const bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01004066{
4067 uint8_t uSimple = CBOR_SIMPLEV_FALSE;
4068 if(b) {
4069 uSimple = CBOR_SIMPLEV_TRUE;
4070 }
Laurence Lundbladecbd7d132024-05-19 11:11:22 -07004071 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01004072}
4073
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004074static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004075QCBOREncode_AddBoolToMap(QCBOREncodeContext *pMe, const char *szLabel, const bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01004076{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004077 QCBOREncode_AddSZString(pMe, szLabel);
4078 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01004079}
4080
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004081static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004082QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pMe, const int64_t nLabel, const bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01004083{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004084 QCBOREncode_AddInt64(pMe, nLabel);
4085 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01004086}
4087
4088
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004089static inline void
4090QCBOREncode_AddNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01004091{
Laurence Lundbladecbd7d132024-05-19 11:11:22 -07004092 QCBOREncode_AddSimple(pMe, CBOR_SIMPLEV_NULL);
Michael Eckel5c531332020-03-02 01:35:30 +01004093}
4094
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004095static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004096QCBOREncode_AddNULLToMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01004097{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004098 QCBOREncode_AddSZString(pMe, szLabel);
4099 QCBOREncode_AddNULL(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01004100}
4101
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004102static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004103QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01004104{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004105 QCBOREncode_AddInt64(pMe, nLabel);
4106 QCBOREncode_AddNULL(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01004107}
4108
4109
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004110static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004111QCBOREncode_AddUndef(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01004112{
Laurence Lundbladecbd7d132024-05-19 11:11:22 -07004113 QCBOREncode_AddSimple(pMe, CBOR_SIMPLEV_UNDEF);
Michael Eckel5c531332020-03-02 01:35:30 +01004114}
4115
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004116static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004117QCBOREncode_AddUndefToMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01004118{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004119 QCBOREncode_AddSZString(pMe, szLabel);
4120 QCBOREncode_AddUndef(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01004121}
4122
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004123static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004124QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01004125{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004126 QCBOREncode_AddInt64(pMe, nLabel);
4127 QCBOREncode_AddUndef(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01004128}
4129
4130
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004131static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004132QCBOREncode_OpenArray(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01004133{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004134 QCBOREncode_Private_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
Michael Eckel5c531332020-03-02 01:35:30 +01004135}
4136
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004137static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004138QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01004139{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004140 QCBOREncode_AddSZString(pMe, szLabel);
4141 QCBOREncode_OpenArray(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01004142}
4143
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004144static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004145QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01004146{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004147 QCBOREncode_AddInt64(pMe, nLabel);
4148 QCBOREncode_OpenArray(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01004149}
4150
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -08004151
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004152static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004153QCBOREncode_CloseArray(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01004154{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004155 QCBOREncode_Private_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
Michael Eckel5c531332020-03-02 01:35:30 +01004156}
4157
4158
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004159static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004160QCBOREncode_OpenMap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01004161{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004162 QCBOREncode_Private_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
Michael Eckel5c531332020-03-02 01:35:30 +01004163}
4164
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004165static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004166QCBOREncode_OpenMapInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01004167{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004168 QCBOREncode_AddSZString(pMe, szLabel);
4169 QCBOREncode_OpenMap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01004170}
4171
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004172static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004173QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01004174{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004175 QCBOREncode_AddInt64(pMe, nLabel);
4176 QCBOREncode_OpenMap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01004177}
4178
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004179static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004180QCBOREncode_CloseMap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01004181{
Laurence Lundbladeeb3cdef2024-02-17 20:38:55 -08004182 (pMe->pfnCloseMap)(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01004183}
4184
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004185static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004186QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01004187{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004188 QCBOREncode_Private_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01004189}
4190
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004191static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07004192QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pMe,
4193 const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01004194{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004195 QCBOREncode_AddSZString(pMe, szLabel);
4196 QCBOREncode_OpenArrayIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01004197}
4198
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004199static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07004200QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004201 const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01004202{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004203 QCBOREncode_AddInt64(pMe, nLabel);
4204 QCBOREncode_OpenArrayIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01004205}
4206
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004207static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004208QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01004209{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004210 QCBOREncode_Private_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01004211}
4212
4213
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004214static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004215QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01004216{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004217 QCBOREncode_Private_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01004218}
4219
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004220static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07004221QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pMe,
4222 const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01004223{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004224 QCBOREncode_AddSZString(pMe, szLabel);
4225 QCBOREncode_OpenMapIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01004226}
4227
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004228static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07004229QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004230 const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01004231{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004232 QCBOREncode_AddInt64(pMe, nLabel);
4233 QCBOREncode_OpenMapIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01004234}
4235
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004236static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004237QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01004238{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004239 QCBOREncode_Private_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01004240}
4241
4242
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004243static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004244QCBOREncode_BstrWrap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01004245{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004246 QCBOREncode_Private_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_BYTE_STRING);
Michael Eckel5c531332020-03-02 01:35:30 +01004247}
4248
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004249static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004250QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01004251{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004252 QCBOREncode_AddSZString(pMe, szLabel);
4253 QCBOREncode_BstrWrap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01004254}
4255
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004256static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004257QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01004258{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004259 QCBOREncode_AddInt64(pMe, nLabel);
4260 QCBOREncode_BstrWrap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01004261}
4262
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004263static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004264QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pMe, UsefulBufC *pWrappedCBOR)
Michael Eckel5c531332020-03-02 01:35:30 +01004265{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004266 QCBOREncode_CloseBstrWrap2(pMe, true, pWrappedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01004267}
4268
4269
Michael Eckel5c531332020-03-02 01:35:30 +01004270
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004271static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07004272QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pMe,
4273 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004274 const UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01004275{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004276 QCBOREncode_AddSZString(pMe, szLabel);
4277 QCBOREncode_AddEncoded(pMe, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01004278}
4279
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004280static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07004281QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07004282 const int64_t nLabel,
4283 const UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01004284{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004285 QCBOREncode_AddInt64(pMe, nLabel);
4286 QCBOREncode_AddEncoded(pMe, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01004287}
4288
4289
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004290static inline int
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004291QCBOREncode_IsBufferNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01004292{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004293 return UsefulOutBuf_IsBufferNULL(&(pMe->OutBuf));
Michael Eckel5c531332020-03-02 01:35:30 +01004294}
4295
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07004296static inline QCBORError
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004297QCBOREncode_GetErrorState(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01004298{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004299 if(UsefulOutBuf_GetError(&(pMe->OutBuf))) {
Laurence Lundbladef2f0c3f2024-04-12 13:01:54 -07004300 /* Items didn't fit in the buffer. This check catches this
4301 * condition for all the appends and inserts so checks aren't
4302 * needed when the appends and inserts are performed. And of
4303 * course UsefulBuf will never overrun the input buffer given to
4304 * it. No complex analysis of the error handling in this file is
4305 * needed to know that is true. Just read the UsefulBuf code.
4306 */
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004307 pMe->uError = QCBOR_ERR_BUFFER_TOO_SMALL;
Laurence Lundbladef2f0c3f2024-04-12 13:01:54 -07004308 /* QCBOR_ERR_BUFFER_TOO_SMALL masks other errors, but that is
4309 * OK. Once the caller fixes this, they'll be unmasked.
4310 */
Michael Eckel5c531332020-03-02 01:35:30 +01004311 }
4312
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07004313 return (QCBORError)pMe->uError;
Michael Eckel5c531332020-03-02 01:35:30 +01004314}
4315
4316
Laurence Lundblade45d5e482020-09-15 21:15:15 -07004317/* ========================================================================
4318 END OF PRIVATE INLINE IMPLEMENTATION
4319 ======================================================================== */
Michael Eckel5c531332020-03-02 01:35:30 +01004320
4321#ifdef __cplusplus
4322}
4323#endif
4324
Laurence Lundblade844bb5c2020-03-01 17:27:25 -08004325#endif /* qcbor_encode_h */