blob: 99786dd58da3c5d8143b8b88ba89c55400d5f56e [file] [log] [blame]
Michael Eckel5c531332020-03-02 01:35:30 +01001/*==============================================================================
2 Copyright (c) 2016-2018, The Linux Foundation.
Laurence Lundbladed6e13022023-11-26 10:14:02 -07003 Copyright (c) 2018-2023, Laurence Lundblade.
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +02004 Copyright (c) 2021, Arm Limited.
Michael Eckel5c531332020-03-02 01:35:30 +01005 All rights reserved.
6
7Redistribution and use in source and binary forms, with or without
8modification, are permitted provided that the following conditions are
9met:
10 * Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above
13 copyright notice, this list of conditions and the following
14 disclaimer in the documentation and/or other materials provided
15 with the distribution.
16 * Neither the name of The Linux Foundation nor the names of its
17 contributors, nor the name "Laurence Lundblade" may be used to
18 endorse or promote products derived from this software without
19 specific prior written permission.
20
21THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
22WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
24ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
25BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
30OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
31IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 =============================================================================*/
33
34
Laurence Lundblade844bb5c2020-03-01 17:27:25 -080035#ifndef qcbor_encode_h
36#define qcbor_encode_h
Michael Eckel5c531332020-03-02 01:35:30 +010037
38
Laurence Lundblade844bb5c2020-03-01 17:27:25 -080039#include "qcbor/qcbor_common.h"
40#include "qcbor/qcbor_private.h"
Michael Eckel5c531332020-03-02 01:35:30 +010041#include <stdbool.h>
Laurence Lundblade844bb5c2020-03-01 17:27:25 -080042
Michael Eckel5c531332020-03-02 01:35:30 +010043
44#ifdef __cplusplus
45extern "C" {
Dave Thaler12b23752020-03-27 01:23:08 -070046#if 0
Michael Eckel5c531332020-03-02 01:35:30 +010047} // Keep editor indention formatting happy
48#endif
49#endif
50
Michael Eckel5c531332020-03-02 01:35:30 +010051
52/**
Laurence Lundblade844bb5c2020-03-01 17:27:25 -080053 @file qcbor_encode.h
Michael Eckel5c531332020-03-02 01:35:30 +010054
Laurence Lundblade9a3b6252020-10-21 21:30:31 -070055 @anchor Overview
56
57 # QCBOR Overview
Michael Eckel5c531332020-03-02 01:35:30 +010058
59 This implements CBOR -- Concise Binary Object Representation as
Laurence Lundbladec02e13e2020-12-06 05:45:41 -080060 defined in [RFC 8949] (https://tools.ietf.org/html/rfc8949). More
Laurence Lundblade18e1d522020-10-22 02:18:41 -070061 information is at http://cbor.io. This is a near-complete implementation of
62 the specification. [RFC 8742] (https://tools.ietf.org/html/rfc8742) CBOR
63 Sequences is also supported. Limitations are listed further down.
Michael Eckel5c531332020-03-02 01:35:30 +010064
Laurence Lundblade9a3b6252020-10-21 21:30:31 -070065 See @ref Encoding for general discussion on encoding,
66 @ref BasicDecode for general discussion on the basic decode features
67 and @ref SpiffyDecode for general discussion on the easier-to-use
68 decoder functions.
69
Michael Eckel5c531332020-03-02 01:35:30 +010070 CBOR is intentionally designed to be translatable to JSON, but not
Laurence Lundbladec02e13e2020-12-06 05:45:41 -080071 all CBOR can convert to JSON. See RFC 8949 for more info on how to
Michael Eckel5c531332020-03-02 01:35:30 +010072 construct CBOR that is the most JSON friendly.
73
74 The memory model for encoding and decoding is that encoded CBOR must
75 be in a contiguous buffer in memory. During encoding the caller must
76 supply an output buffer and if the encoding would go off the end of
77 the buffer an error is returned. During decoding the caller supplies
78 the encoded CBOR in a contiguous buffer and the decoder returns
79 pointers and lengths into that buffer for strings.
80
81 This implementation does not require malloc. All data structures
82 passed in/out of the APIs can fit on the stack.
83
84 Decoding of indefinite-length strings is a special case that requires
85 a "string allocator" to allocate memory into which the segments of
86 the string are coalesced. Without this, decoding will error out if an
87 indefinite-length string is encountered (indefinite-length maps and
88 arrays do not require the string allocator). A simple string
89 allocator called MemPool is built-in and will work if supplied with a
90 block of memory to allocate. The string allocator can optionally use
91 malloc() or some other custom scheme.
92
93 Here are some terms and definitions:
94
95 - "Item", "Data Item": An integer or string or such. The basic "thing" that
96 CBOR is about. An array is an item itself that contains some items.
97
98 - "Array": An ordered sequence of items, the same as JSON.
99
100 - "Map": A collection of label/value pairs. Each pair is a data
101 item. A JSON "object" is the same as a CBOR "map".
102
103 - "Label": The data item in a pair in a map that names or identifies
104 the pair, not the value. This implementation refers to it as a
105 "label". JSON refers to it as the "name". The CBOR RFC refers to it
106 this as a "key". This implementation chooses label instead because
107 key is too easily confused with a cryptographic key. The COSE
108 standard, which uses CBOR, has also chosen to use the term "label"
109 rather than "key" for this same reason.
110
111 - "Key": See "Label" above.
112
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700113 - "Tag": A data item that is an explicitly labeled new data
114 type made up of the tagging integer and the tag content.
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700115 See @ref Tags-Overview and @ref Tag-Usage.
Michael Eckel5c531332020-03-02 01:35:30 +0100116
117 - "Initial Byte": The first byte of an encoded item. Encoding and
118 decoding of this byte is taken care of by the implementation.
119
120 - "Additional Info": In addition to the major type, all data items
121 have some other info. This is usually the length of the data but can
122 be several other things. Encoding and decoding of this is taken care
123 of by the implementation.
124
125 CBOR has two mechanisms for tagging and labeling the data values like
126 integers and strings. For example, an integer that represents
127 someone's birthday in epoch seconds since Jan 1, 1970 could be
128 encoded like this:
129
130 - First it is CBOR_MAJOR_TYPE_POSITIVE_INT (@ref QCBOR_TYPE_INT64),
131 the primitive positive integer.
132
133 - Next it has a "tag" @ref CBOR_TAG_DATE_EPOCH indicating the integer
134 represents a date in the form of the number of seconds since Jan 1,
135 1970.
136
137 - Last it has a string "label" like "BirthDate" indicating the
138 meaning of the data.
139
140 The encoded binary looks like this:
141
142 a1 # Map of 1 item
143 69 # Indicates text string of 9 bytes
144 426972746844617465 # The text "BirthDate"
145 c1 # Tags next integer as epoch date
146 1a # Indicates a 4-byte integer
147 580d4172 # unsigned integer date 1477263730
148
149 Implementors using this API will primarily work with
150 labels. Generally, tags are only needed for making up new data
151 types. This implementation covers most of the data types defined in
152 the RFC using tags. It also, allows for the use of custom tags if
153 necessary.
154
155 This implementation explicitly supports labels that are text strings
156 and integers. Text strings translate nicely into JSON objects and are
157 very readable. Integer labels are much less readable but can be very
158 compact. If they are in the range of 0 to 23, they take up only one
159 byte.
160
161 CBOR allows a label to be any type of data including an array or a
162 map. It is possible to use this API to construct and parse such
163 labels, but it is not explicitly supported.
164
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700165 @anchor Encoding
166
167 ## Encoding
168
Michael Eckel5c531332020-03-02 01:35:30 +0100169 A common encoding usage mode is to invoke the encoding twice. First
Laurence Lundblade8ece3732021-09-21 21:47:23 -0700170 with the output buffer as @ref SizeCalculateUsefulBuf to compute the
171 length of the needed output buffer. The correct sized output buffer
172 is allocated. The encoder is invoked a second time with the allocated
173 output buffer.
Michael Eckel5c531332020-03-02 01:35:30 +0100174
175 The double invocation is not required if the maximum output buffer
176 size can be predicted. This is usually possible for simple CBOR
Laurence Lundblade8ece3732021-09-21 21:47:23 -0700177 structures.
Michael Eckel5c531332020-03-02 01:35:30 +0100178
179 If a buffer too small to hold the encoded output is given, the error
180 @ref QCBOR_ERR_BUFFER_TOO_SMALL will be returned. Data will never be
181 written off the end of the output buffer no matter which functions
182 here are called or what parameters are passed to them.
183
184 The encoding error handling is simple. The only possible errors are
185 trying to encode structures that are too large or too complex. There
186 are no internal malloc calls so there will be no failures for out of
187 memory. The error state is tracked internally, so there is no need
188 to check for errors when encoding. Only the return code from
189 QCBOREncode_Finish() need be checked as once an error happens, the
190 encoder goes into an error state and calls to it to add more data
191 will do nothing. An error check is not needed after every data item
192 is added.
193
194 Encoding generally proceeds by calling QCBOREncode_Init(), calling
195 lots of @c QCBOREncode_AddXxx() functions and calling
196 QCBOREncode_Finish(). There are many @c QCBOREncode_AddXxx()
197 functions for various data types. The input buffers need only to be
198 valid during the @c QCBOREncode_AddXxx() calls as the data is copied
199 into the output buffer.
200
201 There are three `Add` functions for each data type. The first / main
202 one for the type is for adding the data item to an array. The second
203 one's name ends in `ToMap`, is used for adding data items to maps and
204 takes a string argument that is its label in the map. The third one
205 ends in `ToMapN`, is also used for adding data items to maps, and
206 takes an integer argument that is its label in the map.
207
208 The simplest aggregate type is an array, which is a simple ordered
209 set of items without labels the same as JSON arrays. Call
210 QCBOREncode_OpenArray() to open a new array, then various @c
211 QCBOREncode_AddXxx() functions to put items in the array and then
212 QCBOREncode_CloseArray(). Nesting to the limit @ref
213 QCBOR_MAX_ARRAY_NESTING is allowed. All opens must be matched by
214 closes or an encoding error will be returned.
215
216 The other aggregate type is a map which does use labels. The `Add`
217 functions that end in `ToMap` and `ToMapN` are convenient ways to add
218 labeled data items to a map. You can also call any type of `Add`
219 function once to add a label of any time and then call any type of
220 `Add` again to add its value.
221
222 Note that when you nest arrays or maps in a map, the nested array or
223 map has a label.
Laurence Lundblade2feb1e12020-07-15 03:50:45 -0700224
Laurence Lundbladee3553422020-05-02 11:11:17 -0700225 Many CBOR-based protocols start with an array or map. This makes them
226 self-delimiting. No external length or end marker is needed to know
227 the end. It is also possible not start this way, in which case this
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700228 it is usually called a CBOR sequence which is described in
229 [RFC 8742] (https://tools.ietf.org/html/rfc8742). This encoder supports
230 either just by whether the first item added is an array, map or other.
Michael Eckel5c531332020-03-02 01:35:30 +0100231
Laurence Lundbladeda97bf42020-11-05 03:38:50 -0800232 If QCBOR is compiled with QCBOR_DISABLE_ENCODE_USAGE_GUARDS defined,
233 the errors QCBOR_ERR_CLOSE_MISMATCH, QCBOR_ERR_ARRAY_TOO_LONG,
234 QCBOR_ERR_TOO_MANY_CLOSES, QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN, and
235 QCBOR_ERR_ENCODE_UNSUPPORTED will never be returned. It is up to the
236 caller to make sure that opened maps, arrays and byte-string wrapping
237 is closed correctly and that QCBOREncode_AddType7() is called
238 correctly. With this defined, it is easier to make a mistake when
239 authoring the encoding of a protocol that will output not well formed
240 CBOR, but as long as the calling code is correct, it is safe to
241 disable these checks. Bounds checking that prevents security issues
242 in the code is still enforced. This define reduces the size of
243 encoding object code by about 150 bytes.
244
Michael Eckel5c531332020-03-02 01:35:30 +0100245 @anchor Tags-Overview
Laurence Lundblade9b334962020-08-27 10:55:53 -0700246
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700247 ## Tags Overview
248
249 Any CBOR data item can be made into a tag to add semantics, define a
250 new data type or such. Some tags are fully standardized and some are
251 just registered. Others are not registered and used in a proprietary
252 way.
Michael Eckel5c531332020-03-02 01:35:30 +0100253
254 Encoding and decoding of many of the registered tags is fully
255 implemented by QCBOR. It is also possible to encode and decode tags
256 that are not directly supported. For many use cases the built-in tag
257 support should be adequate.
258
259 For example, the registered epoch date tag is supported in encoding
260 by QCBOREncode_AddDateEpoch() and in decoding by @ref
261 QCBOR_TYPE_DATE_EPOCH and the @c epochDate member of @ref
262 QCBORItem. This is typical of the built-in tag support. There is an
263 API to encode data for it and a @c QCBOR_TYPE_XXX when it is decoded.
264
265 Tags are registered in the [IANA CBOR Tags Registry]
266 (https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml). There
267 are roughly three options to create a new tag. First, a public
268 specification can be created and the new tag registered with IANA.
269 This is the most formal. Second, the new tag can be registered with
270 IANA with just a short description rather than a full specification.
271 These tags must be greater than 256. Third, a tag can be used without
272 any IANA registration, though the registry should be checked to see
273 that the new value doesn't collide with one that is registered. The
274 value of these tags must be 256 or larger.
275
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700276 See also @ref CBORTags and @ref Tag-Usage
277
Michael Eckel5c531332020-03-02 01:35:30 +0100278 The encoding side of tags not built-in is handled by
279 QCBOREncode_AddTag() and is relatively simple. Tag decoding is more
280 complex and mainly handled by QCBORDecode_GetNext(). Decoding of the
281 structure of tagged data not built-in (if there is any) has to be
282 implemented by the caller.
283
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700284 @anchor Floating-Point
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700285
286 ## Floating-Point
287
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700288 By default QCBOR fully supports IEEE 754 floating-point:
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700289 - Encode/decode of double, single and half-precision
290 - CBOR preferred serialization of floating-point
291 - Floating-point epoch dates
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700292
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700293 For the most part, the type double is used in the interface for
294 floating-point values. In the default configuration, all decoded
295 floating-point values are returned as a double.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700296
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700297 With CBOR preferred serialization, the encoder outputs the smallest
298 representation of the double or float that preserves precision. Zero,
299 NaN and infinity are always output as a half-precision, each taking
300 just 2 bytes. This reduces the number of bytes needed to encode
Laurence Lundblade4b270642020-08-14 12:53:07 -0700301 double and single-precision, especially if zero, NaN and infinity are
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700302 frequently used.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700303
Laurence Lundblade4b270642020-08-14 12:53:07 -0700304 To avoid use of preferred serialization in the standard configuration
305 when encoding, use QCBOREncode_AddDoubleNoPreferred() or
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700306 QCBOREncode_AddFloatNoPreferred().
307
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700308 This implementation of preferred floating-point serialization and
309 half-precision does not depend on the CPU having floating-point HW or
310 the compiler bringing in a (sometimes large) library to compensate
Laurence Lundblade4b270642020-08-14 12:53:07 -0700311 for lack of CPU support. This implementation uses shifts and masks
312 rather than floating-point functions.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700313
Laurence Lundblade4b270642020-08-14 12:53:07 -0700314 To reduce overall object code by about 900 bytes, define
315 QCBOR_DISABLE_PREFERRED_FLOAT. This will eliminate all support for
316 preferred serialization and half-precision. An error will be returned
317 when attempting to decode half-precision. A float will always be
318 encoded and decoded as 32-bits and a double will always be encoded
319 and decoded as 64 bits.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700320
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700321 Note that even if QCBOR_DISABLE_PREFERRED_FLOAT is not defined all
322 the float-point encoding object code can be avoided by never calling
Laurence Lundbladefe09bbf2020-07-16 12:14:51 -0700323 any functions that encode double or float. Just not calling
324 floating-point functions will reduce object code by about 500 bytes.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700325
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700326 On CPUs that have no floating-point hardware,
327 QCBOR_DISABLE_FLOAT_HW_USE should be defined in most cases. If it is
328 not, then the compiler will bring in possibly large software
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700329 libraries to compensate. Defining QCBOR_DISABLE_FLOAT_HW_USE reduces
330 object code size on CPUs with floating-point hardware by a tiny
331 amount and eliminates the need for <math.h>
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700332
Laurence Lundblade4b270642020-08-14 12:53:07 -0700333 When QCBOR_DISABLE_FLOAT_HW_USE is defined, trying to decoding
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700334 floating-point dates will give error
335 @ref QCBOR_ERR_FLOAT_DATE_DISABLED and decoded single-precision
336 numbers will be returned as @ref QCBOR_TYPE_FLOAT instead of
337 converting them to double as usual.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700338
339 If both QCBOR_DISABLE_FLOAT_HW_USE and QCBOR_DISABLE_PREFERRED_FLOAT
Laurence Lundblade4b270642020-08-14 12:53:07 -0700340 are defined, then the only thing QCBOR can do is encode/decode a C
341 float type as 32-bits and a C double type as 64-bits. Floating-point
342 epoch dates will be unsupported.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700343
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200344 If USEFULBUF_DISABLE_ALL_FLOATis defined, then floating point support is
345 completely disabled. Decoding functions return @ref QCBOR_ERR_ALL_FLOAT_DISABLED
346 if a floating point value is encountered during decoding. Functions that are
347 encoding floating point values are not available.
348
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700349 ## Limitations
350
Michael Eckel5c531332020-03-02 01:35:30 +0100351 Summary Limits of this implementation:
352 - The entire encoded CBOR must fit into contiguous memory.
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700353 - Max size of encoded / decoded CBOR data is a few bytes less than @c UINT32_MAX (4GB).
Michael Eckel5c531332020-03-02 01:35:30 +0100354 - Max array / map nesting level when encoding / decoding is
355 @ref QCBOR_MAX_ARRAY_NESTING (this is typically 15).
356 - Max items in an array or map when encoding / decoding is
357 @ref QCBOR_MAX_ITEMS_IN_ARRAY (typically 65,536).
358 - Does not directly support labels in maps other than text strings & integers.
359 - Does not directly support integer labels greater than @c INT64_MAX.
360 - Epoch dates limited to @c INT64_MAX (+/- 292 billion years).
361 - Exponents for bigfloats and decimal integers are limited to @c INT64_MAX.
362 - Tags on labels are ignored during decoding.
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700363 - The maximum tag nesting is @c QCBOR_MAX_TAGS_PER_ITEM (typically 4).
Michael Eckel5c531332020-03-02 01:35:30 +0100364 - Works only on 32- and 64-bit CPUs (modifications could make it work
365 on 16-bit CPUs).
366
367 The public interface uses @c size_t for all lengths. Internally the
368 implementation uses 32-bit lengths by design to use less memory and
369 fit structures on the stack. This limits the encoded CBOR it can work
370 with to size @c UINT32_MAX (4GB) which should be enough.
371
372 This implementation assumes two's compliment integer machines. @c
373 <stdint.h> also requires this. It is possible to modify this
374 implementation for another integer representation, but all modern
375 machines seem to be two's compliment.
Michael Eckel5c531332020-03-02 01:35:30 +0100376 */
377
378
Laurence Lundblade825164e2020-10-22 20:18:06 -0700379/**
Michael Eckel5c531332020-03-02 01:35:30 +0100380 The size of the buffer to be passed to QCBOREncode_EncodeHead(). It is one
381 byte larger than sizeof(uint64_t) + 1, the actual maximum size of the
Laurence Lundblade825164e2020-10-22 20:18:06 -0700382 head of a CBOR data item because QCBOREncode_EncodeHead() needs
Michael Eckel5c531332020-03-02 01:35:30 +0100383 one extra byte to work.
384 */
385#define QCBOR_HEAD_BUFFER_SIZE (sizeof(uint64_t) + 2)
386
Michael Eckel5c531332020-03-02 01:35:30 +0100387
Laurence Lundblade9b334962020-08-27 10:55:53 -0700388/**
Laurence Lundblade825164e2020-10-22 20:18:06 -0700389 Output the full CBOR tag. See @ref CBORTags, @ref Tag-Usage and
390 @ref Tags-Overview.
Laurence Lundblade9b334962020-08-27 10:55:53 -0700391 */
392#define QCBOR_ENCODE_AS_TAG 0
393
394/**
Laurence Lundblade825164e2020-10-22 20:18:06 -0700395 Output only the 'borrowed' content format for the relevant tag.
396 See @ref CBORTags, @ref Tag-Usage and @ref Tags-Overview.
Laurence Lundblade9b334962020-08-27 10:55:53 -0700397 */
398#define QCBOR_ENCODE_AS_BORROWED 1
399
Michael Eckel5c531332020-03-02 01:35:30 +0100400
401/**
402 QCBOREncodeContext is the data type that holds context for all the
403 encoding functions. It is less than 200 bytes, so it can go on the
404 stack. The contents are opaque, and the caller should not access
405 internal members. A context may be re used serially as long as it is
406 re initialized.
407 */
408typedef struct _QCBOREncodeContext QCBOREncodeContext;
409
410
411/**
412 Initialize the encoder to prepare to encode some CBOR.
413
414 @param[in,out] pCtx The encoder context to initialize.
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800415 @param[in] Storage The buffer into which the encoded result
416 will be written.
Michael Eckel5c531332020-03-02 01:35:30 +0100417
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800418 Call this once at the start of an encoding of some CBOR. Then call
419 the many functions like QCBOREncode_AddInt64() and
420 QCBOREncode_AddText() to add the different data items. Finally, call
421 QCBOREncode_Finish() to get the pointer and length of the encoded
422 result.
Michael Eckel5c531332020-03-02 01:35:30 +0100423
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800424 The primary purpose of this function is to give the pointer and
425 length of the output buffer into which the encoded CBOR will be
426 written. This is done with a @ref UsefulBuf structure, which is just
427 a pointer and length (it is equivalent to two parameters, one a
428 pointer and one a length, but a little prettier).
Michael Eckel5c531332020-03-02 01:35:30 +0100429
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800430 The output buffer can be allocated any way (malloc, stack,
431 static). It is just some memory that QCBOR writes to. The length must
432 be the length of the allocated buffer. QCBOR will never write past
433 that length, but might write up to that length. If the buffer is too
434 small, encoding will go into an error state and not write anything
435 further.
436
437 If allocating on the stack the convenience macro
438 UsefulBuf_MAKE_STACK_UB() can be used, but its use is not required.
439
440 Since there is no reallocation or such, the output buffer must be
441 correctly sized when passed in here. It is OK, but wasteful if it is
442 too large. One way to pick the size is to figure out the maximum size
443 that will ever be needed and hard code a buffer of that size.
444
445 Another way to do it is to have QCBOR calculate it for you. To do
Laurence Lundblade8ece3732021-09-21 21:47:23 -0700446 this, pass @ref SizeCalculateUsefulBuf for @c Storage.
447 Then call all the functions to add the CBOR exactly as if
448 encoding for real. Finally, call QCBOREncode_FinishGetSize().
449 Once the length is obtained, allocate a buffer of that
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800450 size, call QCBOREncode_Init() again with the real buffer. Call all
451 the add functions again and finally, QCBOREncode_Finish() to obtain
Laurence Lundblade8ece3732021-09-21 21:47:23 -0700452 the final result. This uses twice the CPU time, but that is
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800453 usually not an issue.
454
455 See QCBOREncode_Finish() for how the pointer and length for the
456 encoded CBOR is returned.
457
Laurence Lundblade8ece3732021-09-21 21:47:23 -0700458 For practical purposes QCBOR can't output encoded CBOR larger than
459 @c UINT32_MAX (4GB) even on 64-bit CPUs because the internal offsets
460 used to track the start of an array/map are 32 bits to reduce the
461 size of the encoding context.
Michael Eckel5c531332020-03-02 01:35:30 +0100462
463 A @ref QCBOREncodeContext can be reused over and over as long as
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800464 QCBOREncode_Init() is called before each use.
Michael Eckel5c531332020-03-02 01:35:30 +0100465 */
466void QCBOREncode_Init(QCBOREncodeContext *pCtx, UsefulBuf Storage);
467
468
469/**
470 @brief Add a signed 64-bit integer to the encoded output.
471
472 @param[in] pCtx The encoding context to add the integer to.
473 @param[in] nNum The integer to add.
474
475 The integer will be encoded and added to the CBOR output.
476
477 This function figures out the size and the sign and encodes in the
478 correct minimal CBOR. Specifically, it will select CBOR major type 0
479 or 1 based on sign and will encode to 1, 2, 4 or 8 bytes depending on
480 the value of the integer. Values less than 24 effectively encode to
481 one byte because they are encoded in with the CBOR major type. This
482 is a neat and efficient characteristic of CBOR that can be taken
483 advantage of when designing CBOR-based protocols. If integers like
484 tags can be kept between -23 and 23 they will be encoded in one byte
485 including the major type.
486
487 If you pass a smaller int, say an @c int16_t or a small value, say
488 100, the encoding will still be CBOR's most compact that can
489 represent the value. For example, CBOR always encodes the value 0 as
490 one byte, 0x00. The representation as 0x00 includes identification of
491 the type as an integer too as the major type for an integer is 0. See
Laurence Lundbladec02e13e2020-12-06 05:45:41 -0800492 [RFC 8949] (https://tools.ietf.org/html/rfc8949) Appendix A for more
493 examples of CBOR encoding. This compact encoding is also preferred
494 serialization CBOR as per section 34.1 in RFC 8949.
Michael Eckel5c531332020-03-02 01:35:30 +0100495
496 There are no functions to add @c int16_t or @c int32_t because they
497 are not necessary because this always encodes to the smallest number
498 of bytes based on the value (If this code is running on a 32-bit
499 machine having a way to add 32-bit integers would reduce code size
500 some).
501
502 If the encoding context is in an error state, this will do
503 nothing. If an error occurs when adding this integer, the internal
504 error flag will be set, and the error will be returned when
505 QCBOREncode_Finish() is called.
506
507 See also QCBOREncode_AddUInt64().
508 */
509void QCBOREncode_AddInt64(QCBOREncodeContext *pCtx, int64_t nNum);
510
511static void QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum);
512
513static void QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum);
514
515
516/**
517 @brief Add an unsigned 64-bit integer to the encoded output.
518
519 @param[in] pCtx The encoding context to add the integer to.
520 @param[in] uNum The integer to add.
521
522 The integer will be encoded and added to the CBOR output.
523
524 The only reason so use this function is for integers larger than @c
525 INT64_MAX and smaller than @c UINT64_MAX. Otherwise
526 QCBOREncode_AddInt64() will work fine.
527
528 Error handling is the same as for QCBOREncode_AddInt64().
529 */
530void QCBOREncode_AddUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
531
532static void QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum);
533
534static void QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum);
535
536
537/**
538 @brief Add a UTF-8 text string to the encoded output.
539
540 @param[in] pCtx The encoding context to add the text to.
541 @param[in] Text Pointer and length of text to add.
542
543 The text passed in must be unencoded UTF-8 according to [RFC 3629]
544 (https://tools.ietf.org/html/rfc3629). There is no NULL
545 termination. The text is added as CBOR major type 3.
546
547 If called with @c nBytesLen equal to 0, an empty string will be
548 added. When @c nBytesLen is 0, @c pBytes may be @c NULL.
549
550 Note that the restriction of the buffer length to a @c uint32_t is
551 entirely intentional as this encoder is not capable of encoding
552 lengths greater. This limit to 4GB for a text string should not be a
553 problem.
554
Laurence Lundbladeadaf5c22020-09-25 10:37:09 -0700555 Text lines in Internet protocols (on the wire) are delimited by
556 either a CRLF or just an LF. Officially many protocols specify CRLF,
557 but implementations often work with either. CBOR type 3 text can be
558 either line ending, even a mixture of both.
559
560 Operating systems usually have a line end convention. Windows uses
561 CRLF. Linux and MacOS use LF. Some applications on a given OS may
562 work with either and some may not.
563
564 The majority of use cases and CBOR protocols using type 3 text will
565 work with either line ending. However, some use cases or protocols
566 may not work with either in which case translation to and/or from the
567 local line end convention, typically that of the OS, is necessary.
568
569 QCBOR does no line ending translation for type 3 text when encoding
570 and decoding.
571
Michael Eckel5c531332020-03-02 01:35:30 +0100572 Error handling is the same as QCBOREncode_AddInt64().
573 */
574static void QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text);
575
576static void QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text);
577
578static void QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text);
579
580
581/**
582 @brief Add a UTF-8 text string to the encoded output.
583
584 @param[in] pCtx The encoding context to add the text to.
585 @param[in] szString Null-terminated text to add.
586
587 This works the same as QCBOREncode_AddText().
588 */
589static void QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString);
590
591static void QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString);
592
593static void QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString);
594
595
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200596#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Michael Eckel5c531332020-03-02 01:35:30 +0100597/**
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700598 @brief Add a double-precision floating-point number to the encoded output.
Michael Eckel5c531332020-03-02 01:35:30 +0100599
600 @param[in] pCtx The encoding context to add the double to.
601 @param[in] dNum The double-precision number to add.
602
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700603 This encodes and outputs a floating-point number. CBOR major type 7
604 is used.
Michael Eckel5c531332020-03-02 01:35:30 +0100605
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700606 This implements preferred serialization, selectively encoding the
607 double-precision floating-point number as either double-precision,
608 single-precision or half-precision. Infinity, NaN and 0 are always
609 encoded as half-precision. If no precision will be lost in the
610 conversion to half-precision, then it will be converted and
611 encoded. If not and no precision will be lost in conversion to
612 single-precision, then it will be converted and encoded. If not, then
613 no conversion is performed, and it encoded as a double-precision.
Michael Eckel5c531332020-03-02 01:35:30 +0100614
615 Half-precision floating-point numbers take up 2 bytes, half that of
616 single-precision, one quarter of double-precision
617
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700618 This automatically reduces the size of encoded CBOR, maybe even by
619 four if most of values are 0, infinity or NaN.
Michael Eckel5c531332020-03-02 01:35:30 +0100620
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700621 When decoded, QCBOR will usually return these values as
622 double-precision.
623
624 It is possible to disable this preferred serialization when compiling
625 QCBOR. In that case, this functions the same as
626 QCBOREncode_AddDoubleNoPreferred().
Michael Eckel5c531332020-03-02 01:35:30 +0100627
628 Error handling is the same as QCBOREncode_AddInt64().
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700629
630 See also QCBOREncode_AddDoubleNoPreferred(), QCBOREncode_AddFloat()
631 and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
Michael Eckel5c531332020-03-02 01:35:30 +0100632 */
633void QCBOREncode_AddDouble(QCBOREncodeContext *pCtx, double dNum);
634
635static void QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
636
637static void QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
638
639
640/**
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700641 @brief Add a single-precision floating-point number to the encoded output.
642
643 @param[in] pCtx The encoding context to add the double to.
644 @param[in] fNum The single-precision number to add.
645
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700646 This is identical to QCBOREncode_AddDouble() except the input is
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700647 single-precision.
648
649 See also QCBOREncode_AddDouble(), QCBOREncode_AddDoubleNoPreferred(),
650 and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
651*/
652void QCBOREncode_AddFloat(QCBOREncodeContext *pCtx, float fNum);
653
654static void QCBOREncode_AddFloatToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
655
656static void QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700657
658
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700659/**
660 @brief Add a double-precision floating-point number without preferred encoding.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700661
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700662 @param[in] pCtx The encoding context to add the double to.
663 @param[in] dNum The double-precision number to add.
664
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700665 This always outputs the number as a 64-bit double-precision.
666 Preferred serialization is not used.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700667
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700668 Error handling is the same as QCBOREncode_AddInt64().
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700669
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700670 See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
671 QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700672*/
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700673void QCBOREncode_AddDoubleNoPreferred(QCBOREncodeContext *pCtx, double dNum);
674
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700675static void QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
676
677static void QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
678
679
680/**
681 @brief Add a single-precision floating-point number without preferred encoding.
682
683 @param[in] pCtx The encoding context to add the double to.
684 @param[in] fNum The single-precision number to add.
685
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700686 This always outputs the number as a 32-bit single-precision.
687 Preferred serialization is not used.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700688
689 Error handling is the same as QCBOREncode_AddInt64().
690
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700691 See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
692 QCBOREncode_AddDoubleNoPreferred() and @ref Floating-Point.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700693*/
694void QCBOREncode_AddFloatNoPreferred(QCBOREncodeContext *pCtx, float fNum);
695
696static void QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
697
698static void QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float fNum);
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200699#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700700
701
Michael Eckel5c531332020-03-02 01:35:30 +0100702/**
703 @brief Add an optional tag.
704
705 @param[in] pCtx The encoding context to add the tag to.
706 @param[in] uTag The tag to add
707
708 This outputs a CBOR major type 6 item that tags the next data item
709 that is output usually to indicate it is some new data type.
710
711 For many of the common standard tags, a function to encode data using
712 it is provided and this is not needed. For example,
713 QCBOREncode_AddDateEpoch() already exists to output integers
714 representing dates with the right tag.
715
716 The tag is applied to the next data item added to the encoded
717 output. That data item that is to be tagged can be of any major CBOR
718 type. Any number of tags can be added to a data item by calling this
719 multiple times before the data item is added.
720
721 See @ref Tags-Overview for discussion of creating new non-standard
722 tags. See QCBORDecode_GetNext() for discussion of decoding custom
723 tags.
724*/
Laurence Lundblade6416a0f2020-09-19 23:26:34 -0700725void QCBOREncode_AddTag(QCBOREncodeContext *pCtx, uint64_t uTag);
Michael Eckel5c531332020-03-02 01:35:30 +0100726
727
728/**
729 @brief Add an epoch-based date.
730
731 @param[in] pCtx The encoding context to add the date to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700732 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700733 @param[in] nDate Number of seconds since 1970-01-01T00:00Z in UTC time.
Michael Eckel5c531332020-03-02 01:35:30 +0100734
Laurence Lundbladec02e13e2020-12-06 05:45:41 -0800735 As per RFC 8949 this is similar to UNIX/Linux/POSIX dates. This is
Michael Eckel5c531332020-03-02 01:35:30 +0100736 the most compact way to specify a date and time in CBOR. Note that
737 this is always UTC and does not include the time zone. Use
738 QCBOREncode_AddDateString() if you want to include the time zone.
739
Laurence Lundblade46d63e92021-05-13 11:37:10 -0700740 The preferred integer encoding rules apply here so the date will be encoded in
Michael Eckel5c531332020-03-02 01:35:30 +0100741 a minimal number of bytes. Until about the year 2106 these dates will
742 encode in 6 bytes -- one byte for the tag, one byte for the type and
743 4 bytes for the integer. After that it will encode to 10 bytes.
744
745 Negative values are supported for dates before 1970.
746
747 If you care about leap-seconds and that level of accuracy, make sure
748 the system you are running this code on does it correctly. This code
749 just takes the value passed in.
750
751 This implementation cannot encode fractional seconds using float or
752 double even though that is allowed by CBOR, but you can encode them
Laurence Lundblade46d63e92021-05-13 11:37:10 -0700753 if you want to by calling QCBOREncode_AddTag() and QCBOREncode_AddDouble().
Michael Eckel5c531332020-03-02 01:35:30 +0100754
755 Error handling is the same as QCBOREncode_AddInt64().
Laurence Lundblade46d63e92021-05-13 11:37:10 -0700756
757 See also QCBOREncode_AddTDaysEpoch().
Michael Eckel5c531332020-03-02 01:35:30 +0100758 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700759static void QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pCtx,
760 uint8_t uTagRequirement,
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700761 int64_t nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -0700762
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700763static void QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pCtx,
764 const char *szLabel,
765 uint8_t uTagRequirement,
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700766 int64_t nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -0700767
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700768static void QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pCtx,
769 int64_t nLabel,
770 uint8_t uTagRequirement,
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700771 int64_t nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -0700772
773
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700774static void QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx,
775 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100776
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700777static void QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx,
778 const char *szLabel,
779 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100780
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700781static void QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx,
782 int64_t nLabel,
783 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100784
785
Laurence Lundblade46d63e92021-05-13 11:37:10 -0700786
787/**
788 @brief Add an epoch-based day-count date.
789
790 @param[in] pCtx The encoding context to add the date to.
791 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
792 @ref QCBOR_ENCODE_AS_BORROWED.
793 @param[in] nDays Number of days before or after 1970-01-0.
794
795 This date format is described in
796 [RFC 8943] (https://tools.ietf.org/html/rfc8943).
797
798 The integer encoding rules apply here so the date will be encoded in
799 a minimal number of bytes. Until about the year 2149 these dates will
800 encode in 4 bytes -- one byte for the tag, one byte for the type and
801 2 bytes for the integer.
802
803 See also QCBOREncode_AddTDateEpoch().
804
805*/
806static void QCBOREncode_AddTDaysEpoch(QCBOREncodeContext *pCtx,
807 uint8_t uTagRequirement,
808 int64_t nDays);
809
810static void QCBOREncode_AddTDaysEpochToMapSZ(QCBOREncodeContext *pCtx,
811 const char *szLabel,
812 uint8_t uTagRequirement,
813 int64_t nDays);
814
815static void QCBOREncode_AddTDaysEpochToMapN(QCBOREncodeContext *pCtx,
816 int64_t nLabel,
817 uint8_t uTagRequirement,
818 int64_t nDays);
819
820
821
822
Michael Eckel5c531332020-03-02 01:35:30 +0100823/**
824 @brief Add a byte string to the encoded output.
825
826 @param[in] pCtx The encoding context to add the bytes to.
827 @param[in] Bytes Pointer and length of the input data.
828
829 Simply adds the bytes to the encoded output as CBOR major type 2.
830
831 If called with @c Bytes.len equal to 0, an empty string will be
832 added. When @c Bytes.len is 0, @c Bytes.ptr may be @c NULL.
833
834 Error handling is the same as QCBOREncode_AddInt64().
835 */
836static void QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
837
838static void QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
839
840static void QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
841
842
Michael Eckel5c531332020-03-02 01:35:30 +0100843/**
Laurence Lundbladeb24faef2022-04-26 11:03:08 -0600844 @brief Set up to write a byte string value directly to encoded output.
845
846 @param[in] pCtx The encoding context to add the bytes to.
847 @param[out] pPlace Pointer and length of place to write byte string value.
848
849 QCBOREncode_AddBytes() is the normal way to encode a byte string.
850 This is for special cases and by passes some of the pointer safety.
851
852 The purpose of this is to output the bytes that make up a byte string
853 value directly to the QCBOR output buffer so you don't need to have a
854 copy of it in memory. This is particularly useful if the byte string
855 is large, for example, the encrypted payload of a COSE_Encrypt
856 message. The payload encryption algorithm can output directly to the
857 encoded CBOR buffer, perhaps by making it the output buffer
858 for some function (e.g. symmetric encryption) or by multiple writes.
859
860 The pointer in \c pPlace is where to start writing. Writing is just
861 copying bytes to the location by the pointer in \c pPlace. Writing
862 past the length in \c pPlace will be writing off the end of the
863 output buffer.
864
865 If there is no room in the output buffer @ref NULLUsefulBuf will be
866 returned and there is no need to call QCBOREncode_CloseBytes().
867
868 The byte string must be closed by calling QCBOREncode_CloseBytes().
869
870 Warning: this bypasses some of the usual checks provided by QCBOR
871 against writing off the end of the encoded output buffer.
872 */
873void
874QCBOREncode_OpenBytes(QCBOREncodeContext *pCtx, UsefulBuf *pPlace);
875
876static void
877QCBOREncode_OpenBytesInMapSZ(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBuf *pPlace);
878
879static void
880QCBOREncode_OpenBytesInMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBuf *pPlace);
881
882
883/**
884 @brief Close out a byte string written directly to encoded output.
885
886 @param[in] pCtx The encoding context to add the bytes to.
887 @param[out] uAmount The number of bytes written, the length of the byte string.
888
889 This closes out a call to QCBOREncode_OpenBytes(). This inserts a
890 CBOR header at the front of the byte string value to make it a
891 well-formed byte string.
892
893 If there was no call to QCBOREncode_OpenBytes() then
894 @ref QCBOR_ERR_TOO_MANY_CLOSES is set.
895 */
896void QCBOREncode_CloseBytes(QCBOREncodeContext *pCtx, size_t uAmount);
897
898
899/**
Michael Eckel5c531332020-03-02 01:35:30 +0100900 @brief Add a binary UUID to the encoded output.
901
902 @param[in] pCtx The encoding context to add the UUID to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700903 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100904 @param[in] Bytes Pointer and length of the binary UUID.
905
906 A binary UUID as defined in [RFC 4122]
907 (https://tools.ietf.org/html/rfc4122) is added to the output.
908
909 It is output as CBOR major type 2, a binary string, with tag @ref
910 CBOR_TAG_BIN_UUID indicating the binary string is a UUID.
911 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700912static void QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pCtx,
913 uint8_t uTagRequirement,
914 UsefulBufC Bytes);
915
916static void QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pCtx,
917 const char *szLabel,
918 uint8_t uTagRequirement,
919 UsefulBufC Bytes);
920
921static void QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pCtx,
922 int64_t nLabel,
923 uint8_t uTagRequirement,
924 UsefulBufC Bytes);
925
926
Michael Eckel5c531332020-03-02 01:35:30 +0100927static void QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
928
929static void QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
930
931static void QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
932
933
934/**
935 @brief Add a positive big number to the encoded output.
936
937 @param[in] pCtx The encoding context to add the big number to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700938 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100939 @param[in] Bytes Pointer and length of the big number.
940
941 Big numbers are integers larger than 64-bits. Their format is
Laurence Lundbladec02e13e2020-12-06 05:45:41 -0800942 described in [RFC 8949] (https://tools.ietf.org/html/rfc8949).
Michael Eckel5c531332020-03-02 01:35:30 +0100943
944 It is output as CBOR major type 2, a binary string, with tag @ref
945 CBOR_TAG_POS_BIGNUM indicating the binary string is a positive big
946 number.
947
948 Often big numbers are used to represent cryptographic keys, however,
949 COSE which defines representations for keys chose not to use this
950 particular type.
951 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700952static void QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pCtx,
953 uint8_t uTagRequirement,
954 UsefulBufC Bytes);
955
956static void QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pCtx,
957 const char *szLabel,
958 uint8_t uTagRequirement,
959 UsefulBufC Bytes);
960
961static void QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pCtx,
962 int64_t nLabel,
963 uint8_t uTagRequirement,
964 UsefulBufC Bytes);
965
966
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700967static void QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx,
968 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100969
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700970static void QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx,
971 const char *szLabel,
972 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100973
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700974static void QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx,
975 int64_t nLabel,
976 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100977
978
979/**
980 @brief Add a negative big number to the encoded output.
981
982 @param[in] pCtx The encoding context to add the big number to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700983 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100984 @param[in] Bytes Pointer and length of the big number.
985
986 Big numbers are integers larger than 64-bits. Their format is
Laurence Lundbladec02e13e2020-12-06 05:45:41 -0800987 described in [RFC 8949] (https://tools.ietf.org/html/rfc8949).
Michael Eckel5c531332020-03-02 01:35:30 +0100988
989 It is output as CBOR major type 2, a binary string, with tag @ref
990 CBOR_TAG_NEG_BIGNUM indicating the binary string is a negative big
991 number.
992
993 Often big numbers are used to represent cryptographic keys, however,
994 COSE which defines representations for keys chose not to use this
995 particular type.
996 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700997static void QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pCtx,
998 uint8_t uTagRequirement,
999 UsefulBufC Bytes);
1000
1001static void QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pCtx,
1002 const char *szLabel,
1003 uint8_t uTagRequirement,
1004 UsefulBufC Bytes);
1005
1006static void QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pCtx,
1007 int64_t nLabel,
1008 uint8_t uTagRequirement,
1009 UsefulBufC Bytes);
1010
1011
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001012static void QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx,
1013 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001014
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001015static void QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx,
1016 const char *szLabel,
1017 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001018
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001019static void QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx,
1020 int64_t nLabel,
1021 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01001022
1023
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07001024#ifndef QCBOR_DISABLE_EXP_AND_MANTISSA
Michael Eckel5c531332020-03-02 01:35:30 +01001025/**
1026 @brief Add a decimal fraction to the encoded output.
1027
1028 @param[in] pCtx The encoding context to add the decimal fraction to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001029 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001030 @param[in] nMantissa The mantissa.
1031 @param[in] nBase10Exponent The exponent.
1032
1033 The value is nMantissa * 10 ^ nBase10Exponent.
1034
1035 A decimal fraction is good for exact representation of some values
1036 that can't be represented exactly with standard C (IEEE 754)
1037 floating-point numbers. Much larger and much smaller numbers can
1038 also be represented than floating-point because of the larger number
1039 of bits in the exponent.
1040
1041 The decimal fraction is conveyed as two integers, a mantissa and a
1042 base-10 scaling factor.
1043
1044 For example, 273.15 is represented by the two integers 27315 and -2.
1045
1046 The exponent and mantissa have the range from @c INT64_MIN to
1047 @c INT64_MAX for both encoding and decoding (CBOR allows @c -UINT64_MAX
1048 to @c UINT64_MAX, but this implementation doesn't support this range to
1049 reduce code size and interface complexity a little).
1050
1051 CBOR Preferred encoding of the integers is used, thus they will be encoded
1052 in the smallest number of bytes possible.
1053
1054 See also QCBOREncode_AddDecimalFractionBigNum() for a decimal
1055 fraction with arbitrarily large precision and QCBOREncode_AddBigFloat().
1056
1057 There is no representation of positive or negative infinity or NaN
1058 (Not a Number). Use QCBOREncode_AddDouble() to encode them.
1059
1060 See @ref expAndMantissa for decoded representation.
1061 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001062static void QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pCtx,
1063 uint8_t uTagRequirement,
1064 int64_t nMantissa,
1065 int64_t nBase10Exponent);
1066
1067static void QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001068 const char *szLabel,
1069 uint8_t uTagRequirement,
1070 int64_t nMantissa,
1071 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001072
1073static void QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pCtx,
1074 int64_t nLabel,
1075 uint8_t uTagRequirement,
1076 int64_t nMantissa,
1077 int64_t nBase10Exponent);
1078
1079
Michael Eckel5c531332020-03-02 01:35:30 +01001080static void QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pCtx,
1081 int64_t nMantissa,
1082 int64_t nBase10Exponent);
1083
1084static void QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pCtx,
1085 const char *szLabel,
1086 int64_t nMantissa,
1087 int64_t nBase10Exponent);
1088
1089static void QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pCtx,
1090 int64_t nLabel,
1091 int64_t nMantissa,
1092 int64_t nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01001093/**
1094 @brief Add a decimal fraction with a big number mantissa to the encoded output.
1095
1096 @param[in] pCtx The encoding context to add the decimal fraction to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001097 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001098 @param[in] Mantissa The mantissa.
1099 @param[in] bIsNegative false if mantissa is positive, true if negative.
1100 @param[in] nBase10Exponent The exponent.
1101
1102 This is the same as QCBOREncode_AddDecimalFraction() except the
1103 mantissa is a big number (See QCBOREncode_AddPositiveBignum())
1104 allowing for arbitrarily large precision.
1105
1106 See @ref expAndMantissa for decoded representation.
1107 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001108static void QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pCtx,
1109 uint8_t uTagRequirement,
1110 UsefulBufC Mantissa,
1111 bool bIsNegative,
1112 int64_t nBase10Exponent);
1113
1114static void QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001115 const char *szLabel,
1116 uint8_t uTagRequirement,
1117 UsefulBufC Mantissa,
1118 bool bIsNegative,
1119 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001120
1121static void QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
1122 int64_t nLabel,
1123 uint8_t uTagRequirement,
1124 UsefulBufC Mantissa,
1125 bool bIsNegative,
1126 int64_t nBase10Exponent);
1127
1128
Michael Eckel5c531332020-03-02 01:35:30 +01001129static void QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pCtx,
1130 UsefulBufC Mantissa,
1131 bool bIsNegative,
1132 int64_t nBase10Exponent);
1133
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001134static void QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001135 const char *szLabel,
1136 UsefulBufC Mantissa,
1137 bool bIsNegative,
1138 int64_t nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01001139
1140static void QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
1141 int64_t nLabel,
1142 UsefulBufC Mantissa,
1143 bool bIsNegative,
1144 int64_t nBase10Exponent);
1145
1146/**
1147 @brief Add a big floating-point number to the encoded output.
1148
1149 @param[in] pCtx The encoding context to add the bigfloat to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001150 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001151 @param[in] nMantissa The mantissa.
1152 @param[in] nBase2Exponent The exponent.
1153
1154 The value is nMantissa * 2 ^ nBase2Exponent.
1155
1156 "Bigfloats", as CBOR terms them, are similar to IEEE floating-point
1157 numbers in having a mantissa and base-2 exponent, but they are not
1158 supported by hardware or encoded the same. They explicitly use two
1159 CBOR-encoded integers to convey the mantissa and exponent, each of which
1160 can be 8, 16, 32 or 64 bits. With both the mantissa and exponent
1161 64 bits they can express more precision and a larger range than an
1162 IEEE double floating-point number. See
1163 QCBOREncode_AddBigFloatBigNum() for even more precision.
1164
1165 For example, 1.5 would be represented by a mantissa of 3 and an
1166 exponent of -1.
1167
1168 The exponent and mantissa have the range from @c INT64_MIN to
1169 @c INT64_MAX for both encoding and decoding (CBOR allows @c -UINT64_MAX
1170 to @c UINT64_MAX, but this implementation doesn't support this range to
1171 reduce code size and interface complexity a little).
1172
1173 CBOR Preferred encoding of the integers is used, thus they will be encoded
1174 in the smallest number of bytes possible.
1175
1176 This can also be used to represent floating-point numbers in
1177 environments that don't support IEEE 754.
1178
1179 See @ref expAndMantissa for decoded representation.
1180 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001181static void QCBOREncode_AddTBigFloat(QCBOREncodeContext *pCtx,
1182 uint8_t uTagRequirement,
1183 int64_t nMantissa,
1184 int64_t nBase2Exponent);
1185
1186static void QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001187 const char *szLabel,
1188 uint8_t uTagRequirement,
1189 int64_t nMantissa,
1190 int64_t nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001191
1192static void QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pCtx,
1193 int64_t nLabel,
1194 uint8_t uTagRequirement,
1195 int64_t nMantissa,
1196 int64_t nBase2Exponent);
1197
1198
Michael Eckel5c531332020-03-02 01:35:30 +01001199static void QCBOREncode_AddBigFloat(QCBOREncodeContext *pCtx,
1200 int64_t nMantissa,
1201 int64_t nBase2Exponent);
1202
1203static void QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pCtx,
1204 const char *szLabel,
1205 int64_t nMantissa,
1206 int64_t nBase2Exponent);
1207
1208static void QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pCtx,
1209 int64_t nLabel,
1210 int64_t nMantissa,
1211 int64_t nBase2Exponent);
1212
Michael Eckel5c531332020-03-02 01:35:30 +01001213/**
1214 @brief Add a big floating-point number with a big number mantissa to
1215 the encoded output.
1216
1217 @param[in] pCtx The encoding context to add the bigfloat to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001218 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001219 @param[in] Mantissa The mantissa.
1220 @param[in] bIsNegative false if mantissa is positive, true if negative.
1221 @param[in] nBase2Exponent The exponent.
1222
1223 This is the same as QCBOREncode_AddBigFloat() except the mantissa is
1224 a big number (See QCBOREncode_AddPositiveBignum()) allowing for
1225 arbitrary precision.
1226
1227 See @ref expAndMantissa for decoded representation.
1228 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001229static void QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pCtx,
1230 uint8_t uTagRequirement,
1231 UsefulBufC Mantissa,
1232 bool bIsNegative,
1233 int64_t nBase2Exponent);
1234
1235static void QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001236 const char *szLabel,
1237 uint8_t uTagRequirement,
1238 UsefulBufC Mantissa,
1239 bool bIsNegative,
1240 int64_t nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001241
1242static void QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1243 int64_t nLabel,
1244 uint8_t uTagRequirement,
1245 UsefulBufC Mantissa,
1246 bool bIsNegative,
1247 int64_t nBase2Exponent);
1248
1249
Michael Eckel5c531332020-03-02 01:35:30 +01001250static void QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pCtx,
1251 UsefulBufC Mantissa,
1252 bool bIsNegative,
1253 int64_t nBase2Exponent);
1254
1255static void QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pCtx,
1256 const char *szLabel,
1257 UsefulBufC Mantissa,
1258 bool bIsNegative,
1259 int64_t nBase2Exponent);
1260
1261static void QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1262 int64_t nLabel,
1263 UsefulBufC Mantissa,
1264 bool bIsNegative,
1265 int64_t nBase2Exponent);
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07001266#endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
Michael Eckel5c531332020-03-02 01:35:30 +01001267
1268
1269/**
1270 @brief Add a text URI to the encoded output.
1271
1272 @param[in] pCtx The encoding context to add the URI to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001273 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001274 @param[in] URI Pointer and length of the URI.
1275
1276 The format of URI must be per [RFC 3986]
1277 (https://tools.ietf.org/html/rfc3986).
1278
1279 It is output as CBOR major type 3, a text string, with tag @ref
1280 CBOR_TAG_URI indicating the text string is a URI.
1281
1282 A URI in a NULL-terminated string, @c szURI, can be easily added with
1283 this code:
1284
1285 QCBOREncode_AddURI(pCtx, UsefulBuf_FromSZ(szURI));
1286 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001287static void QCBOREncode_AddTURI(QCBOREncodeContext *pCtx,
1288 uint8_t uTagRequirement,
1289 UsefulBufC URI);
1290
1291static void QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pCtx,
1292 const char *szLabel,
1293 uint8_t uTagRequirement,
1294 UsefulBufC URI);
1295
1296static void QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pCtx,
1297 int64_t nLabel,
1298 uint8_t uTagRequirement,
1299 UsefulBufC URI);
1300
1301
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001302static void QCBOREncode_AddURI(QCBOREncodeContext *pCtx,
1303 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001304
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001305static void QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx,
1306 const char *szLabel,
1307 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001308
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001309static void QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx,
1310 int64_t nLabel,
1311 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001312
1313
1314/**
1315 @brief Add Base64-encoded text to encoded output.
1316
1317 @param[in] pCtx The encoding context to add the base-64 text to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001318 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001319 @param[in] B64Text Pointer and length of the base-64 encoded text.
1320
1321 The text content is Base64 encoded data per [RFC 4648]
1322 (https://tools.ietf.org/html/rfc4648).
1323
1324 It is output as CBOR major type 3, a text string, with tag @ref
1325 CBOR_TAG_B64 indicating the text string is Base64 encoded.
1326 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001327static void QCBOREncode_AddTB64Text(QCBOREncodeContext *pCtx,
1328 uint8_t uTagRequirement,
1329 UsefulBufC B64Text);
1330
1331static void QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pCtx,
1332 const char *szLabel,
1333 uint8_t uTagRequirement,
1334 UsefulBufC B64Text);
1335
1336static void QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pCtx,
1337 int64_t nLabel,
1338 uint8_t uTagRequirement,
1339 UsefulBufC B64Text);
1340
1341
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001342static void QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx,
1343 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001344
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001345static void QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx,
1346 const char *szLabel,
1347 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001348
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001349static void QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx,
1350 int64_t nLabel,
1351 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001352
1353
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001354
Michael Eckel5c531332020-03-02 01:35:30 +01001355/**
1356 @brief Add base64url encoded data to encoded output.
1357
1358 @param[in] pCtx The encoding context to add the base64url to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001359 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001360 @param[in] B64Text Pointer and length of the base64url encoded text.
1361
1362 The text content is base64URL encoded text as per [RFC 4648]
1363 (https://tools.ietf.org/html/rfc4648).
1364
1365 It is output as CBOR major type 3, a text string, with tag @ref
1366 CBOR_TAG_B64URL indicating the text string is a Base64url encoded.
1367 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001368static void QCBOREncode_AddTB64URLText(QCBOREncodeContext *pCtx,
1369 uint8_t uTagRequirement,
1370 UsefulBufC B64Text);
1371
1372static void QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pCtx,
1373 const char *szLabel,
1374 uint8_t uTagRequirement,
1375 UsefulBufC B64Text);
1376
1377static void QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pCtx,
1378 int64_t nLabel,
1379 uint8_t uTagRequirement,
1380 UsefulBufC B64Text);
1381
1382
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001383static void QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx,
1384 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001385
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001386static void QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx,
1387 const char *szLabel,
1388 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001389
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001390static void QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx,
1391 int64_t nLabel,
1392 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001393
1394
1395/**
1396 @brief Add Perl Compatible Regular Expression.
1397
1398 @param[in] pCtx The encoding context to add the regular expression to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001399 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001400 @param[in] Regex Pointer and length of the regular expression.
1401
1402 The text content is Perl Compatible Regular
1403 Expressions (PCRE) / JavaScript syntax [ECMA262].
1404
1405 It is output as CBOR major type 3, a text string, with tag @ref
1406 CBOR_TAG_REGEX indicating the text string is a regular expression.
1407 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001408static void QCBOREncode_AddTRegex(QCBOREncodeContext *pCtx,
1409 uint8_t uTagRequirement,
1410 UsefulBufC Regex);
1411
1412static void QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pCtx,
1413 const char *szLabel,
1414 uint8_t uTagRequirement,
1415 UsefulBufC Regex);
1416
1417static void QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pCtx,
1418 int64_t nLabel,
1419 uint8_t uTagRequirement,
1420 UsefulBufC Regex);
1421
1422
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001423static void QCBOREncode_AddRegex(QCBOREncodeContext *pCtx,
1424 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001425
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001426static void QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx,
1427 const char *szLabel,
1428 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001429
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001430static void QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx,
1431 int64_t nLabel,
1432 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001433
1434
1435/**
Laurence Lundblade4982f412020-09-18 23:02:18 -07001436 @brief MIME encoded data to the encoded output.
Michael Eckel5c531332020-03-02 01:35:30 +01001437
Laurence Lundblade4982f412020-09-18 23:02:18 -07001438 @param[in] pCtx The encoding context to add the MIME data to.
1439 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1440 @ref QCBOR_ENCODE_AS_BORROWED.
1441 @param[in] MIMEData Pointer and length of the MIME data.
Michael Eckel5c531332020-03-02 01:35:30 +01001442
1443 The text content is in MIME format per [RFC 2045]
Laurence Lundblade4982f412020-09-18 23:02:18 -07001444 (https://tools.ietf.org/html/rfc2045) including the headers.
Michael Eckel5c531332020-03-02 01:35:30 +01001445
Laurence Lundblade4982f412020-09-18 23:02:18 -07001446 It is output as CBOR major type 2, a binary string, with tag @ref
1447 CBOR_TAG_BINARY_MIME indicating the string is MIME data. This
1448 outputs tag 257, not tag 36, as it can carry any type of MIME binary,
1449 7-bit, 8-bit, quoted-printable and base64 where tag 36 cannot.
1450
1451 Previous versions of QCBOR, those before spiffy decode, output tag
1452 36. Decoding supports both tag 36 and 257. (if the old behavior with
1453 tag 36 is needed, copy the inline functions below and change the tag
1454 number).
1455
1456 See also QCBORDecode_GetMIMEMessage() and
1457 @ref QCBOR_TYPE_BINARY_MIME.
Laurence Lundbladeadaf5c22020-09-25 10:37:09 -07001458
1459 This does no translation of line endings. See QCBOREncode_AddText()
1460 for a discussion of line endings in CBOR.
Michael Eckel5c531332020-03-02 01:35:30 +01001461 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001462static void QCBOREncode_AddTMIMEData(QCBOREncodeContext *pCtx,
1463 uint8_t uTagRequirement,
1464 UsefulBufC MIMEData);
1465
1466static void QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pCtx,
1467 const char *szLabel,
1468 uint8_t uTagRequirement,
1469 UsefulBufC MIMEData);
1470
1471static void QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pCtx,
1472 int64_t nLabel,
1473 uint8_t uTagRequirement,
1474 UsefulBufC MIMEData);
1475
1476
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001477static void QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx,
1478 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001479
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001480static void QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx,
1481 const char *szLabel,
1482 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001483
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001484static void QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx,
1485 int64_t nLabel,
1486 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001487
1488
1489/**
1490 @brief Add an RFC 3339 date string
1491
1492 @param[in] pCtx The encoding context to add the date to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001493 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001494 @param[in] szDate Null-terminated string with date to add.
1495
1496 The string szDate should be in the form of [RFC 3339]
1497 (https://tools.ietf.org/html/rfc3339) as defined by section 3.3 in
1498 [RFC 4287] (https://tools.ietf.org/html/rfc4287). This is as
Laurence Lundbladec02e13e2020-12-06 05:45:41 -08001499 described in section 3.4.1 in [RFC 8949]
1500 (https://tools.ietf.org/html/rfc8949).
Michael Eckel5c531332020-03-02 01:35:30 +01001501
1502 Note that this function doesn't validate the format of the date string
1503 at all. If you add an incorrect format date string, the generated
1504 CBOR will be incorrect and the receiver may not be able to handle it.
1505
1506 Error handling is the same as QCBOREncode_AddInt64().
Laurence Lundblade46d63e92021-05-13 11:37:10 -07001507
1508 See also QCBOREncode_AddTDayString().
Michael Eckel5c531332020-03-02 01:35:30 +01001509 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001510static void QCBOREncode_AddTDateString(QCBOREncodeContext *pCtx,
1511 uint8_t uTagRequirement,
1512 const char *szDate);
1513
1514static void QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pCtx,
1515 const char *szLabel,
1516 uint8_t uTagRequirement,
1517 const char *szDate);
1518
1519static void QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pCtx,
1520 int64_t nLabel,
1521 uint8_t uTagRequirement,
1522 const char *szDate);
1523
1524
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001525static void QCBOREncode_AddDateString(QCBOREncodeContext *pCtx,
1526 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001527
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001528static void QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx,
1529 const char *szLabel,
1530 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001531
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001532static void QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx,
1533 int64_t nLabel,
1534 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001535
Laurence Lundblade46d63e92021-05-13 11:37:10 -07001536
1537/**
1538 @brief Add a date-only string.
1539
1540 @param[in] pCtx The encoding context to add the date to.
1541 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1542 @ref QCBOR_ENCODE_AS_BORROWED.
1543 @param[in] szDate Null-terminated string with date to add.
1544
1545 This date format is described in
1546 [RFC 8943] (https://tools.ietf.org/html/rfc8943), but that mainly
1547 references RFC 3339. The string szDate must be in the forrm
1548 specified the ABNF for a full-date in
1549 [RFC 3339] (https://tools.ietf.org/html/rfc3339). Examples of this
1550 are "1985-04-12" and "1937-01-01". The time and the time zone are
1551 never included.
1552
1553 Note that this function doesn't validate the format of the date
1554 string at all. If you add an incorrect format date string, the
1555 generated CBOR will be incorrect and the receiver may not be able to
1556 handle it.
1557
1558 Error handling is the same as QCBOREncode_AddInt64().
1559
1560 See also QCBOREncode_AddTDateString().
1561 */
1562static void
1563QCBOREncode_AddTDaysString(QCBOREncodeContext *pCtx,
1564 uint8_t uTagRequirement,
1565 const char *szDate);
1566
1567static void
1568QCBOREncode_AddTDaysStringToMapSZ(QCBOREncodeContext *pCtx,
1569 const char *szLabel,
1570 uint8_t uTagRequirement,
1571 const char *szDate);
1572
1573static void
1574QCBOREncode_AddTDaysStringToMapN(QCBOREncodeContext *pCtx,
1575 int64_t nLabel,
1576 uint8_t uTagRequirement,
1577 const char *szDate);
1578
1579
Michael Eckel5c531332020-03-02 01:35:30 +01001580/**
1581 @brief Add a standard Boolean.
1582
1583 @param[in] pCtx The encoding context to add the Boolean to.
1584 @param[in] b true or false from @c <stdbool.h>.
1585
1586 Adds a Boolean value as CBOR major type 7.
1587
1588 Error handling is the same as QCBOREncode_AddInt64().
1589 */
1590static void QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b);
1591
1592static void QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b);
1593
1594static void QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b);
1595
1596
1597
1598/**
1599 @brief Add a NULL to the encoded output.
1600
1601 @param[in] pCtx The encoding context to add the NULL to.
1602
1603 Adds the NULL value as CBOR major type 7.
1604
1605 This NULL doesn't have any special meaning in CBOR such as a
1606 terminating value for a string or an empty value.
1607
1608 Error handling is the same as QCBOREncode_AddInt64().
1609 */
1610static void QCBOREncode_AddNULL(QCBOREncodeContext *pCtx);
1611
1612static void QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1613
1614static void QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1615
1616
1617/**
1618 @brief Add an "undef" to the encoded output.
1619
1620 @param[in] pCtx The encoding context to add the "undef" to.
1621
1622 Adds the undef value as CBOR major type 7.
1623
1624 Note that this value will not translate to JSON.
1625
1626 This Undef doesn't have any special meaning in CBOR such as a
1627 terminating value for a string or an empty value.
1628
1629 Error handling is the same as QCBOREncode_AddInt64().
1630 */
1631static void QCBOREncode_AddUndef(QCBOREncodeContext *pCtx);
1632
1633static void QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1634
1635static void QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1636
1637
1638/**
1639 @brief Indicates that the next items added are in an array.
1640
1641 @param[in] pCtx The encoding context to open the array in.
1642
1643 Arrays are the basic CBOR aggregate or structure type. Call this
1644 function to start or open an array. Then call the various @c
1645 QCBOREncode_AddXxx() functions to add the items that go into the
1646 array. Then call QCBOREncode_CloseArray() when all items have been
1647 added. The data items in the array can be of any type and can be of
1648 mixed types.
1649
1650 Nesting of arrays and maps is allowed and supported just by calling
1651 QCBOREncode_OpenArray() again before calling
1652 QCBOREncode_CloseArray(). While CBOR has no limit on nesting, this
1653 implementation does in order to keep it smaller and simpler. The
1654 limit is @ref QCBOR_MAX_ARRAY_NESTING. This is the max number of
1655 times this can be called without calling
1656 QCBOREncode_CloseArray(). QCBOREncode_Finish() will return @ref
1657 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP when it is called as this function
1658 just sets an error state and returns no value when this occurs.
1659
1660 If you try to add more than @ref QCBOR_MAX_ITEMS_IN_ARRAY items to a
1661 single array or map, @ref QCBOR_ERR_ARRAY_TOO_LONG will be returned
1662 when QCBOREncode_Finish() is called.
1663
1664 An array itself must have a label if it is being added to a map.
1665 Note that array elements do not have labels (but map elements do).
1666
1667 An array itself may be tagged by calling QCBOREncode_AddTag() before this call.
1668 */
1669static void QCBOREncode_OpenArray(QCBOREncodeContext *pCtx);
1670
1671static void QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1672
1673static void QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1674
1675
1676/**
1677 @brief Close an open array.
1678
1679 @param[in] pCtx The encoding context to close the array in.
1680
1681 The closes an array opened by QCBOREncode_OpenArray(). It reduces
1682 nesting level by one. All arrays (and maps) must be closed before
1683 calling QCBOREncode_Finish().
1684
1685 When an error occurs as a result of this call, the encoder records
1686 the error and enters the error state. The error will be returned when
1687 QCBOREncode_Finish() is called.
1688
1689 If this has been called more times than QCBOREncode_OpenArray(), then
1690 @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when QCBOREncode_Finish()
1691 is called.
1692
1693 If this is called and it is not an array that is currently open, @ref
1694 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
1695 is called.
1696 */
1697static void QCBOREncode_CloseArray(QCBOREncodeContext *pCtx);
1698
1699
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07001700
1701
Michael Eckel5c531332020-03-02 01:35:30 +01001702/**
1703 @brief Indicates that the next items added are in a map.
1704
1705 @param[in] pCtx The encoding context to open the map in.
1706
1707 See QCBOREncode_OpenArray() for more information, particularly error
1708 handling.
1709
1710 CBOR maps are an aggregate type where each item in the map consists
1711 of a label and a value. They are similar to JSON objects.
1712
1713 The value can be any CBOR type including another map.
1714
1715 The label can also be any CBOR type, but in practice they are
1716 typically, integers as this gives the most compact output. They might
1717 also be text strings which gives readability and translation to JSON.
1718
1719 Every @c QCBOREncode_AddXxx() call has one version that ends with @c
1720 InMap for adding items to maps with string labels and one that ends
1721 with @c InMapN that is for adding with integer labels.
1722
Laurence Lundbladec02e13e2020-12-06 05:45:41 -08001723 RFC 8949 uses the term "key" instead of "label".
Michael Eckel5c531332020-03-02 01:35:30 +01001724
1725 If you wish to use map labels that are neither integer labels nor
1726 text strings, then just call the QCBOREncode_AddXxx() function
1727 explicitly to add the label. Then call it again to add the value.
1728
Laurence Lundbladec02e13e2020-12-06 05:45:41 -08001729 See the [RFC 8949] (https://tools.ietf.org/html/rfc8949) for a lot
Michael Eckel5c531332020-03-02 01:35:30 +01001730 more information on creating maps.
1731 */
1732static void QCBOREncode_OpenMap(QCBOREncodeContext *pCtx);
1733
1734static void QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1735
1736static void QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1737
1738
Michael Eckel5c531332020-03-02 01:35:30 +01001739/**
1740 @brief Close an open map.
1741
1742 @param[in] pCtx The encoding context to close the map in .
1743
1744 This closes a map opened by QCBOREncode_OpenMap(). It reduces nesting
1745 level by one.
1746
1747 When an error occurs as a result of this call, the encoder records
1748 the error and enters the error state. The error will be returned when
1749 QCBOREncode_Finish() is called.
1750
1751 If this has been called more times than QCBOREncode_OpenMap(),
1752 then @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1753 QCBOREncode_Finish() is called.
1754
1755 If this is called and it is not a map that is currently open, @ref
1756 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
1757 is called.
1758 */
1759static void QCBOREncode_CloseMap(QCBOREncodeContext *pCtx);
1760
1761
1762/**
Laurence Lundblade85a18ca2023-11-27 21:25:10 -07001763 * @brief Indicates that the next items added are in an indefinite length array.
1764 *
1765 * @param[in] pCtx The encoding context to open the array in.
1766 *
1767 * This is the same as QCBOREncode_OpenArray() except the array is
1768 * indefinite length.
1769 *
1770 * This must be closed with QCBOREncode_CloseArrayIndefiniteLength().
1771 */
1772static void QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pCtx);
1773
1774static void QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pCtx,
1775 const char *szLabel);
1776
1777static void
1778QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pCtx,
1779 int64_t nLabel);
1780
1781
1782/**
1783 * @brief Close an open indefinite length array.
1784 *
1785 * @param[in] pCtx The encoding context to close the array in.
1786 *
1787 * This is the same as QCBOREncode_CloseArray(), but the open array
1788 * that is being close must be of indefinite length.
1789 */
1790static void
1791QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pCtx);
1792
1793
1794/**
1795 * @brief Indicates that the next items added are in an indefinite length map.
1796 *
1797 * @param[in] pCtx The encoding context to open the map in.
1798 *
1799 * This is the same as QCBOREncode_OpenMap() except the array is
1800 * indefinite length.
1801 *
1802 * This must be closed with QCBOREncode_CloseMapIndefiniteLength().
1803 */
1804static void QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pCtx);
1805
1806static void QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pCtx,
1807 const char *szLabel);
1808
1809static void
1810QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pCtx,
1811 int64_t nLabel);
1812
1813
1814/**
1815 * @brief Close an open indefinite length map.
1816 *
1817 * @param[in] pCtx The encoding context to close the map in.
1818 *
1819 * This is the same as QCBOREncode_CloseMap(), but the open map that
1820 * is being close must be of indefinite length.
1821 */
1822static void
1823QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pCtx);
1824
1825
Laurence Lundbladec92e4162023-11-27 21:51:26 -07001826/**
Laurence Lundbladed6e13022023-11-26 10:14:02 -07001827 * @brief Close and sort an open map.
1828 *
1829 * @param[in] pCtx The encoding context to close the map in .
1830 *
1831 * This is the same as QCBOREncode_CloseMap() except it sorts the map
1832 * per RFC 8949 Section 4.2.1. This sort is lexicographic of the CBOR-
1833 * encoded map labels.
1834 *
1835 * This is more expensive than most things in the encoder. It uses
1836 * bubble sort which runs in n-squared time where n is the number of
1837 * map items. Sorting large maps on slow CPUs might be slow. This is
1838 * also increases the object code size of the encoder by about 30%.
1839 *
1840 * Bubble sort was selected so as to not need an extra buffer to track
1841 * map item offsets. Bubble sort works well even though map items are
1842 * not all the same size because it always swaps adjacent items.
1843 */
1844void QCBOREncode_CloseAndSortMap(QCBOREncodeContext *pCtx);
1845
1846void QCBOREncode_CloseAndSortMapIndef(QCBOREncodeContext *pCtx);
1847
1848
1849/**
Michael Eckel5c531332020-03-02 01:35:30 +01001850 @brief Indicate start of encoded CBOR to be wrapped in a bstr.
1851
1852 @param[in] pCtx The encoding context to open the bstr-wrapped CBOR in.
1853
1854 All added encoded items between this call and a call to
1855 QCBOREncode_CloseBstrWrap2() will be wrapped in a bstr. They will
1856 appear in the final output as a byte string. That byte string will
1857 contain encoded CBOR. This increases nesting level by one.
1858
1859 The typical use case is for encoded CBOR that is to be
1860 cryptographically hashed, as part of a [RFC 8152, COSE]
Laurence Lundbladec02e13e2020-12-06 05:45:41 -08001861 (https://tools.ietf.org/html/rfc8152) implementation. The
1862 wrapping byte string is taken as input by the hash function
1863 (which is why it is returned by QCBOREncode_CloseBstrWrap2()).
1864 It is also easy to recover on decoding with standard CBOR
1865 decoders.
Michael Eckel5c531332020-03-02 01:35:30 +01001866
1867 Using QCBOREncode_BstrWrap() and QCBOREncode_CloseBstrWrap2() avoids
1868 having to encode the items first in one buffer (e.g., the COSE
1869 payload) and then add that buffer as a bstr to another encoding
1870 (e.g. the COSE to-be-signed bytes, the @c Sig_structure) potentially
1871 halving the memory needed.
1872
Laurence Lundbladec02e13e2020-12-06 05:45:41 -08001873 CBOR by nature must be decoded item by item in order from the start.
1874 By wrapping some CBOR in a byte string, the decoding of that wrapped
1875 CBOR can be skipped. This is another use of wrapping, perhaps
1876 because the CBOR is large and deeply nested. Perhaps APIs for
1877 handling one defined CBOR message that is being embedded in another
1878 only take input as a byte string. Perhaps the desire is to be able
1879 to decode the out layer even in the wrapped has errors.
Michael Eckel5c531332020-03-02 01:35:30 +01001880 */
1881static void QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx);
1882
1883static void QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1884
1885static void QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1886
1887
1888/**
1889 @brief Close a wrapping bstr.
1890
1891 @param[in] pCtx The encoding context to close of bstr wrapping in.
1892 @param[in] bIncludeCBORHead Include the encoded CBOR head of the bstr
1893 as well as the bytes in @c pWrappedCBOR.
1894 @param[out] pWrappedCBOR A @ref UsefulBufC containing wrapped bytes.
1895
1896 The closes a wrapping bstr opened by QCBOREncode_BstrWrap(). It reduces
1897 nesting level by one.
1898
1899 A pointer and length of the enclosed encoded CBOR is returned in @c
1900 *pWrappedCBOR if it is not @c NULL. The main purpose of this is so
1901 this data can be hashed (e.g., with SHA-256) as part of a [RFC 8152,
1902 COSE] (https://tools.ietf.org/html/rfc8152)
1903 implementation. **WARNING**, this pointer and length should be used
1904 right away before any other calls to @c QCBOREncode_CloseXxx() as
1905 they will move data around and the pointer and length will no longer
1906 be to the correct encoded CBOR.
1907
1908 When an error occurs as a result of this call, the encoder records
1909 the error and enters the error state. The error will be returned when
1910 QCBOREncode_Finish() is called.
1911
1912 If this has been called more times than QCBOREncode_BstrWrap(), then
1913 @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1914 QCBOREncode_Finish() is called.
1915
1916 If this is called and it is not a wrapping bstr that is currently
1917 open, @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
1918 QCBOREncode_Finish() is called.
1919
1920 QCBOREncode_CloseBstrWrap() is a deprecated version of this function
1921 that is equivalent to the call with @c bIncludeCBORHead @c true.
1922 */
1923void QCBOREncode_CloseBstrWrap2(QCBOREncodeContext *pCtx, bool bIncludeCBORHead, UsefulBufC *pWrappedCBOR);
1924
1925static void QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR);
1926
1927
1928/**
Laurence Lundblade8d3b8552021-06-10 11:11:54 -07001929 * @brief Cancel byte string wrapping.
1930 *
1931 * @param[in] pCtx The encoding context.
1932 *
1933 * This cancels QCBOREncode_BstrWrap() making tghe encoding as if it
1934 * were never called.
1935 *
1936 * WARNING: This does not work on QCBOREncode_BstrWrapInMap()
1937 * or QCBOREncode_BstrWrapInMapN() and there is no error detection
1938 * of an attempt at their use.
1939 *
1940 * This only works if nothing has been added into the wrapped byte
1941 * string. If something has been added, this sets the error
1942 * @ref QCBOR_ERR_CANNOT_CANCEL.
1943 */
1944void QCBOREncode_CancelBstrWrap(QCBOREncodeContext *pCtx);
1945
1946
1947/**
Michael Eckel5c531332020-03-02 01:35:30 +01001948 @brief Add some already-encoded CBOR bytes.
1949
1950 @param[in] pCtx The encoding context to add the already-encode CBOR to.
1951 @param[in] Encoded The already-encoded CBOR to add to the context.
1952
1953 The encoded CBOR being added must be fully conforming CBOR. It must
1954 be complete with no arrays or maps that are incomplete. While this
1955 encoder doesn't ever produce indefinite lengths, it is OK for the
1956 raw CBOR added here to have indefinite lengths.
1957
1958 The raw CBOR added here is not checked in anyway. If it is not
1959 conforming or has open arrays or such, the final encoded CBOR
1960 will probably be wrong or not what was intended.
1961
1962 If the encoded CBOR being added here contains multiple items, they
1963 must be enclosed in a map or array. At the top level the raw
1964 CBOR must be a single data item.
1965 */
1966static void QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded);
1967
1968static void QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded);
1969
1970static void QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded);
1971
1972
1973/**
1974 @brief Get the encoded result.
1975
1976 @param[in] pCtx The context to finish encoding with.
Laurence Lundblade8510f8c2020-12-01 11:31:16 -08001977 @param[out] pEncodedCBOR Structure in which the pointer and length of the encoded
1978 CBOR is returned.
Michael Eckel5c531332020-03-02 01:35:30 +01001979
Laurence Lundbladeb9702452021-03-08 21:02:57 -08001980 @retval QCBOR_SUCCESS Encoded CBOR is returned.
1981
Michael Eckel5c531332020-03-02 01:35:30 +01001982 @retval QCBOR_ERR_TOO_MANY_CLOSES Nesting error
1983
1984 @retval QCBOR_ERR_CLOSE_MISMATCH Nesting error
1985
1986 @retval QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN Nesting error
1987
1988 @retval QCBOR_ERR_BUFFER_TOO_LARGE Encoded output buffer size
1989
1990 @retval QCBOR_ERR_BUFFER_TOO_SMALL Encoded output buffer size
1991
1992 @retval QCBOR_ERR_ARRAY_NESTING_TOO_DEEP Implementation limit
1993
1994 @retval QCBOR_ERR_ARRAY_TOO_LONG Implementation limit
1995
Laurence Lundblade8510f8c2020-12-01 11:31:16 -08001996 On success, the pointer and length of the encoded CBOR are returned
1997 in @c *pEncodedCBOR. The pointer is the same pointer that was passed
1998 in to QCBOREncode_Init(). Note that it is not const when passed to
1999 QCBOREncode_Init(), but it is const when returned here. The length
2000 will be smaller than or equal to the length passed in when
2001 QCBOREncode_Init() as this is the length of the actual result, not
2002 the size of the buffer it was written to.
Michael Eckel5c531332020-03-02 01:35:30 +01002003
Laurence Lundblade8510f8c2020-12-01 11:31:16 -08002004 If a @c NULL was passed for @c Storage.ptr when QCBOREncode_Init()
2005 was called, @c NULL will be returned here, but the length will be
2006 that of the CBOR that would have been encoded.
Michael Eckel5c531332020-03-02 01:35:30 +01002007
2008 Encoding errors primarily manifest here as most other encoding function
2009 do no return an error. They just set the error state in the encode
2010 context after which no encoding function does anything.
2011
2012 Three types of errors manifest here. The first type are nesting
2013 errors where the number of @c QCBOREncode_OpenXxx() calls do not
2014 match the number @c QCBOREncode_CloseXxx() calls. The solution is to
2015 fix the calling code.
2016
2017 The second type of error is because the buffer given is either too
2018 small or too large. The remedy is to give a correctly sized buffer.
2019
2020 The third type are due to limits in this implementation. @ref
2021 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP can be worked around by encoding the
2022 CBOR in two (or more) phases and adding the CBOR from the first phase
2023 to the second with @c QCBOREncode_AddEncoded().
2024
2025 If an error is returned, the buffer may have partially encoded
2026 incorrect CBOR in it and it should not be used. Likewise, the length
2027 may be incorrect and should not be used.
2028
2029 Note that the error could have occurred in one of the many @c
2030 QCBOREncode_AddXxx() calls long before QCBOREncode_Finish() was
2031 called. This error handling reduces the CBOR implementation size but
2032 makes debugging harder.
2033
2034 This may be called multiple times. It will always return the same. It
2035 can also be interleaved with calls to QCBOREncode_FinishGetSize().
2036
2037 QCBOREncode_GetErrorState() can be called to get the current
Laurence Lundblade8510f8c2020-12-01 11:31:16 -08002038 error state in order to abort encoding early as an optimization, but
2039 calling it is is never required.
Michael Eckel5c531332020-03-02 01:35:30 +01002040 */
2041QCBORError QCBOREncode_Finish(QCBOREncodeContext *pCtx, UsefulBufC *pEncodedCBOR);
2042
2043
2044/**
2045 @brief Get the encoded CBOR and error status.
2046
2047 @param[in] pCtx The context to finish encoding with.
2048 @param[out] uEncodedLen The length of the encoded or potentially
2049 encoded CBOR in bytes.
2050
2051 @return The same errors as QCBOREncode_Finish().
2052
2053 This functions the same as QCBOREncode_Finish(), but only returns the
2054 size of the encoded output.
2055 */
2056QCBORError QCBOREncode_FinishGetSize(QCBOREncodeContext *pCtx, size_t *uEncodedLen);
2057
2058
2059/**
2060 @brief Indicate whether output buffer is NULL or not.
2061
2062 @param[in] pCtx The encoding context.
2063
2064 @return 1 if the output buffer is @c NULL.
2065
2066 Sometimes a @c NULL input buffer is given to QCBOREncode_Init() so
2067 that the size of the generated CBOR can be calculated without
2068 allocating a buffer for it. This returns 1 when the output buffer is
2069 NULL and 0 when it is not.
2070*/
2071static int QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx);
2072
Laurence Lundblade825164e2020-10-22 20:18:06 -07002073
2074/**
Michael Eckel5c531332020-03-02 01:35:30 +01002075 @brief Get the encoding error state.
2076
2077 @param[in] pCtx The encoding context.
2078
Laurence Lundbladeabf5c572020-06-29 21:21:29 -07002079 @return One of @ref QCBORError. See return values from
Michael Eckel5c531332020-03-02 01:35:30 +01002080 QCBOREncode_Finish()
2081
2082 Normally encoding errors need only be handled at the end of encoding
2083 when QCBOREncode_Finish() is called. This can be called to get the
2084 error result before finish should there be a need to halt encoding
2085 before QCBOREncode_Finish() is called.
2086*/
2087static QCBORError QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx);
2088
2089
2090/**
2091 Encode the "head" of a CBOR data item.
2092
2093 @param buffer Buffer to output the encoded head to; must be
2094 @ref QCBOR_HEAD_BUFFER_SIZE bytes in size.
2095 @param uMajorType One of CBOR_MAJOR_TYPE_XX.
2096 @param uMinLen The minimum number of bytes to encode uNumber. Almost always
2097 this is 0 to use preferred minimal encoding. If this is 4,
2098 then even the values 0xffff and smaller will be encoded
Laurence Lundblade98427e92020-09-28 21:33:23 -07002099 in 4 bytes. This is used primarily when encoding a
Michael Eckel5c531332020-03-02 01:35:30 +01002100 float or double put into uNumber as the leading zero bytes
2101 for them must be encoded.
2102 @param uNumber The numeric argument part of the CBOR head.
2103 @return Pointer and length of the encoded head or
Laurence Lundblade9a3b6252020-10-21 21:30:31 -07002104 @ref NULLUsefulBufC if the output buffer is too small.
Michael Eckel5c531332020-03-02 01:35:30 +01002105
Laurence Lundblade98427e92020-09-28 21:33:23 -07002106 Callers do not to need to call this for normal CBOR encoding. Note that it doesn't even
Michael Eckel5c531332020-03-02 01:35:30 +01002107 take a @ref QCBOREncodeContext argument.
2108
2109 This encodes the major type and argument part of a data item. The
2110 argument is an integer that is usually either the value or the length
2111 of the data item.
2112
2113 This is exposed in the public interface to allow hashing of some CBOR
2114 data types, bstr in particular, a chunk at a time so the full CBOR
2115 doesn't have to be encoded in a contiguous buffer.
2116
2117 For example, if you have a 100,000 byte binary blob in a buffer that
2118 needs to be a bstr encoded and then hashed. You could allocate a
2119 100,010 byte buffer and encode it normally. Alternatively, you can
2120 encode the head in a 10 byte buffer with this function, hash that and
2121 then hash the 100,000 bytes using the same hash context.
2122
2123 See also QCBOREncode_AddBytesLenOnly();
2124 */
2125UsefulBufC QCBOREncode_EncodeHead(UsefulBuf buffer,
2126 uint8_t uMajorType,
2127 uint8_t uMinLen,
2128 uint64_t uNumber);
2129
2130
Michael Eckel5c531332020-03-02 01:35:30 +01002131
2132
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002133/* =========================================================================
2134 BEGINNING OF PRIVATE INLINE IMPLEMENTATION
2135 ========================================================================= */
Michael Eckel5c531332020-03-02 01:35:30 +01002136
2137/**
2138 @brief Semi-private method to add a buffer full of bytes to encoded output
2139
2140 @param[in] pCtx The encoding context to add the integer to.
2141 @param[in] uMajorType The CBOR major type of the bytes.
2142 @param[in] Bytes The bytes to add.
2143
2144 Use QCBOREncode_AddText() or QCBOREncode_AddBytes() or
2145 QCBOREncode_AddEncoded() instead. They are inline functions that call
2146 this and supply the correct major type. This function is public to
2147 make the inline functions work to keep the overall code size down and
2148 because the C language has no way to make it private.
2149
2150 If this is called the major type should be @c
2151 CBOR_MAJOR_TYPE_TEXT_STRING, @c CBOR_MAJOR_TYPE_BYTE_STRING or @c
2152 CBOR_MAJOR_NONE_TYPE_RAW. The last one is special for adding
2153 already-encoded CBOR.
2154 */
2155void QCBOREncode_AddBuffer(QCBOREncodeContext *pCtx, uint8_t uMajorType, UsefulBufC Bytes);
2156
2157
2158/**
2159 @brief Semi-private method to open a map, array or bstr-wrapped CBOR
2160
2161 @param[in] pCtx The context to add to.
2162 @param[in] uMajorType The major CBOR type to close
2163
2164 Call QCBOREncode_OpenArray(), QCBOREncode_OpenMap() or
2165 QCBOREncode_BstrWrap() instead of this.
2166 */
2167void QCBOREncode_OpenMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType);
2168
2169
2170/**
2171 @brief Semi-private method to open a map, array with indefinite length
2172
2173 @param[in] pCtx The context to add to.
2174 @param[in] uMajorType The major CBOR type to close
2175
2176 Call QCBOREncode_OpenArrayIndefiniteLength() or
2177 QCBOREncode_OpenMapIndefiniteLength() instead of this.
2178 */
2179void QCBOREncode_OpenMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx, uint8_t uMajorType);
2180
2181
2182/**
2183 @brief Semi-private method to close a map, array or bstr wrapped CBOR
2184
2185 @param[in] pCtx The context to add to.
2186 @param[in] uMajorType The major CBOR type to close.
2187
2188 Call QCBOREncode_CloseArray() or QCBOREncode_CloseMap() instead of this.
2189 */
2190void QCBOREncode_CloseMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType);
2191
2192
2193/**
2194 @brief Semi-private method to close a map, array with indefinite length
2195
2196 @param[in] pCtx The context to add to.
2197 @param[in] uMajorType The major CBOR type to close.
2198
2199 Call QCBOREncode_CloseArrayIndefiniteLength() or
2200 QCBOREncode_CloseMapIndefiniteLength() instead of this.
2201 */
2202void QCBOREncode_CloseMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx,
2203 uint8_t uMajorType);
2204
2205
2206/**
2207 @brief Semi-private method to add simple types.
2208
2209 @param[in] pCtx The encoding context to add the simple value to.
2210 @param[in] uMinLen Minimum encoding size for uNum. Usually 0.
2211 @param[in] uNum One of CBOR_SIMPLEV_FALSE through _UNDEF or other.
2212
2213 This is used to add simple types like true and false.
2214
2215 Call QCBOREncode_AddBool(), QCBOREncode_AddNULL(),
2216 QCBOREncode_AddUndef() instead of this.
2217
2218 This function can add simple values that are not defined by CBOR
2219 yet. This expansion point in CBOR should not be used unless they are
2220 standardized.
2221
2222 Error handling is the same as QCBOREncode_AddInt64().
2223 */
2224void QCBOREncode_AddType7(QCBOREncodeContext *pCtx, uint8_t uMinLen, uint64_t uNum);
2225
2226
2227/**
2228 @brief Semi-private method to add bigfloats and decimal fractions.
2229
Laurence Lundblade1fa579b2020-11-25 00:31:37 -08002230 @param[in] pCtx The encoding context to add the value to.
2231 @param[in] uTag The type 6 tag indicating what this is to be.
2232 @param[in] BigNumMantissa Is @ref NULLUsefulBufC if mantissa is an
2233 @c int64_t or the actual big number mantissa
2234 if not.
2235 @param[in] bBigNumIsNegative This is @c true if the big number is negative.
2236 @param[in] nMantissa The @c int64_t mantissa if it is not a big number.
2237 @param[in] nExponent The exponent.
Michael Eckel5c531332020-03-02 01:35:30 +01002238
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002239 This outputs either the @ref CBOR_TAG_DECIMAL_FRACTION or @ref
2240 CBOR_TAG_BIGFLOAT tag. if @c uTag is @ref CBOR_TAG_INVALID64, then
2241 this outputs the "borrowed" content format.
Michael Eckel5c531332020-03-02 01:35:30 +01002242
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002243 The tag content output by this is an array with two members, the
2244 exponent and then the mantissa. The mantissa can be either a big
2245 number or an @c int64_t.
2246
2247 This implementation cannot output an exponent further from 0 than
Laurence Lundblade9a3b6252020-10-21 21:30:31 -07002248 @c INT64_MAX.
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002249
Laurence Lundblade1fa579b2020-11-25 00:31:37 -08002250 To output a mantissa that is between INT64_MAX and UINT64_MAX from 0,
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002251 it must be as a big number.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002252
Michael Eckel5c531332020-03-02 01:35:30 +01002253 Typically, QCBOREncode_AddDecimalFraction(), QCBOREncode_AddBigFloat(),
2254 QCBOREncode_AddDecimalFractionBigNum() or QCBOREncode_AddBigFloatBigNum()
2255 is called instead of this.
2256 */
2257void QCBOREncode_AddExponentAndMantissa(QCBOREncodeContext *pCtx,
2258 uint64_t uTag,
2259 UsefulBufC BigNumMantissa,
2260 bool bBigNumIsNegative,
2261 int64_t nMantissa,
2262 int64_t nExponent);
2263
2264/**
2265 @brief Semi-private method to add only the type and length of a byte string.
2266
2267 @param[in] pCtx The context to initialize.
2268 @param[in] Bytes Pointer and length of the input data.
2269
2270 This is the same as QCBOREncode_AddBytes() except it only adds the
2271 CBOR encoding for the type and the length. It doesn't actually add
2272 the bytes. You can't actually produce correct CBOR with this and the
2273 rest of this API. It is only used for a special case where
2274 the valid CBOR is created manually by putting this type and length in
2275 and then adding the actual bytes. In particular, when only a hash of
2276 the encoded CBOR is needed, where the type and header are hashed
2277 separately and then the bytes is hashed. This makes it possible to
2278 implement COSE Sign1 with only one copy of the payload in the output
2279 buffer, rather than two, roughly cutting memory use in half.
2280
2281 This is only used for this odd case, but this is a supported
2282 tested function.
2283
2284 See also QCBOREncode_EncodeHead().
2285*/
2286static inline void QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
2287
2288static inline void QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
2289
2290static inline void QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
2291
2292
2293
2294
2295
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002296static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002297QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pMe, const char *szLabel, int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002298{
2299 // Use _AddBuffer() because _AddSZString() is defined below, not above
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002300 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
2301 QCBOREncode_AddInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002302}
2303
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002304static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002305QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pMe, int64_t nLabel, int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002306{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002307 QCBOREncode_AddInt64(pMe, nLabel);
2308 QCBOREncode_AddInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002309}
2310
2311
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002312static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002313QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pMe, const char *szLabel, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002314{
2315 // Use _AddBuffer() because _AddSZString() is defined below, not above
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002316 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
2317 QCBOREncode_AddUInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002318}
2319
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002320static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002321QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002322{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002323 QCBOREncode_AddInt64(pMe, nLabel);
2324 QCBOREncode_AddUInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002325}
2326
2327
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002328static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002329QCBOREncode_AddText(QCBOREncodeContext *pMe, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002330{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002331 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002332}
2333
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002334static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002335QCBOREncode_AddTextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002336{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002337 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szLabel));
2338 QCBOREncode_AddText(pMe, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002339}
2340
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002341static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002342QCBOREncode_AddTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002343{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002344 QCBOREncode_AddInt64(pMe, nLabel);
2345 QCBOREncode_AddText(pMe, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002346}
2347
2348
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002349inline static void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002350QCBOREncode_AddSZString(QCBOREncodeContext *pMe, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002351{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002352 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szString));
Michael Eckel5c531332020-03-02 01:35:30 +01002353}
2354
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002355static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002356QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pMe, const char *szLabel, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002357{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002358 QCBOREncode_AddSZString(pMe, szLabel);
2359 QCBOREncode_AddSZString(pMe, szString);
Michael Eckel5c531332020-03-02 01:35:30 +01002360}
2361
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002362static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002363QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002364{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002365 QCBOREncode_AddInt64(pMe, nLabel);
2366 QCBOREncode_AddSZString(pMe, szString);
Michael Eckel5c531332020-03-02 01:35:30 +01002367}
2368
2369
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +02002370#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002371static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002372QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pMe, const char *szLabel, double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002373{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002374 QCBOREncode_AddSZString(pMe, szLabel);
2375 QCBOREncode_AddDouble(pMe, dNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002376}
2377
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002378static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002379QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pMe, int64_t nLabel, double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002380{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002381 QCBOREncode_AddInt64(pMe, nLabel);
2382 QCBOREncode_AddDouble(pMe, dNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002383}
2384
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002385static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002386QCBOREncode_AddFloatToMap(QCBOREncodeContext *pMe, const char *szLabel, float dNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002387{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002388 QCBOREncode_AddSZString(pMe, szLabel);
2389 QCBOREncode_AddFloat(pMe, dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002390}
2391
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002392static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002393QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pMe, int64_t nLabel, float fNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002394{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002395 QCBOREncode_AddInt64(pMe, nLabel);
2396 QCBOREncode_AddFloat(pMe, fNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002397}
2398
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002399static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002400QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pMe, const char *szLabel, double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002401{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002402 QCBOREncode_AddSZString(pMe, szLabel);
2403 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002404}
2405
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002406static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002407QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pMe, int64_t nLabel, double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002408{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002409 QCBOREncode_AddInt64(pMe, nLabel);
2410 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002411}
2412
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002413static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002414QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pMe, const char *szLabel, float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002415{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002416 QCBOREncode_AddSZString(pMe, szLabel);
2417 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002418}
2419
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002420static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002421QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pMe, int64_t nLabel, float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002422{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002423 QCBOREncode_AddInt64(pMe, nLabel);
2424 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002425}
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +02002426#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002427
Michael Eckel5c531332020-03-02 01:35:30 +01002428
Laurence Lundblade9b334962020-08-27 10:55:53 -07002429
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002430static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002431QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pMe, uint8_t uTag, int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002432{
2433 if(uTag == QCBOR_ENCODE_AS_TAG) {
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002434 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_EPOCH);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002435 }
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002436 QCBOREncode_AddInt64(pMe, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002437}
2438
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002439static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002440QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTag, int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002441{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002442 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002443 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002444}
2445
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002446static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002447QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTag, int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002448{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002449 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002450 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002451}
2452
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002453static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002454QCBOREncode_AddDateEpoch(QCBOREncodeContext *pMe, int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002455{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002456 QCBOREncode_AddTDateEpoch(pMe, QCBOR_ENCODE_AS_TAG, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002457}
2458
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002459static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002460QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pMe, const char *szLabel, int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002461{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002462 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002463 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002464}
2465
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002466static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002467QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pMe, int64_t nLabel, int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002468{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002469 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002470 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002471}
2472
2473
Laurence Lundblade46d63e92021-05-13 11:37:10 -07002474static inline void
2475QCBOREncode_AddTDaysEpoch(QCBOREncodeContext *pMe, uint8_t uTag, int64_t nDays)
2476{
2477 if(uTag == QCBOR_ENCODE_AS_TAG) {
2478 QCBOREncode_AddTag(pMe, CBOR_TAG_DAYS_EPOCH);
2479 }
2480 QCBOREncode_AddInt64(pMe, nDays);
2481}
2482
2483static inline void
2484QCBOREncode_AddTDaysEpochToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTag, int64_t nDays)
2485{
2486 QCBOREncode_AddSZString(pMe, szLabel);
2487 QCBOREncode_AddTDaysEpoch(pMe, uTag, nDays);
2488}
2489
2490static inline void
2491QCBOREncode_AddTDaysEpochToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTag, int64_t nDays)
2492{
2493 QCBOREncode_AddInt64(pMe, nLabel);
2494 QCBOREncode_AddTDaysEpoch(pMe, uTag, nDays);
2495}
2496
Laurence Lundblade9b334962020-08-27 10:55:53 -07002497
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002498static inline void
2499QCBOREncode_AddBytes(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002500{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002501 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002502}
2503
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002504static inline void
2505QCBOREncode_AddBytesToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002506{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002507 QCBOREncode_AddSZString(pMe, szLabel);
2508 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002509}
2510
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002511static inline void
2512QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002513{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002514 QCBOREncode_AddInt64(pMe, nLabel);
2515 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002516}
2517
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002518static inline void
Laurence Lundbladeb24faef2022-04-26 11:03:08 -06002519QCBOREncode_OpenBytesInMapSZ(QCBOREncodeContext *pMe, const char *szLabel, UsefulBuf *pPlace)
2520{
2521 QCBOREncode_AddSZString(pMe, szLabel);
2522 QCBOREncode_OpenBytes(pMe, pPlace);
2523}
2524
2525static inline void
2526QCBOREncode_OpenBytesInMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBuf *pPlace)
2527{
2528 QCBOREncode_AddInt64(pMe, nLabel);
2529 QCBOREncode_OpenBytes(pMe, pPlace);
2530}
2531
2532static inline void
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002533QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002534{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002535 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002536}
2537
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002538static inline void
2539QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002540{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002541 QCBOREncode_AddSZString(pMe, szLabel);
2542 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002543}
2544
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002545static inline void
2546QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002547{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002548 QCBOREncode_AddInt64(pMe, nLabel);
2549 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002550}
2551
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002552
2553static inline void
2554QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002555{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002556 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2557 QCBOREncode_AddTag(pMe, CBOR_TAG_BIN_UUID);
2558 }
2559 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002560}
2561
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002562static inline void
2563QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pMe,
2564 const char *szLabel,
2565 uint8_t uTagRequirement,
2566 UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002567{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002568 QCBOREncode_AddSZString(pMe, szLabel);
2569 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002570}
2571
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002572static inline void
2573QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002574{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002575 QCBOREncode_AddInt64(pMe, nLabel);
2576 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002577}
2578
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002579static inline void
2580QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002581{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002582 QCBOREncode_AddTBinaryUUID(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002583}
2584
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002585static inline void
2586QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002587{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002588 QCBOREncode_AddTBinaryUUIDToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002589}
2590
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002591static inline void
2592QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002593{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002594 QCBOREncode_AddTBinaryUUIDToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002595}
2596
2597
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002598static inline void
2599QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002600{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002601 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2602 QCBOREncode_AddTag(pMe, CBOR_TAG_POS_BIGNUM);
2603 }
2604 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002605}
2606
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002607static inline void
2608QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pMe,
2609 const char *szLabel,
2610 uint8_t uTagRequirement,
2611 UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002612{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002613 QCBOREncode_AddSZString(pMe, szLabel);
2614 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002615}
2616
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002617static inline void
2618QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002619{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002620 QCBOREncode_AddInt64(pMe, nLabel);
2621 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002622}
2623
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002624static inline void
2625QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2626{
2627 QCBOREncode_AddTPositiveBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2628}
2629
2630static inline void
2631QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2632{
2633 QCBOREncode_AddTPositiveBignumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2634}
2635
2636static inline void
2637QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2638{
2639 QCBOREncode_AddTPositiveBignumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2640}
2641
2642
2643static inline void
2644QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
2645{
2646 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2647 QCBOREncode_AddTag(pMe, CBOR_TAG_NEG_BIGNUM);
2648 }
2649 QCBOREncode_AddBytes(pMe, Bytes);
2650}
2651
2652static inline void
2653QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pMe,
2654 const char *szLabel,
2655 uint8_t uTagRequirement,
2656 UsefulBufC Bytes)
2657{
2658 QCBOREncode_AddSZString(pMe, szLabel);
2659 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2660}
2661
2662static inline void
2663QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
2664{
2665 QCBOREncode_AddInt64(pMe, nLabel);
2666 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2667}
2668
2669static inline void
2670QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2671{
2672 QCBOREncode_AddTNegativeBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2673}
2674
2675static inline void
2676QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2677{
2678 QCBOREncode_AddTNegativeBignumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2679}
2680
2681static inline void
2682QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2683{
2684 QCBOREncode_AddTNegativeBignumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2685}
2686
2687
Michael Eckel5c531332020-03-02 01:35:30 +01002688
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07002689#ifndef QCBOR_DISABLE_EXP_AND_MANTISSA
Michael Eckel5c531332020-03-02 01:35:30 +01002690
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002691static inline void
2692QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pMe,
2693 uint8_t uTagRequirement,
2694 int64_t nMantissa,
2695 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002696{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002697 uint64_t uTag;
2698 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2699 uTag = CBOR_TAG_DECIMAL_FRACTION;
2700 } else {
2701 uTag = CBOR_TAG_INVALID64;
2702 }
2703 QCBOREncode_AddExponentAndMantissa(pMe,
2704 uTag,
Michael Eckel5c531332020-03-02 01:35:30 +01002705 NULLUsefulBufC,
2706 false,
2707 nMantissa,
2708 nBase10Exponent);
2709}
2710
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002711static inline void
2712QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pMe,
2713 const char *szLabel,
2714 uint8_t uTagRequirement,
2715 int64_t nMantissa,
2716 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002717{
2718 QCBOREncode_AddSZString(pMe, szLabel);
2719 QCBOREncode_AddTDecimalFraction(pMe, uTagRequirement, nMantissa, nBase10Exponent);
2720}
2721
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002722static inline void
2723QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pMe,
2724 int64_t nLabel,
2725 uint8_t uTagRequirement,
2726 int64_t nMantissa,
2727 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002728{
2729 QCBOREncode_AddInt64(pMe, nLabel);
2730 QCBOREncode_AddTDecimalFraction(pMe, uTagRequirement, nMantissa, nBase10Exponent);
2731}
2732
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002733static inline void
2734QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pMe,
2735 int64_t nMantissa,
2736 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002737{
2738 QCBOREncode_AddTDecimalFraction(pMe, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
2739}
2740
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002741static inline void
2742QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pMe,
2743 const char *szLabel,
2744 int64_t nMantissa,
2745 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002746{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002747 QCBOREncode_AddTDecimalFractionToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002748}
2749
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002750static inline void
2751QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pMe,
2752 int64_t nLabel,
2753 int64_t nMantissa,
2754 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002755{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002756 QCBOREncode_AddTDecimalFractionToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002757}
2758
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002759
2760
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002761static inline void
2762QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pMe,
2763 uint8_t uTagRequirement,
2764 UsefulBufC Mantissa,
2765 bool bIsNegative,
2766 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002767{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002768 uint64_t uTag;
2769 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2770 uTag = CBOR_TAG_DECIMAL_FRACTION;
2771 } else {
2772 uTag = CBOR_TAG_INVALID64;
2773 }
2774 QCBOREncode_AddExponentAndMantissa(pMe,
2775 uTag,
Michael Eckel5c531332020-03-02 01:35:30 +01002776 Mantissa, bIsNegative,
2777 0,
2778 nBase10Exponent);
2779}
2780
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002781static inline void
2782QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
2783 const char *szLabel,
2784 uint8_t uTagRequirement,
2785 UsefulBufC Mantissa,
2786 bool bIsNegative,
2787 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002788{
2789 QCBOREncode_AddSZString(pMe, szLabel);
2790 QCBOREncode_AddTDecimalFractionBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase10Exponent);
2791}
2792
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002793static inline void
2794QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
2795 int64_t nLabel,
2796 uint8_t uTagRequirement,
2797 UsefulBufC Mantissa,
2798 bool bIsNegative,
2799 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002800{
2801 QCBOREncode_AddInt64(pMe, nLabel);
2802 QCBOREncode_AddTDecimalFractionBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase10Exponent);
2803}
2804
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002805static inline void
2806QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pMe,
2807 UsefulBufC Mantissa,
2808 bool bIsNegative,
2809 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002810{
2811 QCBOREncode_AddTDecimalFractionBigNum(pMe, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase10Exponent);
2812}
2813
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002814static inline void
2815QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
2816 const char *szLabel,
2817 UsefulBufC Mantissa,
2818 bool bIsNegative,
2819 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002820{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002821 QCBOREncode_AddTDecimalFractionBigNumToMapSZ(pMe,
2822 szLabel,
2823 QCBOR_ENCODE_AS_TAG,
2824 Mantissa,
2825 bIsNegative,
2826 nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002827}
2828
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002829static inline void
2830QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
2831 int64_t nLabel,
2832 UsefulBufC Mantissa,
2833 bool bIsNegative,
2834 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002835{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002836 QCBOREncode_AddTDecimalFractionBigNumToMapN(pMe,
2837 nLabel,
2838 QCBOR_ENCODE_AS_TAG,
2839 Mantissa,
2840 bIsNegative,
2841 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002842}
2843
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002844
2845
2846
2847
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002848static inline void
2849QCBOREncode_AddTBigFloat(QCBOREncodeContext *pMe,
2850 uint8_t uTagRequirement,
2851 int64_t nMantissa,
2852 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002853{
2854 uint64_t uTag;
2855 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2856 uTag = CBOR_TAG_BIGFLOAT;
2857 } else {
2858 uTag = CBOR_TAG_INVALID64;
2859 }
2860 QCBOREncode_AddExponentAndMantissa(pMe, uTag, NULLUsefulBufC, false, nMantissa, nBase2Exponent);
2861}
2862
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002863static inline void
2864QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pMe,
2865 const char *szLabel,
2866 uint8_t uTagRequirement,
2867 int64_t nMantissa,
2868 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002869{
2870 QCBOREncode_AddSZString(pMe, szLabel);
2871 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
2872}
2873
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002874static inline void
2875QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pMe,
2876 int64_t nLabel,
2877 uint8_t uTagRequirement,
2878 int64_t nMantissa,
2879 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002880{
2881 QCBOREncode_AddInt64(pMe, nLabel);
2882 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
2883}
2884
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002885static inline void
2886QCBOREncode_AddBigFloat(QCBOREncodeContext *pMe,
2887 int64_t nMantissa,
2888 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002889{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002890 QCBOREncode_AddTBigFloat(pMe, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002891}
2892
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002893static inline void
2894QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pMe,
2895 const char *szLabel,
2896 int64_t nMantissa,
2897 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002898{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002899 QCBOREncode_AddTBigFloatToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002900}
2901
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002902static inline void
2903QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pMe,
2904 int64_t nLabel,
2905 int64_t nMantissa,
2906 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002907{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002908 QCBOREncode_AddTBigFloatToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002909}
2910
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002911
2912
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002913static inline void
2914QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pMe,
2915 uint8_t uTagRequirement,
2916 UsefulBufC Mantissa,
2917 bool bIsNegative,
2918 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002919{
2920 uint64_t uTag;
2921 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2922 uTag = CBOR_TAG_BIGFLOAT;
2923 } else {
2924 uTag = CBOR_TAG_INVALID64;
2925 }
2926 QCBOREncode_AddExponentAndMantissa(pMe, uTag, Mantissa, bIsNegative, 0, nBase2Exponent);
2927}
2928
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002929static inline void
2930QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pMe,
2931 const char *szLabel,
2932 uint8_t uTagRequirement,
2933 UsefulBufC Mantissa,
2934 bool bIsNegative,
2935 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002936{
2937 QCBOREncode_AddSZString(pMe, szLabel);
2938 QCBOREncode_AddTBigFloatBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase2Exponent);
2939}
2940
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002941static inline void
2942QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
2943 int64_t nLabel,
2944 uint8_t uTagRequirement,
2945 UsefulBufC Mantissa,
2946 bool bIsNegative,
2947 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002948{
2949 QCBOREncode_AddInt64(pMe, nLabel);
2950 QCBOREncode_AddTBigFloatBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase2Exponent);
2951}
2952
2953
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002954static inline void
2955QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pMe,
2956 UsefulBufC Mantissa,
2957 bool bIsNegative,
2958 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002959{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002960 QCBOREncode_AddTBigFloatBigNum(pMe, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002961}
2962
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002963static inline void
2964QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pMe,
2965 const char *szLabel,
2966 UsefulBufC Mantissa,
2967 bool bIsNegative,
2968 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002969{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002970 QCBOREncode_AddTBigFloatBigNumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002971}
2972
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002973static inline void
2974QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
2975 int64_t nLabel,
2976 UsefulBufC Mantissa,
2977 bool bIsNegative,
2978 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002979{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002980 QCBOREncode_AddTBigFloatBigNumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002981}
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07002982#endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
Michael Eckel5c531332020-03-02 01:35:30 +01002983
2984
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002985static inline void
2986QCBOREncode_AddTURI(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002987{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002988 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2989 QCBOREncode_AddTag(pMe, CBOR_TAG_URI);
2990 }
2991 QCBOREncode_AddText(pMe, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002992}
2993
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002994static inline void
2995QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002996{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002997 QCBOREncode_AddSZString(pMe, szLabel);
2998 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002999}
3000
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003001static inline void
3002QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01003003{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003004 QCBOREncode_AddInt64(pMe, nLabel);
3005 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
3006}
3007
3008static inline void
3009QCBOREncode_AddURI(QCBOREncodeContext *pMe, UsefulBufC URI)
3010{
3011 QCBOREncode_AddTURI(pMe, QCBOR_ENCODE_AS_TAG, URI);
3012}
3013
3014static inline void
3015QCBOREncode_AddURIToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC URI)
3016{
3017 QCBOREncode_AddTURIToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, URI);
3018}
3019
3020static inline void
3021QCBOREncode_AddURIToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC URI)
3022{
3023 QCBOREncode_AddTURIToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01003024}
3025
3026
3027
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003028static inline void
3029QCBOREncode_AddTB64Text(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003030{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003031 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3032 QCBOREncode_AddTag(pMe, CBOR_TAG_B64);
3033 }
3034 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003035}
3036
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003037static inline void
3038QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pMe,
3039 const char *szLabel,
3040 uint8_t uTagRequirement,
3041 UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003042{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003043 QCBOREncode_AddSZString(pMe, szLabel);
3044 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003045}
3046
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003047static inline void
3048QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003049{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003050 QCBOREncode_AddInt64(pMe, nLabel);
3051 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
3052}
3053
3054static inline void
3055QCBOREncode_AddB64Text(QCBOREncodeContext *pMe, UsefulBufC B64Text)
3056{
3057 QCBOREncode_AddTB64Text(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
3058}
3059
3060static inline void
3061QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC B64Text)
3062{
3063 QCBOREncode_AddTB64TextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
3064}
3065
3066static inline void
3067QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC B64Text)
3068{
3069 QCBOREncode_AddTB64TextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003070}
3071
3072
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003073
3074static inline void
3075QCBOREncode_AddTB64URLText(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003076{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003077 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3078 QCBOREncode_AddTag(pMe, CBOR_TAG_B64URL);
3079 }
3080 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003081}
3082
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003083static inline void
3084QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pMe,
3085 const char *szLabel,
3086 uint8_t uTagRequirement,
3087 UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003088{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003089 QCBOREncode_AddSZString(pMe, szLabel);
3090 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003091}
3092
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003093static inline void
3094QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01003095{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003096 QCBOREncode_AddInt64(pMe, nLabel);
3097 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
3098}
3099
3100static inline void
3101QCBOREncode_AddB64URLText(QCBOREncodeContext *pMe, UsefulBufC B64Text)
3102{
3103 QCBOREncode_AddTB64URLText(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
3104}
3105
3106static inline void
3107QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC B64Text)
3108{
3109 QCBOREncode_AddTB64URLTextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
3110}
3111
3112static inline void
3113QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC B64Text)
3114{
3115 QCBOREncode_AddTB64URLTextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01003116}
3117
3118
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003119
3120static inline void
3121QCBOREncode_AddTRegex(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003122{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003123 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3124 QCBOREncode_AddTag(pMe, CBOR_TAG_REGEX);
3125 }
3126 QCBOREncode_AddText(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01003127}
3128
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003129static inline void
3130QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003131{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003132 QCBOREncode_AddSZString(pMe, szLabel);
3133 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01003134}
3135
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003136static inline void
3137QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01003138{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003139 QCBOREncode_AddInt64(pMe, nLabel);
3140 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
3141}
3142
3143static inline void
3144QCBOREncode_AddRegex(QCBOREncodeContext *pMe, UsefulBufC Bytes)
3145{
3146 QCBOREncode_AddTRegex(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
3147}
3148
3149static inline void
3150QCBOREncode_AddRegexToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
3151{
3152 QCBOREncode_AddTRegexToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
3153}
3154
3155static inline void
3156QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
3157{
3158 QCBOREncode_AddTRegexToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
3159
Michael Eckel5c531332020-03-02 01:35:30 +01003160}
3161
3162
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003163static inline void
3164QCBOREncode_AddTMIMEData(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01003165{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003166 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
Laurence Lundblade4982f412020-09-18 23:02:18 -07003167 QCBOREncode_AddTag(pMe, CBOR_TAG_BINARY_MIME);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003168 }
Laurence Lundblade4982f412020-09-18 23:02:18 -07003169 QCBOREncode_AddBytes(pMe, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01003170}
3171
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003172static inline void
3173QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pMe,
3174 const char *szLabel,
3175 uint8_t uTagRequirement,
3176 UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01003177{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003178 QCBOREncode_AddSZString(pMe, szLabel);
3179 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01003180}
3181
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003182static inline void
3183QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01003184{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003185 QCBOREncode_AddInt64(pMe, nLabel);
3186 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
3187}
3188
3189static inline void
3190QCBOREncode_AddMIMEData(QCBOREncodeContext *pMe, UsefulBufC MIMEData)
3191{
3192 QCBOREncode_AddTMIMEData(pMe, QCBOR_ENCODE_AS_TAG, MIMEData);
3193}
3194
3195static inline void
3196QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC MIMEData)
3197{
3198 QCBOREncode_AddTMIMEDataToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
3199}
3200
3201static inline void
3202QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC MIMEData)
3203{
3204 QCBOREncode_AddTMIMEDataToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01003205}
3206
3207
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003208static inline void
3209QCBOREncode_AddTDateString(QCBOREncodeContext *pMe, uint8_t uTagRequirement, const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01003210{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003211 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3212 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_STRING);
3213 }
3214 QCBOREncode_AddSZString(pMe, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01003215}
3216
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003217static inline void
3218QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pMe,
3219 const char *szLabel,
3220 uint8_t uTagRequirement,
3221 const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01003222{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003223 QCBOREncode_AddSZString(pMe, szLabel);
3224 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01003225}
3226
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003227static inline void
3228QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01003229{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003230 QCBOREncode_AddInt64(pMe, nLabel);
3231 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
3232}
3233
3234static inline void
3235QCBOREncode_AddDateString(QCBOREncodeContext *pMe, const char *szDate)
3236{
3237 QCBOREncode_AddTDateString(pMe, QCBOR_ENCODE_AS_TAG, szDate);
3238}
3239
3240static inline void
3241QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pMe, const char *szLabel, const char *szDate)
3242{
3243 QCBOREncode_AddTDateStringToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, szDate);
3244}
3245
3246static inline void
3247QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, const char *szDate)
3248{
3249 QCBOREncode_AddTDateStringToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01003250}
3251
3252
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003253static inline void
Laurence Lundblade46d63e92021-05-13 11:37:10 -07003254QCBOREncode_AddTDaysString(QCBOREncodeContext *pMe, uint8_t uTagRequirement, const char *szDate)
3255{
3256 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3257 QCBOREncode_AddTag(pMe, CBOR_TAG_DAYS_STRING);
3258 }
3259 QCBOREncode_AddSZString(pMe, szDate);
3260}
3261
3262static inline void
3263QCBOREncode_AddTDaysStringToMapSZ(QCBOREncodeContext *pMe,
3264 const char *szLabel,
3265 uint8_t uTagRequirement,
3266 const char *szDate)
3267{
3268 QCBOREncode_AddSZString(pMe, szLabel);
3269 QCBOREncode_AddTDaysString(pMe, uTagRequirement, szDate);
3270}
3271
3272static inline void
3273QCBOREncode_AddTDaysStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, const char *szDate)
3274{
3275 QCBOREncode_AddInt64(pMe, nLabel);
3276 QCBOREncode_AddTDaysString(pMe, uTagRequirement, szDate);
3277}
3278
3279
3280
3281static inline void
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003282QCBOREncode_AddSimple(QCBOREncodeContext *pMe, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01003283{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003284 QCBOREncode_AddType7(pMe, 0, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01003285}
3286
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003287static inline void
3288QCBOREncode_AddSimpleToMap(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01003289{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003290 QCBOREncode_AddSZString(pMe, szLabel);
3291 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01003292}
3293
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003294static inline void
3295QCBOREncode_AddSimpleToMapN(QCBOREncodeContext *pMe, int nLabel, uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01003296{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003297 QCBOREncode_AddInt64(pMe, nLabel);
3298 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01003299}
3300
3301
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003302static inline void
3303QCBOREncode_AddBool(QCBOREncodeContext *pMe, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01003304{
3305 uint8_t uSimple = CBOR_SIMPLEV_FALSE;
3306 if(b) {
3307 uSimple = CBOR_SIMPLEV_TRUE;
3308 }
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003309 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01003310}
3311
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003312static inline void
3313QCBOREncode_AddBoolToMap(QCBOREncodeContext *pMe, const char *szLabel, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01003314{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003315 QCBOREncode_AddSZString(pMe, szLabel);
3316 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01003317}
3318
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003319static inline void
3320QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pMe, int64_t nLabel, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01003321{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003322 QCBOREncode_AddInt64(pMe, nLabel);
3323 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01003324}
3325
3326
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003327static inline void
3328QCBOREncode_AddNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003329{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003330 QCBOREncode_AddSimple(pMe, CBOR_SIMPLEV_NULL);
Michael Eckel5c531332020-03-02 01:35:30 +01003331}
3332
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003333static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003334QCBOREncode_AddNULLToMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003335{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003336 QCBOREncode_AddSZString(pMe, szLabel);
3337 QCBOREncode_AddNULL(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003338}
3339
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003340static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003341QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003342{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003343 QCBOREncode_AddInt64(pMe, nLabel);
3344 QCBOREncode_AddNULL(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003345}
3346
3347
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003348static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003349QCBOREncode_AddUndef(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003350{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003351 QCBOREncode_AddSimple(pMe, CBOR_SIMPLEV_UNDEF);
Michael Eckel5c531332020-03-02 01:35:30 +01003352}
3353
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003354static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003355QCBOREncode_AddUndefToMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003356{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003357 QCBOREncode_AddSZString(pMe, szLabel);
3358 QCBOREncode_AddUndef(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003359}
3360
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003361static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003362QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003363{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003364 QCBOREncode_AddInt64(pMe, nLabel);
3365 QCBOREncode_AddUndef(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003366}
3367
3368
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003369static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003370QCBOREncode_OpenArray(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003371{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003372 QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
Michael Eckel5c531332020-03-02 01:35:30 +01003373}
3374
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003375static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003376QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003377{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003378 QCBOREncode_AddSZString(pMe, szLabel);
3379 QCBOREncode_OpenArray(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003380}
3381
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003382static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003383QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003384{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003385 QCBOREncode_AddInt64(pMe, nLabel);
3386 QCBOREncode_OpenArray(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003387}
3388
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003389static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003390QCBOREncode_CloseArray(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003391{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003392 QCBOREncode_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
Michael Eckel5c531332020-03-02 01:35:30 +01003393}
3394
3395
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003396static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003397QCBOREncode_OpenMap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003398{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003399 QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
Michael Eckel5c531332020-03-02 01:35:30 +01003400}
3401
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003402static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003403QCBOREncode_OpenMapInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003404{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003405 QCBOREncode_AddSZString(pMe, szLabel);
3406 QCBOREncode_OpenMap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003407}
3408
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003409static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003410QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003411{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003412 QCBOREncode_AddInt64(pMe, nLabel);
3413 QCBOREncode_OpenMap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003414}
3415
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003416static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003417QCBOREncode_CloseMap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003418{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003419 QCBOREncode_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
Michael Eckel5c531332020-03-02 01:35:30 +01003420}
3421
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003422static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003423QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003424{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003425 QCBOREncode_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003426}
3427
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003428static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003429QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003430{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003431 QCBOREncode_AddSZString(pMe, szLabel);
3432 QCBOREncode_OpenArrayIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003433}
3434
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003435static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003436QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003437{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003438 QCBOREncode_AddInt64(pMe, nLabel);
3439 QCBOREncode_OpenArrayIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003440}
3441
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003442static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003443QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003444{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003445 QCBOREncode_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003446}
3447
3448
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003449static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003450QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003451{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003452 QCBOREncode_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003453}
3454
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003455static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003456QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003457{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003458 QCBOREncode_AddSZString(pMe, szLabel);
3459 QCBOREncode_OpenMapIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003460}
3461
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003462static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003463QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003464{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003465 QCBOREncode_AddInt64(pMe, nLabel);
3466 QCBOREncode_OpenMapIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003467}
3468
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003469static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003470QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003471{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003472 QCBOREncode_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003473}
3474
3475
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003476static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003477QCBOREncode_BstrWrap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003478{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003479 QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_BYTE_STRING);
Michael Eckel5c531332020-03-02 01:35:30 +01003480}
3481
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003482static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003483QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003484{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003485 QCBOREncode_AddSZString(pMe, szLabel);
3486 QCBOREncode_BstrWrap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003487}
3488
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003489static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003490QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003491{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003492 QCBOREncode_AddInt64(pMe, nLabel);
3493 QCBOREncode_BstrWrap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003494}
3495
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003496static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003497QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pMe, UsefulBufC *pWrappedCBOR)
Michael Eckel5c531332020-03-02 01:35:30 +01003498{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003499 QCBOREncode_CloseBstrWrap2(pMe, true, pWrappedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01003500}
3501
3502
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003503static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003504QCBOREncode_AddEncoded(QCBOREncodeContext *pMe, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003505{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003506 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_RAW, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003507}
3508
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003509static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003510QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003511{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003512 QCBOREncode_AddSZString(pMe, szLabel);
3513 QCBOREncode_AddEncoded(pMe, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003514}
3515
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003516static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003517QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003518{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003519 QCBOREncode_AddInt64(pMe, nLabel);
3520 QCBOREncode_AddEncoded(pMe, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003521}
3522
3523
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003524static inline int
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003525QCBOREncode_IsBufferNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003526{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003527 return UsefulOutBuf_IsBufferNULL(&(pMe->OutBuf));
Michael Eckel5c531332020-03-02 01:35:30 +01003528}
3529
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003530static inline QCBORError
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003531QCBOREncode_GetErrorState(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003532{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003533 if(UsefulOutBuf_GetError(&(pMe->OutBuf))) {
Michael Eckel5c531332020-03-02 01:35:30 +01003534 // Items didn't fit in the buffer.
3535 // This check catches this condition for all the appends and inserts
3536 // so checks aren't needed when the appends and inserts are performed.
3537 // And of course UsefulBuf will never overrun the input buffer given
3538 // to it. No complex analysis of the error handling in this file is
3539 // needed to know that is true. Just read the UsefulBuf code.
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003540 pMe->uError = QCBOR_ERR_BUFFER_TOO_SMALL;
Michael Eckel5c531332020-03-02 01:35:30 +01003541 // QCBOR_ERR_BUFFER_TOO_SMALL masks other errors, but that is
3542 // OK. Once the caller fixes this, they'll be unmasked.
3543 }
3544
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003545 return (QCBORError)pMe->uError;
Michael Eckel5c531332020-03-02 01:35:30 +01003546}
3547
3548
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003549/* ========================================================================
3550 END OF PRIVATE INLINE IMPLEMENTATION
3551 ======================================================================== */
Michael Eckel5c531332020-03-02 01:35:30 +01003552
3553#ifdef __cplusplus
3554}
3555#endif
3556
Laurence Lundblade844bb5c2020-03-01 17:27:25 -08003557#endif /* qcbor_encode_h */