blob: ae5027aa77a97212d2599223dc2d06df36053c34 [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
Laurence Lundblade825164e2020-10-22 20:18:06 -0700361/**
Michael Eckel5c531332020-03-02 01:35:30 +0100362 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
Laurence Lundblade825164e2020-10-22 20:18:06 -0700364 head of a CBOR data item because QCBOREncode_EncodeHead() needs
Michael Eckel5c531332020-03-02 01:35:30 +0100365 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 Lundblade825164e2020-10-22 20:18:06 -0700371 Output the full CBOR tag. See @ref CBORTags, @ref Tag-Usage and
372 @ref Tags-Overview.
Laurence Lundblade9b334962020-08-27 10:55:53 -0700373 */
374#define QCBOR_ENCODE_AS_TAG 0
375
376/**
Laurence Lundblade825164e2020-10-22 20:18:06 -0700377 Output only the 'borrowed' content format for the relevant tag.
378 See @ref CBORTags, @ref Tag-Usage and @ref Tags-Overview.
Laurence Lundblade9b334962020-08-27 10:55:53 -0700379 */
380#define QCBOR_ENCODE_AS_BORROWED 1
381
Michael Eckel5c531332020-03-02 01:35:30 +0100382
383/**
384 QCBOREncodeContext is the data type that holds context for all the
385 encoding functions. It is less than 200 bytes, so it can go on the
386 stack. The contents are opaque, and the caller should not access
387 internal members. A context may be re used serially as long as it is
388 re initialized.
389 */
390typedef struct _QCBOREncodeContext QCBOREncodeContext;
391
392
393/**
394 Initialize the encoder to prepare to encode some CBOR.
395
396 @param[in,out] pCtx The encoder context to initialize.
397 @param[in] Storage The buffer into which this encoded result
398 will be placed.
399
400 Call this once at the start of an encoding of a CBOR structure. Then
401 call the various @c QCBOREncode_AddXxx() functions to add the data
402 items. Then call QCBOREncode_Finish().
403
404 The maximum output buffer is @c UINT32_MAX (4GB). This is not a
405 practical limit in any way and reduces the memory needed by the
406 implementation. The error @ref QCBOR_ERR_BUFFER_TOO_LARGE will be
407 returned by QCBOREncode_Finish() if a larger buffer length is passed
408 in.
409
410 If this is called with @c Storage.ptr as @c NULL and @c Storage.len a
411 large value like @c UINT32_MAX, all the QCBOREncode_AddXxx()
412 functions and QCBOREncode_Finish() can still be called. No data will
413 be encoded, but the length of what would be encoded will be
414 calculated. The length of the encoded structure will be handed back
415 in the call to QCBOREncode_Finish(). You can then allocate a buffer
416 of that size and call all the encoding again, this time to fill in
417 the buffer.
418
419 A @ref QCBOREncodeContext can be reused over and over as long as
420 QCBOREncode_Init() is called.
421 */
422void QCBOREncode_Init(QCBOREncodeContext *pCtx, UsefulBuf Storage);
423
424
425/**
426 @brief Add a signed 64-bit integer to the encoded output.
427
428 @param[in] pCtx The encoding context to add the integer to.
429 @param[in] nNum The integer to add.
430
431 The integer will be encoded and added to the CBOR output.
432
433 This function figures out the size and the sign and encodes in the
434 correct minimal CBOR. Specifically, it will select CBOR major type 0
435 or 1 based on sign and will encode to 1, 2, 4 or 8 bytes depending on
436 the value of the integer. Values less than 24 effectively encode to
437 one byte because they are encoded in with the CBOR major type. This
438 is a neat and efficient characteristic of CBOR that can be taken
439 advantage of when designing CBOR-based protocols. If integers like
440 tags can be kept between -23 and 23 they will be encoded in one byte
441 including the major type.
442
443 If you pass a smaller int, say an @c int16_t or a small value, say
444 100, the encoding will still be CBOR's most compact that can
445 represent the value. For example, CBOR always encodes the value 0 as
446 one byte, 0x00. The representation as 0x00 includes identification of
447 the type as an integer too as the major type for an integer is 0. See
448 [RFC 7049] (https://tools.ietf.org/html/rfc7049) Appendix A for more
449 examples of CBOR encoding. This compact encoding is also canonical
450 CBOR as per section 3.9 in RFC 7049.
451
452 There are no functions to add @c int16_t or @c int32_t because they
453 are not necessary because this always encodes to the smallest number
454 of bytes based on the value (If this code is running on a 32-bit
455 machine having a way to add 32-bit integers would reduce code size
456 some).
457
458 If the encoding context is in an error state, this will do
459 nothing. If an error occurs when adding this integer, the internal
460 error flag will be set, and the error will be returned when
461 QCBOREncode_Finish() is called.
462
463 See also QCBOREncode_AddUInt64().
464 */
465void QCBOREncode_AddInt64(QCBOREncodeContext *pCtx, int64_t nNum);
466
467static void QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum);
468
469static void QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum);
470
471
472/**
473 @brief Add an unsigned 64-bit integer to the encoded output.
474
475 @param[in] pCtx The encoding context to add the integer to.
476 @param[in] uNum The integer to add.
477
478 The integer will be encoded and added to the CBOR output.
479
480 The only reason so use this function is for integers larger than @c
481 INT64_MAX and smaller than @c UINT64_MAX. Otherwise
482 QCBOREncode_AddInt64() will work fine.
483
484 Error handling is the same as for QCBOREncode_AddInt64().
485 */
486void QCBOREncode_AddUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
487
488static void QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum);
489
490static void QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum);
491
492
493/**
494 @brief Add a UTF-8 text string to the encoded output.
495
496 @param[in] pCtx The encoding context to add the text to.
497 @param[in] Text Pointer and length of text to add.
498
499 The text passed in must be unencoded UTF-8 according to [RFC 3629]
500 (https://tools.ietf.org/html/rfc3629). There is no NULL
501 termination. The text is added as CBOR major type 3.
502
503 If called with @c nBytesLen equal to 0, an empty string will be
504 added. When @c nBytesLen is 0, @c pBytes may be @c NULL.
505
506 Note that the restriction of the buffer length to a @c uint32_t is
507 entirely intentional as this encoder is not capable of encoding
508 lengths greater. This limit to 4GB for a text string should not be a
509 problem.
510
Laurence Lundbladeadaf5c22020-09-25 10:37:09 -0700511 Text lines in Internet protocols (on the wire) are delimited by
512 either a CRLF or just an LF. Officially many protocols specify CRLF,
513 but implementations often work with either. CBOR type 3 text can be
514 either line ending, even a mixture of both.
515
516 Operating systems usually have a line end convention. Windows uses
517 CRLF. Linux and MacOS use LF. Some applications on a given OS may
518 work with either and some may not.
519
520 The majority of use cases and CBOR protocols using type 3 text will
521 work with either line ending. However, some use cases or protocols
522 may not work with either in which case translation to and/or from the
523 local line end convention, typically that of the OS, is necessary.
524
525 QCBOR does no line ending translation for type 3 text when encoding
526 and decoding.
527
Michael Eckel5c531332020-03-02 01:35:30 +0100528 Error handling is the same as QCBOREncode_AddInt64().
529 */
530static void QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text);
531
532static void QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text);
533
534static void QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text);
535
536
537/**
538 @brief Add a UTF-8 text string to the encoded output.
539
540 @param[in] pCtx The encoding context to add the text to.
541 @param[in] szString Null-terminated text to add.
542
543 This works the same as QCBOREncode_AddText().
544 */
545static void QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString);
546
547static void QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString);
548
549static void QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString);
550
551
552/**
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700553 @brief Add a double-precision floating-point number to the encoded output.
Michael Eckel5c531332020-03-02 01:35:30 +0100554
555 @param[in] pCtx The encoding context to add the double to.
556 @param[in] dNum The double-precision number to add.
557
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700558 This encodes and outputs a floating-point number. CBOR major type 7
559 is used.
Michael Eckel5c531332020-03-02 01:35:30 +0100560
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700561 This implements preferred serialization, selectively encoding the
562 double-precision floating-point number as either double-precision,
563 single-precision or half-precision. Infinity, NaN and 0 are always
564 encoded as half-precision. If no precision will be lost in the
565 conversion to half-precision, then it will be converted and
566 encoded. If not and no precision will be lost in conversion to
567 single-precision, then it will be converted and encoded. If not, then
568 no conversion is performed, and it encoded as a double-precision.
Michael Eckel5c531332020-03-02 01:35:30 +0100569
570 Half-precision floating-point numbers take up 2 bytes, half that of
571 single-precision, one quarter of double-precision
572
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700573 This automatically reduces the size of encoded CBOR, maybe even by
574 four if most of values are 0, infinity or NaN.
Michael Eckel5c531332020-03-02 01:35:30 +0100575
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700576 When decoded, QCBOR will usually return these values as
577 double-precision.
578
579 It is possible to disable this preferred serialization when compiling
580 QCBOR. In that case, this functions the same as
581 QCBOREncode_AddDoubleNoPreferred().
Michael Eckel5c531332020-03-02 01:35:30 +0100582
583 Error handling is the same as QCBOREncode_AddInt64().
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700584
585 See also QCBOREncode_AddDoubleNoPreferred(), QCBOREncode_AddFloat()
586 and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
Michael Eckel5c531332020-03-02 01:35:30 +0100587 */
588void QCBOREncode_AddDouble(QCBOREncodeContext *pCtx, double dNum);
589
590static void QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
591
592static void QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
593
594
595/**
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700596 @brief Add a single-precision floating-point number to the encoded output.
597
598 @param[in] pCtx The encoding context to add the double to.
599 @param[in] fNum The single-precision number to add.
600
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700601 This is identical to QCBOREncode_AddDouble() except the input is
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700602 single-precision.
603
604 See also QCBOREncode_AddDouble(), QCBOREncode_AddDoubleNoPreferred(),
605 and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
606*/
607void QCBOREncode_AddFloat(QCBOREncodeContext *pCtx, float fNum);
608
609static void QCBOREncode_AddFloatToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
610
611static void QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700612
613
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700614/**
615 @brief Add a double-precision floating-point number without preferred encoding.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700616
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700617 @param[in] pCtx The encoding context to add the double to.
618 @param[in] dNum The double-precision number to add.
619
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700620 This always outputs the number as a 64-bit double-precision.
621 Preferred serialization is not used.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700622
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700623 Error handling is the same as QCBOREncode_AddInt64().
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700624
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700625 See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
626 QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700627*/
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700628void QCBOREncode_AddDoubleNoPreferred(QCBOREncodeContext *pCtx, double dNum);
629
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700630static void QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
631
632static void QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
633
634
635/**
636 @brief Add a single-precision floating-point number without preferred encoding.
637
638 @param[in] pCtx The encoding context to add the double to.
639 @param[in] fNum The single-precision number to add.
640
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700641 This always outputs the number as a 32-bit single-precision.
642 Preferred serialization is not used.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700643
644 Error handling is the same as QCBOREncode_AddInt64().
645
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700646 See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
647 QCBOREncode_AddDoubleNoPreferred() and @ref Floating-Point.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700648*/
649void QCBOREncode_AddFloatNoPreferred(QCBOREncodeContext *pCtx, float fNum);
650
651static void QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
652
653static void QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float fNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700654
655
Michael Eckel5c531332020-03-02 01:35:30 +0100656/**
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
Michael Eckel5c531332020-03-02 01:35:30 +0100759/**
760 @brief Add a binary UUID to the encoded output.
761
762 @param[in] pCtx The encoding context to add the UUID to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700763 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100764 @param[in] Bytes Pointer and length of the binary UUID.
765
766 A binary UUID as defined in [RFC 4122]
767 (https://tools.ietf.org/html/rfc4122) is added to the output.
768
769 It is output as CBOR major type 2, a binary string, with tag @ref
770 CBOR_TAG_BIN_UUID indicating the binary string is a UUID.
771 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700772static void QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pCtx,
773 uint8_t uTagRequirement,
774 UsefulBufC Bytes);
775
776static void QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pCtx,
777 const char *szLabel,
778 uint8_t uTagRequirement,
779 UsefulBufC Bytes);
780
781static void QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pCtx,
782 int64_t nLabel,
783 uint8_t uTagRequirement,
784 UsefulBufC Bytes);
785
786
Michael Eckel5c531332020-03-02 01:35:30 +0100787static void QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
788
789static void QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
790
791static void QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
792
793
794/**
795 @brief Add a positive big number to the encoded output.
796
797 @param[in] pCtx The encoding context to add the big number to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700798 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100799 @param[in] Bytes Pointer and length of the big number.
800
801 Big numbers are integers larger than 64-bits. Their format is
802 described in [RFC 7049] (https://tools.ietf.org/html/rfc7049).
803
804 It is output as CBOR major type 2, a binary string, with tag @ref
805 CBOR_TAG_POS_BIGNUM indicating the binary string is a positive big
806 number.
807
808 Often big numbers are used to represent cryptographic keys, however,
809 COSE which defines representations for keys chose not to use this
810 particular type.
811 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700812static void QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pCtx,
813 uint8_t uTagRequirement,
814 UsefulBufC Bytes);
815
816static void QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pCtx,
817 const char *szLabel,
818 uint8_t uTagRequirement,
819 UsefulBufC Bytes);
820
821static void QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pCtx,
822 int64_t nLabel,
823 uint8_t uTagRequirement,
824 UsefulBufC Bytes);
825
826
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700827static void QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx,
828 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100829
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700830static void QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx,
831 const char *szLabel,
832 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100833
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700834static void QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx,
835 int64_t nLabel,
836 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100837
838
839/**
840 @brief Add a negative big number to the encoded output.
841
842 @param[in] pCtx The encoding context to add the big number to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700843 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100844 @param[in] Bytes Pointer and length of the big number.
845
846 Big numbers are integers larger than 64-bits. Their format is
847 described in [RFC 7049] (https://tools.ietf.org/html/rfc7049).
848
849 It is output as CBOR major type 2, a binary string, with tag @ref
850 CBOR_TAG_NEG_BIGNUM indicating the binary string is a negative big
851 number.
852
853 Often big numbers are used to represent cryptographic keys, however,
854 COSE which defines representations for keys chose not to use this
855 particular type.
856 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700857static void QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pCtx,
858 uint8_t uTagRequirement,
859 UsefulBufC Bytes);
860
861static void QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pCtx,
862 const char *szLabel,
863 uint8_t uTagRequirement,
864 UsefulBufC Bytes);
865
866static void QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pCtx,
867 int64_t nLabel,
868 uint8_t uTagRequirement,
869 UsefulBufC Bytes);
870
871
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700872static void QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx,
873 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100874
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700875static void QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx,
876 const char *szLabel,
877 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100878
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700879static void QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx,
880 int64_t nLabel,
881 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100882
883
884#ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
885/**
886 @brief Add a decimal fraction to the encoded output.
887
888 @param[in] pCtx The encoding context to add the decimal fraction to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700889 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100890 @param[in] nMantissa The mantissa.
891 @param[in] nBase10Exponent The exponent.
892
893 The value is nMantissa * 10 ^ nBase10Exponent.
894
895 A decimal fraction is good for exact representation of some values
896 that can't be represented exactly with standard C (IEEE 754)
897 floating-point numbers. Much larger and much smaller numbers can
898 also be represented than floating-point because of the larger number
899 of bits in the exponent.
900
901 The decimal fraction is conveyed as two integers, a mantissa and a
902 base-10 scaling factor.
903
904 For example, 273.15 is represented by the two integers 27315 and -2.
905
906 The exponent and mantissa have the range from @c INT64_MIN to
907 @c INT64_MAX for both encoding and decoding (CBOR allows @c -UINT64_MAX
908 to @c UINT64_MAX, but this implementation doesn't support this range to
909 reduce code size and interface complexity a little).
910
911 CBOR Preferred encoding of the integers is used, thus they will be encoded
912 in the smallest number of bytes possible.
913
914 See also QCBOREncode_AddDecimalFractionBigNum() for a decimal
915 fraction with arbitrarily large precision and QCBOREncode_AddBigFloat().
916
917 There is no representation of positive or negative infinity or NaN
918 (Not a Number). Use QCBOREncode_AddDouble() to encode them.
919
920 See @ref expAndMantissa for decoded representation.
921 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700922static void QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pCtx,
923 uint8_t uTagRequirement,
924 int64_t nMantissa,
925 int64_t nBase10Exponent);
926
927static void QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -0700928 const char *szLabel,
929 uint8_t uTagRequirement,
930 int64_t nMantissa,
931 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700932
933static void QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pCtx,
934 int64_t nLabel,
935 uint8_t uTagRequirement,
936 int64_t nMantissa,
937 int64_t nBase10Exponent);
938
939
Michael Eckel5c531332020-03-02 01:35:30 +0100940static void QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pCtx,
941 int64_t nMantissa,
942 int64_t nBase10Exponent);
943
944static void QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pCtx,
945 const char *szLabel,
946 int64_t nMantissa,
947 int64_t nBase10Exponent);
948
949static void QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pCtx,
950 int64_t nLabel,
951 int64_t nMantissa,
952 int64_t nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +0100953/**
954 @brief Add a decimal fraction with a big number mantissa to the encoded output.
955
956 @param[in] pCtx The encoding context to add the decimal fraction to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700957 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100958 @param[in] Mantissa The mantissa.
959 @param[in] bIsNegative false if mantissa is positive, true if negative.
960 @param[in] nBase10Exponent The exponent.
961
962 This is the same as QCBOREncode_AddDecimalFraction() except the
963 mantissa is a big number (See QCBOREncode_AddPositiveBignum())
964 allowing for arbitrarily large precision.
965
966 See @ref expAndMantissa for decoded representation.
967 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700968static void QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pCtx,
969 uint8_t uTagRequirement,
970 UsefulBufC Mantissa,
971 bool bIsNegative,
972 int64_t nBase10Exponent);
973
974static void QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -0700975 const char *szLabel,
976 uint8_t uTagRequirement,
977 UsefulBufC Mantissa,
978 bool bIsNegative,
979 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700980
981static void QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
982 int64_t nLabel,
983 uint8_t uTagRequirement,
984 UsefulBufC Mantissa,
985 bool bIsNegative,
986 int64_t nBase10Exponent);
987
988
Michael Eckel5c531332020-03-02 01:35:30 +0100989static void QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pCtx,
990 UsefulBufC Mantissa,
991 bool bIsNegative,
992 int64_t nBase10Exponent);
993
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700994static void QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -0700995 const char *szLabel,
996 UsefulBufC Mantissa,
997 bool bIsNegative,
998 int64_t nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +0100999
1000static void QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
1001 int64_t nLabel,
1002 UsefulBufC Mantissa,
1003 bool bIsNegative,
1004 int64_t nBase10Exponent);
1005
1006/**
1007 @brief Add a big floating-point number to the encoded output.
1008
1009 @param[in] pCtx The encoding context to add the bigfloat to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001010 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001011 @param[in] nMantissa The mantissa.
1012 @param[in] nBase2Exponent The exponent.
1013
1014 The value is nMantissa * 2 ^ nBase2Exponent.
1015
1016 "Bigfloats", as CBOR terms them, are similar to IEEE floating-point
1017 numbers in having a mantissa and base-2 exponent, but they are not
1018 supported by hardware or encoded the same. They explicitly use two
1019 CBOR-encoded integers to convey the mantissa and exponent, each of which
1020 can be 8, 16, 32 or 64 bits. With both the mantissa and exponent
1021 64 bits they can express more precision and a larger range than an
1022 IEEE double floating-point number. See
1023 QCBOREncode_AddBigFloatBigNum() for even more precision.
1024
1025 For example, 1.5 would be represented by a mantissa of 3 and an
1026 exponent of -1.
1027
1028 The exponent and mantissa have the range from @c INT64_MIN to
1029 @c INT64_MAX for both encoding and decoding (CBOR allows @c -UINT64_MAX
1030 to @c UINT64_MAX, but this implementation doesn't support this range to
1031 reduce code size and interface complexity a little).
1032
1033 CBOR Preferred encoding of the integers is used, thus they will be encoded
1034 in the smallest number of bytes possible.
1035
1036 This can also be used to represent floating-point numbers in
1037 environments that don't support IEEE 754.
1038
1039 See @ref expAndMantissa for decoded representation.
1040 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001041static void QCBOREncode_AddTBigFloat(QCBOREncodeContext *pCtx,
1042 uint8_t uTagRequirement,
1043 int64_t nMantissa,
1044 int64_t nBase2Exponent);
1045
1046static void QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001047 const char *szLabel,
1048 uint8_t uTagRequirement,
1049 int64_t nMantissa,
1050 int64_t nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001051
1052static void QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pCtx,
1053 int64_t nLabel,
1054 uint8_t uTagRequirement,
1055 int64_t nMantissa,
1056 int64_t nBase2Exponent);
1057
1058
Michael Eckel5c531332020-03-02 01:35:30 +01001059static void QCBOREncode_AddBigFloat(QCBOREncodeContext *pCtx,
1060 int64_t nMantissa,
1061 int64_t nBase2Exponent);
1062
1063static void QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pCtx,
1064 const char *szLabel,
1065 int64_t nMantissa,
1066 int64_t nBase2Exponent);
1067
1068static void QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pCtx,
1069 int64_t nLabel,
1070 int64_t nMantissa,
1071 int64_t nBase2Exponent);
1072
Michael Eckel5c531332020-03-02 01:35:30 +01001073/**
1074 @brief Add a big floating-point number with a big number mantissa to
1075 the encoded output.
1076
1077 @param[in] pCtx The encoding context to add the bigfloat to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001078 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001079 @param[in] Mantissa The mantissa.
1080 @param[in] bIsNegative false if mantissa is positive, true if negative.
1081 @param[in] nBase2Exponent The exponent.
1082
1083 This is the same as QCBOREncode_AddBigFloat() except the mantissa is
1084 a big number (See QCBOREncode_AddPositiveBignum()) allowing for
1085 arbitrary precision.
1086
1087 See @ref expAndMantissa for decoded representation.
1088 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001089static void QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pCtx,
1090 uint8_t uTagRequirement,
1091 UsefulBufC Mantissa,
1092 bool bIsNegative,
1093 int64_t nBase2Exponent);
1094
1095static void QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001096 const char *szLabel,
1097 uint8_t uTagRequirement,
1098 UsefulBufC Mantissa,
1099 bool bIsNegative,
1100 int64_t nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001101
1102static void QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1103 int64_t nLabel,
1104 uint8_t uTagRequirement,
1105 UsefulBufC Mantissa,
1106 bool bIsNegative,
1107 int64_t nBase2Exponent);
1108
1109
Michael Eckel5c531332020-03-02 01:35:30 +01001110static void QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pCtx,
1111 UsefulBufC Mantissa,
1112 bool bIsNegative,
1113 int64_t nBase2Exponent);
1114
1115static void QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pCtx,
1116 const char *szLabel,
1117 UsefulBufC Mantissa,
1118 bool bIsNegative,
1119 int64_t nBase2Exponent);
1120
1121static void QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1122 int64_t nLabel,
1123 UsefulBufC Mantissa,
1124 bool bIsNegative,
1125 int64_t nBase2Exponent);
1126#endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
1127
1128
1129/**
1130 @brief Add a text URI to the encoded output.
1131
1132 @param[in] pCtx The encoding context to add the URI to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001133 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001134 @param[in] URI Pointer and length of the URI.
1135
1136 The format of URI must be per [RFC 3986]
1137 (https://tools.ietf.org/html/rfc3986).
1138
1139 It is output as CBOR major type 3, a text string, with tag @ref
1140 CBOR_TAG_URI indicating the text string is a URI.
1141
1142 A URI in a NULL-terminated string, @c szURI, can be easily added with
1143 this code:
1144
1145 QCBOREncode_AddURI(pCtx, UsefulBuf_FromSZ(szURI));
1146 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001147static void QCBOREncode_AddTURI(QCBOREncodeContext *pCtx,
1148 uint8_t uTagRequirement,
1149 UsefulBufC URI);
1150
1151static void QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pCtx,
1152 const char *szLabel,
1153 uint8_t uTagRequirement,
1154 UsefulBufC URI);
1155
1156static void QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pCtx,
1157 int64_t nLabel,
1158 uint8_t uTagRequirement,
1159 UsefulBufC URI);
1160
1161
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001162static void QCBOREncode_AddURI(QCBOREncodeContext *pCtx,
1163 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001164
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001165static void QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx,
1166 const char *szLabel,
1167 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001168
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001169static void QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx,
1170 int64_t nLabel,
1171 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001172
1173
1174/**
1175 @brief Add Base64-encoded text to encoded output.
1176
1177 @param[in] pCtx The encoding context to add the base-64 text to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001178 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001179 @param[in] B64Text Pointer and length of the base-64 encoded text.
1180
1181 The text content is Base64 encoded data per [RFC 4648]
1182 (https://tools.ietf.org/html/rfc4648).
1183
1184 It is output as CBOR major type 3, a text string, with tag @ref
1185 CBOR_TAG_B64 indicating the text string is Base64 encoded.
1186 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001187static void QCBOREncode_AddTB64Text(QCBOREncodeContext *pCtx,
1188 uint8_t uTagRequirement,
1189 UsefulBufC B64Text);
1190
1191static void QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pCtx,
1192 const char *szLabel,
1193 uint8_t uTagRequirement,
1194 UsefulBufC B64Text);
1195
1196static void QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pCtx,
1197 int64_t nLabel,
1198 uint8_t uTagRequirement,
1199 UsefulBufC B64Text);
1200
1201
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001202static void QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx,
1203 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001204
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001205static void QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx,
1206 const char *szLabel,
1207 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001208
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001209static void QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx,
1210 int64_t nLabel,
1211 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001212
1213
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001214
Michael Eckel5c531332020-03-02 01:35:30 +01001215/**
1216 @brief Add base64url encoded data to encoded output.
1217
1218 @param[in] pCtx The encoding context to add the base64url to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001219 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001220 @param[in] B64Text Pointer and length of the base64url encoded text.
1221
1222 The text content is base64URL encoded text as per [RFC 4648]
1223 (https://tools.ietf.org/html/rfc4648).
1224
1225 It is output as CBOR major type 3, a text string, with tag @ref
1226 CBOR_TAG_B64URL indicating the text string is a Base64url encoded.
1227 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001228static void QCBOREncode_AddTB64URLText(QCBOREncodeContext *pCtx,
1229 uint8_t uTagRequirement,
1230 UsefulBufC B64Text);
1231
1232static void QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pCtx,
1233 const char *szLabel,
1234 uint8_t uTagRequirement,
1235 UsefulBufC B64Text);
1236
1237static void QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pCtx,
1238 int64_t nLabel,
1239 uint8_t uTagRequirement,
1240 UsefulBufC B64Text);
1241
1242
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001243static void QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx,
1244 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001245
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001246static void QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx,
1247 const char *szLabel,
1248 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001249
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001250static void QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx,
1251 int64_t nLabel,
1252 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001253
1254
1255/**
1256 @brief Add Perl Compatible Regular Expression.
1257
1258 @param[in] pCtx The encoding context to add the regular expression to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001259 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001260 @param[in] Regex Pointer and length of the regular expression.
1261
1262 The text content is Perl Compatible Regular
1263 Expressions (PCRE) / JavaScript syntax [ECMA262].
1264
1265 It is output as CBOR major type 3, a text string, with tag @ref
1266 CBOR_TAG_REGEX indicating the text string is a regular expression.
1267 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001268static void QCBOREncode_AddTRegex(QCBOREncodeContext *pCtx,
1269 uint8_t uTagRequirement,
1270 UsefulBufC Regex);
1271
1272static void QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pCtx,
1273 const char *szLabel,
1274 uint8_t uTagRequirement,
1275 UsefulBufC Regex);
1276
1277static void QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pCtx,
1278 int64_t nLabel,
1279 uint8_t uTagRequirement,
1280 UsefulBufC Regex);
1281
1282
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001283static void QCBOREncode_AddRegex(QCBOREncodeContext *pCtx,
1284 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001285
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001286static void QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx,
1287 const char *szLabel,
1288 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001289
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001290static void QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx,
1291 int64_t nLabel,
1292 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001293
1294
1295/**
Laurence Lundblade4982f412020-09-18 23:02:18 -07001296 @brief MIME encoded data to the encoded output.
Michael Eckel5c531332020-03-02 01:35:30 +01001297
Laurence Lundblade4982f412020-09-18 23:02:18 -07001298 @param[in] pCtx The encoding context to add the MIME data to.
1299 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1300 @ref QCBOR_ENCODE_AS_BORROWED.
1301 @param[in] MIMEData Pointer and length of the MIME data.
Michael Eckel5c531332020-03-02 01:35:30 +01001302
1303 The text content is in MIME format per [RFC 2045]
Laurence Lundblade4982f412020-09-18 23:02:18 -07001304 (https://tools.ietf.org/html/rfc2045) including the headers.
Michael Eckel5c531332020-03-02 01:35:30 +01001305
Laurence Lundblade4982f412020-09-18 23:02:18 -07001306 It is output as CBOR major type 2, a binary string, with tag @ref
1307 CBOR_TAG_BINARY_MIME indicating the string is MIME data. This
1308 outputs tag 257, not tag 36, as it can carry any type of MIME binary,
1309 7-bit, 8-bit, quoted-printable and base64 where tag 36 cannot.
1310
1311 Previous versions of QCBOR, those before spiffy decode, output tag
1312 36. Decoding supports both tag 36 and 257. (if the old behavior with
1313 tag 36 is needed, copy the inline functions below and change the tag
1314 number).
1315
1316 See also QCBORDecode_GetMIMEMessage() and
1317 @ref QCBOR_TYPE_BINARY_MIME.
Laurence Lundbladeadaf5c22020-09-25 10:37:09 -07001318
1319 This does no translation of line endings. See QCBOREncode_AddText()
1320 for a discussion of line endings in CBOR.
Michael Eckel5c531332020-03-02 01:35:30 +01001321 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001322static void QCBOREncode_AddTMIMEData(QCBOREncodeContext *pCtx,
1323 uint8_t uTagRequirement,
1324 UsefulBufC MIMEData);
1325
1326static void QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pCtx,
1327 const char *szLabel,
1328 uint8_t uTagRequirement,
1329 UsefulBufC MIMEData);
1330
1331static void QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pCtx,
1332 int64_t nLabel,
1333 uint8_t uTagRequirement,
1334 UsefulBufC MIMEData);
1335
1336
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001337static void QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx,
1338 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001339
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001340static void QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx,
1341 const char *szLabel,
1342 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001343
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001344static void QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx,
1345 int64_t nLabel,
1346 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001347
1348
1349/**
1350 @brief Add an RFC 3339 date string
1351
1352 @param[in] pCtx The encoding context to add the date to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001353 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001354 @param[in] szDate Null-terminated string with date to add.
1355
1356 The string szDate should be in the form of [RFC 3339]
1357 (https://tools.ietf.org/html/rfc3339) as defined by section 3.3 in
1358 [RFC 4287] (https://tools.ietf.org/html/rfc4287). This is as
1359 described in section 2.4.1 in [RFC 7049]
1360 (https://tools.ietf.org/html/rfc7049).
1361
1362 Note that this function doesn't validate the format of the date string
1363 at all. If you add an incorrect format date string, the generated
1364 CBOR will be incorrect and the receiver may not be able to handle it.
1365
1366 Error handling is the same as QCBOREncode_AddInt64().
1367 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001368static void QCBOREncode_AddTDateString(QCBOREncodeContext *pCtx,
1369 uint8_t uTagRequirement,
1370 const char *szDate);
1371
1372static void QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pCtx,
1373 const char *szLabel,
1374 uint8_t uTagRequirement,
1375 const char *szDate);
1376
1377static void QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pCtx,
1378 int64_t nLabel,
1379 uint8_t uTagRequirement,
1380 const char *szDate);
1381
1382
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001383static void QCBOREncode_AddDateString(QCBOREncodeContext *pCtx,
1384 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001385
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001386static void QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx,
1387 const char *szLabel,
1388 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001389
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001390static void QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx,
1391 int64_t nLabel,
1392 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001393
Michael Eckel5c531332020-03-02 01:35:30 +01001394/**
1395 @brief Add a standard Boolean.
1396
1397 @param[in] pCtx The encoding context to add the Boolean to.
1398 @param[in] b true or false from @c <stdbool.h>.
1399
1400 Adds a Boolean value as CBOR major type 7.
1401
1402 Error handling is the same as QCBOREncode_AddInt64().
1403 */
1404static void QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b);
1405
1406static void QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b);
1407
1408static void QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b);
1409
1410
1411
1412/**
1413 @brief Add a NULL to the encoded output.
1414
1415 @param[in] pCtx The encoding context to add the NULL to.
1416
1417 Adds the NULL value as CBOR major type 7.
1418
1419 This NULL doesn't have any special meaning in CBOR such as a
1420 terminating value for a string or an empty value.
1421
1422 Error handling is the same as QCBOREncode_AddInt64().
1423 */
1424static void QCBOREncode_AddNULL(QCBOREncodeContext *pCtx);
1425
1426static void QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1427
1428static void QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1429
1430
1431/**
1432 @brief Add an "undef" to the encoded output.
1433
1434 @param[in] pCtx The encoding context to add the "undef" to.
1435
1436 Adds the undef value as CBOR major type 7.
1437
1438 Note that this value will not translate to JSON.
1439
1440 This Undef doesn't have any special meaning in CBOR such as a
1441 terminating value for a string or an empty value.
1442
1443 Error handling is the same as QCBOREncode_AddInt64().
1444 */
1445static void QCBOREncode_AddUndef(QCBOREncodeContext *pCtx);
1446
1447static void QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1448
1449static void QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1450
1451
1452/**
1453 @brief Indicates that the next items added are in an array.
1454
1455 @param[in] pCtx The encoding context to open the array in.
1456
1457 Arrays are the basic CBOR aggregate or structure type. Call this
1458 function to start or open an array. Then call the various @c
1459 QCBOREncode_AddXxx() functions to add the items that go into the
1460 array. Then call QCBOREncode_CloseArray() when all items have been
1461 added. The data items in the array can be of any type and can be of
1462 mixed types.
1463
1464 Nesting of arrays and maps is allowed and supported just by calling
1465 QCBOREncode_OpenArray() again before calling
1466 QCBOREncode_CloseArray(). While CBOR has no limit on nesting, this
1467 implementation does in order to keep it smaller and simpler. The
1468 limit is @ref QCBOR_MAX_ARRAY_NESTING. This is the max number of
1469 times this can be called without calling
1470 QCBOREncode_CloseArray(). QCBOREncode_Finish() will return @ref
1471 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP when it is called as this function
1472 just sets an error state and returns no value when this occurs.
1473
1474 If you try to add more than @ref QCBOR_MAX_ITEMS_IN_ARRAY items to a
1475 single array or map, @ref QCBOR_ERR_ARRAY_TOO_LONG will be returned
1476 when QCBOREncode_Finish() is called.
1477
1478 An array itself must have a label if it is being added to a map.
1479 Note that array elements do not have labels (but map elements do).
1480
1481 An array itself may be tagged by calling QCBOREncode_AddTag() before this call.
1482 */
1483static void QCBOREncode_OpenArray(QCBOREncodeContext *pCtx);
1484
1485static void QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1486
1487static void QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1488
1489
1490/**
1491 @brief Close an open array.
1492
1493 @param[in] pCtx The encoding context to close the array in.
1494
1495 The closes an array opened by QCBOREncode_OpenArray(). It reduces
1496 nesting level by one. All arrays (and maps) must be closed before
1497 calling QCBOREncode_Finish().
1498
1499 When an error occurs as a result of this call, the encoder records
1500 the error and enters the error state. The error will be returned when
1501 QCBOREncode_Finish() is called.
1502
1503 If this has been called more times than QCBOREncode_OpenArray(), then
1504 @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when QCBOREncode_Finish()
1505 is called.
1506
1507 If this is called and it is not an array that is currently open, @ref
1508 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
1509 is called.
1510 */
1511static void QCBOREncode_CloseArray(QCBOREncodeContext *pCtx);
1512
1513
1514/**
1515 @brief Indicates that the next items added are in a map.
1516
1517 @param[in] pCtx The encoding context to open the map in.
1518
1519 See QCBOREncode_OpenArray() for more information, particularly error
1520 handling.
1521
1522 CBOR maps are an aggregate type where each item in the map consists
1523 of a label and a value. They are similar to JSON objects.
1524
1525 The value can be any CBOR type including another map.
1526
1527 The label can also be any CBOR type, but in practice they are
1528 typically, integers as this gives the most compact output. They might
1529 also be text strings which gives readability and translation to JSON.
1530
1531 Every @c QCBOREncode_AddXxx() call has one version that ends with @c
1532 InMap for adding items to maps with string labels and one that ends
1533 with @c InMapN that is for adding with integer labels.
1534
1535 RFC 7049 uses the term "key" instead of "label".
1536
1537 If you wish to use map labels that are neither integer labels nor
1538 text strings, then just call the QCBOREncode_AddXxx() function
1539 explicitly to add the label. Then call it again to add the value.
1540
1541 See the [RFC 7049] (https://tools.ietf.org/html/rfc7049) for a lot
1542 more information on creating maps.
1543 */
1544static void QCBOREncode_OpenMap(QCBOREncodeContext *pCtx);
1545
1546static void QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1547
1548static void QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1549
1550
Michael Eckel5c531332020-03-02 01:35:30 +01001551/**
1552 @brief Close an open map.
1553
1554 @param[in] pCtx The encoding context to close the map in .
1555
1556 This closes a map opened by QCBOREncode_OpenMap(). It reduces nesting
1557 level by one.
1558
1559 When an error occurs as a result of this call, the encoder records
1560 the error and enters the error state. The error will be returned when
1561 QCBOREncode_Finish() is called.
1562
1563 If this has been called more times than QCBOREncode_OpenMap(),
1564 then @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1565 QCBOREncode_Finish() is called.
1566
1567 If this is called and it is not a map that is currently open, @ref
1568 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
1569 is called.
1570 */
1571static void QCBOREncode_CloseMap(QCBOREncodeContext *pCtx);
1572
1573
1574/**
1575 @brief Indicate start of encoded CBOR to be wrapped in a bstr.
1576
1577 @param[in] pCtx The encoding context to open the bstr-wrapped CBOR in.
1578
1579 All added encoded items between this call and a call to
1580 QCBOREncode_CloseBstrWrap2() will be wrapped in a bstr. They will
1581 appear in the final output as a byte string. That byte string will
1582 contain encoded CBOR. This increases nesting level by one.
1583
1584 The typical use case is for encoded CBOR that is to be
1585 cryptographically hashed, as part of a [RFC 8152, COSE]
1586 (https://tools.ietf.org/html/rfc8152) implementation.
1587
1588 Using QCBOREncode_BstrWrap() and QCBOREncode_CloseBstrWrap2() avoids
1589 having to encode the items first in one buffer (e.g., the COSE
1590 payload) and then add that buffer as a bstr to another encoding
1591 (e.g. the COSE to-be-signed bytes, the @c Sig_structure) potentially
1592 halving the memory needed.
1593
1594 RFC 7049 states the purpose of this wrapping is to prevent code
1595 relaying the signed data but not verifying it from tampering with the
1596 signed data thus making the signature unverifiable. It is also quite
1597 beneficial for the signature verification code. Standard CBOR
1598 decoders usually do not give access to partially decoded CBOR as
1599 would be needed to check the signature of some CBOR. With this
1600 wrapping, standard CBOR decoders can be used to get to all the data
1601 needed for a signature verification.
1602 */
1603static void QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx);
1604
1605static void QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1606
1607static void QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1608
1609
1610/**
1611 @brief Close a wrapping bstr.
1612
1613 @param[in] pCtx The encoding context to close of bstr wrapping in.
1614 @param[in] bIncludeCBORHead Include the encoded CBOR head of the bstr
1615 as well as the bytes in @c pWrappedCBOR.
1616 @param[out] pWrappedCBOR A @ref UsefulBufC containing wrapped bytes.
1617
1618 The closes a wrapping bstr opened by QCBOREncode_BstrWrap(). It reduces
1619 nesting level by one.
1620
1621 A pointer and length of the enclosed encoded CBOR is returned in @c
1622 *pWrappedCBOR if it is not @c NULL. The main purpose of this is so
1623 this data can be hashed (e.g., with SHA-256) as part of a [RFC 8152,
1624 COSE] (https://tools.ietf.org/html/rfc8152)
1625 implementation. **WARNING**, this pointer and length should be used
1626 right away before any other calls to @c QCBOREncode_CloseXxx() as
1627 they will move data around and the pointer and length will no longer
1628 be to the correct encoded CBOR.
1629
1630 When an error occurs as a result of this call, the encoder records
1631 the error and enters the error state. The error will be returned when
1632 QCBOREncode_Finish() is called.
1633
1634 If this has been called more times than QCBOREncode_BstrWrap(), then
1635 @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1636 QCBOREncode_Finish() is called.
1637
1638 If this is called and it is not a wrapping bstr that is currently
1639 open, @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
1640 QCBOREncode_Finish() is called.
1641
1642 QCBOREncode_CloseBstrWrap() is a deprecated version of this function
1643 that is equivalent to the call with @c bIncludeCBORHead @c true.
1644 */
1645void QCBOREncode_CloseBstrWrap2(QCBOREncodeContext *pCtx, bool bIncludeCBORHead, UsefulBufC *pWrappedCBOR);
1646
1647static void QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR);
1648
1649
1650/**
1651 @brief Add some already-encoded CBOR bytes.
1652
1653 @param[in] pCtx The encoding context to add the already-encode CBOR to.
1654 @param[in] Encoded The already-encoded CBOR to add to the context.
1655
1656 The encoded CBOR being added must be fully conforming CBOR. It must
1657 be complete with no arrays or maps that are incomplete. While this
1658 encoder doesn't ever produce indefinite lengths, it is OK for the
1659 raw CBOR added here to have indefinite lengths.
1660
1661 The raw CBOR added here is not checked in anyway. If it is not
1662 conforming or has open arrays or such, the final encoded CBOR
1663 will probably be wrong or not what was intended.
1664
1665 If the encoded CBOR being added here contains multiple items, they
1666 must be enclosed in a map or array. At the top level the raw
1667 CBOR must be a single data item.
1668 */
1669static void QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded);
1670
1671static void QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded);
1672
1673static void QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded);
1674
1675
1676/**
1677 @brief Get the encoded result.
1678
1679 @param[in] pCtx The context to finish encoding with.
1680 @param[out] pEncodedCBOR Pointer and length of encoded CBOR.
1681
1682 @retval QCBOR_ERR_TOO_MANY_CLOSES Nesting error
1683
1684 @retval QCBOR_ERR_CLOSE_MISMATCH Nesting error
1685
1686 @retval QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN Nesting error
1687
1688 @retval QCBOR_ERR_BUFFER_TOO_LARGE Encoded output buffer size
1689
1690 @retval QCBOR_ERR_BUFFER_TOO_SMALL Encoded output buffer size
1691
1692 @retval QCBOR_ERR_ARRAY_NESTING_TOO_DEEP Implementation limit
1693
1694 @retval QCBOR_ERR_ARRAY_TOO_LONG Implementation limit
1695
1696 If this returns success @ref QCBOR_SUCCESS the encoding was a success
1697 and the return length is correct and complete.
1698
1699 If no buffer was passed to QCBOREncode_Init(), then only the length
1700 was computed. If a buffer was passed, then the encoded CBOR is in the
1701 buffer.
1702
1703 Encoding errors primarily manifest here as most other encoding function
1704 do no return an error. They just set the error state in the encode
1705 context after which no encoding function does anything.
1706
1707 Three types of errors manifest here. The first type are nesting
1708 errors where the number of @c QCBOREncode_OpenXxx() calls do not
1709 match the number @c QCBOREncode_CloseXxx() calls. The solution is to
1710 fix the calling code.
1711
1712 The second type of error is because the buffer given is either too
1713 small or too large. The remedy is to give a correctly sized buffer.
1714
1715 The third type are due to limits in this implementation. @ref
1716 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP can be worked around by encoding the
1717 CBOR in two (or more) phases and adding the CBOR from the first phase
1718 to the second with @c QCBOREncode_AddEncoded().
1719
1720 If an error is returned, the buffer may have partially encoded
1721 incorrect CBOR in it and it should not be used. Likewise, the length
1722 may be incorrect and should not be used.
1723
1724 Note that the error could have occurred in one of the many @c
1725 QCBOREncode_AddXxx() calls long before QCBOREncode_Finish() was
1726 called. This error handling reduces the CBOR implementation size but
1727 makes debugging harder.
1728
1729 This may be called multiple times. It will always return the same. It
1730 can also be interleaved with calls to QCBOREncode_FinishGetSize().
1731
1732 QCBOREncode_GetErrorState() can be called to get the current
1733 error state and abort encoding early as an optimization, but is
1734 is never required.
1735 */
1736QCBORError QCBOREncode_Finish(QCBOREncodeContext *pCtx, UsefulBufC *pEncodedCBOR);
1737
1738
1739/**
1740 @brief Get the encoded CBOR and error status.
1741
1742 @param[in] pCtx The context to finish encoding with.
1743 @param[out] uEncodedLen The length of the encoded or potentially
1744 encoded CBOR in bytes.
1745
1746 @return The same errors as QCBOREncode_Finish().
1747
1748 This functions the same as QCBOREncode_Finish(), but only returns the
1749 size of the encoded output.
1750 */
1751QCBORError QCBOREncode_FinishGetSize(QCBOREncodeContext *pCtx, size_t *uEncodedLen);
1752
1753
1754/**
1755 @brief Indicate whether output buffer is NULL or not.
1756
1757 @param[in] pCtx The encoding context.
1758
1759 @return 1 if the output buffer is @c NULL.
1760
1761 Sometimes a @c NULL input buffer is given to QCBOREncode_Init() so
1762 that the size of the generated CBOR can be calculated without
1763 allocating a buffer for it. This returns 1 when the output buffer is
1764 NULL and 0 when it is not.
1765*/
1766static int QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx);
1767
Laurence Lundblade825164e2020-10-22 20:18:06 -07001768
1769/**
Michael Eckel5c531332020-03-02 01:35:30 +01001770 @brief Get the encoding error state.
1771
1772 @param[in] pCtx The encoding context.
1773
Laurence Lundbladeabf5c572020-06-29 21:21:29 -07001774 @return One of @ref QCBORError. See return values from
Michael Eckel5c531332020-03-02 01:35:30 +01001775 QCBOREncode_Finish()
1776
1777 Normally encoding errors need only be handled at the end of encoding
1778 when QCBOREncode_Finish() is called. This can be called to get the
1779 error result before finish should there be a need to halt encoding
1780 before QCBOREncode_Finish() is called.
1781*/
1782static QCBORError QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx);
1783
1784
1785/**
1786 Encode the "head" of a CBOR data item.
1787
1788 @param buffer Buffer to output the encoded head to; must be
1789 @ref QCBOR_HEAD_BUFFER_SIZE bytes in size.
1790 @param uMajorType One of CBOR_MAJOR_TYPE_XX.
1791 @param uMinLen The minimum number of bytes to encode uNumber. Almost always
1792 this is 0 to use preferred minimal encoding. If this is 4,
1793 then even the values 0xffff and smaller will be encoded
Laurence Lundblade98427e92020-09-28 21:33:23 -07001794 in 4 bytes. This is used primarily when encoding a
Michael Eckel5c531332020-03-02 01:35:30 +01001795 float or double put into uNumber as the leading zero bytes
1796 for them must be encoded.
1797 @param uNumber The numeric argument part of the CBOR head.
1798 @return Pointer and length of the encoded head or
Laurence Lundblade9a3b6252020-10-21 21:30:31 -07001799 @ref NULLUsefulBufC if the output buffer is too small.
Michael Eckel5c531332020-03-02 01:35:30 +01001800
Laurence Lundblade98427e92020-09-28 21:33:23 -07001801 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 +01001802 take a @ref QCBOREncodeContext argument.
1803
1804 This encodes the major type and argument part of a data item. The
1805 argument is an integer that is usually either the value or the length
1806 of the data item.
1807
1808 This is exposed in the public interface to allow hashing of some CBOR
1809 data types, bstr in particular, a chunk at a time so the full CBOR
1810 doesn't have to be encoded in a contiguous buffer.
1811
1812 For example, if you have a 100,000 byte binary blob in a buffer that
1813 needs to be a bstr encoded and then hashed. You could allocate a
1814 100,010 byte buffer and encode it normally. Alternatively, you can
1815 encode the head in a 10 byte buffer with this function, hash that and
1816 then hash the 100,000 bytes using the same hash context.
1817
1818 See also QCBOREncode_AddBytesLenOnly();
1819 */
1820UsefulBufC QCBOREncode_EncodeHead(UsefulBuf buffer,
1821 uint8_t uMajorType,
1822 uint8_t uMinLen,
1823 uint64_t uNumber);
1824
1825
Michael Eckel5c531332020-03-02 01:35:30 +01001826
1827
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001828/* =========================================================================
1829 BEGINNING OF PRIVATE INLINE IMPLEMENTATION
1830 ========================================================================= */
Michael Eckel5c531332020-03-02 01:35:30 +01001831
1832/**
1833 @brief Semi-private method to add a buffer full of bytes to encoded output
1834
1835 @param[in] pCtx The encoding context to add the integer to.
1836 @param[in] uMajorType The CBOR major type of the bytes.
1837 @param[in] Bytes The bytes to add.
1838
1839 Use QCBOREncode_AddText() or QCBOREncode_AddBytes() or
1840 QCBOREncode_AddEncoded() instead. They are inline functions that call
1841 this and supply the correct major type. This function is public to
1842 make the inline functions work to keep the overall code size down and
1843 because the C language has no way to make it private.
1844
1845 If this is called the major type should be @c
1846 CBOR_MAJOR_TYPE_TEXT_STRING, @c CBOR_MAJOR_TYPE_BYTE_STRING or @c
1847 CBOR_MAJOR_NONE_TYPE_RAW. The last one is special for adding
1848 already-encoded CBOR.
1849 */
1850void QCBOREncode_AddBuffer(QCBOREncodeContext *pCtx, uint8_t uMajorType, UsefulBufC Bytes);
1851
1852
1853/**
1854 @brief Semi-private method to open a map, array or bstr-wrapped CBOR
1855
1856 @param[in] pCtx The context to add to.
1857 @param[in] uMajorType The major CBOR type to close
1858
1859 Call QCBOREncode_OpenArray(), QCBOREncode_OpenMap() or
1860 QCBOREncode_BstrWrap() instead of this.
1861 */
1862void QCBOREncode_OpenMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType);
1863
1864
1865/**
1866 @brief Semi-private method to open a map, array with indefinite length
1867
1868 @param[in] pCtx The context to add to.
1869 @param[in] uMajorType The major CBOR type to close
1870
1871 Call QCBOREncode_OpenArrayIndefiniteLength() or
1872 QCBOREncode_OpenMapIndefiniteLength() instead of this.
1873 */
1874void QCBOREncode_OpenMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx, uint8_t uMajorType);
1875
1876
1877/**
1878 @brief Semi-private method to close a map, array or bstr wrapped CBOR
1879
1880 @param[in] pCtx The context to add to.
1881 @param[in] uMajorType The major CBOR type to close.
1882
1883 Call QCBOREncode_CloseArray() or QCBOREncode_CloseMap() instead of this.
1884 */
1885void QCBOREncode_CloseMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType);
1886
1887
1888/**
1889 @brief Semi-private method to close a map, array with indefinite length
1890
1891 @param[in] pCtx The context to add to.
1892 @param[in] uMajorType The major CBOR type to close.
1893
1894 Call QCBOREncode_CloseArrayIndefiniteLength() or
1895 QCBOREncode_CloseMapIndefiniteLength() instead of this.
1896 */
1897void QCBOREncode_CloseMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx,
1898 uint8_t uMajorType);
1899
1900
1901/**
1902 @brief Semi-private method to add simple types.
1903
1904 @param[in] pCtx The encoding context to add the simple value to.
1905 @param[in] uMinLen Minimum encoding size for uNum. Usually 0.
1906 @param[in] uNum One of CBOR_SIMPLEV_FALSE through _UNDEF or other.
1907
1908 This is used to add simple types like true and false.
1909
1910 Call QCBOREncode_AddBool(), QCBOREncode_AddNULL(),
1911 QCBOREncode_AddUndef() instead of this.
1912
1913 This function can add simple values that are not defined by CBOR
1914 yet. This expansion point in CBOR should not be used unless they are
1915 standardized.
1916
1917 Error handling is the same as QCBOREncode_AddInt64().
1918 */
1919void QCBOREncode_AddType7(QCBOREncodeContext *pCtx, uint8_t uMinLen, uint64_t uNum);
1920
1921
1922/**
1923 @brief Semi-private method to add bigfloats and decimal fractions.
1924
1925 @param[in] pCtx The encoding context to add the value to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001926 @param[in] uTag The type 6 tag indicating what this is to be.
Michael Eckel5c531332020-03-02 01:35:30 +01001927 @param[in] BigNumMantissa Is @ref NULLUsefulBufC if mantissa is an
1928 @c int64_t or the actual big number mantissa
1929 if not.
1930 @param[in] nMantissa The @c int64_t mantissa if it is not a big number.
1931 @param[in] nExponent The exponent.
1932
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001933 This outputs either the @ref CBOR_TAG_DECIMAL_FRACTION or @ref
1934 CBOR_TAG_BIGFLOAT tag. if @c uTag is @ref CBOR_TAG_INVALID64, then
1935 this outputs the "borrowed" content format.
Michael Eckel5c531332020-03-02 01:35:30 +01001936
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001937 The tag content output by this is an array with two members, the
1938 exponent and then the mantissa. The mantissa can be either a big
1939 number or an @c int64_t.
1940
1941 This implementation cannot output an exponent further from 0 than
Laurence Lundblade9a3b6252020-10-21 21:30:31 -07001942 @c INT64_MAX.
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001943
1944 To output a mantissa that is bewteen INT64_MAX and UINT64_MAX from 0,
1945 it must be as a big number.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001946
Michael Eckel5c531332020-03-02 01:35:30 +01001947 Typically, QCBOREncode_AddDecimalFraction(), QCBOREncode_AddBigFloat(),
1948 QCBOREncode_AddDecimalFractionBigNum() or QCBOREncode_AddBigFloatBigNum()
1949 is called instead of this.
1950 */
1951void QCBOREncode_AddExponentAndMantissa(QCBOREncodeContext *pCtx,
1952 uint64_t uTag,
1953 UsefulBufC BigNumMantissa,
1954 bool bBigNumIsNegative,
1955 int64_t nMantissa,
1956 int64_t nExponent);
1957
1958/**
1959 @brief Semi-private method to add only the type and length of a byte string.
1960
1961 @param[in] pCtx The context to initialize.
1962 @param[in] Bytes Pointer and length of the input data.
1963
1964 This is the same as QCBOREncode_AddBytes() except it only adds the
1965 CBOR encoding for the type and the length. It doesn't actually add
1966 the bytes. You can't actually produce correct CBOR with this and the
1967 rest of this API. It is only used for a special case where
1968 the valid CBOR is created manually by putting this type and length in
1969 and then adding the actual bytes. In particular, when only a hash of
1970 the encoded CBOR is needed, where the type and header are hashed
1971 separately and then the bytes is hashed. This makes it possible to
1972 implement COSE Sign1 with only one copy of the payload in the output
1973 buffer, rather than two, roughly cutting memory use in half.
1974
1975 This is only used for this odd case, but this is a supported
1976 tested function.
1977
1978 See also QCBOREncode_EncodeHead().
1979*/
1980static inline void QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
1981
1982static inline void QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
1983
1984static inline void QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
1985
1986
1987
1988
1989
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001990static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001991QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pMe, const char *szLabel, int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01001992{
1993 // Use _AddBuffer() because _AddSZString() is defined below, not above
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001994 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
1995 QCBOREncode_AddInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01001996}
1997
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001998static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001999QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pMe, int64_t nLabel, int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002000{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002001 QCBOREncode_AddInt64(pMe, nLabel);
2002 QCBOREncode_AddInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002003}
2004
2005
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002006static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002007QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pMe, const char *szLabel, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002008{
2009 // Use _AddBuffer() because _AddSZString() is defined below, not above
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002010 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
2011 QCBOREncode_AddUInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002012}
2013
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002014static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002015QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002016{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002017 QCBOREncode_AddInt64(pMe, nLabel);
2018 QCBOREncode_AddUInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002019}
2020
2021
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002022static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002023QCBOREncode_AddText(QCBOREncodeContext *pMe, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002024{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002025 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002026}
2027
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002028static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002029QCBOREncode_AddTextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002030{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002031 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szLabel));
2032 QCBOREncode_AddText(pMe, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002033}
2034
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002035static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002036QCBOREncode_AddTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002037{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002038 QCBOREncode_AddInt64(pMe, nLabel);
2039 QCBOREncode_AddText(pMe, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002040}
2041
2042
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002043inline static void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002044QCBOREncode_AddSZString(QCBOREncodeContext *pMe, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002045{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002046 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szString));
Michael Eckel5c531332020-03-02 01:35:30 +01002047}
2048
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002049static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002050QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pMe, const char *szLabel, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002051{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002052 QCBOREncode_AddSZString(pMe, szLabel);
2053 QCBOREncode_AddSZString(pMe, szString);
Michael Eckel5c531332020-03-02 01:35:30 +01002054}
2055
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002056static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002057QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002058{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002059 QCBOREncode_AddInt64(pMe, nLabel);
2060 QCBOREncode_AddSZString(pMe, szString);
Michael Eckel5c531332020-03-02 01:35:30 +01002061}
2062
2063
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002064static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002065QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pMe, const char *szLabel, double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002066{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002067 QCBOREncode_AddSZString(pMe, szLabel);
2068 QCBOREncode_AddDouble(pMe, dNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002069}
2070
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002071static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002072QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pMe, int64_t nLabel, double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002073{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002074 QCBOREncode_AddInt64(pMe, nLabel);
2075 QCBOREncode_AddDouble(pMe, dNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002076}
2077
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002078static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002079QCBOREncode_AddFloatToMap(QCBOREncodeContext *pMe, const char *szLabel, float dNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002080{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002081 QCBOREncode_AddSZString(pMe, szLabel);
2082 QCBOREncode_AddFloat(pMe, dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002083}
2084
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002085static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002086QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pMe, int64_t nLabel, float fNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002087{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002088 QCBOREncode_AddInt64(pMe, nLabel);
2089 QCBOREncode_AddFloat(pMe, fNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002090}
2091
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002092static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002093QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pMe, const char *szLabel, double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002094{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002095 QCBOREncode_AddSZString(pMe, szLabel);
2096 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002097}
2098
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002099static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002100QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pMe, int64_t nLabel, double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002101{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002102 QCBOREncode_AddInt64(pMe, nLabel);
2103 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002104}
2105
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002106static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002107QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pMe, const char *szLabel, float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002108{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002109 QCBOREncode_AddSZString(pMe, szLabel);
2110 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002111}
2112
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002113static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002114QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pMe, int64_t nLabel, float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002115{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002116 QCBOREncode_AddInt64(pMe, nLabel);
2117 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002118}
2119
Michael Eckel5c531332020-03-02 01:35:30 +01002120
Laurence Lundblade9b334962020-08-27 10:55:53 -07002121
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002122static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002123QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pMe, uint8_t uTag, int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002124{
2125 if(uTag == QCBOR_ENCODE_AS_TAG) {
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002126 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_EPOCH);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002127 }
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002128 QCBOREncode_AddInt64(pMe, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002129}
2130
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002131static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002132QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTag, int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002133{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002134 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002135 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002136}
2137
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002138static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002139QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTag, int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002140{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002141 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002142 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002143}
2144
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002145static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002146QCBOREncode_AddDateEpoch(QCBOREncodeContext *pMe, int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002147{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002148 QCBOREncode_AddTDateEpoch(pMe, QCBOR_ENCODE_AS_TAG, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002149}
2150
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002151static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002152QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pMe, const char *szLabel, int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002153{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002154 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002155 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002156}
2157
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002158static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002159QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pMe, int64_t nLabel, int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002160{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002161 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002162 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002163}
2164
2165
Laurence Lundblade9b334962020-08-27 10:55:53 -07002166
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002167static inline void
2168QCBOREncode_AddBytes(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002169{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002170 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002171}
2172
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002173static inline void
2174QCBOREncode_AddBytesToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002175{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002176 QCBOREncode_AddSZString(pMe, szLabel);
2177 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002178}
2179
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002180static inline void
2181QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002182{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002183 QCBOREncode_AddInt64(pMe, nLabel);
2184 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002185}
2186
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002187static inline void
2188QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002189{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002190 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002191}
2192
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002193static inline void
2194QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002195{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002196 QCBOREncode_AddSZString(pMe, szLabel);
2197 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002198}
2199
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002200static inline void
2201QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002202{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002203 QCBOREncode_AddInt64(pMe, nLabel);
2204 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002205}
2206
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002207
2208static inline void
2209QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002210{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002211 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2212 QCBOREncode_AddTag(pMe, CBOR_TAG_BIN_UUID);
2213 }
2214 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002215}
2216
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002217static inline void
2218QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pMe,
2219 const char *szLabel,
2220 uint8_t uTagRequirement,
2221 UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002222{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002223 QCBOREncode_AddSZString(pMe, szLabel);
2224 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002225}
2226
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002227static inline void
2228QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002229{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002230 QCBOREncode_AddInt64(pMe, nLabel);
2231 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002232}
2233
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002234static inline void
2235QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002236{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002237 QCBOREncode_AddTBinaryUUID(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002238}
2239
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002240static inline void
2241QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002242{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002243 QCBOREncode_AddTBinaryUUIDToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002244}
2245
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002246static inline void
2247QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002248{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002249 QCBOREncode_AddTBinaryUUIDToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002250}
2251
2252
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002253static inline void
2254QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002255{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002256 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2257 QCBOREncode_AddTag(pMe, CBOR_TAG_POS_BIGNUM);
2258 }
2259 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002260}
2261
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002262static inline void
2263QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pMe,
2264 const char *szLabel,
2265 uint8_t uTagRequirement,
2266 UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002267{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002268 QCBOREncode_AddSZString(pMe, szLabel);
2269 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002270}
2271
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002272static inline void
2273QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002274{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002275 QCBOREncode_AddInt64(pMe, nLabel);
2276 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002277}
2278
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002279static inline void
2280QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2281{
2282 QCBOREncode_AddTPositiveBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2283}
2284
2285static inline void
2286QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2287{
2288 QCBOREncode_AddTPositiveBignumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2289}
2290
2291static inline void
2292QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2293{
2294 QCBOREncode_AddTPositiveBignumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2295}
2296
2297
2298static inline void
2299QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
2300{
2301 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2302 QCBOREncode_AddTag(pMe, CBOR_TAG_NEG_BIGNUM);
2303 }
2304 QCBOREncode_AddBytes(pMe, Bytes);
2305}
2306
2307static inline void
2308QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pMe,
2309 const char *szLabel,
2310 uint8_t uTagRequirement,
2311 UsefulBufC Bytes)
2312{
2313 QCBOREncode_AddSZString(pMe, szLabel);
2314 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2315}
2316
2317static inline void
2318QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
2319{
2320 QCBOREncode_AddInt64(pMe, nLabel);
2321 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2322}
2323
2324static inline void
2325QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2326{
2327 QCBOREncode_AddTNegativeBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2328}
2329
2330static inline void
2331QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2332{
2333 QCBOREncode_AddTNegativeBignumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2334}
2335
2336static inline void
2337QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2338{
2339 QCBOREncode_AddTNegativeBignumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2340}
2341
2342
Michael Eckel5c531332020-03-02 01:35:30 +01002343
2344#ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
2345
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002346static inline void
2347QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pMe,
2348 uint8_t uTagRequirement,
2349 int64_t nMantissa,
2350 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002351{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002352 uint64_t uTag;
2353 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2354 uTag = CBOR_TAG_DECIMAL_FRACTION;
2355 } else {
2356 uTag = CBOR_TAG_INVALID64;
2357 }
2358 QCBOREncode_AddExponentAndMantissa(pMe,
2359 uTag,
Michael Eckel5c531332020-03-02 01:35:30 +01002360 NULLUsefulBufC,
2361 false,
2362 nMantissa,
2363 nBase10Exponent);
2364}
2365
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002366static inline void
2367QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pMe,
2368 const char *szLabel,
2369 uint8_t uTagRequirement,
2370 int64_t nMantissa,
2371 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002372{
2373 QCBOREncode_AddSZString(pMe, szLabel);
2374 QCBOREncode_AddTDecimalFraction(pMe, uTagRequirement, nMantissa, nBase10Exponent);
2375}
2376
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002377static inline void
2378QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pMe,
2379 int64_t nLabel,
2380 uint8_t uTagRequirement,
2381 int64_t nMantissa,
2382 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002383{
2384 QCBOREncode_AddInt64(pMe, nLabel);
2385 QCBOREncode_AddTDecimalFraction(pMe, uTagRequirement, nMantissa, nBase10Exponent);
2386}
2387
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002388static inline void
2389QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pMe,
2390 int64_t nMantissa,
2391 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002392{
2393 QCBOREncode_AddTDecimalFraction(pMe, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
2394}
2395
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002396static inline void
2397QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pMe,
2398 const char *szLabel,
2399 int64_t nMantissa,
2400 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002401{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002402 QCBOREncode_AddTDecimalFractionToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002403}
2404
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002405static inline void
2406QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pMe,
2407 int64_t nLabel,
2408 int64_t nMantissa,
2409 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002410{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002411 QCBOREncode_AddTDecimalFractionToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002412}
2413
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002414
2415
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002416static inline void
2417QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pMe,
2418 uint8_t uTagRequirement,
2419 UsefulBufC Mantissa,
2420 bool bIsNegative,
2421 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002422{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002423 uint64_t uTag;
2424 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2425 uTag = CBOR_TAG_DECIMAL_FRACTION;
2426 } else {
2427 uTag = CBOR_TAG_INVALID64;
2428 }
2429 QCBOREncode_AddExponentAndMantissa(pMe,
2430 uTag,
Michael Eckel5c531332020-03-02 01:35:30 +01002431 Mantissa, bIsNegative,
2432 0,
2433 nBase10Exponent);
2434}
2435
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002436static inline void
2437QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
2438 const char *szLabel,
2439 uint8_t uTagRequirement,
2440 UsefulBufC Mantissa,
2441 bool bIsNegative,
2442 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002443{
2444 QCBOREncode_AddSZString(pMe, szLabel);
2445 QCBOREncode_AddTDecimalFractionBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase10Exponent);
2446}
2447
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002448static inline void
2449QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
2450 int64_t nLabel,
2451 uint8_t uTagRequirement,
2452 UsefulBufC Mantissa,
2453 bool bIsNegative,
2454 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002455{
2456 QCBOREncode_AddInt64(pMe, nLabel);
2457 QCBOREncode_AddTDecimalFractionBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase10Exponent);
2458}
2459
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002460static inline void
2461QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pMe,
2462 UsefulBufC Mantissa,
2463 bool bIsNegative,
2464 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002465{
2466 QCBOREncode_AddTDecimalFractionBigNum(pMe, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase10Exponent);
2467}
2468
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002469static inline void
2470QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
2471 const char *szLabel,
2472 UsefulBufC Mantissa,
2473 bool bIsNegative,
2474 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002475{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002476 QCBOREncode_AddTDecimalFractionBigNumToMapSZ(pMe,
2477 szLabel,
2478 QCBOR_ENCODE_AS_TAG,
2479 Mantissa,
2480 bIsNegative,
2481 nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002482}
2483
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002484static inline void
2485QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
2486 int64_t nLabel,
2487 UsefulBufC Mantissa,
2488 bool bIsNegative,
2489 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002490{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002491 QCBOREncode_AddTDecimalFractionBigNumToMapN(pMe,
2492 nLabel,
2493 QCBOR_ENCODE_AS_TAG,
2494 Mantissa,
2495 bIsNegative,
2496 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002497}
2498
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002499
2500
2501
2502
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002503static inline void
2504QCBOREncode_AddTBigFloat(QCBOREncodeContext *pMe,
2505 uint8_t uTagRequirement,
2506 int64_t nMantissa,
2507 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002508{
2509 uint64_t uTag;
2510 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2511 uTag = CBOR_TAG_BIGFLOAT;
2512 } else {
2513 uTag = CBOR_TAG_INVALID64;
2514 }
2515 QCBOREncode_AddExponentAndMantissa(pMe, uTag, NULLUsefulBufC, false, nMantissa, nBase2Exponent);
2516}
2517
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002518static inline void
2519QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pMe,
2520 const char *szLabel,
2521 uint8_t uTagRequirement,
2522 int64_t nMantissa,
2523 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002524{
2525 QCBOREncode_AddSZString(pMe, szLabel);
2526 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
2527}
2528
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002529static inline void
2530QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pMe,
2531 int64_t nLabel,
2532 uint8_t uTagRequirement,
2533 int64_t nMantissa,
2534 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002535{
2536 QCBOREncode_AddInt64(pMe, nLabel);
2537 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
2538}
2539
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002540static inline void
2541QCBOREncode_AddBigFloat(QCBOREncodeContext *pMe,
2542 int64_t nMantissa,
2543 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002544{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002545 QCBOREncode_AddTBigFloat(pMe, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002546}
2547
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002548static inline void
2549QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pMe,
2550 const char *szLabel,
2551 int64_t nMantissa,
2552 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002553{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002554 QCBOREncode_AddTBigFloatToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002555}
2556
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002557static inline void
2558QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pMe,
2559 int64_t nLabel,
2560 int64_t nMantissa,
2561 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002562{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002563 QCBOREncode_AddTBigFloatToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002564}
2565
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002566
2567
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002568static inline void
2569QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pMe,
2570 uint8_t uTagRequirement,
2571 UsefulBufC Mantissa,
2572 bool bIsNegative,
2573 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002574{
2575 uint64_t uTag;
2576 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2577 uTag = CBOR_TAG_BIGFLOAT;
2578 } else {
2579 uTag = CBOR_TAG_INVALID64;
2580 }
2581 QCBOREncode_AddExponentAndMantissa(pMe, uTag, Mantissa, bIsNegative, 0, nBase2Exponent);
2582}
2583
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002584static inline void
2585QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pMe,
2586 const char *szLabel,
2587 uint8_t uTagRequirement,
2588 UsefulBufC Mantissa,
2589 bool bIsNegative,
2590 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002591{
2592 QCBOREncode_AddSZString(pMe, szLabel);
2593 QCBOREncode_AddTBigFloatBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase2Exponent);
2594}
2595
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002596static inline void
2597QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
2598 int64_t nLabel,
2599 uint8_t uTagRequirement,
2600 UsefulBufC Mantissa,
2601 bool bIsNegative,
2602 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002603{
2604 QCBOREncode_AddInt64(pMe, nLabel);
2605 QCBOREncode_AddTBigFloatBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase2Exponent);
2606}
2607
2608
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002609static inline void
2610QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pMe,
2611 UsefulBufC Mantissa,
2612 bool bIsNegative,
2613 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002614{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002615 QCBOREncode_AddTBigFloatBigNum(pMe, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002616}
2617
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002618static inline void
2619QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pMe,
2620 const char *szLabel,
2621 UsefulBufC Mantissa,
2622 bool bIsNegative,
2623 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002624{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002625 QCBOREncode_AddTBigFloatBigNumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002626}
2627
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002628static inline void
2629QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
2630 int64_t nLabel,
2631 UsefulBufC Mantissa,
2632 bool bIsNegative,
2633 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002634{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002635 QCBOREncode_AddTBigFloatBigNumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002636}
2637#endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
2638
2639
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002640static inline void
2641QCBOREncode_AddTURI(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002642{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002643 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2644 QCBOREncode_AddTag(pMe, CBOR_TAG_URI);
2645 }
2646 QCBOREncode_AddText(pMe, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002647}
2648
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002649static inline void
2650QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002651{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002652 QCBOREncode_AddSZString(pMe, szLabel);
2653 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002654}
2655
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002656static inline void
2657QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002658{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002659 QCBOREncode_AddInt64(pMe, nLabel);
2660 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
2661}
2662
2663static inline void
2664QCBOREncode_AddURI(QCBOREncodeContext *pMe, UsefulBufC URI)
2665{
2666 QCBOREncode_AddTURI(pMe, QCBOR_ENCODE_AS_TAG, URI);
2667}
2668
2669static inline void
2670QCBOREncode_AddURIToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC URI)
2671{
2672 QCBOREncode_AddTURIToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, URI);
2673}
2674
2675static inline void
2676QCBOREncode_AddURIToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC URI)
2677{
2678 QCBOREncode_AddTURIToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002679}
2680
2681
2682
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002683static inline void
2684QCBOREncode_AddTB64Text(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002685{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002686 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2687 QCBOREncode_AddTag(pMe, CBOR_TAG_B64);
2688 }
2689 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002690}
2691
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002692static inline void
2693QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pMe,
2694 const char *szLabel,
2695 uint8_t uTagRequirement,
2696 UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002697{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002698 QCBOREncode_AddSZString(pMe, szLabel);
2699 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002700}
2701
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002702static inline void
2703QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002704{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002705 QCBOREncode_AddInt64(pMe, nLabel);
2706 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
2707}
2708
2709static inline void
2710QCBOREncode_AddB64Text(QCBOREncodeContext *pMe, UsefulBufC B64Text)
2711{
2712 QCBOREncode_AddTB64Text(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
2713}
2714
2715static inline void
2716QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC B64Text)
2717{
2718 QCBOREncode_AddTB64TextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
2719}
2720
2721static inline void
2722QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC B64Text)
2723{
2724 QCBOREncode_AddTB64TextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002725}
2726
2727
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002728
2729static inline void
2730QCBOREncode_AddTB64URLText(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002731{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002732 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2733 QCBOREncode_AddTag(pMe, CBOR_TAG_B64URL);
2734 }
2735 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002736}
2737
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002738static inline void
2739QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pMe,
2740 const char *szLabel,
2741 uint8_t uTagRequirement,
2742 UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002743{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002744 QCBOREncode_AddSZString(pMe, szLabel);
2745 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002746}
2747
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002748static inline void
2749QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002750{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002751 QCBOREncode_AddInt64(pMe, nLabel);
2752 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
2753}
2754
2755static inline void
2756QCBOREncode_AddB64URLText(QCBOREncodeContext *pMe, UsefulBufC B64Text)
2757{
2758 QCBOREncode_AddTB64URLText(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
2759}
2760
2761static inline void
2762QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC B64Text)
2763{
2764 QCBOREncode_AddTB64URLTextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
2765}
2766
2767static inline void
2768QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC B64Text)
2769{
2770 QCBOREncode_AddTB64URLTextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002771}
2772
2773
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002774
2775static inline void
2776QCBOREncode_AddTRegex(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002777{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002778 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2779 QCBOREncode_AddTag(pMe, CBOR_TAG_REGEX);
2780 }
2781 QCBOREncode_AddText(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002782}
2783
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002784static inline void
2785QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002786{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002787 QCBOREncode_AddSZString(pMe, szLabel);
2788 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002789}
2790
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002791static inline void
2792QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002793{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002794 QCBOREncode_AddInt64(pMe, nLabel);
2795 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
2796}
2797
2798static inline void
2799QCBOREncode_AddRegex(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2800{
2801 QCBOREncode_AddTRegex(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2802}
2803
2804static inline void
2805QCBOREncode_AddRegexToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2806{
2807 QCBOREncode_AddTRegexToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2808}
2809
2810static inline void
2811QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2812{
2813 QCBOREncode_AddTRegexToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2814
Michael Eckel5c531332020-03-02 01:35:30 +01002815}
2816
2817
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002818static inline void
2819QCBOREncode_AddTMIMEData(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01002820{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002821 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
Laurence Lundblade4982f412020-09-18 23:02:18 -07002822 QCBOREncode_AddTag(pMe, CBOR_TAG_BINARY_MIME);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002823 }
Laurence Lundblade4982f412020-09-18 23:02:18 -07002824 QCBOREncode_AddBytes(pMe, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01002825}
2826
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002827static inline void
2828QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pMe,
2829 const char *szLabel,
2830 uint8_t uTagRequirement,
2831 UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01002832{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002833 QCBOREncode_AddSZString(pMe, szLabel);
2834 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01002835}
2836
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002837static inline void
2838QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01002839{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002840 QCBOREncode_AddInt64(pMe, nLabel);
2841 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
2842}
2843
2844static inline void
2845QCBOREncode_AddMIMEData(QCBOREncodeContext *pMe, UsefulBufC MIMEData)
2846{
2847 QCBOREncode_AddTMIMEData(pMe, QCBOR_ENCODE_AS_TAG, MIMEData);
2848}
2849
2850static inline void
2851QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC MIMEData)
2852{
2853 QCBOREncode_AddTMIMEDataToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
2854}
2855
2856static inline void
2857QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC MIMEData)
2858{
2859 QCBOREncode_AddTMIMEDataToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01002860}
2861
2862
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002863static inline void
2864QCBOREncode_AddTDateString(QCBOREncodeContext *pMe, uint8_t uTagRequirement, const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002865{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002866 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2867 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_STRING);
2868 }
2869 QCBOREncode_AddSZString(pMe, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002870}
2871
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002872static inline void
2873QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pMe,
2874 const char *szLabel,
2875 uint8_t uTagRequirement,
2876 const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002877{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002878 QCBOREncode_AddSZString(pMe, szLabel);
2879 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002880}
2881
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002882static inline void
2883QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002884{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002885 QCBOREncode_AddInt64(pMe, nLabel);
2886 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
2887}
2888
2889static inline void
2890QCBOREncode_AddDateString(QCBOREncodeContext *pMe, const char *szDate)
2891{
2892 QCBOREncode_AddTDateString(pMe, QCBOR_ENCODE_AS_TAG, szDate);
2893}
2894
2895static inline void
2896QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pMe, const char *szLabel, const char *szDate)
2897{
2898 QCBOREncode_AddTDateStringToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, szDate);
2899}
2900
2901static inline void
2902QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, const char *szDate)
2903{
2904 QCBOREncode_AddTDateStringToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002905}
2906
2907
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002908static inline void
2909QCBOREncode_AddSimple(QCBOREncodeContext *pMe, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002910{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002911 QCBOREncode_AddType7(pMe, 0, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002912}
2913
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002914static inline void
2915QCBOREncode_AddSimpleToMap(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01002916{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002917 QCBOREncode_AddSZString(pMe, szLabel);
2918 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01002919}
2920
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002921static inline void
2922QCBOREncode_AddSimpleToMapN(QCBOREncodeContext *pMe, int nLabel, uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01002923{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002924 QCBOREncode_AddInt64(pMe, nLabel);
2925 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01002926}
2927
2928
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002929static inline void
2930QCBOREncode_AddBool(QCBOREncodeContext *pMe, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01002931{
2932 uint8_t uSimple = CBOR_SIMPLEV_FALSE;
2933 if(b) {
2934 uSimple = CBOR_SIMPLEV_TRUE;
2935 }
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002936 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01002937}
2938
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002939static inline void
2940QCBOREncode_AddBoolToMap(QCBOREncodeContext *pMe, const char *szLabel, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01002941{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002942 QCBOREncode_AddSZString(pMe, szLabel);
2943 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01002944}
2945
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002946static inline void
2947QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pMe, int64_t nLabel, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01002948{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002949 QCBOREncode_AddInt64(pMe, nLabel);
2950 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01002951}
2952
2953
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002954static inline void
2955QCBOREncode_AddNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01002956{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002957 QCBOREncode_AddSimple(pMe, CBOR_SIMPLEV_NULL);
Michael Eckel5c531332020-03-02 01:35:30 +01002958}
2959
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002960static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002961QCBOREncode_AddNULLToMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002962{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002963 QCBOREncode_AddSZString(pMe, szLabel);
2964 QCBOREncode_AddNULL(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01002965}
2966
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002967static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002968QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002969{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002970 QCBOREncode_AddInt64(pMe, nLabel);
2971 QCBOREncode_AddNULL(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01002972}
2973
2974
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002975static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002976QCBOREncode_AddUndef(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01002977{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002978 QCBOREncode_AddSimple(pMe, CBOR_SIMPLEV_UNDEF);
Michael Eckel5c531332020-03-02 01:35:30 +01002979}
2980
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002981static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002982QCBOREncode_AddUndefToMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002983{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002984 QCBOREncode_AddSZString(pMe, szLabel);
2985 QCBOREncode_AddUndef(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01002986}
2987
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002988static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002989QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002990{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002991 QCBOREncode_AddInt64(pMe, nLabel);
2992 QCBOREncode_AddUndef(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01002993}
2994
2995
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002996static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002997QCBOREncode_OpenArray(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01002998{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002999 QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
Michael Eckel5c531332020-03-02 01:35:30 +01003000}
3001
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003002static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003003QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003004{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003005 QCBOREncode_AddSZString(pMe, szLabel);
3006 QCBOREncode_OpenArray(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003007}
3008
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003009static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003010QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003011{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003012 QCBOREncode_AddInt64(pMe, nLabel);
3013 QCBOREncode_OpenArray(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003014}
3015
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003016static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003017QCBOREncode_CloseArray(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003018{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003019 QCBOREncode_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
Michael Eckel5c531332020-03-02 01:35:30 +01003020}
3021
3022
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003023static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003024QCBOREncode_OpenMap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003025{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003026 QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
Michael Eckel5c531332020-03-02 01:35:30 +01003027}
3028
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003029static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003030QCBOREncode_OpenMapInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003031{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003032 QCBOREncode_AddSZString(pMe, szLabel);
3033 QCBOREncode_OpenMap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003034}
3035
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003036static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003037QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003038{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003039 QCBOREncode_AddInt64(pMe, nLabel);
3040 QCBOREncode_OpenMap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003041}
3042
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003043static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003044QCBOREncode_CloseMap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003045{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003046 QCBOREncode_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
Michael Eckel5c531332020-03-02 01:35:30 +01003047}
3048
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003049static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003050QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003051{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003052 QCBOREncode_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003053}
3054
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003055static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003056QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003057{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003058 QCBOREncode_AddSZString(pMe, szLabel);
3059 QCBOREncode_OpenArrayIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003060}
3061
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003062static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003063QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003064{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003065 QCBOREncode_AddInt64(pMe, nLabel);
3066 QCBOREncode_OpenArrayIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003067}
3068
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003069static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003070QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003071{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003072 QCBOREncode_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003073}
3074
3075
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003076static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003077QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003078{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003079 QCBOREncode_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003080}
3081
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003082static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003083QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003084{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003085 QCBOREncode_AddSZString(pMe, szLabel);
3086 QCBOREncode_OpenMapIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003087}
3088
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003089static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003090QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003091{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003092 QCBOREncode_AddInt64(pMe, nLabel);
3093 QCBOREncode_OpenMapIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003094}
3095
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003096static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003097QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003098{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003099 QCBOREncode_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003100}
3101
3102
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003103static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003104QCBOREncode_BstrWrap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003105{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003106 QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_BYTE_STRING);
Michael Eckel5c531332020-03-02 01:35:30 +01003107}
3108
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003109static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003110QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003111{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003112 QCBOREncode_AddSZString(pMe, szLabel);
3113 QCBOREncode_BstrWrap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003114}
3115
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003116static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003117QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003118{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003119 QCBOREncode_AddInt64(pMe, nLabel);
3120 QCBOREncode_BstrWrap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003121}
3122
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003123static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003124QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pMe, UsefulBufC *pWrappedCBOR)
Michael Eckel5c531332020-03-02 01:35:30 +01003125{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003126 QCBOREncode_CloseBstrWrap2(pMe, true, pWrappedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01003127}
3128
3129
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003130static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003131QCBOREncode_AddEncoded(QCBOREncodeContext *pMe, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003132{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003133 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_RAW, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003134}
3135
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003136static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003137QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003138{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003139 QCBOREncode_AddSZString(pMe, szLabel);
3140 QCBOREncode_AddEncoded(pMe, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003141}
3142
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003143static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003144QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003145{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003146 QCBOREncode_AddInt64(pMe, nLabel);
3147 QCBOREncode_AddEncoded(pMe, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003148}
3149
3150
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003151static inline int
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003152QCBOREncode_IsBufferNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003153{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003154 return UsefulOutBuf_IsBufferNULL(&(pMe->OutBuf));
Michael Eckel5c531332020-03-02 01:35:30 +01003155}
3156
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003157static inline QCBORError
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003158QCBOREncode_GetErrorState(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003159{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003160 if(UsefulOutBuf_GetError(&(pMe->OutBuf))) {
Michael Eckel5c531332020-03-02 01:35:30 +01003161 // Items didn't fit in the buffer.
3162 // This check catches this condition for all the appends and inserts
3163 // so checks aren't needed when the appends and inserts are performed.
3164 // And of course UsefulBuf will never overrun the input buffer given
3165 // to it. No complex analysis of the error handling in this file is
3166 // needed to know that is true. Just read the UsefulBuf code.
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003167 pMe->uError = QCBOR_ERR_BUFFER_TOO_SMALL;
Michael Eckel5c531332020-03-02 01:35:30 +01003168 // QCBOR_ERR_BUFFER_TOO_SMALL masks other errors, but that is
3169 // OK. Once the caller fixes this, they'll be unmasked.
3170 }
3171
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003172 return (QCBORError)pMe->uError;
Michael Eckel5c531332020-03-02 01:35:30 +01003173}
3174
3175
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003176/* ========================================================================
3177 END OF PRIVATE INLINE IMPLEMENTATION
3178 ======================================================================== */
Michael Eckel5c531332020-03-02 01:35:30 +01003179
3180#ifdef __cplusplus
3181}
3182#endif
3183
Laurence Lundblade844bb5c2020-03-01 17:27:25 -08003184#endif /* qcbor_encode_h */