1 // SPDX-License-Identifier: BSD-3-Clause
2 /* ===========================================================================
3 * Copyright (c) 2016-2018, The Linux Foundation.
4 * Copyright (c) 2018-2024, Laurence Lundblade.
5 * Copyright (c) 2021, Arm Limited.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met:
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 * * Neither the name of The Linux Foundation nor the names of its
18 * contributors, nor the name "Laurence Lundblade" may be used to
19 * endorse or promote products derived from this software without
20 * specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
29 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
31 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
32 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * ========================================================================= */
34
35
36 #ifndef qcbor_encode_h
37 #define qcbor_encode_h
38
39
40 #include "qcbor/qcbor_common.h"
41 #include "qcbor/qcbor_private.h"
42 #include <stdbool.h>
43
44
45 #ifdef __cplusplus
46 extern "C" {
47 #if 0
48 } // Keep editor indention formatting happy
49 #endif
50 #endif
51
52
53 /**
54 * @file qcbor_encode.h
55 *
56 * @anchor Overview
57 *
58 * # QCBOR Overview
59 *
60 * This implements CBOR -- Concise Binary Object Representation as
61 * defined in [RFC 8949] (https://tools.ietf.org/html/rfc8949). More
62 * information is at http://cbor.io. This is a near-complete implementation of
63 * the specification. [RFC 8742] (https://tools.ietf.org/html/rfc8742) CBOR
64 * Sequences is also supported. Limitations are listed further down.
65 *
66 * See @ref Encoding for general discussion on encoding,
67 * @ref BasicDecode for general discussion on the basic decode features
68 * and @ref SpiffyDecode for general discussion on the easier-to-use
69 * decoder functions.
70 *
71 * CBOR is intentionally designed to be translatable to JSON, but not
72 * all CBOR can convert to JSON. See RFC 8949 for more info on how to
73 * construct CBOR that is the most JSON friendly.
74 *
75 * The memory model for encoding and decoding is that encoded CBOR must
76 * be in a contiguous buffer in memory. During encoding the caller must
77 * supply an output buffer and if the encoding would go off the end of
78 * the buffer an error is returned. During decoding the caller supplies
79 * the encoded CBOR in a contiguous buffer and the decoder returns
80 * pointers and lengths into that buffer for strings.
81 *
82 * This implementation does not require malloc. All data structures
83 * passed in/out of the APIs can fit on the stack.
84 *
85 * Decoding of indefinite-length strings is a special case that requires
86 * a "string allocator" to allocate memory into which the segments of
87 * the string are coalesced. Without this, decoding will error out if an
88 * indefinite-length string is encountered (indefinite-length maps and
89 * arrays do not require the string allocator). A simple string
90 * allocator called MemPool is built-in and will work if supplied with a
91 * block of memory to allocate. The string allocator can optionally use
92 * malloc() or some other custom scheme.
93 *
94 * Here are some terms and definitions:
95 *
96 * - "Item", "Data Item": An integer or string or such. The basic "thing" that
97 * CBOR is about. An array is an item itself that contains some items.
98 *
99 * - "Array": An ordered sequence of items, the same as JSON.
100 *
101 * - "Map": A collection of label/value pairs. Each pair is a data
102 * item. A JSON "object" is the same as a CBOR "map".
103 *
104 * - "Label": The data item in a pair in a map that names or identifies
105 * the pair, not the value. This implementation refers to it as a
106 * "label". JSON refers to it as the "name". The CBOR RFC refers to it
107 * this as a "key". This implementation chooses label instead because
108 * key is too easily confused with a cryptographic key. The COSE
109 * standard, which uses CBOR, has also chosen to use the term "label"
110 * rather than "key" for this same reason.
111 *
112 * - "Key": See "Label" above.
113 *
114 * - "Tag": A data item that is an explicitly labeled new data
115 * type made up of the tagging integer and the tag content.
116 * See @ref Tags-Overview and @ref Tag-Usage.
117 *
118 * - "Initial Byte": The first byte of an encoded item. Encoding and
119 * decoding of this byte is taken care of by the implementation.
120 *
121 * - "Additional Info": In addition to the major type, all data items
122 * have some other info. This is usually the length of the data but can
123 * be several other things. Encoding and decoding of this is taken care
124 * of by the implementation.
125 *
126 * CBOR has two mechanisms for tagging and labeling the data values like
127 * integers and strings. For example, an integer that represents
128 * someone's birthday in epoch seconds since Jan 1, 1970 could be
129 * encoded like this:
130 *
131 * - First it is CBOR_MAJOR_TYPE_POSITIVE_INT (@ref QCBOR_TYPE_INT64),
132 * the primitive positive integer.
133 *
134 * - Next it has a "tag" @ref CBOR_TAG_DATE_EPOCH indicating the integer
135 * represents a date in the form of the number of seconds since Jan 1,
136 * 1970.
137 *
138 * - Last it has a string "label" like "BirthDate" indicating the
139 * meaning of the data.
140 *
141 * The encoded binary looks like this:
142 *
143 * a1 # Map of 1 item
144 * 69 # Indicates text string of 9 bytes
145 * 426972746844617465 # The text "BirthDate"
146 * c1 # Tags next integer as epoch date
147 * 1a # Indicates a 4-byte integer
148 * 580d4172 # unsigned integer date 1477263730
149 *
150 * Implementors using this API will primarily work with
151 * labels. Generally, tags are only needed for making up new data
152 * types. This implementation covers most of the data types defined in
153 * the RFC using tags. It also, allows for the use of custom tags if
154 * necessary.
155 *
156 * This implementation explicitly supports labels that are text strings
157 * and integers. Text strings translate nicely into JSON objects and are
158 * very readable. Integer labels are much less readable but can be very
159 * compact. If they are in the range of 0 to 23, they take up only one
160 * byte.
161 *
162 * CBOR allows a label to be any type of data including an array or a
163 * map. It is possible to use this API to construct and parse such
164 * labels, but it is not explicitly supported.
165 *
166 * @anchor Encoding
167 *
168 * ## Encoding
169 *
170 * A common encoding usage mode is to invoke the encoding twice. First
171 * with the output buffer as @ref SizeCalculateUsefulBuf to compute the
172 * length of the needed output buffer. The correct sized output buffer
173 * is allocated. The encoder is invoked a second time with the allocated
174 * output buffer.
175 *
176 * The double invocation is not required if the maximum output buffer
177 * size can be predicted. This is usually possible for simple CBOR
178 * structures.
179 *
180 * If a buffer too small to hold the encoded output is given, the error
181 * @ref QCBOR_ERR_BUFFER_TOO_SMALL will be returned. Data will never be
182 * written off the end of the output buffer no matter which functions
183 * here are called or what parameters are passed to them.
184 *
185 * The encoding error handling is simple. The only possible errors are
186 * trying to encode structures that are too large or too complex. There
187 * are no internal malloc calls so there will be no failures for out of
188 * memory. The error state is tracked internally, so there is no need
189 * to check for errors when encoding. Only the return code from
190 * QCBOREncode_Finish() need be checked as once an error happens, the
191 * encoder goes into an error state and calls to it to add more data
192 * will do nothing. An error check is not needed after every data item
193 * is added.
194 *
195 * Encoding generally proceeds by calling QCBOREncode_Init(), calling
196 * lots of @c QCBOREncode_AddXxx() functions and calling
197 * QCBOREncode_Finish(). There are many @c QCBOREncode_AddXxx()
198 * functions for various data types. The input buffers need only to be
199 * valid during the @c QCBOREncode_AddXxx() calls as the data is copied
200 * into the output buffer.
201 *
202 * There are three `Add` functions for each data type. The first / main
203 * one for the type is for adding the data item to an array. The second
204 * one's name ends in `ToMap`, is used for adding data items to maps and
205 * takes a string argument that is its label in the map. The third one
206 * ends in `ToMapN`, is also used for adding data items to maps, and
207 * takes an integer argument that is its label in the map.
208 *
209 * The simplest aggregate type is an array, which is a simple ordered
210 * set of items without labels the same as JSON arrays. Call
211 * QCBOREncode_OpenArray() to open a new array, then various @c
212 * QCBOREncode_AddXxx() functions to put items in the array and then
213 * QCBOREncode_CloseArray(). Nesting to the limit @ref
214 * QCBOR_MAX_ARRAY_NESTING is allowed. All opens must be matched by
215 * closes or an encoding error will be returned.
216 *
217 * The other aggregate type is a map which does use labels. The `Add`
218 * functions that end in `ToMap` and `ToMapN` are convenient ways to add
219 * labeled data items to a map. You can also call any type of `Add`
220 * function once to add a label of any type and then call any type of
221 * `Add` again to add its value.
222 *
223 * Note that when you nest arrays or maps in a map, the nested array or
224 * map has a label.
225 *
226 * Many CBOR-based protocols start with an array or map. This makes them
227 * self-delimiting. No external length or end marker is needed to know
228 * the end. It is also possible not start this way, in which case this
229 * it is usually called a CBOR sequence which is described in
230 * [RFC 8742] (https://tools.ietf.org/html/rfc8742). This encoder supports
231 * either just by whether the first item added is an array, map or other.
232 *
233 * If QCBOR is compiled with QCBOR_DISABLE_ENCODE_USAGE_GUARDS defined,
234 * the errors QCBOR_ERR_CLOSE_MISMATCH, QCBOR_ERR_ARRAY_TOO_LONG,
235 * QCBOR_ERR_TOO_MANY_CLOSES, QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN, and
236 * QCBOR_ERR_ENCODE_UNSUPPORTED will never be returned. It is up to the
237 * caller to make sure that opened maps, arrays and byte-string wrapping
238 * is closed correctly and that QCBOREncode_AddType7() is called
239 * correctly. With this defined, it is easier to make a mistake when
240 * authoring the encoding of a protocol that will output not well formed
241 * CBOR, but as long as the calling code is correct, it is safe to
242 * disable these checks. Bounds checking that prevents security issues
243 * in the code is still enforced. This define reduces the size of
244 * encoding object code by about 150 bytes.
245 *
246 * @anchor Tags-Overview
247 *
248 * ## Tags Overview
249 *
250 * Any CBOR data item can be made into a tag to add semantics, define a
251 * new data type or such. Some tags are fully standardized and some are
252 * just registered. Others are not registered and used in a proprietary
253 * way.
254 *
255 * Encoding and decoding of many of the registered tags is fully
256 * implemented by QCBOR. It is also possible to encode and decode tags
257 * that are not directly supported. For many use cases the built-in tag
258 * support should be adequate.
259 *
260 * For example, the registered epoch date tag is supported in encoding
261 * by QCBOREncode_AddDateEpoch() and in decoding by @ref
262 * QCBOR_TYPE_DATE_EPOCH and the @c epochDate member of @ref
263 * QCBORItem. This is typical of the built-in tag support. There is an
264 * API to encode data for it and a @c QCBOR_TYPE_XXX when it is decoded.
265 *
266 * Tags are registered in the [IANA CBOR Tags Registry]
267 * (https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml). There
268 * are roughly three options to create a new tag. First, a public
269 * specification can be created and the new tag registered with IANA.
270 * This is the most formal. Second, the new tag can be registered with
271 * IANA with just a short description rather than a full specification.
272 * These tags must be greater than 256. Third, a tag can be used without
273 * any IANA registration, though the registry should be checked to see
274 * that the new value doesn't collide with one that is registered. The
275 * value of these tags must be 256 or larger.
276 *
277 * See also @ref CBORTags and @ref Tag-Usage
278 *
279 * The encoding side of tags not built-in is handled by
280 * QCBOREncode_AddTag() and is relatively simple. Tag decoding is more
281 * complex and mainly handled by QCBORDecode_GetNext(). Decoding of the
282 * structure of tagged data not built-in (if there is any) has to be
283 * implemented by the caller.
284 *
285 * @anchor Floating-Point
286 *
287 * ## Floating-Point
288 *
289 * By default QCBOR fully supports IEEE 754 floating-point:
290 * - Encode/decode of double, single and half-precision
291 * - CBOR preferred serialization of floating-point
292 * - Floating-point epoch dates
293 *
294 * For the most part, the type double is used in the interface for
295 * floating-point values. In the default configuration, all decoded
296 * floating-point values are returned as a double.
297 *
298 * With CBOR preferred serialization, the encoder outputs the smallest
299 * representation of the double or float that preserves precision. Zero,
300 * NaN and infinity are always output as a half-precision, each taking
301 * just 2 bytes. This reduces the number of bytes needed to encode
302 * double and single-precision, especially if zero, NaN and infinity are
303 * frequently used.
304 *
305 * To avoid use of preferred serialization in the standard configuration
306 * when encoding, use QCBOREncode_AddDoubleNoPreferred() or
307 * QCBOREncode_AddFloatNoPreferred().
308 *
309 * This implementation of preferred floating-point serialization and
310 * half-precision does not depend on the CPU having floating-point HW or
311 * the compiler bringing in a (sometimes large) library to compensate
312 * for lack of CPU support. This implementation uses shifts and masks
313 * rather than floating-point functions.
314 *
315 * To reduce overall object code by about 900 bytes, define
316 * QCBOR_DISABLE_PREFERRED_FLOAT. This will eliminate all support for
317 * preferred serialization and half-precision. An error will be returned
318 * when attempting to decode half-precision. A float will always be
319 * encoded and decoded as 32-bits and a double will always be encoded
320 * and decoded as 64 bits.
321 *
322 * Note that even if QCBOR_DISABLE_PREFERRED_FLOAT is not defined all
323 * the float-point encoding object code can be avoided by never calling
324 * any functions that encode double or float. Just not calling
325 * floating-point functions will reduce object code by about 500 bytes.
326 *
327 * On CPUs that have no floating-point hardware,
328 * QCBOR_DISABLE_FLOAT_HW_USE should be defined in most cases. If it is
329 * not, then the compiler will bring in possibly large software
330 * libraries to compensate. Defining QCBOR_DISABLE_FLOAT_HW_USE reduces
331 * object code size on CPUs with floating-point hardware by a tiny
332 * amount and eliminates the need for <math.h>
333 *
334 * When QCBOR_DISABLE_FLOAT_HW_USE is defined, trying to decoding
335 * floating-point dates will give error
336 * @ref QCBOR_ERR_FLOAT_DATE_DISABLED and decoded single-precision
337 * numbers will be returned as @ref QCBOR_TYPE_FLOAT instead of
338 * converting them to double as usual.
339 *
340 * If both QCBOR_DISABLE_FLOAT_HW_USE and QCBOR_DISABLE_PREFERRED_FLOAT
341 * are defined, then the only thing QCBOR can do is encode/decode a C
342 * float type as 32-bits and a C double type as 64-bits. Floating-point
343 * epoch dates will be unsupported.
344 *
345 * If USEFULBUF_DISABLE_ALL_FLOAT is defined, then floating point
346 * support is completely disabled. Decoding functions return
347 * @ref QCBOR_ERR_ALL_FLOAT_DISABLED if a floating point value is
348 * encountered during decoding. Functions that are encoding floating
349 * point values are not available.
350 *
351 * ## Limitations
352 *
353 * Summary limitations:
354 * - The entire encoded CBOR must fit into contiguous memory.
355 * - Max size of encoded CBOR data is a few bytes less than
356 * @c UINT32_MAX (4GB).
357 * - Max array / map nesting level when encoding or decoding is
358 * @ref QCBOR_MAX_ARRAY_NESTING (this is typically 15).
359 * - Max items in an array or map when encoding or decoding is
360 * @ref QCBOR_MAX_ITEMS_IN_ARRAY (typically 65,536).
361 * - Does not directly support labels in maps other than text strings & integers.
362 * - Does not directly support integer labels beyond whats fits in @c int64_t
363 * or @c uint64_t.
364 * - Epoch dates limited to @c INT64_MAX (+/- 292 billion years).
365 * - Exponents for bigfloats and decimal integers are limited to whats fits in
366 * @c int64_t.
367 * - Tags on labels are ignored during decoding.
368 * - The maximum tag nesting is @c QCBOR_MAX_TAGS_PER_ITEM (typically 4).
369 * - Works only on 32- and 64-bit CPUs.
370 * - QCBORDecode_EnterBstrWrapped() doesn't work on indefinite-length strings.
371 *
372 * The public interface uses @c size_t for all lengths. Internally the
373 * implementation uses 32-bit lengths by design to use less memory and
374 * fit structures on the stack. This limits the encoded CBOR it can
375 * work with to size @c UINT32_MAX (4GB).
376 *
377 * This implementation requires two's compliment integers. While
378 * C doesn't require two's compliment, <stdint.h> does. Other
379 * parts of this implementation may also require two's compliment.
380 */
381
382
383 /**
384 * The size of the buffer to be passed to QCBOREncode_EncodeHead(). It
385 * is one byte larger than sizeof(uint64_t) + 1, the actual maximum
386 * size of the head of a CBOR data item because
387 * QCBOREncode_EncodeHead() needs one extra byte to work.
388 */
389 #define QCBOR_HEAD_BUFFER_SIZE (sizeof(uint64_t) + 2)
390
391
392 /**
393 * Output the full CBOR tag. See @ref CBORTags, @ref Tag-Usage and
394 * @ref Tags-Overview.
395 */
396 #define QCBOR_ENCODE_AS_TAG 0
397
398 /**
399 * Output only the 'borrowed' content format for the relevant tag.
400 * See @ref CBORTags, @ref Tag-Usage and @ref Tags-Overview.
401 */
402 #define QCBOR_ENCODE_AS_BORROWED 1
403
404
405 /**
406 * QCBOREncodeContext is the data type that holds context for all the
407 * encoding functions. It is less than 200 bytes, so it can go on the
408 * stack. The contents are opaque, and the caller should not access
409 * internal members. A context may be re used serially as long as it is
410 * re initialized.
411 */
412 typedef struct _QCBOREncodeContext QCBOREncodeContext;
413
414
415 /**
416 * Initialize the encoder to prepare to encode some CBOR.
417 *
418 * @param[in,out] pCtx The encoder context to initialize.
419 * @param[in] Storage The buffer into which the encoded result
420 * will be written.
421 *
422 * Call this once at the start of an encoding of some CBOR. Then call
423 * the many functions like QCBOREncode_AddInt64() and
424 * QCBOREncode_AddText() to add the different data items. Finally,
425 * call QCBOREncode_Finish() to get the pointer and length of the
426 * encoded result.
427 *
428 * The primary purpose of this function is to give the pointer and
429 * length of the output buffer into which the encoded CBOR will be
430 * written. This is done with a @ref UsefulBuf structure, which is
431 * just a pointer and length (it is equivalent to two parameters, one
432 * a pointer and one a length, but a little prettier).
433 *
434 * The output buffer can be allocated any way (malloc, stack,
435 * static). It is just some memory that QCBOR writes to. The length
436 * must be the length of the allocated buffer. QCBOR will never write
437 * past that length, but might write up to that length. If the buffer
438 * is too small, encoding will go into an error state and not write
439 * anything further.
440 *
441 * If allocating on the stack the convenience macro
442 * UsefulBuf_MAKE_STACK_UB() can be used, but its use is not required.
443 *
444 * Since there is no reallocation or such, the output buffer must be
445 * correctly sized when passed in here. It is OK, but wasteful if it
446 * is too large. One way to pick the size is to figure out the maximum
447 * size that will ever be needed and hard code a buffer of that size.
448 *
449 * Another way to do it is to have QCBOR calculate it for you. To do
450 * this, pass @ref SizeCalculateUsefulBuf for @c Storage. Then call
451 * all the functions to add the CBOR exactly as if encoding for
452 * real. Finally, call QCBOREncode_FinishGetSize(). Once the length
453 * is obtained, allocate a buffer of that size, call
454 * QCBOREncode_Init() again with the real buffer. Call all the add
455 * functions again and finally, QCBOREncode_Finish() to obtain the
456 * final result. This uses twice the CPU time, but that is usually not
457 * an issue.
458 *
459 * See QCBOREncode_Finish() for how the pointer and length for the
460 * encoded CBOR is returned.
461 *
462 * For practical purposes QCBOR can't output encoded CBOR larger than
463 * @c UINT32_MAX (4GB) even on 64-bit CPUs because the internal
464 * offsets used to track the start of an array/map are 32 bits to
465 * reduce the size of the encoding context.
466 *
467 * A @ref QCBOREncodeContext can be reused over and over as long as
468 * QCBOREncode_Init() is called before each use.
469 */
470 void
471 QCBOREncode_Init(QCBOREncodeContext *pCtx, UsefulBuf Storage);
472
473
474 /**
475 * @brief Add a signed 64-bit integer to the encoded output.
476 *
477 * @param[in] pCtx The encoding context to add the integer to.
478 * @param[in] nNum The integer to add.
479 *
480 * The integer will be encoded and added to the CBOR output.
481 *
482 * This function figures out the size and the sign and encodes in the
483 * correct minimal CBOR. Specifically, it will select CBOR major type
484 * 0 or 1 based on sign and will encode to 1, 2, 4 or 8 bytes
485 * depending on the value of the integer. Values less than 24
486 * effectively encode to one byte because they are encoded in with the
487 * CBOR major type. This is a neat and efficient characteristic of
488 * CBOR that can be taken advantage of when designing CBOR-based
489 * protocols. If integers like tags can be kept between -23 and 23
490 * they will be encoded in one byte including the major type.
491 *
492 * If you pass a smaller int, say an @c int16_t or a small value, say
493 * 100, the encoding will still be CBOR's most compact that can
494 * represent the value. For example, CBOR always encodes the value 0
495 * as one byte, 0x00. The representation as 0x00 includes
496 * identification of the type as an integer too as the major type for
497 * an integer is 0. See [RFC 8949]
498 * (https://tools.ietf.org/html/rfc8949) Appendix A for more examples
499 * of CBOR encoding. This compact encoding is also preferred
500 * serialization CBOR as per section 34.1 in RFC 8949.
501 *
502 * There are no functions to add @c int16_t or @c int32_t because they
503 * are not necessary because this always encodes to the smallest
504 * number of bytes based on the value (If this code is running on a
505 * 32-bit machine having a way to add 32-bit integers would reduce
506 * code size some).
507 *
508 * If the encoding context is in an error state, this will do
509 * nothing. If an error occurs when adding this integer, the internal
510 * error flag will be set, and the error will be returned when
511 * QCBOREncode_Finish() is called.
512 *
513 * See also QCBOREncode_AddUInt64().
514 */
515 void
516 QCBOREncode_AddInt64(QCBOREncodeContext *pCtx, int64_t nNum);
517
518 static void
519 QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum);
520
521 static void
522 QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum);
523
524
525 /**
526 * @brief Add an unsigned 64-bit integer to the encoded output.
527 *
528 * @param[in] pCtx The encoding context to add the integer to.
529 * @param[in] uNum The integer to add.
530 *
531 * The integer will be encoded and added to the CBOR output.
532 *
533 * The only reason so use this function is for integers larger than
534 * @c INT64_MAX and smaller than @c UINT64_MAX. Otherwise
535 * QCBOREncode_AddInt64() will work fine.
536 *
537 * Error handling is the same as for QCBOREncode_AddInt64().
538 */
539 static void
540 QCBOREncode_AddUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
541
542 static void
543 QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum);
544
545 static void
546 QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum);
547
548
549 /**
550 * @brief Add a UTF-8 text string to the encoded output.
551 *
552 * @param[in] pCtx The encoding context to add the text to.
553 * @param[in] Text Pointer and length of text to add.
554 *
555 * The text passed in must be unencoded UTF-8 according to [RFC 3629]
556 * (https://tools.ietf.org/html/rfc3629). There is no NULL
557 * termination. The text is added as CBOR major type 3.
558 *
559 * If called with @c nBytesLen equal to 0, an empty string will be
560 * added. When @c nBytesLen is 0, @c pBytes may be @c NULL.
561 *
562 * Note that the restriction of the buffer length to a @c uint32_t is
563 * entirely intentional as this encoder is not capable of encoding
564 * lengths greater. This limit to 4GB for a text string should not be
565 * a problem.
566 *
567 * Text lines in Internet protocols (on the wire) are delimited by
568 * either a CRLF or just an LF. Officially many protocols specify
569 * CRLF, but implementations often work with either. CBOR type 3 text
570 * can be either line ending, even a mixture of both.
571 *
572 * Operating systems usually have a line end convention. Windows uses
573 * CRLF. Linux and MacOS use LF. Some applications on a given OS may
574 * work with either and some may not.
575 *
576 * The majority of use cases and CBOR protocols using type 3 text will
577 * work with either line ending. However, some use cases or protocols
578 * may not work with either in which case translation to and/or from
579 * the local line end convention, typically that of the OS, is
580 * necessary.
581 *
582 * QCBOR does no line ending translation for type 3 text when encoding
583 * and decoding.
584 *
585 * Error handling is the same as QCBOREncode_AddInt64().
586 */
587 static void
588 QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text);
589
590 static void
591 QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text);
592
593 static void
594 QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text);
595
596
597 /**
598 * @brief Add a UTF-8 text string to the encoded output.
599 *
600 * @param[in] pCtx The encoding context to add the text to.
601 * @param[in] szString Null-terminated text to add.
602 *
603 * This works the same as QCBOREncode_AddText().
604 */
605 static void
606 QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString);
607
608 static void
609 QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString);
610
611 static void
612 QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString);
613
614
615 #ifndef USEFULBUF_DISABLE_ALL_FLOAT
616 /**
617 * @brief Add a double-precision floating-point number to the encoded output.
618 *
619 * @param[in] pCtx The encoding context to add the double to.
620 * @param[in] dNum The double-precision number to add.
621 *
622 * This encodes and outputs a floating-point number. CBOR major type 7
623 * is used.
624 *
625 * This implements preferred serialization, selectively encoding the
626 * double-precision floating-point number as either double-precision,
627 * single-precision or half-precision. Infinity, NaN and 0 are always
628 * encoded as half-precision. If no precision will be lost in the
629 * conversion to half-precision, then it will be converted and
630 * encoded. If not and no precision will be lost in conversion to
631 * single-precision, then it will be converted and encoded. If not,
632 * then no conversion is performed, and it encoded as a
633 * double-precision.
634 *
635 * Half-precision floating-point numbers take up 2 bytes, half that of
636 * single-precision, one quarter of double-precision
637 *
638 * This automatically reduces the size of encoded CBOR, maybe even by
639 * four if most of values are 0, infinity or NaN.
640 *
641 * When decoded, QCBOR will usually return these values as
642 * double-precision.
643 *
644 * It is possible to disable this preferred serialization when compiling
645 * QCBOR. In that case, this functions the same as
646 * QCBOREncode_AddDoubleNoPreferred().
647 *
648 * Error handling is the same as QCBOREncode_AddInt64().
649 *
650 * See also QCBOREncode_AddDoubleNoPreferred(), QCBOREncode_AddFloat()
651 * and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
652 */
653 static void
654 QCBOREncode_AddDouble(QCBOREncodeContext *pCtx, double dNum);
655
656 static void
657 QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
658
659 static void
660 QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
661
662
663 /**
664 * @brief Add a single-precision floating-point number to the encoded output.
665 *
666 * @param[in] pCtx The encoding context to add the double to.
667 * @param[in] fNum The single-precision number to add.
668 *
669 * This is identical to QCBOREncode_AddDouble() except the input is
670 * single-precision.
671 *
672 * See also QCBOREncode_AddDouble(), QCBOREncode_AddDoubleNoPreferred(),
673 * and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
674 */
675 static void
676 QCBOREncode_AddFloat(QCBOREncodeContext *pCtx, float fNum);
677
678 static void
679 QCBOREncode_AddFloatToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
680
681 static void
682 QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float dNum);
683
684
685 /**
686 * @brief Add a double-precision floating-point number without preferred encoding.
687 *
688 * @param[in] pCtx The encoding context to add the double to.
689 * @param[in] dNum The double-precision number to add.
690 *
691 * This always outputs the number as a 64-bit double-precision.
692 * Preferred serialization is not used.
693 *
694 * Error handling is the same as QCBOREncode_AddInt64().
695 *
696 * See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
697 * QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
698 */
699 static void
700 QCBOREncode_AddDoubleNoPreferred(QCBOREncodeContext *pCtx, double dNum);
701
702 static void
703 QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
704
705 static void
706 QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
707
708
709 /**
710 * @brief Add a single-precision floating-point number without preferred encoding.
711 *
712 * @param[in] pCtx The encoding context to add the double to.
713 * @param[in] fNum The single-precision number to add.
714 *
715 * This always outputs the number as a 32-bit single-precision.
716 * Preferred serialization is not used.
717 *
718 * Error handling is the same as QCBOREncode_AddInt64().
719 *
720 * See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
721 * QCBOREncode_AddDoubleNoPreferred() and @ref Floating-Point.
722 */
723 static void
724 QCBOREncode_AddFloatNoPreferred(QCBOREncodeContext *pCtx, float fNum);
725
726 static void
727 QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
728
729 static void
730 QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float fNum);
731 #endif /* USEFULBUF_DISABLE_ALL_FLOAT */
732
733
734 /**
735 * @brief Add an optional tag.
736 *
737 * @param[in] pCtx The encoding context to add the tag to.
738 * @param[in] uTag The tag to add
739 *
740 * This outputs a CBOR major type 6 item that tags the next data item
741 * that is output usually to indicate it is some new data type.
742 *
743 * For many of the common standard tags, a function to encode data
744 * using it is provided and this is not needed. For example,
745 * QCBOREncode_AddDateEpoch() already exists to output integers
746 * representing dates with the right tag.
747 *
748 * The tag is applied to the next data item added to the encoded
749 * output. That data item that is to be tagged can be of any major
750 * CBOR type. Any number of tags can be added to a data item by
751 * calling this multiple times before the data item is added.
752 *
753 * See @ref Tags-Overview for discussion of creating new non-standard
754 * tags. See QCBORDecode_GetNext() for discussion of decoding custom
755 * tags.
756 */
757 static void
758 QCBOREncode_AddTag(QCBOREncodeContext *pCtx, uint64_t uTag);
759
760
761 /**
762 * @brief Add an epoch-based date.
763 *
764 * @param[in] pCtx The encoding context to add the date to.
765 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
766 * @ref QCBOR_ENCODE_AS_BORROWED.
767 * @param[in] nDate Number of seconds since 1970-01-01T00:00Z
768 * in UTC time.
769 *
770 * As per RFC 8949 this is similar to UNIX/Linux/POSIX dates. This is
771 * the most compact way to specify a date and time in CBOR. Note that
772 * this is always UTC and does not include the time zone. Use
773 * QCBOREncode_AddDateString() if you want to include the time zone.
774 *
775 * The preferred integer serialization rules apply here so the date will be
776 * encoded in a minimal number of bytes. Until about the year 2106
777 * these dates will encode in 6 bytes -- one byte for the tag, one
778 * byte for the type and 4 bytes for the integer. After that it will
779 * encode to 10 bytes.
780 *
781 * Negative values are supported for dates before 1970.
782 *
783 * If you care about leap-seconds and that level of accuracy, make sure
784 * the system you are running this code on does it correctly. This code
785 * just takes the value passed in.
786 *
787 * This implementation cannot encode fractional seconds using float or
788 * double even though that is allowed by CBOR, but you can encode them
789 * if you want to by calling QCBOREncode_AddTag() and QCBOREncode_AddDouble().
790 *
791 * Error handling is the same as QCBOREncode_AddInt64().
792 *
793 * See also QCBOREncode_AddTDaysEpoch().
794 */
795 static void
796 QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pCtx,
797 uint8_t uTagRequirement,
798 int64_t nDate);
799
800 static void
801 QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pCtx,
802 const char *szLabel,
803 uint8_t uTagRequirement,
804 int64_t nDate);
805
806 static void
807 QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pCtx,
808 int64_t nLabel,
809 uint8_t uTagRequirement,
810 int64_t nDate);
811
812
813 static void
814 QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx,
815 int64_t nDate);
816
817 static void
818 QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx,
819 const char *szLabel,
820 int64_t nDate);
821
822 static void
823 QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx,
824 int64_t nLabel,
825 int64_t nDate);
826
827
828
829 /**
830 * @brief Add an epoch-based day-count date.
831 *
832 * @param[in] pCtx The encoding context to add the date to.
833 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
834 * @ref QCBOR_ENCODE_AS_BORROWED.
835 * @param[in] nDays Number of days before or after 1970-01-0.
836 *
837 * This date format is described in
838 * [RFC 8943] (https://tools.ietf.org/html/rfc8943).
839 *
840 * The preferred integer serialization rules apply here so the date
841 * will be encoded in a minimal number of bytes. Until about the year
842 * 2149 these dates will encode in 4 bytes -- one byte for the tag,
843 * one byte for the type and 2 bytes for the integer.
844 *
845 * See also QCBOREncode_AddTDateEpoch().
846 */
847 static void
848 QCBOREncode_AddTDaysEpoch(QCBOREncodeContext *pCtx,
849 uint8_t uTagRequirement,
850 int64_t nDays);
851
852 static void
853 QCBOREncode_AddTDaysEpochToMapSZ(QCBOREncodeContext *pCtx,
854 const char *szLabel,
855 uint8_t uTagRequirement,
856 int64_t nDays);
857
858 static void
859 QCBOREncode_AddTDaysEpochToMapN(QCBOREncodeContext *pCtx,
860 int64_t nLabel,
861 uint8_t uTagRequirement,
862 int64_t nDays);
863
864
865
866
867 /**
868 * @brief Add a byte string to the encoded output.
869 *
870 * @param[in] pCtx The encoding context to add the bytes to.
871 * @param[in] Bytes Pointer and length of the input data.
872 *
873 * Simply adds the bytes to the encoded output as CBOR major type 2.
874 *
875 * If called with @c Bytes.len equal to 0, an empty string will be
876 * added. When @c Bytes.len is 0, @c Bytes.ptr may be @c NULL.
877 *
878 * Error handling is the same as QCBOREncode_AddInt64().
879 */
880 static void
881 QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
882
883 static void
884 QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
885
886 static void
887 QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
888
889
890 /**
891 * @brief Set up to write a byte string value directly to encoded output.
892 *
893 * @param[in] pCtx The encoding context to add the bytes to.
894 * @param[out] pPlace Pointer and length of place to write byte string value.
895 *
896 * QCBOREncode_AddBytes() is the normal way to encode a byte string.
897 * This is for special cases and by passes some of the pointer safety.
898 *
899 * The purpose of this is to output the bytes that make up a byte
900 * string value directly to the QCBOR output buffer so you don't need
901 * to have a copy of it in memory. This is particularly useful if the
902 * byte string is large, for example, the encrypted payload of a
903 * COSE_Encrypt message. The payload encryption algorithm can output
904 * directly to the encoded CBOR buffer, perhaps by making it the
905 * output buffer for some function (e.g. symmetric encryption) or by
906 * multiple writes.
907 *
908 * The pointer in @c pPlace is where to start writing. Writing is just
909 * copying bytes to the location by the pointer in \c pPlace. Writing
910 * past the length in @c pPlace will be writing off the end of the
911 * output buffer.
912 *
913 * If there is no room in the output buffer @ref NULLUsefulBuf will be
914 * returned and there is no need to call QCBOREncode_CloseBytes().
915 *
916 * The byte string must be closed by calling QCBOREncode_CloseBytes().
917 *
918 * Warning: this bypasses some of the usual checks provided by QCBOR
919 * against writing off the end of the encoded output buffer.
920 */
921 void
922 QCBOREncode_OpenBytes(QCBOREncodeContext *pCtx, UsefulBuf *pPlace);
923
924 static void
925 QCBOREncode_OpenBytesInMapSZ(QCBOREncodeContext *pCtx,
926 const char *szLabel,
927 UsefulBuf *pPlace);
928
929 static void
930 QCBOREncode_OpenBytesInMapN(QCBOREncodeContext *pCtx,
931 int64_t nLabel,
932 UsefulBuf *pPlace);
933
934
935 /**
936 * @brief Close out a byte string written directly to encoded output.
937 *
938 * @param[in] pCtx The encoding context to add the bytes to.
939 * @param[out] uAmount The number of bytes written, the length of the
940 * byte string.
941 *
942 * This closes out a call to QCBOREncode_OpenBytes(). This inserts a
943 * CBOR header at the front of the byte string value to make it a
944 * well-formed byte string.
945 *
946 * If there was no call to QCBOREncode_OpenBytes() then @ref
947 * QCBOR_ERR_TOO_MANY_CLOSES is set.
948 */
949 void
950 QCBOREncode_CloseBytes(QCBOREncodeContext *pCtx, size_t uAmount);
951
952
953 /**
954 * @brief Add a binary UUID to the encoded output.
955 *
956 * @param[in] pCtx The encoding context to add the UUID to.
957 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
958 * @ref QCBOR_ENCODE_AS_BORROWED.
959 * @param[in] Bytes Pointer and length of the binary UUID.
960 *
961 * A binary UUID as defined in [RFC 4122]
962 * (https://tools.ietf.org/html/rfc4122) is added to the output.
963 *
964 * It is output as CBOR major type 2, a binary string, with tag @ref
965 * CBOR_TAG_BIN_UUID indicating the binary string is a UUID.
966 */
967 static void
968 QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pCtx,
969 uint8_t uTagRequirement,
970 UsefulBufC Bytes);
971
972 static void
973 QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pCtx,
974 const char *szLabel,
975 uint8_t uTagRequirement,
976 UsefulBufC Bytes);
977
978 static void
979 QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pCtx,
980 int64_t nLabel,
981 uint8_t uTagRequirement,
982 UsefulBufC Bytes);
983
984
985 static void
986 QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
987
988 static void
989 QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
990
991 static void
992 QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
993
994
995 /**
996 * @brief Add a positive big number to the encoded output.
997 *
998 * @param[in] pCtx The encoding context to add the big number to.
999 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1000 * @ref QCBOR_ENCODE_AS_BORROWED.
1001 * @param[in] Bytes Pointer and length of the big number.
1002 *
1003 * Big numbers are integers larger than 64-bits. Their format is
1004 * described in [RFC 8949] (https://tools.ietf.org/html/rfc8949).
1005 *
1006 * It is output as CBOR major type 2, a binary string, with tag
1007 * @ref CBOR_TAG_POS_BIGNUM indicating the binary string is a positive
1008 * big number.
1009 *
1010 * Often big numbers are used to represent cryptographic keys,
1011 * however, COSE which defines representations for keys chose not to
1012 * use this particular type.
1013 */
1014 static void
1015 QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pCtx,
1016 uint8_t uTagRequirement,
1017 UsefulBufC Bytes);
1018
1019 static void
1020 QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pCtx,
1021 const char *szLabel,
1022 uint8_t uTagRequirement,
1023 UsefulBufC Bytes);
1024
1025 static void
1026 QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pCtx,
1027 int64_t nLabel,
1028 uint8_t uTagRequirement,
1029 UsefulBufC Bytes);
1030
1031
1032 static void
1033 QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx,
1034 UsefulBufC Bytes);
1035
1036 static void
1037 QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx,
1038 const char *szLabel,
1039 UsefulBufC Bytes);
1040
1041 static void
1042 QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx,
1043 int64_t nLabel,
1044 UsefulBufC Bytes);
1045
1046
1047 /**
1048 * @brief Add a negative big number to the encoded output.
1049 *
1050 * @param[in] pCtx The encoding context to add the big number to.
1051 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1052 * @ref QCBOR_ENCODE_AS_BORROWED.
1053 * @param[in] Bytes Pointer and length of the big number.
1054 *
1055 * Big numbers are integers larger than 64-bits. Their format is
1056 * described in [RFC 8949] (https://tools.ietf.org/html/rfc8949).
1057 *
1058 * It is output as CBOR major type 2, a binary string, with tag
1059 * @ref CBOR_TAG_NEG_BIGNUM indicating the binary string is a negative
1060 * big number.
1061 *
1062 * Often big numbers are used to represent cryptographic keys,
1063 * however, COSE which defines representations for keys chose not to
1064 * use this particular type.
1065 */
1066 static void
1067 QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pCtx,
1068 uint8_t uTagRequirement,
1069 UsefulBufC Bytes);
1070
1071 static void
1072 QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pCtx,
1073 const char *szLabel,
1074 uint8_t uTagRequirement,
1075 UsefulBufC Bytes);
1076
1077 static void
1078 QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pCtx,
1079 int64_t nLabel,
1080 uint8_t uTagRequirement,
1081 UsefulBufC Bytes);
1082
1083
1084 static void
1085 QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx,
1086 UsefulBufC Bytes);
1087
1088 static void
1089 QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx,
1090 const char *szLabel,
1091 UsefulBufC Bytes);
1092
1093 static void
1094 QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx,
1095 int64_t nLabel,
1096 UsefulBufC Bytes);
1097
1098
1099 #ifndef QCBOR_DISABLE_EXP_AND_MANTISSA
1100 /**
1101 * @brief Add a decimal fraction to the encoded output.
1102 *
1103 * @param[in] pCtx Encoding context to add the decimal fraction to.
1104 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1105 * @ref QCBOR_ENCODE_AS_BORROWED.
1106 * @param[in] nMantissa The mantissa.
1107 * @param[in] nBase10Exponent The exponent.
1108 *
1109 * The value is nMantissa * 10 ^ nBase10Exponent.
1110 *
1111 * A decimal fraction is good for exact representation of some values
1112 * that can't be represented exactly with standard C (IEEE 754)
1113 * floating-point numbers. Much larger and much smaller numbers can
1114 * also be represented than floating-point because of the larger
1115 * number of bits in the exponent.
1116 *
1117 * The decimal fraction is conveyed as two integers, a mantissa and a
1118 * base-10 scaling factor.
1119 *
1120 * For example, 273.15 is represented by the two integers 27315 and -2.
1121 *
1122 * The exponent and mantissa have the range from @c INT64_MIN to
1123 * @c INT64_MAX for both encoding and decoding (CBOR allows
1124 * @c -UINT64_MAX to @c UINT64_MAX, but this implementation doesn't
1125 * support this range to reduce code size and interface complexity a
1126 * little).
1127 *
1128 * CBOR Preferred serialization of the integers is used, thus they
1129 * will be encoded in the smallest number of bytes possible.
1130 *
1131 * See also QCBOREncode_AddDecimalFractionBigNum() for a decimal
1132 * fraction with arbitrarily large precision and
1133 * QCBOREncode_AddBigFloat().
1134 *
1135 * There is no representation of positive or negative infinity or NaN
1136 * (Not a Number). Use QCBOREncode_AddDouble() to encode them.
1137 *
1138 * See @ref expAndMantissa for decoded representation.
1139 */
1140 static void
1141 QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pCtx,
1142 uint8_t uTagRequirement,
1143 int64_t nMantissa,
1144 int64_t nBase10Exponent);
1145
1146 static void
1147 QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pCtx,
1148 const char *szLabel,
1149 uint8_t uTagRequirement,
1150 int64_t nMantissa,
1151 int64_t nBase10Exponent);
1152
1153 static void
1154 QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pCtx,
1155 int64_t nLabel,
1156 uint8_t uTagRequirement,
1157 int64_t nMantissa,
1158 int64_t nBase10Exponent);
1159
1160
1161 static void
1162 QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pCtx,
1163 int64_t nMantissa,
1164 int64_t nBase10Exponent);
1165
1166 static void
1167 QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pCtx,
1168 const char *szLabel,
1169 int64_t nMantissa,
1170 int64_t nBase10Exponent);
1171
1172 static void
1173 QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pCtx,
1174 int64_t nLabel,
1175 int64_t nMantissa,
1176 int64_t nBase10Exponent);
1177
1178
1179 /**
1180 * @brief Add a decimal fraction with a big number mantissa to the encoded output.
1181 *
1182 * @param[in] pCtx Encoding context to add the decimal fraction to.
1183 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1184 * @ref QCBOR_ENCODE_AS_BORROWED.
1185 * @param[in] Mantissa The mantissa.
1186 * @param[in] bIsNegative false if mantissa is positive, true if negative.
1187 * @param[in] nBase10Exponent The exponent.
1188 *
1189 * This is the same as QCBOREncode_AddDecimalFraction() except the
1190 * mantissa is a big number (See QCBOREncode_AddPositiveBignum())
1191 * allowing for arbitrarily large precision.
1192 *
1193 * See @ref expAndMantissa for decoded representation.
1194 */
1195 static void
1196 QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pCtx,
1197 uint8_t uTagRequirement,
1198 UsefulBufC Mantissa,
1199 bool bIsNegative,
1200 int64_t nBase10Exponent);
1201
1202 static void
1203 QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
1204 const char *szLabel,
1205 uint8_t uTagRequirement,
1206 UsefulBufC Mantissa,
1207 bool bIsNegative,
1208 int64_t nBase10Exponent);
1209
1210 static void
1211 QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
1212 int64_t nLabel,
1213 uint8_t uTagRequirement,
1214 UsefulBufC Mantissa,
1215 bool bIsNegative,
1216 int64_t nBase10Exponent);
1217
1218
1219 static void
1220 QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pCtx,
1221 UsefulBufC Mantissa,
1222 bool bIsNegative,
1223 int64_t nBase10Exponent);
1224
1225 static void
1226 QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
1227 const char *szLabel,
1228 UsefulBufC Mantissa,
1229 bool bIsNegative,
1230 int64_t nBase10Exponent);
1231
1232 static void
1233 QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
1234 int64_t nLabel,
1235 UsefulBufC Mantissa,
1236 bool bIsNegative,
1237 int64_t nBase10Exponent);
1238
1239 /**
1240 * @brief Add a big floating-point number to the encoded output.
1241 *
1242 * @param[in] pCtx The encoding context to add the bigfloat to.
1243 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1244 * @ref QCBOR_ENCODE_AS_BORROWED.
1245 * @param[in] nMantissa The mantissa.
1246 * @param[in] nBase2Exponent The exponent.
1247 *
1248 * The value is nMantissa * 2 ^ nBase2Exponent.
1249 *
1250 * "Bigfloats", as CBOR terms them, are similar to IEEE floating-point
1251 * numbers in having a mantissa and base-2 exponent, but they are not
1252 * supported by hardware or encoded the same. They explicitly use two
1253 * CBOR-encoded integers to convey the mantissa and exponent, each of
1254 * which can be 8, 16, 32 or 64 bits. With both the mantissa and
1255 * exponent 64 bits they can express more precision and a larger range
1256 * than an IEEE double floating-point number. See
1257 * QCBOREncode_AddBigFloatBigNum() for even more precision.
1258 *
1259 * For example, 1.5 would be represented by a mantissa of 3 and an
1260 * exponent of -1.
1261 *
1262 * The exponent and mantissa have the range from @c INT64_MIN to
1263 * @c INT64_MAX for both encoding and decoding (CBOR allows @c
1264 * -UINT64_MAX to @c UINT64_MAX, but this implementation doesn't
1265 * support this range to reduce code size and interface complexity a
1266 * little).
1267 *
1268 * CBOR preferred serialization of the integers is used, thus they will
1269 * be encoded in the smallest number of bytes possible.
1270 *
1271 * This can also be used to represent floating-point numbers in
1272 * environments that don't support IEEE 754.
1273 *
1274 * See @ref expAndMantissa for decoded representation.
1275 */
1276 static void
1277 QCBOREncode_AddTBigFloat(QCBOREncodeContext *pCtx,
1278 uint8_t uTagRequirement,
1279 int64_t nMantissa,
1280 int64_t nBase2Exponent);
1281
1282 static void
1283 QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pCtx,
1284 const char *szLabel,
1285 uint8_t uTagRequirement,
1286 int64_t nMantissa,
1287 int64_t nBase2Exponent);
1288
1289 static void
1290 QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pCtx,
1291 int64_t nLabel,
1292 uint8_t uTagRequirement,
1293 int64_t nMantissa,
1294 int64_t nBase2Exponent);
1295
1296
1297 static void
1298 QCBOREncode_AddBigFloat(QCBOREncodeContext *pCtx,
1299 int64_t nMantissa,
1300 int64_t nBase2Exponent);
1301
1302 static void
1303 QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pCtx,
1304 const char *szLabel,
1305 int64_t nMantissa,
1306 int64_t nBase2Exponent);
1307
1308 static void
1309 QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pCtx,
1310 int64_t nLabel,
1311 int64_t nMantissa,
1312 int64_t nBase2Exponent);
1313
1314 /**
1315 * @brief Add a big floating-point number with a big number mantissa to
1316 * the encoded output.
1317 *
1318 * @param[in] pCtx The encoding context to add the bigfloat to.
1319 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1320 * @ref QCBOR_ENCODE_AS_BORROWED.
1321 * @param[in] Mantissa The mantissa.
1322 * @param[in] bIsNegative false if mantissa is positive, true if negative.
1323 * @param[in] nBase2Exponent The exponent.
1324 *
1325 * This is the same as QCBOREncode_AddBigFloat() except the mantissa
1326 * is a big number (See QCBOREncode_AddPositiveBignum()) allowing for
1327 * arbitrary precision.
1328 *
1329 * See @ref expAndMantissa for decoded representation.
1330 */
1331 static void
1332 QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pCtx,
1333 uint8_t uTagRequirement,
1334 UsefulBufC Mantissa,
1335 bool bIsNegative,
1336 int64_t nBase2Exponent);
1337
1338 static void
1339 QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pCtx,
1340 const char *szLabel,
1341 uint8_t uTagRequirement,
1342 UsefulBufC Mantissa,
1343 bool bIsNegative,
1344 int64_t nBase2Exponent);
1345
1346 static void
1347 QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1348 int64_t nLabel,
1349 uint8_t uTagRequirement,
1350 UsefulBufC Mantissa,
1351 bool bIsNegative,
1352 int64_t nBase2Exponent);
1353
1354
1355 static void
1356 QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pCtx,
1357 UsefulBufC Mantissa,
1358 bool bIsNegative,
1359 int64_t nBase2Exponent);
1360
1361 static void
1362 QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pCtx,
1363 const char *szLabel,
1364 UsefulBufC Mantissa,
1365 bool bIsNegative,
1366 int64_t nBase2Exponent);
1367
1368 static void
1369 QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1370 int64_t nLabel,
1371 UsefulBufC Mantissa,
1372 bool bIsNegative,
1373 int64_t nBase2Exponent);
1374 #endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
1375
1376
1377 /**
1378 * @brief Add a text URI to the encoded output.
1379 *
1380 * @param[in] pCtx The encoding context to add the URI to.
1381 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1382 * @ref QCBOR_ENCODE_AS_BORROWED.
1383 * @param[in] URI Pointer and length of the URI.
1384 *
1385 * The format of URI must be per [RFC 3986]
1386 * (https://tools.ietf.org/html/rfc3986).
1387 *
1388 * It is output as CBOR major type 3, a text string, with tag @ref
1389 * CBOR_TAG_URI indicating the text string is a URI.
1390 *
1391 * A URI in a NULL-terminated string, @c szURI, can be easily added with
1392 * this code:
1393 *
1394 * QCBOREncode_AddURI(pCtx, UsefulBuf_FromSZ(szURI));
1395 */
1396 static void
1397 QCBOREncode_AddTURI(QCBOREncodeContext *pCtx,
1398 uint8_t uTagRequirement,
1399 UsefulBufC URI);
1400
1401 static void
1402 QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pCtx,
1403 const char *szLabel,
1404 uint8_t uTagRequirement,
1405 UsefulBufC URI);
1406
1407 static void
1408 QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pCtx,
1409 int64_t nLabel,
1410 uint8_t uTagRequirement,
1411 UsefulBufC URI);
1412
1413
1414 static void
1415 QCBOREncode_AddURI(QCBOREncodeContext *pCtx,
1416 UsefulBufC URI);
1417
1418 static void
1419 QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx,
1420 const char *szLabel,
1421 UsefulBufC URI);
1422
1423 static void
1424 QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx,
1425 int64_t nLabel,
1426 UsefulBufC URI);
1427
1428
1429 /**
1430 * @brief Add Base64-encoded text to encoded output.
1431 *
1432 * @param[in] pCtx The encoding context to add the base-64 text to.
1433 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1434 * @ref QCBOR_ENCODE_AS_BORROWED.
1435 * @param[in] B64Text Pointer and length of the base-64 encoded text.
1436 *
1437 * The text content is Base64 encoded data per [RFC 4648]
1438 * (https://tools.ietf.org/html/rfc4648).
1439 *
1440 * It is output as CBOR major type 3, a text string, with tag @ref
1441 * CBOR_TAG_B64 indicating the text string is Base64 encoded.
1442 */
1443 static void
1444 QCBOREncode_AddTB64Text(QCBOREncodeContext *pCtx,
1445 uint8_t uTagRequirement,
1446 UsefulBufC B64Text);
1447
1448 static void
1449 QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pCtx,
1450 const char *szLabel,
1451 uint8_t uTagRequirement,
1452 UsefulBufC B64Text);
1453
1454 static void
1455 QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pCtx,
1456 int64_t nLabel,
1457 uint8_t uTagRequirement,
1458 UsefulBufC B64Text);
1459
1460
1461 static void
1462 QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx,
1463 UsefulBufC B64Text);
1464
1465 static void
1466 QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx,
1467 const char *szLabel,
1468 UsefulBufC B64Text);
1469
1470 static void
1471 QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx,
1472 int64_t nLabel,
1473 UsefulBufC B64Text);
1474
1475
1476
1477 /**
1478 * @brief Add base64url encoded data to encoded output.
1479 *
1480 * @param[in] pCtx The encoding context to add the base64url to.
1481 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1482 * @ref QCBOR_ENCODE_AS_BORROWED.
1483 * @param[in] B64Text Pointer and length of the base64url encoded text.
1484 *
1485 * The text content is base64URL encoded text as per [RFC 4648]
1486 * (https://tools.ietf.org/html/rfc4648).
1487 *
1488 * It is output as CBOR major type 3, a text string, with tag
1489 * @ref CBOR_TAG_B64URL indicating the text string is a Base64url
1490 * encoded.
1491 */
1492 static void
1493 QCBOREncode_AddTB64URLText(QCBOREncodeContext *pCtx,
1494 uint8_t uTagRequirement,
1495 UsefulBufC B64Text);
1496
1497 static void
1498 QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pCtx,
1499 const char *szLabel,
1500 uint8_t uTagRequirement,
1501 UsefulBufC B64Text);
1502
1503 static void
1504 QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pCtx,
1505 int64_t nLabel,
1506 uint8_t uTagRequirement,
1507 UsefulBufC B64Text);
1508
1509
1510 static void
1511 QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx,
1512 UsefulBufC B64Text);
1513
1514 static void
1515 QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx,
1516 const char *szLabel,
1517 UsefulBufC B64Text);
1518
1519 static void
1520 QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx,
1521 int64_t nLabel,
1522 UsefulBufC B64Text);
1523
1524
1525 /**
1526 * @brief Add Perl Compatible Regular Expression.
1527 *
1528 * @param[in] pCtx Encoding context to add the regular expression to.
1529 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1530 * @ref QCBOR_ENCODE_AS_BORROWED.
1531 * @param[in] Regex Pointer and length of the regular expression.
1532 *
1533 * The text content is Perl Compatible Regular
1534 * Expressions (PCRE) / JavaScript syntax [ECMA262].
1535 *
1536 * It is output as CBOR major type 3, a text string, with tag @ref
1537 * CBOR_TAG_REGEX indicating the text string is a regular expression.
1538 */
1539 static void
1540 QCBOREncode_AddTRegex(QCBOREncodeContext *pCtx,
1541 uint8_t uTagRequirement,
1542 UsefulBufC Regex);
1543
1544 static void
1545 QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pCtx,
1546 const char *szLabel,
1547 uint8_t uTagRequirement,
1548 UsefulBufC Regex);
1549
1550 static void
1551 QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pCtx,
1552 int64_t nLabel,
1553 uint8_t uTagRequirement,
1554 UsefulBufC Regex);
1555
1556
1557 static void
1558 QCBOREncode_AddRegex(QCBOREncodeContext *pCtx,
1559 UsefulBufC Regex);
1560
1561 static void
1562 QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx,
1563 const char *szLabel,
1564 UsefulBufC Regex);
1565
1566 static void
1567 QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx,
1568 int64_t nLabel,
1569 UsefulBufC Regex);
1570
1571
1572 /**
1573 * @brief MIME encoded data to the encoded output.
1574 *
1575 * @param[in] pCtx The encoding context to add the MIME data to.
1576 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1577 * @ref QCBOR_ENCODE_AS_BORROWED.
1578 * @param[in] MIMEData Pointer and length of the MIME data.
1579 *
1580 * The text content is in MIME format per [RFC 2045]
1581 * (https://tools.ietf.org/html/rfc2045) including the headers.
1582 *
1583 * It is output as CBOR major type 2, a binary string, with tag
1584 * @ref CBOR_TAG_BINARY_MIME indicating the string is MIME data. This
1585 * outputs tag 257, not tag 36, as it can carry any type of MIME
1586 * binary, 7-bit, 8-bit, quoted-printable and base64 where tag 36
1587 * cannot.
1588 *
1589 * Previous versions of QCBOR, those before spiffy decode, output tag
1590 * 36. Decoding supports both tag 36 and 257. (if the old behavior
1591 * with tag 36 is needed, copy the inline functions below and change
1592 * the tag number).
1593 *
1594 * See also QCBORDecode_GetMIMEMessage() and
1595 * @ref QCBOR_TYPE_BINARY_MIME.
1596 *
1597 * This does no translation of line endings. See QCBOREncode_AddText()
1598 * for a discussion of line endings in CBOR.
1599 */
1600 static void
1601 QCBOREncode_AddTMIMEData(QCBOREncodeContext *pCtx,
1602 uint8_t uTagRequirement,
1603 UsefulBufC MIMEData);
1604
1605 static void
1606 QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pCtx,
1607 const char *szLabel,
1608 uint8_t uTagRequirement,
1609 UsefulBufC MIMEData);
1610
1611 static void
1612 QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pCtx,
1613 int64_t nLabel,
1614 uint8_t uTagRequirement,
1615 UsefulBufC MIMEData);
1616
1617
1618 static void
1619 QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx,
1620 UsefulBufC MIMEData);
1621
1622 static void
1623 QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx,
1624 const char *szLabel,
1625 UsefulBufC MIMEData);
1626
1627 static void
1628 QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx,
1629 int64_t nLabel,
1630 UsefulBufC MIMEData);
1631
1632
1633 /**
1634 * @brief Add an RFC 3339 date string
1635 *
1636 * @param[in] pCtx The encoding context to add the date to.
1637 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1638 * @ref QCBOR_ENCODE_AS_BORROWED.
1639 * @param[in] szDate Null-terminated string with date to add.
1640 *
1641 * The string szDate should be in the form of [RFC 3339]
1642 * (https://tools.ietf.org/html/rfc3339) as defined by section 3.3 in
1643 * [RFC 4287] (https://tools.ietf.org/html/rfc4287). This is as
1644 * described in section 3.4.1 in [RFC 8949]
1645 * (https://tools.ietf.org/html/rfc8949).
1646 *
1647 * Note that this function doesn't validate the format of the date
1648 * string at all. If you add an incorrect format date string, the
1649 * generated CBOR will be incorrect and the receiver may not be able
1650 * to handle it.
1651 *
1652 * Error handling is the same as QCBOREncode_AddInt64().
1653 *
1654 * See also QCBOREncode_AddTDayString().
1655 */
1656 static void
1657 QCBOREncode_AddTDateString(QCBOREncodeContext *pCtx,
1658 uint8_t uTagRequirement,
1659 const char *szDate);
1660
1661 static void
1662 QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pCtx,
1663 const char *szLabel,
1664 uint8_t uTagRequirement,
1665 const char *szDate);
1666
1667 static void
1668 QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pCtx,
1669 int64_t nLabel,
1670 uint8_t uTagRequirement,
1671 const char *szDate);
1672
1673
1674 static void
1675 QCBOREncode_AddDateString(QCBOREncodeContext *pCtx,
1676 const char *szDate);
1677
1678 static void
1679 QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx,
1680 const char *szLabel,
1681 const char *szDate);
1682
1683 static void
1684 QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx,
1685 int64_t nLabel,
1686 const char *szDate);
1687
1688
1689 /**
1690 * @brief Add a date-only string.
1691 *
1692 * @param[in] pCtx The encoding context to add the date to.
1693 * @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1694 * @ref QCBOR_ENCODE_AS_BORROWED.
1695 * @param[in] szDate Null-terminated string with date to add.
1696 *
1697 * This date format is described in
1698 * [RFC 8943] (https://tools.ietf.org/html/rfc8943), but that mainly
1699 * references RFC 3339. The string szDate must be in the forrm
1700 * specified the ABNF for a full-date in
1701 * [RFC 3339] (https://tools.ietf.org/html/rfc3339). Examples of this
1702 * are "1985-04-12" and "1937-01-01". The time and the time zone are
1703 * never included.
1704 *
1705 * Note that this function doesn't validate the format of the date
1706 * string at all. If you add an incorrect format date string, the
1707 * generated CBOR will be incorrect and the receiver may not be able
1708 * to handle it.
1709 *
1710 * Error handling is the same as QCBOREncode_AddInt64().
1711 *
1712 * See also QCBOREncode_AddTDateString().
1713 */
1714 static void
1715 QCBOREncode_AddTDaysString(QCBOREncodeContext *pCtx,
1716 uint8_t uTagRequirement,
1717 const char *szDate);
1718
1719 static void
1720 QCBOREncode_AddTDaysStringToMapSZ(QCBOREncodeContext *pCtx,
1721 const char *szLabel,
1722 uint8_t uTagRequirement,
1723 const char *szDate);
1724
1725 static void
1726 QCBOREncode_AddTDaysStringToMapN(QCBOREncodeContext *pCtx,
1727 int64_t nLabel,
1728 uint8_t uTagRequirement,
1729 const char *szDate);
1730
1731
1732 /**
1733 * @brief Add a standard Boolean.
1734 *
1735 * @param[in] pCtx The encoding context to add the Boolean to.
1736 * @param[in] b true or false from @c <stdbool.h>.
1737 *
1738 * Adds a Boolean value as CBOR major type 7.
1739 *
1740 * Error handling is the same as QCBOREncode_AddInt64().
1741 */
1742 static void
1743 QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b);
1744
1745 static void
1746 QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b);
1747
1748 static void
1749 QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b);
1750
1751
1752 /**
1753 * @brief Add a NULL to the encoded output.
1754 *
1755 * @param[in] pCtx The encoding context to add the NULL to.
1756 *
1757 * Adds the NULL value as CBOR major type 7.
1758 *
1759 * This NULL doesn't have any special meaning in CBOR such as a
1760 * terminating value for a string or an empty value.
1761 *
1762 * Error handling is the same as QCBOREncode_AddInt64().
1763 */
1764 static void
1765 QCBOREncode_AddNULL(QCBOREncodeContext *pCtx);
1766
1767 static void
1768 QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1769
1770 static void
1771 QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1772
1773
1774 /**
1775 * @brief Add an "undef" to the encoded output.
1776 *
1777 * @param[in] pCtx The encoding context to add the "undef" to.
1778 *
1779 * Adds the undef value as CBOR major type 7.
1780 *
1781 * Note that this value will not translate to JSON.
1782 *
1783 * This Undef doesn't have any special meaning in CBOR such as a
1784 * terminating value for a string or an empty value.
1785 *
1786 * Error handling is the same as QCBOREncode_AddInt64().
1787 */
1788 static void
1789 QCBOREncode_AddUndef(QCBOREncodeContext *pCtx);
1790
1791 static void
1792 QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1793
1794 static void
1795 QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1796
1797
1798 /**
1799 * @brief Add a simple value.
1800 *
1801 * @param[in] pMe The encode context.
1802 * @param[in] uNum The simple value.
1803 *
1804 * QCBOREncode_AddBool(), QCBOREncode_AddUndef() and
1805 * QCBOREncode_AddNull() are preferred to this for the simple values
1806 * defined in RFC 8949, but this can be used for them too.
1807 *
1808 * The main purpose of this is to add simple values beyond those in
1809 * defined RFC 8949. Note that simple values must be registered with
1810 * IANA. Those in the range of 0 to 19 must be standardized. Those in
1811 * the range of 32 to 255 do not require a standard, but must be
1812 * publically specified. There is no range of values for proprietary
1813 * use. See
1814 * https://www.iana.org/assignments/cbor-simple-values/cbor-simple-values.xhtml
1815 */
1816 static void
1817 QCBOREncode_AddSimple(QCBOREncodeContext *pMe, const uint8_t uNum);
1818
1819 static void
1820 QCBOREncode_AddSimpleToMap(QCBOREncodeContext *pMe,
1821 const char *szLabel,
1822 const uint8_t uSimple);
1823
1824 static void
1825 QCBOREncode_AddSimpleToMapN(QCBOREncodeContext *pMe,
1826 const int64_t nLabel,
1827 const uint8_t uSimple);
1828
1829
1830 /**
1831 * @brief Indicates that the next items added are in an array.
1832 *
1833 * @param[in] pCtx The encoding context to open the array in.
1834 *
1835 * Arrays are the basic CBOR aggregate or structure type. Call this
1836 * function to start or open an array. Then call the various
1837 * @c QCBOREncode_AddXxx() functions to add the items that go into the
1838 * array. Then call QCBOREncode_CloseArray() when all items have been
1839 * added. The data items in the array can be of any type and can be of
1840 * mixed types.
1841 *
1842 * Nesting of arrays and maps is allowed and supported just by calling
1843 * QCBOREncode_OpenArray() again before calling
1844 * QCBOREncode_CloseArray(). While CBOR has no limit on nesting, this
1845 * implementation does in order to keep it smaller and simpler. The
1846 * limit is @ref QCBOR_MAX_ARRAY_NESTING. This is the max number of
1847 * times this can be called without calling
1848 * QCBOREncode_CloseArray(). QCBOREncode_Finish() will return
1849 * @ref QCBOR_ERR_ARRAY_NESTING_TOO_DEEP when it is called as this
1850 * function just sets an error state and returns no value when this
1851 * occurs.
1852 *
1853 * If you try to add more than @ref QCBOR_MAX_ITEMS_IN_ARRAY items to
1854 * a single array or map, @ref QCBOR_ERR_ARRAY_TOO_LONG will be
1855 * returned when QCBOREncode_Finish() is called.
1856 *
1857 * An array itself must have a label if it is being added to a map.
1858 * Note that array elements do not have labels (but map elements do).
1859 *
1860 * An array itself may be tagged by calling QCBOREncode_AddTag()
1861 * before this call.
1862 */
1863 static void
1864 QCBOREncode_OpenArray(QCBOREncodeContext *pCtx);
1865
1866 static void
1867 QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1868
1869 static void
1870 QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1871
1872
1873 /**
1874 * @brief Close an open array.
1875 *
1876 * @param[in] pCtx The encoding context to close the array in.
1877 *
1878 * The closes an array opened by QCBOREncode_OpenArray(). It reduces
1879 * nesting level by one. All arrays (and maps) must be closed before
1880 * calling QCBOREncode_Finish().
1881 *
1882 * When an error occurs as a result of this call, the encoder records
1883 * the error and enters the error state. The error will be returned
1884 * when QCBOREncode_Finish() is called.
1885 *
1886 * If this has been called more times than QCBOREncode_OpenArray(), then
1887 * @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when QCBOREncode_Finish()
1888 * is called.
1889 *
1890 * If this is called and it is not an array that is currently open,
1891 * @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
1892 * QCBOREncode_Finish() is called.
1893 */
1894 static void
1895 QCBOREncode_CloseArray(QCBOREncodeContext *pCtx);
1896
1897
1898
1899
1900 /**
1901 * @brief Indicates that the next items added are in a map.
1902 *
1903 * @param[in] pCtx The encoding context to open the map in.
1904 *
1905 * See QCBOREncode_OpenArray() for more information, particularly
1906 * error handling.
1907 *
1908 * CBOR maps are an aggregate type where each item in the map consists
1909 * of a label and a value. They are similar to JSON objects.
1910 *
1911 * The value can be any CBOR type including another map.
1912 *
1913 * The label can also be any CBOR type, but in practice they are
1914 * typically, integers as this gives the most compact output. They
1915 * might also be text strings which gives readability and translation
1916 * to JSON.
1917 *
1918 * Every @c QCBOREncode_AddXxx() call has one version that ends with
1919 * @c InMap for adding items to maps with string labels and one that
1920 * ends with @c InMapN that is for adding with integer labels.
1921 *
1922 * RFC 8949 uses the term "key" instead of "label".
1923 *
1924 * If you wish to use map labels that are neither integer labels nor
1925 * text strings, then just call the QCBOREncode_AddXxx() function
1926 * explicitly to add the label. Then call it again to add the value.
1927 *
1928 * See the [RFC 8949] (https://tools.ietf.org/html/rfc8949) for a lot
1929 * more information on creating maps.
1930 */
1931 static void
1932 QCBOREncode_OpenMap(QCBOREncodeContext *pCtx);
1933
1934 static void
1935 QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1936
1937 static void
1938 QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1939
1940
1941 /**
1942 * @brief Close an open map.
1943 *
1944 * @param[in] pCtx The encoding context to close the map in.
1945 *
1946 * This closes a map opened by QCBOREncode_OpenMap(). It reduces
1947 * nesting level by one.
1948 *
1949 * When an error occurs as a result of this call, the encoder records
1950 * the error and enters the error state. The error will be returned
1951 * when QCBOREncode_Finish() is called.
1952 *
1953 * If this has been called more times than QCBOREncode_OpenMap(), then
1954 * @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1955 * QCBOREncode_Finish() is called.
1956 *
1957 * If this is called and it is not a map that is currently open,
1958 * @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
1959 * QCBOREncode_Finish() is called.
1960 */
1961 static void
1962 QCBOREncode_CloseMap(QCBOREncodeContext *pCtx);
1963
1964
1965 /**
1966 * @brief Indicates that the next items added are in an indefinite length array.
1967 *
1968 * @param[in] pCtx The encoding context to open the array in.
1969 *
1970 * This is the same as QCBOREncode_OpenArray() except the array is
1971 * indefinite length.
1972 *
1973 * This must be closed with QCBOREncode_CloseArrayIndefiniteLength().
1974 */
1975 static void
1976 QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pCtx);
1977
1978 static void
1979 QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pCtx,
1980 const char *szLabel);
1981
1982 static void
1983 QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pCtx,
1984 int64_t nLabel);
1985
1986
1987 /**
1988 * @brief Close an open indefinite length array.
1989 *
1990 * @param[in] pCtx The encoding context to close the array in.
1991 *
1992 * This is the same as QCBOREncode_CloseArray(), but the open array
1993 * that is being close must be of indefinite length.
1994 */
1995 static void
1996 QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pCtx);
1997
1998
1999 /**
2000 * @brief Indicates that the next items added are in an indefinite length map.
2001 *
2002 * @param[in] pCtx The encoding context to open the map in.
2003 *
2004 * This is the same as QCBOREncode_OpenMap() except the array is
2005 * indefinite length.
2006 *
2007 * This must be closed with QCBOREncode_CloseMapIndefiniteLength().
2008 */
2009 static void
2010 QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pCtx);
2011
2012 static void
2013 QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pCtx,
2014 const char *szLabel);
2015
2016 static void
2017 QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pCtx,
2018 int64_t nLabel);
2019
2020
2021 /**
2022 * @brief Close an open indefinite length map.
2023 *
2024 * @param[in] pCtx The encoding context to close the map in.
2025 *
2026 * This is the same as QCBOREncode_CloseMap(), but the open map that
2027 * is being close must be of indefinite length.
2028 */
2029 static void
2030 QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pCtx);
2031
2032
2033
2034
2035 /**
2036 * @brief Indicate start of encoded CBOR to be wrapped in a bstr.
2037 *
2038 * @param[in] pCtx The encoding context to open the bstr-wrapped CBOR in.
2039 *
2040 * All added encoded items between this call and a call to
2041 * QCBOREncode_CloseBstrWrap2() will be wrapped in a bstr. They will
2042 * appear in the final output as a byte string. That byte string will
2043 * contain encoded CBOR. This increases nesting level by one.
2044 *
2045 * The typical use case is for encoded CBOR that is to be
2046 * cryptographically hashed, as part of a [RFC 8152, COSE]
2047 * (https://tools.ietf.org/html/rfc8152) implementation. The wrapping
2048 * byte string is taken as input by the hash function (which is why it
2049 * is returned by QCBOREncode_CloseBstrWrap2()). It is also easy to
2050 * recover on decoding with standard CBOR decoders.
2051 *
2052 * Using QCBOREncode_BstrWrap() and QCBOREncode_CloseBstrWrap2()
2053 * avoids having to encode the items first in one buffer (e.g., the
2054 * COSE payload) and then add that buffer as a bstr to another
2055 * encoding (e.g. the COSE to-be-signed bytes, the @c Sig_structure)
2056 * potentially halving the memory needed.
2057 *
2058 * CBOR by nature must be decoded item by item in order from the
2059 * start. By wrapping some CBOR in a byte string, the decoding of
2060 * that wrapped CBOR can be skipped. This is another use of wrapping,
2061 * perhaps because the CBOR is large and deeply nested. Perhaps APIs
2062 * for handling one defined CBOR message that is being embedded in
2063 * another only take input as a byte string. Perhaps the desire is to
2064 * be able to decode the out layer even in the wrapped has errors.
2065 */
2066 static void
2067 QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx);
2068
2069 static void
2070 QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
2071
2072 static void
2073 QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
2074
2075
2076 /**
2077 * @brief Close a wrapping bstr.
2078 *
2079 * @param[in] pCtx The encoding context to close of bstr wrapping in.
2080 * @param[in] bIncludeCBORHead Include the encoded CBOR head of the bstr
2081 * as well as the bytes in @c pWrappedCBOR.
2082 * @param[out] pWrappedCBOR A @ref UsefulBufC containing wrapped bytes.
2083 *
2084 * The closes a wrapping bstr opened by QCBOREncode_BstrWrap(). It reduces
2085 * nesting level by one.
2086 *
2087 * A pointer and length of the enclosed encoded CBOR is returned in @c
2088 * *pWrappedCBOR if it is not @c NULL. The main purpose of this is so
2089 * this data can be hashed (e.g., with SHA-256) as part of a [RFC
2090 * 8152, COSE] (https://tools.ietf.org/html/rfc8152)
2091 * implementation. **WARNING**, this pointer and length should be used
2092 * right away before any other calls to @c QCBOREncode_CloseXxx() as
2093 * they will move data around and the pointer and length will no
2094 * longer be to the correct encoded CBOR.
2095 *
2096 * When an error occurs as a result of this call, the encoder records
2097 * the error and enters the error state. The error will be returned
2098 * when QCBOREncode_Finish() is called.
2099 *
2100 * If this has been called more times than QCBOREncode_BstrWrap(),
2101 * then @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
2102 * QCBOREncode_Finish() is called.
2103 *
2104 * If this is called and it is not a wrapping bstr that is currently
2105 * open, @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
2106 * QCBOREncode_Finish() is called.
2107 *
2108 * QCBOREncode_CloseBstrWrap() is a deprecated version of this function
2109 * that is equivalent to the call with @c bIncludeCBORHead @c true.
2110 */
2111 void
2112 QCBOREncode_CloseBstrWrap2(QCBOREncodeContext *pCtx, bool bIncludeCBORHead, UsefulBufC *pWrappedCBOR);
2113
2114 static void
2115 QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR);
2116
2117
2118 /**
2119 * @brief Cancel byte string wrapping.
2120 *
2121 * @param[in] pCtx The encoding context.
2122 *
2123 * This cancels QCBOREncode_BstrWrap() making tghe encoding as if it
2124 * were never called.
2125 *
2126 * WARNING: This does not work on QCBOREncode_BstrWrapInMap()
2127 * or QCBOREncode_BstrWrapInMapN() and there is no error detection
2128 * of an attempt at their use.
2129 *
2130 * This only works if nothing has been added into the wrapped byte
2131 * string. If something has been added, this sets the error
2132 * @ref QCBOR_ERR_CANNOT_CANCEL.
2133 */
2134 void
2135 QCBOREncode_CancelBstrWrap(QCBOREncodeContext *pCtx);
2136
2137
2138 /**
2139 * @brief Add some already-encoded CBOR bytes.
2140 *
2141 * @param[in] pCtx The encoding context to add the already-encode CBOR to.
2142 * @param[in] Encoded The already-encoded CBOR to add to the context.
2143 *
2144 * The encoded CBOR being added must be fully conforming CBOR. It must
2145 * be complete with no arrays or maps that are incomplete. While this
2146 * encoder doesn't ever produce indefinite lengths, it is OK for the
2147 * raw CBOR added here to have indefinite lengths.
2148 *
2149 * The raw CBOR added here is not checked in anyway. If it is not
2150 * conforming or has open arrays or such, the final encoded CBOR
2151 * will probably be wrong or not what was intended.
2152 *
2153 * If the encoded CBOR being added here contains multiple items, they
2154 * must be enclosed in a map or array. At the top level the raw
2155 * CBOR must be a single data item.
2156 */
2157 void
2158 QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded);
2159
2160 static void
2161 QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded);
2162
2163 static void
2164 QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded);
2165
2166
2167 /**
2168 * @brief Get the encoded result.
2169 *
2170 * @param[in] pCtx The context to finish encoding with.
2171 * @param[out] pEncodedCBOR Structure in which the pointer and length of
2172 * the encoded CBOR is returned.
2173 *
2174 * @retval QCBOR_SUCCESS Encoded CBOR is returned.
2175 *
2176 * @retval QCBOR_ERR_TOO_MANY_CLOSES Nesting error
2177 *
2178 * @retval QCBOR_ERR_CLOSE_MISMATCH Nesting error
2179 *
2180 * @retval QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN Nesting error
2181 *
2182 * @retval QCBOR_ERR_BUFFER_TOO_LARGE Encoded output buffer size
2183 *
2184 * @retval QCBOR_ERR_BUFFER_TOO_SMALL Encoded output buffer size
2185 *
2186 * @retval QCBOR_ERR_ARRAY_NESTING_TOO_DEEP Implementation limit
2187 *
2188 * @retval QCBOR_ERR_ARRAY_TOO_LONG Implementation limit
2189 *
2190 * On success, the pointer and length of the encoded CBOR are returned
2191 * in @c *pEncodedCBOR. The pointer is the same pointer that was passed
2192 * in to QCBOREncode_Init(). Note that it is not const when passed to
2193 * QCBOREncode_Init(), but it is const when returned here. The length
2194 * will be smaller than or equal to the length passed in when
2195 * QCBOREncode_Init() as this is the length of the actual result, not
2196 * the size of the buffer it was written to.
2197 *
2198 * If a @c NULL was passed for @c Storage.ptr when QCBOREncode_Init()
2199 * was called, @c NULL will be returned here, but the length will be
2200 * that of the CBOR that would have been encoded.
2201 *
2202 * Encoding errors primarily manifest here as most other encoding function
2203 * do no return an error. They just set the error state in the encode
2204 * context after which no encoding function does anything.
2205 *
2206 * Three types of errors manifest here. The first type are nesting
2207 * errors where the number of @c QCBOREncode_OpenXxx() calls do not
2208 * match the number @c QCBOREncode_CloseXxx() calls. The solution is to
2209 * fix the calling code.
2210 *
2211 * The second type of error is because the buffer given is either too
2212 * small or too large. The remedy is to give a correctly sized buffer.
2213 *
2214 * The third type are due to limits in this implementation.
2215 * @ref QCBOR_ERR_ARRAY_NESTING_TOO_DEEP can be worked around by
2216 * encoding the CBOR in two (or more) phases and adding the CBOR from
2217 * the first phase to the second with @c QCBOREncode_AddEncoded().
2218 *
2219 * If an error is returned, the buffer may have partially encoded
2220 * incorrect CBOR in it and it should not be used. Likewise, the length
2221 * may be incorrect and should not be used.
2222 *
2223 * Note that the error could have occurred in one of the many
2224 * @c QCBOREncode_AddXxx() calls long before QCBOREncode_Finish() was
2225 * called. This error handling reduces the CBOR implementation size
2226 * but makes debugging harder.
2227 *
2228 * This may be called multiple times. It will always return the
2229 * same. It can also be interleaved with calls to
2230 * QCBOREncode_FinishGetSize().
2231 *
2232 * QCBOREncode_GetErrorState() can be called to get the current
2233 * error state in order to abort encoding early as an optimization, but
2234 * calling it is is never required.
2235 */
2236 QCBORError
2237 QCBOREncode_Finish(QCBOREncodeContext *pCtx, UsefulBufC *pEncodedCBOR);
2238
2239
2240 /**
2241 * @brief Get the encoded CBOR and error status.
2242 *
2243 * @param[in] pCtx The context to finish encoding with.
2244 * @param[out] uEncodedLen The length of the encoded or potentially
2245 * encoded CBOR in bytes.
2246 *
2247 * @return The same errors as QCBOREncode_Finish().
2248 *
2249 * This functions the same as QCBOREncode_Finish(), but only returns the
2250 * size of the encoded output.
2251 */
2252 QCBORError
2253 QCBOREncode_FinishGetSize(QCBOREncodeContext *pCtx, size_t *uEncodedLen);
2254
2255
2256 /**
2257 * @brief Indicate whether output buffer is NULL or not.
2258 *
2259 * @param[in] pCtx The encoding context.
2260 *
2261 * @return 1 if the output buffer is @c NULL.
2262 *
2263 * Sometimes a @c NULL input buffer is given to QCBOREncode_Init() so
2264 * that the size of the generated CBOR can be calculated without
2265 * allocating a buffer for it. This returns 1 when the output buffer
2266 * is @c NULL and 0 when it is not.
2267 */
2268 static int
2269 QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx);
2270
2271
2272 /**
2273 * @brief Get the encoding error state.
2274 *
2275 * @param[in] pCtx The encoding context.
2276 *
2277 * @return One of @ref QCBORError. See return values from
2278 * QCBOREncode_Finish()
2279 *
2280 * Normally encoding errors need only be handled at the end of
2281 * encoding when QCBOREncode_Finish() is called. This can be called to
2282 * get the error result before finish should there be a need to halt
2283 * encoding before QCBOREncode_Finish() is called.
2284 */
2285 static QCBORError
2286 QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx);
2287
2288
2289 /**
2290 * Encode the "head" of a CBOR data item.
2291 *
2292 * @param Buffer Buffer to output the encoded head to; must be
2293 * @ref QCBOR_HEAD_BUFFER_SIZE bytes in size.
2294 * @param uMajorType One of CBOR_MAJOR_TYPE_XX.
2295 * @param uMinLen The minimum number of bytes to encode uNumber. Almost
2296 * always this is 0 to use preferred
2297 * serialization. If this is 4, then even the
2298 * values 0xffff and smaller will be encoded in 4
2299 * bytes. This is used primarily when encoding a
2300 * float or double put into uNumber as the leading
2301 * zero bytes for them must be encoded.
2302 * @param uNumber The numeric argument part of the CBOR head.
2303 * @return Pointer and length of the encoded head or
2304 * @ref NULLUsefulBufC if the output buffer is too small.
2305 *
2306 * Callers do not to need to call this for normal CBOR encoding. Note
2307 * that it doesn't even take a @ref QCBOREncodeContext argument.
2308 *
2309 * This encodes the major type and argument part of a data item. The
2310 * argument is an integer that is usually either the value or the length
2311 * of the data item.
2312 *
2313 * This is exposed in the public interface to allow hashing of some CBOR
2314 * data types, bstr in particular, a chunk at a time so the full CBOR
2315 * doesn't have to be encoded in a contiguous buffer.
2316 *
2317 * For example, if you have a 100,000 byte binary blob in a buffer that
2318 * needs to be a bstr encoded and then hashed. You could allocate a
2319 * 100,010 byte buffer and encode it normally. Alternatively, you can
2320 * encode the head in a 10 byte buffer with this function, hash that and
2321 * then hash the 100,000 bytes using the same hash context.
2322 */
2323 UsefulBufC
2324 QCBOREncode_EncodeHead(UsefulBuf Buffer,
2325 uint8_t uMajorType,
2326 uint8_t uMinLen,
2327 uint64_t uNumber);
2328
2329
2330
2331
2332 /* =========================================================================
2333 BEGINNING OF PRIVATE IMPLEMENTATION
2334 ========================================================================= */
2335
2336 /* Semi-private funcion used by public inline functions. See qcbor_encode.c */
2337 void QCBOREncode_Private_AppendCBORHead(QCBOREncodeContext *pMe,
2338 const uint8_t uMajorType,
2339 const uint64_t uArgument,
2340 const uint8_t uMinLen);
2341
2342
2343 /* Semi-private funcion used by public inline functions. See qcbor_encode.c */
2344 void
2345 QCBOREncode_Private_AddBuffer(QCBOREncodeContext *pCtx,
2346 uint8_t uMajorType,
2347 UsefulBufC Bytes);
2348
2349
2350 /* Semi-private function for adding a double with preferred encoding. See qcbor_encode.c */
2351 void
2352 QCBOREncode_Private_AddPreferredDouble(QCBOREncodeContext *pMe, const double dNum);
2353
2354
2355 /* Semi-private function for adding a float with preferred encoding. See qcbor_encode.c */
2356 void
2357 QCBOREncode_Private_AddPreferredFloat(QCBOREncodeContext *pMe, const float fNum);
2358
2359
2360 /* Semi-private funcion used by public inline functions. See qcbor_encode.c */
2361 void
2362 QCBOREncode_Private_OpenMapOrArray(QCBOREncodeContext *pCtx,
2363 uint8_t uMajorType);
2364
2365
2366 /* Semi-private funcion used by public inline functions. See qcbor_encode.c */
2367 void
2368 QCBOREncode_Private_OpenMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx,
2369 uint8_t uMajorType);
2370
2371
2372 /* Semi-private funcion used by public inline functions. See qcbor_encode.c */
2373 void
2374 QCBOREncode_Private_CloseMapOrArray(QCBOREncodeContext *pCtx,
2375 uint8_t uMajorType);
2376
2377
2378 /* Semi-private funcion used by public inline functions. See qcbor_encode.c */
2379 void
2380 QCBOREncode_Private_CloseMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx,
2381 uint8_t uMajorType);
2382
2383
2384 /* Semi-private funcion used by public inline functions. See qcbor_encode.c */
2385 void
2386 QCBOREncode_Private_AddExpMantissa(QCBOREncodeContext *pCtx,
2387 uint64_t uTag,
2388 UsefulBufC BigNumMantissa,
2389 bool bBigNumIsNegative,
2390 int64_t nMantissa,
2391 int64_t nExponent);
2392
2393
2394 /**
2395 * @brief Semi-private method to add simple items and floating-point.
2396 *
2397 * @param[in] pMe The encoding context.
2398 * @param[in] uMinLen Minimum encoding size for uNum. Usually 0.
2399 * @param[in] uArgument The value to add.
2400 *
2401 * This is used to add simple types like true and false and float-point
2402 * values, both of which are type 7.
2403 *
2404 * Call QCBOREncode_AddBool(), QCBOREncode_AddNULL(),
2405 * QCBOREncode_AddUndef() QCBOREncode_AddDouble() instead of this.
2406 *
2407 * Error handling is the same as QCBOREncode_AddInt64().
2408 */
2409 static inline void
QCBOREncode_Private_AddType7(QCBOREncodeContext * pMe,const uint8_t uMinLen,const uint64_t uArgument)2410 QCBOREncode_Private_AddType7(QCBOREncodeContext *pMe,
2411 const uint8_t uMinLen,
2412 const uint64_t uArgument)
2413 {
2414 QCBOREncode_Private_AppendCBORHead(pMe, CBOR_MAJOR_TYPE_SIMPLE, uArgument, uMinLen);
2415 }
2416
2417
2418 /**
2419 * @brief Semi-private method to add only the type and length of a byte string.
2420 *
2421 * @param[in] pCtx The context to initialize.
2422 * @param[in] Bytes Pointer and length of the input data.
2423 *
2424 * This will be removed in QCBOR 2.0. It was never a public function.
2425 *
2426 * This is the same as QCBOREncode_AddBytes() except it only adds the
2427 * CBOR encoding for the type and the length. It doesn't actually add
2428 * the bytes. You can't actually produce correct CBOR with this and
2429 * the rest of this API. It is only used for a special case where the
2430 * valid CBOR is created manually by putting this type and length in
2431 * and then adding the actual bytes. In particular, when only a hash
2432 * of the encoded CBOR is needed, where the type and header are hashed
2433 * separately and then the bytes is hashed. This makes it possible to
2434 * implement COSE Sign1 with only one copy of the payload in the
2435 * output buffer, rather than two, roughly cutting memory use in half.
2436 *
2437 * This is only used for this odd case, but this is a supported
2438 * tested function for QCBOR 1.0.
2439 *
2440 * See also QCBOREncode_EncodeHead().
2441 */
2442 static void
2443 QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pCtx,
2444 UsefulBufC Bytes);
2445
2446 static void
2447 QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pCtx,
2448 const char *szLabel,
2449 UsefulBufC Bytes);
2450
2451 static void
2452 QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pCtx,
2453 int64_t nLabel,
2454 UsefulBufC Bytes);
2455
2456
2457 /* Forward declaration */
2458 static void
2459 QCBOREncode_AddSZString(QCBOREncodeContext *pMe, const char *szString);
2460
2461
2462
2463
2464 static inline void
QCBOREncode_AddInt64ToMap(QCBOREncodeContext * pMe,const char * szLabel,const int64_t uNum)2465 QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pMe,
2466 const char *szLabel,
2467 const int64_t uNum)
2468 {
2469 QCBOREncode_AddSZString(pMe, szLabel);
2470 QCBOREncode_AddInt64(pMe, uNum);
2471 }
2472
2473 static inline void
QCBOREncode_AddInt64ToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const int64_t uNum)2474 QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pMe,
2475 const int64_t nLabel,
2476 const int64_t uNum)
2477 {
2478 QCBOREncode_AddInt64(pMe, nLabel);
2479 QCBOREncode_AddInt64(pMe, uNum);
2480 }
2481
2482
2483 static inline void
QCBOREncode_AddUInt64(QCBOREncodeContext * pMe,const uint64_t uValue)2484 QCBOREncode_AddUInt64(QCBOREncodeContext *pMe, const uint64_t uValue)
2485 {
2486 QCBOREncode_Private_AppendCBORHead(pMe, CBOR_MAJOR_TYPE_POSITIVE_INT, uValue, 0);
2487 }
2488
2489
2490 static inline void
QCBOREncode_AddUInt64ToMap(QCBOREncodeContext * pMe,const char * szLabel,const uint64_t uNum)2491 QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pMe,
2492 const char *szLabel,
2493 const uint64_t uNum)
2494 {
2495 QCBOREncode_AddSZString(pMe, szLabel);
2496 QCBOREncode_AddUInt64(pMe, uNum);
2497 }
2498
2499 static inline void
QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint64_t uNum)2500 QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pMe,
2501 const int64_t nLabel,
2502 const uint64_t uNum)
2503 {
2504 QCBOREncode_AddInt64(pMe, nLabel);
2505 QCBOREncode_AddUInt64(pMe, uNum);
2506 }
2507
2508
2509 static inline void
QCBOREncode_AddText(QCBOREncodeContext * pMe,const UsefulBufC Text)2510 QCBOREncode_AddText(QCBOREncodeContext *pMe, const UsefulBufC Text)
2511 {
2512 QCBOREncode_Private_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, Text);
2513 }
2514
2515 static inline void
QCBOREncode_AddTextToMap(QCBOREncodeContext * pMe,const char * szLabel,const UsefulBufC Text)2516 QCBOREncode_AddTextToMap(QCBOREncodeContext *pMe,
2517 const char *szLabel,
2518 const UsefulBufC Text)
2519 {
2520 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szLabel));
2521 QCBOREncode_AddText(pMe, Text);
2522 }
2523
2524 static inline void
QCBOREncode_AddTextToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const UsefulBufC Text)2525 QCBOREncode_AddTextToMapN(QCBOREncodeContext *pMe,
2526 const int64_t nLabel,
2527 const UsefulBufC Text)
2528 {
2529 QCBOREncode_AddInt64(pMe, nLabel);
2530 QCBOREncode_AddText(pMe, Text);
2531 }
2532
2533
2534 inline static void
QCBOREncode_AddSZString(QCBOREncodeContext * pMe,const char * szString)2535 QCBOREncode_AddSZString(QCBOREncodeContext *pMe, const char *szString)
2536 {
2537 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szString));
2538 }
2539
2540 static inline void
QCBOREncode_AddSZStringToMap(QCBOREncodeContext * pMe,const char * szLabel,const char * szString)2541 QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pMe,
2542 const char *szLabel,
2543 const char *szString)
2544 {
2545 QCBOREncode_AddSZString(pMe, szLabel);
2546 QCBOREncode_AddSZString(pMe, szString);
2547 }
2548
2549 static inline void
QCBOREncode_AddSZStringToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const char * szString)2550 QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pMe,
2551 const int64_t nLabel,
2552 const char *szString)
2553 {
2554 QCBOREncode_AddInt64(pMe, nLabel);
2555 QCBOREncode_AddSZString(pMe, szString);
2556 }
2557
2558
2559
2560 /*
2561 * Public functions for adding a tag. See qcbor/qcbor_encode.h
2562 */
2563 static inline void
QCBOREncode_AddTag(QCBOREncodeContext * pMe,const uint64_t uTag)2564 QCBOREncode_AddTag(QCBOREncodeContext *pMe, const uint64_t uTag)
2565 {
2566 QCBOREncode_Private_AppendCBORHead(pMe, CBOR_MAJOR_TYPE_TAG, uTag, 0);
2567 }
2568
2569
2570
2571 #ifndef USEFULBUF_DISABLE_ALL_FLOAT
2572
2573 static inline void
QCBOREncode_AddDoubleNoPreferred(QCBOREncodeContext * pMe,const double dNum)2574 QCBOREncode_AddDoubleNoPreferred(QCBOREncodeContext *pMe, const double dNum)
2575 {
2576 QCBOREncode_Private_AddType7(pMe,
2577 sizeof(uint64_t),
2578 UsefulBufUtil_CopyDoubleToUint64(dNum));
2579 }
2580
2581 static inline void
QCBOREncode_AddFloatNoPreferred(QCBOREncodeContext * pMe,const float fNum)2582 QCBOREncode_AddFloatNoPreferred(QCBOREncodeContext *pMe, const float fNum)
2583 {
2584 QCBOREncode_Private_AddType7(pMe,
2585 sizeof(uint32_t),
2586 UsefulBufUtil_CopyFloatToUint32(fNum));
2587 }
2588
2589
2590 static inline void
QCBOREncode_AddDouble(QCBOREncodeContext * pMe,const double dNum)2591 QCBOREncode_AddDouble(QCBOREncodeContext *pMe, const double dNum)
2592 {
2593 #ifndef QCBOR_DISABLE_PREFERRED_FLOAT
2594 QCBOREncode_Private_AddPreferredDouble(pMe, dNum);
2595 #else /* QCBOR_DISABLE_PREFERRED_FLOAT */
2596 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
2597 #endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
2598 }
2599
2600 static inline void
QCBOREncode_AddDoubleToMap(QCBOREncodeContext * pMe,const char * szLabel,const double dNum)2601 QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pMe,
2602 const char *szLabel,
2603 const double dNum)
2604 {
2605 QCBOREncode_AddSZString(pMe, szLabel);
2606 QCBOREncode_AddDouble(pMe, dNum);
2607 }
2608
2609 static inline void
QCBOREncode_AddDoubleToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const double dNum)2610 QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pMe,
2611 const int64_t nLabel,
2612 const double dNum)
2613 {
2614 QCBOREncode_AddInt64(pMe, nLabel);
2615 QCBOREncode_AddDouble(pMe, dNum);
2616 }
2617
2618
2619 static inline void
QCBOREncode_AddFloat(QCBOREncodeContext * pMe,const float fNum)2620 QCBOREncode_AddFloat(QCBOREncodeContext *pMe, const float fNum)
2621 {
2622 #ifndef QCBOR_DISABLE_PREFERRED_FLOAT
2623 QCBOREncode_Private_AddPreferredFloat(pMe, fNum);
2624 #else /* QCBOR_DISABLE_PREFERRED_FLOAT */
2625 QCBOREncode_AddFloatNoPreferred(pMe, fNum);
2626 #endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
2627 }
2628
2629 static inline void
QCBOREncode_AddFloatToMap(QCBOREncodeContext * pMe,const char * szLabel,const float dNum)2630 QCBOREncode_AddFloatToMap(QCBOREncodeContext *pMe,
2631 const char *szLabel,
2632 const float dNum)
2633 {
2634 QCBOREncode_AddSZString(pMe, szLabel);
2635 QCBOREncode_AddFloat(pMe, dNum);
2636 }
2637
2638 static inline void
QCBOREncode_AddFloatToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const float fNum)2639 QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pMe,
2640 const int64_t nLabel,
2641 const float fNum)
2642 {
2643 QCBOREncode_AddInt64(pMe, nLabel);
2644 QCBOREncode_AddFloat(pMe, fNum);
2645 }
2646
2647 static inline void
QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext * pMe,const char * szLabel,const double dNum)2648 QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pMe,
2649 const char *szLabel,
2650 const double dNum)
2651 {
2652 QCBOREncode_AddSZString(pMe, szLabel);
2653 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
2654 }
2655
2656 static inline void
QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const double dNum)2657 QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pMe,
2658 const int64_t nLabel,
2659 const double dNum)
2660 {
2661 QCBOREncode_AddInt64(pMe, nLabel);
2662 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
2663 }
2664
2665 static inline void
QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext * pMe,const char * szLabel,const float dNum)2666 QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pMe,
2667 const char *szLabel,
2668 const float dNum)
2669 {
2670 QCBOREncode_AddSZString(pMe, szLabel);
2671 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
2672 }
2673
2674 static inline void
QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const float dNum)2675 QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pMe,
2676 const int64_t nLabel,
2677 const float dNum)
2678 {
2679 QCBOREncode_AddInt64(pMe, nLabel);
2680 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
2681 }
2682 #endif /* USEFULBUF_DISABLE_ALL_FLOAT */
2683
2684
2685
2686
2687
2688 static inline void
QCBOREncode_AddTDateEpoch(QCBOREncodeContext * pMe,const uint8_t uTag,const int64_t nDate)2689 QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pMe,
2690 const uint8_t uTag,
2691 const int64_t nDate)
2692 {
2693 if(uTag == QCBOR_ENCODE_AS_TAG) {
2694 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_EPOCH);
2695 }
2696 QCBOREncode_AddInt64(pMe, nDate);
2697 }
2698
2699 static inline void
QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTag,const int64_t nDate)2700 QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pMe,
2701 const char *szLabel,
2702 const uint8_t uTag,
2703 const int64_t nDate)
2704 {
2705 QCBOREncode_AddSZString(pMe, szLabel);
2706 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
2707 }
2708
2709 static inline void
QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTag,const int64_t nDate)2710 QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pMe,
2711 const int64_t nLabel,
2712 const uint8_t uTag,
2713 const int64_t nDate)
2714 {
2715 QCBOREncode_AddInt64(pMe, nLabel);
2716 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
2717 }
2718
2719 static inline void
QCBOREncode_AddDateEpoch(QCBOREncodeContext * pMe,const int64_t nDate)2720 QCBOREncode_AddDateEpoch(QCBOREncodeContext *pMe,
2721 const int64_t nDate)
2722 {
2723 QCBOREncode_AddTDateEpoch(pMe, QCBOR_ENCODE_AS_TAG, nDate);
2724 }
2725
2726 static inline void
QCBOREncode_AddDateEpochToMap(QCBOREncodeContext * pMe,const char * szLabel,const int64_t nDate)2727 QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pMe,
2728 const char *szLabel,
2729 const int64_t nDate)
2730 {
2731 QCBOREncode_AddSZString(pMe, szLabel);
2732 QCBOREncode_AddDateEpoch(pMe, nDate);
2733 }
2734
2735 static inline void
QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const int64_t nDate)2736 QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pMe,
2737 const int64_t nLabel,
2738 const int64_t nDate)
2739 {
2740 QCBOREncode_AddInt64(pMe, nLabel);
2741 QCBOREncode_AddDateEpoch(pMe, nDate);
2742 }
2743
2744
2745 static inline void
QCBOREncode_AddTDaysEpoch(QCBOREncodeContext * pMe,const uint8_t uTag,const int64_t nDays)2746 QCBOREncode_AddTDaysEpoch(QCBOREncodeContext *pMe,
2747 const uint8_t uTag,
2748 const int64_t nDays)
2749 {
2750 if(uTag == QCBOR_ENCODE_AS_TAG) {
2751 QCBOREncode_AddTag(pMe, CBOR_TAG_DAYS_EPOCH);
2752 }
2753 QCBOREncode_AddInt64(pMe, nDays);
2754 }
2755
2756 static inline void
QCBOREncode_AddTDaysEpochToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTag,const int64_t nDays)2757 QCBOREncode_AddTDaysEpochToMapSZ(QCBOREncodeContext *pMe,
2758 const char *szLabel,
2759 const uint8_t uTag,
2760 const int64_t nDays)
2761 {
2762 QCBOREncode_AddSZString(pMe, szLabel);
2763 QCBOREncode_AddTDaysEpoch(pMe, uTag, nDays);
2764 }
2765
2766 static inline void
QCBOREncode_AddTDaysEpochToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTag,const int64_t nDays)2767 QCBOREncode_AddTDaysEpochToMapN(QCBOREncodeContext *pMe,
2768 const int64_t nLabel,
2769 const uint8_t uTag,
2770 const int64_t nDays)
2771 {
2772 QCBOREncode_AddInt64(pMe, nLabel);
2773 QCBOREncode_AddTDaysEpoch(pMe, uTag, nDays);
2774 }
2775
2776
2777 static inline void
QCBOREncode_AddBytes(QCBOREncodeContext * pMe,const UsefulBufC Bytes)2778 QCBOREncode_AddBytes(QCBOREncodeContext *pMe,
2779 const UsefulBufC Bytes)
2780 {
2781 QCBOREncode_Private_AddBuffer(pMe, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes);
2782 }
2783
2784 static inline void
QCBOREncode_AddBytesToMap(QCBOREncodeContext * pMe,const char * szLabel,const UsefulBufC Bytes)2785 QCBOREncode_AddBytesToMap(QCBOREncodeContext *pMe,
2786 const char *szLabel,
2787 const UsefulBufC Bytes)
2788 {
2789 QCBOREncode_AddSZString(pMe, szLabel);
2790 QCBOREncode_AddBytes(pMe, Bytes);
2791 }
2792
2793 static inline void
QCBOREncode_AddBytesToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const UsefulBufC Bytes)2794 QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pMe,
2795 const int64_t nLabel,
2796 const UsefulBufC Bytes)
2797 {
2798 QCBOREncode_AddInt64(pMe, nLabel);
2799 QCBOREncode_AddBytes(pMe, Bytes);
2800 }
2801
2802 static inline void
QCBOREncode_OpenBytesInMapSZ(QCBOREncodeContext * pMe,const char * szLabel,UsefulBuf * pPlace)2803 QCBOREncode_OpenBytesInMapSZ(QCBOREncodeContext *pMe,
2804 const char *szLabel,
2805 UsefulBuf *pPlace)
2806 {
2807 QCBOREncode_AddSZString(pMe, szLabel);
2808 QCBOREncode_OpenBytes(pMe, pPlace);
2809 }
2810
2811 static inline void
QCBOREncode_OpenBytesInMapN(QCBOREncodeContext * pMe,const int64_t nLabel,UsefulBuf * pPlace)2812 QCBOREncode_OpenBytesInMapN(QCBOREncodeContext *pMe,
2813 const int64_t nLabel,
2814 UsefulBuf *pPlace)
2815 {
2816 QCBOREncode_AddInt64(pMe, nLabel);
2817 QCBOREncode_OpenBytes(pMe, pPlace);
2818 }
2819
2820
2821 /*
2822 * Public functions for adding only a byte string length. See qcbor/qcbor_encode.h
2823 */
2824 static inline void
QCBOREncode_AddBytesLenOnly(QCBOREncodeContext * pMe,const UsefulBufC Bytes)2825 QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
2826 {
2827 QCBOREncode_Private_AppendCBORHead(pMe, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes.len, 0);
2828 }
2829
2830
2831 static inline void
QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext * pMe,const char * szLabel,const UsefulBufC Bytes)2832 QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pMe,
2833 const char *szLabel,
2834 const UsefulBufC Bytes)
2835 {
2836 QCBOREncode_AddSZString(pMe, szLabel);
2837 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
2838 }
2839
2840 static inline void
QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const UsefulBufC Bytes)2841 QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pMe,
2842 const int64_t nLabel,
2843 const UsefulBufC Bytes)
2844 {
2845 QCBOREncode_AddInt64(pMe, nLabel);
2846 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
2847 }
2848
2849
2850 static inline void
QCBOREncode_AddTBinaryUUID(QCBOREncodeContext * pMe,const uint8_t uTagRequirement,const UsefulBufC Bytes)2851 QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pMe,
2852 const uint8_t uTagRequirement,
2853 const UsefulBufC Bytes)
2854 {
2855 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2856 QCBOREncode_AddTag(pMe, CBOR_TAG_BIN_UUID);
2857 }
2858 QCBOREncode_AddBytes(pMe, Bytes);
2859 }
2860
2861 static inline void
QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,const UsefulBufC Bytes)2862 QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pMe,
2863 const char *szLabel,
2864 const uint8_t uTagRequirement,
2865 const UsefulBufC Bytes)
2866 {
2867 QCBOREncode_AddSZString(pMe, szLabel);
2868 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
2869 }
2870
2871 static inline void
QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,const UsefulBufC Bytes)2872 QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pMe,
2873 const int64_t nLabel,
2874 const uint8_t uTagRequirement,
2875 const UsefulBufC Bytes)
2876 {
2877 QCBOREncode_AddInt64(pMe, nLabel);
2878 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
2879 }
2880
2881 static inline void
QCBOREncode_AddBinaryUUID(QCBOREncodeContext * pMe,const UsefulBufC Bytes)2882 QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
2883 {
2884 QCBOREncode_AddTBinaryUUID(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2885 }
2886
2887 static inline void
QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext * pMe,const char * szLabel,const UsefulBufC Bytes)2888 QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pMe,
2889 const char *szLabel,
2890 const UsefulBufC Bytes)
2891 {
2892 QCBOREncode_AddTBinaryUUIDToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2893 }
2894
2895 static inline void
QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const UsefulBufC Bytes)2896 QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pMe,
2897 const int64_t nLabel,
2898 const UsefulBufC Bytes)
2899 {
2900 QCBOREncode_AddTBinaryUUIDToMapN(pMe,
2901 nLabel,
2902 QCBOR_ENCODE_AS_TAG,
2903 Bytes);
2904 }
2905
2906
2907 static inline void
QCBOREncode_AddTPositiveBignum(QCBOREncodeContext * pMe,const uint8_t uTagRequirement,const UsefulBufC Bytes)2908 QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pMe,
2909 const uint8_t uTagRequirement,
2910 const UsefulBufC Bytes)
2911 {
2912 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2913 QCBOREncode_AddTag(pMe, CBOR_TAG_POS_BIGNUM);
2914 }
2915 QCBOREncode_AddBytes(pMe, Bytes);
2916 }
2917
2918 static inline void
QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,const UsefulBufC Bytes)2919 QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pMe,
2920 const char *szLabel,
2921 const uint8_t uTagRequirement,
2922 const UsefulBufC Bytes)
2923 {
2924 QCBOREncode_AddSZString(pMe, szLabel);
2925 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
2926 }
2927
2928 static inline void
QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,const UsefulBufC Bytes)2929 QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pMe,
2930 const int64_t nLabel,
2931 const uint8_t uTagRequirement,
2932 const UsefulBufC Bytes)
2933 {
2934 QCBOREncode_AddInt64(pMe, nLabel);
2935 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
2936 }
2937
2938 static inline void
QCBOREncode_AddPositiveBignum(QCBOREncodeContext * pMe,const UsefulBufC Bytes)2939 QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
2940 {
2941 QCBOREncode_AddTPositiveBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2942 }
2943
2944 static inline void
QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext * pMe,const char * szLabel,const UsefulBufC Bytes)2945 QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pMe,
2946 const char *szLabel,
2947 const UsefulBufC Bytes)
2948 {
2949 QCBOREncode_AddTPositiveBignumToMapSZ(pMe,
2950 szLabel,
2951 QCBOR_ENCODE_AS_TAG,
2952 Bytes);
2953 }
2954
2955 static inline void
QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const UsefulBufC Bytes)2956 QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pMe,
2957 const int64_t nLabel,
2958 const UsefulBufC Bytes)
2959 {
2960 QCBOREncode_AddTPositiveBignumToMapN(pMe,
2961 nLabel,
2962 QCBOR_ENCODE_AS_TAG,
2963 Bytes);
2964 }
2965
2966
2967 static inline void
QCBOREncode_AddTNegativeBignum(QCBOREncodeContext * pMe,const uint8_t uTagRequirement,const UsefulBufC Bytes)2968 QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pMe,
2969 const uint8_t uTagRequirement,
2970 const UsefulBufC Bytes)
2971 {
2972 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2973 QCBOREncode_AddTag(pMe, CBOR_TAG_NEG_BIGNUM);
2974 }
2975 QCBOREncode_AddBytes(pMe, Bytes);
2976 }
2977
2978 static inline void
QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,const UsefulBufC Bytes)2979 QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pMe,
2980 const char *szLabel,
2981 const uint8_t uTagRequirement,
2982 const UsefulBufC Bytes)
2983 {
2984 QCBOREncode_AddSZString(pMe, szLabel);
2985 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2986 }
2987
2988 static inline void
QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,const UsefulBufC Bytes)2989 QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pMe,
2990 const int64_t nLabel,
2991 const uint8_t uTagRequirement,
2992 const UsefulBufC Bytes)
2993 {
2994 QCBOREncode_AddInt64(pMe, nLabel);
2995 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2996 }
2997
2998 static inline void
QCBOREncode_AddNegativeBignum(QCBOREncodeContext * pMe,const UsefulBufC Bytes)2999 QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
3000 {
3001 QCBOREncode_AddTNegativeBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
3002 }
3003
3004 static inline void
QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext * pMe,const char * szLabel,const UsefulBufC Bytes)3005 QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pMe,
3006 const char *szLabel,
3007 const UsefulBufC Bytes)
3008 {
3009 QCBOREncode_AddTNegativeBignumToMapSZ(pMe,
3010 szLabel,
3011 QCBOR_ENCODE_AS_TAG,
3012 Bytes);
3013 }
3014
3015 static inline void
QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const UsefulBufC Bytes)3016 QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pMe,
3017 const int64_t nLabel,
3018 const UsefulBufC Bytes)
3019 {
3020 QCBOREncode_AddTNegativeBignumToMapN(pMe,
3021 nLabel,
3022 QCBOR_ENCODE_AS_TAG,
3023 Bytes);
3024 }
3025
3026
3027
3028 #ifndef QCBOR_DISABLE_EXP_AND_MANTISSA
3029
3030 static inline void
QCBOREncode_AddTDecimalFraction(QCBOREncodeContext * pMe,const uint8_t uTagRequirement,const int64_t nMantissa,const int64_t nBase10Exponent)3031 QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pMe,
3032 const uint8_t uTagRequirement,
3033 const int64_t nMantissa,
3034 const int64_t nBase10Exponent)
3035 {
3036 uint64_t uTag;
3037 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3038 uTag = CBOR_TAG_DECIMAL_FRACTION;
3039 } else {
3040 uTag = CBOR_TAG_INVALID64;
3041 }
3042 QCBOREncode_Private_AddExpMantissa(pMe,
3043 uTag,
3044 NULLUsefulBufC,
3045 false,
3046 nMantissa,
3047 nBase10Exponent);
3048 }
3049
3050 static inline void
QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,const int64_t nMantissa,const int64_t nBase10Exponent)3051 QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pMe,
3052 const char *szLabel,
3053 const uint8_t uTagRequirement,
3054 const int64_t nMantissa,
3055 const int64_t nBase10Exponent)
3056 {
3057 QCBOREncode_AddSZString(pMe, szLabel);
3058 QCBOREncode_AddTDecimalFraction(pMe,
3059 uTagRequirement,
3060 nMantissa,
3061 nBase10Exponent);
3062 }
3063
3064 static inline void
QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,const int64_t nMantissa,const int64_t nBase10Exponent)3065 QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pMe,
3066 const int64_t nLabel,
3067 const uint8_t uTagRequirement,
3068 const int64_t nMantissa,
3069 const int64_t nBase10Exponent)
3070 {
3071 QCBOREncode_AddInt64(pMe, nLabel);
3072 QCBOREncode_AddTDecimalFraction(pMe,
3073 uTagRequirement,
3074 nMantissa,
3075 nBase10Exponent);
3076 }
3077
3078 static inline void
QCBOREncode_AddDecimalFraction(QCBOREncodeContext * pMe,const int64_t nMantissa,const int64_t nBase10Exponent)3079 QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pMe,
3080 const int64_t nMantissa,
3081 const int64_t nBase10Exponent)
3082 {
3083 QCBOREncode_AddTDecimalFraction(pMe,
3084 QCBOR_ENCODE_AS_TAG,
3085 nMantissa,
3086 nBase10Exponent);
3087 }
3088
3089 static inline void
QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext * pMe,const char * szLabel,const int64_t nMantissa,const int64_t nBase10Exponent)3090 QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pMe,
3091 const char *szLabel,
3092 const int64_t nMantissa,
3093 const int64_t nBase10Exponent)
3094 {
3095 QCBOREncode_AddTDecimalFractionToMapSZ(pMe,
3096 szLabel,
3097 QCBOR_ENCODE_AS_TAG,
3098 nMantissa,
3099 nBase10Exponent);
3100 }
3101
3102 static inline void
QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const int64_t nMantissa,const int64_t nBase10Exponent)3103 QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pMe,
3104 const int64_t nLabel,
3105 const int64_t nMantissa,
3106 const int64_t nBase10Exponent)
3107 {
3108 QCBOREncode_AddTDecimalFractionToMapN(pMe,
3109 nLabel,
3110 QCBOR_ENCODE_AS_TAG,
3111 nMantissa,
3112 nBase10Exponent);
3113 }
3114
3115
3116
3117 static inline void
QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext * pMe,const uint8_t uTagRequirement,const UsefulBufC Mantissa,const bool bIsNegative,const int64_t nBase10Exponent)3118 QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pMe,
3119 const uint8_t uTagRequirement,
3120 const UsefulBufC Mantissa,
3121 const bool bIsNegative,
3122 const int64_t nBase10Exponent)
3123 {
3124 uint64_t uTag;
3125 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3126 uTag = CBOR_TAG_DECIMAL_FRACTION;
3127 } else {
3128 uTag = CBOR_TAG_INVALID64;
3129 }
3130 QCBOREncode_Private_AddExpMantissa(pMe,
3131 uTag,
3132 Mantissa,
3133 bIsNegative,
3134 0,
3135 nBase10Exponent);
3136 }
3137
3138 static inline void
QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,const UsefulBufC Mantissa,const bool bIsNegative,const int64_t nBase10Exponent)3139 QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
3140 const char *szLabel,
3141 const uint8_t uTagRequirement,
3142 const UsefulBufC Mantissa,
3143 const bool bIsNegative,
3144 const int64_t nBase10Exponent)
3145 {
3146 QCBOREncode_AddSZString(pMe, szLabel);
3147 QCBOREncode_AddTDecimalFractionBigNum(pMe,
3148 uTagRequirement,
3149 Mantissa,
3150 bIsNegative,
3151 nBase10Exponent);
3152 }
3153
3154 static inline void
QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,const UsefulBufC Mantissa,const bool bIsNegative,const int64_t nBase10Exponent)3155 QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
3156 const int64_t nLabel,
3157 const uint8_t uTagRequirement,
3158 const UsefulBufC Mantissa,
3159 const bool bIsNegative,
3160 const int64_t nBase10Exponent)
3161 {
3162 QCBOREncode_AddInt64(pMe, nLabel);
3163 QCBOREncode_AddTDecimalFractionBigNum(pMe,
3164 uTagRequirement,
3165 Mantissa,
3166 bIsNegative,
3167 nBase10Exponent);
3168 }
3169
3170 static inline void
QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext * pMe,const UsefulBufC Mantissa,const bool bIsNegative,const int64_t nBase10Exponent)3171 QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pMe,
3172 const UsefulBufC Mantissa,
3173 const bool bIsNegative,
3174 const int64_t nBase10Exponent)
3175 {
3176 QCBOREncode_AddTDecimalFractionBigNum(pMe,
3177 QCBOR_ENCODE_AS_TAG,
3178 Mantissa,
3179 bIsNegative,
3180 nBase10Exponent);
3181 }
3182
3183 static inline void
QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const UsefulBufC Mantissa,const bool bIsNegative,const int64_t nBase10Exponent)3184 QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
3185 const char *szLabel,
3186 const UsefulBufC Mantissa,
3187 const bool bIsNegative,
3188 const int64_t nBase10Exponent)
3189 {
3190 QCBOREncode_AddTDecimalFractionBigNumToMapSZ(pMe,
3191 szLabel,
3192 QCBOR_ENCODE_AS_TAG,
3193 Mantissa,
3194 bIsNegative,
3195 nBase10Exponent);
3196 }
3197
3198 static inline void
QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const UsefulBufC Mantissa,const bool bIsNegative,const int64_t nBase2Exponent)3199 QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
3200 const int64_t nLabel,
3201 const UsefulBufC Mantissa,
3202 const bool bIsNegative,
3203 const int64_t nBase2Exponent)
3204 {
3205 QCBOREncode_AddTDecimalFractionBigNumToMapN(pMe,
3206 nLabel,
3207 QCBOR_ENCODE_AS_TAG,
3208 Mantissa,
3209 bIsNegative,
3210 nBase2Exponent);
3211 }
3212
3213
3214
3215
3216
3217 static inline void
QCBOREncode_AddTBigFloat(QCBOREncodeContext * pMe,const uint8_t uTagRequirement,const int64_t nMantissa,const int64_t nBase2Exponent)3218 QCBOREncode_AddTBigFloat(QCBOREncodeContext *pMe,
3219 const uint8_t uTagRequirement,
3220 const int64_t nMantissa,
3221 const int64_t nBase2Exponent)
3222 {
3223 uint64_t uTag;
3224 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3225 uTag = CBOR_TAG_BIGFLOAT;
3226 } else {
3227 uTag = CBOR_TAG_INVALID64;
3228 }
3229 QCBOREncode_Private_AddExpMantissa(pMe,
3230 uTag,
3231 NULLUsefulBufC,
3232 false,
3233 nMantissa,
3234 nBase2Exponent);
3235 }
3236
3237 static inline void
QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,const int64_t nMantissa,const int64_t nBase2Exponent)3238 QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pMe,
3239 const char *szLabel,
3240 const uint8_t uTagRequirement,
3241 const int64_t nMantissa,
3242 const int64_t nBase2Exponent)
3243 {
3244 QCBOREncode_AddSZString(pMe, szLabel);
3245 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
3246 }
3247
3248 static inline void
QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,const int64_t nMantissa,const int64_t nBase2Exponent)3249 QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pMe,
3250 const int64_t nLabel,
3251 const uint8_t uTagRequirement,
3252 const int64_t nMantissa,
3253 const int64_t nBase2Exponent)
3254 {
3255 QCBOREncode_AddInt64(pMe, nLabel);
3256 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
3257 }
3258
3259 static inline void
QCBOREncode_AddBigFloat(QCBOREncodeContext * pMe,const int64_t nMantissa,const int64_t nBase2Exponent)3260 QCBOREncode_AddBigFloat(QCBOREncodeContext *pMe,
3261 const int64_t nMantissa,
3262 const int64_t nBase2Exponent)
3263 {
3264 QCBOREncode_AddTBigFloat(pMe,
3265 QCBOR_ENCODE_AS_TAG,
3266 nMantissa,
3267 nBase2Exponent);
3268 }
3269
3270 static inline void
QCBOREncode_AddBigFloatToMap(QCBOREncodeContext * pMe,const char * szLabel,const int64_t nMantissa,const int64_t nBase2Exponent)3271 QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pMe,
3272 const char *szLabel,
3273 const int64_t nMantissa,
3274 const int64_t nBase2Exponent)
3275 {
3276 QCBOREncode_AddTBigFloatToMapSZ(pMe,
3277 szLabel,
3278 QCBOR_ENCODE_AS_TAG,
3279 nMantissa,
3280 nBase2Exponent);
3281 }
3282
3283 static inline void
QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const int64_t nMantissa,const int64_t nBase2Exponent)3284 QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pMe,
3285 const int64_t nLabel,
3286 const int64_t nMantissa,
3287 const int64_t nBase2Exponent)
3288 {
3289 QCBOREncode_AddTBigFloatToMapN(pMe,
3290 nLabel,
3291 QCBOR_ENCODE_AS_TAG,
3292 nMantissa,
3293 nBase2Exponent);
3294 }
3295
3296
3297
3298 static inline void
QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext * pMe,const uint8_t uTagRequirement,const UsefulBufC Mantissa,const bool bIsNegative,const int64_t nBase2Exponent)3299 QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pMe,
3300 const uint8_t uTagRequirement,
3301 const UsefulBufC Mantissa,
3302 const bool bIsNegative,
3303 const int64_t nBase2Exponent)
3304 {
3305 uint64_t uTag;
3306 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3307 uTag = CBOR_TAG_BIGFLOAT;
3308 } else {
3309 uTag = CBOR_TAG_INVALID64;
3310 }
3311 QCBOREncode_Private_AddExpMantissa(pMe,
3312 uTag,
3313 Mantissa,
3314 bIsNegative,
3315 0,
3316 nBase2Exponent);
3317 }
3318
3319 static inline void
QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,const UsefulBufC Mantissa,const bool bIsNegative,const int64_t nBase2Exponent)3320 QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pMe,
3321 const char *szLabel,
3322 const uint8_t uTagRequirement,
3323 const UsefulBufC Mantissa,
3324 const bool bIsNegative,
3325 const int64_t nBase2Exponent)
3326 {
3327 QCBOREncode_AddSZString(pMe, szLabel);
3328 QCBOREncode_AddTBigFloatBigNum(pMe,
3329 uTagRequirement,
3330 Mantissa,
3331 bIsNegative,
3332 nBase2Exponent);
3333 }
3334
3335 static inline void
QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,const UsefulBufC Mantissa,const bool bIsNegative,const int64_t nBase2Exponent)3336 QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
3337 const int64_t nLabel,
3338 const uint8_t uTagRequirement,
3339 const UsefulBufC Mantissa,
3340 const bool bIsNegative,
3341 const int64_t nBase2Exponent)
3342 {
3343 QCBOREncode_AddInt64(pMe, nLabel);
3344 QCBOREncode_AddTBigFloatBigNum(pMe,
3345 uTagRequirement,
3346 Mantissa,
3347 bIsNegative,
3348 nBase2Exponent);
3349 }
3350
3351
3352 static inline void
QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext * pMe,const UsefulBufC Mantissa,const bool bIsNegative,const int64_t nBase2Exponent)3353 QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pMe,
3354 const UsefulBufC Mantissa,
3355 const bool bIsNegative,
3356 const int64_t nBase2Exponent)
3357 {
3358 QCBOREncode_AddTBigFloatBigNum(pMe,
3359 QCBOR_ENCODE_AS_TAG,
3360 Mantissa, bIsNegative,
3361 nBase2Exponent);
3362 }
3363
3364 static inline void
QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext * pMe,const char * szLabel,const UsefulBufC Mantissa,const bool bIsNegative,const int64_t nBase2Exponent)3365 QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pMe,
3366 const char *szLabel,
3367 const UsefulBufC Mantissa,
3368 const bool bIsNegative,
3369 const int64_t nBase2Exponent)
3370 {
3371 QCBOREncode_AddTBigFloatBigNumToMapSZ(pMe,
3372 szLabel,
3373 QCBOR_ENCODE_AS_TAG,
3374 Mantissa,
3375 bIsNegative,
3376 nBase2Exponent);
3377 }
3378
3379 static inline void
QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const UsefulBufC Mantissa,const bool bIsNegative,const int64_t nBase2Exponent)3380 QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
3381 const int64_t nLabel,
3382 const UsefulBufC Mantissa,
3383 const bool bIsNegative,
3384 const int64_t nBase2Exponent)
3385 {
3386 QCBOREncode_AddTBigFloatBigNumToMapN(pMe,
3387 nLabel,
3388 QCBOR_ENCODE_AS_TAG,
3389 Mantissa,
3390 bIsNegative,
3391 nBase2Exponent);
3392 }
3393 #endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
3394
3395
3396 static inline void
QCBOREncode_AddTURI(QCBOREncodeContext * pMe,const uint8_t uTagRequirement,const UsefulBufC URI)3397 QCBOREncode_AddTURI(QCBOREncodeContext *pMe,
3398 const uint8_t uTagRequirement,
3399 const UsefulBufC URI)
3400 {
3401 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3402 QCBOREncode_AddTag(pMe, CBOR_TAG_URI);
3403 }
3404 QCBOREncode_AddText(pMe, URI);
3405 }
3406
3407 static inline void
QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,const UsefulBufC URI)3408 QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pMe,
3409 const char *szLabel,
3410 const uint8_t uTagRequirement,
3411 const UsefulBufC URI)
3412 {
3413 QCBOREncode_AddSZString(pMe, szLabel);
3414 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
3415 }
3416
3417 static inline void
QCBOREncode_AddTURIToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,const UsefulBufC URI)3418 QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pMe,
3419 const int64_t nLabel,
3420 const uint8_t uTagRequirement,
3421 const UsefulBufC URI)
3422 {
3423 QCBOREncode_AddInt64(pMe, nLabel);
3424 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
3425 }
3426
3427 static inline void
QCBOREncode_AddURI(QCBOREncodeContext * pMe,const UsefulBufC URI)3428 QCBOREncode_AddURI(QCBOREncodeContext *pMe, const UsefulBufC URI)
3429 {
3430 QCBOREncode_AddTURI(pMe, QCBOR_ENCODE_AS_TAG, URI);
3431 }
3432
3433 static inline void
QCBOREncode_AddURIToMap(QCBOREncodeContext * pMe,const char * szLabel,const UsefulBufC URI)3434 QCBOREncode_AddURIToMap(QCBOREncodeContext *pMe,
3435 const char *szLabel,
3436 const UsefulBufC URI)
3437 {
3438 QCBOREncode_AddTURIToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, URI);
3439 }
3440
3441 static inline void
QCBOREncode_AddURIToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const UsefulBufC URI)3442 QCBOREncode_AddURIToMapN(QCBOREncodeContext *pMe,
3443 const int64_t nLabel,
3444 const UsefulBufC URI)
3445 {
3446 QCBOREncode_AddTURIToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, URI);
3447 }
3448
3449
3450
3451 static inline void
QCBOREncode_AddTB64Text(QCBOREncodeContext * pMe,const uint8_t uTagRequirement,const UsefulBufC B64Text)3452 QCBOREncode_AddTB64Text(QCBOREncodeContext *pMe,
3453 const uint8_t uTagRequirement,
3454 const UsefulBufC B64Text)
3455 {
3456 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3457 QCBOREncode_AddTag(pMe, CBOR_TAG_B64);
3458 }
3459 QCBOREncode_AddText(pMe, B64Text);
3460 }
3461
3462 static inline void
QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,const UsefulBufC B64Text)3463 QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pMe,
3464 const char *szLabel,
3465 const uint8_t uTagRequirement,
3466 const UsefulBufC B64Text)
3467 {
3468 QCBOREncode_AddSZString(pMe, szLabel);
3469 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
3470 }
3471
3472 static inline void
QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,const UsefulBufC B64Text)3473 QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pMe,
3474 const int64_t nLabel,
3475 const uint8_t uTagRequirement,
3476 const UsefulBufC B64Text)
3477 {
3478 QCBOREncode_AddInt64(pMe, nLabel);
3479 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
3480 }
3481
3482 static inline void
QCBOREncode_AddB64Text(QCBOREncodeContext * pMe,const UsefulBufC B64Text)3483 QCBOREncode_AddB64Text(QCBOREncodeContext *pMe, const UsefulBufC B64Text)
3484 {
3485 QCBOREncode_AddTB64Text(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
3486 }
3487
3488 static inline void
QCBOREncode_AddB64TextToMap(QCBOREncodeContext * pMe,const char * szLabel,const UsefulBufC B64Text)3489 QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pMe,
3490 const char *szLabel,
3491 const UsefulBufC B64Text)
3492 {
3493 QCBOREncode_AddTB64TextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
3494 }
3495
3496 static inline void
QCBOREncode_AddB64TextToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const UsefulBufC B64Text)3497 QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pMe,
3498 const int64_t nLabel,
3499 const UsefulBufC B64Text)
3500 {
3501 QCBOREncode_AddTB64TextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
3502 }
3503
3504
3505
3506 static inline void
QCBOREncode_AddTB64URLText(QCBOREncodeContext * pMe,const uint8_t uTagRequirement,const UsefulBufC B64Text)3507 QCBOREncode_AddTB64URLText(QCBOREncodeContext *pMe,
3508 const uint8_t uTagRequirement,
3509 const UsefulBufC B64Text)
3510 {
3511 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3512 QCBOREncode_AddTag(pMe, CBOR_TAG_B64URL);
3513 }
3514 QCBOREncode_AddText(pMe, B64Text);
3515 }
3516
3517 static inline void
QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,const UsefulBufC B64Text)3518 QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pMe,
3519 const char *szLabel,
3520 const uint8_t uTagRequirement,
3521 const UsefulBufC B64Text)
3522 {
3523 QCBOREncode_AddSZString(pMe, szLabel);
3524 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
3525 }
3526
3527 static inline void
QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,const UsefulBufC B64Text)3528 QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pMe,
3529 const int64_t nLabel,
3530 const uint8_t uTagRequirement,
3531 const UsefulBufC B64Text)
3532 {
3533 QCBOREncode_AddInt64(pMe, nLabel);
3534 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
3535 }
3536
3537 static inline void
QCBOREncode_AddB64URLText(QCBOREncodeContext * pMe,const UsefulBufC B64Text)3538 QCBOREncode_AddB64URLText(QCBOREncodeContext *pMe, const UsefulBufC B64Text)
3539 {
3540 QCBOREncode_AddTB64URLText(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
3541 }
3542
3543 static inline void
QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext * pMe,const char * szLabel,const UsefulBufC B64Text)3544 QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pMe,
3545 const char *szLabel,
3546 const UsefulBufC B64Text)
3547 {
3548 QCBOREncode_AddTB64URLTextToMapSZ(pMe,
3549 szLabel,
3550 QCBOR_ENCODE_AS_TAG,
3551 B64Text);
3552 }
3553
3554 static inline void
QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const UsefulBufC B64Text)3555 QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pMe,
3556 const int64_t nLabel,
3557 const UsefulBufC B64Text)
3558 {
3559 QCBOREncode_AddTB64URLTextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
3560 }
3561
3562
3563
3564 static inline void
QCBOREncode_AddTRegex(QCBOREncodeContext * pMe,const uint8_t uTagRequirement,const UsefulBufC Bytes)3565 QCBOREncode_AddTRegex(QCBOREncodeContext *pMe,
3566 const uint8_t uTagRequirement,
3567 const UsefulBufC Bytes)
3568 {
3569 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3570 QCBOREncode_AddTag(pMe, CBOR_TAG_REGEX);
3571 }
3572 QCBOREncode_AddText(pMe, Bytes);
3573 }
3574
3575 static inline void
QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,const UsefulBufC Bytes)3576 QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pMe,
3577 const char *szLabel,
3578 const uint8_t uTagRequirement,
3579 const UsefulBufC Bytes)
3580 {
3581 QCBOREncode_AddSZString(pMe, szLabel);
3582 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
3583 }
3584
3585 static inline void
QCBOREncode_AddTRegexToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,const UsefulBufC Bytes)3586 QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pMe,
3587 const int64_t nLabel,
3588 const uint8_t uTagRequirement,
3589 const UsefulBufC Bytes)
3590 {
3591 QCBOREncode_AddInt64(pMe, nLabel);
3592 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
3593 }
3594
3595 static inline void
QCBOREncode_AddRegex(QCBOREncodeContext * pMe,const UsefulBufC Bytes)3596 QCBOREncode_AddRegex(QCBOREncodeContext *pMe, const UsefulBufC Bytes)
3597 {
3598 QCBOREncode_AddTRegex(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
3599 }
3600
3601 static inline void
QCBOREncode_AddRegexToMap(QCBOREncodeContext * pMe,const char * szLabel,const UsefulBufC Bytes)3602 QCBOREncode_AddRegexToMap(QCBOREncodeContext *pMe,
3603 const char *szLabel,
3604 const UsefulBufC Bytes)
3605 {
3606 QCBOREncode_AddTRegexToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
3607 }
3608
3609 static inline void
QCBOREncode_AddRegexToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const UsefulBufC Bytes)3610 QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pMe,
3611 const int64_t nLabel,
3612 const UsefulBufC Bytes)
3613 {
3614 QCBOREncode_AddTRegexToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
3615
3616 }
3617
3618
3619 static inline void
QCBOREncode_AddTMIMEData(QCBOREncodeContext * pMe,const uint8_t uTagRequirement,const UsefulBufC MIMEData)3620 QCBOREncode_AddTMIMEData(QCBOREncodeContext *pMe,
3621 const uint8_t uTagRequirement,
3622 const UsefulBufC MIMEData)
3623 {
3624 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3625 QCBOREncode_AddTag(pMe, CBOR_TAG_BINARY_MIME);
3626 }
3627 QCBOREncode_AddBytes(pMe, MIMEData);
3628 }
3629
3630 static inline void
QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,const UsefulBufC MIMEData)3631 QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pMe,
3632 const char *szLabel,
3633 const uint8_t uTagRequirement,
3634 const UsefulBufC MIMEData)
3635 {
3636 QCBOREncode_AddSZString(pMe, szLabel);
3637 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
3638 }
3639
3640 static inline void
QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,const UsefulBufC MIMEData)3641 QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pMe,
3642 const int64_t nLabel,
3643 const uint8_t uTagRequirement,
3644 const UsefulBufC MIMEData)
3645 {
3646 QCBOREncode_AddInt64(pMe, nLabel);
3647 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
3648 }
3649
3650 static inline void
QCBOREncode_AddMIMEData(QCBOREncodeContext * pMe,UsefulBufC MIMEData)3651 QCBOREncode_AddMIMEData(QCBOREncodeContext *pMe, UsefulBufC MIMEData)
3652 {
3653 QCBOREncode_AddTMIMEData(pMe, QCBOR_ENCODE_AS_TAG, MIMEData);
3654 }
3655
3656 static inline void
QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext * pMe,const char * szLabel,const UsefulBufC MIMEData)3657 QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pMe,
3658 const char *szLabel,
3659 const UsefulBufC MIMEData)
3660 {
3661 QCBOREncode_AddTMIMEDataToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
3662 }
3663
3664 static inline void
QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const UsefulBufC MIMEData)3665 QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pMe,
3666 const int64_t nLabel,
3667 const UsefulBufC MIMEData)
3668 {
3669 QCBOREncode_AddTMIMEDataToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
3670 }
3671
3672
3673 static inline void
QCBOREncode_AddTDateString(QCBOREncodeContext * pMe,const uint8_t uTagRequirement,const char * szDate)3674 QCBOREncode_AddTDateString(QCBOREncodeContext *pMe,
3675 const uint8_t uTagRequirement,
3676 const char *szDate)
3677 {
3678 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3679 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_STRING);
3680 }
3681 QCBOREncode_AddSZString(pMe, szDate);
3682 }
3683
3684 static inline void
QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,const char * szDate)3685 QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pMe,
3686 const char *szLabel,
3687 const uint8_t uTagRequirement,
3688 const char *szDate)
3689 {
3690 QCBOREncode_AddSZString(pMe, szLabel);
3691 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
3692 }
3693
3694 static inline void
QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,const char * szDate)3695 QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pMe,
3696 const int64_t nLabel,
3697 const uint8_t uTagRequirement,
3698 const char *szDate)
3699 {
3700 QCBOREncode_AddInt64(pMe, nLabel);
3701 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
3702 }
3703
3704 static inline void
QCBOREncode_AddDateString(QCBOREncodeContext * pMe,const char * szDate)3705 QCBOREncode_AddDateString(QCBOREncodeContext *pMe, const char *szDate)
3706 {
3707 QCBOREncode_AddTDateString(pMe, QCBOR_ENCODE_AS_TAG, szDate);
3708 }
3709
3710 static inline void
QCBOREncode_AddDateStringToMap(QCBOREncodeContext * pMe,const char * szLabel,const char * szDate)3711 QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pMe,
3712 const char *szLabel,
3713 const char *szDate)
3714 {
3715 QCBOREncode_AddTDateStringToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, szDate);
3716 }
3717
3718 static inline void
QCBOREncode_AddDateStringToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const char * szDate)3719 QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pMe,
3720 const int64_t nLabel,
3721 const char *szDate)
3722 {
3723 QCBOREncode_AddTDateStringToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, szDate);
3724 }
3725
3726
3727 static inline void
QCBOREncode_AddTDaysString(QCBOREncodeContext * pMe,const uint8_t uTagRequirement,const char * szDate)3728 QCBOREncode_AddTDaysString(QCBOREncodeContext *pMe,
3729 const uint8_t uTagRequirement,
3730 const char *szDate)
3731 {
3732 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3733 QCBOREncode_AddTag(pMe, CBOR_TAG_DAYS_STRING);
3734 }
3735 QCBOREncode_AddSZString(pMe, szDate);
3736 }
3737
3738 static inline void
QCBOREncode_AddTDaysStringToMapSZ(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,const char * szDate)3739 QCBOREncode_AddTDaysStringToMapSZ(QCBOREncodeContext *pMe,
3740 const char *szLabel,
3741 const uint8_t uTagRequirement,
3742 const char *szDate)
3743 {
3744 QCBOREncode_AddSZString(pMe, szLabel);
3745 QCBOREncode_AddTDaysString(pMe, uTagRequirement, szDate);
3746 }
3747
3748 static inline void
QCBOREncode_AddTDaysStringToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,const char * szDate)3749 QCBOREncode_AddTDaysStringToMapN(QCBOREncodeContext *pMe,
3750 const int64_t nLabel,
3751 const uint8_t uTagRequirement,
3752 const char *szDate)
3753 {
3754 QCBOREncode_AddInt64(pMe, nLabel);
3755 QCBOREncode_AddTDaysString(pMe, uTagRequirement, szDate);
3756 }
3757
3758
3759 static inline void
QCBOREncode_AddSimple(QCBOREncodeContext * pMe,const uint8_t uNum)3760 QCBOREncode_AddSimple(QCBOREncodeContext *pMe, const uint8_t uNum)
3761 {
3762 /* This check often is optimized out because uNum is known at compile time. */
3763 #ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
3764 if(uNum >= CBOR_SIMPLEV_RESERVED_START && uNum <= CBOR_SIMPLEV_RESERVED_END) {
3765 pMe->uError = QCBOR_ERR_ENCODE_UNSUPPORTED;
3766 return;
3767 }
3768 #endif /* !QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
3769
3770 QCBOREncode_Private_AddType7(pMe, 0, uNum);
3771 }
3772
3773 static inline void
QCBOREncode_AddSimpleToMap(QCBOREncodeContext * pMe,const char * szLabel,const uint8_t uSimple)3774 QCBOREncode_AddSimpleToMap(QCBOREncodeContext *pMe,
3775 const char *szLabel,
3776 const uint8_t uSimple)
3777 {
3778 QCBOREncode_AddSZString(pMe, szLabel);
3779 QCBOREncode_AddSimple(pMe, uSimple);
3780 }
3781
3782 static inline void
QCBOREncode_AddSimpleToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const uint8_t uSimple)3783 QCBOREncode_AddSimpleToMapN(QCBOREncodeContext *pMe,
3784 const int64_t nLabel,
3785 const uint8_t uSimple)
3786 {
3787 QCBOREncode_AddInt64(pMe, nLabel);
3788 QCBOREncode_AddSimple(pMe, uSimple);
3789 }
3790
3791
3792 static inline void
QCBOREncode_AddBool(QCBOREncodeContext * pMe,const bool b)3793 QCBOREncode_AddBool(QCBOREncodeContext *pMe, const bool b)
3794 {
3795 uint8_t uSimple = CBOR_SIMPLEV_FALSE;
3796 if(b) {
3797 uSimple = CBOR_SIMPLEV_TRUE;
3798 }
3799 QCBOREncode_AddSimple(pMe, uSimple);
3800 }
3801
3802 static inline void
QCBOREncode_AddBoolToMap(QCBOREncodeContext * pMe,const char * szLabel,const bool b)3803 QCBOREncode_AddBoolToMap(QCBOREncodeContext *pMe, const char *szLabel, const bool b)
3804 {
3805 QCBOREncode_AddSZString(pMe, szLabel);
3806 QCBOREncode_AddBool(pMe, b);
3807 }
3808
3809 static inline void
QCBOREncode_AddBoolToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const bool b)3810 QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pMe, const int64_t nLabel, const bool b)
3811 {
3812 QCBOREncode_AddInt64(pMe, nLabel);
3813 QCBOREncode_AddBool(pMe, b);
3814 }
3815
3816
3817 static inline void
QCBOREncode_AddNULL(QCBOREncodeContext * pMe)3818 QCBOREncode_AddNULL(QCBOREncodeContext *pMe)
3819 {
3820 QCBOREncode_AddSimple(pMe, CBOR_SIMPLEV_NULL);
3821 }
3822
3823 static inline void
QCBOREncode_AddNULLToMap(QCBOREncodeContext * pMe,const char * szLabel)3824 QCBOREncode_AddNULLToMap(QCBOREncodeContext *pMe, const char *szLabel)
3825 {
3826 QCBOREncode_AddSZString(pMe, szLabel);
3827 QCBOREncode_AddNULL(pMe);
3828 }
3829
3830 static inline void
QCBOREncode_AddNULLToMapN(QCBOREncodeContext * pMe,const int64_t nLabel)3831 QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
3832 {
3833 QCBOREncode_AddInt64(pMe, nLabel);
3834 QCBOREncode_AddNULL(pMe);
3835 }
3836
3837
3838 static inline void
QCBOREncode_AddUndef(QCBOREncodeContext * pMe)3839 QCBOREncode_AddUndef(QCBOREncodeContext *pMe)
3840 {
3841 QCBOREncode_AddSimple(pMe, CBOR_SIMPLEV_UNDEF);
3842 }
3843
3844 static inline void
QCBOREncode_AddUndefToMap(QCBOREncodeContext * pMe,const char * szLabel)3845 QCBOREncode_AddUndefToMap(QCBOREncodeContext *pMe, const char *szLabel)
3846 {
3847 QCBOREncode_AddSZString(pMe, szLabel);
3848 QCBOREncode_AddUndef(pMe);
3849 }
3850
3851 static inline void
QCBOREncode_AddUndefToMapN(QCBOREncodeContext * pMe,const int64_t nLabel)3852 QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
3853 {
3854 QCBOREncode_AddInt64(pMe, nLabel);
3855 QCBOREncode_AddUndef(pMe);
3856 }
3857
3858
3859 static inline void
QCBOREncode_OpenArray(QCBOREncodeContext * pMe)3860 QCBOREncode_OpenArray(QCBOREncodeContext *pMe)
3861 {
3862 QCBOREncode_Private_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
3863 }
3864
3865 static inline void
QCBOREncode_OpenArrayInMap(QCBOREncodeContext * pMe,const char * szLabel)3866 QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pMe, const char *szLabel)
3867 {
3868 QCBOREncode_AddSZString(pMe, szLabel);
3869 QCBOREncode_OpenArray(pMe);
3870 }
3871
3872 static inline void
QCBOREncode_OpenArrayInMapN(QCBOREncodeContext * pMe,const int64_t nLabel)3873 QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
3874 {
3875 QCBOREncode_AddInt64(pMe, nLabel);
3876 QCBOREncode_OpenArray(pMe);
3877 }
3878
3879 static inline void
QCBOREncode_CloseArray(QCBOREncodeContext * pMe)3880 QCBOREncode_CloseArray(QCBOREncodeContext *pMe)
3881 {
3882 QCBOREncode_Private_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
3883 }
3884
3885
3886 static inline void
QCBOREncode_OpenMap(QCBOREncodeContext * pMe)3887 QCBOREncode_OpenMap(QCBOREncodeContext *pMe)
3888 {
3889 QCBOREncode_Private_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
3890 }
3891
3892 static inline void
QCBOREncode_OpenMapInMap(QCBOREncodeContext * pMe,const char * szLabel)3893 QCBOREncode_OpenMapInMap(QCBOREncodeContext *pMe, const char *szLabel)
3894 {
3895 QCBOREncode_AddSZString(pMe, szLabel);
3896 QCBOREncode_OpenMap(pMe);
3897 }
3898
3899 static inline void
QCBOREncode_OpenMapInMapN(QCBOREncodeContext * pMe,const int64_t nLabel)3900 QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
3901 {
3902 QCBOREncode_AddInt64(pMe, nLabel);
3903 QCBOREncode_OpenMap(pMe);
3904 }
3905
3906 static inline void
QCBOREncode_CloseMap(QCBOREncodeContext * pMe)3907 QCBOREncode_CloseMap(QCBOREncodeContext *pMe)
3908 {
3909 QCBOREncode_Private_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
3910 }
3911
3912 static inline void
QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext * pMe)3913 QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pMe)
3914 {
3915 QCBOREncode_Private_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
3916 }
3917
3918 static inline void
QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext * pMe,const char * szLabel)3919 QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pMe,
3920 const char *szLabel)
3921 {
3922 QCBOREncode_AddSZString(pMe, szLabel);
3923 QCBOREncode_OpenArrayIndefiniteLength(pMe);
3924 }
3925
3926 static inline void
QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext * pMe,const int64_t nLabel)3927 QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pMe,
3928 const int64_t nLabel)
3929 {
3930 QCBOREncode_AddInt64(pMe, nLabel);
3931 QCBOREncode_OpenArrayIndefiniteLength(pMe);
3932 }
3933
3934 static inline void
QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext * pMe)3935 QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pMe)
3936 {
3937 QCBOREncode_Private_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
3938 }
3939
3940
3941 static inline void
QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext * pMe)3942 QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pMe)
3943 {
3944 QCBOREncode_Private_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
3945 }
3946
3947 static inline void
QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext * pMe,const char * szLabel)3948 QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pMe,
3949 const char *szLabel)
3950 {
3951 QCBOREncode_AddSZString(pMe, szLabel);
3952 QCBOREncode_OpenMapIndefiniteLength(pMe);
3953 }
3954
3955 static inline void
QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext * pMe,const int64_t nLabel)3956 QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pMe,
3957 const int64_t nLabel)
3958 {
3959 QCBOREncode_AddInt64(pMe, nLabel);
3960 QCBOREncode_OpenMapIndefiniteLength(pMe);
3961 }
3962
3963 static inline void
QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext * pMe)3964 QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pMe)
3965 {
3966 QCBOREncode_Private_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
3967 }
3968
3969
3970 static inline void
QCBOREncode_BstrWrap(QCBOREncodeContext * pMe)3971 QCBOREncode_BstrWrap(QCBOREncodeContext *pMe)
3972 {
3973 QCBOREncode_Private_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_BYTE_STRING);
3974 }
3975
3976 static inline void
QCBOREncode_BstrWrapInMap(QCBOREncodeContext * pMe,const char * szLabel)3977 QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pMe, const char *szLabel)
3978 {
3979 QCBOREncode_AddSZString(pMe, szLabel);
3980 QCBOREncode_BstrWrap(pMe);
3981 }
3982
3983 static inline void
QCBOREncode_BstrWrapInMapN(QCBOREncodeContext * pMe,const int64_t nLabel)3984 QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pMe, const int64_t nLabel)
3985 {
3986 QCBOREncode_AddInt64(pMe, nLabel);
3987 QCBOREncode_BstrWrap(pMe);
3988 }
3989
3990 static inline void
QCBOREncode_CloseBstrWrap(QCBOREncodeContext * pMe,UsefulBufC * pWrappedCBOR)3991 QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pMe, UsefulBufC *pWrappedCBOR)
3992 {
3993 QCBOREncode_CloseBstrWrap2(pMe, true, pWrappedCBOR);
3994 }
3995
3996
3997
3998 static inline void
QCBOREncode_AddEncodedToMap(QCBOREncodeContext * pMe,const char * szLabel,const UsefulBufC Encoded)3999 QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pMe,
4000 const char *szLabel,
4001 const UsefulBufC Encoded)
4002 {
4003 QCBOREncode_AddSZString(pMe, szLabel);
4004 QCBOREncode_AddEncoded(pMe, Encoded);
4005 }
4006
4007 static inline void
QCBOREncode_AddEncodedToMapN(QCBOREncodeContext * pMe,const int64_t nLabel,const UsefulBufC Encoded)4008 QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pMe,
4009 const int64_t nLabel,
4010 const UsefulBufC Encoded)
4011 {
4012 QCBOREncode_AddInt64(pMe, nLabel);
4013 QCBOREncode_AddEncoded(pMe, Encoded);
4014 }
4015
4016
4017 static inline int
QCBOREncode_IsBufferNULL(QCBOREncodeContext * pMe)4018 QCBOREncode_IsBufferNULL(QCBOREncodeContext *pMe)
4019 {
4020 return UsefulOutBuf_IsBufferNULL(&(pMe->OutBuf));
4021 }
4022
4023 static inline QCBORError
QCBOREncode_GetErrorState(QCBOREncodeContext * pMe)4024 QCBOREncode_GetErrorState(QCBOREncodeContext *pMe)
4025 {
4026 if(UsefulOutBuf_GetError(&(pMe->OutBuf))) {
4027 /* Items didn't fit in the buffer. This check catches this
4028 * condition for all the appends and inserts so checks aren't
4029 * needed when the appends and inserts are performed. And of
4030 * course UsefulBuf will never overrun the input buffer given to
4031 * it. No complex analysis of the error handling in this file is
4032 * needed to know that is true. Just read the UsefulBuf code.
4033 */
4034 pMe->uError = QCBOR_ERR_BUFFER_TOO_SMALL;
4035 /* QCBOR_ERR_BUFFER_TOO_SMALL masks other errors, but that is
4036 * OK. Once the caller fixes this, they'll be unmasked.
4037 */
4038 }
4039
4040 return (QCBORError)pMe->uError;
4041 }
4042
4043
4044 /* ========================================================================
4045 END OF PRIVATE INLINE IMPLEMENTATION
4046 ======================================================================== */
4047
4048 #ifdef __cplusplus
4049 }
4050 #endif
4051
4052 #endif /* qcbor_encode_h */
4053