blob: ba654eef105154c8b355d3f98cf44000f0262262 [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.
Michael Eckel5c531332020-03-02 01:35:30 +01004 All rights reserved.
5
6Redistribution and use in source and binary forms, with or without
7modification, are permitted provided that the following conditions are
8met:
9 * Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above
12 copyright notice, this list of conditions and the following
13 disclaimer in the documentation and/or other materials provided
14 with the distribution.
15 * Neither the name of The Linux Foundation nor the names of its
16 contributors, nor the name "Laurence Lundblade" may be used to
17 endorse or promote products derived from this software without
18 specific prior written permission.
19
20THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
21WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
23ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
24BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
30IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 =============================================================================*/
32
33
Laurence Lundblade844bb5c2020-03-01 17:27:25 -080034#ifndef qcbor_encode_h
35#define qcbor_encode_h
Michael Eckel5c531332020-03-02 01:35:30 +010036
37
Laurence Lundblade844bb5c2020-03-01 17:27:25 -080038#include "qcbor/qcbor_common.h"
39#include "qcbor/qcbor_private.h"
Michael Eckel5c531332020-03-02 01:35:30 +010040#include <stdbool.h>
Laurence Lundblade844bb5c2020-03-01 17:27:25 -080041
Michael Eckel5c531332020-03-02 01:35:30 +010042
43#ifdef __cplusplus
44extern "C" {
Dave Thaler12b23752020-03-27 01:23:08 -070045#if 0
Michael Eckel5c531332020-03-02 01:35:30 +010046} // Keep editor indention formatting happy
47#endif
48#endif
49
Michael Eckel5c531332020-03-02 01:35:30 +010050
51/**
Laurence Lundblade844bb5c2020-03-01 17:27:25 -080052 @file qcbor_encode.h
Michael Eckel5c531332020-03-02 01:35:30 +010053
Laurence Lundblade9a3b6252020-10-21 21:30:31 -070054 @anchor Overview
55
56 # QCBOR Overview
Michael Eckel5c531332020-03-02 01:35:30 +010057
58 This implements CBOR -- Concise Binary Object Representation as
Laurence Lundbladec02e13e2020-12-06 05:45:41 -080059 defined in [RFC 8949] (https://tools.ietf.org/html/rfc8949). More
Laurence Lundblade18e1d522020-10-22 02:18:41 -070060 information is at http://cbor.io. This is a near-complete implementation of
61 the specification. [RFC 8742] (https://tools.ietf.org/html/rfc8742) CBOR
62 Sequences is also supported. Limitations are listed further down.
Michael Eckel5c531332020-03-02 01:35:30 +010063
Laurence Lundblade9a3b6252020-10-21 21:30:31 -070064 See @ref Encoding for general discussion on encoding,
65 @ref BasicDecode for general discussion on the basic decode features
66 and @ref SpiffyDecode for general discussion on the easier-to-use
67 decoder functions.
68
Michael Eckel5c531332020-03-02 01:35:30 +010069 CBOR is intentionally designed to be translatable to JSON, but not
Laurence Lundbladec02e13e2020-12-06 05:45:41 -080070 all CBOR can convert to JSON. See RFC 8949 for more info on how to
Michael Eckel5c531332020-03-02 01:35:30 +010071 construct CBOR that is the most JSON friendly.
72
73 The memory model for encoding and decoding is that encoded CBOR must
74 be in a contiguous buffer in memory. During encoding the caller must
75 supply an output buffer and if the encoding would go off the end of
76 the buffer an error is returned. During decoding the caller supplies
77 the encoded CBOR in a contiguous buffer and the decoder returns
78 pointers and lengths into that buffer for strings.
79
80 This implementation does not require malloc. All data structures
81 passed in/out of the APIs can fit on the stack.
82
83 Decoding of indefinite-length strings is a special case that requires
84 a "string allocator" to allocate memory into which the segments of
85 the string are coalesced. Without this, decoding will error out if an
86 indefinite-length string is encountered (indefinite-length maps and
87 arrays do not require the string allocator). A simple string
88 allocator called MemPool is built-in and will work if supplied with a
89 block of memory to allocate. The string allocator can optionally use
90 malloc() or some other custom scheme.
91
92 Here are some terms and definitions:
93
94 - "Item", "Data Item": An integer or string or such. The basic "thing" that
95 CBOR is about. An array is an item itself that contains some items.
96
97 - "Array": An ordered sequence of items, the same as JSON.
98
99 - "Map": A collection of label/value pairs. Each pair is a data
100 item. A JSON "object" is the same as a CBOR "map".
101
102 - "Label": The data item in a pair in a map that names or identifies
103 the pair, not the value. This implementation refers to it as a
104 "label". JSON refers to it as the "name". The CBOR RFC refers to it
105 this as a "key". This implementation chooses label instead because
106 key is too easily confused with a cryptographic key. The COSE
107 standard, which uses CBOR, has also chosen to use the term "label"
108 rather than "key" for this same reason.
109
110 - "Key": See "Label" above.
111
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700112 - "Tag": A data item that is an explicitly labeled new data
113 type made up of the tagging integer and the tag content.
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700114 See @ref Tags-Overview and @ref Tag-Usage.
Michael Eckel5c531332020-03-02 01:35:30 +0100115
116 - "Initial Byte": The first byte of an encoded item. Encoding and
117 decoding of this byte is taken care of by the implementation.
118
119 - "Additional Info": In addition to the major type, all data items
120 have some other info. This is usually the length of the data but can
121 be several other things. Encoding and decoding of this is taken care
122 of by the implementation.
123
124 CBOR has two mechanisms for tagging and labeling the data values like
125 integers and strings. For example, an integer that represents
126 someone's birthday in epoch seconds since Jan 1, 1970 could be
127 encoded like this:
128
129 - First it is CBOR_MAJOR_TYPE_POSITIVE_INT (@ref QCBOR_TYPE_INT64),
130 the primitive positive integer.
131
132 - Next it has a "tag" @ref CBOR_TAG_DATE_EPOCH indicating the integer
133 represents a date in the form of the number of seconds since Jan 1,
134 1970.
135
136 - Last it has a string "label" like "BirthDate" indicating the
137 meaning of the data.
138
139 The encoded binary looks like this:
140
141 a1 # Map of 1 item
142 69 # Indicates text string of 9 bytes
143 426972746844617465 # The text "BirthDate"
144 c1 # Tags next integer as epoch date
145 1a # Indicates a 4-byte integer
146 580d4172 # unsigned integer date 1477263730
147
148 Implementors using this API will primarily work with
149 labels. Generally, tags are only needed for making up new data
150 types. This implementation covers most of the data types defined in
151 the RFC using tags. It also, allows for the use of custom tags if
152 necessary.
153
154 This implementation explicitly supports labels that are text strings
155 and integers. Text strings translate nicely into JSON objects and are
156 very readable. Integer labels are much less readable but can be very
157 compact. If they are in the range of 0 to 23, they take up only one
158 byte.
159
160 CBOR allows a label to be any type of data including an array or a
161 map. It is possible to use this API to construct and parse such
162 labels, but it is not explicitly supported.
163
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700164 @anchor Encoding
165
166 ## Encoding
167
Michael Eckel5c531332020-03-02 01:35:30 +0100168 A common encoding usage mode is to invoke the encoding twice. First
169 with no output buffer to compute the length of the needed output
170 buffer. Then the correct sized output buffer is allocated. Last the
171 encoder is invoked again, this time with the output buffer.
172
173 The double invocation is not required if the maximum output buffer
174 size can be predicted. This is usually possible for simple CBOR
175 structures. If the double invocation is implemented, it can be in a
176 loop or function as in the example code so that the code doesn't have
177 to actually be written twice, saving code size.
178
179 If a buffer too small to hold the encoded output is given, the error
180 @ref QCBOR_ERR_BUFFER_TOO_SMALL will be returned. Data will never be
181 written off the end of the output buffer no matter which functions
182 here are called or what parameters are passed to them.
183
184 The encoding error handling is simple. The only possible errors are
185 trying to encode structures that are too large or too complex. There
186 are no internal malloc calls so there will be no failures for out of
187 memory. The error state is tracked internally, so there is no need
188 to check for errors when encoding. Only the return code from
189 QCBOREncode_Finish() need be checked as once an error happens, the
190 encoder goes into an error state and calls to it to add more data
191 will do nothing. An error check is not needed after every data item
192 is added.
193
194 Encoding generally proceeds by calling QCBOREncode_Init(), calling
195 lots of @c QCBOREncode_AddXxx() functions and calling
196 QCBOREncode_Finish(). There are many @c QCBOREncode_AddXxx()
197 functions for various data types. The input buffers need only to be
198 valid during the @c QCBOREncode_AddXxx() calls as the data is copied
199 into the output buffer.
200
201 There are three `Add` functions for each data type. The first / main
202 one for the type is for adding the data item to an array. The second
203 one's name ends in `ToMap`, is used for adding data items to maps and
204 takes a string argument that is its label in the map. The third one
205 ends in `ToMapN`, is also used for adding data items to maps, and
206 takes an integer argument that is its label in the map.
207
208 The simplest aggregate type is an array, which is a simple ordered
209 set of items without labels the same as JSON arrays. Call
210 QCBOREncode_OpenArray() to open a new array, then various @c
211 QCBOREncode_AddXxx() functions to put items in the array and then
212 QCBOREncode_CloseArray(). Nesting to the limit @ref
213 QCBOR_MAX_ARRAY_NESTING is allowed. All opens must be matched by
214 closes or an encoding error will be returned.
215
216 The other aggregate type is a map which does use labels. The `Add`
217 functions that end in `ToMap` and `ToMapN` are convenient ways to add
218 labeled data items to a map. You can also call any type of `Add`
219 function once to add a label of any time and then call any type of
220 `Add` again to add its value.
221
222 Note that when you nest arrays or maps in a map, the nested array or
223 map has a label.
Laurence Lundblade2feb1e12020-07-15 03:50:45 -0700224
Laurence Lundbladee3553422020-05-02 11:11:17 -0700225 Many CBOR-based protocols start with an array or map. This makes them
226 self-delimiting. No external length or end marker is needed to know
227 the end. It is also possible not start this way, in which case this
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700228 it is usually called a CBOR sequence which is described in
229 [RFC 8742] (https://tools.ietf.org/html/rfc8742). This encoder supports
230 either just by whether the first item added is an array, map or other.
Michael Eckel5c531332020-03-02 01:35:30 +0100231
Laurence Lundbladeda97bf42020-11-05 03:38:50 -0800232 If QCBOR is compiled with QCBOR_DISABLE_ENCODE_USAGE_GUARDS defined,
233 the errors QCBOR_ERR_CLOSE_MISMATCH, QCBOR_ERR_ARRAY_TOO_LONG,
234 QCBOR_ERR_TOO_MANY_CLOSES, QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN, and
235 QCBOR_ERR_ENCODE_UNSUPPORTED will never be returned. It is up to the
236 caller to make sure that opened maps, arrays and byte-string wrapping
237 is closed correctly and that QCBOREncode_AddType7() is called
238 correctly. With this defined, it is easier to make a mistake when
239 authoring the encoding of a protocol that will output not well formed
240 CBOR, but as long as the calling code is correct, it is safe to
241 disable these checks. Bounds checking that prevents security issues
242 in the code is still enforced. This define reduces the size of
243 encoding object code by about 150 bytes.
244
Michael Eckel5c531332020-03-02 01:35:30 +0100245 @anchor Tags-Overview
Laurence Lundblade9b334962020-08-27 10:55:53 -0700246
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700247 ## Tags Overview
248
249 Any CBOR data item can be made into a tag to add semantics, define a
250 new data type or such. Some tags are fully standardized and some are
251 just registered. Others are not registered and used in a proprietary
252 way.
Michael Eckel5c531332020-03-02 01:35:30 +0100253
254 Encoding and decoding of many of the registered tags is fully
255 implemented by QCBOR. It is also possible to encode and decode tags
256 that are not directly supported. For many use cases the built-in tag
257 support should be adequate.
258
259 For example, the registered epoch date tag is supported in encoding
260 by QCBOREncode_AddDateEpoch() and in decoding by @ref
261 QCBOR_TYPE_DATE_EPOCH and the @c epochDate member of @ref
262 QCBORItem. This is typical of the built-in tag support. There is an
263 API to encode data for it and a @c QCBOR_TYPE_XXX when it is decoded.
264
265 Tags are registered in the [IANA CBOR Tags Registry]
266 (https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml). There
267 are roughly three options to create a new tag. First, a public
268 specification can be created and the new tag registered with IANA.
269 This is the most formal. Second, the new tag can be registered with
270 IANA with just a short description rather than a full specification.
271 These tags must be greater than 256. Third, a tag can be used without
272 any IANA registration, though the registry should be checked to see
273 that the new value doesn't collide with one that is registered. The
274 value of these tags must be 256 or larger.
275
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700276 See also @ref CBORTags and @ref Tag-Usage
277
Michael Eckel5c531332020-03-02 01:35:30 +0100278 The encoding side of tags not built-in is handled by
279 QCBOREncode_AddTag() and is relatively simple. Tag decoding is more
280 complex and mainly handled by QCBORDecode_GetNext(). Decoding of the
281 structure of tagged data not built-in (if there is any) has to be
282 implemented by the caller.
283
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700284 @anchor Floating-Point
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700285
286 ## Floating-Point
287
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700288 By default QCBOR fully supports IEEE 754 floating-point:
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700289 - Encode/decode of double, single and half-precision
290 - CBOR preferred serialization of floating-point
291 - Floating-point epoch dates
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700292
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700293 For the most part, the type double is used in the interface for
294 floating-point values. In the default configuration, all decoded
295 floating-point values are returned as a double.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700296
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700297 With CBOR preferred serialization, the encoder outputs the smallest
298 representation of the double or float that preserves precision. Zero,
299 NaN and infinity are always output as a half-precision, each taking
300 just 2 bytes. This reduces the number of bytes needed to encode
Laurence Lundblade4b270642020-08-14 12:53:07 -0700301 double and single-precision, especially if zero, NaN and infinity are
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700302 frequently used.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700303
Laurence Lundblade4b270642020-08-14 12:53:07 -0700304 To avoid use of preferred serialization in the standard configuration
305 when encoding, use QCBOREncode_AddDoubleNoPreferred() or
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700306 QCBOREncode_AddFloatNoPreferred().
307
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700308 This implementation of preferred floating-point serialization and
309 half-precision does not depend on the CPU having floating-point HW or
310 the compiler bringing in a (sometimes large) library to compensate
Laurence Lundblade4b270642020-08-14 12:53:07 -0700311 for lack of CPU support. This implementation uses shifts and masks
312 rather than floating-point functions.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700313
Laurence Lundblade4b270642020-08-14 12:53:07 -0700314 To reduce overall object code by about 900 bytes, define
315 QCBOR_DISABLE_PREFERRED_FLOAT. This will eliminate all support for
316 preferred serialization and half-precision. An error will be returned
317 when attempting to decode half-precision. A float will always be
318 encoded and decoded as 32-bits and a double will always be encoded
319 and decoded as 64 bits.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700320
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700321 Note that even if QCBOR_DISABLE_PREFERRED_FLOAT is not defined all
322 the float-point encoding object code can be avoided by never calling
Laurence Lundbladefe09bbf2020-07-16 12:14:51 -0700323 any functions that encode double or float. Just not calling
324 floating-point functions will reduce object code by about 500 bytes.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700325
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700326 On CPUs that have no floating-point hardware,
327 QCBOR_DISABLE_FLOAT_HW_USE should be defined in most cases. If it is
328 not, then the compiler will bring in possibly large software
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700329 libraries to compensate. Defining QCBOR_DISABLE_FLOAT_HW_USE reduces
330 object code size on CPUs with floating-point hardware by a tiny
331 amount and eliminates the need for <math.h>
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700332
Laurence Lundblade4b270642020-08-14 12:53:07 -0700333 When QCBOR_DISABLE_FLOAT_HW_USE is defined, trying to decoding
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700334 floating-point dates will give error
335 @ref QCBOR_ERR_FLOAT_DATE_DISABLED and decoded single-precision
336 numbers will be returned as @ref QCBOR_TYPE_FLOAT instead of
337 converting them to double as usual.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700338
339 If both QCBOR_DISABLE_FLOAT_HW_USE and QCBOR_DISABLE_PREFERRED_FLOAT
Laurence Lundblade4b270642020-08-14 12:53:07 -0700340 are defined, then the only thing QCBOR can do is encode/decode a C
341 float type as 32-bits and a C double type as 64-bits. Floating-point
342 epoch dates will be unsupported.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700343
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700344 ## Limitations
345
Michael Eckel5c531332020-03-02 01:35:30 +0100346 Summary Limits of this implementation:
347 - The entire encoded CBOR must fit into contiguous memory.
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700348 - Max size of encoded / decoded CBOR data is a few bytes less than @c UINT32_MAX (4GB).
Michael Eckel5c531332020-03-02 01:35:30 +0100349 - Max array / map nesting level when encoding / decoding is
350 @ref QCBOR_MAX_ARRAY_NESTING (this is typically 15).
351 - Max items in an array or map when encoding / decoding is
352 @ref QCBOR_MAX_ITEMS_IN_ARRAY (typically 65,536).
353 - Does not directly support labels in maps other than text strings & integers.
354 - Does not directly support integer labels greater than @c INT64_MAX.
355 - Epoch dates limited to @c INT64_MAX (+/- 292 billion years).
356 - Exponents for bigfloats and decimal integers are limited to @c INT64_MAX.
357 - Tags on labels are ignored during decoding.
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700358 - The maximum tag nesting is @c QCBOR_MAX_TAGS_PER_ITEM (typically 4).
Michael Eckel5c531332020-03-02 01:35:30 +0100359 - Works only on 32- and 64-bit CPUs (modifications could make it work
360 on 16-bit CPUs).
361
362 The public interface uses @c size_t for all lengths. Internally the
363 implementation uses 32-bit lengths by design to use less memory and
364 fit structures on the stack. This limits the encoded CBOR it can work
365 with to size @c UINT32_MAX (4GB) which should be enough.
366
367 This implementation assumes two's compliment integer machines. @c
368 <stdint.h> also requires this. It is possible to modify this
369 implementation for another integer representation, but all modern
370 machines seem to be two's compliment.
Michael Eckel5c531332020-03-02 01:35:30 +0100371 */
372
373
Laurence Lundblade825164e2020-10-22 20:18:06 -0700374/**
Michael Eckel5c531332020-03-02 01:35:30 +0100375 The size of the buffer to be passed to QCBOREncode_EncodeHead(). It is one
376 byte larger than sizeof(uint64_t) + 1, the actual maximum size of the
Laurence Lundblade825164e2020-10-22 20:18:06 -0700377 head of a CBOR data item because QCBOREncode_EncodeHead() needs
Michael Eckel5c531332020-03-02 01:35:30 +0100378 one extra byte to work.
379 */
380#define QCBOR_HEAD_BUFFER_SIZE (sizeof(uint64_t) + 2)
381
Michael Eckel5c531332020-03-02 01:35:30 +0100382
Laurence Lundblade9b334962020-08-27 10:55:53 -0700383/**
Laurence Lundblade825164e2020-10-22 20:18:06 -0700384 Output the full CBOR tag. See @ref CBORTags, @ref Tag-Usage and
385 @ref Tags-Overview.
Laurence Lundblade9b334962020-08-27 10:55:53 -0700386 */
387#define QCBOR_ENCODE_AS_TAG 0
388
389/**
Laurence Lundblade825164e2020-10-22 20:18:06 -0700390 Output only the 'borrowed' content format for the relevant tag.
391 See @ref CBORTags, @ref Tag-Usage and @ref Tags-Overview.
Laurence Lundblade9b334962020-08-27 10:55:53 -0700392 */
393#define QCBOR_ENCODE_AS_BORROWED 1
394
Michael Eckel5c531332020-03-02 01:35:30 +0100395
396/**
397 QCBOREncodeContext is the data type that holds context for all the
398 encoding functions. It is less than 200 bytes, so it can go on the
399 stack. The contents are opaque, and the caller should not access
400 internal members. A context may be re used serially as long as it is
401 re initialized.
402 */
403typedef struct _QCBOREncodeContext QCBOREncodeContext;
404
405
406/**
407 Initialize the encoder to prepare to encode some CBOR.
408
409 @param[in,out] pCtx The encoder context to initialize.
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800410 @param[in] Storage The buffer into which the encoded result
411 will be written.
Michael Eckel5c531332020-03-02 01:35:30 +0100412
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800413 Call this once at the start of an encoding of some CBOR. Then call
414 the many functions like QCBOREncode_AddInt64() and
415 QCBOREncode_AddText() to add the different data items. Finally, call
416 QCBOREncode_Finish() to get the pointer and length of the encoded
417 result.
Michael Eckel5c531332020-03-02 01:35:30 +0100418
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800419 The primary purpose of this function is to give the pointer and
420 length of the output buffer into which the encoded CBOR will be
421 written. This is done with a @ref UsefulBuf structure, which is just
422 a pointer and length (it is equivalent to two parameters, one a
423 pointer and one a length, but a little prettier).
Michael Eckel5c531332020-03-02 01:35:30 +0100424
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800425 The output buffer can be allocated any way (malloc, stack,
426 static). It is just some memory that QCBOR writes to. The length must
427 be the length of the allocated buffer. QCBOR will never write past
428 that length, but might write up to that length. If the buffer is too
429 small, encoding will go into an error state and not write anything
430 further.
431
432 If allocating on the stack the convenience macro
433 UsefulBuf_MAKE_STACK_UB() can be used, but its use is not required.
434
435 Since there is no reallocation or such, the output buffer must be
436 correctly sized when passed in here. It is OK, but wasteful if it is
437 too large. One way to pick the size is to figure out the maximum size
438 that will ever be needed and hard code a buffer of that size.
439
440 Another way to do it is to have QCBOR calculate it for you. To do
441 this set @c Storage.ptr to @c NULL and @c Storage.len to @c
442 UINT32_MAX. Then call all the functions to add the CBOR exactly as if
443 encoding for real. Then call QCBOREncode_Finish(). The pointer
444 returned will be @c NULL, but the length returned is that of what would
445 be encoded. Once the length is obtained, allocate a buffer of that
446 size, call QCBOREncode_Init() again with the real buffer. Call all
447 the add functions again and finally, QCBOREncode_Finish() to obtain
448 the final result. This uses almost twice the CPU time, but that is
449 usually not an issue.
450
451 See QCBOREncode_Finish() for how the pointer and length for the
452 encoded CBOR is returned.
453
454 The maximum output buffer size allowed is @c UINT32_MAX (4GB). The
455 error @ref QCBOR_ERR_BUFFER_TOO_LARGE will be returned by
456 QCBOREncode_Finish() if a larger buffer length is passed in.
Michael Eckel5c531332020-03-02 01:35:30 +0100457
458 A @ref QCBOREncodeContext can be reused over and over as long as
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800459 QCBOREncode_Init() is called before each use.
Michael Eckel5c531332020-03-02 01:35:30 +0100460 */
461void QCBOREncode_Init(QCBOREncodeContext *pCtx, UsefulBuf Storage);
462
463
464/**
465 @brief Add a signed 64-bit integer to the encoded output.
466
467 @param[in] pCtx The encoding context to add the integer to.
468 @param[in] nNum The integer to add.
469
470 The integer will be encoded and added to the CBOR output.
471
472 This function figures out the size and the sign and encodes in the
473 correct minimal CBOR. Specifically, it will select CBOR major type 0
474 or 1 based on sign and will encode to 1, 2, 4 or 8 bytes depending on
475 the value of the integer. Values less than 24 effectively encode to
476 one byte because they are encoded in with the CBOR major type. This
477 is a neat and efficient characteristic of CBOR that can be taken
478 advantage of when designing CBOR-based protocols. If integers like
479 tags can be kept between -23 and 23 they will be encoded in one byte
480 including the major type.
481
482 If you pass a smaller int, say an @c int16_t or a small value, say
483 100, the encoding will still be CBOR's most compact that can
484 represent the value. For example, CBOR always encodes the value 0 as
485 one byte, 0x00. The representation as 0x00 includes identification of
486 the type as an integer too as the major type for an integer is 0. See
Laurence Lundbladec02e13e2020-12-06 05:45:41 -0800487 [RFC 8949] (https://tools.ietf.org/html/rfc8949) Appendix A for more
488 examples of CBOR encoding. This compact encoding is also preferred
489 serialization CBOR as per section 34.1 in RFC 8949.
Michael Eckel5c531332020-03-02 01:35:30 +0100490
491 There are no functions to add @c int16_t or @c int32_t because they
492 are not necessary because this always encodes to the smallest number
493 of bytes based on the value (If this code is running on a 32-bit
494 machine having a way to add 32-bit integers would reduce code size
495 some).
496
497 If the encoding context is in an error state, this will do
498 nothing. If an error occurs when adding this integer, the internal
499 error flag will be set, and the error will be returned when
500 QCBOREncode_Finish() is called.
501
502 See also QCBOREncode_AddUInt64().
503 */
504void QCBOREncode_AddInt64(QCBOREncodeContext *pCtx, int64_t nNum);
505
506static void QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum);
507
508static void QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum);
509
510
511/**
512 @brief Add an unsigned 64-bit integer to the encoded output.
513
514 @param[in] pCtx The encoding context to add the integer to.
515 @param[in] uNum The integer to add.
516
517 The integer will be encoded and added to the CBOR output.
518
519 The only reason so use this function is for integers larger than @c
520 INT64_MAX and smaller than @c UINT64_MAX. Otherwise
521 QCBOREncode_AddInt64() will work fine.
522
523 Error handling is the same as for QCBOREncode_AddInt64().
524 */
525void QCBOREncode_AddUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
526
527static void QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum);
528
529static void QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum);
530
531
532/**
533 @brief Add a UTF-8 text string to the encoded output.
534
535 @param[in] pCtx The encoding context to add the text to.
536 @param[in] Text Pointer and length of text to add.
537
538 The text passed in must be unencoded UTF-8 according to [RFC 3629]
539 (https://tools.ietf.org/html/rfc3629). There is no NULL
540 termination. The text is added as CBOR major type 3.
541
542 If called with @c nBytesLen equal to 0, an empty string will be
543 added. When @c nBytesLen is 0, @c pBytes may be @c NULL.
544
545 Note that the restriction of the buffer length to a @c uint32_t is
546 entirely intentional as this encoder is not capable of encoding
547 lengths greater. This limit to 4GB for a text string should not be a
548 problem.
549
Laurence Lundbladeadaf5c22020-09-25 10:37:09 -0700550 Text lines in Internet protocols (on the wire) are delimited by
551 either a CRLF or just an LF. Officially many protocols specify CRLF,
552 but implementations often work with either. CBOR type 3 text can be
553 either line ending, even a mixture of both.
554
555 Operating systems usually have a line end convention. Windows uses
556 CRLF. Linux and MacOS use LF. Some applications on a given OS may
557 work with either and some may not.
558
559 The majority of use cases and CBOR protocols using type 3 text will
560 work with either line ending. However, some use cases or protocols
561 may not work with either in which case translation to and/or from the
562 local line end convention, typically that of the OS, is necessary.
563
564 QCBOR does no line ending translation for type 3 text when encoding
565 and decoding.
566
Michael Eckel5c531332020-03-02 01:35:30 +0100567 Error handling is the same as QCBOREncode_AddInt64().
568 */
569static void QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text);
570
571static void QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text);
572
573static void QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text);
574
575
576/**
577 @brief Add a UTF-8 text string to the encoded output.
578
579 @param[in] pCtx The encoding context to add the text to.
580 @param[in] szString Null-terminated text to add.
581
582 This works the same as QCBOREncode_AddText().
583 */
584static void QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString);
585
586static void QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString);
587
588static void QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString);
589
590
591/**
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700592 @brief Add a double-precision floating-point number to the encoded output.
Michael Eckel5c531332020-03-02 01:35:30 +0100593
594 @param[in] pCtx The encoding context to add the double to.
595 @param[in] dNum The double-precision number to add.
596
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700597 This encodes and outputs a floating-point number. CBOR major type 7
598 is used.
Michael Eckel5c531332020-03-02 01:35:30 +0100599
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700600 This implements preferred serialization, selectively encoding the
601 double-precision floating-point number as either double-precision,
602 single-precision or half-precision. Infinity, NaN and 0 are always
603 encoded as half-precision. If no precision will be lost in the
604 conversion to half-precision, then it will be converted and
605 encoded. If not and no precision will be lost in conversion to
606 single-precision, then it will be converted and encoded. If not, then
607 no conversion is performed, and it encoded as a double-precision.
Michael Eckel5c531332020-03-02 01:35:30 +0100608
609 Half-precision floating-point numbers take up 2 bytes, half that of
610 single-precision, one quarter of double-precision
611
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700612 This automatically reduces the size of encoded CBOR, maybe even by
613 four if most of values are 0, infinity or NaN.
Michael Eckel5c531332020-03-02 01:35:30 +0100614
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700615 When decoded, QCBOR will usually return these values as
616 double-precision.
617
618 It is possible to disable this preferred serialization when compiling
619 QCBOR. In that case, this functions the same as
620 QCBOREncode_AddDoubleNoPreferred().
Michael Eckel5c531332020-03-02 01:35:30 +0100621
622 Error handling is the same as QCBOREncode_AddInt64().
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700623
624 See also QCBOREncode_AddDoubleNoPreferred(), QCBOREncode_AddFloat()
625 and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
Michael Eckel5c531332020-03-02 01:35:30 +0100626 */
627void QCBOREncode_AddDouble(QCBOREncodeContext *pCtx, double dNum);
628
629static void QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
630
631static void QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
632
633
634/**
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700635 @brief Add a single-precision floating-point number to the encoded output.
636
637 @param[in] pCtx The encoding context to add the double to.
638 @param[in] fNum The single-precision number to add.
639
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700640 This is identical to QCBOREncode_AddDouble() except the input is
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700641 single-precision.
642
643 See also QCBOREncode_AddDouble(), QCBOREncode_AddDoubleNoPreferred(),
644 and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
645*/
646void QCBOREncode_AddFloat(QCBOREncodeContext *pCtx, float fNum);
647
648static void QCBOREncode_AddFloatToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
649
650static void QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700651
652
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700653/**
654 @brief Add a double-precision floating-point number without preferred encoding.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700655
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700656 @param[in] pCtx The encoding context to add the double to.
657 @param[in] dNum The double-precision number to add.
658
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700659 This always outputs the number as a 64-bit double-precision.
660 Preferred serialization is not used.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700661
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700662 Error handling is the same as QCBOREncode_AddInt64().
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700663
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700664 See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
665 QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700666*/
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700667void QCBOREncode_AddDoubleNoPreferred(QCBOREncodeContext *pCtx, double dNum);
668
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700669static void QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
670
671static void QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
672
673
674/**
675 @brief Add a single-precision floating-point number without preferred encoding.
676
677 @param[in] pCtx The encoding context to add the double to.
678 @param[in] fNum The single-precision number to add.
679
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700680 This always outputs the number as a 32-bit single-precision.
681 Preferred serialization is not used.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700682
683 Error handling is the same as QCBOREncode_AddInt64().
684
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700685 See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
686 QCBOREncode_AddDoubleNoPreferred() and @ref Floating-Point.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700687*/
688void QCBOREncode_AddFloatNoPreferred(QCBOREncodeContext *pCtx, float fNum);
689
690static void QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
691
692static void QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float fNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700693
694
Michael Eckel5c531332020-03-02 01:35:30 +0100695/**
696 @brief Add an optional tag.
697
698 @param[in] pCtx The encoding context to add the tag to.
699 @param[in] uTag The tag to add
700
701 This outputs a CBOR major type 6 item that tags the next data item
702 that is output usually to indicate it is some new data type.
703
704 For many of the common standard tags, a function to encode data using
705 it is provided and this is not needed. For example,
706 QCBOREncode_AddDateEpoch() already exists to output integers
707 representing dates with the right tag.
708
709 The tag is applied to the next data item added to the encoded
710 output. That data item that is to be tagged can be of any major CBOR
711 type. Any number of tags can be added to a data item by calling this
712 multiple times before the data item is added.
713
714 See @ref Tags-Overview for discussion of creating new non-standard
715 tags. See QCBORDecode_GetNext() for discussion of decoding custom
716 tags.
717*/
Laurence Lundblade6416a0f2020-09-19 23:26:34 -0700718void QCBOREncode_AddTag(QCBOREncodeContext *pCtx, uint64_t uTag);
Michael Eckel5c531332020-03-02 01:35:30 +0100719
720
721/**
722 @brief Add an epoch-based date.
723
724 @param[in] pCtx The encoding context to add the date to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700725 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700726 @param[in] nDate Number of seconds since 1970-01-01T00:00Z in UTC time.
Michael Eckel5c531332020-03-02 01:35:30 +0100727
Laurence Lundbladec02e13e2020-12-06 05:45:41 -0800728 As per RFC 8949 this is similar to UNIX/Linux/POSIX dates. This is
Michael Eckel5c531332020-03-02 01:35:30 +0100729 the most compact way to specify a date and time in CBOR. Note that
730 this is always UTC and does not include the time zone. Use
731 QCBOREncode_AddDateString() if you want to include the time zone.
732
733 The integer encoding rules apply here so the date will be encoded in
734 a minimal number of bytes. Until about the year 2106 these dates will
735 encode in 6 bytes -- one byte for the tag, one byte for the type and
736 4 bytes for the integer. After that it will encode to 10 bytes.
737
738 Negative values are supported for dates before 1970.
739
740 If you care about leap-seconds and that level of accuracy, make sure
741 the system you are running this code on does it correctly. This code
742 just takes the value passed in.
743
744 This implementation cannot encode fractional seconds using float or
745 double even though that is allowed by CBOR, but you can encode them
746 if you want to by calling QCBOREncode_AddDouble() and
747 QCBOREncode_AddTag().
748
749 Error handling is the same as QCBOREncode_AddInt64().
750 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700751static void QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pCtx,
752 uint8_t uTagRequirement,
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700753 int64_t nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -0700754
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700755static void QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pCtx,
756 const char *szLabel,
757 uint8_t uTagRequirement,
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700758 int64_t nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -0700759
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700760static void QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pCtx,
761 int64_t nLabel,
762 uint8_t uTagRequirement,
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700763 int64_t nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -0700764
765
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700766static void QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx,
767 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100768
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700769static void QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx,
770 const char *szLabel,
771 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100772
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700773static void QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx,
774 int64_t nLabel,
775 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100776
777
778/**
779 @brief Add a byte string to the encoded output.
780
781 @param[in] pCtx The encoding context to add the bytes to.
782 @param[in] Bytes Pointer and length of the input data.
783
784 Simply adds the bytes to the encoded output as CBOR major type 2.
785
786 If called with @c Bytes.len equal to 0, an empty string will be
787 added. When @c Bytes.len is 0, @c Bytes.ptr may be @c NULL.
788
789 Error handling is the same as QCBOREncode_AddInt64().
790 */
791static void QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
792
793static void QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
794
795static void QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
796
797
Michael Eckel5c531332020-03-02 01:35:30 +0100798/**
799 @brief Add a binary UUID to the encoded output.
800
801 @param[in] pCtx The encoding context to add the UUID to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700802 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100803 @param[in] Bytes Pointer and length of the binary UUID.
804
805 A binary UUID as defined in [RFC 4122]
806 (https://tools.ietf.org/html/rfc4122) is added to the output.
807
808 It is output as CBOR major type 2, a binary string, with tag @ref
809 CBOR_TAG_BIN_UUID indicating the binary string is a UUID.
810 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700811static void QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pCtx,
812 uint8_t uTagRequirement,
813 UsefulBufC Bytes);
814
815static void QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pCtx,
816 const char *szLabel,
817 uint8_t uTagRequirement,
818 UsefulBufC Bytes);
819
820static void QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pCtx,
821 int64_t nLabel,
822 uint8_t uTagRequirement,
823 UsefulBufC Bytes);
824
825
Michael Eckel5c531332020-03-02 01:35:30 +0100826static void QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
827
828static void QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
829
830static void QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
831
832
833/**
834 @brief Add a positive big number to the encoded output.
835
836 @param[in] pCtx The encoding context to add the big number to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700837 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100838 @param[in] Bytes Pointer and length of the big number.
839
840 Big numbers are integers larger than 64-bits. Their format is
Laurence Lundbladec02e13e2020-12-06 05:45:41 -0800841 described in [RFC 8949] (https://tools.ietf.org/html/rfc8949).
Michael Eckel5c531332020-03-02 01:35:30 +0100842
843 It is output as CBOR major type 2, a binary string, with tag @ref
844 CBOR_TAG_POS_BIGNUM indicating the binary string is a positive big
845 number.
846
847 Often big numbers are used to represent cryptographic keys, however,
848 COSE which defines representations for keys chose not to use this
849 particular type.
850 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700851static void QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pCtx,
852 uint8_t uTagRequirement,
853 UsefulBufC Bytes);
854
855static void QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pCtx,
856 const char *szLabel,
857 uint8_t uTagRequirement,
858 UsefulBufC Bytes);
859
860static void QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pCtx,
861 int64_t nLabel,
862 uint8_t uTagRequirement,
863 UsefulBufC Bytes);
864
865
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700866static void QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx,
867 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100868
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700869static void QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx,
870 const char *szLabel,
871 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100872
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700873static void QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx,
874 int64_t nLabel,
875 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100876
877
878/**
879 @brief Add a negative big number to the encoded output.
880
881 @param[in] pCtx The encoding context to add the big number to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700882 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100883 @param[in] Bytes Pointer and length of the big number.
884
885 Big numbers are integers larger than 64-bits. Their format is
Laurence Lundbladec02e13e2020-12-06 05:45:41 -0800886 described in [RFC 8949] (https://tools.ietf.org/html/rfc8949).
Michael Eckel5c531332020-03-02 01:35:30 +0100887
888 It is output as CBOR major type 2, a binary string, with tag @ref
889 CBOR_TAG_NEG_BIGNUM indicating the binary string is a negative big
890 number.
891
892 Often big numbers are used to represent cryptographic keys, however,
893 COSE which defines representations for keys chose not to use this
894 particular type.
895 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700896static void QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pCtx,
897 uint8_t uTagRequirement,
898 UsefulBufC Bytes);
899
900static void QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pCtx,
901 const char *szLabel,
902 uint8_t uTagRequirement,
903 UsefulBufC Bytes);
904
905static void QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pCtx,
906 int64_t nLabel,
907 uint8_t uTagRequirement,
908 UsefulBufC Bytes);
909
910
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700911static void QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx,
912 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100913
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700914static void QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx,
915 const char *szLabel,
916 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100917
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700918static void QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx,
919 int64_t nLabel,
920 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100921
922
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -0700923#ifndef QCBOR_DISABLE_EXP_AND_MANTISSA
Michael Eckel5c531332020-03-02 01:35:30 +0100924/**
925 @brief Add a decimal fraction to the encoded output.
926
927 @param[in] pCtx The encoding context to add the decimal fraction 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] nMantissa The mantissa.
930 @param[in] nBase10Exponent The exponent.
931
932 The value is nMantissa * 10 ^ nBase10Exponent.
933
934 A decimal fraction is good for exact representation of some values
935 that can't be represented exactly with standard C (IEEE 754)
936 floating-point numbers. Much larger and much smaller numbers can
937 also be represented than floating-point because of the larger number
938 of bits in the exponent.
939
940 The decimal fraction is conveyed as two integers, a mantissa and a
941 base-10 scaling factor.
942
943 For example, 273.15 is represented by the two integers 27315 and -2.
944
945 The exponent and mantissa have the range from @c INT64_MIN to
946 @c INT64_MAX for both encoding and decoding (CBOR allows @c -UINT64_MAX
947 to @c UINT64_MAX, but this implementation doesn't support this range to
948 reduce code size and interface complexity a little).
949
950 CBOR Preferred encoding of the integers is used, thus they will be encoded
951 in the smallest number of bytes possible.
952
953 See also QCBOREncode_AddDecimalFractionBigNum() for a decimal
954 fraction with arbitrarily large precision and QCBOREncode_AddBigFloat().
955
956 There is no representation of positive or negative infinity or NaN
957 (Not a Number). Use QCBOREncode_AddDouble() to encode them.
958
959 See @ref expAndMantissa for decoded representation.
960 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700961static void QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pCtx,
962 uint8_t uTagRequirement,
963 int64_t nMantissa,
964 int64_t nBase10Exponent);
965
966static void QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -0700967 const char *szLabel,
968 uint8_t uTagRequirement,
969 int64_t nMantissa,
970 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700971
972static void QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pCtx,
973 int64_t nLabel,
974 uint8_t uTagRequirement,
975 int64_t nMantissa,
976 int64_t nBase10Exponent);
977
978
Michael Eckel5c531332020-03-02 01:35:30 +0100979static void QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pCtx,
980 int64_t nMantissa,
981 int64_t nBase10Exponent);
982
983static void QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pCtx,
984 const char *szLabel,
985 int64_t nMantissa,
986 int64_t nBase10Exponent);
987
988static void QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pCtx,
989 int64_t nLabel,
990 int64_t nMantissa,
991 int64_t nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +0100992/**
993 @brief Add a decimal fraction with a big number mantissa to the encoded output.
994
995 @param[in] pCtx The encoding context to add the decimal fraction to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700996 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100997 @param[in] Mantissa The mantissa.
998 @param[in] bIsNegative false if mantissa is positive, true if negative.
999 @param[in] nBase10Exponent The exponent.
1000
1001 This is the same as QCBOREncode_AddDecimalFraction() except the
1002 mantissa is a big number (See QCBOREncode_AddPositiveBignum())
1003 allowing for arbitrarily large precision.
1004
1005 See @ref expAndMantissa for decoded representation.
1006 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001007static void QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pCtx,
1008 uint8_t uTagRequirement,
1009 UsefulBufC Mantissa,
1010 bool bIsNegative,
1011 int64_t nBase10Exponent);
1012
1013static void QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001014 const char *szLabel,
1015 uint8_t uTagRequirement,
1016 UsefulBufC Mantissa,
1017 bool bIsNegative,
1018 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001019
1020static void QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
1021 int64_t nLabel,
1022 uint8_t uTagRequirement,
1023 UsefulBufC Mantissa,
1024 bool bIsNegative,
1025 int64_t nBase10Exponent);
1026
1027
Michael Eckel5c531332020-03-02 01:35:30 +01001028static void QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pCtx,
1029 UsefulBufC Mantissa,
1030 bool bIsNegative,
1031 int64_t nBase10Exponent);
1032
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001033static void QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001034 const char *szLabel,
1035 UsefulBufC Mantissa,
1036 bool bIsNegative,
1037 int64_t nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01001038
1039static void QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
1040 int64_t nLabel,
1041 UsefulBufC Mantissa,
1042 bool bIsNegative,
1043 int64_t nBase10Exponent);
1044
1045/**
1046 @brief Add a big floating-point number to the encoded output.
1047
1048 @param[in] pCtx The encoding context to add the bigfloat to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001049 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001050 @param[in] nMantissa The mantissa.
1051 @param[in] nBase2Exponent The exponent.
1052
1053 The value is nMantissa * 2 ^ nBase2Exponent.
1054
1055 "Bigfloats", as CBOR terms them, are similar to IEEE floating-point
1056 numbers in having a mantissa and base-2 exponent, but they are not
1057 supported by hardware or encoded the same. They explicitly use two
1058 CBOR-encoded integers to convey the mantissa and exponent, each of which
1059 can be 8, 16, 32 or 64 bits. With both the mantissa and exponent
1060 64 bits they can express more precision and a larger range than an
1061 IEEE double floating-point number. See
1062 QCBOREncode_AddBigFloatBigNum() for even more precision.
1063
1064 For example, 1.5 would be represented by a mantissa of 3 and an
1065 exponent of -1.
1066
1067 The exponent and mantissa have the range from @c INT64_MIN to
1068 @c INT64_MAX for both encoding and decoding (CBOR allows @c -UINT64_MAX
1069 to @c UINT64_MAX, but this implementation doesn't support this range to
1070 reduce code size and interface complexity a little).
1071
1072 CBOR Preferred encoding of the integers is used, thus they will be encoded
1073 in the smallest number of bytes possible.
1074
1075 This can also be used to represent floating-point numbers in
1076 environments that don't support IEEE 754.
1077
1078 See @ref expAndMantissa for decoded representation.
1079 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001080static void QCBOREncode_AddTBigFloat(QCBOREncodeContext *pCtx,
1081 uint8_t uTagRequirement,
1082 int64_t nMantissa,
1083 int64_t nBase2Exponent);
1084
1085static void QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001086 const char *szLabel,
1087 uint8_t uTagRequirement,
1088 int64_t nMantissa,
1089 int64_t nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001090
1091static void QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pCtx,
1092 int64_t nLabel,
1093 uint8_t uTagRequirement,
1094 int64_t nMantissa,
1095 int64_t nBase2Exponent);
1096
1097
Michael Eckel5c531332020-03-02 01:35:30 +01001098static void QCBOREncode_AddBigFloat(QCBOREncodeContext *pCtx,
1099 int64_t nMantissa,
1100 int64_t nBase2Exponent);
1101
1102static void QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pCtx,
1103 const char *szLabel,
1104 int64_t nMantissa,
1105 int64_t nBase2Exponent);
1106
1107static void QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pCtx,
1108 int64_t nLabel,
1109 int64_t nMantissa,
1110 int64_t nBase2Exponent);
1111
Michael Eckel5c531332020-03-02 01:35:30 +01001112/**
1113 @brief Add a big floating-point number with a big number mantissa to
1114 the encoded output.
1115
1116 @param[in] pCtx The encoding context to add the bigfloat to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001117 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001118 @param[in] Mantissa The mantissa.
1119 @param[in] bIsNegative false if mantissa is positive, true if negative.
1120 @param[in] nBase2Exponent The exponent.
1121
1122 This is the same as QCBOREncode_AddBigFloat() except the mantissa is
1123 a big number (See QCBOREncode_AddPositiveBignum()) allowing for
1124 arbitrary precision.
1125
1126 See @ref expAndMantissa for decoded representation.
1127 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001128static void QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pCtx,
1129 uint8_t uTagRequirement,
1130 UsefulBufC Mantissa,
1131 bool bIsNegative,
1132 int64_t nBase2Exponent);
1133
1134static void QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001135 const char *szLabel,
1136 uint8_t uTagRequirement,
1137 UsefulBufC Mantissa,
1138 bool bIsNegative,
1139 int64_t nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001140
1141static void QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1142 int64_t nLabel,
1143 uint8_t uTagRequirement,
1144 UsefulBufC Mantissa,
1145 bool bIsNegative,
1146 int64_t nBase2Exponent);
1147
1148
Michael Eckel5c531332020-03-02 01:35:30 +01001149static void QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pCtx,
1150 UsefulBufC Mantissa,
1151 bool bIsNegative,
1152 int64_t nBase2Exponent);
1153
1154static void QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pCtx,
1155 const char *szLabel,
1156 UsefulBufC Mantissa,
1157 bool bIsNegative,
1158 int64_t nBase2Exponent);
1159
1160static void QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1161 int64_t nLabel,
1162 UsefulBufC Mantissa,
1163 bool bIsNegative,
1164 int64_t nBase2Exponent);
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07001165#endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
Michael Eckel5c531332020-03-02 01:35:30 +01001166
1167
1168/**
1169 @brief Add a text URI to the encoded output.
1170
1171 @param[in] pCtx The encoding context to add the URI to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001172 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001173 @param[in] URI Pointer and length of the URI.
1174
1175 The format of URI must be per [RFC 3986]
1176 (https://tools.ietf.org/html/rfc3986).
1177
1178 It is output as CBOR major type 3, a text string, with tag @ref
1179 CBOR_TAG_URI indicating the text string is a URI.
1180
1181 A URI in a NULL-terminated string, @c szURI, can be easily added with
1182 this code:
1183
1184 QCBOREncode_AddURI(pCtx, UsefulBuf_FromSZ(szURI));
1185 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001186static void QCBOREncode_AddTURI(QCBOREncodeContext *pCtx,
1187 uint8_t uTagRequirement,
1188 UsefulBufC URI);
1189
1190static void QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pCtx,
1191 const char *szLabel,
1192 uint8_t uTagRequirement,
1193 UsefulBufC URI);
1194
1195static void QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pCtx,
1196 int64_t nLabel,
1197 uint8_t uTagRequirement,
1198 UsefulBufC URI);
1199
1200
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001201static void QCBOREncode_AddURI(QCBOREncodeContext *pCtx,
1202 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001203
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001204static void QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx,
1205 const char *szLabel,
1206 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001207
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001208static void QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx,
1209 int64_t nLabel,
1210 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001211
1212
1213/**
1214 @brief Add Base64-encoded text to encoded output.
1215
1216 @param[in] pCtx The encoding context to add the base-64 text to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001217 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001218 @param[in] B64Text Pointer and length of the base-64 encoded text.
1219
1220 The text content is Base64 encoded data per [RFC 4648]
1221 (https://tools.ietf.org/html/rfc4648).
1222
1223 It is output as CBOR major type 3, a text string, with tag @ref
1224 CBOR_TAG_B64 indicating the text string is Base64 encoded.
1225 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001226static void QCBOREncode_AddTB64Text(QCBOREncodeContext *pCtx,
1227 uint8_t uTagRequirement,
1228 UsefulBufC B64Text);
1229
1230static void QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pCtx,
1231 const char *szLabel,
1232 uint8_t uTagRequirement,
1233 UsefulBufC B64Text);
1234
1235static void QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pCtx,
1236 int64_t nLabel,
1237 uint8_t uTagRequirement,
1238 UsefulBufC B64Text);
1239
1240
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001241static void QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx,
1242 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001243
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001244static void QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx,
1245 const char *szLabel,
1246 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001247
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001248static void QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx,
1249 int64_t nLabel,
1250 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001251
1252
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001253
Michael Eckel5c531332020-03-02 01:35:30 +01001254/**
1255 @brief Add base64url encoded data to encoded output.
1256
1257 @param[in] pCtx The encoding context to add the base64url to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001258 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001259 @param[in] B64Text Pointer and length of the base64url encoded text.
1260
1261 The text content is base64URL encoded text as per [RFC 4648]
1262 (https://tools.ietf.org/html/rfc4648).
1263
1264 It is output as CBOR major type 3, a text string, with tag @ref
1265 CBOR_TAG_B64URL indicating the text string is a Base64url encoded.
1266 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001267static void QCBOREncode_AddTB64URLText(QCBOREncodeContext *pCtx,
1268 uint8_t uTagRequirement,
1269 UsefulBufC B64Text);
1270
1271static void QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pCtx,
1272 const char *szLabel,
1273 uint8_t uTagRequirement,
1274 UsefulBufC B64Text);
1275
1276static void QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pCtx,
1277 int64_t nLabel,
1278 uint8_t uTagRequirement,
1279 UsefulBufC B64Text);
1280
1281
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001282static void QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx,
1283 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001284
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001285static void QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx,
1286 const char *szLabel,
1287 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001288
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001289static void QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx,
1290 int64_t nLabel,
1291 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001292
1293
1294/**
1295 @brief Add Perl Compatible Regular Expression.
1296
1297 @param[in] pCtx The encoding context to add the regular expression to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001298 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001299 @param[in] Regex Pointer and length of the regular expression.
1300
1301 The text content is Perl Compatible Regular
1302 Expressions (PCRE) / JavaScript syntax [ECMA262].
1303
1304 It is output as CBOR major type 3, a text string, with tag @ref
1305 CBOR_TAG_REGEX indicating the text string is a regular expression.
1306 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001307static void QCBOREncode_AddTRegex(QCBOREncodeContext *pCtx,
1308 uint8_t uTagRequirement,
1309 UsefulBufC Regex);
1310
1311static void QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pCtx,
1312 const char *szLabel,
1313 uint8_t uTagRequirement,
1314 UsefulBufC Regex);
1315
1316static void QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pCtx,
1317 int64_t nLabel,
1318 uint8_t uTagRequirement,
1319 UsefulBufC Regex);
1320
1321
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001322static void QCBOREncode_AddRegex(QCBOREncodeContext *pCtx,
1323 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001324
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001325static void QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx,
1326 const char *szLabel,
1327 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001328
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001329static void QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx,
1330 int64_t nLabel,
1331 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001332
1333
1334/**
Laurence Lundblade4982f412020-09-18 23:02:18 -07001335 @brief MIME encoded data to the encoded output.
Michael Eckel5c531332020-03-02 01:35:30 +01001336
Laurence Lundblade4982f412020-09-18 23:02:18 -07001337 @param[in] pCtx The encoding context to add the MIME data to.
1338 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1339 @ref QCBOR_ENCODE_AS_BORROWED.
1340 @param[in] MIMEData Pointer and length of the MIME data.
Michael Eckel5c531332020-03-02 01:35:30 +01001341
1342 The text content is in MIME format per [RFC 2045]
Laurence Lundblade4982f412020-09-18 23:02:18 -07001343 (https://tools.ietf.org/html/rfc2045) including the headers.
Michael Eckel5c531332020-03-02 01:35:30 +01001344
Laurence Lundblade4982f412020-09-18 23:02:18 -07001345 It is output as CBOR major type 2, a binary string, with tag @ref
1346 CBOR_TAG_BINARY_MIME indicating the string is MIME data. This
1347 outputs tag 257, not tag 36, as it can carry any type of MIME binary,
1348 7-bit, 8-bit, quoted-printable and base64 where tag 36 cannot.
1349
1350 Previous versions of QCBOR, those before spiffy decode, output tag
1351 36. Decoding supports both tag 36 and 257. (if the old behavior with
1352 tag 36 is needed, copy the inline functions below and change the tag
1353 number).
1354
1355 See also QCBORDecode_GetMIMEMessage() and
1356 @ref QCBOR_TYPE_BINARY_MIME.
Laurence Lundbladeadaf5c22020-09-25 10:37:09 -07001357
1358 This does no translation of line endings. See QCBOREncode_AddText()
1359 for a discussion of line endings in CBOR.
Michael Eckel5c531332020-03-02 01:35:30 +01001360 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001361static void QCBOREncode_AddTMIMEData(QCBOREncodeContext *pCtx,
1362 uint8_t uTagRequirement,
1363 UsefulBufC MIMEData);
1364
1365static void QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pCtx,
1366 const char *szLabel,
1367 uint8_t uTagRequirement,
1368 UsefulBufC MIMEData);
1369
1370static void QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pCtx,
1371 int64_t nLabel,
1372 uint8_t uTagRequirement,
1373 UsefulBufC MIMEData);
1374
1375
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001376static void QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx,
1377 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001378
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001379static void QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx,
1380 const char *szLabel,
1381 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001382
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001383static void QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx,
1384 int64_t nLabel,
1385 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001386
1387
1388/**
1389 @brief Add an RFC 3339 date string
1390
1391 @param[in] pCtx The encoding context to add the date to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001392 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001393 @param[in] szDate Null-terminated string with date to add.
1394
1395 The string szDate should be in the form of [RFC 3339]
1396 (https://tools.ietf.org/html/rfc3339) as defined by section 3.3 in
1397 [RFC 4287] (https://tools.ietf.org/html/rfc4287). This is as
Laurence Lundbladec02e13e2020-12-06 05:45:41 -08001398 described in section 3.4.1 in [RFC 8949]
1399 (https://tools.ietf.org/html/rfc8949).
Michael Eckel5c531332020-03-02 01:35:30 +01001400
1401 Note that this function doesn't validate the format of the date string
1402 at all. If you add an incorrect format date string, the generated
1403 CBOR will be incorrect and the receiver may not be able to handle it.
1404
1405 Error handling is the same as QCBOREncode_AddInt64().
1406 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001407static void QCBOREncode_AddTDateString(QCBOREncodeContext *pCtx,
1408 uint8_t uTagRequirement,
1409 const char *szDate);
1410
1411static void QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pCtx,
1412 const char *szLabel,
1413 uint8_t uTagRequirement,
1414 const char *szDate);
1415
1416static void QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pCtx,
1417 int64_t nLabel,
1418 uint8_t uTagRequirement,
1419 const char *szDate);
1420
1421
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001422static void QCBOREncode_AddDateString(QCBOREncodeContext *pCtx,
1423 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001424
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001425static void QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx,
1426 const char *szLabel,
1427 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001428
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001429static void QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx,
1430 int64_t nLabel,
1431 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001432
Michael Eckel5c531332020-03-02 01:35:30 +01001433/**
1434 @brief Add a standard Boolean.
1435
1436 @param[in] pCtx The encoding context to add the Boolean to.
1437 @param[in] b true or false from @c <stdbool.h>.
1438
1439 Adds a Boolean value as CBOR major type 7.
1440
1441 Error handling is the same as QCBOREncode_AddInt64().
1442 */
1443static void QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b);
1444
1445static void QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b);
1446
1447static void QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b);
1448
1449
1450
1451/**
1452 @brief Add a NULL to the encoded output.
1453
1454 @param[in] pCtx The encoding context to add the NULL to.
1455
1456 Adds the NULL value as CBOR major type 7.
1457
1458 This NULL doesn't have any special meaning in CBOR such as a
1459 terminating value for a string or an empty value.
1460
1461 Error handling is the same as QCBOREncode_AddInt64().
1462 */
1463static void QCBOREncode_AddNULL(QCBOREncodeContext *pCtx);
1464
1465static void QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1466
1467static void QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1468
1469
1470/**
1471 @brief Add an "undef" to the encoded output.
1472
1473 @param[in] pCtx The encoding context to add the "undef" to.
1474
1475 Adds the undef value as CBOR major type 7.
1476
1477 Note that this value will not translate to JSON.
1478
1479 This Undef doesn't have any special meaning in CBOR such as a
1480 terminating value for a string or an empty value.
1481
1482 Error handling is the same as QCBOREncode_AddInt64().
1483 */
1484static void QCBOREncode_AddUndef(QCBOREncodeContext *pCtx);
1485
1486static void QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1487
1488static void QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1489
1490
1491/**
1492 @brief Indicates that the next items added are in an array.
1493
1494 @param[in] pCtx The encoding context to open the array in.
1495
1496 Arrays are the basic CBOR aggregate or structure type. Call this
1497 function to start or open an array. Then call the various @c
1498 QCBOREncode_AddXxx() functions to add the items that go into the
1499 array. Then call QCBOREncode_CloseArray() when all items have been
1500 added. The data items in the array can be of any type and can be of
1501 mixed types.
1502
1503 Nesting of arrays and maps is allowed and supported just by calling
1504 QCBOREncode_OpenArray() again before calling
1505 QCBOREncode_CloseArray(). While CBOR has no limit on nesting, this
1506 implementation does in order to keep it smaller and simpler. The
1507 limit is @ref QCBOR_MAX_ARRAY_NESTING. This is the max number of
1508 times this can be called without calling
1509 QCBOREncode_CloseArray(). QCBOREncode_Finish() will return @ref
1510 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP when it is called as this function
1511 just sets an error state and returns no value when this occurs.
1512
1513 If you try to add more than @ref QCBOR_MAX_ITEMS_IN_ARRAY items to a
1514 single array or map, @ref QCBOR_ERR_ARRAY_TOO_LONG will be returned
1515 when QCBOREncode_Finish() is called.
1516
1517 An array itself must have a label if it is being added to a map.
1518 Note that array elements do not have labels (but map elements do).
1519
1520 An array itself may be tagged by calling QCBOREncode_AddTag() before this call.
1521 */
1522static void QCBOREncode_OpenArray(QCBOREncodeContext *pCtx);
1523
1524static void QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1525
1526static void QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1527
1528
1529/**
1530 @brief Close an open array.
1531
1532 @param[in] pCtx The encoding context to close the array in.
1533
1534 The closes an array opened by QCBOREncode_OpenArray(). It reduces
1535 nesting level by one. All arrays (and maps) must be closed before
1536 calling QCBOREncode_Finish().
1537
1538 When an error occurs as a result of this call, the encoder records
1539 the error and enters the error state. The error will be returned when
1540 QCBOREncode_Finish() is called.
1541
1542 If this has been called more times than QCBOREncode_OpenArray(), then
1543 @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when QCBOREncode_Finish()
1544 is called.
1545
1546 If this is called and it is not an array that is currently open, @ref
1547 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
1548 is called.
1549 */
1550static void QCBOREncode_CloseArray(QCBOREncodeContext *pCtx);
1551
1552
1553/**
1554 @brief Indicates that the next items added are in a map.
1555
1556 @param[in] pCtx The encoding context to open the map in.
1557
1558 See QCBOREncode_OpenArray() for more information, particularly error
1559 handling.
1560
1561 CBOR maps are an aggregate type where each item in the map consists
1562 of a label and a value. They are similar to JSON objects.
1563
1564 The value can be any CBOR type including another map.
1565
1566 The label can also be any CBOR type, but in practice they are
1567 typically, integers as this gives the most compact output. They might
1568 also be text strings which gives readability and translation to JSON.
1569
1570 Every @c QCBOREncode_AddXxx() call has one version that ends with @c
1571 InMap for adding items to maps with string labels and one that ends
1572 with @c InMapN that is for adding with integer labels.
1573
Laurence Lundbladec02e13e2020-12-06 05:45:41 -08001574 RFC 8949 uses the term "key" instead of "label".
Michael Eckel5c531332020-03-02 01:35:30 +01001575
1576 If you wish to use map labels that are neither integer labels nor
1577 text strings, then just call the QCBOREncode_AddXxx() function
1578 explicitly to add the label. Then call it again to add the value.
1579
Laurence Lundbladec02e13e2020-12-06 05:45:41 -08001580 See the [RFC 8949] (https://tools.ietf.org/html/rfc8949) for a lot
Michael Eckel5c531332020-03-02 01:35:30 +01001581 more information on creating maps.
1582 */
1583static void QCBOREncode_OpenMap(QCBOREncodeContext *pCtx);
1584
1585static void QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1586
1587static void QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1588
1589
Michael Eckel5c531332020-03-02 01:35:30 +01001590/**
1591 @brief Close an open map.
1592
1593 @param[in] pCtx The encoding context to close the map in .
1594
1595 This closes a map opened by QCBOREncode_OpenMap(). It reduces nesting
1596 level by one.
1597
1598 When an error occurs as a result of this call, the encoder records
1599 the error and enters the error state. The error will be returned when
1600 QCBOREncode_Finish() is called.
1601
1602 If this has been called more times than QCBOREncode_OpenMap(),
1603 then @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1604 QCBOREncode_Finish() is called.
1605
1606 If this is called and it is not a map that is currently open, @ref
1607 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
1608 is called.
1609 */
1610static void QCBOREncode_CloseMap(QCBOREncodeContext *pCtx);
1611
1612
1613/**
1614 @brief Indicate start of encoded CBOR to be wrapped in a bstr.
1615
1616 @param[in] pCtx The encoding context to open the bstr-wrapped CBOR in.
1617
1618 All added encoded items between this call and a call to
1619 QCBOREncode_CloseBstrWrap2() will be wrapped in a bstr. They will
1620 appear in the final output as a byte string. That byte string will
1621 contain encoded CBOR. This increases nesting level by one.
1622
1623 The typical use case is for encoded CBOR that is to be
1624 cryptographically hashed, as part of a [RFC 8152, COSE]
Laurence Lundbladec02e13e2020-12-06 05:45:41 -08001625 (https://tools.ietf.org/html/rfc8152) implementation. The
1626 wrapping byte string is taken as input by the hash function
1627 (which is why it is returned by QCBOREncode_CloseBstrWrap2()).
1628 It is also easy to recover on decoding with standard CBOR
1629 decoders.
Michael Eckel5c531332020-03-02 01:35:30 +01001630
1631 Using QCBOREncode_BstrWrap() and QCBOREncode_CloseBstrWrap2() avoids
1632 having to encode the items first in one buffer (e.g., the COSE
1633 payload) and then add that buffer as a bstr to another encoding
1634 (e.g. the COSE to-be-signed bytes, the @c Sig_structure) potentially
1635 halving the memory needed.
1636
Laurence Lundbladec02e13e2020-12-06 05:45:41 -08001637 CBOR by nature must be decoded item by item in order from the start.
1638 By wrapping some CBOR in a byte string, the decoding of that wrapped
1639 CBOR can be skipped. This is another use of wrapping, perhaps
1640 because the CBOR is large and deeply nested. Perhaps APIs for
1641 handling one defined CBOR message that is being embedded in another
1642 only take input as a byte string. Perhaps the desire is to be able
1643 to decode the out layer even in the wrapped has errors.
Michael Eckel5c531332020-03-02 01:35:30 +01001644 */
1645static void QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx);
1646
1647static void QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1648
1649static void QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1650
1651
1652/**
1653 @brief Close a wrapping bstr.
1654
1655 @param[in] pCtx The encoding context to close of bstr wrapping in.
1656 @param[in] bIncludeCBORHead Include the encoded CBOR head of the bstr
1657 as well as the bytes in @c pWrappedCBOR.
1658 @param[out] pWrappedCBOR A @ref UsefulBufC containing wrapped bytes.
1659
1660 The closes a wrapping bstr opened by QCBOREncode_BstrWrap(). It reduces
1661 nesting level by one.
1662
1663 A pointer and length of the enclosed encoded CBOR is returned in @c
1664 *pWrappedCBOR if it is not @c NULL. The main purpose of this is so
1665 this data can be hashed (e.g., with SHA-256) as part of a [RFC 8152,
1666 COSE] (https://tools.ietf.org/html/rfc8152)
1667 implementation. **WARNING**, this pointer and length should be used
1668 right away before any other calls to @c QCBOREncode_CloseXxx() as
1669 they will move data around and the pointer and length will no longer
1670 be to the correct encoded CBOR.
1671
1672 When an error occurs as a result of this call, the encoder records
1673 the error and enters the error state. The error will be returned when
1674 QCBOREncode_Finish() is called.
1675
1676 If this has been called more times than QCBOREncode_BstrWrap(), then
1677 @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1678 QCBOREncode_Finish() is called.
1679
1680 If this is called and it is not a wrapping bstr that is currently
1681 open, @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
1682 QCBOREncode_Finish() is called.
1683
1684 QCBOREncode_CloseBstrWrap() is a deprecated version of this function
1685 that is equivalent to the call with @c bIncludeCBORHead @c true.
1686 */
1687void QCBOREncode_CloseBstrWrap2(QCBOREncodeContext *pCtx, bool bIncludeCBORHead, UsefulBufC *pWrappedCBOR);
1688
1689static void QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR);
1690
1691
1692/**
1693 @brief Add some already-encoded CBOR bytes.
1694
1695 @param[in] pCtx The encoding context to add the already-encode CBOR to.
1696 @param[in] Encoded The already-encoded CBOR to add to the context.
1697
1698 The encoded CBOR being added must be fully conforming CBOR. It must
1699 be complete with no arrays or maps that are incomplete. While this
1700 encoder doesn't ever produce indefinite lengths, it is OK for the
1701 raw CBOR added here to have indefinite lengths.
1702
1703 The raw CBOR added here is not checked in anyway. If it is not
1704 conforming or has open arrays or such, the final encoded CBOR
1705 will probably be wrong or not what was intended.
1706
1707 If the encoded CBOR being added here contains multiple items, they
1708 must be enclosed in a map or array. At the top level the raw
1709 CBOR must be a single data item.
1710 */
1711static void QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded);
1712
1713static void QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded);
1714
1715static void QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded);
1716
1717
1718/**
1719 @brief Get the encoded result.
1720
1721 @param[in] pCtx The context to finish encoding with.
Laurence Lundblade8510f8c2020-12-01 11:31:16 -08001722 @param[out] pEncodedCBOR Structure in which the pointer and length of the encoded
1723 CBOR is returned.
Michael Eckel5c531332020-03-02 01:35:30 +01001724
Laurence Lundbladeb9702452021-03-08 21:02:57 -08001725 @retval QCBOR_SUCCESS Encoded CBOR is returned.
1726
Michael Eckel5c531332020-03-02 01:35:30 +01001727 @retval QCBOR_ERR_TOO_MANY_CLOSES Nesting error
1728
1729 @retval QCBOR_ERR_CLOSE_MISMATCH Nesting error
1730
1731 @retval QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN Nesting error
1732
1733 @retval QCBOR_ERR_BUFFER_TOO_LARGE Encoded output buffer size
1734
1735 @retval QCBOR_ERR_BUFFER_TOO_SMALL Encoded output buffer size
1736
1737 @retval QCBOR_ERR_ARRAY_NESTING_TOO_DEEP Implementation limit
1738
1739 @retval QCBOR_ERR_ARRAY_TOO_LONG Implementation limit
1740
Laurence Lundblade8510f8c2020-12-01 11:31:16 -08001741 On success, the pointer and length of the encoded CBOR are returned
1742 in @c *pEncodedCBOR. The pointer is the same pointer that was passed
1743 in to QCBOREncode_Init(). Note that it is not const when passed to
1744 QCBOREncode_Init(), but it is const when returned here. The length
1745 will be smaller than or equal to the length passed in when
1746 QCBOREncode_Init() as this is the length of the actual result, not
1747 the size of the buffer it was written to.
Michael Eckel5c531332020-03-02 01:35:30 +01001748
Laurence Lundblade8510f8c2020-12-01 11:31:16 -08001749 If a @c NULL was passed for @c Storage.ptr when QCBOREncode_Init()
1750 was called, @c NULL will be returned here, but the length will be
1751 that of the CBOR that would have been encoded.
Michael Eckel5c531332020-03-02 01:35:30 +01001752
1753 Encoding errors primarily manifest here as most other encoding function
1754 do no return an error. They just set the error state in the encode
1755 context after which no encoding function does anything.
1756
1757 Three types of errors manifest here. The first type are nesting
1758 errors where the number of @c QCBOREncode_OpenXxx() calls do not
1759 match the number @c QCBOREncode_CloseXxx() calls. The solution is to
1760 fix the calling code.
1761
1762 The second type of error is because the buffer given is either too
1763 small or too large. The remedy is to give a correctly sized buffer.
1764
1765 The third type are due to limits in this implementation. @ref
1766 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP can be worked around by encoding the
1767 CBOR in two (or more) phases and adding the CBOR from the first phase
1768 to the second with @c QCBOREncode_AddEncoded().
1769
1770 If an error is returned, the buffer may have partially encoded
1771 incorrect CBOR in it and it should not be used. Likewise, the length
1772 may be incorrect and should not be used.
1773
1774 Note that the error could have occurred in one of the many @c
1775 QCBOREncode_AddXxx() calls long before QCBOREncode_Finish() was
1776 called. This error handling reduces the CBOR implementation size but
1777 makes debugging harder.
1778
1779 This may be called multiple times. It will always return the same. It
1780 can also be interleaved with calls to QCBOREncode_FinishGetSize().
1781
1782 QCBOREncode_GetErrorState() can be called to get the current
Laurence Lundblade8510f8c2020-12-01 11:31:16 -08001783 error state in order to abort encoding early as an optimization, but
1784 calling it is is never required.
Michael Eckel5c531332020-03-02 01:35:30 +01001785 */
1786QCBORError QCBOREncode_Finish(QCBOREncodeContext *pCtx, UsefulBufC *pEncodedCBOR);
1787
1788
1789/**
1790 @brief Get the encoded CBOR and error status.
1791
1792 @param[in] pCtx The context to finish encoding with.
1793 @param[out] uEncodedLen The length of the encoded or potentially
1794 encoded CBOR in bytes.
1795
1796 @return The same errors as QCBOREncode_Finish().
1797
1798 This functions the same as QCBOREncode_Finish(), but only returns the
1799 size of the encoded output.
1800 */
1801QCBORError QCBOREncode_FinishGetSize(QCBOREncodeContext *pCtx, size_t *uEncodedLen);
1802
1803
1804/**
1805 @brief Indicate whether output buffer is NULL or not.
1806
1807 @param[in] pCtx The encoding context.
1808
1809 @return 1 if the output buffer is @c NULL.
1810
1811 Sometimes a @c NULL input buffer is given to QCBOREncode_Init() so
1812 that the size of the generated CBOR can be calculated without
1813 allocating a buffer for it. This returns 1 when the output buffer is
1814 NULL and 0 when it is not.
1815*/
1816static int QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx);
1817
Laurence Lundblade825164e2020-10-22 20:18:06 -07001818
1819/**
Michael Eckel5c531332020-03-02 01:35:30 +01001820 @brief Get the encoding error state.
1821
1822 @param[in] pCtx The encoding context.
1823
Laurence Lundbladeabf5c572020-06-29 21:21:29 -07001824 @return One of @ref QCBORError. See return values from
Michael Eckel5c531332020-03-02 01:35:30 +01001825 QCBOREncode_Finish()
1826
1827 Normally encoding errors need only be handled at the end of encoding
1828 when QCBOREncode_Finish() is called. This can be called to get the
1829 error result before finish should there be a need to halt encoding
1830 before QCBOREncode_Finish() is called.
1831*/
1832static QCBORError QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx);
1833
1834
1835/**
1836 Encode the "head" of a CBOR data item.
1837
1838 @param buffer Buffer to output the encoded head to; must be
1839 @ref QCBOR_HEAD_BUFFER_SIZE bytes in size.
1840 @param uMajorType One of CBOR_MAJOR_TYPE_XX.
1841 @param uMinLen The minimum number of bytes to encode uNumber. Almost always
1842 this is 0 to use preferred minimal encoding. If this is 4,
1843 then even the values 0xffff and smaller will be encoded
Laurence Lundblade98427e92020-09-28 21:33:23 -07001844 in 4 bytes. This is used primarily when encoding a
Michael Eckel5c531332020-03-02 01:35:30 +01001845 float or double put into uNumber as the leading zero bytes
1846 for them must be encoded.
1847 @param uNumber The numeric argument part of the CBOR head.
1848 @return Pointer and length of the encoded head or
Laurence Lundblade9a3b6252020-10-21 21:30:31 -07001849 @ref NULLUsefulBufC if the output buffer is too small.
Michael Eckel5c531332020-03-02 01:35:30 +01001850
Laurence Lundblade98427e92020-09-28 21:33:23 -07001851 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 +01001852 take a @ref QCBOREncodeContext argument.
1853
1854 This encodes the major type and argument part of a data item. The
1855 argument is an integer that is usually either the value or the length
1856 of the data item.
1857
1858 This is exposed in the public interface to allow hashing of some CBOR
1859 data types, bstr in particular, a chunk at a time so the full CBOR
1860 doesn't have to be encoded in a contiguous buffer.
1861
1862 For example, if you have a 100,000 byte binary blob in a buffer that
1863 needs to be a bstr encoded and then hashed. You could allocate a
1864 100,010 byte buffer and encode it normally. Alternatively, you can
1865 encode the head in a 10 byte buffer with this function, hash that and
1866 then hash the 100,000 bytes using the same hash context.
1867
1868 See also QCBOREncode_AddBytesLenOnly();
1869 */
1870UsefulBufC QCBOREncode_EncodeHead(UsefulBuf buffer,
1871 uint8_t uMajorType,
1872 uint8_t uMinLen,
1873 uint64_t uNumber);
1874
1875
Michael Eckel5c531332020-03-02 01:35:30 +01001876
1877
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001878/* =========================================================================
1879 BEGINNING OF PRIVATE INLINE IMPLEMENTATION
1880 ========================================================================= */
Michael Eckel5c531332020-03-02 01:35:30 +01001881
1882/**
1883 @brief Semi-private method to add a buffer full of bytes to encoded output
1884
1885 @param[in] pCtx The encoding context to add the integer to.
1886 @param[in] uMajorType The CBOR major type of the bytes.
1887 @param[in] Bytes The bytes to add.
1888
1889 Use QCBOREncode_AddText() or QCBOREncode_AddBytes() or
1890 QCBOREncode_AddEncoded() instead. They are inline functions that call
1891 this and supply the correct major type. This function is public to
1892 make the inline functions work to keep the overall code size down and
1893 because the C language has no way to make it private.
1894
1895 If this is called the major type should be @c
1896 CBOR_MAJOR_TYPE_TEXT_STRING, @c CBOR_MAJOR_TYPE_BYTE_STRING or @c
1897 CBOR_MAJOR_NONE_TYPE_RAW. The last one is special for adding
1898 already-encoded CBOR.
1899 */
1900void QCBOREncode_AddBuffer(QCBOREncodeContext *pCtx, uint8_t uMajorType, UsefulBufC Bytes);
1901
1902
1903/**
1904 @brief Semi-private method to open a map, array or bstr-wrapped CBOR
1905
1906 @param[in] pCtx The context to add to.
1907 @param[in] uMajorType The major CBOR type to close
1908
1909 Call QCBOREncode_OpenArray(), QCBOREncode_OpenMap() or
1910 QCBOREncode_BstrWrap() instead of this.
1911 */
1912void QCBOREncode_OpenMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType);
1913
1914
1915/**
1916 @brief Semi-private method to open a map, array with indefinite length
1917
1918 @param[in] pCtx The context to add to.
1919 @param[in] uMajorType The major CBOR type to close
1920
1921 Call QCBOREncode_OpenArrayIndefiniteLength() or
1922 QCBOREncode_OpenMapIndefiniteLength() instead of this.
1923 */
1924void QCBOREncode_OpenMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx, uint8_t uMajorType);
1925
1926
1927/**
1928 @brief Semi-private method to close a map, array or bstr wrapped CBOR
1929
1930 @param[in] pCtx The context to add to.
1931 @param[in] uMajorType The major CBOR type to close.
1932
1933 Call QCBOREncode_CloseArray() or QCBOREncode_CloseMap() instead of this.
1934 */
1935void QCBOREncode_CloseMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType);
1936
1937
1938/**
1939 @brief Semi-private method to close a map, array with indefinite length
1940
1941 @param[in] pCtx The context to add to.
1942 @param[in] uMajorType The major CBOR type to close.
1943
1944 Call QCBOREncode_CloseArrayIndefiniteLength() or
1945 QCBOREncode_CloseMapIndefiniteLength() instead of this.
1946 */
1947void QCBOREncode_CloseMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx,
1948 uint8_t uMajorType);
1949
1950
1951/**
1952 @brief Semi-private method to add simple types.
1953
1954 @param[in] pCtx The encoding context to add the simple value to.
1955 @param[in] uMinLen Minimum encoding size for uNum. Usually 0.
1956 @param[in] uNum One of CBOR_SIMPLEV_FALSE through _UNDEF or other.
1957
1958 This is used to add simple types like true and false.
1959
1960 Call QCBOREncode_AddBool(), QCBOREncode_AddNULL(),
1961 QCBOREncode_AddUndef() instead of this.
1962
1963 This function can add simple values that are not defined by CBOR
1964 yet. This expansion point in CBOR should not be used unless they are
1965 standardized.
1966
1967 Error handling is the same as QCBOREncode_AddInt64().
1968 */
1969void QCBOREncode_AddType7(QCBOREncodeContext *pCtx, uint8_t uMinLen, uint64_t uNum);
1970
1971
1972/**
1973 @brief Semi-private method to add bigfloats and decimal fractions.
1974
Laurence Lundblade1fa579b2020-11-25 00:31:37 -08001975 @param[in] pCtx The encoding context to add the value to.
1976 @param[in] uTag The type 6 tag indicating what this is to be.
1977 @param[in] BigNumMantissa Is @ref NULLUsefulBufC if mantissa is an
1978 @c int64_t or the actual big number mantissa
1979 if not.
1980 @param[in] bBigNumIsNegative This is @c true if the big number is negative.
1981 @param[in] nMantissa The @c int64_t mantissa if it is not a big number.
1982 @param[in] nExponent The exponent.
Michael Eckel5c531332020-03-02 01:35:30 +01001983
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001984 This outputs either the @ref CBOR_TAG_DECIMAL_FRACTION or @ref
1985 CBOR_TAG_BIGFLOAT tag. if @c uTag is @ref CBOR_TAG_INVALID64, then
1986 this outputs the "borrowed" content format.
Michael Eckel5c531332020-03-02 01:35:30 +01001987
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001988 The tag content output by this is an array with two members, the
1989 exponent and then the mantissa. The mantissa can be either a big
1990 number or an @c int64_t.
1991
1992 This implementation cannot output an exponent further from 0 than
Laurence Lundblade9a3b6252020-10-21 21:30:31 -07001993 @c INT64_MAX.
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001994
Laurence Lundblade1fa579b2020-11-25 00:31:37 -08001995 To output a mantissa that is between INT64_MAX and UINT64_MAX from 0,
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001996 it must be as a big number.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001997
Michael Eckel5c531332020-03-02 01:35:30 +01001998 Typically, QCBOREncode_AddDecimalFraction(), QCBOREncode_AddBigFloat(),
1999 QCBOREncode_AddDecimalFractionBigNum() or QCBOREncode_AddBigFloatBigNum()
2000 is called instead of this.
2001 */
2002void QCBOREncode_AddExponentAndMantissa(QCBOREncodeContext *pCtx,
2003 uint64_t uTag,
2004 UsefulBufC BigNumMantissa,
2005 bool bBigNumIsNegative,
2006 int64_t nMantissa,
2007 int64_t nExponent);
2008
2009/**
2010 @brief Semi-private method to add only the type and length of a byte string.
2011
2012 @param[in] pCtx The context to initialize.
2013 @param[in] Bytes Pointer and length of the input data.
2014
2015 This is the same as QCBOREncode_AddBytes() except it only adds the
2016 CBOR encoding for the type and the length. It doesn't actually add
2017 the bytes. You can't actually produce correct CBOR with this and the
2018 rest of this API. It is only used for a special case where
2019 the valid CBOR is created manually by putting this type and length in
2020 and then adding the actual bytes. In particular, when only a hash of
2021 the encoded CBOR is needed, where the type and header are hashed
2022 separately and then the bytes is hashed. This makes it possible to
2023 implement COSE Sign1 with only one copy of the payload in the output
2024 buffer, rather than two, roughly cutting memory use in half.
2025
2026 This is only used for this odd case, but this is a supported
2027 tested function.
2028
2029 See also QCBOREncode_EncodeHead().
2030*/
2031static inline void QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
2032
2033static inline void QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
2034
2035static inline void QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
2036
2037
2038
2039
2040
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002041static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002042QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pMe, const char *szLabel, int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002043{
2044 // Use _AddBuffer() because _AddSZString() is defined below, not above
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002045 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
2046 QCBOREncode_AddInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002047}
2048
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002049static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002050QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pMe, int64_t nLabel, int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002051{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002052 QCBOREncode_AddInt64(pMe, nLabel);
2053 QCBOREncode_AddInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002054}
2055
2056
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002057static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002058QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pMe, const char *szLabel, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002059{
2060 // Use _AddBuffer() because _AddSZString() is defined below, not above
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002061 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
2062 QCBOREncode_AddUInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002063}
2064
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002065static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002066QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002067{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002068 QCBOREncode_AddInt64(pMe, nLabel);
2069 QCBOREncode_AddUInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002070}
2071
2072
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002073static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002074QCBOREncode_AddText(QCBOREncodeContext *pMe, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002075{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002076 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002077}
2078
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002079static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002080QCBOREncode_AddTextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002081{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002082 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szLabel));
2083 QCBOREncode_AddText(pMe, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002084}
2085
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002086static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002087QCBOREncode_AddTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002088{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002089 QCBOREncode_AddInt64(pMe, nLabel);
2090 QCBOREncode_AddText(pMe, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002091}
2092
2093
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002094inline static void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002095QCBOREncode_AddSZString(QCBOREncodeContext *pMe, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002096{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002097 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szString));
Michael Eckel5c531332020-03-02 01:35:30 +01002098}
2099
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002100static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002101QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pMe, const char *szLabel, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002102{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002103 QCBOREncode_AddSZString(pMe, szLabel);
2104 QCBOREncode_AddSZString(pMe, szString);
Michael Eckel5c531332020-03-02 01:35:30 +01002105}
2106
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002107static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002108QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002109{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002110 QCBOREncode_AddInt64(pMe, nLabel);
2111 QCBOREncode_AddSZString(pMe, szString);
Michael Eckel5c531332020-03-02 01:35:30 +01002112}
2113
2114
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002115static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002116QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pMe, const char *szLabel, double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002117{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002118 QCBOREncode_AddSZString(pMe, szLabel);
2119 QCBOREncode_AddDouble(pMe, dNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002120}
2121
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002122static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002123QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pMe, int64_t nLabel, double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002124{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002125 QCBOREncode_AddInt64(pMe, nLabel);
2126 QCBOREncode_AddDouble(pMe, dNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002127}
2128
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002129static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002130QCBOREncode_AddFloatToMap(QCBOREncodeContext *pMe, const char *szLabel, float dNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002131{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002132 QCBOREncode_AddSZString(pMe, szLabel);
2133 QCBOREncode_AddFloat(pMe, dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002134}
2135
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002136static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002137QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pMe, int64_t nLabel, float fNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002138{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002139 QCBOREncode_AddInt64(pMe, nLabel);
2140 QCBOREncode_AddFloat(pMe, fNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002141}
2142
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002143static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002144QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pMe, const char *szLabel, double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002145{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002146 QCBOREncode_AddSZString(pMe, szLabel);
2147 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002148}
2149
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002150static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002151QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pMe, int64_t nLabel, double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002152{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002153 QCBOREncode_AddInt64(pMe, nLabel);
2154 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002155}
2156
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002157static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002158QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pMe, const char *szLabel, float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002159{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002160 QCBOREncode_AddSZString(pMe, szLabel);
2161 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002162}
2163
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002164static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002165QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pMe, int64_t nLabel, float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002166{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002167 QCBOREncode_AddInt64(pMe, nLabel);
2168 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002169}
2170
Michael Eckel5c531332020-03-02 01:35:30 +01002171
Laurence Lundblade9b334962020-08-27 10:55:53 -07002172
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002173static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002174QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pMe, uint8_t uTag, int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002175{
2176 if(uTag == QCBOR_ENCODE_AS_TAG) {
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002177 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_EPOCH);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002178 }
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002179 QCBOREncode_AddInt64(pMe, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002180}
2181
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002182static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002183QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTag, int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002184{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002185 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002186 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002187}
2188
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002189static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002190QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTag, int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002191{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002192 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002193 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002194}
2195
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002196static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002197QCBOREncode_AddDateEpoch(QCBOREncodeContext *pMe, int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002198{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002199 QCBOREncode_AddTDateEpoch(pMe, QCBOR_ENCODE_AS_TAG, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002200}
2201
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002202static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002203QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pMe, const char *szLabel, int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002204{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002205 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002206 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002207}
2208
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002209static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002210QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pMe, int64_t nLabel, int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002211{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002212 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002213 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002214}
2215
2216
Laurence Lundblade9b334962020-08-27 10:55:53 -07002217
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002218static inline void
2219QCBOREncode_AddBytes(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002220{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002221 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002222}
2223
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002224static inline void
2225QCBOREncode_AddBytesToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002226{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002227 QCBOREncode_AddSZString(pMe, szLabel);
2228 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002229}
2230
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002231static inline void
2232QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002233{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002234 QCBOREncode_AddInt64(pMe, nLabel);
2235 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002236}
2237
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002238static inline void
2239QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002240{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002241 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002242}
2243
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002244static inline void
2245QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002246{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002247 QCBOREncode_AddSZString(pMe, szLabel);
2248 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002249}
2250
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002251static inline void
2252QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002253{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002254 QCBOREncode_AddInt64(pMe, nLabel);
2255 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002256}
2257
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002258
2259static inline void
2260QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002261{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002262 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2263 QCBOREncode_AddTag(pMe, CBOR_TAG_BIN_UUID);
2264 }
2265 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002266}
2267
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002268static inline void
2269QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pMe,
2270 const char *szLabel,
2271 uint8_t uTagRequirement,
2272 UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002273{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002274 QCBOREncode_AddSZString(pMe, szLabel);
2275 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002276}
2277
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002278static inline void
2279QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002280{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002281 QCBOREncode_AddInt64(pMe, nLabel);
2282 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002283}
2284
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002285static inline void
2286QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002287{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002288 QCBOREncode_AddTBinaryUUID(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002289}
2290
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002291static inline void
2292QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002293{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002294 QCBOREncode_AddTBinaryUUIDToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002295}
2296
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002297static inline void
2298QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002299{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002300 QCBOREncode_AddTBinaryUUIDToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002301}
2302
2303
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002304static inline void
2305QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002306{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002307 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2308 QCBOREncode_AddTag(pMe, CBOR_TAG_POS_BIGNUM);
2309 }
2310 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002311}
2312
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002313static inline void
2314QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pMe,
2315 const char *szLabel,
2316 uint8_t uTagRequirement,
2317 UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002318{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002319 QCBOREncode_AddSZString(pMe, szLabel);
2320 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002321}
2322
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002323static inline void
2324QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002325{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002326 QCBOREncode_AddInt64(pMe, nLabel);
2327 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002328}
2329
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002330static inline void
2331QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2332{
2333 QCBOREncode_AddTPositiveBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2334}
2335
2336static inline void
2337QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2338{
2339 QCBOREncode_AddTPositiveBignumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2340}
2341
2342static inline void
2343QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2344{
2345 QCBOREncode_AddTPositiveBignumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2346}
2347
2348
2349static inline void
2350QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
2351{
2352 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2353 QCBOREncode_AddTag(pMe, CBOR_TAG_NEG_BIGNUM);
2354 }
2355 QCBOREncode_AddBytes(pMe, Bytes);
2356}
2357
2358static inline void
2359QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pMe,
2360 const char *szLabel,
2361 uint8_t uTagRequirement,
2362 UsefulBufC Bytes)
2363{
2364 QCBOREncode_AddSZString(pMe, szLabel);
2365 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2366}
2367
2368static inline void
2369QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
2370{
2371 QCBOREncode_AddInt64(pMe, nLabel);
2372 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2373}
2374
2375static inline void
2376QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2377{
2378 QCBOREncode_AddTNegativeBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2379}
2380
2381static inline void
2382QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2383{
2384 QCBOREncode_AddTNegativeBignumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2385}
2386
2387static inline void
2388QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2389{
2390 QCBOREncode_AddTNegativeBignumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2391}
2392
2393
Michael Eckel5c531332020-03-02 01:35:30 +01002394
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07002395#ifndef QCBOR_DISABLE_EXP_AND_MANTISSA
Michael Eckel5c531332020-03-02 01:35:30 +01002396
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002397static inline void
2398QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pMe,
2399 uint8_t uTagRequirement,
2400 int64_t nMantissa,
2401 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002402{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002403 uint64_t uTag;
2404 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2405 uTag = CBOR_TAG_DECIMAL_FRACTION;
2406 } else {
2407 uTag = CBOR_TAG_INVALID64;
2408 }
2409 QCBOREncode_AddExponentAndMantissa(pMe,
2410 uTag,
Michael Eckel5c531332020-03-02 01:35:30 +01002411 NULLUsefulBufC,
2412 false,
2413 nMantissa,
2414 nBase10Exponent);
2415}
2416
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002417static inline void
2418QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pMe,
2419 const char *szLabel,
2420 uint8_t uTagRequirement,
2421 int64_t nMantissa,
2422 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002423{
2424 QCBOREncode_AddSZString(pMe, szLabel);
2425 QCBOREncode_AddTDecimalFraction(pMe, uTagRequirement, nMantissa, nBase10Exponent);
2426}
2427
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002428static inline void
2429QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pMe,
2430 int64_t nLabel,
2431 uint8_t uTagRequirement,
2432 int64_t nMantissa,
2433 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002434{
2435 QCBOREncode_AddInt64(pMe, nLabel);
2436 QCBOREncode_AddTDecimalFraction(pMe, uTagRequirement, nMantissa, nBase10Exponent);
2437}
2438
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002439static inline void
2440QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pMe,
2441 int64_t nMantissa,
2442 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002443{
2444 QCBOREncode_AddTDecimalFraction(pMe, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
2445}
2446
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002447static inline void
2448QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pMe,
2449 const char *szLabel,
2450 int64_t nMantissa,
2451 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002452{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002453 QCBOREncode_AddTDecimalFractionToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002454}
2455
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002456static inline void
2457QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pMe,
2458 int64_t nLabel,
2459 int64_t nMantissa,
2460 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002461{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002462 QCBOREncode_AddTDecimalFractionToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002463}
2464
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002465
2466
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002467static inline void
2468QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pMe,
2469 uint8_t uTagRequirement,
2470 UsefulBufC Mantissa,
2471 bool bIsNegative,
2472 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002473{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002474 uint64_t uTag;
2475 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2476 uTag = CBOR_TAG_DECIMAL_FRACTION;
2477 } else {
2478 uTag = CBOR_TAG_INVALID64;
2479 }
2480 QCBOREncode_AddExponentAndMantissa(pMe,
2481 uTag,
Michael Eckel5c531332020-03-02 01:35:30 +01002482 Mantissa, bIsNegative,
2483 0,
2484 nBase10Exponent);
2485}
2486
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002487static inline void
2488QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
2489 const char *szLabel,
2490 uint8_t uTagRequirement,
2491 UsefulBufC Mantissa,
2492 bool bIsNegative,
2493 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002494{
2495 QCBOREncode_AddSZString(pMe, szLabel);
2496 QCBOREncode_AddTDecimalFractionBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase10Exponent);
2497}
2498
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002499static inline void
2500QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
2501 int64_t nLabel,
2502 uint8_t uTagRequirement,
2503 UsefulBufC Mantissa,
2504 bool bIsNegative,
2505 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002506{
2507 QCBOREncode_AddInt64(pMe, nLabel);
2508 QCBOREncode_AddTDecimalFractionBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase10Exponent);
2509}
2510
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002511static inline void
2512QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pMe,
2513 UsefulBufC Mantissa,
2514 bool bIsNegative,
2515 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002516{
2517 QCBOREncode_AddTDecimalFractionBigNum(pMe, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase10Exponent);
2518}
2519
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002520static inline void
2521QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
2522 const char *szLabel,
2523 UsefulBufC Mantissa,
2524 bool bIsNegative,
2525 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002526{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002527 QCBOREncode_AddTDecimalFractionBigNumToMapSZ(pMe,
2528 szLabel,
2529 QCBOR_ENCODE_AS_TAG,
2530 Mantissa,
2531 bIsNegative,
2532 nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002533}
2534
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002535static inline void
2536QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
2537 int64_t nLabel,
2538 UsefulBufC Mantissa,
2539 bool bIsNegative,
2540 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002541{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002542 QCBOREncode_AddTDecimalFractionBigNumToMapN(pMe,
2543 nLabel,
2544 QCBOR_ENCODE_AS_TAG,
2545 Mantissa,
2546 bIsNegative,
2547 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002548}
2549
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002550
2551
2552
2553
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002554static inline void
2555QCBOREncode_AddTBigFloat(QCBOREncodeContext *pMe,
2556 uint8_t uTagRequirement,
2557 int64_t nMantissa,
2558 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002559{
2560 uint64_t uTag;
2561 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2562 uTag = CBOR_TAG_BIGFLOAT;
2563 } else {
2564 uTag = CBOR_TAG_INVALID64;
2565 }
2566 QCBOREncode_AddExponentAndMantissa(pMe, uTag, NULLUsefulBufC, false, nMantissa, nBase2Exponent);
2567}
2568
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002569static inline void
2570QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pMe,
2571 const char *szLabel,
2572 uint8_t uTagRequirement,
2573 int64_t nMantissa,
2574 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002575{
2576 QCBOREncode_AddSZString(pMe, szLabel);
2577 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
2578}
2579
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002580static inline void
2581QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pMe,
2582 int64_t nLabel,
2583 uint8_t uTagRequirement,
2584 int64_t nMantissa,
2585 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002586{
2587 QCBOREncode_AddInt64(pMe, nLabel);
2588 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
2589}
2590
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002591static inline void
2592QCBOREncode_AddBigFloat(QCBOREncodeContext *pMe,
2593 int64_t nMantissa,
2594 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002595{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002596 QCBOREncode_AddTBigFloat(pMe, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002597}
2598
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002599static inline void
2600QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pMe,
2601 const char *szLabel,
2602 int64_t nMantissa,
2603 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002604{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002605 QCBOREncode_AddTBigFloatToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002606}
2607
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002608static inline void
2609QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pMe,
2610 int64_t nLabel,
2611 int64_t nMantissa,
2612 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002613{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002614 QCBOREncode_AddTBigFloatToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002615}
2616
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002617
2618
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002619static inline void
2620QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pMe,
2621 uint8_t uTagRequirement,
2622 UsefulBufC Mantissa,
2623 bool bIsNegative,
2624 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002625{
2626 uint64_t uTag;
2627 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2628 uTag = CBOR_TAG_BIGFLOAT;
2629 } else {
2630 uTag = CBOR_TAG_INVALID64;
2631 }
2632 QCBOREncode_AddExponentAndMantissa(pMe, uTag, Mantissa, bIsNegative, 0, nBase2Exponent);
2633}
2634
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002635static inline void
2636QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pMe,
2637 const char *szLabel,
2638 uint8_t uTagRequirement,
2639 UsefulBufC Mantissa,
2640 bool bIsNegative,
2641 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002642{
2643 QCBOREncode_AddSZString(pMe, szLabel);
2644 QCBOREncode_AddTBigFloatBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase2Exponent);
2645}
2646
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002647static inline void
2648QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
2649 int64_t nLabel,
2650 uint8_t uTagRequirement,
2651 UsefulBufC Mantissa,
2652 bool bIsNegative,
2653 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002654{
2655 QCBOREncode_AddInt64(pMe, nLabel);
2656 QCBOREncode_AddTBigFloatBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase2Exponent);
2657}
2658
2659
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002660static inline void
2661QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pMe,
2662 UsefulBufC Mantissa,
2663 bool bIsNegative,
2664 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002665{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002666 QCBOREncode_AddTBigFloatBigNum(pMe, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002667}
2668
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002669static inline void
2670QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pMe,
2671 const char *szLabel,
2672 UsefulBufC Mantissa,
2673 bool bIsNegative,
2674 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002675{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002676 QCBOREncode_AddTBigFloatBigNumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002677}
2678
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002679static inline void
2680QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
2681 int64_t nLabel,
2682 UsefulBufC Mantissa,
2683 bool bIsNegative,
2684 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002685{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002686 QCBOREncode_AddTBigFloatBigNumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002687}
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07002688#endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
Michael Eckel5c531332020-03-02 01:35:30 +01002689
2690
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002691static inline void
2692QCBOREncode_AddTURI(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002693{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002694 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2695 QCBOREncode_AddTag(pMe, CBOR_TAG_URI);
2696 }
2697 QCBOREncode_AddText(pMe, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002698}
2699
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002700static inline void
2701QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002702{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002703 QCBOREncode_AddSZString(pMe, szLabel);
2704 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002705}
2706
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002707static inline void
2708QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002709{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002710 QCBOREncode_AddInt64(pMe, nLabel);
2711 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
2712}
2713
2714static inline void
2715QCBOREncode_AddURI(QCBOREncodeContext *pMe, UsefulBufC URI)
2716{
2717 QCBOREncode_AddTURI(pMe, QCBOR_ENCODE_AS_TAG, URI);
2718}
2719
2720static inline void
2721QCBOREncode_AddURIToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC URI)
2722{
2723 QCBOREncode_AddTURIToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, URI);
2724}
2725
2726static inline void
2727QCBOREncode_AddURIToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC URI)
2728{
2729 QCBOREncode_AddTURIToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002730}
2731
2732
2733
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002734static inline void
2735QCBOREncode_AddTB64Text(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002736{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002737 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2738 QCBOREncode_AddTag(pMe, CBOR_TAG_B64);
2739 }
2740 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002741}
2742
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002743static inline void
2744QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pMe,
2745 const char *szLabel,
2746 uint8_t uTagRequirement,
2747 UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002748{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002749 QCBOREncode_AddSZString(pMe, szLabel);
2750 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002751}
2752
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002753static inline void
2754QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002755{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002756 QCBOREncode_AddInt64(pMe, nLabel);
2757 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
2758}
2759
2760static inline void
2761QCBOREncode_AddB64Text(QCBOREncodeContext *pMe, UsefulBufC B64Text)
2762{
2763 QCBOREncode_AddTB64Text(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
2764}
2765
2766static inline void
2767QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC B64Text)
2768{
2769 QCBOREncode_AddTB64TextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
2770}
2771
2772static inline void
2773QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC B64Text)
2774{
2775 QCBOREncode_AddTB64TextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002776}
2777
2778
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002779
2780static inline void
2781QCBOREncode_AddTB64URLText(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002782{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002783 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2784 QCBOREncode_AddTag(pMe, CBOR_TAG_B64URL);
2785 }
2786 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002787}
2788
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002789static inline void
2790QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pMe,
2791 const char *szLabel,
2792 uint8_t uTagRequirement,
2793 UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002794{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002795 QCBOREncode_AddSZString(pMe, szLabel);
2796 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002797}
2798
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002799static inline void
2800QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002801{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002802 QCBOREncode_AddInt64(pMe, nLabel);
2803 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
2804}
2805
2806static inline void
2807QCBOREncode_AddB64URLText(QCBOREncodeContext *pMe, UsefulBufC B64Text)
2808{
2809 QCBOREncode_AddTB64URLText(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
2810}
2811
2812static inline void
2813QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC B64Text)
2814{
2815 QCBOREncode_AddTB64URLTextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
2816}
2817
2818static inline void
2819QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC B64Text)
2820{
2821 QCBOREncode_AddTB64URLTextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002822}
2823
2824
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002825
2826static inline void
2827QCBOREncode_AddTRegex(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002828{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002829 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2830 QCBOREncode_AddTag(pMe, CBOR_TAG_REGEX);
2831 }
2832 QCBOREncode_AddText(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002833}
2834
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002835static inline void
2836QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002837{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002838 QCBOREncode_AddSZString(pMe, szLabel);
2839 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002840}
2841
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002842static inline void
2843QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002844{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002845 QCBOREncode_AddInt64(pMe, nLabel);
2846 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
2847}
2848
2849static inline void
2850QCBOREncode_AddRegex(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2851{
2852 QCBOREncode_AddTRegex(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2853}
2854
2855static inline void
2856QCBOREncode_AddRegexToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2857{
2858 QCBOREncode_AddTRegexToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2859}
2860
2861static inline void
2862QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2863{
2864 QCBOREncode_AddTRegexToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2865
Michael Eckel5c531332020-03-02 01:35:30 +01002866}
2867
2868
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002869static inline void
2870QCBOREncode_AddTMIMEData(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01002871{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002872 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
Laurence Lundblade4982f412020-09-18 23:02:18 -07002873 QCBOREncode_AddTag(pMe, CBOR_TAG_BINARY_MIME);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002874 }
Laurence Lundblade4982f412020-09-18 23:02:18 -07002875 QCBOREncode_AddBytes(pMe, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01002876}
2877
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002878static inline void
2879QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pMe,
2880 const char *szLabel,
2881 uint8_t uTagRequirement,
2882 UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01002883{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002884 QCBOREncode_AddSZString(pMe, szLabel);
2885 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01002886}
2887
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002888static inline void
2889QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01002890{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002891 QCBOREncode_AddInt64(pMe, nLabel);
2892 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
2893}
2894
2895static inline void
2896QCBOREncode_AddMIMEData(QCBOREncodeContext *pMe, UsefulBufC MIMEData)
2897{
2898 QCBOREncode_AddTMIMEData(pMe, QCBOR_ENCODE_AS_TAG, MIMEData);
2899}
2900
2901static inline void
2902QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC MIMEData)
2903{
2904 QCBOREncode_AddTMIMEDataToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
2905}
2906
2907static inline void
2908QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC MIMEData)
2909{
2910 QCBOREncode_AddTMIMEDataToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01002911}
2912
2913
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002914static inline void
2915QCBOREncode_AddTDateString(QCBOREncodeContext *pMe, uint8_t uTagRequirement, const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002916{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002917 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2918 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_STRING);
2919 }
2920 QCBOREncode_AddSZString(pMe, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002921}
2922
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002923static inline void
2924QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pMe,
2925 const char *szLabel,
2926 uint8_t uTagRequirement,
2927 const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002928{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002929 QCBOREncode_AddSZString(pMe, szLabel);
2930 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002931}
2932
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002933static inline void
2934QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002935{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002936 QCBOREncode_AddInt64(pMe, nLabel);
2937 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
2938}
2939
2940static inline void
2941QCBOREncode_AddDateString(QCBOREncodeContext *pMe, const char *szDate)
2942{
2943 QCBOREncode_AddTDateString(pMe, QCBOR_ENCODE_AS_TAG, szDate);
2944}
2945
2946static inline void
2947QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pMe, const char *szLabel, const char *szDate)
2948{
2949 QCBOREncode_AddTDateStringToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, szDate);
2950}
2951
2952static inline void
2953QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, const char *szDate)
2954{
2955 QCBOREncode_AddTDateStringToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002956}
2957
2958
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002959static inline void
2960QCBOREncode_AddSimple(QCBOREncodeContext *pMe, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002961{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002962 QCBOREncode_AddType7(pMe, 0, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002963}
2964
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002965static inline void
2966QCBOREncode_AddSimpleToMap(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01002967{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002968 QCBOREncode_AddSZString(pMe, szLabel);
2969 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01002970}
2971
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002972static inline void
2973QCBOREncode_AddSimpleToMapN(QCBOREncodeContext *pMe, int nLabel, uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01002974{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002975 QCBOREncode_AddInt64(pMe, nLabel);
2976 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01002977}
2978
2979
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002980static inline void
2981QCBOREncode_AddBool(QCBOREncodeContext *pMe, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01002982{
2983 uint8_t uSimple = CBOR_SIMPLEV_FALSE;
2984 if(b) {
2985 uSimple = CBOR_SIMPLEV_TRUE;
2986 }
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002987 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01002988}
2989
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002990static inline void
2991QCBOREncode_AddBoolToMap(QCBOREncodeContext *pMe, const char *szLabel, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01002992{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002993 QCBOREncode_AddSZString(pMe, szLabel);
2994 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01002995}
2996
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002997static inline void
2998QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pMe, int64_t nLabel, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01002999{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003000 QCBOREncode_AddInt64(pMe, nLabel);
3001 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01003002}
3003
3004
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003005static inline void
3006QCBOREncode_AddNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003007{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003008 QCBOREncode_AddSimple(pMe, CBOR_SIMPLEV_NULL);
Michael Eckel5c531332020-03-02 01:35:30 +01003009}
3010
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003011static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003012QCBOREncode_AddNULLToMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003013{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003014 QCBOREncode_AddSZString(pMe, szLabel);
3015 QCBOREncode_AddNULL(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003016}
3017
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003018static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003019QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003020{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003021 QCBOREncode_AddInt64(pMe, nLabel);
3022 QCBOREncode_AddNULL(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003023}
3024
3025
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003026static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003027QCBOREncode_AddUndef(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003028{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003029 QCBOREncode_AddSimple(pMe, CBOR_SIMPLEV_UNDEF);
Michael Eckel5c531332020-03-02 01:35:30 +01003030}
3031
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003032static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003033QCBOREncode_AddUndefToMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003034{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003035 QCBOREncode_AddSZString(pMe, szLabel);
3036 QCBOREncode_AddUndef(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003037}
3038
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003039static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003040QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003041{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003042 QCBOREncode_AddInt64(pMe, nLabel);
3043 QCBOREncode_AddUndef(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003044}
3045
3046
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003047static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003048QCBOREncode_OpenArray(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003049{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003050 QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
Michael Eckel5c531332020-03-02 01:35:30 +01003051}
3052
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003053static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003054QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003055{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003056 QCBOREncode_AddSZString(pMe, szLabel);
3057 QCBOREncode_OpenArray(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003058}
3059
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003060static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003061QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003062{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003063 QCBOREncode_AddInt64(pMe, nLabel);
3064 QCBOREncode_OpenArray(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003065}
3066
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003067static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003068QCBOREncode_CloseArray(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003069{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003070 QCBOREncode_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
Michael Eckel5c531332020-03-02 01:35:30 +01003071}
3072
3073
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003074static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003075QCBOREncode_OpenMap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003076{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003077 QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
Michael Eckel5c531332020-03-02 01:35:30 +01003078}
3079
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003080static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003081QCBOREncode_OpenMapInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003082{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003083 QCBOREncode_AddSZString(pMe, szLabel);
3084 QCBOREncode_OpenMap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003085}
3086
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003087static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003088QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003089{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003090 QCBOREncode_AddInt64(pMe, nLabel);
3091 QCBOREncode_OpenMap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003092}
3093
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003094static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003095QCBOREncode_CloseMap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003096{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003097 QCBOREncode_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
Michael Eckel5c531332020-03-02 01:35:30 +01003098}
3099
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003100static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003101QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003102{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003103 QCBOREncode_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003104}
3105
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003106static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003107QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003108{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003109 QCBOREncode_AddSZString(pMe, szLabel);
3110 QCBOREncode_OpenArrayIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003111}
3112
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003113static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003114QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003115{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003116 QCBOREncode_AddInt64(pMe, nLabel);
3117 QCBOREncode_OpenArrayIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003118}
3119
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003120static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003121QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003122{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003123 QCBOREncode_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003124}
3125
3126
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003127static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003128QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003129{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003130 QCBOREncode_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003131}
3132
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003133static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003134QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003135{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003136 QCBOREncode_AddSZString(pMe, szLabel);
3137 QCBOREncode_OpenMapIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003138}
3139
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003140static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003141QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003142{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003143 QCBOREncode_AddInt64(pMe, nLabel);
3144 QCBOREncode_OpenMapIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003145}
3146
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003147static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003148QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003149{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003150 QCBOREncode_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003151}
3152
3153
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003154static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003155QCBOREncode_BstrWrap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003156{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003157 QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_BYTE_STRING);
Michael Eckel5c531332020-03-02 01:35:30 +01003158}
3159
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003160static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003161QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003162{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003163 QCBOREncode_AddSZString(pMe, szLabel);
3164 QCBOREncode_BstrWrap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003165}
3166
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003167static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003168QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003169{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003170 QCBOREncode_AddInt64(pMe, nLabel);
3171 QCBOREncode_BstrWrap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003172}
3173
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003174static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003175QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pMe, UsefulBufC *pWrappedCBOR)
Michael Eckel5c531332020-03-02 01:35:30 +01003176{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003177 QCBOREncode_CloseBstrWrap2(pMe, true, pWrappedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01003178}
3179
3180
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003181static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003182QCBOREncode_AddEncoded(QCBOREncodeContext *pMe, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003183{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003184 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_RAW, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003185}
3186
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003187static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003188QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003189{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003190 QCBOREncode_AddSZString(pMe, szLabel);
3191 QCBOREncode_AddEncoded(pMe, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003192}
3193
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003194static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003195QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003196{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003197 QCBOREncode_AddInt64(pMe, nLabel);
3198 QCBOREncode_AddEncoded(pMe, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003199}
3200
3201
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003202static inline int
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003203QCBOREncode_IsBufferNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003204{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003205 return UsefulOutBuf_IsBufferNULL(&(pMe->OutBuf));
Michael Eckel5c531332020-03-02 01:35:30 +01003206}
3207
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003208static inline QCBORError
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003209QCBOREncode_GetErrorState(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003210{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003211 if(UsefulOutBuf_GetError(&(pMe->OutBuf))) {
Michael Eckel5c531332020-03-02 01:35:30 +01003212 // Items didn't fit in the buffer.
3213 // This check catches this condition for all the appends and inserts
3214 // so checks aren't needed when the appends and inserts are performed.
3215 // And of course UsefulBuf will never overrun the input buffer given
3216 // to it. No complex analysis of the error handling in this file is
3217 // needed to know that is true. Just read the UsefulBuf code.
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003218 pMe->uError = QCBOR_ERR_BUFFER_TOO_SMALL;
Michael Eckel5c531332020-03-02 01:35:30 +01003219 // QCBOR_ERR_BUFFER_TOO_SMALL masks other errors, but that is
3220 // OK. Once the caller fixes this, they'll be unmasked.
3221 }
3222
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003223 return (QCBORError)pMe->uError;
Michael Eckel5c531332020-03-02 01:35:30 +01003224}
3225
3226
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003227/* ========================================================================
3228 END OF PRIVATE INLINE IMPLEMENTATION
3229 ======================================================================== */
Michael Eckel5c531332020-03-02 01:35:30 +01003230
3231#ifdef __cplusplus
3232}
3233#endif
3234
Laurence Lundblade844bb5c2020-03-01 17:27:25 -08003235#endif /* qcbor_encode_h */