blob: 75b4d642c61dcb57956807c084976dc7a4bfc77d [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 Lundblade3eead482023-12-16 20:53:22 -0700369 *
370 * The public interface uses @c size_t for all lengths. Internally the
371 * implementation uses 32-bit lengths by design to use less memory and
372 * fit structures on the stack. This limits the encoded CBOR it can
Laurence Lundblade475c2722024-05-08 11:17:47 -0700373 * work with to size @c UINT32_MAX (4GB).
Laurence Lundblade3eead482023-12-16 20:53:22 -0700374 *
Laurence Lundblade475c2722024-05-08 11:17:47 -0700375 * This implementation requires two's compliment integers. While
376 * C doesn't require two's compliment, <stdint.h> does. Other
377 * parts of this implementation may also require two's compliment.
Michael Eckel5c531332020-03-02 01:35:30 +0100378 */
379
380
Laurence Lundblade825164e2020-10-22 20:18:06 -0700381/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700382 * The size of the buffer to be passed to QCBOREncode_EncodeHead(). It
383 * is one byte larger than sizeof(uint64_t) + 1, the actual maximum
384 * size of the head of a CBOR data item because
385 * QCBOREncode_EncodeHead() needs one extra byte to work.
Michael Eckel5c531332020-03-02 01:35:30 +0100386 */
387#define QCBOR_HEAD_BUFFER_SIZE (sizeof(uint64_t) + 2)
388
Michael Eckel5c531332020-03-02 01:35:30 +0100389
Laurence Lundblade9b334962020-08-27 10:55:53 -0700390/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700391 * Output the full CBOR tag. See @ref CBORTags, @ref Tag-Usage and
392 * @ref Tags-Overview.
Laurence Lundblade9b334962020-08-27 10:55:53 -0700393 */
394#define QCBOR_ENCODE_AS_TAG 0
395
396/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700397 * Output only the 'borrowed' content format for the relevant tag.
398 * See @ref CBORTags, @ref Tag-Usage and @ref Tags-Overview.
Laurence Lundblade9b334962020-08-27 10:55:53 -0700399 */
400#define QCBOR_ENCODE_AS_BORROWED 1
401
Michael Eckel5c531332020-03-02 01:35:30 +0100402
403/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700404 * QCBOREncodeContext is the data type that holds context for all the
405 * encoding functions. It is less than 200 bytes, so it can go on the
406 * stack. The contents are opaque, and the caller should not access
407 * internal members. A context may be re used serially as long as it is
408 * re initialized.
Michael Eckel5c531332020-03-02 01:35:30 +0100409 */
410typedef struct _QCBOREncodeContext QCBOREncodeContext;
411
412
413/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700414 * Initialize the encoder to prepare to encode some CBOR.
415 *
416 * @param[in,out] pCtx The encoder context to initialize.
417 * @param[in] Storage The buffer into which the encoded result
418 * will be written.
419 *
420 * Call this once at the start of an encoding of some CBOR. Then call
421 * the many functions like QCBOREncode_AddInt64() and
422 * QCBOREncode_AddText() to add the different data items. Finally,
423 * call QCBOREncode_Finish() to get the pointer and length of the
424 * encoded result.
425 *
426 * The primary purpose of this function is to give the pointer and
427 * length of the output buffer into which the encoded CBOR will be
428 * written. This is done with a @ref UsefulBuf structure, which is
429 * just a pointer and length (it is equivalent to two parameters, one
430 * a pointer and one a length, but a little prettier).
431 *
432 * The output buffer can be allocated any way (malloc, stack,
433 * static). It is just some memory that QCBOR writes to. The length
434 * must be the length of the allocated buffer. QCBOR will never write
435 * past that length, but might write up to that length. If the buffer
436 * is too small, encoding will go into an error state and not write
437 * anything further.
438 *
439 * If allocating on the stack the convenience macro
440 * UsefulBuf_MAKE_STACK_UB() can be used, but its use is not required.
441 *
442 * Since there is no reallocation or such, the output buffer must be
443 * correctly sized when passed in here. It is OK, but wasteful if it
444 * is too large. One way to pick the size is to figure out the maximum
445 * size that will ever be needed and hard code a buffer of that size.
446 *
447 * Another way to do it is to have QCBOR calculate it for you. To do
448 * this, pass @ref SizeCalculateUsefulBuf for @c Storage. Then call
449 * all the functions to add the CBOR exactly as if encoding for
450 * real. Finally, call QCBOREncode_FinishGetSize(). Once the length
451 * is obtained, allocate a buffer of that size, call
452 * QCBOREncode_Init() again with the real buffer. Call all the add
453 * functions again and finally, QCBOREncode_Finish() to obtain the
454 * final result. This uses twice the CPU time, but that is usually not
455 * an issue.
456 *
457 * See QCBOREncode_Finish() for how the pointer and length for the
458 * encoded CBOR is returned.
459 *
460 * For practical purposes QCBOR can't output encoded CBOR larger than
461 * @c UINT32_MAX (4GB) even on 64-bit CPUs because the internal
462 * offsets used to track the start of an array/map are 32 bits to
463 * reduce the size of the encoding context.
464 *
465 * A @ref QCBOREncodeContext can be reused over and over as long as
466 * QCBOREncode_Init() is called before each use.
Michael Eckel5c531332020-03-02 01:35:30 +0100467 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700468void
469QCBOREncode_Init(QCBOREncodeContext *pCtx, UsefulBuf Storage);
Michael Eckel5c531332020-03-02 01:35:30 +0100470
471
472/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700473 * @brief Add a signed 64-bit integer to the encoded output.
474 *
475 * @param[in] pCtx The encoding context to add the integer to.
476 * @param[in] nNum The integer to add.
477 *
478 * The integer will be encoded and added to the CBOR output.
479 *
480 * This function figures out the size and the sign and encodes in the
481 * correct minimal CBOR. Specifically, it will select CBOR major type
482 * 0 or 1 based on sign and will encode to 1, 2, 4 or 8 bytes
483 * depending on the value of the integer. Values less than 24
484 * effectively encode to one byte because they are encoded in with the
485 * CBOR major type. This is a neat and efficient characteristic of
486 * CBOR that can be taken advantage of when designing CBOR-based
487 * protocols. If integers like tags can be kept between -23 and 23
488 * they will be encoded in one byte including the major type.
489 *
490 * If you pass a smaller int, say an @c int16_t or a small value, say
491 * 100, the encoding will still be CBOR's most compact that can
492 * represent the value. For example, CBOR always encodes the value 0
493 * as one byte, 0x00. The representation as 0x00 includes
494 * identification of the type as an integer too as the major type for
495 * an integer is 0. See [RFC 8949]
496 * (https://tools.ietf.org/html/rfc8949) Appendix A for more examples
497 * of CBOR encoding. This compact encoding is also preferred
498 * serialization CBOR as per section 34.1 in RFC 8949.
499 *
500 * There are no functions to add @c int16_t or @c int32_t because they
501 * are not necessary because this always encodes to the smallest
502 * number of bytes based on the value (If this code is running on a
503 * 32-bit machine having a way to add 32-bit integers would reduce
504 * code size some).
505 *
506 * If the encoding context is in an error state, this will do
507 * nothing. If an error occurs when adding this integer, the internal
508 * error flag will be set, and the error will be returned when
509 * QCBOREncode_Finish() is called.
510 *
511 * See also QCBOREncode_AddUInt64().
Michael Eckel5c531332020-03-02 01:35:30 +0100512 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700513void
514QCBOREncode_AddInt64(QCBOREncodeContext *pCtx, int64_t nNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100515
Laurence Lundblade3eead482023-12-16 20:53:22 -0700516static void
517QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100518
Laurence Lundblade3eead482023-12-16 20:53:22 -0700519static void
520QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100521
522
523/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700524 * @brief Add an unsigned 64-bit integer to the encoded output.
525 *
526 * @param[in] pCtx The encoding context to add the integer to.
527 * @param[in] uNum The integer to add.
528 *
529 * The integer will be encoded and added to the CBOR output.
530 *
531 * The only reason so use this function is for integers larger than
532 * @c INT64_MAX and smaller than @c UINT64_MAX. Otherwise
533 * QCBOREncode_AddInt64() will work fine.
534 *
535 * Error handling is the same as for QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +0100536 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700537void
538QCBOREncode_AddUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100539
Laurence Lundblade3eead482023-12-16 20:53:22 -0700540static void
541QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100542
Laurence Lundblade3eead482023-12-16 20:53:22 -0700543static void
544QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100545
546
547/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700548 * @brief Add a UTF-8 text string to the encoded output.
549 *
550 * @param[in] pCtx The encoding context to add the text to.
551 * @param[in] Text Pointer and length of text to add.
552 *
553 * The text passed in must be unencoded UTF-8 according to [RFC 3629]
554 * (https://tools.ietf.org/html/rfc3629). There is no NULL
555 * termination. The text is added as CBOR major type 3.
556 *
557 * If called with @c nBytesLen equal to 0, an empty string will be
558 * added. When @c nBytesLen is 0, @c pBytes may be @c NULL.
559 *
560 * Note that the restriction of the buffer length to a @c uint32_t is
561 * entirely intentional as this encoder is not capable of encoding
562 * lengths greater. This limit to 4GB for a text string should not be
563 * a problem.
564 *
565 * Text lines in Internet protocols (on the wire) are delimited by
566 * either a CRLF or just an LF. Officially many protocols specify
567 * CRLF, but implementations often work with either. CBOR type 3 text
568 * can be either line ending, even a mixture of both.
569 *
570 * Operating systems usually have a line end convention. Windows uses
571 * CRLF. Linux and MacOS use LF. Some applications on a given OS may
572 * work with either and some may not.
573 *
574 * The majority of use cases and CBOR protocols using type 3 text will
575 * work with either line ending. However, some use cases or protocols
576 * may not work with either in which case translation to and/or from
577 * the local line end convention, typically that of the OS, is
578 * necessary.
579 *
580 * QCBOR does no line ending translation for type 3 text when encoding
581 * and decoding.
582 *
583 * Error handling is the same as QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +0100584 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700585static void
586QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text);
Michael Eckel5c531332020-03-02 01:35:30 +0100587
Laurence Lundblade3eead482023-12-16 20:53:22 -0700588static void
589QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text);
Michael Eckel5c531332020-03-02 01:35:30 +0100590
Laurence Lundblade3eead482023-12-16 20:53:22 -0700591static void
592QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text);
Michael Eckel5c531332020-03-02 01:35:30 +0100593
594
595/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700596 * @brief Add a UTF-8 text string to the encoded output.
597 *
598 * @param[in] pCtx The encoding context to add the text to.
599 * @param[in] szString Null-terminated text to add.
600 *
601 * This works the same as QCBOREncode_AddText().
Michael Eckel5c531332020-03-02 01:35:30 +0100602 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700603static void
604QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString);
Michael Eckel5c531332020-03-02 01:35:30 +0100605
Laurence Lundblade3eead482023-12-16 20:53:22 -0700606static void
607QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString);
Michael Eckel5c531332020-03-02 01:35:30 +0100608
Laurence Lundblade3eead482023-12-16 20:53:22 -0700609static void
610QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString);
Michael Eckel5c531332020-03-02 01:35:30 +0100611
612
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200613#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Michael Eckel5c531332020-03-02 01:35:30 +0100614/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700615 * @brief Add a double-precision floating-point number to the encoded output.
616 *
617 * @param[in] pCtx The encoding context to add the double to.
618 * @param[in] dNum The double-precision number to add.
619 *
620 * This encodes and outputs a floating-point number. CBOR major type 7
621 * is used.
622 *
623 * This implements preferred serialization, selectively encoding the
624 * double-precision floating-point number as either double-precision,
625 * single-precision or half-precision. Infinity, NaN and 0 are always
626 * encoded as half-precision. If no precision will be lost in the
627 * conversion to half-precision, then it will be converted and
628 * encoded. If not and no precision will be lost in conversion to
629 * single-precision, then it will be converted and encoded. If not,
630 * then no conversion is performed, and it encoded as a
631 * double-precision.
632 *
633 * Half-precision floating-point numbers take up 2 bytes, half that of
634 * single-precision, one quarter of double-precision
635 *
636 * This automatically reduces the size of encoded CBOR, maybe even by
637 * four if most of values are 0, infinity or NaN.
638 *
639 * When decoded, QCBOR will usually return these values as
640 * double-precision.
641 *
642 * It is possible to disable this preferred serialization when compiling
643 * QCBOR. In that case, this functions the same as
644 * QCBOREncode_AddDoubleNoPreferred().
645 *
646 * Error handling is the same as QCBOREncode_AddInt64().
647 *
648 * See also QCBOREncode_AddDoubleNoPreferred(), QCBOREncode_AddFloat()
649 * and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
Michael Eckel5c531332020-03-02 01:35:30 +0100650 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700651void
652QCBOREncode_AddDouble(QCBOREncodeContext *pCtx, double dNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100653
Laurence Lundblade3eead482023-12-16 20:53:22 -0700654static void
655QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100656
Laurence Lundblade3eead482023-12-16 20:53:22 -0700657static void
658QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
Michael Eckel5c531332020-03-02 01:35:30 +0100659
660
661/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700662 * @brief Add a single-precision floating-point number to the encoded output.
663 *
664 * @param[in] pCtx The encoding context to add the double to.
665 * @param[in] fNum The single-precision number to add.
666 *
667 * This is identical to QCBOREncode_AddDouble() except the input is
668 * single-precision.
669 *
670 * See also QCBOREncode_AddDouble(), QCBOREncode_AddDoubleNoPreferred(),
671 * and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
672 */
673void
674QCBOREncode_AddFloat(QCBOREncodeContext *pCtx, float fNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700675
Laurence Lundblade3eead482023-12-16 20:53:22 -0700676static void
677QCBOREncode_AddFloatToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700678
Laurence Lundblade3eead482023-12-16 20:53:22 -0700679static void
680QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700681
682
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700683/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700684 * @brief Add a double-precision floating-point number without preferred encoding.
685 *
686 * @param[in] pCtx The encoding context to add the double to.
687 * @param[in] dNum The double-precision number to add.
688 *
689 * This always outputs the number as a 64-bit double-precision.
690 * Preferred serialization is not used.
691 *
692 * Error handling is the same as QCBOREncode_AddInt64().
693 *
694 * See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
695 * QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
696 */
697void
698QCBOREncode_AddDoubleNoPreferred(QCBOREncodeContext *pCtx, double dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700699
Laurence Lundblade3eead482023-12-16 20:53:22 -0700700static void
701QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700702
Laurence Lundblade3eead482023-12-16 20:53:22 -0700703static void
704QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700705
706
707/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700708 * @brief Add a single-precision floating-point number without preferred encoding.
709 *
710 * @param[in] pCtx The encoding context to add the double to.
711 * @param[in] fNum The single-precision number to add.
712 *
713 * This always outputs the number as a 32-bit single-precision.
714 * Preferred serialization is not used.
715 *
716 * Error handling is the same as QCBOREncode_AddInt64().
717 *
718 * See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
719 * QCBOREncode_AddDoubleNoPreferred() and @ref Floating-Point.
720 */
721void
722QCBOREncode_AddFloatNoPreferred(QCBOREncodeContext *pCtx, float fNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700723
Laurence Lundblade3eead482023-12-16 20:53:22 -0700724static void
725QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700726
Laurence Lundblade3eead482023-12-16 20:53:22 -0700727static void
728QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float fNum);
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200729#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700730
731
Michael Eckel5c531332020-03-02 01:35:30 +0100732/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700733 * @brief Add an optional tag.
734 *
735 * @param[in] pCtx The encoding context to add the tag to.
736 * @param[in] uTag The tag to add
737 *
738 * This outputs a CBOR major type 6 item that tags the next data item
739 * that is output usually to indicate it is some new data type.
740 *
741 * For many of the common standard tags, a function to encode data
742 * using it is provided and this is not needed. For example,
743 * QCBOREncode_AddDateEpoch() already exists to output integers
744 * representing dates with the right tag.
745 *
746 * The tag is applied to the next data item added to the encoded
747 * output. That data item that is to be tagged can be of any major
748 * CBOR type. Any number of tags can be added to a data item by
749 * calling this multiple times before the data item is added.
750 *
751 * See @ref Tags-Overview for discussion of creating new non-standard
752 * tags. See QCBORDecode_GetNext() for discussion of decoding custom
753 * tags.
Michael Eckel5c531332020-03-02 01:35:30 +0100754 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700755void
756QCBOREncode_AddTag(QCBOREncodeContext *pCtx, uint64_t uTag);
Laurence Lundblade46d63e92021-05-13 11:37:10 -0700757
758
Michael Eckel5c531332020-03-02 01:35:30 +0100759/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700760 * @brief Add an epoch-based date.
761 *
762 * @param[in] pCtx The encoding context to add the date to.
763 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
764 * @ref QCBOR_ENCODE_AS_BORROWED.
765 * @param[in] nDate Number of seconds since 1970-01-01T00:00Z
766 * in UTC time.
767 *
768 * As per RFC 8949 this is similar to UNIX/Linux/POSIX dates. This is
769 * the most compact way to specify a date and time in CBOR. Note that
770 * this is always UTC and does not include the time zone. Use
771 * QCBOREncode_AddDateString() if you want to include the time zone.
772 *
773 * The preferred integer serialization rules apply here so the date will be
774 * encoded in a minimal number of bytes. Until about the year 2106
775 * these dates will encode in 6 bytes -- one byte for the tag, one
776 * byte for the type and 4 bytes for the integer. After that it will
777 * encode to 10 bytes.
778 *
779 * Negative values are supported for dates before 1970.
780 *
781 * If you care about leap-seconds and that level of accuracy, make sure
782 * the system you are running this code on does it correctly. This code
783 * just takes the value passed in.
784 *
785 * This implementation cannot encode fractional seconds using float or
786 * double even though that is allowed by CBOR, but you can encode them
787 * if you want to by calling QCBOREncode_AddTag() and QCBOREncode_AddDouble().
788 *
789 * Error handling is the same as QCBOREncode_AddInt64().
790 *
791 * See also QCBOREncode_AddTDaysEpoch().
Michael Eckel5c531332020-03-02 01:35:30 +0100792 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700793static void
794QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pCtx,
795 uint8_t uTagRequirement,
796 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100797
Laurence Lundblade3eead482023-12-16 20:53:22 -0700798static void
799QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pCtx,
800 const char *szLabel,
801 uint8_t uTagRequirement,
802 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100803
Laurence Lundblade3eead482023-12-16 20:53:22 -0700804static void
805QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pCtx,
806 int64_t nLabel,
807 uint8_t uTagRequirement,
808 int64_t nDate);
809
810
811static void
812QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx,
813 int64_t nDate);
814
815static void
816QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx,
817 const char *szLabel,
818 int64_t nDate);
819
820static void
821QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx,
822 int64_t nLabel,
823 int64_t nDate);
824
Michael Eckel5c531332020-03-02 01:35:30 +0100825
826
Michael Eckel5c531332020-03-02 01:35:30 +0100827/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700828 * @brief Add an epoch-based day-count date.
829 *
830 * @param[in] pCtx The encoding context to add the date to.
831 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
832 * @ref QCBOR_ENCODE_AS_BORROWED.
833 * @param[in] nDays Number of days before or after 1970-01-0.
834 *
835 * This date format is described in
836 * [RFC 8943] (https://tools.ietf.org/html/rfc8943).
837 *
838 * The preferred integer serialization rules apply here so the date
839 * will be encoded in a minimal number of bytes. Until about the year
840 * 2149 these dates will encode in 4 bytes -- one byte for the tag,
841 * one byte for the type and 2 bytes for the integer.
842 *
843 * See also QCBOREncode_AddTDateEpoch().
844 */
845static void
846QCBOREncode_AddTDaysEpoch(QCBOREncodeContext *pCtx,
847 uint8_t uTagRequirement,
848 int64_t nDays);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600849
Laurence Lundblade3eead482023-12-16 20:53:22 -0700850static void
851QCBOREncode_AddTDaysEpochToMapSZ(QCBOREncodeContext *pCtx,
852 const char *szLabel,
853 uint8_t uTagRequirement,
854 int64_t nDays);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600855
Laurence Lundblade3eead482023-12-16 20:53:22 -0700856static void
857QCBOREncode_AddTDaysEpochToMapN(QCBOREncodeContext *pCtx,
858 int64_t nLabel,
859 uint8_t uTagRequirement,
860 int64_t nDays);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600861
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600862
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600863
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600864
Laurence Lundblade3eead482023-12-16 20:53:22 -0700865/**
866 * @brief Add a byte string to the encoded output.
867 *
868 * @param[in] pCtx The encoding context to add the bytes to.
869 * @param[in] Bytes Pointer and length of the input data.
870 *
871 * Simply adds the bytes to the encoded output as CBOR major type 2.
872 *
873 * If called with @c Bytes.len equal to 0, an empty string will be
874 * added. When @c Bytes.len is 0, @c Bytes.ptr may be @c NULL.
875 *
876 * Error handling is the same as QCBOREncode_AddInt64().
877 */
878static void
879QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600880
Laurence Lundblade3eead482023-12-16 20:53:22 -0700881static void
882QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
883
884static void
885QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
886
887
888/**
889 * @brief Set up to write a byte string value directly to encoded output.
890 *
891 * @param[in] pCtx The encoding context to add the bytes to.
892 * @param[out] pPlace Pointer and length of place to write byte string value.
893 *
894 * QCBOREncode_AddBytes() is the normal way to encode a byte string.
895 * This is for special cases and by passes some of the pointer safety.
896 *
897 * The purpose of this is to output the bytes that make up a byte
898 * string value directly to the QCBOR output buffer so you don't need
899 * to have a copy of it in memory. This is particularly useful if the
900 * byte string is large, for example, the encrypted payload of a
901 * COSE_Encrypt message. The payload encryption algorithm can output
902 * directly to the encoded CBOR buffer, perhaps by making it the
903 * output buffer for some function (e.g. symmetric encryption) or by
904 * multiple writes.
905 *
906 * The pointer in @c pPlace is where to start writing. Writing is just
907 * copying bytes to the location by the pointer in \c pPlace. Writing
908 * past the length in @c pPlace will be writing off the end of the
909 * output buffer.
910 *
911 * If there is no room in the output buffer @ref NULLUsefulBuf will be
912 * returned and there is no need to call QCBOREncode_CloseBytes().
913 *
914 * The byte string must be closed by calling QCBOREncode_CloseBytes().
915 *
916 * Warning: this bypasses some of the usual checks provided by QCBOR
917 * against writing off the end of the encoded output buffer.
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600918 */
919void
920QCBOREncode_OpenBytes(QCBOREncodeContext *pCtx, UsefulBuf *pPlace);
921
922static void
Laurence Lundblade3eead482023-12-16 20:53:22 -0700923QCBOREncode_OpenBytesInMapSZ(QCBOREncodeContext *pCtx,
924 const char *szLabel,
925 UsefulBuf *pPlace);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600926
927static void
Laurence Lundblade3eead482023-12-16 20:53:22 -0700928QCBOREncode_OpenBytesInMapN(QCBOREncodeContext *pCtx,
929 int64_t nLabel,
930 UsefulBuf *pPlace);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600931
932
933/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700934 * @brief Close out a byte string written directly to encoded output.
935 *
936 * @param[in] pCtx The encoding context to add the bytes to.
937 * @param[out] uAmount The number of bytes written, the length of the
938 * byte string.
939 *
940 * This closes out a call to QCBOREncode_OpenBytes(). This inserts a
941 * CBOR header at the front of the byte string value to make it a
942 * well-formed byte string.
943 *
944 * If there was no call to QCBOREncode_OpenBytes() then @ref
945 * QCBOR_ERR_TOO_MANY_CLOSES is set.
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600946 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700947void
948QCBOREncode_CloseBytes(QCBOREncodeContext *pCtx, size_t uAmount);
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600949
950
951/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700952 * @brief Add a binary UUID to the encoded output.
953 *
954 * @param[in] pCtx The encoding context to add the UUID to.
955 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
956 * @ref QCBOR_ENCODE_AS_BORROWED.
957 * @param[in] Bytes Pointer and length of the binary UUID.
958 *
959 * A binary UUID as defined in [RFC 4122]
960 * (https://tools.ietf.org/html/rfc4122) is added to the output.
961 *
962 * It is output as CBOR major type 2, a binary string, with tag @ref
963 * CBOR_TAG_BIN_UUID indicating the binary string is a UUID.
Michael Eckel5c531332020-03-02 01:35:30 +0100964 */
Laurence Lundblade3eead482023-12-16 20:53:22 -0700965static void
966QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pCtx,
967 uint8_t uTagRequirement,
968 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700969
Laurence Lundblade3eead482023-12-16 20:53:22 -0700970static void
971QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pCtx,
972 const char *szLabel,
973 uint8_t uTagRequirement,
974 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700975
Laurence Lundblade3eead482023-12-16 20:53:22 -0700976static void
977QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pCtx,
978 int64_t nLabel,
979 uint8_t uTagRequirement,
980 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700981
982
Laurence Lundblade3eead482023-12-16 20:53:22 -0700983static void
984QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100985
Laurence Lundblade3eead482023-12-16 20:53:22 -0700986static void
987QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100988
Laurence Lundblade3eead482023-12-16 20:53:22 -0700989static void
990QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100991
992
993/**
Laurence Lundblade3eead482023-12-16 20:53:22 -0700994 * @brief Add a positive big number to the encoded output.
995 *
996 * @param[in] pCtx The encoding context to add the big number to.
997 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
998 * @ref QCBOR_ENCODE_AS_BORROWED.
999 * @param[in] Bytes Pointer and length of the big number.
1000 *
1001 * Big numbers are integers larger than 64-bits. Their format is
1002 * described in [RFC 8949] (https://tools.ietf.org/html/rfc8949).
1003 *
1004 * It is output as CBOR major type 2, a binary string, with tag
1005 * @ref CBOR_TAG_POS_BIGNUM indicating the binary string is a positive
1006 * big number.
1007 *
1008 * Often big numbers are used to represent cryptographic keys,
1009 * however, COSE which defines representations for keys chose not to
1010 * use this particular type.
Michael Eckel5c531332020-03-02 01:35:30 +01001011 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001012static void
1013QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pCtx,
1014 uint8_t uTagRequirement,
1015 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001016
Laurence Lundblade3eead482023-12-16 20:53:22 -07001017static void
1018QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pCtx,
1019 const char *szLabel,
1020 uint8_t uTagRequirement,
1021 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001022
Laurence Lundblade3eead482023-12-16 20:53:22 -07001023static void
1024QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pCtx,
1025 int64_t nLabel,
1026 uint8_t uTagRequirement,
1027 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001028
1029
Laurence Lundblade3eead482023-12-16 20:53:22 -07001030static void
1031QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx,
1032 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001033
Laurence Lundblade3eead482023-12-16 20:53:22 -07001034static void
1035QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx,
1036 const char *szLabel,
1037 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001038
Laurence Lundblade3eead482023-12-16 20:53:22 -07001039static void
1040QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx,
1041 int64_t nLabel,
1042 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001043
1044
1045/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001046 * @brief Add a negative big number to the encoded output.
1047 *
1048 * @param[in] pCtx The encoding context to add the big number to.
1049 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1050 * @ref QCBOR_ENCODE_AS_BORROWED.
1051 * @param[in] Bytes Pointer and length of the big number.
1052 *
1053 * Big numbers are integers larger than 64-bits. Their format is
1054 * described in [RFC 8949] (https://tools.ietf.org/html/rfc8949).
1055 *
1056 * It is output as CBOR major type 2, a binary string, with tag
1057 * @ref CBOR_TAG_NEG_BIGNUM indicating the binary string is a negative
1058 * big number.
1059 *
1060 * Often big numbers are used to represent cryptographic keys,
1061 * however, COSE which defines representations for keys chose not to
1062 * use this particular type.
Michael Eckel5c531332020-03-02 01:35:30 +01001063 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001064static void
1065QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pCtx,
1066 uint8_t uTagRequirement,
1067 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001068
Laurence Lundblade3eead482023-12-16 20:53:22 -07001069static void
1070QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pCtx,
1071 const char *szLabel,
1072 uint8_t uTagRequirement,
1073 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001074
Laurence Lundblade3eead482023-12-16 20:53:22 -07001075static void
1076QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pCtx,
1077 int64_t nLabel,
1078 uint8_t uTagRequirement,
1079 UsefulBufC Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001080
1081
Laurence Lundblade3eead482023-12-16 20:53:22 -07001082static void
1083QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx,
1084 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001085
Laurence Lundblade3eead482023-12-16 20:53:22 -07001086static void
1087QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx,
1088 const char *szLabel,
1089 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001090
Laurence Lundblade3eead482023-12-16 20:53:22 -07001091static void
1092QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx,
1093 int64_t nLabel,
1094 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001095
1096
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07001097#ifndef QCBOR_DISABLE_EXP_AND_MANTISSA
Michael Eckel5c531332020-03-02 01:35:30 +01001098/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001099 * @brief Add a decimal fraction to the encoded output.
1100 *
1101 * @param[in] pCtx Encoding context to add the decimal fraction to.
1102 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1103 * @ref QCBOR_ENCODE_AS_BORROWED.
1104 * @param[in] nMantissa The mantissa.
1105 * @param[in] nBase10Exponent The exponent.
1106 *
1107 * The value is nMantissa * 10 ^ nBase10Exponent.
1108 *
1109 * A decimal fraction is good for exact representation of some values
1110 * that can't be represented exactly with standard C (IEEE 754)
1111 * floating-point numbers. Much larger and much smaller numbers can
1112 * also be represented than floating-point because of the larger
1113 * number of bits in the exponent.
1114 *
1115 * The decimal fraction is conveyed as two integers, a mantissa and a
1116 * base-10 scaling factor.
1117 *
1118 * For example, 273.15 is represented by the two integers 27315 and -2.
1119 *
1120 * The exponent and mantissa have the range from @c INT64_MIN to
1121 * @c INT64_MAX for both encoding and decoding (CBOR allows
1122 * @c -UINT64_MAX to @c UINT64_MAX, but this implementation doesn't
1123 * support this range to reduce code size and interface complexity a
1124 * little).
1125 *
1126 * CBOR Preferred serialization of the integers is used, thus they
1127 * will be encoded in the smallest number of bytes possible.
1128 *
1129 * See also QCBOREncode_AddDecimalFractionBigNum() for a decimal
1130 * fraction with arbitrarily large precision and
1131 * QCBOREncode_AddBigFloat().
1132 *
1133 * There is no representation of positive or negative infinity or NaN
1134 * (Not a Number). Use QCBOREncode_AddDouble() to encode them.
1135 *
1136 * See @ref expAndMantissa for decoded representation.
Michael Eckel5c531332020-03-02 01:35:30 +01001137 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001138static void
1139QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pCtx,
1140 uint8_t uTagRequirement,
1141 int64_t nMantissa,
1142 int64_t nBase10Exponent);
1143
1144static void
1145QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pCtx,
1146 const char *szLabel,
1147 uint8_t uTagRequirement,
1148 int64_t nMantissa,
1149 int64_t nBase10Exponent);
1150
1151static void
1152QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pCtx,
1153 int64_t nLabel,
1154 uint8_t uTagRequirement,
1155 int64_t nMantissa,
1156 int64_t nBase10Exponent);
1157
1158
1159static void
1160QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pCtx,
1161 int64_t nMantissa,
1162 int64_t nBase10Exponent);
1163
1164static void
1165QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pCtx,
1166 const char *szLabel,
1167 int64_t nMantissa,
1168 int64_t nBase10Exponent);
1169
1170static void
1171QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pCtx,
1172 int64_t nLabel,
1173 int64_t nMantissa,
1174 int64_t nBase10Exponent);
1175
1176
1177/**
1178 * @brief Add a decimal fraction with a big number mantissa to the encoded output.
1179 *
1180 * @param[in] pCtx Encoding context to add the decimal fraction to.
1181 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1182 * @ref QCBOR_ENCODE_AS_BORROWED.
1183 * @param[in] Mantissa The mantissa.
1184 * @param[in] bIsNegative false if mantissa is positive, true if negative.
1185 * @param[in] nBase10Exponent The exponent.
1186 *
1187 * This is the same as QCBOREncode_AddDecimalFraction() except the
1188 * mantissa is a big number (See QCBOREncode_AddPositiveBignum())
1189 * allowing for arbitrarily large precision.
1190 *
1191 * See @ref expAndMantissa for decoded representation.
1192 */
1193static void
1194QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pCtx,
1195 uint8_t uTagRequirement,
1196 UsefulBufC Mantissa,
1197 bool bIsNegative,
1198 int64_t nBase10Exponent);
1199
1200static void
1201QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
1202 const char *szLabel,
1203 uint8_t uTagRequirement,
1204 UsefulBufC Mantissa,
1205 bool bIsNegative,
1206 int64_t nBase10Exponent);
1207
1208static void
1209QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
1210 int64_t nLabel,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001211 uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07001212 UsefulBufC Mantissa,
1213 bool bIsNegative,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001214 int64_t nBase10Exponent);
1215
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001216
Laurence Lundblade3eead482023-12-16 20:53:22 -07001217static void
1218QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pCtx,
1219 UsefulBufC Mantissa,
1220 bool bIsNegative,
1221 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001222
Laurence Lundblade3eead482023-12-16 20:53:22 -07001223static void
1224QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001225 const char *szLabel,
Laurence Lundblade3eead482023-12-16 20:53:22 -07001226 UsefulBufC Mantissa,
1227 bool bIsNegative,
1228 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001229
Laurence Lundblade3eead482023-12-16 20:53:22 -07001230static void
1231QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001232 int64_t nLabel,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001233 UsefulBufC Mantissa,
1234 bool bIsNegative,
Laurence Lundblade3eead482023-12-16 20:53:22 -07001235 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001236
Laurence Lundblade3eead482023-12-16 20:53:22 -07001237/**
1238 * @brief Add a big floating-point number to the encoded output.
1239 *
1240 * @param[in] pCtx The encoding context to add the bigfloat to.
1241 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1242 * @ref QCBOR_ENCODE_AS_BORROWED.
1243 * @param[in] nMantissa The mantissa.
1244 * @param[in] nBase2Exponent The exponent.
1245 *
1246 * The value is nMantissa * 2 ^ nBase2Exponent.
1247 *
1248 * "Bigfloats", as CBOR terms them, are similar to IEEE floating-point
1249 * numbers in having a mantissa and base-2 exponent, but they are not
1250 * supported by hardware or encoded the same. They explicitly use two
1251 * CBOR-encoded integers to convey the mantissa and exponent, each of
1252 * which can be 8, 16, 32 or 64 bits. With both the mantissa and
1253 * exponent 64 bits they can express more precision and a larger range
1254 * than an IEEE double floating-point number. See
1255 * QCBOREncode_AddBigFloatBigNum() for even more precision.
1256 *
1257 * For example, 1.5 would be represented by a mantissa of 3 and an
1258 * exponent of -1.
1259 *
1260 * The exponent and mantissa have the range from @c INT64_MIN to
1261 * @c INT64_MAX for both encoding and decoding (CBOR allows @c
1262 * -UINT64_MAX to @c UINT64_MAX, but this implementation doesn't
1263 * support this range to reduce code size and interface complexity a
1264 * little).
1265 *
1266 * CBOR preferred serialization of the integers is used, thus they will
1267 * be encoded in the smallest number of bytes possible.
1268 *
1269 * This can also be used to represent floating-point numbers in
1270 * environments that don't support IEEE 754.
1271 *
1272 * See @ref expAndMantissa for decoded representation.
1273 */
1274static void
1275QCBOREncode_AddTBigFloat(QCBOREncodeContext *pCtx,
1276 uint8_t uTagRequirement,
1277 int64_t nMantissa,
1278 int64_t nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001279
Laurence Lundblade3eead482023-12-16 20:53:22 -07001280static void
1281QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pCtx,
1282 const char *szLabel,
1283 uint8_t uTagRequirement,
1284 int64_t nMantissa,
1285 int64_t nBase2Exponent);
1286
1287static void
1288QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pCtx,
1289 int64_t nLabel,
1290 uint8_t uTagRequirement,
1291 int64_t nMantissa,
1292 int64_t nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001293
1294
Laurence Lundblade3eead482023-12-16 20:53:22 -07001295static void
1296QCBOREncode_AddBigFloat(QCBOREncodeContext *pCtx,
1297 int64_t nMantissa,
1298 int64_t nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01001299
Laurence Lundblade3eead482023-12-16 20:53:22 -07001300static void
1301QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pCtx,
1302 const char *szLabel,
1303 int64_t nMantissa,
1304 int64_t nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01001305
Laurence Lundblade3eead482023-12-16 20:53:22 -07001306static void
1307QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pCtx,
1308 int64_t nLabel,
1309 int64_t nMantissa,
1310 int64_t nBase2Exponent);
1311
1312/**
1313 * @brief Add a big floating-point number with a big number mantissa to
1314 * the encoded output.
1315 *
1316 * @param[in] pCtx The encoding context to add the bigfloat to.
1317 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1318 * @ref QCBOR_ENCODE_AS_BORROWED.
1319 * @param[in] Mantissa The mantissa.
1320 * @param[in] bIsNegative false if mantissa is positive, true if negative.
1321 * @param[in] nBase2Exponent The exponent.
1322 *
1323 * This is the same as QCBOREncode_AddBigFloat() except the mantissa
1324 * is a big number (See QCBOREncode_AddPositiveBignum()) allowing for
1325 * arbitrary precision.
1326 *
1327 * See @ref expAndMantissa for decoded representation.
1328 */
1329static void
1330QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pCtx,
1331 uint8_t uTagRequirement,
1332 UsefulBufC Mantissa,
1333 bool bIsNegative,
1334 int64_t nBase2Exponent);
1335
1336static void
1337QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pCtx,
1338 const char *szLabel,
1339 uint8_t uTagRequirement,
1340 UsefulBufC Mantissa,
1341 bool bIsNegative,
1342 int64_t nBase2Exponent);
1343
1344static void
1345QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1346 int64_t nLabel,
1347 uint8_t uTagRequirement,
1348 UsefulBufC Mantissa,
1349 bool bIsNegative,
1350 int64_t nBase2Exponent);
1351
1352
1353static void
1354QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pCtx,
1355 UsefulBufC Mantissa,
1356 bool bIsNegative,
1357 int64_t nBase2Exponent);
1358
1359static void
1360QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pCtx,
1361 const char *szLabel,
1362 UsefulBufC Mantissa,
1363 bool bIsNegative,
1364 int64_t nBase2Exponent);
1365
1366static void
1367QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1368 int64_t nLabel,
1369 UsefulBufC Mantissa,
1370 bool bIsNegative,
1371 int64_t nBase2Exponent);
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07001372#endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
Michael Eckel5c531332020-03-02 01:35:30 +01001373
1374
1375/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001376 * @brief Add a text URI to the encoded output.
1377 *
1378 * @param[in] pCtx The encoding context to add the URI to.
1379 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1380 * @ref QCBOR_ENCODE_AS_BORROWED.
1381 * @param[in] URI Pointer and length of the URI.
1382 *
1383 * The format of URI must be per [RFC 3986]
1384 * (https://tools.ietf.org/html/rfc3986).
1385 *
1386 * It is output as CBOR major type 3, a text string, with tag @ref
1387 * CBOR_TAG_URI indicating the text string is a URI.
1388 *
1389 * A URI in a NULL-terminated string, @c szURI, can be easily added with
1390 * this code:
1391 *
1392 * QCBOREncode_AddURI(pCtx, UsefulBuf_FromSZ(szURI));
Michael Eckel5c531332020-03-02 01:35:30 +01001393 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001394static void
1395QCBOREncode_AddTURI(QCBOREncodeContext *pCtx,
1396 uint8_t uTagRequirement,
1397 UsefulBufC URI);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001398
Laurence Lundblade3eead482023-12-16 20:53:22 -07001399static void
1400QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pCtx,
1401 const char *szLabel,
1402 uint8_t uTagRequirement,
1403 UsefulBufC URI);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001404
Laurence Lundblade3eead482023-12-16 20:53:22 -07001405static void
1406QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pCtx,
1407 int64_t nLabel,
1408 uint8_t uTagRequirement,
1409 UsefulBufC URI);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001410
1411
Laurence Lundblade3eead482023-12-16 20:53:22 -07001412static void
1413QCBOREncode_AddURI(QCBOREncodeContext *pCtx,
1414 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001415
Laurence Lundblade3eead482023-12-16 20:53:22 -07001416static void
1417QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx,
1418 const char *szLabel,
1419 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001420
Laurence Lundblade3eead482023-12-16 20:53:22 -07001421static void
1422QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx,
1423 int64_t nLabel,
1424 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001425
1426
1427/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001428 * @brief Add Base64-encoded text to encoded output.
1429 *
1430 * @param[in] pCtx The encoding context to add the base-64 text to.
1431 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1432 * @ref QCBOR_ENCODE_AS_BORROWED.
1433 * @param[in] B64Text Pointer and length of the base-64 encoded text.
1434 *
1435 * The text content is Base64 encoded data per [RFC 4648]
1436 * (https://tools.ietf.org/html/rfc4648).
1437 *
1438 * It is output as CBOR major type 3, a text string, with tag @ref
1439 * CBOR_TAG_B64 indicating the text string is Base64 encoded.
Michael Eckel5c531332020-03-02 01:35:30 +01001440 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001441static void
1442QCBOREncode_AddTB64Text(QCBOREncodeContext *pCtx,
1443 uint8_t uTagRequirement,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001444 UsefulBufC B64Text);
1445
Laurence Lundblade3eead482023-12-16 20:53:22 -07001446static void
1447QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pCtx,
1448 const char *szLabel,
1449 uint8_t uTagRequirement,
1450 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001451
Laurence Lundblade3eead482023-12-16 20:53:22 -07001452static void
1453QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pCtx,
1454 int64_t nLabel,
1455 uint8_t uTagRequirement,
1456 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001457
1458
Laurence Lundblade3eead482023-12-16 20:53:22 -07001459static void
1460QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx,
1461 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001462
Laurence Lundblade3eead482023-12-16 20:53:22 -07001463static void
1464QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx,
1465 const char *szLabel,
1466 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001467
Laurence Lundblade3eead482023-12-16 20:53:22 -07001468static void
1469QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx,
1470 int64_t nLabel,
1471 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001472
1473
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001474
Michael Eckel5c531332020-03-02 01:35:30 +01001475/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001476 * @brief Add base64url encoded data to encoded output.
1477 *
1478 * @param[in] pCtx The encoding context to add the base64url to.
1479 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1480 * @ref QCBOR_ENCODE_AS_BORROWED.
1481 * @param[in] B64Text Pointer and length of the base64url encoded text.
1482 *
1483 * The text content is base64URL encoded text as per [RFC 4648]
1484 * (https://tools.ietf.org/html/rfc4648).
1485 *
1486 * It is output as CBOR major type 3, a text string, with tag
1487 * @ref CBOR_TAG_B64URL indicating the text string is a Base64url
1488 * encoded.
Michael Eckel5c531332020-03-02 01:35:30 +01001489 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001490static void
1491QCBOREncode_AddTB64URLText(QCBOREncodeContext *pCtx,
1492 uint8_t uTagRequirement,
1493 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001494
Laurence Lundblade3eead482023-12-16 20:53:22 -07001495static void
1496QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pCtx,
1497 const char *szLabel,
1498 uint8_t uTagRequirement,
1499 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001500
Laurence Lundblade3eead482023-12-16 20:53:22 -07001501static void
1502QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pCtx,
1503 int64_t nLabel,
1504 uint8_t uTagRequirement,
1505 UsefulBufC B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001506
1507
Laurence Lundblade3eead482023-12-16 20:53:22 -07001508static void
1509QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx,
1510 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001511
Laurence Lundblade3eead482023-12-16 20:53:22 -07001512static void
1513QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx,
1514 const char *szLabel,
1515 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001516
Laurence Lundblade3eead482023-12-16 20:53:22 -07001517static void
1518QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx,
1519 int64_t nLabel,
1520 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001521
1522
1523/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001524 * @brief Add Perl Compatible Regular Expression.
1525 *
1526 * @param[in] pCtx Encoding context to add the regular expression to.
1527 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1528 * @ref QCBOR_ENCODE_AS_BORROWED.
1529 * @param[in] Regex Pointer and length of the regular expression.
1530 *
1531 * The text content is Perl Compatible Regular
1532 * Expressions (PCRE) / JavaScript syntax [ECMA262].
1533 *
1534 * It is output as CBOR major type 3, a text string, with tag @ref
1535 * CBOR_TAG_REGEX indicating the text string is a regular expression.
Michael Eckel5c531332020-03-02 01:35:30 +01001536 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001537static void
1538QCBOREncode_AddTRegex(QCBOREncodeContext *pCtx,
1539 uint8_t uTagRequirement,
1540 UsefulBufC Regex);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001541
Laurence Lundblade3eead482023-12-16 20:53:22 -07001542static void
1543QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pCtx,
1544 const char *szLabel,
1545 uint8_t uTagRequirement,
1546 UsefulBufC Regex);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001547
Laurence Lundblade3eead482023-12-16 20:53:22 -07001548static void
1549QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pCtx,
1550 int64_t nLabel,
1551 uint8_t uTagRequirement,
1552 UsefulBufC Regex);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001553
1554
Laurence Lundblade3eead482023-12-16 20:53:22 -07001555static void
1556QCBOREncode_AddRegex(QCBOREncodeContext *pCtx,
1557 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001558
Laurence Lundblade3eead482023-12-16 20:53:22 -07001559static void
1560QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx,
1561 const char *szLabel,
1562 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001563
Laurence Lundblade3eead482023-12-16 20:53:22 -07001564static void
1565QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx,
1566 int64_t nLabel,
1567 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001568
1569
1570/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001571 * @brief MIME encoded data to the encoded output.
1572 *
1573 * @param[in] pCtx The encoding context to add the MIME data to.
1574 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1575 * @ref QCBOR_ENCODE_AS_BORROWED.
1576 * @param[in] MIMEData Pointer and length of the MIME data.
1577 *
1578 * The text content is in MIME format per [RFC 2045]
1579 * (https://tools.ietf.org/html/rfc2045) including the headers.
1580 *
1581 * It is output as CBOR major type 2, a binary string, with tag
1582 * @ref CBOR_TAG_BINARY_MIME indicating the string is MIME data. This
1583 * outputs tag 257, not tag 36, as it can carry any type of MIME
1584 * binary, 7-bit, 8-bit, quoted-printable and base64 where tag 36
1585 * cannot.
1586 *
1587 * Previous versions of QCBOR, those before spiffy decode, output tag
1588 * 36. Decoding supports both tag 36 and 257. (if the old behavior
1589 * with tag 36 is needed, copy the inline functions below and change
1590 * the tag number).
1591 *
1592 * See also QCBORDecode_GetMIMEMessage() and
1593 * @ref QCBOR_TYPE_BINARY_MIME.
1594 *
1595 * This does no translation of line endings. See QCBOREncode_AddText()
1596 * for a discussion of line endings in CBOR.
Michael Eckel5c531332020-03-02 01:35:30 +01001597 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001598static void
1599QCBOREncode_AddTMIMEData(QCBOREncodeContext *pCtx,
1600 uint8_t uTagRequirement,
1601 UsefulBufC MIMEData);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001602
Laurence Lundblade3eead482023-12-16 20:53:22 -07001603static void
1604QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pCtx,
1605 const char *szLabel,
1606 uint8_t uTagRequirement,
1607 UsefulBufC MIMEData);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001608
Laurence Lundblade3eead482023-12-16 20:53:22 -07001609static void
1610QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pCtx,
1611 int64_t nLabel,
1612 uint8_t uTagRequirement,
1613 UsefulBufC MIMEData);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001614
1615
Laurence Lundblade3eead482023-12-16 20:53:22 -07001616static void
1617QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx,
1618 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001619
Laurence Lundblade3eead482023-12-16 20:53:22 -07001620static void
1621QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx,
1622 const char *szLabel,
1623 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001624
Laurence Lundblade3eead482023-12-16 20:53:22 -07001625static void
1626QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx,
1627 int64_t nLabel,
1628 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001629
1630
1631/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001632 * @brief Add an RFC 3339 date string
1633 *
1634 * @param[in] pCtx The encoding context to add the date to.
1635 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1636 * @ref QCBOR_ENCODE_AS_BORROWED.
1637 * @param[in] szDate Null-terminated string with date to add.
1638 *
1639 * The string szDate should be in the form of [RFC 3339]
1640 * (https://tools.ietf.org/html/rfc3339) as defined by section 3.3 in
1641 * [RFC 4287] (https://tools.ietf.org/html/rfc4287). This is as
1642 * described in section 3.4.1 in [RFC 8949]
1643 * (https://tools.ietf.org/html/rfc8949).
1644 *
1645 * Note that this function doesn't validate the format of the date
1646 * string at all. If you add an incorrect format date string, the
1647 * generated CBOR will be incorrect and the receiver may not be able
1648 * to handle it.
1649 *
1650 * Error handling is the same as QCBOREncode_AddInt64().
1651 *
1652 * See also QCBOREncode_AddTDayString().
Michael Eckel5c531332020-03-02 01:35:30 +01001653 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001654static void
1655QCBOREncode_AddTDateString(QCBOREncodeContext *pCtx,
1656 uint8_t uTagRequirement,
1657 const char *szDate);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001658
Laurence Lundblade3eead482023-12-16 20:53:22 -07001659static void
1660QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pCtx,
1661 const char *szLabel,
1662 uint8_t uTagRequirement,
1663 const char *szDate);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001664
Laurence Lundblade3eead482023-12-16 20:53:22 -07001665static void
1666QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pCtx,
1667 int64_t nLabel,
1668 uint8_t uTagRequirement,
1669 const char *szDate);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001670
1671
Laurence Lundblade3eead482023-12-16 20:53:22 -07001672static void
1673QCBOREncode_AddDateString(QCBOREncodeContext *pCtx,
1674 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001675
Laurence Lundblade3eead482023-12-16 20:53:22 -07001676static void
1677QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx,
1678 const char *szLabel,
1679 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001680
Laurence Lundblade3eead482023-12-16 20:53:22 -07001681static void
1682QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx,
1683 int64_t nLabel,
1684 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001685
Laurence Lundblade46d63e92021-05-13 11:37:10 -07001686
1687/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001688 * @brief Add a date-only string.
1689 *
1690 * @param[in] pCtx The encoding context to add the date to.
1691 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1692 * @ref QCBOR_ENCODE_AS_BORROWED.
1693 * @param[in] szDate Null-terminated string with date to add.
1694 *
1695 * This date format is described in
1696 * [RFC 8943] (https://tools.ietf.org/html/rfc8943), but that mainly
1697 * references RFC 3339. The string szDate must be in the forrm
1698 * specified the ABNF for a full-date in
1699 * [RFC 3339] (https://tools.ietf.org/html/rfc3339). Examples of this
1700 * are "1985-04-12" and "1937-01-01". The time and the time zone are
1701 * never included.
1702 *
1703 * Note that this function doesn't validate the format of the date
1704 * string at all. If you add an incorrect format date string, the
1705 * generated CBOR will be incorrect and the receiver may not be able
1706 * to handle it.
1707 *
1708 * Error handling is the same as QCBOREncode_AddInt64().
1709 *
1710 * See also QCBOREncode_AddTDateString().
Laurence Lundblade46d63e92021-05-13 11:37:10 -07001711 */
1712static void
1713QCBOREncode_AddTDaysString(QCBOREncodeContext *pCtx,
1714 uint8_t uTagRequirement,
1715 const char *szDate);
1716
1717static void
1718QCBOREncode_AddTDaysStringToMapSZ(QCBOREncodeContext *pCtx,
1719 const char *szLabel,
1720 uint8_t uTagRequirement,
1721 const char *szDate);
1722
1723static void
1724QCBOREncode_AddTDaysStringToMapN(QCBOREncodeContext *pCtx,
1725 int64_t nLabel,
1726 uint8_t uTagRequirement,
1727 const char *szDate);
1728
1729
Michael Eckel5c531332020-03-02 01:35:30 +01001730/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001731 * @brief Add a standard Boolean.
1732 *
1733 * @param[in] pCtx The encoding context to add the Boolean to.
1734 * @param[in] b true or false from @c <stdbool.h>.
1735 *
1736 * Adds a Boolean value as CBOR major type 7.
1737 *
1738 * Error handling is the same as QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +01001739 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001740static void
1741QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b);
Michael Eckel5c531332020-03-02 01:35:30 +01001742
Laurence Lundblade3eead482023-12-16 20:53:22 -07001743static void
1744QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b);
Michael Eckel5c531332020-03-02 01:35:30 +01001745
Laurence Lundblade3eead482023-12-16 20:53:22 -07001746static void
1747QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b);
Michael Eckel5c531332020-03-02 01:35:30 +01001748
1749
1750
1751/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001752 * @brief Add a NULL to the encoded output.
1753 *
1754 * @param[in] pCtx The encoding context to add the NULL to.
1755 *
1756 * Adds the NULL value as CBOR major type 7.
1757 *
1758 * This NULL doesn't have any special meaning in CBOR such as a
1759 * terminating value for a string or an empty value.
1760 *
1761 * Error handling is the same as QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +01001762 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001763static void
1764QCBOREncode_AddNULL(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01001765
Laurence Lundblade3eead482023-12-16 20:53:22 -07001766static void
1767QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001768
Laurence Lundblade3eead482023-12-16 20:53:22 -07001769static void
1770QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001771
1772
1773/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001774 * @brief Add an "undef" to the encoded output.
1775 *
1776 * @param[in] pCtx The encoding context to add the "undef" to.
1777 *
1778 * Adds the undef value as CBOR major type 7.
1779 *
1780 * Note that this value will not translate to JSON.
1781 *
1782 * This Undef doesn't have any special meaning in CBOR such as a
1783 * terminating value for a string or an empty value.
1784 *
1785 * Error handling is the same as QCBOREncode_AddInt64().
Michael Eckel5c531332020-03-02 01:35:30 +01001786 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001787static void
1788QCBOREncode_AddUndef(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01001789
Laurence Lundblade3eead482023-12-16 20:53:22 -07001790static void
1791QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001792
Laurence Lundblade3eead482023-12-16 20:53:22 -07001793static void
1794QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001795
1796
1797/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001798 * @brief Indicates that the next items added are in an array.
1799 *
1800 * @param[in] pCtx The encoding context to open the array in.
1801 *
1802 * Arrays are the basic CBOR aggregate or structure type. Call this
1803 * function to start or open an array. Then call the various
1804 * @c QCBOREncode_AddXxx() functions to add the items that go into the
1805 * array. Then call QCBOREncode_CloseArray() when all items have been
1806 * added. The data items in the array can be of any type and can be of
1807 * mixed types.
1808 *
1809 * Nesting of arrays and maps is allowed and supported just by calling
1810 * QCBOREncode_OpenArray() again before calling
1811 * QCBOREncode_CloseArray(). While CBOR has no limit on nesting, this
1812 * implementation does in order to keep it smaller and simpler. The
1813 * limit is @ref QCBOR_MAX_ARRAY_NESTING. This is the max number of
1814 * times this can be called without calling
1815 * QCBOREncode_CloseArray(). QCBOREncode_Finish() will return
1816 * @ref QCBOR_ERR_ARRAY_NESTING_TOO_DEEP when it is called as this
1817 * function just sets an error state and returns no value when this
1818 * occurs.
1819 *
1820 * If you try to add more than @ref QCBOR_MAX_ITEMS_IN_ARRAY items to
1821 * a single array or map, @ref QCBOR_ERR_ARRAY_TOO_LONG will be
1822 * returned when QCBOREncode_Finish() is called.
1823 *
1824 * An array itself must have a label if it is being added to a map.
1825 * Note that array elements do not have labels (but map elements do).
1826 *
1827 * An array itself may be tagged by calling QCBOREncode_AddTag()
1828 * before this call.
Michael Eckel5c531332020-03-02 01:35:30 +01001829 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001830static void
1831QCBOREncode_OpenArray(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01001832
Laurence Lundblade3eead482023-12-16 20:53:22 -07001833static void
1834QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001835
Laurence Lundblade3eead482023-12-16 20:53:22 -07001836static void
1837QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001838
1839
1840/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001841 * @brief Close an open array.
1842 *
1843 * @param[in] pCtx The encoding context to close the array in.
1844 *
1845 * The closes an array opened by QCBOREncode_OpenArray(). It reduces
1846 * nesting level by one. All arrays (and maps) must be closed before
1847 * calling QCBOREncode_Finish().
1848 *
1849 * When an error occurs as a result of this call, the encoder records
1850 * the error and enters the error state. The error will be returned
1851 * when QCBOREncode_Finish() is called.
1852 *
1853 * If this has been called more times than QCBOREncode_OpenArray(), then
1854 * @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when QCBOREncode_Finish()
1855 * is called.
1856 *
1857 * If this is called and it is not an array that is currently open,
1858 * @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
1859 * QCBOREncode_Finish() is called.
Michael Eckel5c531332020-03-02 01:35:30 +01001860 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001861static void
1862QCBOREncode_CloseArray(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01001863
1864
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07001865
1866
Michael Eckel5c531332020-03-02 01:35:30 +01001867/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001868 * @brief Indicates that the next items added are in a map.
1869 *
1870 * @param[in] pCtx The encoding context to open the map in.
1871 *
1872 * See QCBOREncode_OpenArray() for more information, particularly
1873 * error handling.
1874 *
1875 * CBOR maps are an aggregate type where each item in the map consists
1876 * of a label and a value. They are similar to JSON objects.
1877 *
1878 * The value can be any CBOR type including another map.
1879 *
1880 * The label can also be any CBOR type, but in practice they are
1881 * typically, integers as this gives the most compact output. They
1882 * might also be text strings which gives readability and translation
1883 * to JSON.
1884 *
1885 * Every @c QCBOREncode_AddXxx() call has one version that ends with
1886 * @c InMap for adding items to maps with string labels and one that
1887 * ends with @c InMapN that is for adding with integer labels.
1888 *
1889 * RFC 8949 uses the term "key" instead of "label".
1890 *
1891 * If you wish to use map labels that are neither integer labels nor
1892 * text strings, then just call the QCBOREncode_AddXxx() function
1893 * explicitly to add the label. Then call it again to add the value.
1894 *
1895 * See the [RFC 8949] (https://tools.ietf.org/html/rfc8949) for a lot
1896 * more information on creating maps.
Michael Eckel5c531332020-03-02 01:35:30 +01001897 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001898static void
1899QCBOREncode_OpenMap(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01001900
Laurence Lundblade3eead482023-12-16 20:53:22 -07001901static void
1902QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001903
Laurence Lundblade3eead482023-12-16 20:53:22 -07001904static void
1905QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01001906
1907
Michael Eckel5c531332020-03-02 01:35:30 +01001908/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07001909 * @brief Close an open map.
1910 *
1911 * @param[in] pCtx The encoding context to close the map in.
1912 *
1913 * This closes a map opened by QCBOREncode_OpenMap(). It reduces
1914 * nesting level by one.
1915 *
1916 * When an error occurs as a result of this call, the encoder records
1917 * the error and enters the error state. The error will be returned
1918 * when QCBOREncode_Finish() is called.
1919 *
1920 * If this has been called more times than QCBOREncode_OpenMap(), then
1921 * @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1922 * QCBOREncode_Finish() is called.
1923 *
1924 * If this is called and it is not a map that is currently open,
1925 * @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
1926 * QCBOREncode_Finish() is called.
Michael Eckel5c531332020-03-02 01:35:30 +01001927 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001928static void
1929QCBOREncode_CloseMap(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01001930
1931
1932/**
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07001933 * @brief Indicates that the next items added are in an indefinite length array.
1934 *
1935 * @param[in] pCtx The encoding context to open the array in.
1936 *
1937 * This is the same as QCBOREncode_OpenArray() except the array is
1938 * indefinite length.
1939 *
1940 * This must be closed with QCBOREncode_CloseArrayIndefiniteLength().
1941 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001942static void
1943QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pCtx);
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07001944
Laurence Lundblade3eead482023-12-16 20:53:22 -07001945static void
1946QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pCtx,
1947 const char *szLabel);
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07001948
1949static void
1950QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pCtx,
1951 int64_t nLabel);
1952
1953
1954/**
1955 * @brief Close an open indefinite length array.
1956 *
1957 * @param[in] pCtx The encoding context to close the array in.
1958 *
1959 * This is the same as QCBOREncode_CloseArray(), but the open array
1960 * that is being close must be of indefinite length.
1961 */
1962static void
1963QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pCtx);
1964
1965
1966/**
1967 * @brief Indicates that the next items added are in an indefinite length map.
1968 *
1969 * @param[in] pCtx The encoding context to open the map in.
1970 *
1971 * This is the same as QCBOREncode_OpenMap() except the array is
1972 * indefinite length.
1973 *
1974 * This must be closed with QCBOREncode_CloseMapIndefiniteLength().
1975 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07001976static void
1977QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pCtx);
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07001978
Laurence Lundblade3eead482023-12-16 20:53:22 -07001979static void
1980QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pCtx,
1981 const char *szLabel);
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07001982
1983static void
1984QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pCtx,
1985 int64_t nLabel);
1986
1987
1988/**
1989 * @brief Close an open indefinite length map.
1990 *
1991 * @param[in] pCtx The encoding context to close the map in.
1992 *
1993 * This is the same as QCBOREncode_CloseMap(), but the open map that
1994 * is being close must be of indefinite length.
1995 */
1996static void
1997QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pCtx);
1998
1999
2000
2001
2002/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002003 * @brief Indicate start of encoded CBOR to be wrapped in a bstr.
2004 *
2005 * @param[in] pCtx The encoding context to open the bstr-wrapped CBOR in.
2006 *
2007 * All added encoded items between this call and a call to
2008 * QCBOREncode_CloseBstrWrap2() will be wrapped in a bstr. They will
2009 * appear in the final output as a byte string. That byte string will
2010 * contain encoded CBOR. This increases nesting level by one.
2011 *
2012 * The typical use case is for encoded CBOR that is to be
2013 * cryptographically hashed, as part of a [RFC 8152, COSE]
2014 * (https://tools.ietf.org/html/rfc8152) implementation. The wrapping
2015 * byte string is taken as input by the hash function (which is why it
2016 * is returned by QCBOREncode_CloseBstrWrap2()). It is also easy to
2017 * recover on decoding with standard CBOR decoders.
2018 *
2019 * Using QCBOREncode_BstrWrap() and QCBOREncode_CloseBstrWrap2()
2020 * avoids having to encode the items first in one buffer (e.g., the
2021 * COSE payload) and then add that buffer as a bstr to another
2022 * encoding (e.g. the COSE to-be-signed bytes, the @c Sig_structure)
2023 * potentially halving the memory needed.
2024 *
2025 * CBOR by nature must be decoded item by item in order from the
2026 * start. By wrapping some CBOR in a byte string, the decoding of
2027 * that wrapped CBOR can be skipped. This is another use of wrapping,
2028 * perhaps because the CBOR is large and deeply nested. Perhaps APIs
2029 * for handling one defined CBOR message that is being embedded in
2030 * another only take input as a byte string. Perhaps the desire is to
2031 * be able to decode the out layer even in the wrapped has errors.
Michael Eckel5c531332020-03-02 01:35:30 +01002032 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002033static void
2034QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx);
Michael Eckel5c531332020-03-02 01:35:30 +01002035
Laurence Lundblade3eead482023-12-16 20:53:22 -07002036static void
2037QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01002038
Laurence Lundblade3eead482023-12-16 20:53:22 -07002039static void
2040QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
Michael Eckel5c531332020-03-02 01:35:30 +01002041
2042
2043/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002044 * @brief Close a wrapping bstr.
2045 *
2046 * @param[in] pCtx The encoding context to close of bstr wrapping in.
2047 * @param[in] bIncludeCBORHead Include the encoded CBOR head of the bstr
2048 * as well as the bytes in @c pWrappedCBOR.
2049 * @param[out] pWrappedCBOR A @ref UsefulBufC containing wrapped bytes.
2050 *
2051 * The closes a wrapping bstr opened by QCBOREncode_BstrWrap(). It reduces
2052 * nesting level by one.
2053 *
2054 * A pointer and length of the enclosed encoded CBOR is returned in @c
2055 * *pWrappedCBOR if it is not @c NULL. The main purpose of this is so
2056 * this data can be hashed (e.g., with SHA-256) as part of a [RFC
2057 * 8152, COSE] (https://tools.ietf.org/html/rfc8152)
2058 * implementation. **WARNING**, this pointer and length should be used
2059 * right away before any other calls to @c QCBOREncode_CloseXxx() as
2060 * they will move data around and the pointer and length will no
2061 * longer be to the correct encoded CBOR.
2062 *
2063 * When an error occurs as a result of this call, the encoder records
2064 * the error and enters the error state. The error will be returned
2065 * when QCBOREncode_Finish() is called.
2066 *
2067 * If this has been called more times than QCBOREncode_BstrWrap(),
2068 * then @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
2069 * QCBOREncode_Finish() is called.
2070 *
2071 * If this is called and it is not a wrapping bstr that is currently
2072 * open, @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
2073 * QCBOREncode_Finish() is called.
2074 *
2075 * QCBOREncode_CloseBstrWrap() is a deprecated version of this function
2076 * that is equivalent to the call with @c bIncludeCBORHead @c true.
Michael Eckel5c531332020-03-02 01:35:30 +01002077 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002078void
2079QCBOREncode_CloseBstrWrap2(QCBOREncodeContext *pCtx, bool bIncludeCBORHead, UsefulBufC *pWrappedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01002080
Laurence Lundblade3eead482023-12-16 20:53:22 -07002081static void
2082QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01002083
2084
2085/**
Laurence Lundblade8d3b8552021-06-10 11:11:54 -07002086 * @brief Cancel byte string wrapping.
2087 *
2088 * @param[in] pCtx The encoding context.
2089 *
2090 * This cancels QCBOREncode_BstrWrap() making tghe encoding as if it
2091 * were never called.
2092 *
2093 * WARNING: This does not work on QCBOREncode_BstrWrapInMap()
2094 * or QCBOREncode_BstrWrapInMapN() and there is no error detection
2095 * of an attempt at their use.
2096 *
2097 * This only works if nothing has been added into the wrapped byte
2098 * string. If something has been added, this sets the error
2099 * @ref QCBOR_ERR_CANNOT_CANCEL.
2100 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002101void
2102QCBOREncode_CancelBstrWrap(QCBOREncodeContext *pCtx);
Laurence Lundblade8d3b8552021-06-10 11:11:54 -07002103
2104
2105/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002106 * @brief Add some already-encoded CBOR bytes.
2107 *
2108 * @param[in] pCtx The encoding context to add the already-encode CBOR to.
2109 * @param[in] Encoded The already-encoded CBOR to add to the context.
2110 *
2111 * The encoded CBOR being added must be fully conforming CBOR. It must
2112 * be complete with no arrays or maps that are incomplete. While this
2113 * encoder doesn't ever produce indefinite lengths, it is OK for the
2114 * raw CBOR added here to have indefinite lengths.
2115 *
2116 * The raw CBOR added here is not checked in anyway. If it is not
2117 * conforming or has open arrays or such, the final encoded CBOR
2118 * will probably be wrong or not what was intended.
2119 *
2120 * If the encoded CBOR being added here contains multiple items, they
2121 * must be enclosed in a map or array. At the top level the raw
2122 * CBOR must be a single data item.
Michael Eckel5c531332020-03-02 01:35:30 +01002123 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002124static void
2125QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01002126
Laurence Lundblade3eead482023-12-16 20:53:22 -07002127static void
2128QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01002129
Laurence Lundblade3eead482023-12-16 20:53:22 -07002130static void
2131QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01002132
2133
2134/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002135 * @brief Get the encoded result.
2136 *
2137 * @param[in] pCtx The context to finish encoding with.
2138 * @param[out] pEncodedCBOR Structure in which the pointer and length of
2139 * the encoded CBOR is returned.
2140 *
2141 * @retval QCBOR_SUCCESS Encoded CBOR is returned.
2142 *
2143 * @retval QCBOR_ERR_TOO_MANY_CLOSES Nesting error
2144 *
2145 * @retval QCBOR_ERR_CLOSE_MISMATCH Nesting error
2146 *
2147 * @retval QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN Nesting error
2148 *
2149 * @retval QCBOR_ERR_BUFFER_TOO_LARGE Encoded output buffer size
2150 *
2151 * @retval QCBOR_ERR_BUFFER_TOO_SMALL Encoded output buffer size
2152 *
2153 * @retval QCBOR_ERR_ARRAY_NESTING_TOO_DEEP Implementation limit
2154 *
2155 * @retval QCBOR_ERR_ARRAY_TOO_LONG Implementation limit
2156 *
2157 * On success, the pointer and length of the encoded CBOR are returned
2158 * in @c *pEncodedCBOR. The pointer is the same pointer that was passed
2159 * in to QCBOREncode_Init(). Note that it is not const when passed to
2160 * QCBOREncode_Init(), but it is const when returned here. The length
2161 * will be smaller than or equal to the length passed in when
2162 * QCBOREncode_Init() as this is the length of the actual result, not
2163 * the size of the buffer it was written to.
2164 *
2165 * If a @c NULL was passed for @c Storage.ptr when QCBOREncode_Init()
2166 * was called, @c NULL will be returned here, but the length will be
2167 * that of the CBOR that would have been encoded.
2168 *
2169 * Encoding errors primarily manifest here as most other encoding function
2170 * do no return an error. They just set the error state in the encode
2171 * context after which no encoding function does anything.
2172 *
2173 * Three types of errors manifest here. The first type are nesting
2174 * errors where the number of @c QCBOREncode_OpenXxx() calls do not
2175 * match the number @c QCBOREncode_CloseXxx() calls. The solution is to
2176 * fix the calling code.
2177 *
2178 * The second type of error is because the buffer given is either too
2179 * small or too large. The remedy is to give a correctly sized buffer.
2180 *
2181 * The third type are due to limits in this implementation.
2182 * @ref QCBOR_ERR_ARRAY_NESTING_TOO_DEEP can be worked around by
2183 * encoding the CBOR in two (or more) phases and adding the CBOR from
2184 * the first phase to the second with @c QCBOREncode_AddEncoded().
2185 *
2186 * If an error is returned, the buffer may have partially encoded
2187 * incorrect CBOR in it and it should not be used. Likewise, the length
2188 * may be incorrect and should not be used.
2189 *
2190 * Note that the error could have occurred in one of the many
2191 * @c QCBOREncode_AddXxx() calls long before QCBOREncode_Finish() was
2192 * called. This error handling reduces the CBOR implementation size
2193 * but makes debugging harder.
2194 *
2195 * This may be called multiple times. It will always return the
2196 * same. It can also be interleaved with calls to
2197 * QCBOREncode_FinishGetSize().
2198 *
2199 * QCBOREncode_GetErrorState() can be called to get the current
2200 * error state in order to abort encoding early as an optimization, but
2201 * calling it is is never required.
Michael Eckel5c531332020-03-02 01:35:30 +01002202 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002203QCBORError
2204QCBOREncode_Finish(QCBOREncodeContext *pCtx, UsefulBufC *pEncodedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01002205
2206
2207/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002208 * @brief Get the encoded CBOR and error status.
2209 *
2210 * @param[in] pCtx The context to finish encoding with.
2211 * @param[out] uEncodedLen The length of the encoded or potentially
2212 * encoded CBOR in bytes.
2213 *
2214 * @return The same errors as QCBOREncode_Finish().
2215 *
2216 * This functions the same as QCBOREncode_Finish(), but only returns the
2217 * size of the encoded output.
Michael Eckel5c531332020-03-02 01:35:30 +01002218 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002219QCBORError
2220QCBOREncode_FinishGetSize(QCBOREncodeContext *pCtx, size_t *uEncodedLen);
Michael Eckel5c531332020-03-02 01:35:30 +01002221
2222
2223/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002224 * @brief Indicate whether output buffer is NULL or not.
2225 *
2226 * @param[in] pCtx The encoding context.
2227 *
2228 * @return 1 if the output buffer is @c NULL.
2229 *
2230 * Sometimes a @c NULL input buffer is given to QCBOREncode_Init() so
2231 * that the size of the generated CBOR can be calculated without
2232 * allocating a buffer for it. This returns 1 when the output buffer
2233 * is @c NULL and 0 when it is not.
Michael Eckel5c531332020-03-02 01:35:30 +01002234 */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002235static int
2236QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx);
2237
2238
2239/**
2240 * @brief Get the encoding error state.
2241 *
2242 * @param[in] pCtx The encoding context.
2243 *
2244 * @return One of @ref QCBORError. See return values from
2245 * QCBOREncode_Finish()
2246 *
2247 * Normally encoding errors need only be handled at the end of
2248 * encoding when QCBOREncode_Finish() is called. This can be called to
2249 * get the error result before finish should there be a need to halt
2250 * encoding before QCBOREncode_Finish() is called.
2251 */
2252static QCBORError
2253QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx);
2254
2255
2256/**
2257 * Encode the "head" of a CBOR data item.
2258 *
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002259 * @param Buffer Buffer to output the encoded head to; must be
Laurence Lundblade3eead482023-12-16 20:53:22 -07002260 * @ref QCBOR_HEAD_BUFFER_SIZE bytes in size.
2261 * @param uMajorType One of CBOR_MAJOR_TYPE_XX.
2262 * @param uMinLen The minimum number of bytes to encode uNumber. Almost
2263 * always this is 0 to use preferred
2264 * serialization. If this is 4, then even the
2265 * values 0xffff and smaller will be encoded in 4
2266 * bytes. This is used primarily when encoding a
2267 * float or double put into uNumber as the leading
2268 * zero bytes for them must be encoded.
2269 * @param uNumber The numeric argument part of the CBOR head.
2270 * @return Pointer and length of the encoded head or
2271 * @ref NULLUsefulBufC if the output buffer is too small.
2272 *
2273 * Callers do not to need to call this for normal CBOR encoding. Note
2274 * that it doesn't even take a @ref QCBOREncodeContext argument.
2275 *
2276 * This encodes the major type and argument part of a data item. The
2277 * argument is an integer that is usually either the value or the length
2278 * of the data item.
2279 *
2280 * This is exposed in the public interface to allow hashing of some CBOR
2281 * data types, bstr in particular, a chunk at a time so the full CBOR
2282 * doesn't have to be encoded in a contiguous buffer.
2283 *
2284 * For example, if you have a 100,000 byte binary blob in a buffer that
2285 * needs to be a bstr encoded and then hashed. You could allocate a
2286 * 100,010 byte buffer and encode it normally. Alternatively, you can
2287 * encode the head in a 10 byte buffer with this function, hash that and
2288 * then hash the 100,000 bytes using the same hash context.
2289 *
2290 * See also QCBOREncode_AddBytesLenOnly();
2291 */
2292UsefulBufC
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002293QCBOREncode_EncodeHead(UsefulBuf Buffer,
Laurence Lundblade3eead482023-12-16 20:53:22 -07002294 uint8_t uMajorType,
2295 uint8_t uMinLen,
2296 uint64_t uNumber);
Michael Eckel5c531332020-03-02 01:35:30 +01002297
2298
Michael Eckel5c531332020-03-02 01:35:30 +01002299
2300
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002301/* =========================================================================
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002302 BEGINNING OF PRIVATE IMPLEMENTATION
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002303 ========================================================================= */
Michael Eckel5c531332020-03-02 01:35:30 +01002304
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002305/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002306void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002307QCBOREncode_Private_AddBuffer(QCBOREncodeContext *pCtx,
2308 uint8_t uMajorType,
2309 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002310
2311
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002312/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002313void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002314QCBOREncode_Private_OpenMapOrArray(QCBOREncodeContext *pCtx,
2315 uint8_t uMajorType);
Michael Eckel5c531332020-03-02 01:35:30 +01002316
2317
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002318/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002319void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002320QCBOREncode_Private_OpenMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx,
2321 uint8_t uMajorType);
Michael Eckel5c531332020-03-02 01:35:30 +01002322
2323
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002324/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002325void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002326QCBOREncode_Private_CloseMapOrArray(QCBOREncodeContext *pCtx,
2327 uint8_t uMajorType);
Michael Eckel5c531332020-03-02 01:35:30 +01002328
2329
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002330/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002331void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002332QCBOREncode_Private_CloseMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx,
2333 uint8_t uMajorType);
Michael Eckel5c531332020-03-02 01:35:30 +01002334
2335
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002336/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002337void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002338QCBOREncode_Private_AddType7(QCBOREncodeContext *pCtx,
2339 uint8_t uMinLen,
2340 uint64_t uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002341
2342
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002343/* Semi-private funcion used by public inline functions. See qcbor_encode.c */
Laurence Lundblade3eead482023-12-16 20:53:22 -07002344void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002345QCBOREncode_Private_AddExpMantissa(QCBOREncodeContext *pCtx,
Laurence Lundblade3eead482023-12-16 20:53:22 -07002346 uint64_t uTag,
2347 UsefulBufC BigNumMantissa,
2348 bool bBigNumIsNegative,
2349 int64_t nMantissa,
2350 int64_t nExponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002351
2352/**
Laurence Lundblade3eead482023-12-16 20:53:22 -07002353 * @brief Semi-private method to add only the type and length of a byte string.
2354 *
2355 * @param[in] pCtx The context to initialize.
2356 * @param[in] Bytes Pointer and length of the input data.
2357 *
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002358 * This will be removed in QCBOR 2.0. It was never a public function.
2359 *
Laurence Lundblade3eead482023-12-16 20:53:22 -07002360 * This is the same as QCBOREncode_AddBytes() except it only adds the
2361 * CBOR encoding for the type and the length. It doesn't actually add
2362 * the bytes. You can't actually produce correct CBOR with this and
2363 * the rest of this API. It is only used for a special case where the
2364 * valid CBOR is created manually by putting this type and length in
2365 * and then adding the actual bytes. In particular, when only a hash
2366 * of the encoded CBOR is needed, where the type and header are hashed
2367 * separately and then the bytes is hashed. This makes it possible to
2368 * implement COSE Sign1 with only one copy of the payload in the
2369 * output buffer, rather than two, roughly cutting memory use in half.
2370 *
2371 * This is only used for this odd case, but this is a supported
2372 * tested function.
2373 *
2374 * See also QCBOREncode_EncodeHead().
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002375 */
2376static void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002377QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pCtx,
2378 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002379
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002380static void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002381QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pCtx,
2382 const char *szLabel,
2383 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002384
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002385static void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002386QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pCtx,
2387 int64_t nLabel,
2388 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002389
2390
2391
2392
2393
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002394static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002395QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pMe,
2396 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002397 const int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002398{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002399 /* Use _AddBuffer() because _AddSZString() is defined below, not above */
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002400 QCBOREncode_Private_AddBuffer(pMe,
2401 CBOR_MAJOR_TYPE_TEXT_STRING,
2402 UsefulBuf_FromSZ(szLabel));
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002403 QCBOREncode_AddInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002404}
2405
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002406static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002407QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002408 const int64_t nLabel,
2409 const int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002410{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002411 QCBOREncode_AddInt64(pMe, nLabel);
2412 QCBOREncode_AddInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002413}
2414
2415
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002416static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002417QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pMe,
2418 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002419 const uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002420{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002421 /* Use _AddBuffer() because _AddSZString() is defined below, not above */
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002422 QCBOREncode_Private_AddBuffer(pMe,
2423 CBOR_MAJOR_TYPE_TEXT_STRING,
2424 UsefulBuf_FromSZ(szLabel));
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002425 QCBOREncode_AddUInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002426}
2427
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002428static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002429QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002430 const int64_t nLabel,
2431 const uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002432{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002433 QCBOREncode_AddInt64(pMe, nLabel);
2434 QCBOREncode_AddUInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002435}
2436
2437
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002438static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002439QCBOREncode_AddText(QCBOREncodeContext *pMe, const UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002440{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002441 QCBOREncode_Private_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002442}
2443
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002444static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002445QCBOREncode_AddTextToMap(QCBOREncodeContext *pMe,
2446 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002447 const UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002448{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002449 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szLabel));
2450 QCBOREncode_AddText(pMe, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002451}
2452
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002453static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002454QCBOREncode_AddTextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002455 const int64_t nLabel,
2456 const UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002457{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002458 QCBOREncode_AddInt64(pMe, nLabel);
2459 QCBOREncode_AddText(pMe, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002460}
2461
2462
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002463inline static void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002464QCBOREncode_AddSZString(QCBOREncodeContext *pMe, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002465{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002466 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szString));
Michael Eckel5c531332020-03-02 01:35:30 +01002467}
2468
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002469static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002470QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pMe,
2471 const char *szLabel,
2472 const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002473{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002474 QCBOREncode_AddSZString(pMe, szLabel);
2475 QCBOREncode_AddSZString(pMe, szString);
Michael Eckel5c531332020-03-02 01:35:30 +01002476}
2477
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002478static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002479QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002480 const int64_t nLabel,
Laurence Lundblade3eead482023-12-16 20:53:22 -07002481 const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002482{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002483 QCBOREncode_AddInt64(pMe, nLabel);
2484 QCBOREncode_AddSZString(pMe, szString);
Michael Eckel5c531332020-03-02 01:35:30 +01002485}
2486
2487
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +02002488#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002489static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002490QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pMe,
2491 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002492 const double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002493{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002494 QCBOREncode_AddSZString(pMe, szLabel);
2495 QCBOREncode_AddDouble(pMe, dNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002496}
2497
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002498static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002499QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002500 const int64_t nLabel,
2501 const double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002502{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002503 QCBOREncode_AddInt64(pMe, nLabel);
2504 QCBOREncode_AddDouble(pMe, dNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002505}
2506
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002507static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002508QCBOREncode_AddFloatToMap(QCBOREncodeContext *pMe,
2509 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002510 const float dNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002511{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002512 QCBOREncode_AddSZString(pMe, szLabel);
2513 QCBOREncode_AddFloat(pMe, dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002514}
2515
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002516static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002517QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pMe,
2518 const int64_t nLabel,
2519 const float fNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002520{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002521 QCBOREncode_AddInt64(pMe, nLabel);
2522 QCBOREncode_AddFloat(pMe, fNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002523}
2524
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002525static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002526QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pMe,
2527 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002528 const double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002529{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002530 QCBOREncode_AddSZString(pMe, szLabel);
2531 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002532}
2533
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002534static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002535QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002536 const int64_t nLabel,
2537 const double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002538{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002539 QCBOREncode_AddInt64(pMe, nLabel);
2540 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002541}
2542
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002543static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002544QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pMe,
2545 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002546 const float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002547{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002548 QCBOREncode_AddSZString(pMe, szLabel);
2549 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002550}
2551
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002552static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002553QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002554 const int64_t nLabel,
2555 const float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002556{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002557 QCBOREncode_AddInt64(pMe, nLabel);
2558 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002559}
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +02002560#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002561
Michael Eckel5c531332020-03-02 01:35:30 +01002562
Laurence Lundblade9b334962020-08-27 10:55:53 -07002563
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002564static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002565QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pMe,
2566 const uint8_t uTag,
2567 const int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002568{
2569 if(uTag == QCBOR_ENCODE_AS_TAG) {
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002570 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_EPOCH);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002571 }
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002572 QCBOREncode_AddInt64(pMe, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002573}
2574
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002575static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002576QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pMe,
2577 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002578 const uint8_t uTag,
2579 const int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002580{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002581 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002582 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002583}
2584
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002585static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002586QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002587 const int64_t nLabel,
2588 const uint8_t uTag,
2589 const int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002590{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002591 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002592 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002593}
2594
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002595static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002596QCBOREncode_AddDateEpoch(QCBOREncodeContext *pMe,
2597 const int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002598{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002599 QCBOREncode_AddTDateEpoch(pMe, QCBOR_ENCODE_AS_TAG, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002600}
2601
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002602static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002603QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pMe,
2604 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002605 const int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002606{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002607 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002608 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002609}
2610
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002611static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002612QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002613 const int64_t nLabel,
2614 const int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002615{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002616 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002617 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002618}
2619
2620
Laurence Lundblade46d63e92021-05-13 11:37:10 -07002621static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002622QCBOREncode_AddTDaysEpoch(QCBOREncodeContext *pMe,
2623 const uint8_t uTag,
2624 const int64_t nDays)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07002625{
2626 if(uTag == QCBOR_ENCODE_AS_TAG) {
2627 QCBOREncode_AddTag(pMe, CBOR_TAG_DAYS_EPOCH);
2628 }
2629 QCBOREncode_AddInt64(pMe, nDays);
2630}
2631
2632static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002633QCBOREncode_AddTDaysEpochToMapSZ(QCBOREncodeContext *pMe,
2634 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002635 const uint8_t uTag,
2636 const int64_t nDays)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07002637{
2638 QCBOREncode_AddSZString(pMe, szLabel);
2639 QCBOREncode_AddTDaysEpoch(pMe, uTag, nDays);
2640}
2641
2642static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002643QCBOREncode_AddTDaysEpochToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002644 const int64_t nLabel,
2645 const uint8_t uTag,
2646 const int64_t nDays)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07002647{
2648 QCBOREncode_AddInt64(pMe, nLabel);
2649 QCBOREncode_AddTDaysEpoch(pMe, uTag, nDays);
2650}
2651
Laurence Lundblade9b334962020-08-27 10:55:53 -07002652
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002653static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002654QCBOREncode_AddBytes(QCBOREncodeContext *pMe,
2655 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002656{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002657 QCBOREncode_Private_AddBuffer(pMe, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002658}
2659
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002660static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002661QCBOREncode_AddBytesToMap(QCBOREncodeContext *pMe,
2662 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002663 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002664{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002665 QCBOREncode_AddSZString(pMe, szLabel);
2666 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002667}
2668
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002669static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002670QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002671 const int64_t nLabel,
2672 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002673{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002674 QCBOREncode_AddInt64(pMe, nLabel);
2675 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002676}
2677
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002678static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002679QCBOREncode_OpenBytesInMapSZ(QCBOREncodeContext *pMe,
2680 const char *szLabel,
2681 UsefulBuf *pPlace)
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06002682{
2683 QCBOREncode_AddSZString(pMe, szLabel);
2684 QCBOREncode_OpenBytes(pMe, pPlace);
2685}
2686
2687static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002688QCBOREncode_OpenBytesInMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002689 const int64_t nLabel,
Laurence Lundblade3eead482023-12-16 20:53:22 -07002690 UsefulBuf *pPlace)
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06002691{
2692 QCBOREncode_AddInt64(pMe, nLabel);
2693 QCBOREncode_OpenBytes(pMe, pPlace);
2694}
2695
2696static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002697QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002698{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002699 QCBOREncode_Private_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002700}
2701
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002702static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002703QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pMe,
2704 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002705 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002706{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002707 QCBOREncode_AddSZString(pMe, szLabel);
2708 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002709}
2710
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002711static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002712QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002713 const int64_t nLabel,
2714 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002715{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002716 QCBOREncode_AddInt64(pMe, nLabel);
2717 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002718}
2719
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002720
2721static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002722QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002723 const uint8_t uTagRequirement,
2724 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002725{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002726 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2727 QCBOREncode_AddTag(pMe, CBOR_TAG_BIN_UUID);
2728 }
2729 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002730}
2731
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002732static inline void
2733QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pMe,
2734 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002735 const uint8_t uTagRequirement,
2736 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002737{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002738 QCBOREncode_AddSZString(pMe, szLabel);
2739 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002740}
2741
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002742static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002743QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002744 const int64_t nLabel,
2745 const uint8_t uTagRequirement,
2746 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002747{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002748 QCBOREncode_AddInt64(pMe, nLabel);
2749 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002750}
2751
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002752static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002753QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002754{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002755 QCBOREncode_AddTBinaryUUID(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002756}
2757
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002758static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002759QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pMe,
2760 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002761 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002762{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002763 QCBOREncode_AddTBinaryUUIDToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002764}
2765
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002766static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002767QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002768 const int64_t nLabel,
2769 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002770{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002771 QCBOREncode_AddTBinaryUUIDToMapN(pMe,
2772 nLabel,
2773 QCBOR_ENCODE_AS_TAG,
2774 Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002775}
2776
2777
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002778static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002779QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002780 const uint8_t uTagRequirement,
2781 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002782{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002783 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2784 QCBOREncode_AddTag(pMe, CBOR_TAG_POS_BIGNUM);
2785 }
2786 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002787}
2788
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002789static inline void
2790QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pMe,
2791 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002792 const uint8_t uTagRequirement,
2793 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002794{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002795 QCBOREncode_AddSZString(pMe, szLabel);
2796 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002797}
2798
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002799static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002800QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002801 const int64_t nLabel,
2802 const uint8_t uTagRequirement,
2803 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002804{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002805 QCBOREncode_AddInt64(pMe, nLabel);
2806 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002807}
2808
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002809static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002810QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002811{
2812 QCBOREncode_AddTPositiveBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2813}
2814
2815static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002816QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pMe,
2817 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002818 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002819{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002820 QCBOREncode_AddTPositiveBignumToMapSZ(pMe,
2821 szLabel,
2822 QCBOR_ENCODE_AS_TAG,
2823 Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002824}
2825
2826static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002827QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002828 const int64_t nLabel,
2829 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002830{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002831 QCBOREncode_AddTPositiveBignumToMapN(pMe,
2832 nLabel,
2833 QCBOR_ENCODE_AS_TAG,
2834 Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002835}
2836
2837
2838static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002839QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002840 const uint8_t uTagRequirement,
2841 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002842{
2843 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2844 QCBOREncode_AddTag(pMe, CBOR_TAG_NEG_BIGNUM);
2845 }
2846 QCBOREncode_AddBytes(pMe, Bytes);
2847}
2848
2849static inline void
2850QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pMe,
2851 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002852 const uint8_t uTagRequirement,
2853 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002854{
2855 QCBOREncode_AddSZString(pMe, szLabel);
2856 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2857}
2858
2859static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002860QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002861 const int64_t nLabel,
2862 const uint8_t uTagRequirement,
2863 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002864{
2865 QCBOREncode_AddInt64(pMe, nLabel);
2866 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2867}
2868
2869static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002870QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002871{
2872 QCBOREncode_AddTNegativeBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2873}
2874
2875static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002876QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pMe,
2877 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002878 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002879{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002880 QCBOREncode_AddTNegativeBignumToMapSZ(pMe,
2881 szLabel,
2882 QCBOR_ENCODE_AS_TAG,
2883 Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002884}
2885
2886static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07002887QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002888 const int64_t nLabel,
2889 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002890{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002891 QCBOREncode_AddTNegativeBignumToMapN(pMe,
2892 nLabel,
2893 QCBOR_ENCODE_AS_TAG,
2894 Bytes);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002895}
2896
2897
Michael Eckel5c531332020-03-02 01:35:30 +01002898
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07002899#ifndef QCBOR_DISABLE_EXP_AND_MANTISSA
Michael Eckel5c531332020-03-02 01:35:30 +01002900
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002901static inline void
2902QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002903 const uint8_t uTagRequirement,
2904 const int64_t nMantissa,
2905 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002906{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002907 uint64_t uTag;
2908 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2909 uTag = CBOR_TAG_DECIMAL_FRACTION;
2910 } else {
2911 uTag = CBOR_TAG_INVALID64;
2912 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002913 QCBOREncode_Private_AddExpMantissa(pMe,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002914 uTag,
Michael Eckel5c531332020-03-02 01:35:30 +01002915 NULLUsefulBufC,
2916 false,
2917 nMantissa,
2918 nBase10Exponent);
2919}
2920
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002921static inline void
2922QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pMe,
2923 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002924 const uint8_t uTagRequirement,
2925 const int64_t nMantissa,
2926 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002927{
2928 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07002929 QCBOREncode_AddTDecimalFraction(pMe,
2930 uTagRequirement,
2931 nMantissa,
2932 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002933}
2934
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002935static inline void
2936QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002937 const int64_t nLabel,
2938 const uint8_t uTagRequirement,
2939 const int64_t nMantissa,
2940 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002941{
2942 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07002943 QCBOREncode_AddTDecimalFraction(pMe,
2944 uTagRequirement,
2945 nMantissa,
2946 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002947}
2948
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002949static inline void
2950QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002951 const int64_t nMantissa,
2952 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002953{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002954 QCBOREncode_AddTDecimalFraction(pMe,
2955 QCBOR_ENCODE_AS_TAG,
2956 nMantissa,
2957 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002958}
2959
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002960static inline void
2961QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pMe,
2962 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002963 const int64_t nMantissa,
2964 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002965{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002966 QCBOREncode_AddTDecimalFractionToMapSZ(pMe,
2967 szLabel,
2968 QCBOR_ENCODE_AS_TAG,
2969 nMantissa,
2970 nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002971}
2972
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002973static inline void
2974QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002975 const int64_t nLabel,
2976 const int64_t nMantissa,
2977 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002978{
Laurence Lundblade3eead482023-12-16 20:53:22 -07002979 QCBOREncode_AddTDecimalFractionToMapN(pMe,
2980 nLabel,
2981 QCBOR_ENCODE_AS_TAG,
2982 nMantissa,
2983 nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002984}
2985
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002986
2987
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002988static inline void
2989QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07002990 const uint8_t uTagRequirement,
2991 const UsefulBufC Mantissa,
2992 const bool bIsNegative,
2993 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002994{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002995 uint64_t uTag;
2996 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2997 uTag = CBOR_TAG_DECIMAL_FRACTION;
2998 } else {
2999 uTag = CBOR_TAG_INVALID64;
3000 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003001 QCBOREncode_Private_AddExpMantissa(pMe,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003002 uTag,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003003 Mantissa,
3004 bIsNegative,
Michael Eckel5c531332020-03-02 01:35:30 +01003005 0,
3006 nBase10Exponent);
3007}
3008
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003009static inline void
3010QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
3011 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003012 const uint8_t uTagRequirement,
3013 const UsefulBufC Mantissa,
3014 const bool bIsNegative,
3015 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003016{
3017 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003018 QCBOREncode_AddTDecimalFractionBigNum(pMe,
3019 uTagRequirement,
3020 Mantissa,
3021 bIsNegative,
3022 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003023}
3024
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003025static inline void
3026QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003027 const int64_t nLabel,
3028 const uint8_t uTagRequirement,
3029 const UsefulBufC Mantissa,
3030 const bool bIsNegative,
3031 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003032{
3033 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003034 QCBOREncode_AddTDecimalFractionBigNum(pMe,
3035 uTagRequirement,
3036 Mantissa,
3037 bIsNegative,
3038 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003039}
3040
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003041static inline void
3042QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003043 const UsefulBufC Mantissa,
3044 const bool bIsNegative,
3045 const int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003046{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003047 QCBOREncode_AddTDecimalFractionBigNum(pMe,
3048 QCBOR_ENCODE_AS_TAG,
3049 Mantissa,
3050 bIsNegative,
3051 nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003052}
3053
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003054static inline void
3055QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
3056 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003057 const UsefulBufC Mantissa,
3058 const bool bIsNegative,
3059 const int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003060{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003061 QCBOREncode_AddTDecimalFractionBigNumToMapSZ(pMe,
3062 szLabel,
3063 QCBOR_ENCODE_AS_TAG,
3064 Mantissa,
3065 bIsNegative,
3066 nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003067}
3068
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003069static inline void
3070QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003071 const int64_t nLabel,
3072 const UsefulBufC Mantissa,
3073 const bool bIsNegative,
3074 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003075{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003076 QCBOREncode_AddTDecimalFractionBigNumToMapN(pMe,
3077 nLabel,
3078 QCBOR_ENCODE_AS_TAG,
3079 Mantissa,
3080 bIsNegative,
3081 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003082}
3083
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003084
3085
3086
3087
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003088static inline void
3089QCBOREncode_AddTBigFloat(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003090 const uint8_t uTagRequirement,
3091 const int64_t nMantissa,
3092 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003093{
3094 uint64_t uTag;
3095 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3096 uTag = CBOR_TAG_BIGFLOAT;
3097 } else {
3098 uTag = CBOR_TAG_INVALID64;
3099 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003100 QCBOREncode_Private_AddExpMantissa(pMe,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003101 uTag,
3102 NULLUsefulBufC,
3103 false,
3104 nMantissa,
3105 nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003106}
3107
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003108static inline void
3109QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pMe,
3110 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003111 const uint8_t uTagRequirement,
3112 const int64_t nMantissa,
3113 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003114{
3115 QCBOREncode_AddSZString(pMe, szLabel);
3116 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
3117}
3118
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003119static inline void
3120QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003121 const int64_t nLabel,
3122 const uint8_t uTagRequirement,
3123 const int64_t nMantissa,
3124 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003125{
3126 QCBOREncode_AddInt64(pMe, nLabel);
3127 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
3128}
3129
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003130static inline void
3131QCBOREncode_AddBigFloat(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003132 const int64_t nMantissa,
3133 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003134{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003135 QCBOREncode_AddTBigFloat(pMe,
3136 QCBOR_ENCODE_AS_TAG,
3137 nMantissa,
3138 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003139}
3140
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003141static inline void
3142QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pMe,
3143 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003144 const int64_t nMantissa,
3145 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003146{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003147 QCBOREncode_AddTBigFloatToMapSZ(pMe,
3148 szLabel,
3149 QCBOR_ENCODE_AS_TAG,
3150 nMantissa,
3151 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003152}
3153
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003154static inline void
3155QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003156 const int64_t nLabel,
3157 const int64_t nMantissa,
3158 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003159{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003160 QCBOREncode_AddTBigFloatToMapN(pMe,
3161 nLabel,
3162 QCBOR_ENCODE_AS_TAG,
3163 nMantissa,
3164 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003165}
3166
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003167
3168
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003169static inline void
3170QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003171 const uint8_t uTagRequirement,
3172 const UsefulBufC Mantissa,
3173 const bool bIsNegative,
3174 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003175{
3176 uint64_t uTag;
3177 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3178 uTag = CBOR_TAG_BIGFLOAT;
3179 } else {
3180 uTag = CBOR_TAG_INVALID64;
3181 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003182 QCBOREncode_Private_AddExpMantissa(pMe,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003183 uTag,
3184 Mantissa,
3185 bIsNegative,
3186 0,
3187 nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003188}
3189
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003190static inline void
3191QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pMe,
3192 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003193 const uint8_t uTagRequirement,
3194 const UsefulBufC Mantissa,
3195 const bool bIsNegative,
3196 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003197{
3198 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003199 QCBOREncode_AddTBigFloatBigNum(pMe,
3200 uTagRequirement,
3201 Mantissa,
3202 bIsNegative,
3203 nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003204}
3205
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003206static inline void
3207QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003208 const int64_t nLabel,
3209 const uint8_t uTagRequirement,
3210 const UsefulBufC Mantissa,
3211 const bool bIsNegative,
3212 const int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003213{
3214 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade3eead482023-12-16 20:53:22 -07003215 QCBOREncode_AddTBigFloatBigNum(pMe,
3216 uTagRequirement,
3217 Mantissa,
3218 bIsNegative,
3219 nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003220}
3221
3222
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003223static inline void
3224QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003225 const UsefulBufC Mantissa,
3226 const bool bIsNegative,
3227 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003228{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003229 QCBOREncode_AddTBigFloatBigNum(pMe,
3230 QCBOR_ENCODE_AS_TAG,
3231 Mantissa, bIsNegative,
3232 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003233}
3234
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003235static inline void
3236QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pMe,
3237 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003238 const UsefulBufC Mantissa,
3239 const bool bIsNegative,
3240 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003241{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003242 QCBOREncode_AddTBigFloatBigNumToMapSZ(pMe,
3243 szLabel,
3244 QCBOR_ENCODE_AS_TAG,
3245 Mantissa,
3246 bIsNegative,
3247 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003248}
3249
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003250static inline void
3251QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003252 const int64_t nLabel,
3253 const UsefulBufC Mantissa,
3254 const bool bIsNegative,
3255 const int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01003256{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003257 QCBOREncode_AddTBigFloatBigNumToMapN(pMe,
3258 nLabel,
3259 QCBOR_ENCODE_AS_TAG,
3260 Mantissa,
3261 bIsNegative,
3262 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01003263}
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07003264#endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
Michael Eckel5c531332020-03-02 01:35:30 +01003265
3266
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003267static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003268QCBOREncode_AddTURI(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003269 const uint8_t uTagRequirement,
3270 const UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01003271{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003272 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3273 QCBOREncode_AddTag(pMe, CBOR_TAG_URI);
3274 }
3275 QCBOREncode_AddText(pMe, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01003276}
3277
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003278static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003279QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pMe,
3280 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003281 const uint8_t uTagRequirement,
3282 const UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01003283{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003284 QCBOREncode_AddSZString(pMe, szLabel);
3285 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01003286}
3287
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003288static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003289QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003290 const int64_t nLabel,
3291 const uint8_t uTagRequirement,
3292 const UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01003293{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003294 QCBOREncode_AddInt64(pMe, nLabel);
3295 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
3296}
3297
3298static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003299QCBOREncode_AddURI(QCBOREncodeContext *pMe, const UsefulBufC URI)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003300{
3301 QCBOREncode_AddTURI(pMe, QCBOR_ENCODE_AS_TAG, URI);
3302}
3303
3304static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003305QCBOREncode_AddURIToMap(QCBOREncodeContext *pMe,
3306 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003307 const UsefulBufC URI)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003308{
3309 QCBOREncode_AddTURIToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, URI);
3310}
3311
3312static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003313QCBOREncode_AddURIToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003314 const int64_t nLabel,
3315 const UsefulBufC URI)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003316{
3317 QCBOREncode_AddTURIToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01003318}
3319
3320
3321
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003322static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003323QCBOREncode_AddTB64Text(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003324 const uint8_t uTagRequirement,
3325 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003326{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003327 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3328 QCBOREncode_AddTag(pMe, CBOR_TAG_B64);
3329 }
3330 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003331}
3332
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003333static inline void
3334QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pMe,
3335 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003336 const uint8_t uTagRequirement,
3337 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003338{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003339 QCBOREncode_AddSZString(pMe, szLabel);
3340 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003341}
3342
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003343static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003344QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003345 const int64_t nLabel,
3346 const uint8_t uTagRequirement,
3347 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003348{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003349 QCBOREncode_AddInt64(pMe, nLabel);
3350 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
3351}
3352
3353static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003354QCBOREncode_AddB64Text(QCBOREncodeContext *pMe, const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003355{
3356 QCBOREncode_AddTB64Text(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
3357}
3358
3359static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003360QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pMe,
3361 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003362 const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003363{
3364 QCBOREncode_AddTB64TextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
3365}
3366
3367static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003368QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003369 const int64_t nLabel,
3370 const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003371{
3372 QCBOREncode_AddTB64TextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003373}
3374
3375
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003376
3377static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003378QCBOREncode_AddTB64URLText(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003379 const uint8_t uTagRequirement,
3380 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003381{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003382 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3383 QCBOREncode_AddTag(pMe, CBOR_TAG_B64URL);
3384 }
3385 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003386}
3387
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003388static inline void
3389QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pMe,
3390 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003391 const uint8_t uTagRequirement,
3392 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003393{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003394 QCBOREncode_AddSZString(pMe, szLabel);
3395 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003396}
3397
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003398static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003399QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003400 const int64_t nLabel,
3401 const uint8_t uTagRequirement,
3402 const UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003403{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003404 QCBOREncode_AddInt64(pMe, nLabel);
3405 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
3406}
3407
3408static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003409QCBOREncode_AddB64URLText(QCBOREncodeContext *pMe, const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003410{
3411 QCBOREncode_AddTB64URLText(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
3412}
3413
3414static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003415QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pMe,
3416 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003417 const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003418{
Laurence Lundblade3eead482023-12-16 20:53:22 -07003419 QCBOREncode_AddTB64URLTextToMapSZ(pMe,
3420 szLabel,
3421 QCBOR_ENCODE_AS_TAG,
3422 B64Text);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003423}
3424
3425static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003426QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003427 const int64_t nLabel,
3428 const UsefulBufC B64Text)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003429{
3430 QCBOREncode_AddTB64URLTextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003431}
3432
3433
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003434
3435static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003436QCBOREncode_AddTRegex(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003437 const uint8_t uTagRequirement,
3438 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003439{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003440 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3441 QCBOREncode_AddTag(pMe, CBOR_TAG_REGEX);
3442 }
3443 QCBOREncode_AddText(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01003444}
3445
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003446static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003447QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pMe,
3448 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003449 const uint8_t uTagRequirement,
3450 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003451{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003452 QCBOREncode_AddSZString(pMe, szLabel);
3453 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01003454}
3455
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003456static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003457QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003458 const int64_t nLabel,
3459 const uint8_t uTagRequirement,
3460 const UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003461{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003462 QCBOREncode_AddInt64(pMe, nLabel);
3463 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
3464}
3465
3466static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003467QCBOREncode_AddRegex(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003468{
3469 QCBOREncode_AddTRegex(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
3470}
3471
3472static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003473QCBOREncode_AddRegexToMap(QCBOREncodeContext *pMe,
3474 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003475 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003476{
3477 QCBOREncode_AddTRegexToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
3478}
3479
3480static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003481QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003482 const int64_t nLabel,
3483 const UsefulBufC Bytes)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003484{
3485 QCBOREncode_AddTRegexToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
3486
Michael Eckel5c531332020-03-02 01:35:30 +01003487}
3488
3489
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003490static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003491QCBOREncode_AddTMIMEData(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003492 const uint8_t uTagRequirement,
3493 const UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01003494{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003495 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
Laurence Lundblade4982f412020-09-18 23:02:18 -07003496 QCBOREncode_AddTag(pMe, CBOR_TAG_BINARY_MIME);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003497 }
Laurence Lundblade4982f412020-09-18 23:02:18 -07003498 QCBOREncode_AddBytes(pMe, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01003499}
3500
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003501static inline void
3502QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pMe,
3503 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003504 const uint8_t uTagRequirement,
3505 const UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01003506{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003507 QCBOREncode_AddSZString(pMe, szLabel);
3508 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01003509}
3510
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003511static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003512QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003513 const int64_t nLabel,
3514 const uint8_t uTagRequirement,
3515 const UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01003516{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003517 QCBOREncode_AddInt64(pMe, nLabel);
3518 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
3519}
3520
3521static inline void
3522QCBOREncode_AddMIMEData(QCBOREncodeContext *pMe, UsefulBufC MIMEData)
3523{
3524 QCBOREncode_AddTMIMEData(pMe, QCBOR_ENCODE_AS_TAG, MIMEData);
3525}
3526
3527static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003528QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pMe,
3529 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003530 const UsefulBufC MIMEData)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003531{
3532 QCBOREncode_AddTMIMEDataToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
3533}
3534
3535static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003536QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003537 const int64_t nLabel,
3538 const UsefulBufC MIMEData)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003539{
3540 QCBOREncode_AddTMIMEDataToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01003541}
3542
3543
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003544static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003545QCBOREncode_AddTDateString(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003546 const uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003547 const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01003548{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003549 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3550 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_STRING);
3551 }
3552 QCBOREncode_AddSZString(pMe, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01003553}
3554
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003555static inline void
3556QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pMe,
3557 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003558 const uint8_t uTagRequirement,
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003559 const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01003560{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003561 QCBOREncode_AddSZString(pMe, szLabel);
3562 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01003563}
3564
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003565static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003566QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003567 const int64_t nLabel,
3568 const uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003569 const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01003570{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003571 QCBOREncode_AddInt64(pMe, nLabel);
3572 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
3573}
3574
3575static inline void
3576QCBOREncode_AddDateString(QCBOREncodeContext *pMe, const char *szDate)
3577{
3578 QCBOREncode_AddTDateString(pMe, QCBOR_ENCODE_AS_TAG, szDate);
3579}
3580
3581static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003582QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pMe,
3583 const char *szLabel,
3584 const char *szDate)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003585{
3586 QCBOREncode_AddTDateStringToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, szDate);
3587}
3588
3589static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003590QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003591 const int64_t nLabel,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003592 const char *szDate)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003593{
3594 QCBOREncode_AddTDateStringToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01003595}
3596
3597
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003598static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003599QCBOREncode_AddTDaysString(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003600 const uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003601 const char *szDate)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07003602{
3603 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3604 QCBOREncode_AddTag(pMe, CBOR_TAG_DAYS_STRING);
3605 }
3606 QCBOREncode_AddSZString(pMe, szDate);
3607}
3608
3609static inline void
3610QCBOREncode_AddTDaysStringToMapSZ(QCBOREncodeContext *pMe,
3611 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003612 const uint8_t uTagRequirement,
Laurence Lundblade46d63e92021-05-13 11:37:10 -07003613 const char *szDate)
3614{
3615 QCBOREncode_AddSZString(pMe, szLabel);
3616 QCBOREncode_AddTDaysString(pMe, uTagRequirement, szDate);
3617}
3618
3619static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003620QCBOREncode_AddTDaysStringToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003621 const int64_t nLabel,
3622 const uint8_t uTagRequirement,
Laurence Lundblade3eead482023-12-16 20:53:22 -07003623 const char *szDate)
Laurence Lundblade46d63e92021-05-13 11:37:10 -07003624{
3625 QCBOREncode_AddInt64(pMe, nLabel);
3626 QCBOREncode_AddTDaysString(pMe, uTagRequirement, szDate);
3627}
3628
3629
3630
3631static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003632QCBOREncode_Private_AddSimple(QCBOREncodeContext *pMe, const uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01003633{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003634 QCBOREncode_Private_AddType7(pMe, 0, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01003635}
3636
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003637static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003638QCBOREncode_Private_AddSimpleToMap(QCBOREncodeContext *pMe,
3639 const char *szLabel,
3640 const uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01003641{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003642 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003643 QCBOREncode_Private_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01003644}
3645
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003646static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003647QCBOREncode_Private_AddSimpleToMapN(QCBOREncodeContext *pMe,
3648 const int64_t nLabel,
3649 const uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01003650{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003651 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003652 QCBOREncode_Private_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01003653}
3654
3655
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003656static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003657QCBOREncode_AddBool(QCBOREncodeContext *pMe, const bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01003658{
3659 uint8_t uSimple = CBOR_SIMPLEV_FALSE;
3660 if(b) {
3661 uSimple = CBOR_SIMPLEV_TRUE;
3662 }
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003663 QCBOREncode_Private_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01003664}
3665
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003666static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003667QCBOREncode_AddBoolToMap(QCBOREncodeContext *pMe, const char *szLabel, const bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01003668{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003669 QCBOREncode_AddSZString(pMe, szLabel);
3670 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01003671}
3672
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003673static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003674QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pMe, const int64_t nLabel, const bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01003675{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003676 QCBOREncode_AddInt64(pMe, nLabel);
3677 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01003678}
3679
3680
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003681static inline void
3682QCBOREncode_AddNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003683{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003684 QCBOREncode_Private_AddSimple(pMe, CBOR_SIMPLEV_NULL);
Michael Eckel5c531332020-03-02 01:35:30 +01003685}
3686
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003687static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003688QCBOREncode_AddNULLToMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003689{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003690 QCBOREncode_AddSZString(pMe, szLabel);
3691 QCBOREncode_AddNULL(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003692}
3693
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003694static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003695QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003696{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003697 QCBOREncode_AddInt64(pMe, nLabel);
3698 QCBOREncode_AddNULL(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003699}
3700
3701
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003702static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003703QCBOREncode_AddUndef(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003704{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003705 QCBOREncode_Private_AddSimple(pMe, CBOR_SIMPLEV_UNDEF);
Michael Eckel5c531332020-03-02 01:35:30 +01003706}
3707
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003708static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003709QCBOREncode_AddUndefToMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003710{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003711 QCBOREncode_AddSZString(pMe, szLabel);
3712 QCBOREncode_AddUndef(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003713}
3714
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003715static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003716QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003717{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003718 QCBOREncode_AddInt64(pMe, nLabel);
3719 QCBOREncode_AddUndef(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003720}
3721
3722
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003723static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003724QCBOREncode_OpenArray(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003725{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003726 QCBOREncode_Private_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
Michael Eckel5c531332020-03-02 01:35:30 +01003727}
3728
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003729static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003730QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003731{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003732 QCBOREncode_AddSZString(pMe, szLabel);
3733 QCBOREncode_OpenArray(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003734}
3735
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003736static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003737QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003738{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003739 QCBOREncode_AddInt64(pMe, nLabel);
3740 QCBOREncode_OpenArray(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003741}
3742
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003743static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003744QCBOREncode_CloseArray(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003745{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003746 QCBOREncode_Private_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
Michael Eckel5c531332020-03-02 01:35:30 +01003747}
3748
3749
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003750static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003751QCBOREncode_OpenMap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003752{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003753 QCBOREncode_Private_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
Michael Eckel5c531332020-03-02 01:35:30 +01003754}
3755
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003756static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003757QCBOREncode_OpenMapInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003758{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003759 QCBOREncode_AddSZString(pMe, szLabel);
3760 QCBOREncode_OpenMap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003761}
3762
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003763static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003764QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003765{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003766 QCBOREncode_AddInt64(pMe, nLabel);
3767 QCBOREncode_OpenMap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003768}
3769
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003770static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003771QCBOREncode_CloseMap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003772{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003773 QCBOREncode_Private_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
Michael Eckel5c531332020-03-02 01:35:30 +01003774}
3775
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003776static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003777QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003778{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003779 QCBOREncode_Private_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003780}
3781
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003782static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003783QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pMe,
3784 const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003785{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003786 QCBOREncode_AddSZString(pMe, szLabel);
3787 QCBOREncode_OpenArrayIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003788}
3789
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003790static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003791QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003792 const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003793{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003794 QCBOREncode_AddInt64(pMe, nLabel);
3795 QCBOREncode_OpenArrayIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003796}
3797
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003798static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003799QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003800{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003801 QCBOREncode_Private_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003802}
3803
3804
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003805static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003806QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003807{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003808 QCBOREncode_Private_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003809}
3810
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003811static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003812QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pMe,
3813 const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003814{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003815 QCBOREncode_AddSZString(pMe, szLabel);
3816 QCBOREncode_OpenMapIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003817}
3818
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003819static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003820QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003821 const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003822{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003823 QCBOREncode_AddInt64(pMe, nLabel);
3824 QCBOREncode_OpenMapIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003825}
3826
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003827static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003828QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003829{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003830 QCBOREncode_Private_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003831}
3832
3833
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003834static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003835QCBOREncode_BstrWrap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003836{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003837 QCBOREncode_Private_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_BYTE_STRING);
Michael Eckel5c531332020-03-02 01:35:30 +01003838}
3839
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003840static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003841QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003842{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003843 QCBOREncode_AddSZString(pMe, szLabel);
3844 QCBOREncode_BstrWrap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003845}
3846
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003847static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003848QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003849{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003850 QCBOREncode_AddInt64(pMe, nLabel);
3851 QCBOREncode_BstrWrap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003852}
3853
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003854static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003855QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pMe, UsefulBufC *pWrappedCBOR)
Michael Eckel5c531332020-03-02 01:35:30 +01003856{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003857 QCBOREncode_CloseBstrWrap2(pMe, true, pWrappedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01003858}
3859
3860
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003861static inline void
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003862QCBOREncode_AddEncoded(QCBOREncodeContext *pMe, const UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003863{
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003864 QCBOREncode_Private_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_RAW, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003865}
3866
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003867static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003868QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pMe,
3869 const char *szLabel,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003870 const UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003871{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003872 QCBOREncode_AddSZString(pMe, szLabel);
3873 QCBOREncode_AddEncoded(pMe, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003874}
3875
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003876static inline void
Laurence Lundblade3eead482023-12-16 20:53:22 -07003877QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pMe,
Laurence Lundblade8e36f812024-01-26 10:59:29 -07003878 const int64_t nLabel,
3879 const UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003880{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003881 QCBOREncode_AddInt64(pMe, nLabel);
3882 QCBOREncode_AddEncoded(pMe, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003883}
3884
3885
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003886static inline int
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003887QCBOREncode_IsBufferNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003888{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003889 return UsefulOutBuf_IsBufferNULL(&(pMe->OutBuf));
Michael Eckel5c531332020-03-02 01:35:30 +01003890}
3891
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003892static inline QCBORError
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003893QCBOREncode_GetErrorState(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003894{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003895 if(UsefulOutBuf_GetError(&(pMe->OutBuf))) {
Laurence Lundbladef2f0c3f2024-04-12 13:01:54 -07003896 /* Items didn't fit in the buffer. This check catches this
3897 * condition for all the appends and inserts so checks aren't
3898 * needed when the appends and inserts are performed. And of
3899 * course UsefulBuf will never overrun the input buffer given to
3900 * it. No complex analysis of the error handling in this file is
3901 * needed to know that is true. Just read the UsefulBuf code.
3902 */
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003903 pMe->uError = QCBOR_ERR_BUFFER_TOO_SMALL;
Laurence Lundbladef2f0c3f2024-04-12 13:01:54 -07003904 /* QCBOR_ERR_BUFFER_TOO_SMALL masks other errors, but that is
3905 * OK. Once the caller fixes this, they'll be unmasked.
3906 */
Michael Eckel5c531332020-03-02 01:35:30 +01003907 }
3908
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003909 return (QCBORError)pMe->uError;
Michael Eckel5c531332020-03-02 01:35:30 +01003910}
3911
3912
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003913/* ========================================================================
3914 END OF PRIVATE INLINE IMPLEMENTATION
3915 ======================================================================== */
Michael Eckel5c531332020-03-02 01:35:30 +01003916
3917#ifdef __cplusplus
3918}
3919#endif
3920
Laurence Lundblade844bb5c2020-03-01 17:27:25 -08003921#endif /* qcbor_encode_h */