blob: 202a98f2b04230e6a65763c3fb86237157e2fc76 [file] [log] [blame]
Michael Eckel5c531332020-03-02 01:35:30 +01001/*==============================================================================
2 Copyright (c) 2016-2018, The Linux Foundation.
Laurence Lundbladeb9702452021-03-08 21:02:57 -08003 Copyright (c) 2018-2021, 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
170 with no output buffer to compute the length of the needed output
171 buffer. Then the correct sized output buffer is allocated. Last the
172 encoder is invoked again, this time with the output buffer.
173
174 The double invocation is not required if the maximum output buffer
175 size can be predicted. This is usually possible for simple CBOR
176 structures. If the double invocation is implemented, it can be in a
177 loop or function as in the example code so that the code doesn't have
178 to actually be written twice, saving code size.
179
180 If a buffer too small to hold the encoded output is given, the error
181 @ref QCBOR_ERR_BUFFER_TOO_SMALL will be returned. Data will never be
182 written off the end of the output buffer no matter which functions
183 here are called or what parameters are passed to them.
184
185 The encoding error handling is simple. The only possible errors are
186 trying to encode structures that are too large or too complex. There
187 are no internal malloc calls so there will be no failures for out of
188 memory. The error state is tracked internally, so there is no need
189 to check for errors when encoding. Only the return code from
190 QCBOREncode_Finish() need be checked as once an error happens, the
191 encoder goes into an error state and calls to it to add more data
192 will do nothing. An error check is not needed after every data item
193 is added.
194
195 Encoding generally proceeds by calling QCBOREncode_Init(), calling
196 lots of @c QCBOREncode_AddXxx() functions and calling
197 QCBOREncode_Finish(). There are many @c QCBOREncode_AddXxx()
198 functions for various data types. The input buffers need only to be
199 valid during the @c QCBOREncode_AddXxx() calls as the data is copied
200 into the output buffer.
201
202 There are three `Add` functions for each data type. The first / main
203 one for the type is for adding the data item to an array. The second
204 one's name ends in `ToMap`, is used for adding data items to maps and
205 takes a string argument that is its label in the map. The third one
206 ends in `ToMapN`, is also used for adding data items to maps, and
207 takes an integer argument that is its label in the map.
208
209 The simplest aggregate type is an array, which is a simple ordered
210 set of items without labels the same as JSON arrays. Call
211 QCBOREncode_OpenArray() to open a new array, then various @c
212 QCBOREncode_AddXxx() functions to put items in the array and then
213 QCBOREncode_CloseArray(). Nesting to the limit @ref
214 QCBOR_MAX_ARRAY_NESTING is allowed. All opens must be matched by
215 closes or an encoding error will be returned.
216
217 The other aggregate type is a map which does use labels. The `Add`
218 functions that end in `ToMap` and `ToMapN` are convenient ways to add
219 labeled data items to a map. You can also call any type of `Add`
220 function once to add a label of any time and then call any type of
221 `Add` again to add its value.
222
223 Note that when you nest arrays or maps in a map, the nested array or
224 map has a label.
Laurence Lundblade2feb1e12020-07-15 03:50:45 -0700225
Laurence Lundbladee3553422020-05-02 11:11:17 -0700226 Many CBOR-based protocols start with an array or map. This makes them
227 self-delimiting. No external length or end marker is needed to know
228 the end. It is also possible not start this way, in which case this
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700229 it is usually called a CBOR sequence which is described in
230 [RFC 8742] (https://tools.ietf.org/html/rfc8742). This encoder supports
231 either just by whether the first item added is an array, map or other.
Michael Eckel5c531332020-03-02 01:35:30 +0100232
Laurence Lundbladeda97bf42020-11-05 03:38:50 -0800233 If QCBOR is compiled with QCBOR_DISABLE_ENCODE_USAGE_GUARDS defined,
234 the errors QCBOR_ERR_CLOSE_MISMATCH, QCBOR_ERR_ARRAY_TOO_LONG,
235 QCBOR_ERR_TOO_MANY_CLOSES, QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN, and
236 QCBOR_ERR_ENCODE_UNSUPPORTED will never be returned. It is up to the
237 caller to make sure that opened maps, arrays and byte-string wrapping
238 is closed correctly and that QCBOREncode_AddType7() is called
239 correctly. With this defined, it is easier to make a mistake when
240 authoring the encoding of a protocol that will output not well formed
241 CBOR, but as long as the calling code is correct, it is safe to
242 disable these checks. Bounds checking that prevents security issues
243 in the code is still enforced. This define reduces the size of
244 encoding object code by about 150 bytes.
245
Michael Eckel5c531332020-03-02 01:35:30 +0100246 @anchor Tags-Overview
Laurence Lundblade9b334962020-08-27 10:55:53 -0700247
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700248 ## Tags Overview
249
250 Any CBOR data item can be made into a tag to add semantics, define a
251 new data type or such. Some tags are fully standardized and some are
252 just registered. Others are not registered and used in a proprietary
253 way.
Michael Eckel5c531332020-03-02 01:35:30 +0100254
255 Encoding and decoding of many of the registered tags is fully
256 implemented by QCBOR. It is also possible to encode and decode tags
257 that are not directly supported. For many use cases the built-in tag
258 support should be adequate.
259
260 For example, the registered epoch date tag is supported in encoding
261 by QCBOREncode_AddDateEpoch() and in decoding by @ref
262 QCBOR_TYPE_DATE_EPOCH and the @c epochDate member of @ref
263 QCBORItem. This is typical of the built-in tag support. There is an
264 API to encode data for it and a @c QCBOR_TYPE_XXX when it is decoded.
265
266 Tags are registered in the [IANA CBOR Tags Registry]
267 (https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml). There
268 are roughly three options to create a new tag. First, a public
269 specification can be created and the new tag registered with IANA.
270 This is the most formal. Second, the new tag can be registered with
271 IANA with just a short description rather than a full specification.
272 These tags must be greater than 256. Third, a tag can be used without
273 any IANA registration, though the registry should be checked to see
274 that the new value doesn't collide with one that is registered. The
275 value of these tags must be 256 or larger.
276
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700277 See also @ref CBORTags and @ref Tag-Usage
278
Michael Eckel5c531332020-03-02 01:35:30 +0100279 The encoding side of tags not built-in is handled by
280 QCBOREncode_AddTag() and is relatively simple. Tag decoding is more
281 complex and mainly handled by QCBORDecode_GetNext(). Decoding of the
282 structure of tagged data not built-in (if there is any) has to be
283 implemented by the caller.
284
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700285 @anchor Floating-Point
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700286
287 ## Floating-Point
288
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700289 By default QCBOR fully supports IEEE 754 floating-point:
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700290 - Encode/decode of double, single and half-precision
291 - CBOR preferred serialization of floating-point
292 - Floating-point epoch dates
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700293
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700294 For the most part, the type double is used in the interface for
295 floating-point values. In the default configuration, all decoded
296 floating-point values are returned as a double.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700297
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700298 With CBOR preferred serialization, the encoder outputs the smallest
299 representation of the double or float that preserves precision. Zero,
300 NaN and infinity are always output as a half-precision, each taking
301 just 2 bytes. This reduces the number of bytes needed to encode
Laurence Lundblade4b270642020-08-14 12:53:07 -0700302 double and single-precision, especially if zero, NaN and infinity are
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700303 frequently used.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700304
Laurence Lundblade4b270642020-08-14 12:53:07 -0700305 To avoid use of preferred serialization in the standard configuration
306 when encoding, use QCBOREncode_AddDoubleNoPreferred() or
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700307 QCBOREncode_AddFloatNoPreferred().
308
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700309 This implementation of preferred floating-point serialization and
310 half-precision does not depend on the CPU having floating-point HW or
311 the compiler bringing in a (sometimes large) library to compensate
Laurence Lundblade4b270642020-08-14 12:53:07 -0700312 for lack of CPU support. This implementation uses shifts and masks
313 rather than floating-point functions.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700314
Laurence Lundblade4b270642020-08-14 12:53:07 -0700315 To reduce overall object code by about 900 bytes, define
316 QCBOR_DISABLE_PREFERRED_FLOAT. This will eliminate all support for
317 preferred serialization and half-precision. An error will be returned
318 when attempting to decode half-precision. A float will always be
319 encoded and decoded as 32-bits and a double will always be encoded
320 and decoded as 64 bits.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700321
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700322 Note that even if QCBOR_DISABLE_PREFERRED_FLOAT is not defined all
323 the float-point encoding object code can be avoided by never calling
Laurence Lundbladefe09bbf2020-07-16 12:14:51 -0700324 any functions that encode double or float. Just not calling
325 floating-point functions will reduce object code by about 500 bytes.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700326
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700327 On CPUs that have no floating-point hardware,
328 QCBOR_DISABLE_FLOAT_HW_USE should be defined in most cases. If it is
329 not, then the compiler will bring in possibly large software
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700330 libraries to compensate. Defining QCBOR_DISABLE_FLOAT_HW_USE reduces
331 object code size on CPUs with floating-point hardware by a tiny
332 amount and eliminates the need for <math.h>
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700333
Laurence Lundblade4b270642020-08-14 12:53:07 -0700334 When QCBOR_DISABLE_FLOAT_HW_USE is defined, trying to decoding
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700335 floating-point dates will give error
336 @ref QCBOR_ERR_FLOAT_DATE_DISABLED and decoded single-precision
337 numbers will be returned as @ref QCBOR_TYPE_FLOAT instead of
338 converting them to double as usual.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700339
340 If both QCBOR_DISABLE_FLOAT_HW_USE and QCBOR_DISABLE_PREFERRED_FLOAT
Laurence Lundblade4b270642020-08-14 12:53:07 -0700341 are defined, then the only thing QCBOR can do is encode/decode a C
342 float type as 32-bits and a C double type as 64-bits. Floating-point
343 epoch dates will be unsupported.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700344
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200345 If USEFULBUF_DISABLE_ALL_FLOATis defined, then floating point support is
346 completely disabled. Decoding functions return @ref QCBOR_ERR_ALL_FLOAT_DISABLED
347 if a floating point value is encountered during decoding. Functions that are
348 encoding floating point values are not available.
349
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700350 ## Limitations
351
Michael Eckel5c531332020-03-02 01:35:30 +0100352 Summary Limits of this implementation:
353 - The entire encoded CBOR must fit into contiguous memory.
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700354 - Max size of encoded / decoded CBOR data is a few bytes less than @c UINT32_MAX (4GB).
Michael Eckel5c531332020-03-02 01:35:30 +0100355 - Max array / map nesting level when encoding / decoding is
356 @ref QCBOR_MAX_ARRAY_NESTING (this is typically 15).
357 - Max items in an array or map when encoding / decoding is
358 @ref QCBOR_MAX_ITEMS_IN_ARRAY (typically 65,536).
359 - Does not directly support labels in maps other than text strings & integers.
360 - Does not directly support integer labels greater than @c INT64_MAX.
361 - Epoch dates limited to @c INT64_MAX (+/- 292 billion years).
362 - Exponents for bigfloats and decimal integers are limited to @c INT64_MAX.
363 - Tags on labels are ignored during decoding.
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700364 - The maximum tag nesting is @c QCBOR_MAX_TAGS_PER_ITEM (typically 4).
Michael Eckel5c531332020-03-02 01:35:30 +0100365 - Works only on 32- and 64-bit CPUs (modifications could make it work
366 on 16-bit CPUs).
367
368 The public interface uses @c size_t for all lengths. Internally the
369 implementation uses 32-bit lengths by design to use less memory and
370 fit structures on the stack. This limits the encoded CBOR it can work
371 with to size @c UINT32_MAX (4GB) which should be enough.
372
373 This implementation assumes two's compliment integer machines. @c
374 <stdint.h> also requires this. It is possible to modify this
375 implementation for another integer representation, but all modern
376 machines seem to be two's compliment.
Michael Eckel5c531332020-03-02 01:35:30 +0100377 */
378
379
Laurence Lundblade825164e2020-10-22 20:18:06 -0700380/**
Michael Eckel5c531332020-03-02 01:35:30 +0100381 The size of the buffer to be passed to QCBOREncode_EncodeHead(). It is one
382 byte larger than sizeof(uint64_t) + 1, the actual maximum size of the
Laurence Lundblade825164e2020-10-22 20:18:06 -0700383 head of a CBOR data item because QCBOREncode_EncodeHead() needs
Michael Eckel5c531332020-03-02 01:35:30 +0100384 one extra byte to work.
385 */
386#define QCBOR_HEAD_BUFFER_SIZE (sizeof(uint64_t) + 2)
387
Michael Eckel5c531332020-03-02 01:35:30 +0100388
Laurence Lundblade9b334962020-08-27 10:55:53 -0700389/**
Laurence Lundblade825164e2020-10-22 20:18:06 -0700390 Output the full CBOR tag. See @ref CBORTags, @ref Tag-Usage and
391 @ref Tags-Overview.
Laurence Lundblade9b334962020-08-27 10:55:53 -0700392 */
393#define QCBOR_ENCODE_AS_TAG 0
394
395/**
Laurence Lundblade825164e2020-10-22 20:18:06 -0700396 Output only the 'borrowed' content format for the relevant tag.
397 See @ref CBORTags, @ref Tag-Usage and @ref Tags-Overview.
Laurence Lundblade9b334962020-08-27 10:55:53 -0700398 */
399#define QCBOR_ENCODE_AS_BORROWED 1
400
Michael Eckel5c531332020-03-02 01:35:30 +0100401
402/**
403 QCBOREncodeContext is the data type that holds context for all the
404 encoding functions. It is less than 200 bytes, so it can go on the
405 stack. The contents are opaque, and the caller should not access
406 internal members. A context may be re used serially as long as it is
407 re initialized.
408 */
409typedef struct _QCBOREncodeContext QCBOREncodeContext;
410
411
412/**
413 Initialize the encoder to prepare to encode some CBOR.
414
415 @param[in,out] pCtx The encoder context to initialize.
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800416 @param[in] Storage The buffer into which the encoded result
417 will be written.
Michael Eckel5c531332020-03-02 01:35:30 +0100418
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800419 Call this once at the start of an encoding of some CBOR. Then call
420 the many functions like QCBOREncode_AddInt64() and
421 QCBOREncode_AddText() to add the different data items. Finally, call
422 QCBOREncode_Finish() to get the pointer and length of the encoded
423 result.
Michael Eckel5c531332020-03-02 01:35:30 +0100424
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800425 The primary purpose of this function is to give the pointer and
426 length of the output buffer into which the encoded CBOR will be
427 written. This is done with a @ref UsefulBuf structure, which is just
428 a pointer and length (it is equivalent to two parameters, one a
429 pointer and one a length, but a little prettier).
Michael Eckel5c531332020-03-02 01:35:30 +0100430
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800431 The output buffer can be allocated any way (malloc, stack,
432 static). It is just some memory that QCBOR writes to. The length must
433 be the length of the allocated buffer. QCBOR will never write past
434 that length, but might write up to that length. If the buffer is too
435 small, encoding will go into an error state and not write anything
436 further.
437
438 If allocating on the stack the convenience macro
439 UsefulBuf_MAKE_STACK_UB() can be used, but its use is not required.
440
441 Since there is no reallocation or such, the output buffer must be
442 correctly sized when passed in here. It is OK, but wasteful if it is
443 too large. One way to pick the size is to figure out the maximum size
444 that will ever be needed and hard code a buffer of that size.
445
446 Another way to do it is to have QCBOR calculate it for you. To do
447 this set @c Storage.ptr to @c NULL and @c Storage.len to @c
448 UINT32_MAX. Then call all the functions to add the CBOR exactly as if
449 encoding for real. Then call QCBOREncode_Finish(). The pointer
450 returned will be @c NULL, but the length returned is that of what would
451 be encoded. Once the length is obtained, allocate a buffer of that
452 size, call QCBOREncode_Init() again with the real buffer. Call all
453 the add functions again and finally, QCBOREncode_Finish() to obtain
454 the final result. This uses almost twice the CPU time, but that is
455 usually not an issue.
456
457 See QCBOREncode_Finish() for how the pointer and length for the
458 encoded CBOR is returned.
459
460 The maximum output buffer size allowed is @c UINT32_MAX (4GB). The
461 error @ref QCBOR_ERR_BUFFER_TOO_LARGE will be returned by
462 QCBOREncode_Finish() if a larger buffer length is passed in.
Michael Eckel5c531332020-03-02 01:35:30 +0100463
464 A @ref QCBOREncodeContext can be reused over and over as long as
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800465 QCBOREncode_Init() is called before each use.
Michael Eckel5c531332020-03-02 01:35:30 +0100466 */
467void QCBOREncode_Init(QCBOREncodeContext *pCtx, UsefulBuf Storage);
468
469
470/**
471 @brief Add a signed 64-bit integer to the encoded output.
472
473 @param[in] pCtx The encoding context to add the integer to.
474 @param[in] nNum The integer to add.
475
476 The integer will be encoded and added to the CBOR output.
477
478 This function figures out the size and the sign and encodes in the
479 correct minimal CBOR. Specifically, it will select CBOR major type 0
480 or 1 based on sign and will encode to 1, 2, 4 or 8 bytes depending on
481 the value of the integer. Values less than 24 effectively encode to
482 one byte because they are encoded in with the CBOR major type. This
483 is a neat and efficient characteristic of CBOR that can be taken
484 advantage of when designing CBOR-based protocols. If integers like
485 tags can be kept between -23 and 23 they will be encoded in one byte
486 including the major type.
487
488 If you pass a smaller int, say an @c int16_t or a small value, say
489 100, the encoding will still be CBOR's most compact that can
490 represent the value. For example, CBOR always encodes the value 0 as
491 one byte, 0x00. The representation as 0x00 includes identification of
492 the type as an integer too as the major type for an integer is 0. See
Laurence Lundbladec02e13e2020-12-06 05:45:41 -0800493 [RFC 8949] (https://tools.ietf.org/html/rfc8949) Appendix A for more
494 examples of CBOR encoding. This compact encoding is also preferred
495 serialization CBOR as per section 34.1 in RFC 8949.
Michael Eckel5c531332020-03-02 01:35:30 +0100496
497 There are no functions to add @c int16_t or @c int32_t because they
498 are not necessary because this always encodes to the smallest number
499 of bytes based on the value (If this code is running on a 32-bit
500 machine having a way to add 32-bit integers would reduce code size
501 some).
502
503 If the encoding context is in an error state, this will do
504 nothing. If an error occurs when adding this integer, the internal
505 error flag will be set, and the error will be returned when
506 QCBOREncode_Finish() is called.
507
508 See also QCBOREncode_AddUInt64().
509 */
510void QCBOREncode_AddInt64(QCBOREncodeContext *pCtx, int64_t nNum);
511
512static void QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum);
513
514static void QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum);
515
516
517/**
518 @brief Add an unsigned 64-bit integer to the encoded output.
519
520 @param[in] pCtx The encoding context to add the integer to.
521 @param[in] uNum The integer to add.
522
523 The integer will be encoded and added to the CBOR output.
524
525 The only reason so use this function is for integers larger than @c
526 INT64_MAX and smaller than @c UINT64_MAX. Otherwise
527 QCBOREncode_AddInt64() will work fine.
528
529 Error handling is the same as for QCBOREncode_AddInt64().
530 */
531void QCBOREncode_AddUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
532
533static void QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum);
534
535static void QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum);
536
537
538/**
539 @brief Add a UTF-8 text string to the encoded output.
540
541 @param[in] pCtx The encoding context to add the text to.
542 @param[in] Text Pointer and length of text to add.
543
544 The text passed in must be unencoded UTF-8 according to [RFC 3629]
545 (https://tools.ietf.org/html/rfc3629). There is no NULL
546 termination. The text is added as CBOR major type 3.
547
548 If called with @c nBytesLen equal to 0, an empty string will be
549 added. When @c nBytesLen is 0, @c pBytes may be @c NULL.
550
551 Note that the restriction of the buffer length to a @c uint32_t is
552 entirely intentional as this encoder is not capable of encoding
553 lengths greater. This limit to 4GB for a text string should not be a
554 problem.
555
Laurence Lundbladeadaf5c22020-09-25 10:37:09 -0700556 Text lines in Internet protocols (on the wire) are delimited by
557 either a CRLF or just an LF. Officially many protocols specify CRLF,
558 but implementations often work with either. CBOR type 3 text can be
559 either line ending, even a mixture of both.
560
561 Operating systems usually have a line end convention. Windows uses
562 CRLF. Linux and MacOS use LF. Some applications on a given OS may
563 work with either and some may not.
564
565 The majority of use cases and CBOR protocols using type 3 text will
566 work with either line ending. However, some use cases or protocols
567 may not work with either in which case translation to and/or from the
568 local line end convention, typically that of the OS, is necessary.
569
570 QCBOR does no line ending translation for type 3 text when encoding
571 and decoding.
572
Michael Eckel5c531332020-03-02 01:35:30 +0100573 Error handling is the same as QCBOREncode_AddInt64().
574 */
575static void QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text);
576
577static void QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text);
578
579static void QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text);
580
581
582/**
583 @brief Add a UTF-8 text string to the encoded output.
584
585 @param[in] pCtx The encoding context to add the text to.
586 @param[in] szString Null-terminated text to add.
587
588 This works the same as QCBOREncode_AddText().
589 */
590static void QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString);
591
592static void QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString);
593
594static void QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString);
595
596
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200597#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Michael Eckel5c531332020-03-02 01:35:30 +0100598/**
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700599 @brief Add a double-precision floating-point number to the encoded output.
Michael Eckel5c531332020-03-02 01:35:30 +0100600
601 @param[in] pCtx The encoding context to add the double to.
602 @param[in] dNum The double-precision number to add.
603
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700604 This encodes and outputs a floating-point number. CBOR major type 7
605 is used.
Michael Eckel5c531332020-03-02 01:35:30 +0100606
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700607 This implements preferred serialization, selectively encoding the
608 double-precision floating-point number as either double-precision,
609 single-precision or half-precision. Infinity, NaN and 0 are always
610 encoded as half-precision. If no precision will be lost in the
611 conversion to half-precision, then it will be converted and
612 encoded. If not and no precision will be lost in conversion to
613 single-precision, then it will be converted and encoded. If not, then
614 no conversion is performed, and it encoded as a double-precision.
Michael Eckel5c531332020-03-02 01:35:30 +0100615
616 Half-precision floating-point numbers take up 2 bytes, half that of
617 single-precision, one quarter of double-precision
618
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700619 This automatically reduces the size of encoded CBOR, maybe even by
620 four if most of values are 0, infinity or NaN.
Michael Eckel5c531332020-03-02 01:35:30 +0100621
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700622 When decoded, QCBOR will usually return these values as
623 double-precision.
624
625 It is possible to disable this preferred serialization when compiling
626 QCBOR. In that case, this functions the same as
627 QCBOREncode_AddDoubleNoPreferred().
Michael Eckel5c531332020-03-02 01:35:30 +0100628
629 Error handling is the same as QCBOREncode_AddInt64().
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700630
631 See also QCBOREncode_AddDoubleNoPreferred(), QCBOREncode_AddFloat()
632 and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
Michael Eckel5c531332020-03-02 01:35:30 +0100633 */
634void QCBOREncode_AddDouble(QCBOREncodeContext *pCtx, double dNum);
635
636static void QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
637
638static void QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
639
640
641/**
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700642 @brief Add a single-precision floating-point number to the encoded output.
643
644 @param[in] pCtx The encoding context to add the double to.
645 @param[in] fNum The single-precision number to add.
646
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700647 This is identical to QCBOREncode_AddDouble() except the input is
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700648 single-precision.
649
650 See also QCBOREncode_AddDouble(), QCBOREncode_AddDoubleNoPreferred(),
651 and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
652*/
653void QCBOREncode_AddFloat(QCBOREncodeContext *pCtx, float fNum);
654
655static void QCBOREncode_AddFloatToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
656
657static void QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700658
659
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700660/**
661 @brief Add a double-precision floating-point number without preferred encoding.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700662
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700663 @param[in] pCtx The encoding context to add the double to.
664 @param[in] dNum The double-precision number to add.
665
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700666 This always outputs the number as a 64-bit double-precision.
667 Preferred serialization is not used.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700668
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700669 Error handling is the same as QCBOREncode_AddInt64().
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700670
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700671 See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
672 QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700673*/
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700674void QCBOREncode_AddDoubleNoPreferred(QCBOREncodeContext *pCtx, double dNum);
675
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700676static void QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
677
678static void QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
679
680
681/**
682 @brief Add a single-precision floating-point number without preferred encoding.
683
684 @param[in] pCtx The encoding context to add the double to.
685 @param[in] fNum The single-precision number to add.
686
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700687 This always outputs the number as a 32-bit single-precision.
688 Preferred serialization is not used.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700689
690 Error handling is the same as QCBOREncode_AddInt64().
691
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700692 See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
693 QCBOREncode_AddDoubleNoPreferred() and @ref Floating-Point.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700694*/
695void QCBOREncode_AddFloatNoPreferred(QCBOREncodeContext *pCtx, float fNum);
696
697static void QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
698
699static void QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float fNum);
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +0200700#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700701
702
Michael Eckel5c531332020-03-02 01:35:30 +0100703/**
704 @brief Add an optional tag.
705
706 @param[in] pCtx The encoding context to add the tag to.
707 @param[in] uTag The tag to add
708
709 This outputs a CBOR major type 6 item that tags the next data item
710 that is output usually to indicate it is some new data type.
711
712 For many of the common standard tags, a function to encode data using
713 it is provided and this is not needed. For example,
714 QCBOREncode_AddDateEpoch() already exists to output integers
715 representing dates with the right tag.
716
717 The tag is applied to the next data item added to the encoded
718 output. That data item that is to be tagged can be of any major CBOR
719 type. Any number of tags can be added to a data item by calling this
720 multiple times before the data item is added.
721
722 See @ref Tags-Overview for discussion of creating new non-standard
723 tags. See QCBORDecode_GetNext() for discussion of decoding custom
724 tags.
725*/
Laurence Lundblade6416a0f2020-09-19 23:26:34 -0700726void QCBOREncode_AddTag(QCBOREncodeContext *pCtx, uint64_t uTag);
Michael Eckel5c531332020-03-02 01:35:30 +0100727
728
729/**
730 @brief Add an epoch-based date.
731
732 @param[in] pCtx The encoding context to add the date to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700733 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700734 @param[in] nDate Number of seconds since 1970-01-01T00:00Z in UTC time.
Michael Eckel5c531332020-03-02 01:35:30 +0100735
Laurence Lundbladec02e13e2020-12-06 05:45:41 -0800736 As per RFC 8949 this is similar to UNIX/Linux/POSIX dates. This is
Michael Eckel5c531332020-03-02 01:35:30 +0100737 the most compact way to specify a date and time in CBOR. Note that
738 this is always UTC and does not include the time zone. Use
739 QCBOREncode_AddDateString() if you want to include the time zone.
740
Laurence Lundblade46d63e92021-05-13 11:37:10 -0700741 The preferred integer encoding rules apply here so the date will be encoded in
Michael Eckel5c531332020-03-02 01:35:30 +0100742 a minimal number of bytes. Until about the year 2106 these dates will
743 encode in 6 bytes -- one byte for the tag, one byte for the type and
744 4 bytes for the integer. After that it will encode to 10 bytes.
745
746 Negative values are supported for dates before 1970.
747
748 If you care about leap-seconds and that level of accuracy, make sure
749 the system you are running this code on does it correctly. This code
750 just takes the value passed in.
751
752 This implementation cannot encode fractional seconds using float or
753 double even though that is allowed by CBOR, but you can encode them
Laurence Lundblade46d63e92021-05-13 11:37:10 -0700754 if you want to by calling QCBOREncode_AddTag() and QCBOREncode_AddDouble().
Michael Eckel5c531332020-03-02 01:35:30 +0100755
756 Error handling is the same as QCBOREncode_AddInt64().
Laurence Lundblade46d63e92021-05-13 11:37:10 -0700757
758 See also QCBOREncode_AddTDaysEpoch().
Michael Eckel5c531332020-03-02 01:35:30 +0100759 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700760static void QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pCtx,
761 uint8_t uTagRequirement,
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700762 int64_t nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -0700763
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700764static void QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pCtx,
765 const char *szLabel,
766 uint8_t uTagRequirement,
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700767 int64_t nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -0700768
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700769static void QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pCtx,
770 int64_t nLabel,
771 uint8_t uTagRequirement,
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700772 int64_t nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -0700773
774
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700775static void QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx,
776 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100777
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700778static void QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx,
779 const char *szLabel,
780 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100781
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700782static void QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx,
783 int64_t nLabel,
784 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100785
786
Laurence Lundblade46d63e92021-05-13 11:37:10 -0700787
788/**
789 @brief Add an epoch-based day-count date.
790
791 @param[in] pCtx The encoding context to add the date to.
792 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
793 @ref QCBOR_ENCODE_AS_BORROWED.
794 @param[in] nDays Number of days before or after 1970-01-0.
795
796 This date format is described in
797 [RFC 8943] (https://tools.ietf.org/html/rfc8943).
798
799 The integer encoding rules apply here so the date will be encoded in
800 a minimal number of bytes. Until about the year 2149 these dates will
801 encode in 4 bytes -- one byte for the tag, one byte for the type and
802 2 bytes for the integer.
803
804 See also QCBOREncode_AddTDateEpoch().
805
806*/
807static void QCBOREncode_AddTDaysEpoch(QCBOREncodeContext *pCtx,
808 uint8_t uTagRequirement,
809 int64_t nDays);
810
811static void QCBOREncode_AddTDaysEpochToMapSZ(QCBOREncodeContext *pCtx,
812 const char *szLabel,
813 uint8_t uTagRequirement,
814 int64_t nDays);
815
816static void QCBOREncode_AddTDaysEpochToMapN(QCBOREncodeContext *pCtx,
817 int64_t nLabel,
818 uint8_t uTagRequirement,
819 int64_t nDays);
820
821
822
823
Michael Eckel5c531332020-03-02 01:35:30 +0100824/**
825 @brief Add a byte string to the encoded output.
826
827 @param[in] pCtx The encoding context to add the bytes to.
828 @param[in] Bytes Pointer and length of the input data.
829
830 Simply adds the bytes to the encoded output as CBOR major type 2.
831
832 If called with @c Bytes.len equal to 0, an empty string will be
833 added. When @c Bytes.len is 0, @c Bytes.ptr may be @c NULL.
834
835 Error handling is the same as QCBOREncode_AddInt64().
836 */
837static void QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
838
839static void QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
840
841static void QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
842
843
Michael Eckel5c531332020-03-02 01:35:30 +0100844/**
845 @brief Add a binary UUID to the encoded output.
846
847 @param[in] pCtx The encoding context to add the UUID to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700848 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100849 @param[in] Bytes Pointer and length of the binary UUID.
850
851 A binary UUID as defined in [RFC 4122]
852 (https://tools.ietf.org/html/rfc4122) is added to the output.
853
854 It is output as CBOR major type 2, a binary string, with tag @ref
855 CBOR_TAG_BIN_UUID indicating the binary string is a UUID.
856 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700857static void QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pCtx,
858 uint8_t uTagRequirement,
859 UsefulBufC Bytes);
860
861static void QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pCtx,
862 const char *szLabel,
863 uint8_t uTagRequirement,
864 UsefulBufC Bytes);
865
866static void QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pCtx,
867 int64_t nLabel,
868 uint8_t uTagRequirement,
869 UsefulBufC Bytes);
870
871
Michael Eckel5c531332020-03-02 01:35:30 +0100872static void QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
873
874static void QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
875
876static void QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
877
878
879/**
880 @brief Add a positive big number to the encoded output.
881
882 @param[in] pCtx The encoding context to add the big number to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700883 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100884 @param[in] Bytes Pointer and length of the big number.
885
886 Big numbers are integers larger than 64-bits. Their format is
Laurence Lundbladec02e13e2020-12-06 05:45:41 -0800887 described in [RFC 8949] (https://tools.ietf.org/html/rfc8949).
Michael Eckel5c531332020-03-02 01:35:30 +0100888
889 It is output as CBOR major type 2, a binary string, with tag @ref
890 CBOR_TAG_POS_BIGNUM indicating the binary string is a positive big
891 number.
892
893 Often big numbers are used to represent cryptographic keys, however,
894 COSE which defines representations for keys chose not to use this
895 particular type.
896 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700897static void QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pCtx,
898 uint8_t uTagRequirement,
899 UsefulBufC Bytes);
900
901static void QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pCtx,
902 const char *szLabel,
903 uint8_t uTagRequirement,
904 UsefulBufC Bytes);
905
906static void QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pCtx,
907 int64_t nLabel,
908 uint8_t uTagRequirement,
909 UsefulBufC Bytes);
910
911
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700912static void QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx,
913 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100914
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700915static void QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx,
916 const char *szLabel,
917 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100918
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700919static void QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx,
920 int64_t nLabel,
921 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100922
923
924/**
925 @brief Add a negative big number to the encoded output.
926
927 @param[in] pCtx The encoding context to add the big number to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700928 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100929 @param[in] Bytes Pointer and length of the big number.
930
931 Big numbers are integers larger than 64-bits. Their format is
Laurence Lundbladec02e13e2020-12-06 05:45:41 -0800932 described in [RFC 8949] (https://tools.ietf.org/html/rfc8949).
Michael Eckel5c531332020-03-02 01:35:30 +0100933
934 It is output as CBOR major type 2, a binary string, with tag @ref
935 CBOR_TAG_NEG_BIGNUM indicating the binary string is a negative big
936 number.
937
938 Often big numbers are used to represent cryptographic keys, however,
939 COSE which defines representations for keys chose not to use this
940 particular type.
941 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700942static void QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pCtx,
943 uint8_t uTagRequirement,
944 UsefulBufC Bytes);
945
946static void QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pCtx,
947 const char *szLabel,
948 uint8_t uTagRequirement,
949 UsefulBufC Bytes);
950
951static void QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pCtx,
952 int64_t nLabel,
953 uint8_t uTagRequirement,
954 UsefulBufC Bytes);
955
956
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700957static void QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx,
958 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100959
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700960static void QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx,
961 const char *szLabel,
962 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100963
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700964static void QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx,
965 int64_t nLabel,
966 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100967
968
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -0700969#ifndef QCBOR_DISABLE_EXP_AND_MANTISSA
Michael Eckel5c531332020-03-02 01:35:30 +0100970/**
971 @brief Add a decimal fraction to the encoded output.
972
973 @param[in] pCtx The encoding context to add the decimal fraction to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700974 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100975 @param[in] nMantissa The mantissa.
976 @param[in] nBase10Exponent The exponent.
977
978 The value is nMantissa * 10 ^ nBase10Exponent.
979
980 A decimal fraction is good for exact representation of some values
981 that can't be represented exactly with standard C (IEEE 754)
982 floating-point numbers. Much larger and much smaller numbers can
983 also be represented than floating-point because of the larger number
984 of bits in the exponent.
985
986 The decimal fraction is conveyed as two integers, a mantissa and a
987 base-10 scaling factor.
988
989 For example, 273.15 is represented by the two integers 27315 and -2.
990
991 The exponent and mantissa have the range from @c INT64_MIN to
992 @c INT64_MAX for both encoding and decoding (CBOR allows @c -UINT64_MAX
993 to @c UINT64_MAX, but this implementation doesn't support this range to
994 reduce code size and interface complexity a little).
995
996 CBOR Preferred encoding of the integers is used, thus they will be encoded
997 in the smallest number of bytes possible.
998
999 See also QCBOREncode_AddDecimalFractionBigNum() for a decimal
1000 fraction with arbitrarily large precision and QCBOREncode_AddBigFloat().
1001
1002 There is no representation of positive or negative infinity or NaN
1003 (Not a Number). Use QCBOREncode_AddDouble() to encode them.
1004
1005 See @ref expAndMantissa for decoded representation.
1006 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001007static void QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pCtx,
1008 uint8_t uTagRequirement,
1009 int64_t nMantissa,
1010 int64_t nBase10Exponent);
1011
1012static void QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001013 const char *szLabel,
1014 uint8_t uTagRequirement,
1015 int64_t nMantissa,
1016 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001017
1018static void QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pCtx,
1019 int64_t nLabel,
1020 uint8_t uTagRequirement,
1021 int64_t nMantissa,
1022 int64_t nBase10Exponent);
1023
1024
Michael Eckel5c531332020-03-02 01:35:30 +01001025static void QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pCtx,
1026 int64_t nMantissa,
1027 int64_t nBase10Exponent);
1028
1029static void QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pCtx,
1030 const char *szLabel,
1031 int64_t nMantissa,
1032 int64_t nBase10Exponent);
1033
1034static void QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pCtx,
1035 int64_t nLabel,
1036 int64_t nMantissa,
1037 int64_t nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01001038/**
1039 @brief Add a decimal fraction with a big number mantissa to the encoded output.
1040
1041 @param[in] pCtx The encoding context to add the decimal fraction to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001042 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001043 @param[in] Mantissa The mantissa.
1044 @param[in] bIsNegative false if mantissa is positive, true if negative.
1045 @param[in] nBase10Exponent The exponent.
1046
1047 This is the same as QCBOREncode_AddDecimalFraction() except the
1048 mantissa is a big number (See QCBOREncode_AddPositiveBignum())
1049 allowing for arbitrarily large precision.
1050
1051 See @ref expAndMantissa for decoded representation.
1052 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001053static void QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pCtx,
1054 uint8_t uTagRequirement,
1055 UsefulBufC Mantissa,
1056 bool bIsNegative,
1057 int64_t nBase10Exponent);
1058
1059static void QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001060 const char *szLabel,
1061 uint8_t uTagRequirement,
1062 UsefulBufC Mantissa,
1063 bool bIsNegative,
1064 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001065
1066static void QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
1067 int64_t nLabel,
1068 uint8_t uTagRequirement,
1069 UsefulBufC Mantissa,
1070 bool bIsNegative,
1071 int64_t nBase10Exponent);
1072
1073
Michael Eckel5c531332020-03-02 01:35:30 +01001074static void QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pCtx,
1075 UsefulBufC Mantissa,
1076 bool bIsNegative,
1077 int64_t nBase10Exponent);
1078
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001079static void QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001080 const char *szLabel,
1081 UsefulBufC Mantissa,
1082 bool bIsNegative,
1083 int64_t nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01001084
1085static void QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
1086 int64_t nLabel,
1087 UsefulBufC Mantissa,
1088 bool bIsNegative,
1089 int64_t nBase10Exponent);
1090
1091/**
1092 @brief Add a big floating-point number to the encoded output.
1093
1094 @param[in] pCtx The encoding context to add the bigfloat to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001095 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001096 @param[in] nMantissa The mantissa.
1097 @param[in] nBase2Exponent The exponent.
1098
1099 The value is nMantissa * 2 ^ nBase2Exponent.
1100
1101 "Bigfloats", as CBOR terms them, are similar to IEEE floating-point
1102 numbers in having a mantissa and base-2 exponent, but they are not
1103 supported by hardware or encoded the same. They explicitly use two
1104 CBOR-encoded integers to convey the mantissa and exponent, each of which
1105 can be 8, 16, 32 or 64 bits. With both the mantissa and exponent
1106 64 bits they can express more precision and a larger range than an
1107 IEEE double floating-point number. See
1108 QCBOREncode_AddBigFloatBigNum() for even more precision.
1109
1110 For example, 1.5 would be represented by a mantissa of 3 and an
1111 exponent of -1.
1112
1113 The exponent and mantissa have the range from @c INT64_MIN to
1114 @c INT64_MAX for both encoding and decoding (CBOR allows @c -UINT64_MAX
1115 to @c UINT64_MAX, but this implementation doesn't support this range to
1116 reduce code size and interface complexity a little).
1117
1118 CBOR Preferred encoding of the integers is used, thus they will be encoded
1119 in the smallest number of bytes possible.
1120
1121 This can also be used to represent floating-point numbers in
1122 environments that don't support IEEE 754.
1123
1124 See @ref expAndMantissa for decoded representation.
1125 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001126static void QCBOREncode_AddTBigFloat(QCBOREncodeContext *pCtx,
1127 uint8_t uTagRequirement,
1128 int64_t nMantissa,
1129 int64_t nBase2Exponent);
1130
1131static void QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001132 const char *szLabel,
1133 uint8_t uTagRequirement,
1134 int64_t nMantissa,
1135 int64_t nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001136
1137static void QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pCtx,
1138 int64_t nLabel,
1139 uint8_t uTagRequirement,
1140 int64_t nMantissa,
1141 int64_t nBase2Exponent);
1142
1143
Michael Eckel5c531332020-03-02 01:35:30 +01001144static void QCBOREncode_AddBigFloat(QCBOREncodeContext *pCtx,
1145 int64_t nMantissa,
1146 int64_t nBase2Exponent);
1147
1148static void QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pCtx,
1149 const char *szLabel,
1150 int64_t nMantissa,
1151 int64_t nBase2Exponent);
1152
1153static void QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pCtx,
1154 int64_t nLabel,
1155 int64_t nMantissa,
1156 int64_t nBase2Exponent);
1157
Michael Eckel5c531332020-03-02 01:35:30 +01001158/**
1159 @brief Add a big floating-point number with a big number mantissa to
1160 the encoded output.
1161
1162 @param[in] pCtx The encoding context to add the bigfloat to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001163 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001164 @param[in] Mantissa The mantissa.
1165 @param[in] bIsNegative false if mantissa is positive, true if negative.
1166 @param[in] nBase2Exponent The exponent.
1167
1168 This is the same as QCBOREncode_AddBigFloat() except the mantissa is
1169 a big number (See QCBOREncode_AddPositiveBignum()) allowing for
1170 arbitrary precision.
1171
1172 See @ref expAndMantissa for decoded representation.
1173 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001174static void QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pCtx,
1175 uint8_t uTagRequirement,
1176 UsefulBufC Mantissa,
1177 bool bIsNegative,
1178 int64_t nBase2Exponent);
1179
1180static void QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001181 const char *szLabel,
1182 uint8_t uTagRequirement,
1183 UsefulBufC Mantissa,
1184 bool bIsNegative,
1185 int64_t nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001186
1187static void QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1188 int64_t nLabel,
1189 uint8_t uTagRequirement,
1190 UsefulBufC Mantissa,
1191 bool bIsNegative,
1192 int64_t nBase2Exponent);
1193
1194
Michael Eckel5c531332020-03-02 01:35:30 +01001195static void QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pCtx,
1196 UsefulBufC Mantissa,
1197 bool bIsNegative,
1198 int64_t nBase2Exponent);
1199
1200static void QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pCtx,
1201 const char *szLabel,
1202 UsefulBufC Mantissa,
1203 bool bIsNegative,
1204 int64_t nBase2Exponent);
1205
1206static void QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1207 int64_t nLabel,
1208 UsefulBufC Mantissa,
1209 bool bIsNegative,
1210 int64_t nBase2Exponent);
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07001211#endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
Michael Eckel5c531332020-03-02 01:35:30 +01001212
1213
1214/**
1215 @brief Add a text URI to the encoded output.
1216
1217 @param[in] pCtx The encoding context to add the URI 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] URI Pointer and length of the URI.
1220
1221 The format of URI must be per [RFC 3986]
1222 (https://tools.ietf.org/html/rfc3986).
1223
1224 It is output as CBOR major type 3, a text string, with tag @ref
1225 CBOR_TAG_URI indicating the text string is a URI.
1226
1227 A URI in a NULL-terminated string, @c szURI, can be easily added with
1228 this code:
1229
1230 QCBOREncode_AddURI(pCtx, UsefulBuf_FromSZ(szURI));
1231 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001232static void QCBOREncode_AddTURI(QCBOREncodeContext *pCtx,
1233 uint8_t uTagRequirement,
1234 UsefulBufC URI);
1235
1236static void QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pCtx,
1237 const char *szLabel,
1238 uint8_t uTagRequirement,
1239 UsefulBufC URI);
1240
1241static void QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pCtx,
1242 int64_t nLabel,
1243 uint8_t uTagRequirement,
1244 UsefulBufC URI);
1245
1246
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001247static void QCBOREncode_AddURI(QCBOREncodeContext *pCtx,
1248 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001249
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001250static void QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx,
1251 const char *szLabel,
1252 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001253
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001254static void QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx,
1255 int64_t nLabel,
1256 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001257
1258
1259/**
1260 @brief Add Base64-encoded text to encoded output.
1261
1262 @param[in] pCtx The encoding context to add the base-64 text to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001263 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001264 @param[in] B64Text Pointer and length of the base-64 encoded text.
1265
1266 The text content is Base64 encoded data per [RFC 4648]
1267 (https://tools.ietf.org/html/rfc4648).
1268
1269 It is output as CBOR major type 3, a text string, with tag @ref
1270 CBOR_TAG_B64 indicating the text string is Base64 encoded.
1271 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001272static void QCBOREncode_AddTB64Text(QCBOREncodeContext *pCtx,
1273 uint8_t uTagRequirement,
1274 UsefulBufC B64Text);
1275
1276static void QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pCtx,
1277 const char *szLabel,
1278 uint8_t uTagRequirement,
1279 UsefulBufC B64Text);
1280
1281static void QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pCtx,
1282 int64_t nLabel,
1283 uint8_t uTagRequirement,
1284 UsefulBufC B64Text);
1285
1286
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001287static void QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx,
1288 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001289
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001290static void QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx,
1291 const char *szLabel,
1292 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001293
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001294static void QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx,
1295 int64_t nLabel,
1296 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001297
1298
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001299
Michael Eckel5c531332020-03-02 01:35:30 +01001300/**
1301 @brief Add base64url encoded data to encoded output.
1302
1303 @param[in] pCtx The encoding context to add the base64url to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001304 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001305 @param[in] B64Text Pointer and length of the base64url encoded text.
1306
1307 The text content is base64URL encoded text as per [RFC 4648]
1308 (https://tools.ietf.org/html/rfc4648).
1309
1310 It is output as CBOR major type 3, a text string, with tag @ref
1311 CBOR_TAG_B64URL indicating the text string is a Base64url encoded.
1312 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001313static void QCBOREncode_AddTB64URLText(QCBOREncodeContext *pCtx,
1314 uint8_t uTagRequirement,
1315 UsefulBufC B64Text);
1316
1317static void QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pCtx,
1318 const char *szLabel,
1319 uint8_t uTagRequirement,
1320 UsefulBufC B64Text);
1321
1322static void QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pCtx,
1323 int64_t nLabel,
1324 uint8_t uTagRequirement,
1325 UsefulBufC B64Text);
1326
1327
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001328static void QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx,
1329 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001330
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001331static void QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx,
1332 const char *szLabel,
1333 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001334
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001335static void QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx,
1336 int64_t nLabel,
1337 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001338
1339
1340/**
1341 @brief Add Perl Compatible Regular Expression.
1342
1343 @param[in] pCtx The encoding context to add the regular expression to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001344 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001345 @param[in] Regex Pointer and length of the regular expression.
1346
1347 The text content is Perl Compatible Regular
1348 Expressions (PCRE) / JavaScript syntax [ECMA262].
1349
1350 It is output as CBOR major type 3, a text string, with tag @ref
1351 CBOR_TAG_REGEX indicating the text string is a regular expression.
1352 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001353static void QCBOREncode_AddTRegex(QCBOREncodeContext *pCtx,
1354 uint8_t uTagRequirement,
1355 UsefulBufC Regex);
1356
1357static void QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pCtx,
1358 const char *szLabel,
1359 uint8_t uTagRequirement,
1360 UsefulBufC Regex);
1361
1362static void QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pCtx,
1363 int64_t nLabel,
1364 uint8_t uTagRequirement,
1365 UsefulBufC Regex);
1366
1367
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001368static void QCBOREncode_AddRegex(QCBOREncodeContext *pCtx,
1369 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001370
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001371static void QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx,
1372 const char *szLabel,
1373 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001374
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001375static void QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx,
1376 int64_t nLabel,
1377 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001378
1379
1380/**
Laurence Lundblade4982f412020-09-18 23:02:18 -07001381 @brief MIME encoded data to the encoded output.
Michael Eckel5c531332020-03-02 01:35:30 +01001382
Laurence Lundblade4982f412020-09-18 23:02:18 -07001383 @param[in] pCtx The encoding context to add the MIME data to.
1384 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1385 @ref QCBOR_ENCODE_AS_BORROWED.
1386 @param[in] MIMEData Pointer and length of the MIME data.
Michael Eckel5c531332020-03-02 01:35:30 +01001387
1388 The text content is in MIME format per [RFC 2045]
Laurence Lundblade4982f412020-09-18 23:02:18 -07001389 (https://tools.ietf.org/html/rfc2045) including the headers.
Michael Eckel5c531332020-03-02 01:35:30 +01001390
Laurence Lundblade4982f412020-09-18 23:02:18 -07001391 It is output as CBOR major type 2, a binary string, with tag @ref
1392 CBOR_TAG_BINARY_MIME indicating the string is MIME data. This
1393 outputs tag 257, not tag 36, as it can carry any type of MIME binary,
1394 7-bit, 8-bit, quoted-printable and base64 where tag 36 cannot.
1395
1396 Previous versions of QCBOR, those before spiffy decode, output tag
1397 36. Decoding supports both tag 36 and 257. (if the old behavior with
1398 tag 36 is needed, copy the inline functions below and change the tag
1399 number).
1400
1401 See also QCBORDecode_GetMIMEMessage() and
1402 @ref QCBOR_TYPE_BINARY_MIME.
Laurence Lundbladeadaf5c22020-09-25 10:37:09 -07001403
1404 This does no translation of line endings. See QCBOREncode_AddText()
1405 for a discussion of line endings in CBOR.
Michael Eckel5c531332020-03-02 01:35:30 +01001406 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001407static void QCBOREncode_AddTMIMEData(QCBOREncodeContext *pCtx,
1408 uint8_t uTagRequirement,
1409 UsefulBufC MIMEData);
1410
1411static void QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pCtx,
1412 const char *szLabel,
1413 uint8_t uTagRequirement,
1414 UsefulBufC MIMEData);
1415
1416static void QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pCtx,
1417 int64_t nLabel,
1418 uint8_t uTagRequirement,
1419 UsefulBufC MIMEData);
1420
1421
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001422static void QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx,
1423 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001424
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001425static void QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx,
1426 const char *szLabel,
1427 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001428
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001429static void QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx,
1430 int64_t nLabel,
1431 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001432
1433
1434/**
1435 @brief Add an RFC 3339 date string
1436
1437 @param[in] pCtx The encoding context to add the date to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001438 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001439 @param[in] szDate Null-terminated string with date to add.
1440
1441 The string szDate should be in the form of [RFC 3339]
1442 (https://tools.ietf.org/html/rfc3339) as defined by section 3.3 in
1443 [RFC 4287] (https://tools.ietf.org/html/rfc4287). This is as
Laurence Lundbladec02e13e2020-12-06 05:45:41 -08001444 described in section 3.4.1 in [RFC 8949]
1445 (https://tools.ietf.org/html/rfc8949).
Michael Eckel5c531332020-03-02 01:35:30 +01001446
1447 Note that this function doesn't validate the format of the date string
1448 at all. If you add an incorrect format date string, the generated
1449 CBOR will be incorrect and the receiver may not be able to handle it.
1450
1451 Error handling is the same as QCBOREncode_AddInt64().
Laurence Lundblade46d63e92021-05-13 11:37:10 -07001452
1453 See also QCBOREncode_AddTDayString().
Michael Eckel5c531332020-03-02 01:35:30 +01001454 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001455static void QCBOREncode_AddTDateString(QCBOREncodeContext *pCtx,
1456 uint8_t uTagRequirement,
1457 const char *szDate);
1458
1459static void QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pCtx,
1460 const char *szLabel,
1461 uint8_t uTagRequirement,
1462 const char *szDate);
1463
1464static void QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pCtx,
1465 int64_t nLabel,
1466 uint8_t uTagRequirement,
1467 const char *szDate);
1468
1469
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001470static void QCBOREncode_AddDateString(QCBOREncodeContext *pCtx,
1471 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001472
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001473static void QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx,
1474 const char *szLabel,
1475 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001476
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001477static void QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx,
1478 int64_t nLabel,
1479 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001480
Laurence Lundblade46d63e92021-05-13 11:37:10 -07001481
1482/**
1483 @brief Add a date-only string.
1484
1485 @param[in] pCtx The encoding context to add the date to.
1486 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1487 @ref QCBOR_ENCODE_AS_BORROWED.
1488 @param[in] szDate Null-terminated string with date to add.
1489
1490 This date format is described in
1491 [RFC 8943] (https://tools.ietf.org/html/rfc8943), but that mainly
1492 references RFC 3339. The string szDate must be in the forrm
1493 specified the ABNF for a full-date in
1494 [RFC 3339] (https://tools.ietf.org/html/rfc3339). Examples of this
1495 are "1985-04-12" and "1937-01-01". The time and the time zone are
1496 never included.
1497
1498 Note that this function doesn't validate the format of the date
1499 string at all. If you add an incorrect format date string, the
1500 generated CBOR will be incorrect and the receiver may not be able to
1501 handle it.
1502
1503 Error handling is the same as QCBOREncode_AddInt64().
1504
1505 See also QCBOREncode_AddTDateString().
1506 */
1507static void
1508QCBOREncode_AddTDaysString(QCBOREncodeContext *pCtx,
1509 uint8_t uTagRequirement,
1510 const char *szDate);
1511
1512static void
1513QCBOREncode_AddTDaysStringToMapSZ(QCBOREncodeContext *pCtx,
1514 const char *szLabel,
1515 uint8_t uTagRequirement,
1516 const char *szDate);
1517
1518static void
1519QCBOREncode_AddTDaysStringToMapN(QCBOREncodeContext *pCtx,
1520 int64_t nLabel,
1521 uint8_t uTagRequirement,
1522 const char *szDate);
1523
1524
Michael Eckel5c531332020-03-02 01:35:30 +01001525/**
1526 @brief Add a standard Boolean.
1527
1528 @param[in] pCtx The encoding context to add the Boolean to.
1529 @param[in] b true or false from @c <stdbool.h>.
1530
1531 Adds a Boolean value as CBOR major type 7.
1532
1533 Error handling is the same as QCBOREncode_AddInt64().
1534 */
1535static void QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b);
1536
1537static void QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b);
1538
1539static void QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b);
1540
1541
1542
1543/**
1544 @brief Add a NULL to the encoded output.
1545
1546 @param[in] pCtx The encoding context to add the NULL to.
1547
1548 Adds the NULL value as CBOR major type 7.
1549
1550 This NULL doesn't have any special meaning in CBOR such as a
1551 terminating value for a string or an empty value.
1552
1553 Error handling is the same as QCBOREncode_AddInt64().
1554 */
1555static void QCBOREncode_AddNULL(QCBOREncodeContext *pCtx);
1556
1557static void QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1558
1559static void QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1560
1561
1562/**
1563 @brief Add an "undef" to the encoded output.
1564
1565 @param[in] pCtx The encoding context to add the "undef" to.
1566
1567 Adds the undef value as CBOR major type 7.
1568
1569 Note that this value will not translate to JSON.
1570
1571 This Undef doesn't have any special meaning in CBOR such as a
1572 terminating value for a string or an empty value.
1573
1574 Error handling is the same as QCBOREncode_AddInt64().
1575 */
1576static void QCBOREncode_AddUndef(QCBOREncodeContext *pCtx);
1577
1578static void QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1579
1580static void QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1581
1582
1583/**
1584 @brief Indicates that the next items added are in an array.
1585
1586 @param[in] pCtx The encoding context to open the array in.
1587
1588 Arrays are the basic CBOR aggregate or structure type. Call this
1589 function to start or open an array. Then call the various @c
1590 QCBOREncode_AddXxx() functions to add the items that go into the
1591 array. Then call QCBOREncode_CloseArray() when all items have been
1592 added. The data items in the array can be of any type and can be of
1593 mixed types.
1594
1595 Nesting of arrays and maps is allowed and supported just by calling
1596 QCBOREncode_OpenArray() again before calling
1597 QCBOREncode_CloseArray(). While CBOR has no limit on nesting, this
1598 implementation does in order to keep it smaller and simpler. The
1599 limit is @ref QCBOR_MAX_ARRAY_NESTING. This is the max number of
1600 times this can be called without calling
1601 QCBOREncode_CloseArray(). QCBOREncode_Finish() will return @ref
1602 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP when it is called as this function
1603 just sets an error state and returns no value when this occurs.
1604
1605 If you try to add more than @ref QCBOR_MAX_ITEMS_IN_ARRAY items to a
1606 single array or map, @ref QCBOR_ERR_ARRAY_TOO_LONG will be returned
1607 when QCBOREncode_Finish() is called.
1608
1609 An array itself must have a label if it is being added to a map.
1610 Note that array elements do not have labels (but map elements do).
1611
1612 An array itself may be tagged by calling QCBOREncode_AddTag() before this call.
1613 */
1614static void QCBOREncode_OpenArray(QCBOREncodeContext *pCtx);
1615
1616static void QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1617
1618static void QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1619
1620
1621/**
1622 @brief Close an open array.
1623
1624 @param[in] pCtx The encoding context to close the array in.
1625
1626 The closes an array opened by QCBOREncode_OpenArray(). It reduces
1627 nesting level by one. All arrays (and maps) must be closed before
1628 calling QCBOREncode_Finish().
1629
1630 When an error occurs as a result of this call, the encoder records
1631 the error and enters the error state. The error will be returned when
1632 QCBOREncode_Finish() is called.
1633
1634 If this has been called more times than QCBOREncode_OpenArray(), then
1635 @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when QCBOREncode_Finish()
1636 is called.
1637
1638 If this is called and it is not an array that is currently open, @ref
1639 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
1640 is called.
1641 */
1642static void QCBOREncode_CloseArray(QCBOREncodeContext *pCtx);
1643
1644
1645/**
1646 @brief Indicates that the next items added are in a map.
1647
1648 @param[in] pCtx The encoding context to open the map in.
1649
1650 See QCBOREncode_OpenArray() for more information, particularly error
1651 handling.
1652
1653 CBOR maps are an aggregate type where each item in the map consists
1654 of a label and a value. They are similar to JSON objects.
1655
1656 The value can be any CBOR type including another map.
1657
1658 The label can also be any CBOR type, but in practice they are
1659 typically, integers as this gives the most compact output. They might
1660 also be text strings which gives readability and translation to JSON.
1661
1662 Every @c QCBOREncode_AddXxx() call has one version that ends with @c
1663 InMap for adding items to maps with string labels and one that ends
1664 with @c InMapN that is for adding with integer labels.
1665
Laurence Lundbladec02e13e2020-12-06 05:45:41 -08001666 RFC 8949 uses the term "key" instead of "label".
Michael Eckel5c531332020-03-02 01:35:30 +01001667
1668 If you wish to use map labels that are neither integer labels nor
1669 text strings, then just call the QCBOREncode_AddXxx() function
1670 explicitly to add the label. Then call it again to add the value.
1671
Laurence Lundbladec02e13e2020-12-06 05:45:41 -08001672 See the [RFC 8949] (https://tools.ietf.org/html/rfc8949) for a lot
Michael Eckel5c531332020-03-02 01:35:30 +01001673 more information on creating maps.
1674 */
1675static void QCBOREncode_OpenMap(QCBOREncodeContext *pCtx);
1676
1677static void QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1678
1679static void QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1680
1681
Michael Eckel5c531332020-03-02 01:35:30 +01001682/**
1683 @brief Close an open map.
1684
1685 @param[in] pCtx The encoding context to close the map in .
1686
1687 This closes a map opened by QCBOREncode_OpenMap(). It reduces nesting
1688 level by one.
1689
1690 When an error occurs as a result of this call, the encoder records
1691 the error and enters the error state. The error will be returned when
1692 QCBOREncode_Finish() is called.
1693
1694 If this has been called more times than QCBOREncode_OpenMap(),
1695 then @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1696 QCBOREncode_Finish() is called.
1697
1698 If this is called and it is not a map that is currently open, @ref
1699 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
1700 is called.
1701 */
1702static void QCBOREncode_CloseMap(QCBOREncodeContext *pCtx);
1703
1704
1705/**
1706 @brief Indicate start of encoded CBOR to be wrapped in a bstr.
1707
1708 @param[in] pCtx The encoding context to open the bstr-wrapped CBOR in.
1709
1710 All added encoded items between this call and a call to
1711 QCBOREncode_CloseBstrWrap2() will be wrapped in a bstr. They will
1712 appear in the final output as a byte string. That byte string will
1713 contain encoded CBOR. This increases nesting level by one.
1714
1715 The typical use case is for encoded CBOR that is to be
1716 cryptographically hashed, as part of a [RFC 8152, COSE]
Laurence Lundbladec02e13e2020-12-06 05:45:41 -08001717 (https://tools.ietf.org/html/rfc8152) implementation. The
1718 wrapping byte string is taken as input by the hash function
1719 (which is why it is returned by QCBOREncode_CloseBstrWrap2()).
1720 It is also easy to recover on decoding with standard CBOR
1721 decoders.
Michael Eckel5c531332020-03-02 01:35:30 +01001722
1723 Using QCBOREncode_BstrWrap() and QCBOREncode_CloseBstrWrap2() avoids
1724 having to encode the items first in one buffer (e.g., the COSE
1725 payload) and then add that buffer as a bstr to another encoding
1726 (e.g. the COSE to-be-signed bytes, the @c Sig_structure) potentially
1727 halving the memory needed.
1728
Laurence Lundbladec02e13e2020-12-06 05:45:41 -08001729 CBOR by nature must be decoded item by item in order from the start.
1730 By wrapping some CBOR in a byte string, the decoding of that wrapped
1731 CBOR can be skipped. This is another use of wrapping, perhaps
1732 because the CBOR is large and deeply nested. Perhaps APIs for
1733 handling one defined CBOR message that is being embedded in another
1734 only take input as a byte string. Perhaps the desire is to be able
1735 to decode the out layer even in the wrapped has errors.
Michael Eckel5c531332020-03-02 01:35:30 +01001736 */
1737static void QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx);
1738
1739static void QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1740
1741static void QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1742
1743
1744/**
1745 @brief Close a wrapping bstr.
1746
1747 @param[in] pCtx The encoding context to close of bstr wrapping in.
1748 @param[in] bIncludeCBORHead Include the encoded CBOR head of the bstr
1749 as well as the bytes in @c pWrappedCBOR.
1750 @param[out] pWrappedCBOR A @ref UsefulBufC containing wrapped bytes.
1751
1752 The closes a wrapping bstr opened by QCBOREncode_BstrWrap(). It reduces
1753 nesting level by one.
1754
1755 A pointer and length of the enclosed encoded CBOR is returned in @c
1756 *pWrappedCBOR if it is not @c NULL. The main purpose of this is so
1757 this data can be hashed (e.g., with SHA-256) as part of a [RFC 8152,
1758 COSE] (https://tools.ietf.org/html/rfc8152)
1759 implementation. **WARNING**, this pointer and length should be used
1760 right away before any other calls to @c QCBOREncode_CloseXxx() as
1761 they will move data around and the pointer and length will no longer
1762 be to the correct encoded CBOR.
1763
1764 When an error occurs as a result of this call, the encoder records
1765 the error and enters the error state. The error will be returned when
1766 QCBOREncode_Finish() is called.
1767
1768 If this has been called more times than QCBOREncode_BstrWrap(), then
1769 @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1770 QCBOREncode_Finish() is called.
1771
1772 If this is called and it is not a wrapping bstr that is currently
1773 open, @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
1774 QCBOREncode_Finish() is called.
1775
1776 QCBOREncode_CloseBstrWrap() is a deprecated version of this function
1777 that is equivalent to the call with @c bIncludeCBORHead @c true.
1778 */
1779void QCBOREncode_CloseBstrWrap2(QCBOREncodeContext *pCtx, bool bIncludeCBORHead, UsefulBufC *pWrappedCBOR);
1780
1781static void QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR);
1782
1783
1784/**
Laurence Lundblade8d3b8552021-06-10 11:11:54 -07001785 * @brief Cancel byte string wrapping.
1786 *
1787 * @param[in] pCtx The encoding context.
1788 *
1789 * This cancels QCBOREncode_BstrWrap() making tghe encoding as if it
1790 * were never called.
1791 *
1792 * WARNING: This does not work on QCBOREncode_BstrWrapInMap()
1793 * or QCBOREncode_BstrWrapInMapN() and there is no error detection
1794 * of an attempt at their use.
1795 *
1796 * This only works if nothing has been added into the wrapped byte
1797 * string. If something has been added, this sets the error
1798 * @ref QCBOR_ERR_CANNOT_CANCEL.
1799 */
1800void QCBOREncode_CancelBstrWrap(QCBOREncodeContext *pCtx);
1801
1802
1803/**
Michael Eckel5c531332020-03-02 01:35:30 +01001804 @brief Add some already-encoded CBOR bytes.
1805
1806 @param[in] pCtx The encoding context to add the already-encode CBOR to.
1807 @param[in] Encoded The already-encoded CBOR to add to the context.
1808
1809 The encoded CBOR being added must be fully conforming CBOR. It must
1810 be complete with no arrays or maps that are incomplete. While this
1811 encoder doesn't ever produce indefinite lengths, it is OK for the
1812 raw CBOR added here to have indefinite lengths.
1813
1814 The raw CBOR added here is not checked in anyway. If it is not
1815 conforming or has open arrays or such, the final encoded CBOR
1816 will probably be wrong or not what was intended.
1817
1818 If the encoded CBOR being added here contains multiple items, they
1819 must be enclosed in a map or array. At the top level the raw
1820 CBOR must be a single data item.
1821 */
1822static void QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded);
1823
1824static void QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded);
1825
1826static void QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded);
1827
1828
1829/**
1830 @brief Get the encoded result.
1831
1832 @param[in] pCtx The context to finish encoding with.
Laurence Lundblade8510f8c2020-12-01 11:31:16 -08001833 @param[out] pEncodedCBOR Structure in which the pointer and length of the encoded
1834 CBOR is returned.
Michael Eckel5c531332020-03-02 01:35:30 +01001835
Laurence Lundbladeb9702452021-03-08 21:02:57 -08001836 @retval QCBOR_SUCCESS Encoded CBOR is returned.
1837
Michael Eckel5c531332020-03-02 01:35:30 +01001838 @retval QCBOR_ERR_TOO_MANY_CLOSES Nesting error
1839
1840 @retval QCBOR_ERR_CLOSE_MISMATCH Nesting error
1841
1842 @retval QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN Nesting error
1843
1844 @retval QCBOR_ERR_BUFFER_TOO_LARGE Encoded output buffer size
1845
1846 @retval QCBOR_ERR_BUFFER_TOO_SMALL Encoded output buffer size
1847
1848 @retval QCBOR_ERR_ARRAY_NESTING_TOO_DEEP Implementation limit
1849
1850 @retval QCBOR_ERR_ARRAY_TOO_LONG Implementation limit
1851
Laurence Lundblade8510f8c2020-12-01 11:31:16 -08001852 On success, the pointer and length of the encoded CBOR are returned
1853 in @c *pEncodedCBOR. The pointer is the same pointer that was passed
1854 in to QCBOREncode_Init(). Note that it is not const when passed to
1855 QCBOREncode_Init(), but it is const when returned here. The length
1856 will be smaller than or equal to the length passed in when
1857 QCBOREncode_Init() as this is the length of the actual result, not
1858 the size of the buffer it was written to.
Michael Eckel5c531332020-03-02 01:35:30 +01001859
Laurence Lundblade8510f8c2020-12-01 11:31:16 -08001860 If a @c NULL was passed for @c Storage.ptr when QCBOREncode_Init()
1861 was called, @c NULL will be returned here, but the length will be
1862 that of the CBOR that would have been encoded.
Michael Eckel5c531332020-03-02 01:35:30 +01001863
1864 Encoding errors primarily manifest here as most other encoding function
1865 do no return an error. They just set the error state in the encode
1866 context after which no encoding function does anything.
1867
1868 Three types of errors manifest here. The first type are nesting
1869 errors where the number of @c QCBOREncode_OpenXxx() calls do not
1870 match the number @c QCBOREncode_CloseXxx() calls. The solution is to
1871 fix the calling code.
1872
1873 The second type of error is because the buffer given is either too
1874 small or too large. The remedy is to give a correctly sized buffer.
1875
1876 The third type are due to limits in this implementation. @ref
1877 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP can be worked around by encoding the
1878 CBOR in two (or more) phases and adding the CBOR from the first phase
1879 to the second with @c QCBOREncode_AddEncoded().
1880
1881 If an error is returned, the buffer may have partially encoded
1882 incorrect CBOR in it and it should not be used. Likewise, the length
1883 may be incorrect and should not be used.
1884
1885 Note that the error could have occurred in one of the many @c
1886 QCBOREncode_AddXxx() calls long before QCBOREncode_Finish() was
1887 called. This error handling reduces the CBOR implementation size but
1888 makes debugging harder.
1889
1890 This may be called multiple times. It will always return the same. It
1891 can also be interleaved with calls to QCBOREncode_FinishGetSize().
1892
1893 QCBOREncode_GetErrorState() can be called to get the current
Laurence Lundblade8510f8c2020-12-01 11:31:16 -08001894 error state in order to abort encoding early as an optimization, but
1895 calling it is is never required.
Michael Eckel5c531332020-03-02 01:35:30 +01001896 */
1897QCBORError QCBOREncode_Finish(QCBOREncodeContext *pCtx, UsefulBufC *pEncodedCBOR);
1898
1899
1900/**
1901 @brief Get the encoded CBOR and error status.
1902
1903 @param[in] pCtx The context to finish encoding with.
1904 @param[out] uEncodedLen The length of the encoded or potentially
1905 encoded CBOR in bytes.
1906
1907 @return The same errors as QCBOREncode_Finish().
1908
1909 This functions the same as QCBOREncode_Finish(), but only returns the
1910 size of the encoded output.
1911 */
1912QCBORError QCBOREncode_FinishGetSize(QCBOREncodeContext *pCtx, size_t *uEncodedLen);
1913
1914
1915/**
1916 @brief Indicate whether output buffer is NULL or not.
1917
1918 @param[in] pCtx The encoding context.
1919
1920 @return 1 if the output buffer is @c NULL.
1921
1922 Sometimes a @c NULL input buffer is given to QCBOREncode_Init() so
1923 that the size of the generated CBOR can be calculated without
1924 allocating a buffer for it. This returns 1 when the output buffer is
1925 NULL and 0 when it is not.
1926*/
1927static int QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx);
1928
Laurence Lundblade825164e2020-10-22 20:18:06 -07001929
1930/**
Michael Eckel5c531332020-03-02 01:35:30 +01001931 @brief Get the encoding error state.
1932
1933 @param[in] pCtx The encoding context.
1934
Laurence Lundbladeabf5c572020-06-29 21:21:29 -07001935 @return One of @ref QCBORError. See return values from
Michael Eckel5c531332020-03-02 01:35:30 +01001936 QCBOREncode_Finish()
1937
1938 Normally encoding errors need only be handled at the end of encoding
1939 when QCBOREncode_Finish() is called. This can be called to get the
1940 error result before finish should there be a need to halt encoding
1941 before QCBOREncode_Finish() is called.
1942*/
1943static QCBORError QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx);
1944
1945
1946/**
1947 Encode the "head" of a CBOR data item.
1948
1949 @param buffer Buffer to output the encoded head to; must be
1950 @ref QCBOR_HEAD_BUFFER_SIZE bytes in size.
1951 @param uMajorType One of CBOR_MAJOR_TYPE_XX.
1952 @param uMinLen The minimum number of bytes to encode uNumber. Almost always
1953 this is 0 to use preferred minimal encoding. If this is 4,
1954 then even the values 0xffff and smaller will be encoded
Laurence Lundblade98427e92020-09-28 21:33:23 -07001955 in 4 bytes. This is used primarily when encoding a
Michael Eckel5c531332020-03-02 01:35:30 +01001956 float or double put into uNumber as the leading zero bytes
1957 for them must be encoded.
1958 @param uNumber The numeric argument part of the CBOR head.
1959 @return Pointer and length of the encoded head or
Laurence Lundblade9a3b6252020-10-21 21:30:31 -07001960 @ref NULLUsefulBufC if the output buffer is too small.
Michael Eckel5c531332020-03-02 01:35:30 +01001961
Laurence Lundblade98427e92020-09-28 21:33:23 -07001962 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 +01001963 take a @ref QCBOREncodeContext argument.
1964
1965 This encodes the major type and argument part of a data item. The
1966 argument is an integer that is usually either the value or the length
1967 of the data item.
1968
1969 This is exposed in the public interface to allow hashing of some CBOR
1970 data types, bstr in particular, a chunk at a time so the full CBOR
1971 doesn't have to be encoded in a contiguous buffer.
1972
1973 For example, if you have a 100,000 byte binary blob in a buffer that
1974 needs to be a bstr encoded and then hashed. You could allocate a
1975 100,010 byte buffer and encode it normally. Alternatively, you can
1976 encode the head in a 10 byte buffer with this function, hash that and
1977 then hash the 100,000 bytes using the same hash context.
1978
1979 See also QCBOREncode_AddBytesLenOnly();
1980 */
1981UsefulBufC QCBOREncode_EncodeHead(UsefulBuf buffer,
1982 uint8_t uMajorType,
1983 uint8_t uMinLen,
1984 uint64_t uNumber);
1985
1986
Michael Eckel5c531332020-03-02 01:35:30 +01001987
1988
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001989/* =========================================================================
1990 BEGINNING OF PRIVATE INLINE IMPLEMENTATION
1991 ========================================================================= */
Michael Eckel5c531332020-03-02 01:35:30 +01001992
1993/**
1994 @brief Semi-private method to add a buffer full of bytes to encoded output
1995
1996 @param[in] pCtx The encoding context to add the integer to.
1997 @param[in] uMajorType The CBOR major type of the bytes.
1998 @param[in] Bytes The bytes to add.
1999
2000 Use QCBOREncode_AddText() or QCBOREncode_AddBytes() or
2001 QCBOREncode_AddEncoded() instead. They are inline functions that call
2002 this and supply the correct major type. This function is public to
2003 make the inline functions work to keep the overall code size down and
2004 because the C language has no way to make it private.
2005
2006 If this is called the major type should be @c
2007 CBOR_MAJOR_TYPE_TEXT_STRING, @c CBOR_MAJOR_TYPE_BYTE_STRING or @c
2008 CBOR_MAJOR_NONE_TYPE_RAW. The last one is special for adding
2009 already-encoded CBOR.
2010 */
2011void QCBOREncode_AddBuffer(QCBOREncodeContext *pCtx, uint8_t uMajorType, UsefulBufC Bytes);
2012
2013
2014/**
2015 @brief Semi-private method to open a map, array or bstr-wrapped CBOR
2016
2017 @param[in] pCtx The context to add to.
2018 @param[in] uMajorType The major CBOR type to close
2019
2020 Call QCBOREncode_OpenArray(), QCBOREncode_OpenMap() or
2021 QCBOREncode_BstrWrap() instead of this.
2022 */
2023void QCBOREncode_OpenMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType);
2024
2025
2026/**
2027 @brief Semi-private method to open a map, array with indefinite length
2028
2029 @param[in] pCtx The context to add to.
2030 @param[in] uMajorType The major CBOR type to close
2031
2032 Call QCBOREncode_OpenArrayIndefiniteLength() or
2033 QCBOREncode_OpenMapIndefiniteLength() instead of this.
2034 */
2035void QCBOREncode_OpenMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx, uint8_t uMajorType);
2036
2037
2038/**
2039 @brief Semi-private method to close a map, array or bstr wrapped CBOR
2040
2041 @param[in] pCtx The context to add to.
2042 @param[in] uMajorType The major CBOR type to close.
2043
2044 Call QCBOREncode_CloseArray() or QCBOREncode_CloseMap() instead of this.
2045 */
2046void QCBOREncode_CloseMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType);
2047
2048
2049/**
2050 @brief Semi-private method to close a map, array with indefinite length
2051
2052 @param[in] pCtx The context to add to.
2053 @param[in] uMajorType The major CBOR type to close.
2054
2055 Call QCBOREncode_CloseArrayIndefiniteLength() or
2056 QCBOREncode_CloseMapIndefiniteLength() instead of this.
2057 */
2058void QCBOREncode_CloseMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx,
2059 uint8_t uMajorType);
2060
2061
2062/**
2063 @brief Semi-private method to add simple types.
2064
2065 @param[in] pCtx The encoding context to add the simple value to.
2066 @param[in] uMinLen Minimum encoding size for uNum. Usually 0.
2067 @param[in] uNum One of CBOR_SIMPLEV_FALSE through _UNDEF or other.
2068
2069 This is used to add simple types like true and false.
2070
2071 Call QCBOREncode_AddBool(), QCBOREncode_AddNULL(),
2072 QCBOREncode_AddUndef() instead of this.
2073
2074 This function can add simple values that are not defined by CBOR
2075 yet. This expansion point in CBOR should not be used unless they are
2076 standardized.
2077
2078 Error handling is the same as QCBOREncode_AddInt64().
2079 */
2080void QCBOREncode_AddType7(QCBOREncodeContext *pCtx, uint8_t uMinLen, uint64_t uNum);
2081
2082
2083/**
2084 @brief Semi-private method to add bigfloats and decimal fractions.
2085
Laurence Lundblade1fa579b2020-11-25 00:31:37 -08002086 @param[in] pCtx The encoding context to add the value to.
2087 @param[in] uTag The type 6 tag indicating what this is to be.
2088 @param[in] BigNumMantissa Is @ref NULLUsefulBufC if mantissa is an
2089 @c int64_t or the actual big number mantissa
2090 if not.
2091 @param[in] bBigNumIsNegative This is @c true if the big number is negative.
2092 @param[in] nMantissa The @c int64_t mantissa if it is not a big number.
2093 @param[in] nExponent The exponent.
Michael Eckel5c531332020-03-02 01:35:30 +01002094
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002095 This outputs either the @ref CBOR_TAG_DECIMAL_FRACTION or @ref
2096 CBOR_TAG_BIGFLOAT tag. if @c uTag is @ref CBOR_TAG_INVALID64, then
2097 this outputs the "borrowed" content format.
Michael Eckel5c531332020-03-02 01:35:30 +01002098
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002099 The tag content output by this is an array with two members, the
2100 exponent and then the mantissa. The mantissa can be either a big
2101 number or an @c int64_t.
2102
2103 This implementation cannot output an exponent further from 0 than
Laurence Lundblade9a3b6252020-10-21 21:30:31 -07002104 @c INT64_MAX.
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002105
Laurence Lundblade1fa579b2020-11-25 00:31:37 -08002106 To output a mantissa that is between INT64_MAX and UINT64_MAX from 0,
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002107 it must be as a big number.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002108
Michael Eckel5c531332020-03-02 01:35:30 +01002109 Typically, QCBOREncode_AddDecimalFraction(), QCBOREncode_AddBigFloat(),
2110 QCBOREncode_AddDecimalFractionBigNum() or QCBOREncode_AddBigFloatBigNum()
2111 is called instead of this.
2112 */
2113void QCBOREncode_AddExponentAndMantissa(QCBOREncodeContext *pCtx,
2114 uint64_t uTag,
2115 UsefulBufC BigNumMantissa,
2116 bool bBigNumIsNegative,
2117 int64_t nMantissa,
2118 int64_t nExponent);
2119
2120/**
2121 @brief Semi-private method to add only the type and length of a byte string.
2122
2123 @param[in] pCtx The context to initialize.
2124 @param[in] Bytes Pointer and length of the input data.
2125
2126 This is the same as QCBOREncode_AddBytes() except it only adds the
2127 CBOR encoding for the type and the length. It doesn't actually add
2128 the bytes. You can't actually produce correct CBOR with this and the
2129 rest of this API. It is only used for a special case where
2130 the valid CBOR is created manually by putting this type and length in
2131 and then adding the actual bytes. In particular, when only a hash of
2132 the encoded CBOR is needed, where the type and header are hashed
2133 separately and then the bytes is hashed. This makes it possible to
2134 implement COSE Sign1 with only one copy of the payload in the output
2135 buffer, rather than two, roughly cutting memory use in half.
2136
2137 This is only used for this odd case, but this is a supported
2138 tested function.
2139
2140 See also QCBOREncode_EncodeHead().
2141*/
2142static inline void QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
2143
2144static inline void QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
2145
2146static inline void QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
2147
2148
2149
2150
2151
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002152static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002153QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pMe, const char *szLabel, int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002154{
2155 // Use _AddBuffer() because _AddSZString() is defined below, not above
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002156 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
2157 QCBOREncode_AddInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002158}
2159
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002160static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002161QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pMe, int64_t nLabel, int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002162{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002163 QCBOREncode_AddInt64(pMe, nLabel);
2164 QCBOREncode_AddInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002165}
2166
2167
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002168static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002169QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pMe, const char *szLabel, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002170{
2171 // Use _AddBuffer() because _AddSZString() is defined below, not above
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002172 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
2173 QCBOREncode_AddUInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002174}
2175
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002176static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002177QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002178{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002179 QCBOREncode_AddInt64(pMe, nLabel);
2180 QCBOREncode_AddUInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002181}
2182
2183
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002184static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002185QCBOREncode_AddText(QCBOREncodeContext *pMe, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002186{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002187 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002188}
2189
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002190static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002191QCBOREncode_AddTextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002192{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002193 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szLabel));
2194 QCBOREncode_AddText(pMe, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002195}
2196
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002197static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002198QCBOREncode_AddTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002199{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002200 QCBOREncode_AddInt64(pMe, nLabel);
2201 QCBOREncode_AddText(pMe, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002202}
2203
2204
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002205inline static void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002206QCBOREncode_AddSZString(QCBOREncodeContext *pMe, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002207{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002208 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szString));
Michael Eckel5c531332020-03-02 01:35:30 +01002209}
2210
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002211static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002212QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pMe, const char *szLabel, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002213{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002214 QCBOREncode_AddSZString(pMe, szLabel);
2215 QCBOREncode_AddSZString(pMe, szString);
Michael Eckel5c531332020-03-02 01:35:30 +01002216}
2217
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002218static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002219QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002220{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002221 QCBOREncode_AddInt64(pMe, nLabel);
2222 QCBOREncode_AddSZString(pMe, szString);
Michael Eckel5c531332020-03-02 01:35:30 +01002223}
2224
2225
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +02002226#ifndef USEFULBUF_DISABLE_ALL_FLOAT
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002227static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002228QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pMe, const char *szLabel, double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002229{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002230 QCBOREncode_AddSZString(pMe, szLabel);
2231 QCBOREncode_AddDouble(pMe, dNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002232}
2233
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002234static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002235QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pMe, int64_t nLabel, double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002236{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002237 QCBOREncode_AddInt64(pMe, nLabel);
2238 QCBOREncode_AddDouble(pMe, dNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002239}
2240
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002241static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002242QCBOREncode_AddFloatToMap(QCBOREncodeContext *pMe, const char *szLabel, float dNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002243{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002244 QCBOREncode_AddSZString(pMe, szLabel);
2245 QCBOREncode_AddFloat(pMe, dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002246}
2247
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002248static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002249QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pMe, int64_t nLabel, float fNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002250{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002251 QCBOREncode_AddInt64(pMe, nLabel);
2252 QCBOREncode_AddFloat(pMe, fNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002253}
2254
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002255static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002256QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pMe, const char *szLabel, double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002257{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002258 QCBOREncode_AddSZString(pMe, szLabel);
2259 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002260}
2261
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002262static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002263QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pMe, int64_t nLabel, double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002264{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002265 QCBOREncode_AddInt64(pMe, nLabel);
2266 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002267}
2268
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002269static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002270QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pMe, const char *szLabel, float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002271{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002272 QCBOREncode_AddSZString(pMe, szLabel);
2273 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002274}
2275
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002276static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002277QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pMe, int64_t nLabel, float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002278{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002279 QCBOREncode_AddInt64(pMe, nLabel);
2280 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002281}
Máté Tóth-Pálef5f07a2021-09-17 19:31:37 +02002282#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002283
Michael Eckel5c531332020-03-02 01:35:30 +01002284
Laurence Lundblade9b334962020-08-27 10:55:53 -07002285
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002286static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002287QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pMe, uint8_t uTag, int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002288{
2289 if(uTag == QCBOR_ENCODE_AS_TAG) {
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002290 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_EPOCH);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002291 }
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002292 QCBOREncode_AddInt64(pMe, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002293}
2294
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002295static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002296QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTag, int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002297{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002298 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002299 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002300}
2301
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002302static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002303QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTag, int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002304{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002305 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002306 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002307}
2308
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002309static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002310QCBOREncode_AddDateEpoch(QCBOREncodeContext *pMe, int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002311{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002312 QCBOREncode_AddTDateEpoch(pMe, QCBOR_ENCODE_AS_TAG, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002313}
2314
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002315static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002316QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pMe, const char *szLabel, int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002317{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002318 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002319 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002320}
2321
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002322static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002323QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pMe, int64_t nLabel, int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002324{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002325 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002326 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002327}
2328
2329
Laurence Lundblade46d63e92021-05-13 11:37:10 -07002330static inline void
2331QCBOREncode_AddTDaysEpoch(QCBOREncodeContext *pMe, uint8_t uTag, int64_t nDays)
2332{
2333 if(uTag == QCBOR_ENCODE_AS_TAG) {
2334 QCBOREncode_AddTag(pMe, CBOR_TAG_DAYS_EPOCH);
2335 }
2336 QCBOREncode_AddInt64(pMe, nDays);
2337}
2338
2339static inline void
2340QCBOREncode_AddTDaysEpochToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTag, int64_t nDays)
2341{
2342 QCBOREncode_AddSZString(pMe, szLabel);
2343 QCBOREncode_AddTDaysEpoch(pMe, uTag, nDays);
2344}
2345
2346static inline void
2347QCBOREncode_AddTDaysEpochToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTag, int64_t nDays)
2348{
2349 QCBOREncode_AddInt64(pMe, nLabel);
2350 QCBOREncode_AddTDaysEpoch(pMe, uTag, nDays);
2351}
2352
Laurence Lundblade9b334962020-08-27 10:55:53 -07002353
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002354static inline void
2355QCBOREncode_AddBytes(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002356{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002357 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002358}
2359
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002360static inline void
2361QCBOREncode_AddBytesToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002362{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002363 QCBOREncode_AddSZString(pMe, szLabel);
2364 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002365}
2366
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002367static inline void
2368QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002369{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002370 QCBOREncode_AddInt64(pMe, nLabel);
2371 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002372}
2373
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002374static inline void
2375QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002376{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002377 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002378}
2379
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002380static inline void
2381QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002382{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002383 QCBOREncode_AddSZString(pMe, szLabel);
2384 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002385}
2386
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002387static inline void
2388QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002389{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002390 QCBOREncode_AddInt64(pMe, nLabel);
2391 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002392}
2393
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002394
2395static inline void
2396QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002397{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002398 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2399 QCBOREncode_AddTag(pMe, CBOR_TAG_BIN_UUID);
2400 }
2401 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002402}
2403
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002404static inline void
2405QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pMe,
2406 const char *szLabel,
2407 uint8_t uTagRequirement,
2408 UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002409{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002410 QCBOREncode_AddSZString(pMe, szLabel);
2411 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002412}
2413
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002414static inline void
2415QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002416{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002417 QCBOREncode_AddInt64(pMe, nLabel);
2418 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002419}
2420
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002421static inline void
2422QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002423{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002424 QCBOREncode_AddTBinaryUUID(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002425}
2426
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002427static inline void
2428QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002429{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002430 QCBOREncode_AddTBinaryUUIDToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002431}
2432
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002433static inline void
2434QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002435{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002436 QCBOREncode_AddTBinaryUUIDToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002437}
2438
2439
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002440static inline void
2441QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002442{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002443 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2444 QCBOREncode_AddTag(pMe, CBOR_TAG_POS_BIGNUM);
2445 }
2446 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002447}
2448
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002449static inline void
2450QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pMe,
2451 const char *szLabel,
2452 uint8_t uTagRequirement,
2453 UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002454{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002455 QCBOREncode_AddSZString(pMe, szLabel);
2456 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002457}
2458
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002459static inline void
2460QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002461{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002462 QCBOREncode_AddInt64(pMe, nLabel);
2463 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002464}
2465
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002466static inline void
2467QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2468{
2469 QCBOREncode_AddTPositiveBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2470}
2471
2472static inline void
2473QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2474{
2475 QCBOREncode_AddTPositiveBignumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2476}
2477
2478static inline void
2479QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2480{
2481 QCBOREncode_AddTPositiveBignumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2482}
2483
2484
2485static inline void
2486QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
2487{
2488 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2489 QCBOREncode_AddTag(pMe, CBOR_TAG_NEG_BIGNUM);
2490 }
2491 QCBOREncode_AddBytes(pMe, Bytes);
2492}
2493
2494static inline void
2495QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pMe,
2496 const char *szLabel,
2497 uint8_t uTagRequirement,
2498 UsefulBufC Bytes)
2499{
2500 QCBOREncode_AddSZString(pMe, szLabel);
2501 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2502}
2503
2504static inline void
2505QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
2506{
2507 QCBOREncode_AddInt64(pMe, nLabel);
2508 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2509}
2510
2511static inline void
2512QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2513{
2514 QCBOREncode_AddTNegativeBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2515}
2516
2517static inline void
2518QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2519{
2520 QCBOREncode_AddTNegativeBignumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2521}
2522
2523static inline void
2524QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2525{
2526 QCBOREncode_AddTNegativeBignumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2527}
2528
2529
Michael Eckel5c531332020-03-02 01:35:30 +01002530
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07002531#ifndef QCBOR_DISABLE_EXP_AND_MANTISSA
Michael Eckel5c531332020-03-02 01:35:30 +01002532
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002533static inline void
2534QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pMe,
2535 uint8_t uTagRequirement,
2536 int64_t nMantissa,
2537 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002538{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002539 uint64_t uTag;
2540 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2541 uTag = CBOR_TAG_DECIMAL_FRACTION;
2542 } else {
2543 uTag = CBOR_TAG_INVALID64;
2544 }
2545 QCBOREncode_AddExponentAndMantissa(pMe,
2546 uTag,
Michael Eckel5c531332020-03-02 01:35:30 +01002547 NULLUsefulBufC,
2548 false,
2549 nMantissa,
2550 nBase10Exponent);
2551}
2552
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002553static inline void
2554QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pMe,
2555 const char *szLabel,
2556 uint8_t uTagRequirement,
2557 int64_t nMantissa,
2558 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002559{
2560 QCBOREncode_AddSZString(pMe, szLabel);
2561 QCBOREncode_AddTDecimalFraction(pMe, uTagRequirement, nMantissa, nBase10Exponent);
2562}
2563
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002564static inline void
2565QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pMe,
2566 int64_t nLabel,
2567 uint8_t uTagRequirement,
2568 int64_t nMantissa,
2569 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002570{
2571 QCBOREncode_AddInt64(pMe, nLabel);
2572 QCBOREncode_AddTDecimalFraction(pMe, uTagRequirement, nMantissa, nBase10Exponent);
2573}
2574
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002575static inline void
2576QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pMe,
2577 int64_t nMantissa,
2578 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002579{
2580 QCBOREncode_AddTDecimalFraction(pMe, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
2581}
2582
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002583static inline void
2584QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pMe,
2585 const char *szLabel,
2586 int64_t nMantissa,
2587 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002588{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002589 QCBOREncode_AddTDecimalFractionToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002590}
2591
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002592static inline void
2593QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pMe,
2594 int64_t nLabel,
2595 int64_t nMantissa,
2596 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002597{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002598 QCBOREncode_AddTDecimalFractionToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002599}
2600
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002601
2602
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002603static inline void
2604QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pMe,
2605 uint8_t uTagRequirement,
2606 UsefulBufC Mantissa,
2607 bool bIsNegative,
2608 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002609{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002610 uint64_t uTag;
2611 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2612 uTag = CBOR_TAG_DECIMAL_FRACTION;
2613 } else {
2614 uTag = CBOR_TAG_INVALID64;
2615 }
2616 QCBOREncode_AddExponentAndMantissa(pMe,
2617 uTag,
Michael Eckel5c531332020-03-02 01:35:30 +01002618 Mantissa, bIsNegative,
2619 0,
2620 nBase10Exponent);
2621}
2622
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002623static inline void
2624QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
2625 const char *szLabel,
2626 uint8_t uTagRequirement,
2627 UsefulBufC Mantissa,
2628 bool bIsNegative,
2629 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002630{
2631 QCBOREncode_AddSZString(pMe, szLabel);
2632 QCBOREncode_AddTDecimalFractionBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase10Exponent);
2633}
2634
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002635static inline void
2636QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
2637 int64_t nLabel,
2638 uint8_t uTagRequirement,
2639 UsefulBufC Mantissa,
2640 bool bIsNegative,
2641 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002642{
2643 QCBOREncode_AddInt64(pMe, nLabel);
2644 QCBOREncode_AddTDecimalFractionBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase10Exponent);
2645}
2646
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002647static inline void
2648QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pMe,
2649 UsefulBufC Mantissa,
2650 bool bIsNegative,
2651 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002652{
2653 QCBOREncode_AddTDecimalFractionBigNum(pMe, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase10Exponent);
2654}
2655
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002656static inline void
2657QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
2658 const char *szLabel,
2659 UsefulBufC Mantissa,
2660 bool bIsNegative,
2661 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002662{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002663 QCBOREncode_AddTDecimalFractionBigNumToMapSZ(pMe,
2664 szLabel,
2665 QCBOR_ENCODE_AS_TAG,
2666 Mantissa,
2667 bIsNegative,
2668 nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002669}
2670
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002671static inline void
2672QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
2673 int64_t nLabel,
2674 UsefulBufC Mantissa,
2675 bool bIsNegative,
2676 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002677{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002678 QCBOREncode_AddTDecimalFractionBigNumToMapN(pMe,
2679 nLabel,
2680 QCBOR_ENCODE_AS_TAG,
2681 Mantissa,
2682 bIsNegative,
2683 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002684}
2685
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002686
2687
2688
2689
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002690static inline void
2691QCBOREncode_AddTBigFloat(QCBOREncodeContext *pMe,
2692 uint8_t uTagRequirement,
2693 int64_t nMantissa,
2694 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002695{
2696 uint64_t uTag;
2697 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2698 uTag = CBOR_TAG_BIGFLOAT;
2699 } else {
2700 uTag = CBOR_TAG_INVALID64;
2701 }
2702 QCBOREncode_AddExponentAndMantissa(pMe, uTag, NULLUsefulBufC, false, nMantissa, nBase2Exponent);
2703}
2704
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002705static inline void
2706QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pMe,
2707 const char *szLabel,
2708 uint8_t uTagRequirement,
2709 int64_t nMantissa,
2710 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002711{
2712 QCBOREncode_AddSZString(pMe, szLabel);
2713 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
2714}
2715
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002716static inline void
2717QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pMe,
2718 int64_t nLabel,
2719 uint8_t uTagRequirement,
2720 int64_t nMantissa,
2721 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002722{
2723 QCBOREncode_AddInt64(pMe, nLabel);
2724 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
2725}
2726
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002727static inline void
2728QCBOREncode_AddBigFloat(QCBOREncodeContext *pMe,
2729 int64_t nMantissa,
2730 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002731{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002732 QCBOREncode_AddTBigFloat(pMe, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002733}
2734
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002735static inline void
2736QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pMe,
2737 const char *szLabel,
2738 int64_t nMantissa,
2739 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002740{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002741 QCBOREncode_AddTBigFloatToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002742}
2743
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002744static inline void
2745QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pMe,
2746 int64_t nLabel,
2747 int64_t nMantissa,
2748 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002749{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002750 QCBOREncode_AddTBigFloatToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002751}
2752
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002753
2754
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002755static inline void
2756QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pMe,
2757 uint8_t uTagRequirement,
2758 UsefulBufC Mantissa,
2759 bool bIsNegative,
2760 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002761{
2762 uint64_t uTag;
2763 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2764 uTag = CBOR_TAG_BIGFLOAT;
2765 } else {
2766 uTag = CBOR_TAG_INVALID64;
2767 }
2768 QCBOREncode_AddExponentAndMantissa(pMe, uTag, Mantissa, bIsNegative, 0, nBase2Exponent);
2769}
2770
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002771static inline void
2772QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pMe,
2773 const char *szLabel,
2774 uint8_t uTagRequirement,
2775 UsefulBufC Mantissa,
2776 bool bIsNegative,
2777 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002778{
2779 QCBOREncode_AddSZString(pMe, szLabel);
2780 QCBOREncode_AddTBigFloatBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase2Exponent);
2781}
2782
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002783static inline void
2784QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
2785 int64_t nLabel,
2786 uint8_t uTagRequirement,
2787 UsefulBufC Mantissa,
2788 bool bIsNegative,
2789 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002790{
2791 QCBOREncode_AddInt64(pMe, nLabel);
2792 QCBOREncode_AddTBigFloatBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase2Exponent);
2793}
2794
2795
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002796static inline void
2797QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pMe,
2798 UsefulBufC Mantissa,
2799 bool bIsNegative,
2800 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002801{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002802 QCBOREncode_AddTBigFloatBigNum(pMe, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002803}
2804
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002805static inline void
2806QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pMe,
2807 const char *szLabel,
2808 UsefulBufC Mantissa,
2809 bool bIsNegative,
2810 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002811{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002812 QCBOREncode_AddTBigFloatBigNumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002813}
2814
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002815static inline void
2816QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
2817 int64_t nLabel,
2818 UsefulBufC Mantissa,
2819 bool bIsNegative,
2820 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002821{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002822 QCBOREncode_AddTBigFloatBigNumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002823}
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07002824#endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
Michael Eckel5c531332020-03-02 01:35:30 +01002825
2826
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002827static inline void
2828QCBOREncode_AddTURI(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002829{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002830 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2831 QCBOREncode_AddTag(pMe, CBOR_TAG_URI);
2832 }
2833 QCBOREncode_AddText(pMe, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002834}
2835
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002836static inline void
2837QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002838{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002839 QCBOREncode_AddSZString(pMe, szLabel);
2840 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002841}
2842
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002843static inline void
2844QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002845{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002846 QCBOREncode_AddInt64(pMe, nLabel);
2847 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
2848}
2849
2850static inline void
2851QCBOREncode_AddURI(QCBOREncodeContext *pMe, UsefulBufC URI)
2852{
2853 QCBOREncode_AddTURI(pMe, QCBOR_ENCODE_AS_TAG, URI);
2854}
2855
2856static inline void
2857QCBOREncode_AddURIToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC URI)
2858{
2859 QCBOREncode_AddTURIToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, URI);
2860}
2861
2862static inline void
2863QCBOREncode_AddURIToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC URI)
2864{
2865 QCBOREncode_AddTURIToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002866}
2867
2868
2869
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002870static inline void
2871QCBOREncode_AddTB64Text(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002872{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002873 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2874 QCBOREncode_AddTag(pMe, CBOR_TAG_B64);
2875 }
2876 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002877}
2878
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002879static inline void
2880QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pMe,
2881 const char *szLabel,
2882 uint8_t uTagRequirement,
2883 UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002884{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002885 QCBOREncode_AddSZString(pMe, szLabel);
2886 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002887}
2888
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002889static inline void
2890QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002891{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002892 QCBOREncode_AddInt64(pMe, nLabel);
2893 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
2894}
2895
2896static inline void
2897QCBOREncode_AddB64Text(QCBOREncodeContext *pMe, UsefulBufC B64Text)
2898{
2899 QCBOREncode_AddTB64Text(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
2900}
2901
2902static inline void
2903QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC B64Text)
2904{
2905 QCBOREncode_AddTB64TextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
2906}
2907
2908static inline void
2909QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC B64Text)
2910{
2911 QCBOREncode_AddTB64TextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002912}
2913
2914
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002915
2916static inline void
2917QCBOREncode_AddTB64URLText(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002918{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002919 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2920 QCBOREncode_AddTag(pMe, CBOR_TAG_B64URL);
2921 }
2922 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002923}
2924
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002925static inline void
2926QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pMe,
2927 const char *szLabel,
2928 uint8_t uTagRequirement,
2929 UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002930{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002931 QCBOREncode_AddSZString(pMe, szLabel);
2932 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002933}
2934
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002935static inline void
2936QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002937{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002938 QCBOREncode_AddInt64(pMe, nLabel);
2939 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
2940}
2941
2942static inline void
2943QCBOREncode_AddB64URLText(QCBOREncodeContext *pMe, UsefulBufC B64Text)
2944{
2945 QCBOREncode_AddTB64URLText(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
2946}
2947
2948static inline void
2949QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC B64Text)
2950{
2951 QCBOREncode_AddTB64URLTextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
2952}
2953
2954static inline void
2955QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC B64Text)
2956{
2957 QCBOREncode_AddTB64URLTextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002958}
2959
2960
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002961
2962static inline void
2963QCBOREncode_AddTRegex(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002964{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002965 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2966 QCBOREncode_AddTag(pMe, CBOR_TAG_REGEX);
2967 }
2968 QCBOREncode_AddText(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002969}
2970
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002971static inline void
2972QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002973{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002974 QCBOREncode_AddSZString(pMe, szLabel);
2975 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002976}
2977
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002978static inline void
2979QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002980{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002981 QCBOREncode_AddInt64(pMe, nLabel);
2982 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
2983}
2984
2985static inline void
2986QCBOREncode_AddRegex(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2987{
2988 QCBOREncode_AddTRegex(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2989}
2990
2991static inline void
2992QCBOREncode_AddRegexToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2993{
2994 QCBOREncode_AddTRegexToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2995}
2996
2997static inline void
2998QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2999{
3000 QCBOREncode_AddTRegexToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
3001
Michael Eckel5c531332020-03-02 01:35:30 +01003002}
3003
3004
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003005static inline void
3006QCBOREncode_AddTMIMEData(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01003007{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003008 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
Laurence Lundblade4982f412020-09-18 23:02:18 -07003009 QCBOREncode_AddTag(pMe, CBOR_TAG_BINARY_MIME);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003010 }
Laurence Lundblade4982f412020-09-18 23:02:18 -07003011 QCBOREncode_AddBytes(pMe, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01003012}
3013
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003014static inline void
3015QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pMe,
3016 const char *szLabel,
3017 uint8_t uTagRequirement,
3018 UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01003019{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003020 QCBOREncode_AddSZString(pMe, szLabel);
3021 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01003022}
3023
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003024static inline void
3025QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01003026{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003027 QCBOREncode_AddInt64(pMe, nLabel);
3028 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
3029}
3030
3031static inline void
3032QCBOREncode_AddMIMEData(QCBOREncodeContext *pMe, UsefulBufC MIMEData)
3033{
3034 QCBOREncode_AddTMIMEData(pMe, QCBOR_ENCODE_AS_TAG, MIMEData);
3035}
3036
3037static inline void
3038QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC MIMEData)
3039{
3040 QCBOREncode_AddTMIMEDataToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
3041}
3042
3043static inline void
3044QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC MIMEData)
3045{
3046 QCBOREncode_AddTMIMEDataToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01003047}
3048
3049
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003050static inline void
3051QCBOREncode_AddTDateString(QCBOREncodeContext *pMe, uint8_t uTagRequirement, const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01003052{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003053 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3054 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_STRING);
3055 }
3056 QCBOREncode_AddSZString(pMe, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01003057}
3058
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003059static inline void
3060QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pMe,
3061 const char *szLabel,
3062 uint8_t uTagRequirement,
3063 const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01003064{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003065 QCBOREncode_AddSZString(pMe, szLabel);
3066 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01003067}
3068
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003069static inline void
3070QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01003071{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003072 QCBOREncode_AddInt64(pMe, nLabel);
3073 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
3074}
3075
3076static inline void
3077QCBOREncode_AddDateString(QCBOREncodeContext *pMe, const char *szDate)
3078{
3079 QCBOREncode_AddTDateString(pMe, QCBOR_ENCODE_AS_TAG, szDate);
3080}
3081
3082static inline void
3083QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pMe, const char *szLabel, const char *szDate)
3084{
3085 QCBOREncode_AddTDateStringToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, szDate);
3086}
3087
3088static inline void
3089QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, const char *szDate)
3090{
3091 QCBOREncode_AddTDateStringToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01003092}
3093
3094
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003095static inline void
Laurence Lundblade46d63e92021-05-13 11:37:10 -07003096QCBOREncode_AddTDaysString(QCBOREncodeContext *pMe, uint8_t uTagRequirement, const char *szDate)
3097{
3098 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3099 QCBOREncode_AddTag(pMe, CBOR_TAG_DAYS_STRING);
3100 }
3101 QCBOREncode_AddSZString(pMe, szDate);
3102}
3103
3104static inline void
3105QCBOREncode_AddTDaysStringToMapSZ(QCBOREncodeContext *pMe,
3106 const char *szLabel,
3107 uint8_t uTagRequirement,
3108 const char *szDate)
3109{
3110 QCBOREncode_AddSZString(pMe, szLabel);
3111 QCBOREncode_AddTDaysString(pMe, uTagRequirement, szDate);
3112}
3113
3114static inline void
3115QCBOREncode_AddTDaysStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, const char *szDate)
3116{
3117 QCBOREncode_AddInt64(pMe, nLabel);
3118 QCBOREncode_AddTDaysString(pMe, uTagRequirement, szDate);
3119}
3120
3121
3122
3123static inline void
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003124QCBOREncode_AddSimple(QCBOREncodeContext *pMe, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01003125{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003126 QCBOREncode_AddType7(pMe, 0, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01003127}
3128
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003129static inline void
3130QCBOREncode_AddSimpleToMap(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01003131{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003132 QCBOREncode_AddSZString(pMe, szLabel);
3133 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01003134}
3135
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003136static inline void
3137QCBOREncode_AddSimpleToMapN(QCBOREncodeContext *pMe, int nLabel, uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01003138{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003139 QCBOREncode_AddInt64(pMe, nLabel);
3140 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01003141}
3142
3143
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003144static inline void
3145QCBOREncode_AddBool(QCBOREncodeContext *pMe, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01003146{
3147 uint8_t uSimple = CBOR_SIMPLEV_FALSE;
3148 if(b) {
3149 uSimple = CBOR_SIMPLEV_TRUE;
3150 }
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003151 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01003152}
3153
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003154static inline void
3155QCBOREncode_AddBoolToMap(QCBOREncodeContext *pMe, const char *szLabel, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01003156{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003157 QCBOREncode_AddSZString(pMe, szLabel);
3158 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01003159}
3160
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003161static inline void
3162QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pMe, int64_t nLabel, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01003163{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003164 QCBOREncode_AddInt64(pMe, nLabel);
3165 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01003166}
3167
3168
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003169static inline void
3170QCBOREncode_AddNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003171{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003172 QCBOREncode_AddSimple(pMe, CBOR_SIMPLEV_NULL);
Michael Eckel5c531332020-03-02 01:35:30 +01003173}
3174
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003175static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003176QCBOREncode_AddNULLToMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003177{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003178 QCBOREncode_AddSZString(pMe, szLabel);
3179 QCBOREncode_AddNULL(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003180}
3181
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003182static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003183QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003184{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003185 QCBOREncode_AddInt64(pMe, nLabel);
3186 QCBOREncode_AddNULL(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003187}
3188
3189
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003190static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003191QCBOREncode_AddUndef(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003192{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003193 QCBOREncode_AddSimple(pMe, CBOR_SIMPLEV_UNDEF);
Michael Eckel5c531332020-03-02 01:35:30 +01003194}
3195
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003196static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003197QCBOREncode_AddUndefToMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003198{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003199 QCBOREncode_AddSZString(pMe, szLabel);
3200 QCBOREncode_AddUndef(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003201}
3202
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003203static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003204QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003205{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003206 QCBOREncode_AddInt64(pMe, nLabel);
3207 QCBOREncode_AddUndef(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003208}
3209
3210
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003211static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003212QCBOREncode_OpenArray(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003213{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003214 QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
Michael Eckel5c531332020-03-02 01:35:30 +01003215}
3216
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003217static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003218QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003219{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003220 QCBOREncode_AddSZString(pMe, szLabel);
3221 QCBOREncode_OpenArray(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003222}
3223
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003224static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003225QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003226{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003227 QCBOREncode_AddInt64(pMe, nLabel);
3228 QCBOREncode_OpenArray(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003229}
3230
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003231static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003232QCBOREncode_CloseArray(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003233{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003234 QCBOREncode_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
Michael Eckel5c531332020-03-02 01:35:30 +01003235}
3236
3237
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003238static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003239QCBOREncode_OpenMap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003240{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003241 QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
Michael Eckel5c531332020-03-02 01:35:30 +01003242}
3243
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003244static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003245QCBOREncode_OpenMapInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003246{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003247 QCBOREncode_AddSZString(pMe, szLabel);
3248 QCBOREncode_OpenMap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003249}
3250
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003251static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003252QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003253{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003254 QCBOREncode_AddInt64(pMe, nLabel);
3255 QCBOREncode_OpenMap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003256}
3257
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003258static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003259QCBOREncode_CloseMap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003260{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003261 QCBOREncode_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
Michael Eckel5c531332020-03-02 01:35:30 +01003262}
3263
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003264static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003265QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003266{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003267 QCBOREncode_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003268}
3269
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003270static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003271QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003272{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003273 QCBOREncode_AddSZString(pMe, szLabel);
3274 QCBOREncode_OpenArrayIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003275}
3276
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003277static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003278QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003279{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003280 QCBOREncode_AddInt64(pMe, nLabel);
3281 QCBOREncode_OpenArrayIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003282}
3283
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003284static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003285QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003286{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003287 QCBOREncode_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003288}
3289
3290
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003291static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003292QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003293{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003294 QCBOREncode_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003295}
3296
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003297static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003298QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003299{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003300 QCBOREncode_AddSZString(pMe, szLabel);
3301 QCBOREncode_OpenMapIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003302}
3303
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003304static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003305QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003306{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003307 QCBOREncode_AddInt64(pMe, nLabel);
3308 QCBOREncode_OpenMapIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003309}
3310
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003311static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003312QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003313{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003314 QCBOREncode_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003315}
3316
3317
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003318static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003319QCBOREncode_BstrWrap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003320{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003321 QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_BYTE_STRING);
Michael Eckel5c531332020-03-02 01:35:30 +01003322}
3323
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003324static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003325QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003326{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003327 QCBOREncode_AddSZString(pMe, szLabel);
3328 QCBOREncode_BstrWrap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003329}
3330
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003331static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003332QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003333{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003334 QCBOREncode_AddInt64(pMe, nLabel);
3335 QCBOREncode_BstrWrap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003336}
3337
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003338static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003339QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pMe, UsefulBufC *pWrappedCBOR)
Michael Eckel5c531332020-03-02 01:35:30 +01003340{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003341 QCBOREncode_CloseBstrWrap2(pMe, true, pWrappedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01003342}
3343
3344
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003345static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003346QCBOREncode_AddEncoded(QCBOREncodeContext *pMe, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003347{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003348 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_RAW, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003349}
3350
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003351static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003352QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003353{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003354 QCBOREncode_AddSZString(pMe, szLabel);
3355 QCBOREncode_AddEncoded(pMe, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003356}
3357
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003358static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003359QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003360{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003361 QCBOREncode_AddInt64(pMe, nLabel);
3362 QCBOREncode_AddEncoded(pMe, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003363}
3364
3365
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003366static inline int
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003367QCBOREncode_IsBufferNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003368{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003369 return UsefulOutBuf_IsBufferNULL(&(pMe->OutBuf));
Michael Eckel5c531332020-03-02 01:35:30 +01003370}
3371
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003372static inline QCBORError
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003373QCBOREncode_GetErrorState(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003374{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003375 if(UsefulOutBuf_GetError(&(pMe->OutBuf))) {
Michael Eckel5c531332020-03-02 01:35:30 +01003376 // Items didn't fit in the buffer.
3377 // This check catches this condition for all the appends and inserts
3378 // so checks aren't needed when the appends and inserts are performed.
3379 // And of course UsefulBuf will never overrun the input buffer given
3380 // to it. No complex analysis of the error handling in this file is
3381 // needed to know that is true. Just read the UsefulBuf code.
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003382 pMe->uError = QCBOR_ERR_BUFFER_TOO_SMALL;
Michael Eckel5c531332020-03-02 01:35:30 +01003383 // QCBOR_ERR_BUFFER_TOO_SMALL masks other errors, but that is
3384 // OK. Once the caller fixes this, they'll be unmasked.
3385 }
3386
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003387 return (QCBORError)pMe->uError;
Michael Eckel5c531332020-03-02 01:35:30 +01003388}
3389
3390
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003391/* ========================================================================
3392 END OF PRIVATE INLINE IMPLEMENTATION
3393 ======================================================================== */
Michael Eckel5c531332020-03-02 01:35:30 +01003394
3395#ifdef __cplusplus
3396}
3397#endif
3398
Laurence Lundblade844bb5c2020-03-01 17:27:25 -08003399#endif /* qcbor_encode_h */