blob: 54a6c87961186d10be2d921633ece1951e792ebb [file] [log] [blame]
Michael Eckel5c531332020-03-02 01:35:30 +01001/*==============================================================================
2 Copyright (c) 2016-2018, The Linux Foundation.
3 Copyright (c) 2018-2020, Laurence Lundblade.
4 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
59 defined in [RFC 7049] (https://tools.ietf.org/html/rfc7049). 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
70 all CBOR can convert to JSON. See RFC 7049 for more info on how to
71 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
232 @anchor Tags-Overview
Laurence Lundblade9b334962020-08-27 10:55:53 -0700233
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700234 ## Tags Overview
235
236 Any CBOR data item can be made into a tag to add semantics, define a
237 new data type or such. Some tags are fully standardized and some are
238 just registered. Others are not registered and used in a proprietary
239 way.
Michael Eckel5c531332020-03-02 01:35:30 +0100240
241 Encoding and decoding of many of the registered tags is fully
242 implemented by QCBOR. It is also possible to encode and decode tags
243 that are not directly supported. For many use cases the built-in tag
244 support should be adequate.
245
246 For example, the registered epoch date tag is supported in encoding
247 by QCBOREncode_AddDateEpoch() and in decoding by @ref
248 QCBOR_TYPE_DATE_EPOCH and the @c epochDate member of @ref
249 QCBORItem. This is typical of the built-in tag support. There is an
250 API to encode data for it and a @c QCBOR_TYPE_XXX when it is decoded.
251
252 Tags are registered in the [IANA CBOR Tags Registry]
253 (https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml). There
254 are roughly three options to create a new tag. First, a public
255 specification can be created and the new tag registered with IANA.
256 This is the most formal. Second, the new tag can be registered with
257 IANA with just a short description rather than a full specification.
258 These tags must be greater than 256. Third, a tag can be used without
259 any IANA registration, though the registry should be checked to see
260 that the new value doesn't collide with one that is registered. The
261 value of these tags must be 256 or larger.
262
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700263 See also @ref CBORTags and @ref Tag-Usage
264
Michael Eckel5c531332020-03-02 01:35:30 +0100265 The encoding side of tags not built-in is handled by
266 QCBOREncode_AddTag() and is relatively simple. Tag decoding is more
267 complex and mainly handled by QCBORDecode_GetNext(). Decoding of the
268 structure of tagged data not built-in (if there is any) has to be
269 implemented by the caller.
270
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700271 @anchor Floating-Point
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700272
273 ## Floating-Point
274
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700275 By default QCBOR fully supports IEEE 754 floating-point:
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700276 - Encode/decode of double, single and half-precision
277 - CBOR preferred serialization of floating-point
278 - Floating-point epoch dates
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700279
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700280 For the most part, the type double is used in the interface for
281 floating-point values. In the default configuration, all decoded
282 floating-point values are returned as a double.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700283
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700284 With CBOR preferred serialization, the encoder outputs the smallest
285 representation of the double or float that preserves precision. Zero,
286 NaN and infinity are always output as a half-precision, each taking
287 just 2 bytes. This reduces the number of bytes needed to encode
Laurence Lundblade4b270642020-08-14 12:53:07 -0700288 double and single-precision, especially if zero, NaN and infinity are
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700289 frequently used.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700290
Laurence Lundblade4b270642020-08-14 12:53:07 -0700291 To avoid use of preferred serialization in the standard configuration
292 when encoding, use QCBOREncode_AddDoubleNoPreferred() or
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700293 QCBOREncode_AddFloatNoPreferred().
294
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700295 This implementation of preferred floating-point serialization and
296 half-precision does not depend on the CPU having floating-point HW or
297 the compiler bringing in a (sometimes large) library to compensate
Laurence Lundblade4b270642020-08-14 12:53:07 -0700298 for lack of CPU support. This implementation uses shifts and masks
299 rather than floating-point functions.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700300
Laurence Lundblade4b270642020-08-14 12:53:07 -0700301 To reduce overall object code by about 900 bytes, define
302 QCBOR_DISABLE_PREFERRED_FLOAT. This will eliminate all support for
303 preferred serialization and half-precision. An error will be returned
304 when attempting to decode half-precision. A float will always be
305 encoded and decoded as 32-bits and a double will always be encoded
306 and decoded as 64 bits.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700307
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700308 Note that even if QCBOR_DISABLE_PREFERRED_FLOAT is not defined all
309 the float-point encoding object code can be avoided by never calling
Laurence Lundbladefe09bbf2020-07-16 12:14:51 -0700310 any functions that encode double or float. Just not calling
311 floating-point functions will reduce object code by about 500 bytes.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700312
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700313 On CPUs that have no floating-point hardware,
314 QCBOR_DISABLE_FLOAT_HW_USE should be defined in most cases. If it is
315 not, then the compiler will bring in possibly large software
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700316 libraries to compensate. Defining QCBOR_DISABLE_FLOAT_HW_USE reduces
317 object code size on CPUs with floating-point hardware by a tiny
318 amount and eliminates the need for <math.h>
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700319
Laurence Lundblade4b270642020-08-14 12:53:07 -0700320 When QCBOR_DISABLE_FLOAT_HW_USE is defined, trying to decoding
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700321 floating-point dates will give error
322 @ref QCBOR_ERR_FLOAT_DATE_DISABLED and decoded single-precision
323 numbers will be returned as @ref QCBOR_TYPE_FLOAT instead of
324 converting them to double as usual.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700325
326 If both QCBOR_DISABLE_FLOAT_HW_USE and QCBOR_DISABLE_PREFERRED_FLOAT
Laurence Lundblade4b270642020-08-14 12:53:07 -0700327 are defined, then the only thing QCBOR can do is encode/decode a C
328 float type as 32-bits and a C double type as 64-bits. Floating-point
329 epoch dates will be unsupported.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700330
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700331 ## Limitations
332
Michael Eckel5c531332020-03-02 01:35:30 +0100333 Summary Limits of this implementation:
334 - The entire encoded CBOR must fit into contiguous memory.
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700335 - Max size of encoded / decoded CBOR data is a few bytes less than @c UINT32_MAX (4GB).
Michael Eckel5c531332020-03-02 01:35:30 +0100336 - Max array / map nesting level when encoding / decoding is
337 @ref QCBOR_MAX_ARRAY_NESTING (this is typically 15).
338 - Max items in an array or map when encoding / decoding is
339 @ref QCBOR_MAX_ITEMS_IN_ARRAY (typically 65,536).
340 - Does not directly support labels in maps other than text strings & integers.
341 - Does not directly support integer labels greater than @c INT64_MAX.
342 - Epoch dates limited to @c INT64_MAX (+/- 292 billion years).
343 - Exponents for bigfloats and decimal integers are limited to @c INT64_MAX.
344 - Tags on labels are ignored during decoding.
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700345 - The maximum tag nesting is @c QCBOR_MAX_TAGS_PER_ITEM (typically 4).
Michael Eckel5c531332020-03-02 01:35:30 +0100346 - Works only on 32- and 64-bit CPUs (modifications could make it work
347 on 16-bit CPUs).
348
349 The public interface uses @c size_t for all lengths. Internally the
350 implementation uses 32-bit lengths by design to use less memory and
351 fit structures on the stack. This limits the encoded CBOR it can work
352 with to size @c UINT32_MAX (4GB) which should be enough.
353
354 This implementation assumes two's compliment integer machines. @c
355 <stdint.h> also requires this. It is possible to modify this
356 implementation for another integer representation, but all modern
357 machines seem to be two's compliment.
Michael Eckel5c531332020-03-02 01:35:30 +0100358 */
359
360
Michael Eckel5c531332020-03-02 01:35:30 +0100361/*
362 The size of the buffer to be passed to QCBOREncode_EncodeHead(). It is one
363 byte larger than sizeof(uint64_t) + 1, the actual maximum size of the
364 head of a CBOR data item. because QCBOREncode_EncodeHead() needs
365 one extra byte to work.
366 */
367#define QCBOR_HEAD_BUFFER_SIZE (sizeof(uint64_t) + 2)
368
Michael Eckel5c531332020-03-02 01:35:30 +0100369
Laurence Lundblade9b334962020-08-27 10:55:53 -0700370/**
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700371 Output the full CBOR tag. See @ref CBORTags, @ref Tag-Usage and @ref Tags-Overview.
Laurence Lundblade9b334962020-08-27 10:55:53 -0700372 */
373#define QCBOR_ENCODE_AS_TAG 0
374
375/**
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700376 Output only the 'borrowed' content format for the relevant tag.
377 See @ref CBORTags, @ref Tag-Usage and @ref Tags-Overview.
Laurence Lundblade9b334962020-08-27 10:55:53 -0700378 */
379#define QCBOR_ENCODE_AS_BORROWED 1
380
Michael Eckel5c531332020-03-02 01:35:30 +0100381
382/**
383 QCBOREncodeContext is the data type that holds context for all the
384 encoding functions. It is less than 200 bytes, so it can go on the
385 stack. The contents are opaque, and the caller should not access
386 internal members. A context may be re used serially as long as it is
387 re initialized.
388 */
389typedef struct _QCBOREncodeContext QCBOREncodeContext;
390
391
392/**
393 Initialize the encoder to prepare to encode some CBOR.
394
395 @param[in,out] pCtx The encoder context to initialize.
396 @param[in] Storage The buffer into which this encoded result
397 will be placed.
398
399 Call this once at the start of an encoding of a CBOR structure. Then
400 call the various @c QCBOREncode_AddXxx() functions to add the data
401 items. Then call QCBOREncode_Finish().
402
403 The maximum output buffer is @c UINT32_MAX (4GB). This is not a
404 practical limit in any way and reduces the memory needed by the
405 implementation. The error @ref QCBOR_ERR_BUFFER_TOO_LARGE will be
406 returned by QCBOREncode_Finish() if a larger buffer length is passed
407 in.
408
409 If this is called with @c Storage.ptr as @c NULL and @c Storage.len a
410 large value like @c UINT32_MAX, all the QCBOREncode_AddXxx()
411 functions and QCBOREncode_Finish() can still be called. No data will
412 be encoded, but the length of what would be encoded will be
413 calculated. The length of the encoded structure will be handed back
414 in the call to QCBOREncode_Finish(). You can then allocate a buffer
415 of that size and call all the encoding again, this time to fill in
416 the buffer.
417
418 A @ref QCBOREncodeContext can be reused over and over as long as
419 QCBOREncode_Init() is called.
420 */
421void QCBOREncode_Init(QCBOREncodeContext *pCtx, UsefulBuf Storage);
422
423
424/**
425 @brief Add a signed 64-bit integer to the encoded output.
426
427 @param[in] pCtx The encoding context to add the integer to.
428 @param[in] nNum The integer to add.
429
430 The integer will be encoded and added to the CBOR output.
431
432 This function figures out the size and the sign and encodes in the
433 correct minimal CBOR. Specifically, it will select CBOR major type 0
434 or 1 based on sign and will encode to 1, 2, 4 or 8 bytes depending on
435 the value of the integer. Values less than 24 effectively encode to
436 one byte because they are encoded in with the CBOR major type. This
437 is a neat and efficient characteristic of CBOR that can be taken
438 advantage of when designing CBOR-based protocols. If integers like
439 tags can be kept between -23 and 23 they will be encoded in one byte
440 including the major type.
441
442 If you pass a smaller int, say an @c int16_t or a small value, say
443 100, the encoding will still be CBOR's most compact that can
444 represent the value. For example, CBOR always encodes the value 0 as
445 one byte, 0x00. The representation as 0x00 includes identification of
446 the type as an integer too as the major type for an integer is 0. See
447 [RFC 7049] (https://tools.ietf.org/html/rfc7049) Appendix A for more
448 examples of CBOR encoding. This compact encoding is also canonical
449 CBOR as per section 3.9 in RFC 7049.
450
451 There are no functions to add @c int16_t or @c int32_t because they
452 are not necessary because this always encodes to the smallest number
453 of bytes based on the value (If this code is running on a 32-bit
454 machine having a way to add 32-bit integers would reduce code size
455 some).
456
457 If the encoding context is in an error state, this will do
458 nothing. If an error occurs when adding this integer, the internal
459 error flag will be set, and the error will be returned when
460 QCBOREncode_Finish() is called.
461
462 See also QCBOREncode_AddUInt64().
463 */
464void QCBOREncode_AddInt64(QCBOREncodeContext *pCtx, int64_t nNum);
465
466static void QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum);
467
468static void QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum);
469
470
471/**
472 @brief Add an unsigned 64-bit integer to the encoded output.
473
474 @param[in] pCtx The encoding context to add the integer to.
475 @param[in] uNum The integer to add.
476
477 The integer will be encoded and added to the CBOR output.
478
479 The only reason so use this function is for integers larger than @c
480 INT64_MAX and smaller than @c UINT64_MAX. Otherwise
481 QCBOREncode_AddInt64() will work fine.
482
483 Error handling is the same as for QCBOREncode_AddInt64().
484 */
485void QCBOREncode_AddUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
486
487static void QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum);
488
489static void QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum);
490
491
492/**
493 @brief Add a UTF-8 text string to the encoded output.
494
495 @param[in] pCtx The encoding context to add the text to.
496 @param[in] Text Pointer and length of text to add.
497
498 The text passed in must be unencoded UTF-8 according to [RFC 3629]
499 (https://tools.ietf.org/html/rfc3629). There is no NULL
500 termination. The text is added as CBOR major type 3.
501
502 If called with @c nBytesLen equal to 0, an empty string will be
503 added. When @c nBytesLen is 0, @c pBytes may be @c NULL.
504
505 Note that the restriction of the buffer length to a @c uint32_t is
506 entirely intentional as this encoder is not capable of encoding
507 lengths greater. This limit to 4GB for a text string should not be a
508 problem.
509
Laurence Lundbladeadaf5c22020-09-25 10:37:09 -0700510 Text lines in Internet protocols (on the wire) are delimited by
511 either a CRLF or just an LF. Officially many protocols specify CRLF,
512 but implementations often work with either. CBOR type 3 text can be
513 either line ending, even a mixture of both.
514
515 Operating systems usually have a line end convention. Windows uses
516 CRLF. Linux and MacOS use LF. Some applications on a given OS may
517 work with either and some may not.
518
519 The majority of use cases and CBOR protocols using type 3 text will
520 work with either line ending. However, some use cases or protocols
521 may not work with either in which case translation to and/or from the
522 local line end convention, typically that of the OS, is necessary.
523
524 QCBOR does no line ending translation for type 3 text when encoding
525 and decoding.
526
Michael Eckel5c531332020-03-02 01:35:30 +0100527 Error handling is the same as QCBOREncode_AddInt64().
528 */
529static void QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text);
530
531static void QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text);
532
533static void QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text);
534
535
536/**
537 @brief Add a UTF-8 text string to the encoded output.
538
539 @param[in] pCtx The encoding context to add the text to.
540 @param[in] szString Null-terminated text to add.
541
542 This works the same as QCBOREncode_AddText().
543 */
544static void QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString);
545
546static void QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString);
547
548static void QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString);
549
550
551/**
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700552 @brief Add a double-precision floating-point number to the encoded output.
Michael Eckel5c531332020-03-02 01:35:30 +0100553
554 @param[in] pCtx The encoding context to add the double to.
555 @param[in] dNum The double-precision number to add.
556
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700557 This encodes and outputs a floating-point number. CBOR major type 7
558 is used.
Michael Eckel5c531332020-03-02 01:35:30 +0100559
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700560 This implements preferred serialization, selectively encoding the
561 double-precision floating-point number as either double-precision,
562 single-precision or half-precision. Infinity, NaN and 0 are always
563 encoded as half-precision. If no precision will be lost in the
564 conversion to half-precision, then it will be converted and
565 encoded. If not and no precision will be lost in conversion to
566 single-precision, then it will be converted and encoded. If not, then
567 no conversion is performed, and it encoded as a double-precision.
Michael Eckel5c531332020-03-02 01:35:30 +0100568
569 Half-precision floating-point numbers take up 2 bytes, half that of
570 single-precision, one quarter of double-precision
571
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700572 This automatically reduces the size of encoded CBOR, maybe even by
573 four if most of values are 0, infinity or NaN.
Michael Eckel5c531332020-03-02 01:35:30 +0100574
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700575 When decoded, QCBOR will usually return these values as
576 double-precision.
577
578 It is possible to disable this preferred serialization when compiling
579 QCBOR. In that case, this functions the same as
580 QCBOREncode_AddDoubleNoPreferred().
Michael Eckel5c531332020-03-02 01:35:30 +0100581
582 Error handling is the same as QCBOREncode_AddInt64().
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700583
584 See also QCBOREncode_AddDoubleNoPreferred(), QCBOREncode_AddFloat()
585 and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
Michael Eckel5c531332020-03-02 01:35:30 +0100586 */
587void QCBOREncode_AddDouble(QCBOREncodeContext *pCtx, double dNum);
588
589static void QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
590
591static void QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
592
593
594/**
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700595 @brief Add a single-precision floating-point number to the encoded output.
596
597 @param[in] pCtx The encoding context to add the double to.
598 @param[in] fNum The single-precision number to add.
599
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700600 This is identical to QCBOREncode_AddDouble() except the input is
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700601 single-precision.
602
603 See also QCBOREncode_AddDouble(), QCBOREncode_AddDoubleNoPreferred(),
604 and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
605*/
606void QCBOREncode_AddFloat(QCBOREncodeContext *pCtx, float fNum);
607
608static void QCBOREncode_AddFloatToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
609
610static void QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700611
612
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700613/**
614 @brief Add a double-precision floating-point number without preferred encoding.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700615
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700616 @param[in] pCtx The encoding context to add the double to.
617 @param[in] dNum The double-precision number to add.
618
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700619 This always outputs the number as a 64-bit double-precision.
620 Preferred serialization is not used.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700621
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700622 Error handling is the same as QCBOREncode_AddInt64().
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700623
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700624 See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
625 QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700626*/
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700627void QCBOREncode_AddDoubleNoPreferred(QCBOREncodeContext *pCtx, double dNum);
628
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700629static void QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
630
631static void QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
632
633
634/**
635 @brief Add a single-precision floating-point number without preferred encoding.
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 always outputs the number as a 32-bit single-precision.
641 Preferred serialization is not used.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700642
643 Error handling is the same as QCBOREncode_AddInt64().
644
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700645 See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
646 QCBOREncode_AddDoubleNoPreferred() and @ref Floating-Point.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700647*/
648void QCBOREncode_AddFloatNoPreferred(QCBOREncodeContext *pCtx, float fNum);
649
650static void QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
651
652static void QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float fNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700653
654
Michael Eckel5c531332020-03-02 01:35:30 +0100655
656/**
657 @brief Add an optional tag.
658
659 @param[in] pCtx The encoding context to add the tag to.
660 @param[in] uTag The tag to add
661
662 This outputs a CBOR major type 6 item that tags the next data item
663 that is output usually to indicate it is some new data type.
664
665 For many of the common standard tags, a function to encode data using
666 it is provided and this is not needed. For example,
667 QCBOREncode_AddDateEpoch() already exists to output integers
668 representing dates with the right tag.
669
670 The tag is applied to the next data item added to the encoded
671 output. That data item that is to be tagged can be of any major CBOR
672 type. Any number of tags can be added to a data item by calling this
673 multiple times before the data item is added.
674
675 See @ref Tags-Overview for discussion of creating new non-standard
676 tags. See QCBORDecode_GetNext() for discussion of decoding custom
677 tags.
678*/
Laurence Lundblade6416a0f2020-09-19 23:26:34 -0700679void QCBOREncode_AddTag(QCBOREncodeContext *pCtx, uint64_t uTag);
Michael Eckel5c531332020-03-02 01:35:30 +0100680
681
682/**
683 @brief Add an epoch-based date.
684
685 @param[in] pCtx The encoding context to add the date to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700686 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700687 @param[in] nDate Number of seconds since 1970-01-01T00:00Z in UTC time.
Michael Eckel5c531332020-03-02 01:35:30 +0100688
689 As per RFC 7049 this is similar to UNIX/Linux/POSIX dates. This is
690 the most compact way to specify a date and time in CBOR. Note that
691 this is always UTC and does not include the time zone. Use
692 QCBOREncode_AddDateString() if you want to include the time zone.
693
694 The integer encoding rules apply here so the date will be encoded in
695 a minimal number of bytes. Until about the year 2106 these dates will
696 encode in 6 bytes -- one byte for the tag, one byte for the type and
697 4 bytes for the integer. After that it will encode to 10 bytes.
698
699 Negative values are supported for dates before 1970.
700
701 If you care about leap-seconds and that level of accuracy, make sure
702 the system you are running this code on does it correctly. This code
703 just takes the value passed in.
704
705 This implementation cannot encode fractional seconds using float or
706 double even though that is allowed by CBOR, but you can encode them
707 if you want to by calling QCBOREncode_AddDouble() and
708 QCBOREncode_AddTag().
709
710 Error handling is the same as QCBOREncode_AddInt64().
711 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700712static void QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pCtx,
713 uint8_t uTagRequirement,
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700714 int64_t nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -0700715
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700716static void QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pCtx,
717 const char *szLabel,
718 uint8_t uTagRequirement,
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700719 int64_t nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -0700720
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700721static void QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pCtx,
722 int64_t nLabel,
723 uint8_t uTagRequirement,
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700724 int64_t nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -0700725
726
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700727static void QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx,
728 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100729
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700730static void QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx,
731 const char *szLabel,
732 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100733
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700734static void QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx,
735 int64_t nLabel,
736 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100737
738
739/**
740 @brief Add a byte string to the encoded output.
741
742 @param[in] pCtx The encoding context to add the bytes to.
743 @param[in] Bytes Pointer and length of the input data.
744
745 Simply adds the bytes to the encoded output as CBOR major type 2.
746
747 If called with @c Bytes.len equal to 0, an empty string will be
748 added. When @c Bytes.len is 0, @c Bytes.ptr may be @c NULL.
749
750 Error handling is the same as QCBOREncode_AddInt64().
751 */
752static void QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
753
754static void QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
755
756static void QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
757
758
759
760/**
761 @brief Add a binary UUID to the encoded output.
762
763 @param[in] pCtx The encoding context to add the UUID to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700764 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100765 @param[in] Bytes Pointer and length of the binary UUID.
766
767 A binary UUID as defined in [RFC 4122]
768 (https://tools.ietf.org/html/rfc4122) is added to the output.
769
770 It is output as CBOR major type 2, a binary string, with tag @ref
771 CBOR_TAG_BIN_UUID indicating the binary string is a UUID.
772 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700773static void QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pCtx,
774 uint8_t uTagRequirement,
775 UsefulBufC Bytes);
776
777static void QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pCtx,
778 const char *szLabel,
779 uint8_t uTagRequirement,
780 UsefulBufC Bytes);
781
782static void QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pCtx,
783 int64_t nLabel,
784 uint8_t uTagRequirement,
785 UsefulBufC Bytes);
786
787
Michael Eckel5c531332020-03-02 01:35:30 +0100788static void QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
789
790static void QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
791
792static void QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
793
794
795/**
796 @brief Add a positive big number to the encoded output.
797
798 @param[in] pCtx The encoding context to add the big number to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700799 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100800 @param[in] Bytes Pointer and length of the big number.
801
802 Big numbers are integers larger than 64-bits. Their format is
803 described in [RFC 7049] (https://tools.ietf.org/html/rfc7049).
804
805 It is output as CBOR major type 2, a binary string, with tag @ref
806 CBOR_TAG_POS_BIGNUM indicating the binary string is a positive big
807 number.
808
809 Often big numbers are used to represent cryptographic keys, however,
810 COSE which defines representations for keys chose not to use this
811 particular type.
812 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700813static void QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pCtx,
814 uint8_t uTagRequirement,
815 UsefulBufC Bytes);
816
817static void QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pCtx,
818 const char *szLabel,
819 uint8_t uTagRequirement,
820 UsefulBufC Bytes);
821
822static void QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pCtx,
823 int64_t nLabel,
824 uint8_t uTagRequirement,
825 UsefulBufC Bytes);
826
827
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700828static void QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx,
829 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100830
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700831static void QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx,
832 const char *szLabel,
833 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100834
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700835static void QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx,
836 int64_t nLabel,
837 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100838
839
840/**
841 @brief Add a negative big number to the encoded output.
842
843 @param[in] pCtx The encoding context to add the big number to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700844 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100845 @param[in] Bytes Pointer and length of the big number.
846
847 Big numbers are integers larger than 64-bits. Their format is
848 described in [RFC 7049] (https://tools.ietf.org/html/rfc7049).
849
850 It is output as CBOR major type 2, a binary string, with tag @ref
851 CBOR_TAG_NEG_BIGNUM indicating the binary string is a negative big
852 number.
853
854 Often big numbers are used to represent cryptographic keys, however,
855 COSE which defines representations for keys chose not to use this
856 particular type.
857 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700858static void QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pCtx,
859 uint8_t uTagRequirement,
860 UsefulBufC Bytes);
861
862static void QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pCtx,
863 const char *szLabel,
864 uint8_t uTagRequirement,
865 UsefulBufC Bytes);
866
867static void QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pCtx,
868 int64_t nLabel,
869 uint8_t uTagRequirement,
870 UsefulBufC Bytes);
871
872
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700873static void QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx,
874 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100875
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700876static void QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx,
877 const char *szLabel,
878 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100879
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700880static void QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx,
881 int64_t nLabel,
882 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100883
884
885#ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
886/**
887 @brief Add a decimal fraction to the encoded output.
888
889 @param[in] pCtx The encoding context to add the decimal fraction to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700890 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100891 @param[in] nMantissa The mantissa.
892 @param[in] nBase10Exponent The exponent.
893
894 The value is nMantissa * 10 ^ nBase10Exponent.
895
896 A decimal fraction is good for exact representation of some values
897 that can't be represented exactly with standard C (IEEE 754)
898 floating-point numbers. Much larger and much smaller numbers can
899 also be represented than floating-point because of the larger number
900 of bits in the exponent.
901
902 The decimal fraction is conveyed as two integers, a mantissa and a
903 base-10 scaling factor.
904
905 For example, 273.15 is represented by the two integers 27315 and -2.
906
907 The exponent and mantissa have the range from @c INT64_MIN to
908 @c INT64_MAX for both encoding and decoding (CBOR allows @c -UINT64_MAX
909 to @c UINT64_MAX, but this implementation doesn't support this range to
910 reduce code size and interface complexity a little).
911
912 CBOR Preferred encoding of the integers is used, thus they will be encoded
913 in the smallest number of bytes possible.
914
915 See also QCBOREncode_AddDecimalFractionBigNum() for a decimal
916 fraction with arbitrarily large precision and QCBOREncode_AddBigFloat().
917
918 There is no representation of positive or negative infinity or NaN
919 (Not a Number). Use QCBOREncode_AddDouble() to encode them.
920
921 See @ref expAndMantissa for decoded representation.
922 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700923static void QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pCtx,
924 uint8_t uTagRequirement,
925 int64_t nMantissa,
926 int64_t nBase10Exponent);
927
928static void QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -0700929 const char *szLabel,
930 uint8_t uTagRequirement,
931 int64_t nMantissa,
932 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700933
934static void QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pCtx,
935 int64_t nLabel,
936 uint8_t uTagRequirement,
937 int64_t nMantissa,
938 int64_t nBase10Exponent);
939
940
Michael Eckel5c531332020-03-02 01:35:30 +0100941static void QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pCtx,
942 int64_t nMantissa,
943 int64_t nBase10Exponent);
944
945static void QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pCtx,
946 const char *szLabel,
947 int64_t nMantissa,
948 int64_t nBase10Exponent);
949
950static void QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pCtx,
951 int64_t nLabel,
952 int64_t nMantissa,
953 int64_t nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +0100954/**
955 @brief Add a decimal fraction with a big number mantissa to the encoded output.
956
957 @param[in] pCtx The encoding context to add the decimal fraction to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700958 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100959 @param[in] Mantissa The mantissa.
960 @param[in] bIsNegative false if mantissa is positive, true if negative.
961 @param[in] nBase10Exponent The exponent.
962
963 This is the same as QCBOREncode_AddDecimalFraction() except the
964 mantissa is a big number (See QCBOREncode_AddPositiveBignum())
965 allowing for arbitrarily large precision.
966
967 See @ref expAndMantissa for decoded representation.
968 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700969static void QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pCtx,
970 uint8_t uTagRequirement,
971 UsefulBufC Mantissa,
972 bool bIsNegative,
973 int64_t nBase10Exponent);
974
975static void QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -0700976 const char *szLabel,
977 uint8_t uTagRequirement,
978 UsefulBufC Mantissa,
979 bool bIsNegative,
980 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700981
982static void QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
983 int64_t nLabel,
984 uint8_t uTagRequirement,
985 UsefulBufC Mantissa,
986 bool bIsNegative,
987 int64_t nBase10Exponent);
988
989
Michael Eckel5c531332020-03-02 01:35:30 +0100990static void QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pCtx,
991 UsefulBufC Mantissa,
992 bool bIsNegative,
993 int64_t nBase10Exponent);
994
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700995static void QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -0700996 const char *szLabel,
997 UsefulBufC Mantissa,
998 bool bIsNegative,
999 int64_t nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01001000
1001static void QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
1002 int64_t nLabel,
1003 UsefulBufC Mantissa,
1004 bool bIsNegative,
1005 int64_t nBase10Exponent);
1006
1007/**
1008 @brief Add a big floating-point number to the encoded output.
1009
1010 @param[in] pCtx The encoding context to add the bigfloat to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001011 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001012 @param[in] nMantissa The mantissa.
1013 @param[in] nBase2Exponent The exponent.
1014
1015 The value is nMantissa * 2 ^ nBase2Exponent.
1016
1017 "Bigfloats", as CBOR terms them, are similar to IEEE floating-point
1018 numbers in having a mantissa and base-2 exponent, but they are not
1019 supported by hardware or encoded the same. They explicitly use two
1020 CBOR-encoded integers to convey the mantissa and exponent, each of which
1021 can be 8, 16, 32 or 64 bits. With both the mantissa and exponent
1022 64 bits they can express more precision and a larger range than an
1023 IEEE double floating-point number. See
1024 QCBOREncode_AddBigFloatBigNum() for even more precision.
1025
1026 For example, 1.5 would be represented by a mantissa of 3 and an
1027 exponent of -1.
1028
1029 The exponent and mantissa have the range from @c INT64_MIN to
1030 @c INT64_MAX for both encoding and decoding (CBOR allows @c -UINT64_MAX
1031 to @c UINT64_MAX, but this implementation doesn't support this range to
1032 reduce code size and interface complexity a little).
1033
1034 CBOR Preferred encoding of the integers is used, thus they will be encoded
1035 in the smallest number of bytes possible.
1036
1037 This can also be used to represent floating-point numbers in
1038 environments that don't support IEEE 754.
1039
1040 See @ref expAndMantissa for decoded representation.
1041 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001042static void QCBOREncode_AddTBigFloat(QCBOREncodeContext *pCtx,
1043 uint8_t uTagRequirement,
1044 int64_t nMantissa,
1045 int64_t nBase2Exponent);
1046
1047static void QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001048 const char *szLabel,
1049 uint8_t uTagRequirement,
1050 int64_t nMantissa,
1051 int64_t nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001052
1053static void QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pCtx,
1054 int64_t nLabel,
1055 uint8_t uTagRequirement,
1056 int64_t nMantissa,
1057 int64_t nBase2Exponent);
1058
1059
Michael Eckel5c531332020-03-02 01:35:30 +01001060static void QCBOREncode_AddBigFloat(QCBOREncodeContext *pCtx,
1061 int64_t nMantissa,
1062 int64_t nBase2Exponent);
1063
1064static void QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pCtx,
1065 const char *szLabel,
1066 int64_t nMantissa,
1067 int64_t nBase2Exponent);
1068
1069static void QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pCtx,
1070 int64_t nLabel,
1071 int64_t nMantissa,
1072 int64_t nBase2Exponent);
1073
Michael Eckel5c531332020-03-02 01:35:30 +01001074/**
1075 @brief Add a big floating-point number with a big number mantissa to
1076 the encoded output.
1077
1078 @param[in] pCtx The encoding context to add the bigfloat to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001079 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001080 @param[in] Mantissa The mantissa.
1081 @param[in] bIsNegative false if mantissa is positive, true if negative.
1082 @param[in] nBase2Exponent The exponent.
1083
1084 This is the same as QCBOREncode_AddBigFloat() except the mantissa is
1085 a big number (See QCBOREncode_AddPositiveBignum()) allowing for
1086 arbitrary precision.
1087
1088 See @ref expAndMantissa for decoded representation.
1089 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001090static void QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pCtx,
1091 uint8_t uTagRequirement,
1092 UsefulBufC Mantissa,
1093 bool bIsNegative,
1094 int64_t nBase2Exponent);
1095
1096static void QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001097 const char *szLabel,
1098 uint8_t uTagRequirement,
1099 UsefulBufC Mantissa,
1100 bool bIsNegative,
1101 int64_t nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001102
1103static void QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1104 int64_t nLabel,
1105 uint8_t uTagRequirement,
1106 UsefulBufC Mantissa,
1107 bool bIsNegative,
1108 int64_t nBase2Exponent);
1109
1110
Michael Eckel5c531332020-03-02 01:35:30 +01001111static void QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pCtx,
1112 UsefulBufC Mantissa,
1113 bool bIsNegative,
1114 int64_t nBase2Exponent);
1115
1116static void QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pCtx,
1117 const char *szLabel,
1118 UsefulBufC Mantissa,
1119 bool bIsNegative,
1120 int64_t nBase2Exponent);
1121
1122static void QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1123 int64_t nLabel,
1124 UsefulBufC Mantissa,
1125 bool bIsNegative,
1126 int64_t nBase2Exponent);
1127#endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
1128
1129
1130/**
1131 @brief Add a text URI to the encoded output.
1132
1133 @param[in] pCtx The encoding context to add the URI to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001134 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001135 @param[in] URI Pointer and length of the URI.
1136
1137 The format of URI must be per [RFC 3986]
1138 (https://tools.ietf.org/html/rfc3986).
1139
1140 It is output as CBOR major type 3, a text string, with tag @ref
1141 CBOR_TAG_URI indicating the text string is a URI.
1142
1143 A URI in a NULL-terminated string, @c szURI, can be easily added with
1144 this code:
1145
1146 QCBOREncode_AddURI(pCtx, UsefulBuf_FromSZ(szURI));
1147 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001148static void QCBOREncode_AddTURI(QCBOREncodeContext *pCtx,
1149 uint8_t uTagRequirement,
1150 UsefulBufC URI);
1151
1152static void QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pCtx,
1153 const char *szLabel,
1154 uint8_t uTagRequirement,
1155 UsefulBufC URI);
1156
1157static void QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pCtx,
1158 int64_t nLabel,
1159 uint8_t uTagRequirement,
1160 UsefulBufC URI);
1161
1162
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001163static void QCBOREncode_AddURI(QCBOREncodeContext *pCtx,
1164 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001165
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001166static void QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx,
1167 const char *szLabel,
1168 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001169
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001170static void QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx,
1171 int64_t nLabel,
1172 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001173
1174
1175/**
1176 @brief Add Base64-encoded text to encoded output.
1177
1178 @param[in] pCtx The encoding context to add the base-64 text to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001179 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001180 @param[in] B64Text Pointer and length of the base-64 encoded text.
1181
1182 The text content is Base64 encoded data per [RFC 4648]
1183 (https://tools.ietf.org/html/rfc4648).
1184
1185 It is output as CBOR major type 3, a text string, with tag @ref
1186 CBOR_TAG_B64 indicating the text string is Base64 encoded.
1187 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001188static void QCBOREncode_AddTB64Text(QCBOREncodeContext *pCtx,
1189 uint8_t uTagRequirement,
1190 UsefulBufC B64Text);
1191
1192static void QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pCtx,
1193 const char *szLabel,
1194 uint8_t uTagRequirement,
1195 UsefulBufC B64Text);
1196
1197static void QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pCtx,
1198 int64_t nLabel,
1199 uint8_t uTagRequirement,
1200 UsefulBufC B64Text);
1201
1202
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001203static void QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx,
1204 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001205
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001206static void QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx,
1207 const char *szLabel,
1208 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001209
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001210static void QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx,
1211 int64_t nLabel,
1212 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001213
1214
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001215
Michael Eckel5c531332020-03-02 01:35:30 +01001216/**
1217 @brief Add base64url encoded data to encoded output.
1218
1219 @param[in] pCtx The encoding context to add the base64url to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001220 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001221 @param[in] B64Text Pointer and length of the base64url encoded text.
1222
1223 The text content is base64URL encoded text as per [RFC 4648]
1224 (https://tools.ietf.org/html/rfc4648).
1225
1226 It is output as CBOR major type 3, a text string, with tag @ref
1227 CBOR_TAG_B64URL indicating the text string is a Base64url encoded.
1228 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001229static void QCBOREncode_AddTB64URLText(QCBOREncodeContext *pCtx,
1230 uint8_t uTagRequirement,
1231 UsefulBufC B64Text);
1232
1233static void QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pCtx,
1234 const char *szLabel,
1235 uint8_t uTagRequirement,
1236 UsefulBufC B64Text);
1237
1238static void QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pCtx,
1239 int64_t nLabel,
1240 uint8_t uTagRequirement,
1241 UsefulBufC B64Text);
1242
1243
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001244static void QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx,
1245 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001246
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001247static void QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx,
1248 const char *szLabel,
1249 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001250
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001251static void QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx,
1252 int64_t nLabel,
1253 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001254
1255
1256/**
1257 @brief Add Perl Compatible Regular Expression.
1258
1259 @param[in] pCtx The encoding context to add the regular expression to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001260 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001261 @param[in] Regex Pointer and length of the regular expression.
1262
1263 The text content is Perl Compatible Regular
1264 Expressions (PCRE) / JavaScript syntax [ECMA262].
1265
1266 It is output as CBOR major type 3, a text string, with tag @ref
1267 CBOR_TAG_REGEX indicating the text string is a regular expression.
1268 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001269static void QCBOREncode_AddTRegex(QCBOREncodeContext *pCtx,
1270 uint8_t uTagRequirement,
1271 UsefulBufC Regex);
1272
1273static void QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pCtx,
1274 const char *szLabel,
1275 uint8_t uTagRequirement,
1276 UsefulBufC Regex);
1277
1278static void QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pCtx,
1279 int64_t nLabel,
1280 uint8_t uTagRequirement,
1281 UsefulBufC Regex);
1282
1283
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001284static void QCBOREncode_AddRegex(QCBOREncodeContext *pCtx,
1285 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001286
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001287static void QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx,
1288 const char *szLabel,
1289 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001290
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001291static void QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx,
1292 int64_t nLabel,
1293 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001294
1295
1296/**
Laurence Lundblade4982f412020-09-18 23:02:18 -07001297 @brief MIME encoded data to the encoded output.
Michael Eckel5c531332020-03-02 01:35:30 +01001298
Laurence Lundblade4982f412020-09-18 23:02:18 -07001299 @param[in] pCtx The encoding context to add the MIME data to.
1300 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1301 @ref QCBOR_ENCODE_AS_BORROWED.
1302 @param[in] MIMEData Pointer and length of the MIME data.
Michael Eckel5c531332020-03-02 01:35:30 +01001303
1304 The text content is in MIME format per [RFC 2045]
Laurence Lundblade4982f412020-09-18 23:02:18 -07001305 (https://tools.ietf.org/html/rfc2045) including the headers.
Michael Eckel5c531332020-03-02 01:35:30 +01001306
Laurence Lundblade4982f412020-09-18 23:02:18 -07001307 It is output as CBOR major type 2, a binary string, with tag @ref
1308 CBOR_TAG_BINARY_MIME indicating the string is MIME data. This
1309 outputs tag 257, not tag 36, as it can carry any type of MIME binary,
1310 7-bit, 8-bit, quoted-printable and base64 where tag 36 cannot.
1311
1312 Previous versions of QCBOR, those before spiffy decode, output tag
1313 36. Decoding supports both tag 36 and 257. (if the old behavior with
1314 tag 36 is needed, copy the inline functions below and change the tag
1315 number).
1316
1317 See also QCBORDecode_GetMIMEMessage() and
1318 @ref QCBOR_TYPE_BINARY_MIME.
Laurence Lundbladeadaf5c22020-09-25 10:37:09 -07001319
1320 This does no translation of line endings. See QCBOREncode_AddText()
1321 for a discussion of line endings in CBOR.
Michael Eckel5c531332020-03-02 01:35:30 +01001322 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001323static void QCBOREncode_AddTMIMEData(QCBOREncodeContext *pCtx,
1324 uint8_t uTagRequirement,
1325 UsefulBufC MIMEData);
1326
1327static void QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pCtx,
1328 const char *szLabel,
1329 uint8_t uTagRequirement,
1330 UsefulBufC MIMEData);
1331
1332static void QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pCtx,
1333 int64_t nLabel,
1334 uint8_t uTagRequirement,
1335 UsefulBufC MIMEData);
1336
1337
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001338static void QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx,
1339 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001340
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001341static void QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx,
1342 const char *szLabel,
1343 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001344
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001345static void QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx,
1346 int64_t nLabel,
1347 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001348
1349
1350/**
1351 @brief Add an RFC 3339 date string
1352
1353 @param[in] pCtx The encoding context to add the date to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001354 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001355 @param[in] szDate Null-terminated string with date to add.
1356
1357 The string szDate should be in the form of [RFC 3339]
1358 (https://tools.ietf.org/html/rfc3339) as defined by section 3.3 in
1359 [RFC 4287] (https://tools.ietf.org/html/rfc4287). This is as
1360 described in section 2.4.1 in [RFC 7049]
1361 (https://tools.ietf.org/html/rfc7049).
1362
1363 Note that this function doesn't validate the format of the date string
1364 at all. If you add an incorrect format date string, the generated
1365 CBOR will be incorrect and the receiver may not be able to handle it.
1366
1367 Error handling is the same as QCBOREncode_AddInt64().
1368 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001369static void QCBOREncode_AddTDateString(QCBOREncodeContext *pCtx,
1370 uint8_t uTagRequirement,
1371 const char *szDate);
1372
1373static void QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pCtx,
1374 const char *szLabel,
1375 uint8_t uTagRequirement,
1376 const char *szDate);
1377
1378static void QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pCtx,
1379 int64_t nLabel,
1380 uint8_t uTagRequirement,
1381 const char *szDate);
1382
1383
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001384static void QCBOREncode_AddDateString(QCBOREncodeContext *pCtx,
1385 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001386
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001387static void QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx,
1388 const char *szLabel,
1389 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001390
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001391static void QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx,
1392 int64_t nLabel,
1393 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001394
Michael Eckel5c531332020-03-02 01:35:30 +01001395/**
1396 @brief Add a standard Boolean.
1397
1398 @param[in] pCtx The encoding context to add the Boolean to.
1399 @param[in] b true or false from @c <stdbool.h>.
1400
1401 Adds a Boolean value as CBOR major type 7.
1402
1403 Error handling is the same as QCBOREncode_AddInt64().
1404 */
1405static void QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b);
1406
1407static void QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b);
1408
1409static void QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b);
1410
1411
1412
1413/**
1414 @brief Add a NULL to the encoded output.
1415
1416 @param[in] pCtx The encoding context to add the NULL to.
1417
1418 Adds the NULL value as CBOR major type 7.
1419
1420 This NULL doesn't have any special meaning in CBOR such as a
1421 terminating value for a string or an empty value.
1422
1423 Error handling is the same as QCBOREncode_AddInt64().
1424 */
1425static void QCBOREncode_AddNULL(QCBOREncodeContext *pCtx);
1426
1427static void QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1428
1429static void QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1430
1431
1432/**
1433 @brief Add an "undef" to the encoded output.
1434
1435 @param[in] pCtx The encoding context to add the "undef" to.
1436
1437 Adds the undef value as CBOR major type 7.
1438
1439 Note that this value will not translate to JSON.
1440
1441 This Undef doesn't have any special meaning in CBOR such as a
1442 terminating value for a string or an empty value.
1443
1444 Error handling is the same as QCBOREncode_AddInt64().
1445 */
1446static void QCBOREncode_AddUndef(QCBOREncodeContext *pCtx);
1447
1448static void QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1449
1450static void QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1451
1452
1453/**
1454 @brief Indicates that the next items added are in an array.
1455
1456 @param[in] pCtx The encoding context to open the array in.
1457
1458 Arrays are the basic CBOR aggregate or structure type. Call this
1459 function to start or open an array. Then call the various @c
1460 QCBOREncode_AddXxx() functions to add the items that go into the
1461 array. Then call QCBOREncode_CloseArray() when all items have been
1462 added. The data items in the array can be of any type and can be of
1463 mixed types.
1464
1465 Nesting of arrays and maps is allowed and supported just by calling
1466 QCBOREncode_OpenArray() again before calling
1467 QCBOREncode_CloseArray(). While CBOR has no limit on nesting, this
1468 implementation does in order to keep it smaller and simpler. The
1469 limit is @ref QCBOR_MAX_ARRAY_NESTING. This is the max number of
1470 times this can be called without calling
1471 QCBOREncode_CloseArray(). QCBOREncode_Finish() will return @ref
1472 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP when it is called as this function
1473 just sets an error state and returns no value when this occurs.
1474
1475 If you try to add more than @ref QCBOR_MAX_ITEMS_IN_ARRAY items to a
1476 single array or map, @ref QCBOR_ERR_ARRAY_TOO_LONG will be returned
1477 when QCBOREncode_Finish() is called.
1478
1479 An array itself must have a label if it is being added to a map.
1480 Note that array elements do not have labels (but map elements do).
1481
1482 An array itself may be tagged by calling QCBOREncode_AddTag() before this call.
1483 */
1484static void QCBOREncode_OpenArray(QCBOREncodeContext *pCtx);
1485
1486static void QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1487
1488static void QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1489
1490
1491/**
1492 @brief Close an open array.
1493
1494 @param[in] pCtx The encoding context to close the array in.
1495
1496 The closes an array opened by QCBOREncode_OpenArray(). It reduces
1497 nesting level by one. All arrays (and maps) must be closed before
1498 calling QCBOREncode_Finish().
1499
1500 When an error occurs as a result of this call, the encoder records
1501 the error and enters the error state. The error will be returned when
1502 QCBOREncode_Finish() is called.
1503
1504 If this has been called more times than QCBOREncode_OpenArray(), then
1505 @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when QCBOREncode_Finish()
1506 is called.
1507
1508 If this is called and it is not an array that is currently open, @ref
1509 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
1510 is called.
1511 */
1512static void QCBOREncode_CloseArray(QCBOREncodeContext *pCtx);
1513
1514
1515/**
1516 @brief Indicates that the next items added are in a map.
1517
1518 @param[in] pCtx The encoding context to open the map in.
1519
1520 See QCBOREncode_OpenArray() for more information, particularly error
1521 handling.
1522
1523 CBOR maps are an aggregate type where each item in the map consists
1524 of a label and a value. They are similar to JSON objects.
1525
1526 The value can be any CBOR type including another map.
1527
1528 The label can also be any CBOR type, but in practice they are
1529 typically, integers as this gives the most compact output. They might
1530 also be text strings which gives readability and translation to JSON.
1531
1532 Every @c QCBOREncode_AddXxx() call has one version that ends with @c
1533 InMap for adding items to maps with string labels and one that ends
1534 with @c InMapN that is for adding with integer labels.
1535
1536 RFC 7049 uses the term "key" instead of "label".
1537
1538 If you wish to use map labels that are neither integer labels nor
1539 text strings, then just call the QCBOREncode_AddXxx() function
1540 explicitly to add the label. Then call it again to add the value.
1541
1542 See the [RFC 7049] (https://tools.ietf.org/html/rfc7049) for a lot
1543 more information on creating maps.
1544 */
1545static void QCBOREncode_OpenMap(QCBOREncodeContext *pCtx);
1546
1547static void QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1548
1549static void QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1550
1551
1552
1553/**
1554 @brief Close an open map.
1555
1556 @param[in] pCtx The encoding context to close the map in .
1557
1558 This closes a map opened by QCBOREncode_OpenMap(). It reduces nesting
1559 level by one.
1560
1561 When an error occurs as a result of this call, the encoder records
1562 the error and enters the error state. The error will be returned when
1563 QCBOREncode_Finish() is called.
1564
1565 If this has been called more times than QCBOREncode_OpenMap(),
1566 then @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1567 QCBOREncode_Finish() is called.
1568
1569 If this is called and it is not a map that is currently open, @ref
1570 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
1571 is called.
1572 */
1573static void QCBOREncode_CloseMap(QCBOREncodeContext *pCtx);
1574
1575
1576/**
1577 @brief Indicate start of encoded CBOR to be wrapped in a bstr.
1578
1579 @param[in] pCtx The encoding context to open the bstr-wrapped CBOR in.
1580
1581 All added encoded items between this call and a call to
1582 QCBOREncode_CloseBstrWrap2() will be wrapped in a bstr. They will
1583 appear in the final output as a byte string. That byte string will
1584 contain encoded CBOR. This increases nesting level by one.
1585
1586 The typical use case is for encoded CBOR that is to be
1587 cryptographically hashed, as part of a [RFC 8152, COSE]
1588 (https://tools.ietf.org/html/rfc8152) implementation.
1589
1590 Using QCBOREncode_BstrWrap() and QCBOREncode_CloseBstrWrap2() avoids
1591 having to encode the items first in one buffer (e.g., the COSE
1592 payload) and then add that buffer as a bstr to another encoding
1593 (e.g. the COSE to-be-signed bytes, the @c Sig_structure) potentially
1594 halving the memory needed.
1595
1596 RFC 7049 states the purpose of this wrapping is to prevent code
1597 relaying the signed data but not verifying it from tampering with the
1598 signed data thus making the signature unverifiable. It is also quite
1599 beneficial for the signature verification code. Standard CBOR
1600 decoders usually do not give access to partially decoded CBOR as
1601 would be needed to check the signature of some CBOR. With this
1602 wrapping, standard CBOR decoders can be used to get to all the data
1603 needed for a signature verification.
1604 */
1605static void QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx);
1606
1607static void QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1608
1609static void QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1610
1611
1612/**
1613 @brief Close a wrapping bstr.
1614
1615 @param[in] pCtx The encoding context to close of bstr wrapping in.
1616 @param[in] bIncludeCBORHead Include the encoded CBOR head of the bstr
1617 as well as the bytes in @c pWrappedCBOR.
1618 @param[out] pWrappedCBOR A @ref UsefulBufC containing wrapped bytes.
1619
1620 The closes a wrapping bstr opened by QCBOREncode_BstrWrap(). It reduces
1621 nesting level by one.
1622
1623 A pointer and length of the enclosed encoded CBOR is returned in @c
1624 *pWrappedCBOR if it is not @c NULL. The main purpose of this is so
1625 this data can be hashed (e.g., with SHA-256) as part of a [RFC 8152,
1626 COSE] (https://tools.ietf.org/html/rfc8152)
1627 implementation. **WARNING**, this pointer and length should be used
1628 right away before any other calls to @c QCBOREncode_CloseXxx() as
1629 they will move data around and the pointer and length will no longer
1630 be to the correct encoded CBOR.
1631
1632 When an error occurs as a result of this call, the encoder records
1633 the error and enters the error state. The error will be returned when
1634 QCBOREncode_Finish() is called.
1635
1636 If this has been called more times than QCBOREncode_BstrWrap(), then
1637 @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1638 QCBOREncode_Finish() is called.
1639
1640 If this is called and it is not a wrapping bstr that is currently
1641 open, @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
1642 QCBOREncode_Finish() is called.
1643
1644 QCBOREncode_CloseBstrWrap() is a deprecated version of this function
1645 that is equivalent to the call with @c bIncludeCBORHead @c true.
1646 */
1647void QCBOREncode_CloseBstrWrap2(QCBOREncodeContext *pCtx, bool bIncludeCBORHead, UsefulBufC *pWrappedCBOR);
1648
1649static void QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR);
1650
1651
1652/**
1653 @brief Add some already-encoded CBOR bytes.
1654
1655 @param[in] pCtx The encoding context to add the already-encode CBOR to.
1656 @param[in] Encoded The already-encoded CBOR to add to the context.
1657
1658 The encoded CBOR being added must be fully conforming CBOR. It must
1659 be complete with no arrays or maps that are incomplete. While this
1660 encoder doesn't ever produce indefinite lengths, it is OK for the
1661 raw CBOR added here to have indefinite lengths.
1662
1663 The raw CBOR added here is not checked in anyway. If it is not
1664 conforming or has open arrays or such, the final encoded CBOR
1665 will probably be wrong or not what was intended.
1666
1667 If the encoded CBOR being added here contains multiple items, they
1668 must be enclosed in a map or array. At the top level the raw
1669 CBOR must be a single data item.
1670 */
1671static void QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded);
1672
1673static void QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded);
1674
1675static void QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded);
1676
1677
1678/**
1679 @brief Get the encoded result.
1680
1681 @param[in] pCtx The context to finish encoding with.
1682 @param[out] pEncodedCBOR Pointer and length of encoded CBOR.
1683
1684 @retval QCBOR_ERR_TOO_MANY_CLOSES Nesting error
1685
1686 @retval QCBOR_ERR_CLOSE_MISMATCH Nesting error
1687
1688 @retval QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN Nesting error
1689
1690 @retval QCBOR_ERR_BUFFER_TOO_LARGE Encoded output buffer size
1691
1692 @retval QCBOR_ERR_BUFFER_TOO_SMALL Encoded output buffer size
1693
1694 @retval QCBOR_ERR_ARRAY_NESTING_TOO_DEEP Implementation limit
1695
1696 @retval QCBOR_ERR_ARRAY_TOO_LONG Implementation limit
1697
1698 If this returns success @ref QCBOR_SUCCESS the encoding was a success
1699 and the return length is correct and complete.
1700
1701 If no buffer was passed to QCBOREncode_Init(), then only the length
1702 was computed. If a buffer was passed, then the encoded CBOR is in the
1703 buffer.
1704
1705 Encoding errors primarily manifest here as most other encoding function
1706 do no return an error. They just set the error state in the encode
1707 context after which no encoding function does anything.
1708
1709 Three types of errors manifest here. The first type are nesting
1710 errors where the number of @c QCBOREncode_OpenXxx() calls do not
1711 match the number @c QCBOREncode_CloseXxx() calls. The solution is to
1712 fix the calling code.
1713
1714 The second type of error is because the buffer given is either too
1715 small or too large. The remedy is to give a correctly sized buffer.
1716
1717 The third type are due to limits in this implementation. @ref
1718 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP can be worked around by encoding the
1719 CBOR in two (or more) phases and adding the CBOR from the first phase
1720 to the second with @c QCBOREncode_AddEncoded().
1721
1722 If an error is returned, the buffer may have partially encoded
1723 incorrect CBOR in it and it should not be used. Likewise, the length
1724 may be incorrect and should not be used.
1725
1726 Note that the error could have occurred in one of the many @c
1727 QCBOREncode_AddXxx() calls long before QCBOREncode_Finish() was
1728 called. This error handling reduces the CBOR implementation size but
1729 makes debugging harder.
1730
1731 This may be called multiple times. It will always return the same. It
1732 can also be interleaved with calls to QCBOREncode_FinishGetSize().
1733
1734 QCBOREncode_GetErrorState() can be called to get the current
1735 error state and abort encoding early as an optimization, but is
1736 is never required.
1737 */
1738QCBORError QCBOREncode_Finish(QCBOREncodeContext *pCtx, UsefulBufC *pEncodedCBOR);
1739
1740
1741/**
1742 @brief Get the encoded CBOR and error status.
1743
1744 @param[in] pCtx The context to finish encoding with.
1745 @param[out] uEncodedLen The length of the encoded or potentially
1746 encoded CBOR in bytes.
1747
1748 @return The same errors as QCBOREncode_Finish().
1749
1750 This functions the same as QCBOREncode_Finish(), but only returns the
1751 size of the encoded output.
1752 */
1753QCBORError QCBOREncode_FinishGetSize(QCBOREncodeContext *pCtx, size_t *uEncodedLen);
1754
1755
1756/**
1757 @brief Indicate whether output buffer is NULL or not.
1758
1759 @param[in] pCtx The encoding context.
1760
1761 @return 1 if the output buffer is @c NULL.
1762
1763 Sometimes a @c NULL input buffer is given to QCBOREncode_Init() so
1764 that the size of the generated CBOR can be calculated without
1765 allocating a buffer for it. This returns 1 when the output buffer is
1766 NULL and 0 when it is not.
1767*/
1768static int QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx);
1769
1770 /**
1771 @brief Get the encoding error state.
1772
1773 @param[in] pCtx The encoding context.
1774
Laurence Lundbladeabf5c572020-06-29 21:21:29 -07001775 @return One of @ref QCBORError. See return values from
Michael Eckel5c531332020-03-02 01:35:30 +01001776 QCBOREncode_Finish()
1777
1778 Normally encoding errors need only be handled at the end of encoding
1779 when QCBOREncode_Finish() is called. This can be called to get the
1780 error result before finish should there be a need to halt encoding
1781 before QCBOREncode_Finish() is called.
1782*/
1783static QCBORError QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx);
1784
1785
1786/**
1787 Encode the "head" of a CBOR data item.
1788
1789 @param buffer Buffer to output the encoded head to; must be
1790 @ref QCBOR_HEAD_BUFFER_SIZE bytes in size.
1791 @param uMajorType One of CBOR_MAJOR_TYPE_XX.
1792 @param uMinLen The minimum number of bytes to encode uNumber. Almost always
1793 this is 0 to use preferred minimal encoding. If this is 4,
1794 then even the values 0xffff and smaller will be encoded
Laurence Lundblade98427e92020-09-28 21:33:23 -07001795 in 4 bytes. This is used primarily when encoding a
Michael Eckel5c531332020-03-02 01:35:30 +01001796 float or double put into uNumber as the leading zero bytes
1797 for them must be encoded.
1798 @param uNumber The numeric argument part of the CBOR head.
1799 @return Pointer and length of the encoded head or
Laurence Lundblade9a3b6252020-10-21 21:30:31 -07001800 @ref NULLUsefulBufC if the output buffer is too small.
Michael Eckel5c531332020-03-02 01:35:30 +01001801
Laurence Lundblade98427e92020-09-28 21:33:23 -07001802 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 +01001803 take a @ref QCBOREncodeContext argument.
1804
1805 This encodes the major type and argument part of a data item. The
1806 argument is an integer that is usually either the value or the length
1807 of the data item.
1808
1809 This is exposed in the public interface to allow hashing of some CBOR
1810 data types, bstr in particular, a chunk at a time so the full CBOR
1811 doesn't have to be encoded in a contiguous buffer.
1812
1813 For example, if you have a 100,000 byte binary blob in a buffer that
1814 needs to be a bstr encoded and then hashed. You could allocate a
1815 100,010 byte buffer and encode it normally. Alternatively, you can
1816 encode the head in a 10 byte buffer with this function, hash that and
1817 then hash the 100,000 bytes using the same hash context.
1818
1819 See also QCBOREncode_AddBytesLenOnly();
1820 */
1821UsefulBufC QCBOREncode_EncodeHead(UsefulBuf buffer,
1822 uint8_t uMajorType,
1823 uint8_t uMinLen,
1824 uint64_t uNumber);
1825
1826
Michael Eckel5c531332020-03-02 01:35:30 +01001827
1828
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001829/* =========================================================================
1830 BEGINNING OF PRIVATE INLINE IMPLEMENTATION
1831 ========================================================================= */
Michael Eckel5c531332020-03-02 01:35:30 +01001832
1833/**
1834 @brief Semi-private method to add a buffer full of bytes to encoded output
1835
1836 @param[in] pCtx The encoding context to add the integer to.
1837 @param[in] uMajorType The CBOR major type of the bytes.
1838 @param[in] Bytes The bytes to add.
1839
1840 Use QCBOREncode_AddText() or QCBOREncode_AddBytes() or
1841 QCBOREncode_AddEncoded() instead. They are inline functions that call
1842 this and supply the correct major type. This function is public to
1843 make the inline functions work to keep the overall code size down and
1844 because the C language has no way to make it private.
1845
1846 If this is called the major type should be @c
1847 CBOR_MAJOR_TYPE_TEXT_STRING, @c CBOR_MAJOR_TYPE_BYTE_STRING or @c
1848 CBOR_MAJOR_NONE_TYPE_RAW. The last one is special for adding
1849 already-encoded CBOR.
1850 */
1851void QCBOREncode_AddBuffer(QCBOREncodeContext *pCtx, uint8_t uMajorType, UsefulBufC Bytes);
1852
1853
1854/**
1855 @brief Semi-private method to open a map, array or bstr-wrapped CBOR
1856
1857 @param[in] pCtx The context to add to.
1858 @param[in] uMajorType The major CBOR type to close
1859
1860 Call QCBOREncode_OpenArray(), QCBOREncode_OpenMap() or
1861 QCBOREncode_BstrWrap() instead of this.
1862 */
1863void QCBOREncode_OpenMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType);
1864
1865
1866/**
1867 @brief Semi-private method to open a map, array with indefinite length
1868
1869 @param[in] pCtx The context to add to.
1870 @param[in] uMajorType The major CBOR type to close
1871
1872 Call QCBOREncode_OpenArrayIndefiniteLength() or
1873 QCBOREncode_OpenMapIndefiniteLength() instead of this.
1874 */
1875void QCBOREncode_OpenMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx, uint8_t uMajorType);
1876
1877
1878/**
1879 @brief Semi-private method to close a map, array or bstr wrapped CBOR
1880
1881 @param[in] pCtx The context to add to.
1882 @param[in] uMajorType The major CBOR type to close.
1883
1884 Call QCBOREncode_CloseArray() or QCBOREncode_CloseMap() instead of this.
1885 */
1886void QCBOREncode_CloseMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType);
1887
1888
1889/**
1890 @brief Semi-private method to close a map, array with indefinite length
1891
1892 @param[in] pCtx The context to add to.
1893 @param[in] uMajorType The major CBOR type to close.
1894
1895 Call QCBOREncode_CloseArrayIndefiniteLength() or
1896 QCBOREncode_CloseMapIndefiniteLength() instead of this.
1897 */
1898void QCBOREncode_CloseMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx,
1899 uint8_t uMajorType);
1900
1901
1902/**
1903 @brief Semi-private method to add simple types.
1904
1905 @param[in] pCtx The encoding context to add the simple value to.
1906 @param[in] uMinLen Minimum encoding size for uNum. Usually 0.
1907 @param[in] uNum One of CBOR_SIMPLEV_FALSE through _UNDEF or other.
1908
1909 This is used to add simple types like true and false.
1910
1911 Call QCBOREncode_AddBool(), QCBOREncode_AddNULL(),
1912 QCBOREncode_AddUndef() instead of this.
1913
1914 This function can add simple values that are not defined by CBOR
1915 yet. This expansion point in CBOR should not be used unless they are
1916 standardized.
1917
1918 Error handling is the same as QCBOREncode_AddInt64().
1919 */
1920void QCBOREncode_AddType7(QCBOREncodeContext *pCtx, uint8_t uMinLen, uint64_t uNum);
1921
1922
1923/**
1924 @brief Semi-private method to add bigfloats and decimal fractions.
1925
1926 @param[in] pCtx The encoding context to add the value to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001927 @param[in] uTag The type 6 tag indicating what this is to be.
Michael Eckel5c531332020-03-02 01:35:30 +01001928 @param[in] BigNumMantissa Is @ref NULLUsefulBufC if mantissa is an
1929 @c int64_t or the actual big number mantissa
1930 if not.
1931 @param[in] nMantissa The @c int64_t mantissa if it is not a big number.
1932 @param[in] nExponent The exponent.
1933
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001934 This outputs either the @ref CBOR_TAG_DECIMAL_FRACTION or @ref
1935 CBOR_TAG_BIGFLOAT tag. if @c uTag is @ref CBOR_TAG_INVALID64, then
1936 this outputs the "borrowed" content format.
Michael Eckel5c531332020-03-02 01:35:30 +01001937
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001938 The tag content output by this is an array with two members, the
1939 exponent and then the mantissa. The mantissa can be either a big
1940 number or an @c int64_t.
1941
1942 This implementation cannot output an exponent further from 0 than
Laurence Lundblade9a3b6252020-10-21 21:30:31 -07001943 @c INT64_MAX.
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001944
1945 To output a mantissa that is bewteen INT64_MAX and UINT64_MAX from 0,
1946 it must be as a big number.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001947
Michael Eckel5c531332020-03-02 01:35:30 +01001948 Typically, QCBOREncode_AddDecimalFraction(), QCBOREncode_AddBigFloat(),
1949 QCBOREncode_AddDecimalFractionBigNum() or QCBOREncode_AddBigFloatBigNum()
1950 is called instead of this.
1951 */
1952void QCBOREncode_AddExponentAndMantissa(QCBOREncodeContext *pCtx,
1953 uint64_t uTag,
1954 UsefulBufC BigNumMantissa,
1955 bool bBigNumIsNegative,
1956 int64_t nMantissa,
1957 int64_t nExponent);
1958
1959/**
1960 @brief Semi-private method to add only the type and length of a byte string.
1961
1962 @param[in] pCtx The context to initialize.
1963 @param[in] Bytes Pointer and length of the input data.
1964
1965 This is the same as QCBOREncode_AddBytes() except it only adds the
1966 CBOR encoding for the type and the length. It doesn't actually add
1967 the bytes. You can't actually produce correct CBOR with this and the
1968 rest of this API. It is only used for a special case where
1969 the valid CBOR is created manually by putting this type and length in
1970 and then adding the actual bytes. In particular, when only a hash of
1971 the encoded CBOR is needed, where the type and header are hashed
1972 separately and then the bytes is hashed. This makes it possible to
1973 implement COSE Sign1 with only one copy of the payload in the output
1974 buffer, rather than two, roughly cutting memory use in half.
1975
1976 This is only used for this odd case, but this is a supported
1977 tested function.
1978
1979 See also QCBOREncode_EncodeHead().
1980*/
1981static inline void QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
1982
1983static inline void QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
1984
1985static inline void QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
1986
1987
1988
1989
1990
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001991static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001992QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pMe, const char *szLabel, int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01001993{
1994 // Use _AddBuffer() because _AddSZString() is defined below, not above
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001995 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
1996 QCBOREncode_AddInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01001997}
1998
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001999static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002000QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pMe, int64_t nLabel, int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002001{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002002 QCBOREncode_AddInt64(pMe, nLabel);
2003 QCBOREncode_AddInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002004}
2005
2006
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002007static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002008QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pMe, const char *szLabel, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002009{
2010 // Use _AddBuffer() because _AddSZString() is defined below, not above
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002011 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
2012 QCBOREncode_AddUInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002013}
2014
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002015static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002016QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002017{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002018 QCBOREncode_AddInt64(pMe, nLabel);
2019 QCBOREncode_AddUInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002020}
2021
2022
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002023static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002024QCBOREncode_AddText(QCBOREncodeContext *pMe, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002025{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002026 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002027}
2028
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002029static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002030QCBOREncode_AddTextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002031{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002032 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szLabel));
2033 QCBOREncode_AddText(pMe, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002034}
2035
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002036static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002037QCBOREncode_AddTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002038{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002039 QCBOREncode_AddInt64(pMe, nLabel);
2040 QCBOREncode_AddText(pMe, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002041}
2042
2043
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002044inline static void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002045QCBOREncode_AddSZString(QCBOREncodeContext *pMe, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002046{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002047 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szString));
Michael Eckel5c531332020-03-02 01:35:30 +01002048}
2049
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002050static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002051QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pMe, const char *szLabel, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002052{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002053 QCBOREncode_AddSZString(pMe, szLabel);
2054 QCBOREncode_AddSZString(pMe, szString);
Michael Eckel5c531332020-03-02 01:35:30 +01002055}
2056
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002057static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002058QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002059{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002060 QCBOREncode_AddInt64(pMe, nLabel);
2061 QCBOREncode_AddSZString(pMe, szString);
Michael Eckel5c531332020-03-02 01:35:30 +01002062}
2063
2064
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002065static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002066QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pMe, const char *szLabel, double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002067{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002068 QCBOREncode_AddSZString(pMe, szLabel);
2069 QCBOREncode_AddDouble(pMe, dNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002070}
2071
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002072static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002073QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pMe, int64_t nLabel, double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002074{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002075 QCBOREncode_AddInt64(pMe, nLabel);
2076 QCBOREncode_AddDouble(pMe, dNum);
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_AddFloatToMap(QCBOREncodeContext *pMe, const char *szLabel, float dNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002081{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002082 QCBOREncode_AddSZString(pMe, szLabel);
2083 QCBOREncode_AddFloat(pMe, dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002084}
2085
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002086static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002087QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pMe, int64_t nLabel, float fNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002088{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002089 QCBOREncode_AddInt64(pMe, nLabel);
2090 QCBOREncode_AddFloat(pMe, fNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002091}
2092
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002093static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002094QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pMe, const char *szLabel, double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002095{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002096 QCBOREncode_AddSZString(pMe, szLabel);
2097 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002098}
2099
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002100static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002101QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pMe, int64_t nLabel, double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002102{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002103 QCBOREncode_AddInt64(pMe, nLabel);
2104 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002105}
2106
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002107static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002108QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pMe, const char *szLabel, float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002109{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002110 QCBOREncode_AddSZString(pMe, szLabel);
2111 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002112}
2113
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002114static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002115QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pMe, int64_t nLabel, float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002116{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002117 QCBOREncode_AddInt64(pMe, nLabel);
2118 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002119}
2120
Michael Eckel5c531332020-03-02 01:35:30 +01002121
Laurence Lundblade9b334962020-08-27 10:55:53 -07002122
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002123static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002124QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pMe, uint8_t uTag, int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002125{
2126 if(uTag == QCBOR_ENCODE_AS_TAG) {
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002127 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_EPOCH);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002128 }
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002129 QCBOREncode_AddInt64(pMe, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002130}
2131
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002132static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002133QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTag, int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002134{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002135 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002136 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002137}
2138
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002139static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002140QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTag, int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002141{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002142 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002143 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002144}
2145
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002146static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002147QCBOREncode_AddDateEpoch(QCBOREncodeContext *pMe, int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002148{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002149 QCBOREncode_AddTDateEpoch(pMe, QCBOR_ENCODE_AS_TAG, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002150}
2151
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002152static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002153QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pMe, const char *szLabel, int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002154{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002155 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002156 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002157}
2158
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002159static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002160QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pMe, int64_t nLabel, int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002161{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002162 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002163 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002164}
2165
2166
Laurence Lundblade9b334962020-08-27 10:55:53 -07002167
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002168static inline void
2169QCBOREncode_AddBytes(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002170{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002171 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002172}
2173
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002174static inline void
2175QCBOREncode_AddBytesToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002176{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002177 QCBOREncode_AddSZString(pMe, szLabel);
2178 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002179}
2180
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002181static inline void
2182QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002183{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002184 QCBOREncode_AddInt64(pMe, nLabel);
2185 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002186}
2187
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002188static inline void
2189QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002190{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002191 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002192}
2193
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002194static inline void
2195QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002196{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002197 QCBOREncode_AddSZString(pMe, szLabel);
2198 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002199}
2200
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002201static inline void
2202QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002203{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002204 QCBOREncode_AddInt64(pMe, nLabel);
2205 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002206}
2207
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002208
2209static inline void
2210QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002211{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002212 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2213 QCBOREncode_AddTag(pMe, CBOR_TAG_BIN_UUID);
2214 }
2215 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002216}
2217
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002218static inline void
2219QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pMe,
2220 const char *szLabel,
2221 uint8_t uTagRequirement,
2222 UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002223{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002224 QCBOREncode_AddSZString(pMe, szLabel);
2225 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002226}
2227
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002228static inline void
2229QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002230{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002231 QCBOREncode_AddInt64(pMe, nLabel);
2232 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002233}
2234
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002235static inline void
2236QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002237{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002238 QCBOREncode_AddTBinaryUUID(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002239}
2240
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002241static inline void
2242QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002243{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002244 QCBOREncode_AddTBinaryUUIDToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002245}
2246
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002247static inline void
2248QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002249{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002250 QCBOREncode_AddTBinaryUUIDToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002251}
2252
2253
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002254static inline void
2255QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002256{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002257 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2258 QCBOREncode_AddTag(pMe, CBOR_TAG_POS_BIGNUM);
2259 }
2260 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002261}
2262
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002263static inline void
2264QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pMe,
2265 const char *szLabel,
2266 uint8_t uTagRequirement,
2267 UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002268{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002269 QCBOREncode_AddSZString(pMe, szLabel);
2270 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002271}
2272
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002273static inline void
2274QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002275{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002276 QCBOREncode_AddInt64(pMe, nLabel);
2277 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002278}
2279
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002280static inline void
2281QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2282{
2283 QCBOREncode_AddTPositiveBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2284}
2285
2286static inline void
2287QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2288{
2289 QCBOREncode_AddTPositiveBignumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2290}
2291
2292static inline void
2293QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2294{
2295 QCBOREncode_AddTPositiveBignumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2296}
2297
2298
2299static inline void
2300QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
2301{
2302 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2303 QCBOREncode_AddTag(pMe, CBOR_TAG_NEG_BIGNUM);
2304 }
2305 QCBOREncode_AddBytes(pMe, Bytes);
2306}
2307
2308static inline void
2309QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pMe,
2310 const char *szLabel,
2311 uint8_t uTagRequirement,
2312 UsefulBufC Bytes)
2313{
2314 QCBOREncode_AddSZString(pMe, szLabel);
2315 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2316}
2317
2318static inline void
2319QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
2320{
2321 QCBOREncode_AddInt64(pMe, nLabel);
2322 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2323}
2324
2325static inline void
2326QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2327{
2328 QCBOREncode_AddTNegativeBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2329}
2330
2331static inline void
2332QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2333{
2334 QCBOREncode_AddTNegativeBignumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2335}
2336
2337static inline void
2338QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2339{
2340 QCBOREncode_AddTNegativeBignumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2341}
2342
2343
Michael Eckel5c531332020-03-02 01:35:30 +01002344
2345#ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
2346
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002347static inline void
2348QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pMe,
2349 uint8_t uTagRequirement,
2350 int64_t nMantissa,
2351 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002352{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002353 uint64_t uTag;
2354 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2355 uTag = CBOR_TAG_DECIMAL_FRACTION;
2356 } else {
2357 uTag = CBOR_TAG_INVALID64;
2358 }
2359 QCBOREncode_AddExponentAndMantissa(pMe,
2360 uTag,
Michael Eckel5c531332020-03-02 01:35:30 +01002361 NULLUsefulBufC,
2362 false,
2363 nMantissa,
2364 nBase10Exponent);
2365}
2366
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002367static inline void
2368QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pMe,
2369 const char *szLabel,
2370 uint8_t uTagRequirement,
2371 int64_t nMantissa,
2372 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002373{
2374 QCBOREncode_AddSZString(pMe, szLabel);
2375 QCBOREncode_AddTDecimalFraction(pMe, uTagRequirement, nMantissa, nBase10Exponent);
2376}
2377
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002378static inline void
2379QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pMe,
2380 int64_t nLabel,
2381 uint8_t uTagRequirement,
2382 int64_t nMantissa,
2383 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002384{
2385 QCBOREncode_AddInt64(pMe, nLabel);
2386 QCBOREncode_AddTDecimalFraction(pMe, uTagRequirement, nMantissa, nBase10Exponent);
2387}
2388
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002389static inline void
2390QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pMe,
2391 int64_t nMantissa,
2392 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002393{
2394 QCBOREncode_AddTDecimalFraction(pMe, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
2395}
2396
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002397static inline void
2398QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pMe,
2399 const char *szLabel,
2400 int64_t nMantissa,
2401 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002402{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002403 QCBOREncode_AddTDecimalFractionToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002404}
2405
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002406static inline void
2407QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pMe,
2408 int64_t nLabel,
2409 int64_t nMantissa,
2410 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002411{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002412 QCBOREncode_AddTDecimalFractionToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002413}
2414
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002415
2416
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002417static inline void
2418QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pMe,
2419 uint8_t uTagRequirement,
2420 UsefulBufC Mantissa,
2421 bool bIsNegative,
2422 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002423{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002424 uint64_t uTag;
2425 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2426 uTag = CBOR_TAG_DECIMAL_FRACTION;
2427 } else {
2428 uTag = CBOR_TAG_INVALID64;
2429 }
2430 QCBOREncode_AddExponentAndMantissa(pMe,
2431 uTag,
Michael Eckel5c531332020-03-02 01:35:30 +01002432 Mantissa, bIsNegative,
2433 0,
2434 nBase10Exponent);
2435}
2436
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002437static inline void
2438QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
2439 const char *szLabel,
2440 uint8_t uTagRequirement,
2441 UsefulBufC Mantissa,
2442 bool bIsNegative,
2443 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002444{
2445 QCBOREncode_AddSZString(pMe, szLabel);
2446 QCBOREncode_AddTDecimalFractionBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase10Exponent);
2447}
2448
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002449static inline void
2450QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
2451 int64_t nLabel,
2452 uint8_t uTagRequirement,
2453 UsefulBufC Mantissa,
2454 bool bIsNegative,
2455 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002456{
2457 QCBOREncode_AddInt64(pMe, nLabel);
2458 QCBOREncode_AddTDecimalFractionBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase10Exponent);
2459}
2460
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002461static inline void
2462QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pMe,
2463 UsefulBufC Mantissa,
2464 bool bIsNegative,
2465 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002466{
2467 QCBOREncode_AddTDecimalFractionBigNum(pMe, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase10Exponent);
2468}
2469
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002470static inline void
2471QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
2472 const char *szLabel,
2473 UsefulBufC Mantissa,
2474 bool bIsNegative,
2475 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002476{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002477 QCBOREncode_AddTDecimalFractionBigNumToMapSZ(pMe,
2478 szLabel,
2479 QCBOR_ENCODE_AS_TAG,
2480 Mantissa,
2481 bIsNegative,
2482 nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002483}
2484
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002485static inline void
2486QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
2487 int64_t nLabel,
2488 UsefulBufC Mantissa,
2489 bool bIsNegative,
2490 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002491{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002492 QCBOREncode_AddTDecimalFractionBigNumToMapN(pMe,
2493 nLabel,
2494 QCBOR_ENCODE_AS_TAG,
2495 Mantissa,
2496 bIsNegative,
2497 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002498}
2499
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002500
2501
2502
2503
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002504static inline void
2505QCBOREncode_AddTBigFloat(QCBOREncodeContext *pMe,
2506 uint8_t uTagRequirement,
2507 int64_t nMantissa,
2508 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002509{
2510 uint64_t uTag;
2511 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2512 uTag = CBOR_TAG_BIGFLOAT;
2513 } else {
2514 uTag = CBOR_TAG_INVALID64;
2515 }
2516 QCBOREncode_AddExponentAndMantissa(pMe, uTag, NULLUsefulBufC, false, nMantissa, nBase2Exponent);
2517}
2518
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002519static inline void
2520QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pMe,
2521 const char *szLabel,
2522 uint8_t uTagRequirement,
2523 int64_t nMantissa,
2524 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002525{
2526 QCBOREncode_AddSZString(pMe, szLabel);
2527 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
2528}
2529
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002530static inline void
2531QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pMe,
2532 int64_t nLabel,
2533 uint8_t uTagRequirement,
2534 int64_t nMantissa,
2535 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002536{
2537 QCBOREncode_AddInt64(pMe, nLabel);
2538 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
2539}
2540
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002541static inline void
2542QCBOREncode_AddBigFloat(QCBOREncodeContext *pMe,
2543 int64_t nMantissa,
2544 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002545{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002546 QCBOREncode_AddTBigFloat(pMe, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002547}
2548
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002549static inline void
2550QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pMe,
2551 const char *szLabel,
2552 int64_t nMantissa,
2553 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002554{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002555 QCBOREncode_AddTBigFloatToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002556}
2557
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002558static inline void
2559QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pMe,
2560 int64_t nLabel,
2561 int64_t nMantissa,
2562 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002563{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002564 QCBOREncode_AddTBigFloatToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002565}
2566
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002567
2568
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002569static inline void
2570QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pMe,
2571 uint8_t uTagRequirement,
2572 UsefulBufC Mantissa,
2573 bool bIsNegative,
2574 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002575{
2576 uint64_t uTag;
2577 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2578 uTag = CBOR_TAG_BIGFLOAT;
2579 } else {
2580 uTag = CBOR_TAG_INVALID64;
2581 }
2582 QCBOREncode_AddExponentAndMantissa(pMe, uTag, Mantissa, bIsNegative, 0, nBase2Exponent);
2583}
2584
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002585static inline void
2586QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pMe,
2587 const char *szLabel,
2588 uint8_t uTagRequirement,
2589 UsefulBufC Mantissa,
2590 bool bIsNegative,
2591 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002592{
2593 QCBOREncode_AddSZString(pMe, szLabel);
2594 QCBOREncode_AddTBigFloatBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase2Exponent);
2595}
2596
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002597static inline void
2598QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
2599 int64_t nLabel,
2600 uint8_t uTagRequirement,
2601 UsefulBufC Mantissa,
2602 bool bIsNegative,
2603 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002604{
2605 QCBOREncode_AddInt64(pMe, nLabel);
2606 QCBOREncode_AddTBigFloatBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase2Exponent);
2607}
2608
2609
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002610static inline void
2611QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pMe,
2612 UsefulBufC Mantissa,
2613 bool bIsNegative,
2614 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002615{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002616 QCBOREncode_AddTBigFloatBigNum(pMe, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002617}
2618
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002619static inline void
2620QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pMe,
2621 const char *szLabel,
2622 UsefulBufC Mantissa,
2623 bool bIsNegative,
2624 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002625{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002626 QCBOREncode_AddTBigFloatBigNumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002627}
2628
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002629static inline void
2630QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
2631 int64_t nLabel,
2632 UsefulBufC Mantissa,
2633 bool bIsNegative,
2634 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002635{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002636 QCBOREncode_AddTBigFloatBigNumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002637}
2638#endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
2639
2640
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002641static inline void
2642QCBOREncode_AddTURI(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002643{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002644 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2645 QCBOREncode_AddTag(pMe, CBOR_TAG_URI);
2646 }
2647 QCBOREncode_AddText(pMe, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002648}
2649
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002650static inline void
2651QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002652{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002653 QCBOREncode_AddSZString(pMe, szLabel);
2654 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002655}
2656
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002657static inline void
2658QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002659{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002660 QCBOREncode_AddInt64(pMe, nLabel);
2661 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
2662}
2663
2664static inline void
2665QCBOREncode_AddURI(QCBOREncodeContext *pMe, UsefulBufC URI)
2666{
2667 QCBOREncode_AddTURI(pMe, QCBOR_ENCODE_AS_TAG, URI);
2668}
2669
2670static inline void
2671QCBOREncode_AddURIToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC URI)
2672{
2673 QCBOREncode_AddTURIToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, URI);
2674}
2675
2676static inline void
2677QCBOREncode_AddURIToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC URI)
2678{
2679 QCBOREncode_AddTURIToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002680}
2681
2682
2683
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002684static inline void
2685QCBOREncode_AddTB64Text(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002686{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002687 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2688 QCBOREncode_AddTag(pMe, CBOR_TAG_B64);
2689 }
2690 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002691}
2692
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002693static inline void
2694QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pMe,
2695 const char *szLabel,
2696 uint8_t uTagRequirement,
2697 UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002698{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002699 QCBOREncode_AddSZString(pMe, szLabel);
2700 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002701}
2702
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002703static inline void
2704QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002705{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002706 QCBOREncode_AddInt64(pMe, nLabel);
2707 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
2708}
2709
2710static inline void
2711QCBOREncode_AddB64Text(QCBOREncodeContext *pMe, UsefulBufC B64Text)
2712{
2713 QCBOREncode_AddTB64Text(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
2714}
2715
2716static inline void
2717QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC B64Text)
2718{
2719 QCBOREncode_AddTB64TextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
2720}
2721
2722static inline void
2723QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC B64Text)
2724{
2725 QCBOREncode_AddTB64TextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002726}
2727
2728
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002729
2730static inline void
2731QCBOREncode_AddTB64URLText(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002732{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002733 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2734 QCBOREncode_AddTag(pMe, CBOR_TAG_B64URL);
2735 }
2736 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002737}
2738
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002739static inline void
2740QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pMe,
2741 const char *szLabel,
2742 uint8_t uTagRequirement,
2743 UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002744{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002745 QCBOREncode_AddSZString(pMe, szLabel);
2746 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002747}
2748
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002749static inline void
2750QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002751{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002752 QCBOREncode_AddInt64(pMe, nLabel);
2753 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
2754}
2755
2756static inline void
2757QCBOREncode_AddB64URLText(QCBOREncodeContext *pMe, UsefulBufC B64Text)
2758{
2759 QCBOREncode_AddTB64URLText(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
2760}
2761
2762static inline void
2763QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC B64Text)
2764{
2765 QCBOREncode_AddTB64URLTextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
2766}
2767
2768static inline void
2769QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC B64Text)
2770{
2771 QCBOREncode_AddTB64URLTextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002772}
2773
2774
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002775
2776static inline void
2777QCBOREncode_AddTRegex(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002778{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002779 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2780 QCBOREncode_AddTag(pMe, CBOR_TAG_REGEX);
2781 }
2782 QCBOREncode_AddText(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002783}
2784
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002785static inline void
2786QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002787{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002788 QCBOREncode_AddSZString(pMe, szLabel);
2789 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002790}
2791
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002792static inline void
2793QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002794{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002795 QCBOREncode_AddInt64(pMe, nLabel);
2796 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
2797}
2798
2799static inline void
2800QCBOREncode_AddRegex(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2801{
2802 QCBOREncode_AddTRegex(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2803}
2804
2805static inline void
2806QCBOREncode_AddRegexToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2807{
2808 QCBOREncode_AddTRegexToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2809}
2810
2811static inline void
2812QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2813{
2814 QCBOREncode_AddTRegexToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2815
Michael Eckel5c531332020-03-02 01:35:30 +01002816}
2817
2818
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002819static inline void
2820QCBOREncode_AddTMIMEData(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01002821{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002822 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
Laurence Lundblade4982f412020-09-18 23:02:18 -07002823 QCBOREncode_AddTag(pMe, CBOR_TAG_BINARY_MIME);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002824 }
Laurence Lundblade4982f412020-09-18 23:02:18 -07002825 QCBOREncode_AddBytes(pMe, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01002826}
2827
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002828static inline void
2829QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pMe,
2830 const char *szLabel,
2831 uint8_t uTagRequirement,
2832 UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01002833{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002834 QCBOREncode_AddSZString(pMe, szLabel);
2835 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01002836}
2837
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002838static inline void
2839QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01002840{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002841 QCBOREncode_AddInt64(pMe, nLabel);
2842 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
2843}
2844
2845static inline void
2846QCBOREncode_AddMIMEData(QCBOREncodeContext *pMe, UsefulBufC MIMEData)
2847{
2848 QCBOREncode_AddTMIMEData(pMe, QCBOR_ENCODE_AS_TAG, MIMEData);
2849}
2850
2851static inline void
2852QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC MIMEData)
2853{
2854 QCBOREncode_AddTMIMEDataToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
2855}
2856
2857static inline void
2858QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC MIMEData)
2859{
2860 QCBOREncode_AddTMIMEDataToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01002861}
2862
2863
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002864static inline void
2865QCBOREncode_AddTDateString(QCBOREncodeContext *pMe, uint8_t uTagRequirement, const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002866{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002867 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2868 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_STRING);
2869 }
2870 QCBOREncode_AddSZString(pMe, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002871}
2872
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002873static inline void
2874QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pMe,
2875 const char *szLabel,
2876 uint8_t uTagRequirement,
2877 const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002878{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002879 QCBOREncode_AddSZString(pMe, szLabel);
2880 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002881}
2882
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002883static inline void
2884QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002885{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002886 QCBOREncode_AddInt64(pMe, nLabel);
2887 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
2888}
2889
2890static inline void
2891QCBOREncode_AddDateString(QCBOREncodeContext *pMe, const char *szDate)
2892{
2893 QCBOREncode_AddTDateString(pMe, QCBOR_ENCODE_AS_TAG, szDate);
2894}
2895
2896static inline void
2897QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pMe, const char *szLabel, const char *szDate)
2898{
2899 QCBOREncode_AddTDateStringToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, szDate);
2900}
2901
2902static inline void
2903QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, const char *szDate)
2904{
2905 QCBOREncode_AddTDateStringToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002906}
2907
2908
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002909static inline void
2910QCBOREncode_AddSimple(QCBOREncodeContext *pMe, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002911{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002912 QCBOREncode_AddType7(pMe, 0, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002913}
2914
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002915static inline void
2916QCBOREncode_AddSimpleToMap(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01002917{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002918 QCBOREncode_AddSZString(pMe, szLabel);
2919 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01002920}
2921
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002922static inline void
2923QCBOREncode_AddSimpleToMapN(QCBOREncodeContext *pMe, int nLabel, uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01002924{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002925 QCBOREncode_AddInt64(pMe, nLabel);
2926 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01002927}
2928
2929
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002930static inline void
2931QCBOREncode_AddBool(QCBOREncodeContext *pMe, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01002932{
2933 uint8_t uSimple = CBOR_SIMPLEV_FALSE;
2934 if(b) {
2935 uSimple = CBOR_SIMPLEV_TRUE;
2936 }
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002937 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01002938}
2939
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002940static inline void
2941QCBOREncode_AddBoolToMap(QCBOREncodeContext *pMe, const char *szLabel, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01002942{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002943 QCBOREncode_AddSZString(pMe, szLabel);
2944 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01002945}
2946
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002947static inline void
2948QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pMe, int64_t nLabel, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01002949{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002950 QCBOREncode_AddInt64(pMe, nLabel);
2951 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01002952}
2953
2954
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002955static inline void
2956QCBOREncode_AddNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01002957{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002958 QCBOREncode_AddSimple(pMe, CBOR_SIMPLEV_NULL);
Michael Eckel5c531332020-03-02 01:35:30 +01002959}
2960
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002961static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002962QCBOREncode_AddNULLToMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002963{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002964 QCBOREncode_AddSZString(pMe, szLabel);
2965 QCBOREncode_AddNULL(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01002966}
2967
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002968static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002969QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002970{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002971 QCBOREncode_AddInt64(pMe, nLabel);
2972 QCBOREncode_AddNULL(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01002973}
2974
2975
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002976static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002977QCBOREncode_AddUndef(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01002978{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002979 QCBOREncode_AddSimple(pMe, CBOR_SIMPLEV_UNDEF);
Michael Eckel5c531332020-03-02 01:35:30 +01002980}
2981
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002982static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002983QCBOREncode_AddUndefToMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002984{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002985 QCBOREncode_AddSZString(pMe, szLabel);
2986 QCBOREncode_AddUndef(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01002987}
2988
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002989static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002990QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002991{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002992 QCBOREncode_AddInt64(pMe, nLabel);
2993 QCBOREncode_AddUndef(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01002994}
2995
2996
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002997static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002998QCBOREncode_OpenArray(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01002999{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003000 QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
Michael Eckel5c531332020-03-02 01:35:30 +01003001}
3002
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003003static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003004QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003005{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003006 QCBOREncode_AddSZString(pMe, szLabel);
3007 QCBOREncode_OpenArray(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003008}
3009
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003010static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003011QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003012{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003013 QCBOREncode_AddInt64(pMe, nLabel);
3014 QCBOREncode_OpenArray(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003015}
3016
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003017static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003018QCBOREncode_CloseArray(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003019{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003020 QCBOREncode_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
Michael Eckel5c531332020-03-02 01:35:30 +01003021}
3022
3023
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003024static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003025QCBOREncode_OpenMap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003026{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003027 QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
Michael Eckel5c531332020-03-02 01:35:30 +01003028}
3029
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003030static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003031QCBOREncode_OpenMapInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003032{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003033 QCBOREncode_AddSZString(pMe, szLabel);
3034 QCBOREncode_OpenMap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003035}
3036
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003037static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003038QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003039{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003040 QCBOREncode_AddInt64(pMe, nLabel);
3041 QCBOREncode_OpenMap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003042}
3043
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003044static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003045QCBOREncode_CloseMap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003046{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003047 QCBOREncode_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
Michael Eckel5c531332020-03-02 01:35:30 +01003048}
3049
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003050static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003051QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003052{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003053 QCBOREncode_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003054}
3055
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003056static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003057QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003058{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003059 QCBOREncode_AddSZString(pMe, szLabel);
3060 QCBOREncode_OpenArrayIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003061}
3062
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003063static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003064QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003065{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003066 QCBOREncode_AddInt64(pMe, nLabel);
3067 QCBOREncode_OpenArrayIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003068}
3069
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003070static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003071QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003072{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003073 QCBOREncode_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003074}
3075
3076
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003077static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003078QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003079{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003080 QCBOREncode_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003081}
3082
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003083static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003084QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003085{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003086 QCBOREncode_AddSZString(pMe, szLabel);
3087 QCBOREncode_OpenMapIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003088}
3089
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003090static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003091QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003092{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003093 QCBOREncode_AddInt64(pMe, nLabel);
3094 QCBOREncode_OpenMapIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003095}
3096
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003097static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003098QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003099{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003100 QCBOREncode_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003101}
3102
3103
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003104static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003105QCBOREncode_BstrWrap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003106{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003107 QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_BYTE_STRING);
Michael Eckel5c531332020-03-02 01:35:30 +01003108}
3109
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003110static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003111QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003112{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003113 QCBOREncode_AddSZString(pMe, szLabel);
3114 QCBOREncode_BstrWrap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003115}
3116
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003117static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003118QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003119{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003120 QCBOREncode_AddInt64(pMe, nLabel);
3121 QCBOREncode_BstrWrap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003122}
3123
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003124static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003125QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pMe, UsefulBufC *pWrappedCBOR)
Michael Eckel5c531332020-03-02 01:35:30 +01003126{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003127 QCBOREncode_CloseBstrWrap2(pMe, true, pWrappedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01003128}
3129
3130
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003131static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003132QCBOREncode_AddEncoded(QCBOREncodeContext *pMe, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003133{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003134 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_RAW, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003135}
3136
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003137static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003138QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003139{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003140 QCBOREncode_AddSZString(pMe, szLabel);
3141 QCBOREncode_AddEncoded(pMe, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003142}
3143
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003144static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003145QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003146{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003147 QCBOREncode_AddInt64(pMe, nLabel);
3148 QCBOREncode_AddEncoded(pMe, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003149}
3150
3151
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003152static inline int
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003153QCBOREncode_IsBufferNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003154{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003155 return UsefulOutBuf_IsBufferNULL(&(pMe->OutBuf));
Michael Eckel5c531332020-03-02 01:35:30 +01003156}
3157
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003158static inline QCBORError
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003159QCBOREncode_GetErrorState(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003160{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003161 if(UsefulOutBuf_GetError(&(pMe->OutBuf))) {
Michael Eckel5c531332020-03-02 01:35:30 +01003162 // Items didn't fit in the buffer.
3163 // This check catches this condition for all the appends and inserts
3164 // so checks aren't needed when the appends and inserts are performed.
3165 // And of course UsefulBuf will never overrun the input buffer given
3166 // to it. No complex analysis of the error handling in this file is
3167 // needed to know that is true. Just read the UsefulBuf code.
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003168 pMe->uError = QCBOR_ERR_BUFFER_TOO_SMALL;
Michael Eckel5c531332020-03-02 01:35:30 +01003169 // QCBOR_ERR_BUFFER_TOO_SMALL masks other errors, but that is
3170 // OK. Once the caller fixes this, they'll be unmasked.
3171 }
3172
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003173 return (QCBORError)pMe->uError;
Michael Eckel5c531332020-03-02 01:35:30 +01003174}
3175
3176
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003177/* ========================================================================
3178 END OF PRIVATE INLINE IMPLEMENTATION
3179 ======================================================================== */
Michael Eckel5c531332020-03-02 01:35:30 +01003180
3181#ifdef __cplusplus
3182}
3183#endif
3184
Laurence Lundblade844bb5c2020-03-01 17:27:25 -08003185#endif /* qcbor_encode_h */