blob: 54a36350fdd3c3d0eff07a8042eadc8c98cb497c [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
Laurence Lundbladeda97bf42020-11-05 03:38:50 -0800232 If QCBOR is compiled with QCBOR_DISABLE_ENCODE_USAGE_GUARDS defined,
233 the errors QCBOR_ERR_CLOSE_MISMATCH, QCBOR_ERR_ARRAY_TOO_LONG,
234 QCBOR_ERR_TOO_MANY_CLOSES, QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN, and
235 QCBOR_ERR_ENCODE_UNSUPPORTED will never be returned. It is up to the
236 caller to make sure that opened maps, arrays and byte-string wrapping
237 is closed correctly and that QCBOREncode_AddType7() is called
238 correctly. With this defined, it is easier to make a mistake when
239 authoring the encoding of a protocol that will output not well formed
240 CBOR, but as long as the calling code is correct, it is safe to
241 disable these checks. Bounds checking that prevents security issues
242 in the code is still enforced. This define reduces the size of
243 encoding object code by about 150 bytes.
244
Michael Eckel5c531332020-03-02 01:35:30 +0100245 @anchor Tags-Overview
Laurence Lundblade9b334962020-08-27 10:55:53 -0700246
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700247 ## Tags Overview
248
249 Any CBOR data item can be made into a tag to add semantics, define a
250 new data type or such. Some tags are fully standardized and some are
251 just registered. Others are not registered and used in a proprietary
252 way.
Michael Eckel5c531332020-03-02 01:35:30 +0100253
254 Encoding and decoding of many of the registered tags is fully
255 implemented by QCBOR. It is also possible to encode and decode tags
256 that are not directly supported. For many use cases the built-in tag
257 support should be adequate.
258
259 For example, the registered epoch date tag is supported in encoding
260 by QCBOREncode_AddDateEpoch() and in decoding by @ref
261 QCBOR_TYPE_DATE_EPOCH and the @c epochDate member of @ref
262 QCBORItem. This is typical of the built-in tag support. There is an
263 API to encode data for it and a @c QCBOR_TYPE_XXX when it is decoded.
264
265 Tags are registered in the [IANA CBOR Tags Registry]
266 (https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml). There
267 are roughly three options to create a new tag. First, a public
268 specification can be created and the new tag registered with IANA.
269 This is the most formal. Second, the new tag can be registered with
270 IANA with just a short description rather than a full specification.
271 These tags must be greater than 256. Third, a tag can be used without
272 any IANA registration, though the registry should be checked to see
273 that the new value doesn't collide with one that is registered. The
274 value of these tags must be 256 or larger.
275
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700276 See also @ref CBORTags and @ref Tag-Usage
277
Michael Eckel5c531332020-03-02 01:35:30 +0100278 The encoding side of tags not built-in is handled by
279 QCBOREncode_AddTag() and is relatively simple. Tag decoding is more
280 complex and mainly handled by QCBORDecode_GetNext(). Decoding of the
281 structure of tagged data not built-in (if there is any) has to be
282 implemented by the caller.
283
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700284 @anchor Floating-Point
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700285
286 ## Floating-Point
287
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700288 By default QCBOR fully supports IEEE 754 floating-point:
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700289 - Encode/decode of double, single and half-precision
290 - CBOR preferred serialization of floating-point
291 - Floating-point epoch dates
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700292
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700293 For the most part, the type double is used in the interface for
294 floating-point values. In the default configuration, all decoded
295 floating-point values are returned as a double.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700296
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700297 With CBOR preferred serialization, the encoder outputs the smallest
298 representation of the double or float that preserves precision. Zero,
299 NaN and infinity are always output as a half-precision, each taking
300 just 2 bytes. This reduces the number of bytes needed to encode
Laurence Lundblade4b270642020-08-14 12:53:07 -0700301 double and single-precision, especially if zero, NaN and infinity are
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700302 frequently used.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700303
Laurence Lundblade4b270642020-08-14 12:53:07 -0700304 To avoid use of preferred serialization in the standard configuration
305 when encoding, use QCBOREncode_AddDoubleNoPreferred() or
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700306 QCBOREncode_AddFloatNoPreferred().
307
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700308 This implementation of preferred floating-point serialization and
309 half-precision does not depend on the CPU having floating-point HW or
310 the compiler bringing in a (sometimes large) library to compensate
Laurence Lundblade4b270642020-08-14 12:53:07 -0700311 for lack of CPU support. This implementation uses shifts and masks
312 rather than floating-point functions.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700313
Laurence Lundblade4b270642020-08-14 12:53:07 -0700314 To reduce overall object code by about 900 bytes, define
315 QCBOR_DISABLE_PREFERRED_FLOAT. This will eliminate all support for
316 preferred serialization and half-precision. An error will be returned
317 when attempting to decode half-precision. A float will always be
318 encoded and decoded as 32-bits and a double will always be encoded
319 and decoded as 64 bits.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700320
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700321 Note that even if QCBOR_DISABLE_PREFERRED_FLOAT is not defined all
322 the float-point encoding object code can be avoided by never calling
Laurence Lundbladefe09bbf2020-07-16 12:14:51 -0700323 any functions that encode double or float. Just not calling
324 floating-point functions will reduce object code by about 500 bytes.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700325
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700326 On CPUs that have no floating-point hardware,
327 QCBOR_DISABLE_FLOAT_HW_USE should be defined in most cases. If it is
328 not, then the compiler will bring in possibly large software
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700329 libraries to compensate. Defining QCBOR_DISABLE_FLOAT_HW_USE reduces
330 object code size on CPUs with floating-point hardware by a tiny
331 amount and eliminates the need for <math.h>
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700332
Laurence Lundblade4b270642020-08-14 12:53:07 -0700333 When QCBOR_DISABLE_FLOAT_HW_USE is defined, trying to decoding
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700334 floating-point dates will give error
335 @ref QCBOR_ERR_FLOAT_DATE_DISABLED and decoded single-precision
336 numbers will be returned as @ref QCBOR_TYPE_FLOAT instead of
337 converting them to double as usual.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700338
339 If both QCBOR_DISABLE_FLOAT_HW_USE and QCBOR_DISABLE_PREFERRED_FLOAT
Laurence Lundblade4b270642020-08-14 12:53:07 -0700340 are defined, then the only thing QCBOR can do is encode/decode a C
341 float type as 32-bits and a C double type as 64-bits. Floating-point
342 epoch dates will be unsupported.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700343
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700344 ## Limitations
345
Michael Eckel5c531332020-03-02 01:35:30 +0100346 Summary Limits of this implementation:
347 - The entire encoded CBOR must fit into contiguous memory.
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700348 - Max size of encoded / decoded CBOR data is a few bytes less than @c UINT32_MAX (4GB).
Michael Eckel5c531332020-03-02 01:35:30 +0100349 - Max array / map nesting level when encoding / decoding is
350 @ref QCBOR_MAX_ARRAY_NESTING (this is typically 15).
351 - Max items in an array or map when encoding / decoding is
352 @ref QCBOR_MAX_ITEMS_IN_ARRAY (typically 65,536).
353 - Does not directly support labels in maps other than text strings & integers.
354 - Does not directly support integer labels greater than @c INT64_MAX.
355 - Epoch dates limited to @c INT64_MAX (+/- 292 billion years).
356 - Exponents for bigfloats and decimal integers are limited to @c INT64_MAX.
357 - Tags on labels are ignored during decoding.
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700358 - The maximum tag nesting is @c QCBOR_MAX_TAGS_PER_ITEM (typically 4).
Michael Eckel5c531332020-03-02 01:35:30 +0100359 - Works only on 32- and 64-bit CPUs (modifications could make it work
360 on 16-bit CPUs).
361
362 The public interface uses @c size_t for all lengths. Internally the
363 implementation uses 32-bit lengths by design to use less memory and
364 fit structures on the stack. This limits the encoded CBOR it can work
365 with to size @c UINT32_MAX (4GB) which should be enough.
366
367 This implementation assumes two's compliment integer machines. @c
368 <stdint.h> also requires this. It is possible to modify this
369 implementation for another integer representation, but all modern
370 machines seem to be two's compliment.
Michael Eckel5c531332020-03-02 01:35:30 +0100371 */
372
373
Laurence Lundblade825164e2020-10-22 20:18:06 -0700374/**
Michael Eckel5c531332020-03-02 01:35:30 +0100375 The size of the buffer to be passed to QCBOREncode_EncodeHead(). It is one
376 byte larger than sizeof(uint64_t) + 1, the actual maximum size of the
Laurence Lundblade825164e2020-10-22 20:18:06 -0700377 head of a CBOR data item because QCBOREncode_EncodeHead() needs
Michael Eckel5c531332020-03-02 01:35:30 +0100378 one extra byte to work.
379 */
380#define QCBOR_HEAD_BUFFER_SIZE (sizeof(uint64_t) + 2)
381
Michael Eckel5c531332020-03-02 01:35:30 +0100382
Laurence Lundblade9b334962020-08-27 10:55:53 -0700383/**
Laurence Lundblade825164e2020-10-22 20:18:06 -0700384 Output the full CBOR tag. See @ref CBORTags, @ref Tag-Usage and
385 @ref Tags-Overview.
Laurence Lundblade9b334962020-08-27 10:55:53 -0700386 */
387#define QCBOR_ENCODE_AS_TAG 0
388
389/**
Laurence Lundblade825164e2020-10-22 20:18:06 -0700390 Output only the 'borrowed' content format for the relevant tag.
391 See @ref CBORTags, @ref Tag-Usage and @ref Tags-Overview.
Laurence Lundblade9b334962020-08-27 10:55:53 -0700392 */
393#define QCBOR_ENCODE_AS_BORROWED 1
394
Michael Eckel5c531332020-03-02 01:35:30 +0100395
396/**
397 QCBOREncodeContext is the data type that holds context for all the
398 encoding functions. It is less than 200 bytes, so it can go on the
399 stack. The contents are opaque, and the caller should not access
400 internal members. A context may be re used serially as long as it is
401 re initialized.
402 */
403typedef struct _QCBOREncodeContext QCBOREncodeContext;
404
405
406/**
407 Initialize the encoder to prepare to encode some CBOR.
408
409 @param[in,out] pCtx The encoder context to initialize.
410 @param[in] Storage The buffer into which this encoded result
411 will be placed.
412
413 Call this once at the start of an encoding of a CBOR structure. Then
414 call the various @c QCBOREncode_AddXxx() functions to add the data
415 items. Then call QCBOREncode_Finish().
416
417 The maximum output buffer is @c UINT32_MAX (4GB). This is not a
418 practical limit in any way and reduces the memory needed by the
419 implementation. The error @ref QCBOR_ERR_BUFFER_TOO_LARGE will be
420 returned by QCBOREncode_Finish() if a larger buffer length is passed
421 in.
422
423 If this is called with @c Storage.ptr as @c NULL and @c Storage.len a
424 large value like @c UINT32_MAX, all the QCBOREncode_AddXxx()
425 functions and QCBOREncode_Finish() can still be called. No data will
426 be encoded, but the length of what would be encoded will be
427 calculated. The length of the encoded structure will be handed back
428 in the call to QCBOREncode_Finish(). You can then allocate a buffer
429 of that size and call all the encoding again, this time to fill in
430 the buffer.
431
432 A @ref QCBOREncodeContext can be reused over and over as long as
433 QCBOREncode_Init() is called.
434 */
435void QCBOREncode_Init(QCBOREncodeContext *pCtx, UsefulBuf Storage);
436
437
438/**
439 @brief Add a signed 64-bit integer to the encoded output.
440
441 @param[in] pCtx The encoding context to add the integer to.
442 @param[in] nNum The integer to add.
443
444 The integer will be encoded and added to the CBOR output.
445
446 This function figures out the size and the sign and encodes in the
447 correct minimal CBOR. Specifically, it will select CBOR major type 0
448 or 1 based on sign and will encode to 1, 2, 4 or 8 bytes depending on
449 the value of the integer. Values less than 24 effectively encode to
450 one byte because they are encoded in with the CBOR major type. This
451 is a neat and efficient characteristic of CBOR that can be taken
452 advantage of when designing CBOR-based protocols. If integers like
453 tags can be kept between -23 and 23 they will be encoded in one byte
454 including the major type.
455
456 If you pass a smaller int, say an @c int16_t or a small value, say
457 100, the encoding will still be CBOR's most compact that can
458 represent the value. For example, CBOR always encodes the value 0 as
459 one byte, 0x00. The representation as 0x00 includes identification of
460 the type as an integer too as the major type for an integer is 0. See
461 [RFC 7049] (https://tools.ietf.org/html/rfc7049) Appendix A for more
462 examples of CBOR encoding. This compact encoding is also canonical
463 CBOR as per section 3.9 in RFC 7049.
464
465 There are no functions to add @c int16_t or @c int32_t because they
466 are not necessary because this always encodes to the smallest number
467 of bytes based on the value (If this code is running on a 32-bit
468 machine having a way to add 32-bit integers would reduce code size
469 some).
470
471 If the encoding context is in an error state, this will do
472 nothing. If an error occurs when adding this integer, the internal
473 error flag will be set, and the error will be returned when
474 QCBOREncode_Finish() is called.
475
476 See also QCBOREncode_AddUInt64().
477 */
478void QCBOREncode_AddInt64(QCBOREncodeContext *pCtx, int64_t nNum);
479
480static void QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum);
481
482static void QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum);
483
484
485/**
486 @brief Add an unsigned 64-bit integer to the encoded output.
487
488 @param[in] pCtx The encoding context to add the integer to.
489 @param[in] uNum The integer to add.
490
491 The integer will be encoded and added to the CBOR output.
492
493 The only reason so use this function is for integers larger than @c
494 INT64_MAX and smaller than @c UINT64_MAX. Otherwise
495 QCBOREncode_AddInt64() will work fine.
496
497 Error handling is the same as for QCBOREncode_AddInt64().
498 */
499void QCBOREncode_AddUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
500
501static void QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum);
502
503static void QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum);
504
505
506/**
507 @brief Add a UTF-8 text string to the encoded output.
508
509 @param[in] pCtx The encoding context to add the text to.
510 @param[in] Text Pointer and length of text to add.
511
512 The text passed in must be unencoded UTF-8 according to [RFC 3629]
513 (https://tools.ietf.org/html/rfc3629). There is no NULL
514 termination. The text is added as CBOR major type 3.
515
516 If called with @c nBytesLen equal to 0, an empty string will be
517 added. When @c nBytesLen is 0, @c pBytes may be @c NULL.
518
519 Note that the restriction of the buffer length to a @c uint32_t is
520 entirely intentional as this encoder is not capable of encoding
521 lengths greater. This limit to 4GB for a text string should not be a
522 problem.
523
Laurence Lundbladeadaf5c22020-09-25 10:37:09 -0700524 Text lines in Internet protocols (on the wire) are delimited by
525 either a CRLF or just an LF. Officially many protocols specify CRLF,
526 but implementations often work with either. CBOR type 3 text can be
527 either line ending, even a mixture of both.
528
529 Operating systems usually have a line end convention. Windows uses
530 CRLF. Linux and MacOS use LF. Some applications on a given OS may
531 work with either and some may not.
532
533 The majority of use cases and CBOR protocols using type 3 text will
534 work with either line ending. However, some use cases or protocols
535 may not work with either in which case translation to and/or from the
536 local line end convention, typically that of the OS, is necessary.
537
538 QCBOR does no line ending translation for type 3 text when encoding
539 and decoding.
540
Michael Eckel5c531332020-03-02 01:35:30 +0100541 Error handling is the same as QCBOREncode_AddInt64().
542 */
543static void QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text);
544
545static void QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text);
546
547static void QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text);
548
549
550/**
551 @brief Add a UTF-8 text string to the encoded output.
552
553 @param[in] pCtx The encoding context to add the text to.
554 @param[in] szString Null-terminated text to add.
555
556 This works the same as QCBOREncode_AddText().
557 */
558static void QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString);
559
560static void QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString);
561
562static void QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString);
563
564
565/**
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700566 @brief Add a double-precision floating-point number to the encoded output.
Michael Eckel5c531332020-03-02 01:35:30 +0100567
568 @param[in] pCtx The encoding context to add the double to.
569 @param[in] dNum The double-precision number to add.
570
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700571 This encodes and outputs a floating-point number. CBOR major type 7
572 is used.
Michael Eckel5c531332020-03-02 01:35:30 +0100573
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700574 This implements preferred serialization, selectively encoding the
575 double-precision floating-point number as either double-precision,
576 single-precision or half-precision. Infinity, NaN and 0 are always
577 encoded as half-precision. If no precision will be lost in the
578 conversion to half-precision, then it will be converted and
579 encoded. If not and no precision will be lost in conversion to
580 single-precision, then it will be converted and encoded. If not, then
581 no conversion is performed, and it encoded as a double-precision.
Michael Eckel5c531332020-03-02 01:35:30 +0100582
583 Half-precision floating-point numbers take up 2 bytes, half that of
584 single-precision, one quarter of double-precision
585
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700586 This automatically reduces the size of encoded CBOR, maybe even by
587 four if most of values are 0, infinity or NaN.
Michael Eckel5c531332020-03-02 01:35:30 +0100588
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700589 When decoded, QCBOR will usually return these values as
590 double-precision.
591
592 It is possible to disable this preferred serialization when compiling
593 QCBOR. In that case, this functions the same as
594 QCBOREncode_AddDoubleNoPreferred().
Michael Eckel5c531332020-03-02 01:35:30 +0100595
596 Error handling is the same as QCBOREncode_AddInt64().
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700597
598 See also QCBOREncode_AddDoubleNoPreferred(), QCBOREncode_AddFloat()
599 and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
Michael Eckel5c531332020-03-02 01:35:30 +0100600 */
601void QCBOREncode_AddDouble(QCBOREncodeContext *pCtx, double dNum);
602
603static void QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
604
605static void QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
606
607
608/**
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700609 @brief Add a single-precision floating-point number to the encoded output.
610
611 @param[in] pCtx The encoding context to add the double to.
612 @param[in] fNum The single-precision number to add.
613
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700614 This is identical to QCBOREncode_AddDouble() except the input is
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700615 single-precision.
616
617 See also QCBOREncode_AddDouble(), QCBOREncode_AddDoubleNoPreferred(),
618 and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
619*/
620void QCBOREncode_AddFloat(QCBOREncodeContext *pCtx, float fNum);
621
622static void QCBOREncode_AddFloatToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
623
624static void QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700625
626
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700627/**
628 @brief Add a double-precision floating-point number without preferred encoding.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700629
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700630 @param[in] pCtx The encoding context to add the double to.
631 @param[in] dNum The double-precision number to add.
632
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700633 This always outputs the number as a 64-bit double-precision.
634 Preferred serialization is not used.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700635
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700636 Error handling is the same as QCBOREncode_AddInt64().
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700637
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700638 See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
639 QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700640*/
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700641void QCBOREncode_AddDoubleNoPreferred(QCBOREncodeContext *pCtx, double dNum);
642
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700643static void QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
644
645static void QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
646
647
648/**
649 @brief Add a single-precision floating-point number without preferred encoding.
650
651 @param[in] pCtx The encoding context to add the double to.
652 @param[in] fNum The single-precision number to add.
653
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700654 This always outputs the number as a 32-bit single-precision.
655 Preferred serialization is not used.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700656
657 Error handling is the same as QCBOREncode_AddInt64().
658
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700659 See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
660 QCBOREncode_AddDoubleNoPreferred() and @ref Floating-Point.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700661*/
662void QCBOREncode_AddFloatNoPreferred(QCBOREncodeContext *pCtx, float fNum);
663
664static void QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
665
666static void QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float fNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700667
668
Michael Eckel5c531332020-03-02 01:35:30 +0100669/**
670 @brief Add an optional tag.
671
672 @param[in] pCtx The encoding context to add the tag to.
673 @param[in] uTag The tag to add
674
675 This outputs a CBOR major type 6 item that tags the next data item
676 that is output usually to indicate it is some new data type.
677
678 For many of the common standard tags, a function to encode data using
679 it is provided and this is not needed. For example,
680 QCBOREncode_AddDateEpoch() already exists to output integers
681 representing dates with the right tag.
682
683 The tag is applied to the next data item added to the encoded
684 output. That data item that is to be tagged can be of any major CBOR
685 type. Any number of tags can be added to a data item by calling this
686 multiple times before the data item is added.
687
688 See @ref Tags-Overview for discussion of creating new non-standard
689 tags. See QCBORDecode_GetNext() for discussion of decoding custom
690 tags.
691*/
Laurence Lundblade6416a0f2020-09-19 23:26:34 -0700692void QCBOREncode_AddTag(QCBOREncodeContext *pCtx, uint64_t uTag);
Michael Eckel5c531332020-03-02 01:35:30 +0100693
694
695/**
696 @brief Add an epoch-based date.
697
698 @param[in] pCtx The encoding context to add the date to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700699 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700700 @param[in] nDate Number of seconds since 1970-01-01T00:00Z in UTC time.
Michael Eckel5c531332020-03-02 01:35:30 +0100701
702 As per RFC 7049 this is similar to UNIX/Linux/POSIX dates. This is
703 the most compact way to specify a date and time in CBOR. Note that
704 this is always UTC and does not include the time zone. Use
705 QCBOREncode_AddDateString() if you want to include the time zone.
706
707 The integer encoding rules apply here so the date will be encoded in
708 a minimal number of bytes. Until about the year 2106 these dates will
709 encode in 6 bytes -- one byte for the tag, one byte for the type and
710 4 bytes for the integer. After that it will encode to 10 bytes.
711
712 Negative values are supported for dates before 1970.
713
714 If you care about leap-seconds and that level of accuracy, make sure
715 the system you are running this code on does it correctly. This code
716 just takes the value passed in.
717
718 This implementation cannot encode fractional seconds using float or
719 double even though that is allowed by CBOR, but you can encode them
720 if you want to by calling QCBOREncode_AddDouble() and
721 QCBOREncode_AddTag().
722
723 Error handling is the same as QCBOREncode_AddInt64().
724 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700725static void QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pCtx,
726 uint8_t uTagRequirement,
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700727 int64_t nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -0700728
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700729static void QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pCtx,
730 const char *szLabel,
731 uint8_t uTagRequirement,
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700732 int64_t nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -0700733
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700734static void QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pCtx,
735 int64_t nLabel,
736 uint8_t uTagRequirement,
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700737 int64_t nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -0700738
739
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700740static void QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx,
741 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100742
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700743static void QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx,
744 const char *szLabel,
745 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100746
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700747static void QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx,
748 int64_t nLabel,
749 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100750
751
752/**
753 @brief Add a byte string to the encoded output.
754
755 @param[in] pCtx The encoding context to add the bytes to.
756 @param[in] Bytes Pointer and length of the input data.
757
758 Simply adds the bytes to the encoded output as CBOR major type 2.
759
760 If called with @c Bytes.len equal to 0, an empty string will be
761 added. When @c Bytes.len is 0, @c Bytes.ptr may be @c NULL.
762
763 Error handling is the same as QCBOREncode_AddInt64().
764 */
765static void QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
766
767static void QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
768
769static void QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
770
771
Michael Eckel5c531332020-03-02 01:35:30 +0100772/**
773 @brief Add a binary UUID to the encoded output.
774
775 @param[in] pCtx The encoding context to add the UUID to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700776 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100777 @param[in] Bytes Pointer and length of the binary UUID.
778
779 A binary UUID as defined in [RFC 4122]
780 (https://tools.ietf.org/html/rfc4122) is added to the output.
781
782 It is output as CBOR major type 2, a binary string, with tag @ref
783 CBOR_TAG_BIN_UUID indicating the binary string is a UUID.
784 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700785static void QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pCtx,
786 uint8_t uTagRequirement,
787 UsefulBufC Bytes);
788
789static void QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pCtx,
790 const char *szLabel,
791 uint8_t uTagRequirement,
792 UsefulBufC Bytes);
793
794static void QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pCtx,
795 int64_t nLabel,
796 uint8_t uTagRequirement,
797 UsefulBufC Bytes);
798
799
Michael Eckel5c531332020-03-02 01:35:30 +0100800static void QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
801
802static void QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
803
804static void QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
805
806
807/**
808 @brief Add a positive big number to the encoded output.
809
810 @param[in] pCtx The encoding context to add the big number to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700811 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100812 @param[in] Bytes Pointer and length of the big number.
813
814 Big numbers are integers larger than 64-bits. Their format is
815 described in [RFC 7049] (https://tools.ietf.org/html/rfc7049).
816
817 It is output as CBOR major type 2, a binary string, with tag @ref
818 CBOR_TAG_POS_BIGNUM indicating the binary string is a positive big
819 number.
820
821 Often big numbers are used to represent cryptographic keys, however,
822 COSE which defines representations for keys chose not to use this
823 particular type.
824 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700825static void QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pCtx,
826 uint8_t uTagRequirement,
827 UsefulBufC Bytes);
828
829static void QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pCtx,
830 const char *szLabel,
831 uint8_t uTagRequirement,
832 UsefulBufC Bytes);
833
834static void QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pCtx,
835 int64_t nLabel,
836 uint8_t uTagRequirement,
837 UsefulBufC Bytes);
838
839
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700840static void QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx,
841 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100842
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700843static void QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx,
844 const char *szLabel,
845 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100846
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700847static void QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx,
848 int64_t nLabel,
849 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100850
851
852/**
853 @brief Add a negative big number to the encoded output.
854
855 @param[in] pCtx The encoding context to add the big number to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700856 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100857 @param[in] Bytes Pointer and length of the big number.
858
859 Big numbers are integers larger than 64-bits. Their format is
860 described in [RFC 7049] (https://tools.ietf.org/html/rfc7049).
861
862 It is output as CBOR major type 2, a binary string, with tag @ref
863 CBOR_TAG_NEG_BIGNUM indicating the binary string is a negative big
864 number.
865
866 Often big numbers are used to represent cryptographic keys, however,
867 COSE which defines representations for keys chose not to use this
868 particular type.
869 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700870static void QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pCtx,
871 uint8_t uTagRequirement,
872 UsefulBufC Bytes);
873
874static void QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pCtx,
875 const char *szLabel,
876 uint8_t uTagRequirement,
877 UsefulBufC Bytes);
878
879static void QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pCtx,
880 int64_t nLabel,
881 uint8_t uTagRequirement,
882 UsefulBufC Bytes);
883
884
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700885static void QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx,
886 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100887
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700888static void QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx,
889 const char *szLabel,
890 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100891
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700892static void QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx,
893 int64_t nLabel,
894 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100895
896
897#ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
898/**
899 @brief Add a decimal fraction to the encoded output.
900
901 @param[in] pCtx The encoding context to add the decimal fraction to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700902 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100903 @param[in] nMantissa The mantissa.
904 @param[in] nBase10Exponent The exponent.
905
906 The value is nMantissa * 10 ^ nBase10Exponent.
907
908 A decimal fraction is good for exact representation of some values
909 that can't be represented exactly with standard C (IEEE 754)
910 floating-point numbers. Much larger and much smaller numbers can
911 also be represented than floating-point because of the larger number
912 of bits in the exponent.
913
914 The decimal fraction is conveyed as two integers, a mantissa and a
915 base-10 scaling factor.
916
917 For example, 273.15 is represented by the two integers 27315 and -2.
918
919 The exponent and mantissa have the range from @c INT64_MIN to
920 @c INT64_MAX for both encoding and decoding (CBOR allows @c -UINT64_MAX
921 to @c UINT64_MAX, but this implementation doesn't support this range to
922 reduce code size and interface complexity a little).
923
924 CBOR Preferred encoding of the integers is used, thus they will be encoded
925 in the smallest number of bytes possible.
926
927 See also QCBOREncode_AddDecimalFractionBigNum() for a decimal
928 fraction with arbitrarily large precision and QCBOREncode_AddBigFloat().
929
930 There is no representation of positive or negative infinity or NaN
931 (Not a Number). Use QCBOREncode_AddDouble() to encode them.
932
933 See @ref expAndMantissa for decoded representation.
934 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700935static void QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pCtx,
936 uint8_t uTagRequirement,
937 int64_t nMantissa,
938 int64_t nBase10Exponent);
939
940static void QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -0700941 const char *szLabel,
942 uint8_t uTagRequirement,
943 int64_t nMantissa,
944 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700945
946static void QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pCtx,
947 int64_t nLabel,
948 uint8_t uTagRequirement,
949 int64_t nMantissa,
950 int64_t nBase10Exponent);
951
952
Michael Eckel5c531332020-03-02 01:35:30 +0100953static void QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pCtx,
954 int64_t nMantissa,
955 int64_t nBase10Exponent);
956
957static void QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pCtx,
958 const char *szLabel,
959 int64_t nMantissa,
960 int64_t nBase10Exponent);
961
962static void QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pCtx,
963 int64_t nLabel,
964 int64_t nMantissa,
965 int64_t nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +0100966/**
967 @brief Add a decimal fraction with a big number mantissa to the encoded output.
968
969 @param[in] pCtx The encoding context to add the decimal fraction to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700970 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100971 @param[in] Mantissa The mantissa.
972 @param[in] bIsNegative false if mantissa is positive, true if negative.
973 @param[in] nBase10Exponent The exponent.
974
975 This is the same as QCBOREncode_AddDecimalFraction() except the
976 mantissa is a big number (See QCBOREncode_AddPositiveBignum())
977 allowing for arbitrarily large precision.
978
979 See @ref expAndMantissa for decoded representation.
980 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700981static void QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pCtx,
982 uint8_t uTagRequirement,
983 UsefulBufC Mantissa,
984 bool bIsNegative,
985 int64_t nBase10Exponent);
986
987static void QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -0700988 const char *szLabel,
989 uint8_t uTagRequirement,
990 UsefulBufC Mantissa,
991 bool bIsNegative,
992 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700993
994static void QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
995 int64_t nLabel,
996 uint8_t uTagRequirement,
997 UsefulBufC Mantissa,
998 bool bIsNegative,
999 int64_t nBase10Exponent);
1000
1001
Michael Eckel5c531332020-03-02 01:35:30 +01001002static void QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pCtx,
1003 UsefulBufC Mantissa,
1004 bool bIsNegative,
1005 int64_t nBase10Exponent);
1006
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001007static void QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001008 const char *szLabel,
1009 UsefulBufC Mantissa,
1010 bool bIsNegative,
1011 int64_t nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01001012
1013static void QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
1014 int64_t nLabel,
1015 UsefulBufC Mantissa,
1016 bool bIsNegative,
1017 int64_t nBase10Exponent);
1018
1019/**
1020 @brief Add a big floating-point number to the encoded output.
1021
1022 @param[in] pCtx The encoding context to add the bigfloat to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001023 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001024 @param[in] nMantissa The mantissa.
1025 @param[in] nBase2Exponent The exponent.
1026
1027 The value is nMantissa * 2 ^ nBase2Exponent.
1028
1029 "Bigfloats", as CBOR terms them, are similar to IEEE floating-point
1030 numbers in having a mantissa and base-2 exponent, but they are not
1031 supported by hardware or encoded the same. They explicitly use two
1032 CBOR-encoded integers to convey the mantissa and exponent, each of which
1033 can be 8, 16, 32 or 64 bits. With both the mantissa and exponent
1034 64 bits they can express more precision and a larger range than an
1035 IEEE double floating-point number. See
1036 QCBOREncode_AddBigFloatBigNum() for even more precision.
1037
1038 For example, 1.5 would be represented by a mantissa of 3 and an
1039 exponent of -1.
1040
1041 The exponent and mantissa have the range from @c INT64_MIN to
1042 @c INT64_MAX for both encoding and decoding (CBOR allows @c -UINT64_MAX
1043 to @c UINT64_MAX, but this implementation doesn't support this range to
1044 reduce code size and interface complexity a little).
1045
1046 CBOR Preferred encoding of the integers is used, thus they will be encoded
1047 in the smallest number of bytes possible.
1048
1049 This can also be used to represent floating-point numbers in
1050 environments that don't support IEEE 754.
1051
1052 See @ref expAndMantissa for decoded representation.
1053 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001054static void QCBOREncode_AddTBigFloat(QCBOREncodeContext *pCtx,
1055 uint8_t uTagRequirement,
1056 int64_t nMantissa,
1057 int64_t nBase2Exponent);
1058
1059static void QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001060 const char *szLabel,
1061 uint8_t uTagRequirement,
1062 int64_t nMantissa,
1063 int64_t nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001064
1065static void QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pCtx,
1066 int64_t nLabel,
1067 uint8_t uTagRequirement,
1068 int64_t nMantissa,
1069 int64_t nBase2Exponent);
1070
1071
Michael Eckel5c531332020-03-02 01:35:30 +01001072static void QCBOREncode_AddBigFloat(QCBOREncodeContext *pCtx,
1073 int64_t nMantissa,
1074 int64_t nBase2Exponent);
1075
1076static void QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pCtx,
1077 const char *szLabel,
1078 int64_t nMantissa,
1079 int64_t nBase2Exponent);
1080
1081static void QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pCtx,
1082 int64_t nLabel,
1083 int64_t nMantissa,
1084 int64_t nBase2Exponent);
1085
Michael Eckel5c531332020-03-02 01:35:30 +01001086/**
1087 @brief Add a big floating-point number with a big number mantissa to
1088 the encoded output.
1089
1090 @param[in] pCtx The encoding context to add the bigfloat to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001091 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001092 @param[in] Mantissa The mantissa.
1093 @param[in] bIsNegative false if mantissa is positive, true if negative.
1094 @param[in] nBase2Exponent The exponent.
1095
1096 This is the same as QCBOREncode_AddBigFloat() except the mantissa is
1097 a big number (See QCBOREncode_AddPositiveBignum()) allowing for
1098 arbitrary precision.
1099
1100 See @ref expAndMantissa for decoded representation.
1101 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001102static void QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pCtx,
1103 uint8_t uTagRequirement,
1104 UsefulBufC Mantissa,
1105 bool bIsNegative,
1106 int64_t nBase2Exponent);
1107
1108static void QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001109 const char *szLabel,
1110 uint8_t uTagRequirement,
1111 UsefulBufC Mantissa,
1112 bool bIsNegative,
1113 int64_t nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001114
1115static void QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1116 int64_t nLabel,
1117 uint8_t uTagRequirement,
1118 UsefulBufC Mantissa,
1119 bool bIsNegative,
1120 int64_t nBase2Exponent);
1121
1122
Michael Eckel5c531332020-03-02 01:35:30 +01001123static void QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pCtx,
1124 UsefulBufC Mantissa,
1125 bool bIsNegative,
1126 int64_t nBase2Exponent);
1127
1128static void QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pCtx,
1129 const char *szLabel,
1130 UsefulBufC Mantissa,
1131 bool bIsNegative,
1132 int64_t nBase2Exponent);
1133
1134static void QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1135 int64_t nLabel,
1136 UsefulBufC Mantissa,
1137 bool bIsNegative,
1138 int64_t nBase2Exponent);
1139#endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
1140
1141
1142/**
1143 @brief Add a text URI to the encoded output.
1144
1145 @param[in] pCtx The encoding context to add the URI to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001146 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001147 @param[in] URI Pointer and length of the URI.
1148
1149 The format of URI must be per [RFC 3986]
1150 (https://tools.ietf.org/html/rfc3986).
1151
1152 It is output as CBOR major type 3, a text string, with tag @ref
1153 CBOR_TAG_URI indicating the text string is a URI.
1154
1155 A URI in a NULL-terminated string, @c szURI, can be easily added with
1156 this code:
1157
1158 QCBOREncode_AddURI(pCtx, UsefulBuf_FromSZ(szURI));
1159 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001160static void QCBOREncode_AddTURI(QCBOREncodeContext *pCtx,
1161 uint8_t uTagRequirement,
1162 UsefulBufC URI);
1163
1164static void QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pCtx,
1165 const char *szLabel,
1166 uint8_t uTagRequirement,
1167 UsefulBufC URI);
1168
1169static void QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pCtx,
1170 int64_t nLabel,
1171 uint8_t uTagRequirement,
1172 UsefulBufC URI);
1173
1174
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001175static void QCBOREncode_AddURI(QCBOREncodeContext *pCtx,
1176 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001177
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001178static void QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx,
1179 const char *szLabel,
1180 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001181
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001182static void QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx,
1183 int64_t nLabel,
1184 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001185
1186
1187/**
1188 @brief Add Base64-encoded text to encoded output.
1189
1190 @param[in] pCtx The encoding context to add the base-64 text to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001191 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001192 @param[in] B64Text Pointer and length of the base-64 encoded text.
1193
1194 The text content is Base64 encoded data per [RFC 4648]
1195 (https://tools.ietf.org/html/rfc4648).
1196
1197 It is output as CBOR major type 3, a text string, with tag @ref
1198 CBOR_TAG_B64 indicating the text string is Base64 encoded.
1199 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001200static void QCBOREncode_AddTB64Text(QCBOREncodeContext *pCtx,
1201 uint8_t uTagRequirement,
1202 UsefulBufC B64Text);
1203
1204static void QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pCtx,
1205 const char *szLabel,
1206 uint8_t uTagRequirement,
1207 UsefulBufC B64Text);
1208
1209static void QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pCtx,
1210 int64_t nLabel,
1211 uint8_t uTagRequirement,
1212 UsefulBufC B64Text);
1213
1214
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001215static void QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx,
1216 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001217
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001218static void QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx,
1219 const char *szLabel,
1220 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001221
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001222static void QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx,
1223 int64_t nLabel,
1224 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001225
1226
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001227
Michael Eckel5c531332020-03-02 01:35:30 +01001228/**
1229 @brief Add base64url encoded data to encoded output.
1230
1231 @param[in] pCtx The encoding context to add the base64url to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001232 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001233 @param[in] B64Text Pointer and length of the base64url encoded text.
1234
1235 The text content is base64URL encoded text as per [RFC 4648]
1236 (https://tools.ietf.org/html/rfc4648).
1237
1238 It is output as CBOR major type 3, a text string, with tag @ref
1239 CBOR_TAG_B64URL indicating the text string is a Base64url encoded.
1240 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001241static void QCBOREncode_AddTB64URLText(QCBOREncodeContext *pCtx,
1242 uint8_t uTagRequirement,
1243 UsefulBufC B64Text);
1244
1245static void QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pCtx,
1246 const char *szLabel,
1247 uint8_t uTagRequirement,
1248 UsefulBufC B64Text);
1249
1250static void QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pCtx,
1251 int64_t nLabel,
1252 uint8_t uTagRequirement,
1253 UsefulBufC B64Text);
1254
1255
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001256static void QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx,
1257 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001258
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001259static void QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx,
1260 const char *szLabel,
1261 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001262
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001263static void QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx,
1264 int64_t nLabel,
1265 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001266
1267
1268/**
1269 @brief Add Perl Compatible Regular Expression.
1270
1271 @param[in] pCtx The encoding context to add the regular expression to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001272 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001273 @param[in] Regex Pointer and length of the regular expression.
1274
1275 The text content is Perl Compatible Regular
1276 Expressions (PCRE) / JavaScript syntax [ECMA262].
1277
1278 It is output as CBOR major type 3, a text string, with tag @ref
1279 CBOR_TAG_REGEX indicating the text string is a regular expression.
1280 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001281static void QCBOREncode_AddTRegex(QCBOREncodeContext *pCtx,
1282 uint8_t uTagRequirement,
1283 UsefulBufC Regex);
1284
1285static void QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pCtx,
1286 const char *szLabel,
1287 uint8_t uTagRequirement,
1288 UsefulBufC Regex);
1289
1290static void QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pCtx,
1291 int64_t nLabel,
1292 uint8_t uTagRequirement,
1293 UsefulBufC Regex);
1294
1295
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001296static void QCBOREncode_AddRegex(QCBOREncodeContext *pCtx,
1297 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001298
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001299static void QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx,
1300 const char *szLabel,
1301 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001302
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001303static void QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx,
1304 int64_t nLabel,
1305 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001306
1307
1308/**
Laurence Lundblade4982f412020-09-18 23:02:18 -07001309 @brief MIME encoded data to the encoded output.
Michael Eckel5c531332020-03-02 01:35:30 +01001310
Laurence Lundblade4982f412020-09-18 23:02:18 -07001311 @param[in] pCtx The encoding context to add the MIME data to.
1312 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1313 @ref QCBOR_ENCODE_AS_BORROWED.
1314 @param[in] MIMEData Pointer and length of the MIME data.
Michael Eckel5c531332020-03-02 01:35:30 +01001315
1316 The text content is in MIME format per [RFC 2045]
Laurence Lundblade4982f412020-09-18 23:02:18 -07001317 (https://tools.ietf.org/html/rfc2045) including the headers.
Michael Eckel5c531332020-03-02 01:35:30 +01001318
Laurence Lundblade4982f412020-09-18 23:02:18 -07001319 It is output as CBOR major type 2, a binary string, with tag @ref
1320 CBOR_TAG_BINARY_MIME indicating the string is MIME data. This
1321 outputs tag 257, not tag 36, as it can carry any type of MIME binary,
1322 7-bit, 8-bit, quoted-printable and base64 where tag 36 cannot.
1323
1324 Previous versions of QCBOR, those before spiffy decode, output tag
1325 36. Decoding supports both tag 36 and 257. (if the old behavior with
1326 tag 36 is needed, copy the inline functions below and change the tag
1327 number).
1328
1329 See also QCBORDecode_GetMIMEMessage() and
1330 @ref QCBOR_TYPE_BINARY_MIME.
Laurence Lundbladeadaf5c22020-09-25 10:37:09 -07001331
1332 This does no translation of line endings. See QCBOREncode_AddText()
1333 for a discussion of line endings in CBOR.
Michael Eckel5c531332020-03-02 01:35:30 +01001334 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001335static void QCBOREncode_AddTMIMEData(QCBOREncodeContext *pCtx,
1336 uint8_t uTagRequirement,
1337 UsefulBufC MIMEData);
1338
1339static void QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pCtx,
1340 const char *szLabel,
1341 uint8_t uTagRequirement,
1342 UsefulBufC MIMEData);
1343
1344static void QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pCtx,
1345 int64_t nLabel,
1346 uint8_t uTagRequirement,
1347 UsefulBufC MIMEData);
1348
1349
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001350static void QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx,
1351 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001352
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001353static void QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx,
1354 const char *szLabel,
1355 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001356
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001357static void QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx,
1358 int64_t nLabel,
1359 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001360
1361
1362/**
1363 @brief Add an RFC 3339 date string
1364
1365 @param[in] pCtx The encoding context to add the date to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001366 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001367 @param[in] szDate Null-terminated string with date to add.
1368
1369 The string szDate should be in the form of [RFC 3339]
1370 (https://tools.ietf.org/html/rfc3339) as defined by section 3.3 in
1371 [RFC 4287] (https://tools.ietf.org/html/rfc4287). This is as
1372 described in section 2.4.1 in [RFC 7049]
1373 (https://tools.ietf.org/html/rfc7049).
1374
1375 Note that this function doesn't validate the format of the date string
1376 at all. If you add an incorrect format date string, the generated
1377 CBOR will be incorrect and the receiver may not be able to handle it.
1378
1379 Error handling is the same as QCBOREncode_AddInt64().
1380 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001381static void QCBOREncode_AddTDateString(QCBOREncodeContext *pCtx,
1382 uint8_t uTagRequirement,
1383 const char *szDate);
1384
1385static void QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pCtx,
1386 const char *szLabel,
1387 uint8_t uTagRequirement,
1388 const char *szDate);
1389
1390static void QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pCtx,
1391 int64_t nLabel,
1392 uint8_t uTagRequirement,
1393 const char *szDate);
1394
1395
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001396static void QCBOREncode_AddDateString(QCBOREncodeContext *pCtx,
1397 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001398
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001399static void QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx,
1400 const char *szLabel,
1401 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001402
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001403static void QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx,
1404 int64_t nLabel,
1405 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001406
Michael Eckel5c531332020-03-02 01:35:30 +01001407/**
1408 @brief Add a standard Boolean.
1409
1410 @param[in] pCtx The encoding context to add the Boolean to.
1411 @param[in] b true or false from @c <stdbool.h>.
1412
1413 Adds a Boolean value as CBOR major type 7.
1414
1415 Error handling is the same as QCBOREncode_AddInt64().
1416 */
1417static void QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b);
1418
1419static void QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b);
1420
1421static void QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b);
1422
1423
1424
1425/**
1426 @brief Add a NULL to the encoded output.
1427
1428 @param[in] pCtx The encoding context to add the NULL to.
1429
1430 Adds the NULL value as CBOR major type 7.
1431
1432 This NULL doesn't have any special meaning in CBOR such as a
1433 terminating value for a string or an empty value.
1434
1435 Error handling is the same as QCBOREncode_AddInt64().
1436 */
1437static void QCBOREncode_AddNULL(QCBOREncodeContext *pCtx);
1438
1439static void QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1440
1441static void QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1442
1443
1444/**
1445 @brief Add an "undef" to the encoded output.
1446
1447 @param[in] pCtx The encoding context to add the "undef" to.
1448
1449 Adds the undef value as CBOR major type 7.
1450
1451 Note that this value will not translate to JSON.
1452
1453 This Undef doesn't have any special meaning in CBOR such as a
1454 terminating value for a string or an empty value.
1455
1456 Error handling is the same as QCBOREncode_AddInt64().
1457 */
1458static void QCBOREncode_AddUndef(QCBOREncodeContext *pCtx);
1459
1460static void QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1461
1462static void QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1463
1464
1465/**
1466 @brief Indicates that the next items added are in an array.
1467
1468 @param[in] pCtx The encoding context to open the array in.
1469
1470 Arrays are the basic CBOR aggregate or structure type. Call this
1471 function to start or open an array. Then call the various @c
1472 QCBOREncode_AddXxx() functions to add the items that go into the
1473 array. Then call QCBOREncode_CloseArray() when all items have been
1474 added. The data items in the array can be of any type and can be of
1475 mixed types.
1476
1477 Nesting of arrays and maps is allowed and supported just by calling
1478 QCBOREncode_OpenArray() again before calling
1479 QCBOREncode_CloseArray(). While CBOR has no limit on nesting, this
1480 implementation does in order to keep it smaller and simpler. The
1481 limit is @ref QCBOR_MAX_ARRAY_NESTING. This is the max number of
1482 times this can be called without calling
1483 QCBOREncode_CloseArray(). QCBOREncode_Finish() will return @ref
1484 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP when it is called as this function
1485 just sets an error state and returns no value when this occurs.
1486
1487 If you try to add more than @ref QCBOR_MAX_ITEMS_IN_ARRAY items to a
1488 single array or map, @ref QCBOR_ERR_ARRAY_TOO_LONG will be returned
1489 when QCBOREncode_Finish() is called.
1490
1491 An array itself must have a label if it is being added to a map.
1492 Note that array elements do not have labels (but map elements do).
1493
1494 An array itself may be tagged by calling QCBOREncode_AddTag() before this call.
1495 */
1496static void QCBOREncode_OpenArray(QCBOREncodeContext *pCtx);
1497
1498static void QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1499
1500static void QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1501
1502
1503/**
1504 @brief Close an open array.
1505
1506 @param[in] pCtx The encoding context to close the array in.
1507
1508 The closes an array opened by QCBOREncode_OpenArray(). It reduces
1509 nesting level by one. All arrays (and maps) must be closed before
1510 calling QCBOREncode_Finish().
1511
1512 When an error occurs as a result of this call, the encoder records
1513 the error and enters the error state. The error will be returned when
1514 QCBOREncode_Finish() is called.
1515
1516 If this has been called more times than QCBOREncode_OpenArray(), then
1517 @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when QCBOREncode_Finish()
1518 is called.
1519
1520 If this is called and it is not an array that is currently open, @ref
1521 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
1522 is called.
1523 */
1524static void QCBOREncode_CloseArray(QCBOREncodeContext *pCtx);
1525
1526
1527/**
1528 @brief Indicates that the next items added are in a map.
1529
1530 @param[in] pCtx The encoding context to open the map in.
1531
1532 See QCBOREncode_OpenArray() for more information, particularly error
1533 handling.
1534
1535 CBOR maps are an aggregate type where each item in the map consists
1536 of a label and a value. They are similar to JSON objects.
1537
1538 The value can be any CBOR type including another map.
1539
1540 The label can also be any CBOR type, but in practice they are
1541 typically, integers as this gives the most compact output. They might
1542 also be text strings which gives readability and translation to JSON.
1543
1544 Every @c QCBOREncode_AddXxx() call has one version that ends with @c
1545 InMap for adding items to maps with string labels and one that ends
1546 with @c InMapN that is for adding with integer labels.
1547
1548 RFC 7049 uses the term "key" instead of "label".
1549
1550 If you wish to use map labels that are neither integer labels nor
1551 text strings, then just call the QCBOREncode_AddXxx() function
1552 explicitly to add the label. Then call it again to add the value.
1553
1554 See the [RFC 7049] (https://tools.ietf.org/html/rfc7049) for a lot
1555 more information on creating maps.
1556 */
1557static void QCBOREncode_OpenMap(QCBOREncodeContext *pCtx);
1558
1559static void QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1560
1561static void QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1562
1563
Michael Eckel5c531332020-03-02 01:35:30 +01001564/**
1565 @brief Close an open map.
1566
1567 @param[in] pCtx The encoding context to close the map in .
1568
1569 This closes a map opened by QCBOREncode_OpenMap(). It reduces nesting
1570 level by one.
1571
1572 When an error occurs as a result of this call, the encoder records
1573 the error and enters the error state. The error will be returned when
1574 QCBOREncode_Finish() is called.
1575
1576 If this has been called more times than QCBOREncode_OpenMap(),
1577 then @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1578 QCBOREncode_Finish() is called.
1579
1580 If this is called and it is not a map that is currently open, @ref
1581 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
1582 is called.
1583 */
1584static void QCBOREncode_CloseMap(QCBOREncodeContext *pCtx);
1585
1586
1587/**
1588 @brief Indicate start of encoded CBOR to be wrapped in a bstr.
1589
1590 @param[in] pCtx The encoding context to open the bstr-wrapped CBOR in.
1591
1592 All added encoded items between this call and a call to
1593 QCBOREncode_CloseBstrWrap2() will be wrapped in a bstr. They will
1594 appear in the final output as a byte string. That byte string will
1595 contain encoded CBOR. This increases nesting level by one.
1596
1597 The typical use case is for encoded CBOR that is to be
1598 cryptographically hashed, as part of a [RFC 8152, COSE]
1599 (https://tools.ietf.org/html/rfc8152) implementation.
1600
1601 Using QCBOREncode_BstrWrap() and QCBOREncode_CloseBstrWrap2() avoids
1602 having to encode the items first in one buffer (e.g., the COSE
1603 payload) and then add that buffer as a bstr to another encoding
1604 (e.g. the COSE to-be-signed bytes, the @c Sig_structure) potentially
1605 halving the memory needed.
1606
1607 RFC 7049 states the purpose of this wrapping is to prevent code
1608 relaying the signed data but not verifying it from tampering with the
1609 signed data thus making the signature unverifiable. It is also quite
1610 beneficial for the signature verification code. Standard CBOR
1611 decoders usually do not give access to partially decoded CBOR as
1612 would be needed to check the signature of some CBOR. With this
1613 wrapping, standard CBOR decoders can be used to get to all the data
1614 needed for a signature verification.
1615 */
1616static void QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx);
1617
1618static void QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1619
1620static void QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1621
1622
1623/**
1624 @brief Close a wrapping bstr.
1625
1626 @param[in] pCtx The encoding context to close of bstr wrapping in.
1627 @param[in] bIncludeCBORHead Include the encoded CBOR head of the bstr
1628 as well as the bytes in @c pWrappedCBOR.
1629 @param[out] pWrappedCBOR A @ref UsefulBufC containing wrapped bytes.
1630
1631 The closes a wrapping bstr opened by QCBOREncode_BstrWrap(). It reduces
1632 nesting level by one.
1633
1634 A pointer and length of the enclosed encoded CBOR is returned in @c
1635 *pWrappedCBOR if it is not @c NULL. The main purpose of this is so
1636 this data can be hashed (e.g., with SHA-256) as part of a [RFC 8152,
1637 COSE] (https://tools.ietf.org/html/rfc8152)
1638 implementation. **WARNING**, this pointer and length should be used
1639 right away before any other calls to @c QCBOREncode_CloseXxx() as
1640 they will move data around and the pointer and length will no longer
1641 be to the correct encoded CBOR.
1642
1643 When an error occurs as a result of this call, the encoder records
1644 the error and enters the error state. The error will be returned when
1645 QCBOREncode_Finish() is called.
1646
1647 If this has been called more times than QCBOREncode_BstrWrap(), then
1648 @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1649 QCBOREncode_Finish() is called.
1650
1651 If this is called and it is not a wrapping bstr that is currently
1652 open, @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
1653 QCBOREncode_Finish() is called.
1654
1655 QCBOREncode_CloseBstrWrap() is a deprecated version of this function
1656 that is equivalent to the call with @c bIncludeCBORHead @c true.
1657 */
1658void QCBOREncode_CloseBstrWrap2(QCBOREncodeContext *pCtx, bool bIncludeCBORHead, UsefulBufC *pWrappedCBOR);
1659
1660static void QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR);
1661
1662
1663/**
1664 @brief Add some already-encoded CBOR bytes.
1665
1666 @param[in] pCtx The encoding context to add the already-encode CBOR to.
1667 @param[in] Encoded The already-encoded CBOR to add to the context.
1668
1669 The encoded CBOR being added must be fully conforming CBOR. It must
1670 be complete with no arrays or maps that are incomplete. While this
1671 encoder doesn't ever produce indefinite lengths, it is OK for the
1672 raw CBOR added here to have indefinite lengths.
1673
1674 The raw CBOR added here is not checked in anyway. If it is not
1675 conforming or has open arrays or such, the final encoded CBOR
1676 will probably be wrong or not what was intended.
1677
1678 If the encoded CBOR being added here contains multiple items, they
1679 must be enclosed in a map or array. At the top level the raw
1680 CBOR must be a single data item.
1681 */
1682static void QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded);
1683
1684static void QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded);
1685
1686static void QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded);
1687
1688
1689/**
1690 @brief Get the encoded result.
1691
1692 @param[in] pCtx The context to finish encoding with.
1693 @param[out] pEncodedCBOR Pointer and length of encoded CBOR.
1694
1695 @retval QCBOR_ERR_TOO_MANY_CLOSES Nesting error
1696
1697 @retval QCBOR_ERR_CLOSE_MISMATCH Nesting error
1698
1699 @retval QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN Nesting error
1700
1701 @retval QCBOR_ERR_BUFFER_TOO_LARGE Encoded output buffer size
1702
1703 @retval QCBOR_ERR_BUFFER_TOO_SMALL Encoded output buffer size
1704
1705 @retval QCBOR_ERR_ARRAY_NESTING_TOO_DEEP Implementation limit
1706
1707 @retval QCBOR_ERR_ARRAY_TOO_LONG Implementation limit
1708
1709 If this returns success @ref QCBOR_SUCCESS the encoding was a success
1710 and the return length is correct and complete.
1711
1712 If no buffer was passed to QCBOREncode_Init(), then only the length
1713 was computed. If a buffer was passed, then the encoded CBOR is in the
1714 buffer.
1715
1716 Encoding errors primarily manifest here as most other encoding function
1717 do no return an error. They just set the error state in the encode
1718 context after which no encoding function does anything.
1719
1720 Three types of errors manifest here. The first type are nesting
1721 errors where the number of @c QCBOREncode_OpenXxx() calls do not
1722 match the number @c QCBOREncode_CloseXxx() calls. The solution is to
1723 fix the calling code.
1724
1725 The second type of error is because the buffer given is either too
1726 small or too large. The remedy is to give a correctly sized buffer.
1727
1728 The third type are due to limits in this implementation. @ref
1729 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP can be worked around by encoding the
1730 CBOR in two (or more) phases and adding the CBOR from the first phase
1731 to the second with @c QCBOREncode_AddEncoded().
1732
1733 If an error is returned, the buffer may have partially encoded
1734 incorrect CBOR in it and it should not be used. Likewise, the length
1735 may be incorrect and should not be used.
1736
1737 Note that the error could have occurred in one of the many @c
1738 QCBOREncode_AddXxx() calls long before QCBOREncode_Finish() was
1739 called. This error handling reduces the CBOR implementation size but
1740 makes debugging harder.
1741
1742 This may be called multiple times. It will always return the same. It
1743 can also be interleaved with calls to QCBOREncode_FinishGetSize().
1744
1745 QCBOREncode_GetErrorState() can be called to get the current
1746 error state and abort encoding early as an optimization, but is
1747 is never required.
1748 */
1749QCBORError QCBOREncode_Finish(QCBOREncodeContext *pCtx, UsefulBufC *pEncodedCBOR);
1750
1751
1752/**
1753 @brief Get the encoded CBOR and error status.
1754
1755 @param[in] pCtx The context to finish encoding with.
1756 @param[out] uEncodedLen The length of the encoded or potentially
1757 encoded CBOR in bytes.
1758
1759 @return The same errors as QCBOREncode_Finish().
1760
1761 This functions the same as QCBOREncode_Finish(), but only returns the
1762 size of the encoded output.
1763 */
1764QCBORError QCBOREncode_FinishGetSize(QCBOREncodeContext *pCtx, size_t *uEncodedLen);
1765
1766
1767/**
1768 @brief Indicate whether output buffer is NULL or not.
1769
1770 @param[in] pCtx The encoding context.
1771
1772 @return 1 if the output buffer is @c NULL.
1773
1774 Sometimes a @c NULL input buffer is given to QCBOREncode_Init() so
1775 that the size of the generated CBOR can be calculated without
1776 allocating a buffer for it. This returns 1 when the output buffer is
1777 NULL and 0 when it is not.
1778*/
1779static int QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx);
1780
Laurence Lundblade825164e2020-10-22 20:18:06 -07001781
1782/**
Michael Eckel5c531332020-03-02 01:35:30 +01001783 @brief Get the encoding error state.
1784
1785 @param[in] pCtx The encoding context.
1786
Laurence Lundbladeabf5c572020-06-29 21:21:29 -07001787 @return One of @ref QCBORError. See return values from
Michael Eckel5c531332020-03-02 01:35:30 +01001788 QCBOREncode_Finish()
1789
1790 Normally encoding errors need only be handled at the end of encoding
1791 when QCBOREncode_Finish() is called. This can be called to get the
1792 error result before finish should there be a need to halt encoding
1793 before QCBOREncode_Finish() is called.
1794*/
1795static QCBORError QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx);
1796
1797
1798/**
1799 Encode the "head" of a CBOR data item.
1800
1801 @param buffer Buffer to output the encoded head to; must be
1802 @ref QCBOR_HEAD_BUFFER_SIZE bytes in size.
1803 @param uMajorType One of CBOR_MAJOR_TYPE_XX.
1804 @param uMinLen The minimum number of bytes to encode uNumber. Almost always
1805 this is 0 to use preferred minimal encoding. If this is 4,
1806 then even the values 0xffff and smaller will be encoded
Laurence Lundblade98427e92020-09-28 21:33:23 -07001807 in 4 bytes. This is used primarily when encoding a
Michael Eckel5c531332020-03-02 01:35:30 +01001808 float or double put into uNumber as the leading zero bytes
1809 for them must be encoded.
1810 @param uNumber The numeric argument part of the CBOR head.
1811 @return Pointer and length of the encoded head or
Laurence Lundblade9a3b6252020-10-21 21:30:31 -07001812 @ref NULLUsefulBufC if the output buffer is too small.
Michael Eckel5c531332020-03-02 01:35:30 +01001813
Laurence Lundblade98427e92020-09-28 21:33:23 -07001814 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 +01001815 take a @ref QCBOREncodeContext argument.
1816
1817 This encodes the major type and argument part of a data item. The
1818 argument is an integer that is usually either the value or the length
1819 of the data item.
1820
1821 This is exposed in the public interface to allow hashing of some CBOR
1822 data types, bstr in particular, a chunk at a time so the full CBOR
1823 doesn't have to be encoded in a contiguous buffer.
1824
1825 For example, if you have a 100,000 byte binary blob in a buffer that
1826 needs to be a bstr encoded and then hashed. You could allocate a
1827 100,010 byte buffer and encode it normally. Alternatively, you can
1828 encode the head in a 10 byte buffer with this function, hash that and
1829 then hash the 100,000 bytes using the same hash context.
1830
1831 See also QCBOREncode_AddBytesLenOnly();
1832 */
1833UsefulBufC QCBOREncode_EncodeHead(UsefulBuf buffer,
1834 uint8_t uMajorType,
1835 uint8_t uMinLen,
1836 uint64_t uNumber);
1837
1838
Michael Eckel5c531332020-03-02 01:35:30 +01001839
1840
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001841/* =========================================================================
1842 BEGINNING OF PRIVATE INLINE IMPLEMENTATION
1843 ========================================================================= */
Michael Eckel5c531332020-03-02 01:35:30 +01001844
1845/**
1846 @brief Semi-private method to add a buffer full of bytes to encoded output
1847
1848 @param[in] pCtx The encoding context to add the integer to.
1849 @param[in] uMajorType The CBOR major type of the bytes.
1850 @param[in] Bytes The bytes to add.
1851
1852 Use QCBOREncode_AddText() or QCBOREncode_AddBytes() or
1853 QCBOREncode_AddEncoded() instead. They are inline functions that call
1854 this and supply the correct major type. This function is public to
1855 make the inline functions work to keep the overall code size down and
1856 because the C language has no way to make it private.
1857
1858 If this is called the major type should be @c
1859 CBOR_MAJOR_TYPE_TEXT_STRING, @c CBOR_MAJOR_TYPE_BYTE_STRING or @c
1860 CBOR_MAJOR_NONE_TYPE_RAW. The last one is special for adding
1861 already-encoded CBOR.
1862 */
1863void QCBOREncode_AddBuffer(QCBOREncodeContext *pCtx, uint8_t uMajorType, UsefulBufC Bytes);
1864
1865
1866/**
1867 @brief Semi-private method to open a map, array or bstr-wrapped CBOR
1868
1869 @param[in] pCtx The context to add to.
1870 @param[in] uMajorType The major CBOR type to close
1871
1872 Call QCBOREncode_OpenArray(), QCBOREncode_OpenMap() or
1873 QCBOREncode_BstrWrap() instead of this.
1874 */
1875void QCBOREncode_OpenMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType);
1876
1877
1878/**
1879 @brief Semi-private method to open a map, array with indefinite length
1880
1881 @param[in] pCtx The context to add to.
1882 @param[in] uMajorType The major CBOR type to close
1883
1884 Call QCBOREncode_OpenArrayIndefiniteLength() or
1885 QCBOREncode_OpenMapIndefiniteLength() instead of this.
1886 */
1887void QCBOREncode_OpenMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx, uint8_t uMajorType);
1888
1889
1890/**
1891 @brief Semi-private method to close a map, array or bstr wrapped CBOR
1892
1893 @param[in] pCtx The context to add to.
1894 @param[in] uMajorType The major CBOR type to close.
1895
1896 Call QCBOREncode_CloseArray() or QCBOREncode_CloseMap() instead of this.
1897 */
1898void QCBOREncode_CloseMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType);
1899
1900
1901/**
1902 @brief Semi-private method to close a map, array with indefinite length
1903
1904 @param[in] pCtx The context to add to.
1905 @param[in] uMajorType The major CBOR type to close.
1906
1907 Call QCBOREncode_CloseArrayIndefiniteLength() or
1908 QCBOREncode_CloseMapIndefiniteLength() instead of this.
1909 */
1910void QCBOREncode_CloseMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx,
1911 uint8_t uMajorType);
1912
1913
1914/**
1915 @brief Semi-private method to add simple types.
1916
1917 @param[in] pCtx The encoding context to add the simple value to.
1918 @param[in] uMinLen Minimum encoding size for uNum. Usually 0.
1919 @param[in] uNum One of CBOR_SIMPLEV_FALSE through _UNDEF or other.
1920
1921 This is used to add simple types like true and false.
1922
1923 Call QCBOREncode_AddBool(), QCBOREncode_AddNULL(),
1924 QCBOREncode_AddUndef() instead of this.
1925
1926 This function can add simple values that are not defined by CBOR
1927 yet. This expansion point in CBOR should not be used unless they are
1928 standardized.
1929
1930 Error handling is the same as QCBOREncode_AddInt64().
1931 */
1932void QCBOREncode_AddType7(QCBOREncodeContext *pCtx, uint8_t uMinLen, uint64_t uNum);
1933
1934
1935/**
1936 @brief Semi-private method to add bigfloats and decimal fractions.
1937
1938 @param[in] pCtx The encoding context to add the value to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001939 @param[in] uTag The type 6 tag indicating what this is to be.
Michael Eckel5c531332020-03-02 01:35:30 +01001940 @param[in] BigNumMantissa Is @ref NULLUsefulBufC if mantissa is an
1941 @c int64_t or the actual big number mantissa
1942 if not.
1943 @param[in] nMantissa The @c int64_t mantissa if it is not a big number.
1944 @param[in] nExponent The exponent.
1945
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001946 This outputs either the @ref CBOR_TAG_DECIMAL_FRACTION or @ref
1947 CBOR_TAG_BIGFLOAT tag. if @c uTag is @ref CBOR_TAG_INVALID64, then
1948 this outputs the "borrowed" content format.
Michael Eckel5c531332020-03-02 01:35:30 +01001949
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001950 The tag content output by this is an array with two members, the
1951 exponent and then the mantissa. The mantissa can be either a big
1952 number or an @c int64_t.
1953
1954 This implementation cannot output an exponent further from 0 than
Laurence Lundblade9a3b6252020-10-21 21:30:31 -07001955 @c INT64_MAX.
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001956
1957 To output a mantissa that is bewteen INT64_MAX and UINT64_MAX from 0,
1958 it must be as a big number.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001959
Michael Eckel5c531332020-03-02 01:35:30 +01001960 Typically, QCBOREncode_AddDecimalFraction(), QCBOREncode_AddBigFloat(),
1961 QCBOREncode_AddDecimalFractionBigNum() or QCBOREncode_AddBigFloatBigNum()
1962 is called instead of this.
1963 */
1964void QCBOREncode_AddExponentAndMantissa(QCBOREncodeContext *pCtx,
1965 uint64_t uTag,
1966 UsefulBufC BigNumMantissa,
1967 bool bBigNumIsNegative,
1968 int64_t nMantissa,
1969 int64_t nExponent);
1970
1971/**
1972 @brief Semi-private method to add only the type and length of a byte string.
1973
1974 @param[in] pCtx The context to initialize.
1975 @param[in] Bytes Pointer and length of the input data.
1976
1977 This is the same as QCBOREncode_AddBytes() except it only adds the
1978 CBOR encoding for the type and the length. It doesn't actually add
1979 the bytes. You can't actually produce correct CBOR with this and the
1980 rest of this API. It is only used for a special case where
1981 the valid CBOR is created manually by putting this type and length in
1982 and then adding the actual bytes. In particular, when only a hash of
1983 the encoded CBOR is needed, where the type and header are hashed
1984 separately and then the bytes is hashed. This makes it possible to
1985 implement COSE Sign1 with only one copy of the payload in the output
1986 buffer, rather than two, roughly cutting memory use in half.
1987
1988 This is only used for this odd case, but this is a supported
1989 tested function.
1990
1991 See also QCBOREncode_EncodeHead().
1992*/
1993static inline void QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
1994
1995static inline void QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
1996
1997static inline void QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
1998
1999
2000
2001
2002
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002003static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002004QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pMe, const char *szLabel, int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002005{
2006 // Use _AddBuffer() because _AddSZString() is defined below, not above
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002007 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
2008 QCBOREncode_AddInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002009}
2010
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002011static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002012QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pMe, int64_t nLabel, int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002013{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002014 QCBOREncode_AddInt64(pMe, nLabel);
2015 QCBOREncode_AddInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002016}
2017
2018
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002019static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002020QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pMe, const char *szLabel, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002021{
2022 // Use _AddBuffer() because _AddSZString() is defined below, not above
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002023 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
2024 QCBOREncode_AddUInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002025}
2026
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002027static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002028QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002029{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002030 QCBOREncode_AddInt64(pMe, nLabel);
2031 QCBOREncode_AddUInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002032}
2033
2034
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002035static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002036QCBOREncode_AddText(QCBOREncodeContext *pMe, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002037{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002038 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002039}
2040
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002041static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002042QCBOREncode_AddTextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002043{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002044 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szLabel));
2045 QCBOREncode_AddText(pMe, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002046}
2047
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002048static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002049QCBOREncode_AddTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002050{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002051 QCBOREncode_AddInt64(pMe, nLabel);
2052 QCBOREncode_AddText(pMe, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002053}
2054
2055
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002056inline static void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002057QCBOREncode_AddSZString(QCBOREncodeContext *pMe, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002058{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002059 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szString));
Michael Eckel5c531332020-03-02 01:35:30 +01002060}
2061
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002062static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002063QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pMe, const char *szLabel, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002064{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002065 QCBOREncode_AddSZString(pMe, szLabel);
2066 QCBOREncode_AddSZString(pMe, szString);
Michael Eckel5c531332020-03-02 01:35:30 +01002067}
2068
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002069static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002070QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002071{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002072 QCBOREncode_AddInt64(pMe, nLabel);
2073 QCBOREncode_AddSZString(pMe, szString);
Michael Eckel5c531332020-03-02 01:35:30 +01002074}
2075
2076
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002077static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002078QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pMe, const char *szLabel, double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002079{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002080 QCBOREncode_AddSZString(pMe, szLabel);
2081 QCBOREncode_AddDouble(pMe, dNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002082}
2083
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002084static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002085QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pMe, int64_t nLabel, double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002086{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002087 QCBOREncode_AddInt64(pMe, nLabel);
2088 QCBOREncode_AddDouble(pMe, dNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002089}
2090
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002091static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002092QCBOREncode_AddFloatToMap(QCBOREncodeContext *pMe, const char *szLabel, float dNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002093{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002094 QCBOREncode_AddSZString(pMe, szLabel);
2095 QCBOREncode_AddFloat(pMe, dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002096}
2097
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002098static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002099QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pMe, int64_t nLabel, float fNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002100{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002101 QCBOREncode_AddInt64(pMe, nLabel);
2102 QCBOREncode_AddFloat(pMe, fNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002103}
2104
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002105static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002106QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pMe, const char *szLabel, double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002107{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002108 QCBOREncode_AddSZString(pMe, szLabel);
2109 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002110}
2111
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002112static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002113QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pMe, int64_t nLabel, double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002114{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002115 QCBOREncode_AddInt64(pMe, nLabel);
2116 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002117}
2118
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002119static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002120QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pMe, const char *szLabel, float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002121{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002122 QCBOREncode_AddSZString(pMe, szLabel);
2123 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002124}
2125
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002126static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002127QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pMe, int64_t nLabel, float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002128{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002129 QCBOREncode_AddInt64(pMe, nLabel);
2130 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002131}
2132
Michael Eckel5c531332020-03-02 01:35:30 +01002133
Laurence Lundblade9b334962020-08-27 10:55:53 -07002134
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002135static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002136QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pMe, uint8_t uTag, int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002137{
2138 if(uTag == QCBOR_ENCODE_AS_TAG) {
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002139 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_EPOCH);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002140 }
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002141 QCBOREncode_AddInt64(pMe, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002142}
2143
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002144static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002145QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTag, int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002146{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002147 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002148 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002149}
2150
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002151static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002152QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTag, int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002153{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002154 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002155 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002156}
2157
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002158static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002159QCBOREncode_AddDateEpoch(QCBOREncodeContext *pMe, int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002160{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002161 QCBOREncode_AddTDateEpoch(pMe, QCBOR_ENCODE_AS_TAG, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002162}
2163
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002164static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002165QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pMe, const char *szLabel, int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002166{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002167 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002168 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002169}
2170
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002171static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002172QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pMe, int64_t nLabel, int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002173{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002174 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002175 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002176}
2177
2178
Laurence Lundblade9b334962020-08-27 10:55:53 -07002179
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002180static inline void
2181QCBOREncode_AddBytes(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002182{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002183 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002184}
2185
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002186static inline void
2187QCBOREncode_AddBytesToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002188{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002189 QCBOREncode_AddSZString(pMe, szLabel);
2190 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002191}
2192
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002193static inline void
2194QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002195{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002196 QCBOREncode_AddInt64(pMe, nLabel);
2197 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002198}
2199
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002200static inline void
2201QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002202{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002203 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002204}
2205
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002206static inline void
2207QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002208{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002209 QCBOREncode_AddSZString(pMe, szLabel);
2210 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002211}
2212
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002213static inline void
2214QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002215{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002216 QCBOREncode_AddInt64(pMe, nLabel);
2217 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002218}
2219
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002220
2221static inline void
2222QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002223{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002224 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2225 QCBOREncode_AddTag(pMe, CBOR_TAG_BIN_UUID);
2226 }
2227 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002228}
2229
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002230static inline void
2231QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pMe,
2232 const char *szLabel,
2233 uint8_t uTagRequirement,
2234 UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002235{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002236 QCBOREncode_AddSZString(pMe, szLabel);
2237 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002238}
2239
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002240static inline void
2241QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002242{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002243 QCBOREncode_AddInt64(pMe, nLabel);
2244 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002245}
2246
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002247static inline void
2248QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002249{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002250 QCBOREncode_AddTBinaryUUID(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002251}
2252
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002253static inline void
2254QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002255{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002256 QCBOREncode_AddTBinaryUUIDToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002257}
2258
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002259static inline void
2260QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002261{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002262 QCBOREncode_AddTBinaryUUIDToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002263}
2264
2265
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002266static inline void
2267QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002268{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002269 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2270 QCBOREncode_AddTag(pMe, CBOR_TAG_POS_BIGNUM);
2271 }
2272 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002273}
2274
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002275static inline void
2276QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pMe,
2277 const char *szLabel,
2278 uint8_t uTagRequirement,
2279 UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002280{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002281 QCBOREncode_AddSZString(pMe, szLabel);
2282 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002283}
2284
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002285static inline void
2286QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002287{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002288 QCBOREncode_AddInt64(pMe, nLabel);
2289 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002290}
2291
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002292static inline void
2293QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2294{
2295 QCBOREncode_AddTPositiveBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2296}
2297
2298static inline void
2299QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2300{
2301 QCBOREncode_AddTPositiveBignumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2302}
2303
2304static inline void
2305QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2306{
2307 QCBOREncode_AddTPositiveBignumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2308}
2309
2310
2311static inline void
2312QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
2313{
2314 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2315 QCBOREncode_AddTag(pMe, CBOR_TAG_NEG_BIGNUM);
2316 }
2317 QCBOREncode_AddBytes(pMe, Bytes);
2318}
2319
2320static inline void
2321QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pMe,
2322 const char *szLabel,
2323 uint8_t uTagRequirement,
2324 UsefulBufC Bytes)
2325{
2326 QCBOREncode_AddSZString(pMe, szLabel);
2327 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2328}
2329
2330static inline void
2331QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
2332{
2333 QCBOREncode_AddInt64(pMe, nLabel);
2334 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2335}
2336
2337static inline void
2338QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2339{
2340 QCBOREncode_AddTNegativeBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2341}
2342
2343static inline void
2344QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2345{
2346 QCBOREncode_AddTNegativeBignumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2347}
2348
2349static inline void
2350QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2351{
2352 QCBOREncode_AddTNegativeBignumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2353}
2354
2355
Michael Eckel5c531332020-03-02 01:35:30 +01002356
2357#ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
2358
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002359static inline void
2360QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pMe,
2361 uint8_t uTagRequirement,
2362 int64_t nMantissa,
2363 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002364{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002365 uint64_t uTag;
2366 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2367 uTag = CBOR_TAG_DECIMAL_FRACTION;
2368 } else {
2369 uTag = CBOR_TAG_INVALID64;
2370 }
2371 QCBOREncode_AddExponentAndMantissa(pMe,
2372 uTag,
Michael Eckel5c531332020-03-02 01:35:30 +01002373 NULLUsefulBufC,
2374 false,
2375 nMantissa,
2376 nBase10Exponent);
2377}
2378
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002379static inline void
2380QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pMe,
2381 const char *szLabel,
2382 uint8_t uTagRequirement,
2383 int64_t nMantissa,
2384 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002385{
2386 QCBOREncode_AddSZString(pMe, szLabel);
2387 QCBOREncode_AddTDecimalFraction(pMe, uTagRequirement, nMantissa, nBase10Exponent);
2388}
2389
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002390static inline void
2391QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pMe,
2392 int64_t nLabel,
2393 uint8_t uTagRequirement,
2394 int64_t nMantissa,
2395 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002396{
2397 QCBOREncode_AddInt64(pMe, nLabel);
2398 QCBOREncode_AddTDecimalFraction(pMe, uTagRequirement, nMantissa, nBase10Exponent);
2399}
2400
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002401static inline void
2402QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pMe,
2403 int64_t nMantissa,
2404 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002405{
2406 QCBOREncode_AddTDecimalFraction(pMe, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
2407}
2408
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002409static inline void
2410QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pMe,
2411 const char *szLabel,
2412 int64_t nMantissa,
2413 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002414{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002415 QCBOREncode_AddTDecimalFractionToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002416}
2417
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002418static inline void
2419QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pMe,
2420 int64_t nLabel,
2421 int64_t nMantissa,
2422 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002423{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002424 QCBOREncode_AddTDecimalFractionToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002425}
2426
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002427
2428
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002429static inline void
2430QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pMe,
2431 uint8_t uTagRequirement,
2432 UsefulBufC Mantissa,
2433 bool bIsNegative,
2434 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002435{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002436 uint64_t uTag;
2437 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2438 uTag = CBOR_TAG_DECIMAL_FRACTION;
2439 } else {
2440 uTag = CBOR_TAG_INVALID64;
2441 }
2442 QCBOREncode_AddExponentAndMantissa(pMe,
2443 uTag,
Michael Eckel5c531332020-03-02 01:35:30 +01002444 Mantissa, bIsNegative,
2445 0,
2446 nBase10Exponent);
2447}
2448
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002449static inline void
2450QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
2451 const char *szLabel,
2452 uint8_t uTagRequirement,
2453 UsefulBufC Mantissa,
2454 bool bIsNegative,
2455 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002456{
2457 QCBOREncode_AddSZString(pMe, szLabel);
2458 QCBOREncode_AddTDecimalFractionBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase10Exponent);
2459}
2460
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002461static inline void
2462QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
2463 int64_t nLabel,
2464 uint8_t uTagRequirement,
2465 UsefulBufC Mantissa,
2466 bool bIsNegative,
2467 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002468{
2469 QCBOREncode_AddInt64(pMe, nLabel);
2470 QCBOREncode_AddTDecimalFractionBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase10Exponent);
2471}
2472
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002473static inline void
2474QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pMe,
2475 UsefulBufC Mantissa,
2476 bool bIsNegative,
2477 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002478{
2479 QCBOREncode_AddTDecimalFractionBigNum(pMe, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase10Exponent);
2480}
2481
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002482static inline void
2483QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
2484 const char *szLabel,
2485 UsefulBufC Mantissa,
2486 bool bIsNegative,
2487 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002488{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002489 QCBOREncode_AddTDecimalFractionBigNumToMapSZ(pMe,
2490 szLabel,
2491 QCBOR_ENCODE_AS_TAG,
2492 Mantissa,
2493 bIsNegative,
2494 nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002495}
2496
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002497static inline void
2498QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
2499 int64_t nLabel,
2500 UsefulBufC Mantissa,
2501 bool bIsNegative,
2502 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002503{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002504 QCBOREncode_AddTDecimalFractionBigNumToMapN(pMe,
2505 nLabel,
2506 QCBOR_ENCODE_AS_TAG,
2507 Mantissa,
2508 bIsNegative,
2509 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002510}
2511
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002512
2513
2514
2515
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002516static inline void
2517QCBOREncode_AddTBigFloat(QCBOREncodeContext *pMe,
2518 uint8_t uTagRequirement,
2519 int64_t nMantissa,
2520 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002521{
2522 uint64_t uTag;
2523 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2524 uTag = CBOR_TAG_BIGFLOAT;
2525 } else {
2526 uTag = CBOR_TAG_INVALID64;
2527 }
2528 QCBOREncode_AddExponentAndMantissa(pMe, uTag, NULLUsefulBufC, false, nMantissa, nBase2Exponent);
2529}
2530
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002531static inline void
2532QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pMe,
2533 const char *szLabel,
2534 uint8_t uTagRequirement,
2535 int64_t nMantissa,
2536 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002537{
2538 QCBOREncode_AddSZString(pMe, szLabel);
2539 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
2540}
2541
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002542static inline void
2543QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pMe,
2544 int64_t nLabel,
2545 uint8_t uTagRequirement,
2546 int64_t nMantissa,
2547 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002548{
2549 QCBOREncode_AddInt64(pMe, nLabel);
2550 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
2551}
2552
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002553static inline void
2554QCBOREncode_AddBigFloat(QCBOREncodeContext *pMe,
2555 int64_t nMantissa,
2556 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002557{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002558 QCBOREncode_AddTBigFloat(pMe, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002559}
2560
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002561static inline void
2562QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pMe,
2563 const char *szLabel,
2564 int64_t nMantissa,
2565 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002566{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002567 QCBOREncode_AddTBigFloatToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002568}
2569
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002570static inline void
2571QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pMe,
2572 int64_t nLabel,
2573 int64_t nMantissa,
2574 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002575{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002576 QCBOREncode_AddTBigFloatToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002577}
2578
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002579
2580
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002581static inline void
2582QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pMe,
2583 uint8_t uTagRequirement,
2584 UsefulBufC Mantissa,
2585 bool bIsNegative,
2586 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002587{
2588 uint64_t uTag;
2589 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2590 uTag = CBOR_TAG_BIGFLOAT;
2591 } else {
2592 uTag = CBOR_TAG_INVALID64;
2593 }
2594 QCBOREncode_AddExponentAndMantissa(pMe, uTag, Mantissa, bIsNegative, 0, nBase2Exponent);
2595}
2596
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002597static inline void
2598QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pMe,
2599 const char *szLabel,
2600 uint8_t uTagRequirement,
2601 UsefulBufC Mantissa,
2602 bool bIsNegative,
2603 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002604{
2605 QCBOREncode_AddSZString(pMe, szLabel);
2606 QCBOREncode_AddTBigFloatBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase2Exponent);
2607}
2608
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002609static inline void
2610QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
2611 int64_t nLabel,
2612 uint8_t uTagRequirement,
2613 UsefulBufC Mantissa,
2614 bool bIsNegative,
2615 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002616{
2617 QCBOREncode_AddInt64(pMe, nLabel);
2618 QCBOREncode_AddTBigFloatBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase2Exponent);
2619}
2620
2621
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002622static inline void
2623QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pMe,
2624 UsefulBufC Mantissa,
2625 bool bIsNegative,
2626 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002627{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002628 QCBOREncode_AddTBigFloatBigNum(pMe, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002629}
2630
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002631static inline void
2632QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pMe,
2633 const char *szLabel,
2634 UsefulBufC Mantissa,
2635 bool bIsNegative,
2636 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002637{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002638 QCBOREncode_AddTBigFloatBigNumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002639}
2640
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002641static inline void
2642QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
2643 int64_t nLabel,
2644 UsefulBufC Mantissa,
2645 bool bIsNegative,
2646 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002647{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002648 QCBOREncode_AddTBigFloatBigNumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002649}
2650#endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
2651
2652
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002653static inline void
2654QCBOREncode_AddTURI(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002655{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002656 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2657 QCBOREncode_AddTag(pMe, CBOR_TAG_URI);
2658 }
2659 QCBOREncode_AddText(pMe, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002660}
2661
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002662static inline void
2663QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002664{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002665 QCBOREncode_AddSZString(pMe, szLabel);
2666 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002667}
2668
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002669static inline void
2670QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002671{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002672 QCBOREncode_AddInt64(pMe, nLabel);
2673 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
2674}
2675
2676static inline void
2677QCBOREncode_AddURI(QCBOREncodeContext *pMe, UsefulBufC URI)
2678{
2679 QCBOREncode_AddTURI(pMe, QCBOR_ENCODE_AS_TAG, URI);
2680}
2681
2682static inline void
2683QCBOREncode_AddURIToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC URI)
2684{
2685 QCBOREncode_AddTURIToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, URI);
2686}
2687
2688static inline void
2689QCBOREncode_AddURIToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC URI)
2690{
2691 QCBOREncode_AddTURIToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002692}
2693
2694
2695
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002696static inline void
2697QCBOREncode_AddTB64Text(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002698{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002699 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2700 QCBOREncode_AddTag(pMe, CBOR_TAG_B64);
2701 }
2702 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002703}
2704
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002705static inline void
2706QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pMe,
2707 const char *szLabel,
2708 uint8_t uTagRequirement,
2709 UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002710{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002711 QCBOREncode_AddSZString(pMe, szLabel);
2712 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002713}
2714
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002715static inline void
2716QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002717{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002718 QCBOREncode_AddInt64(pMe, nLabel);
2719 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
2720}
2721
2722static inline void
2723QCBOREncode_AddB64Text(QCBOREncodeContext *pMe, UsefulBufC B64Text)
2724{
2725 QCBOREncode_AddTB64Text(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
2726}
2727
2728static inline void
2729QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC B64Text)
2730{
2731 QCBOREncode_AddTB64TextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
2732}
2733
2734static inline void
2735QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC B64Text)
2736{
2737 QCBOREncode_AddTB64TextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002738}
2739
2740
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002741
2742static inline void
2743QCBOREncode_AddTB64URLText(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002744{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002745 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2746 QCBOREncode_AddTag(pMe, CBOR_TAG_B64URL);
2747 }
2748 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002749}
2750
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002751static inline void
2752QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pMe,
2753 const char *szLabel,
2754 uint8_t uTagRequirement,
2755 UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002756{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002757 QCBOREncode_AddSZString(pMe, szLabel);
2758 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002759}
2760
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002761static inline void
2762QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002763{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002764 QCBOREncode_AddInt64(pMe, nLabel);
2765 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
2766}
2767
2768static inline void
2769QCBOREncode_AddB64URLText(QCBOREncodeContext *pMe, UsefulBufC B64Text)
2770{
2771 QCBOREncode_AddTB64URLText(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
2772}
2773
2774static inline void
2775QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC B64Text)
2776{
2777 QCBOREncode_AddTB64URLTextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
2778}
2779
2780static inline void
2781QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC B64Text)
2782{
2783 QCBOREncode_AddTB64URLTextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002784}
2785
2786
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002787
2788static inline void
2789QCBOREncode_AddTRegex(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002790{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002791 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2792 QCBOREncode_AddTag(pMe, CBOR_TAG_REGEX);
2793 }
2794 QCBOREncode_AddText(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002795}
2796
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002797static inline void
2798QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002799{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002800 QCBOREncode_AddSZString(pMe, szLabel);
2801 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002802}
2803
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002804static inline void
2805QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002806{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002807 QCBOREncode_AddInt64(pMe, nLabel);
2808 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
2809}
2810
2811static inline void
2812QCBOREncode_AddRegex(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2813{
2814 QCBOREncode_AddTRegex(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2815}
2816
2817static inline void
2818QCBOREncode_AddRegexToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2819{
2820 QCBOREncode_AddTRegexToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2821}
2822
2823static inline void
2824QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2825{
2826 QCBOREncode_AddTRegexToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2827
Michael Eckel5c531332020-03-02 01:35:30 +01002828}
2829
2830
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002831static inline void
2832QCBOREncode_AddTMIMEData(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01002833{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002834 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
Laurence Lundblade4982f412020-09-18 23:02:18 -07002835 QCBOREncode_AddTag(pMe, CBOR_TAG_BINARY_MIME);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002836 }
Laurence Lundblade4982f412020-09-18 23:02:18 -07002837 QCBOREncode_AddBytes(pMe, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01002838}
2839
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002840static inline void
2841QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pMe,
2842 const char *szLabel,
2843 uint8_t uTagRequirement,
2844 UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01002845{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002846 QCBOREncode_AddSZString(pMe, szLabel);
2847 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01002848}
2849
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002850static inline void
2851QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01002852{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002853 QCBOREncode_AddInt64(pMe, nLabel);
2854 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
2855}
2856
2857static inline void
2858QCBOREncode_AddMIMEData(QCBOREncodeContext *pMe, UsefulBufC MIMEData)
2859{
2860 QCBOREncode_AddTMIMEData(pMe, QCBOR_ENCODE_AS_TAG, MIMEData);
2861}
2862
2863static inline void
2864QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC MIMEData)
2865{
2866 QCBOREncode_AddTMIMEDataToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
2867}
2868
2869static inline void
2870QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC MIMEData)
2871{
2872 QCBOREncode_AddTMIMEDataToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01002873}
2874
2875
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002876static inline void
2877QCBOREncode_AddTDateString(QCBOREncodeContext *pMe, uint8_t uTagRequirement, const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002878{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002879 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2880 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_STRING);
2881 }
2882 QCBOREncode_AddSZString(pMe, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002883}
2884
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002885static inline void
2886QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pMe,
2887 const char *szLabel,
2888 uint8_t uTagRequirement,
2889 const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002890{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002891 QCBOREncode_AddSZString(pMe, szLabel);
2892 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002893}
2894
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002895static inline void
2896QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002897{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002898 QCBOREncode_AddInt64(pMe, nLabel);
2899 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
2900}
2901
2902static inline void
2903QCBOREncode_AddDateString(QCBOREncodeContext *pMe, const char *szDate)
2904{
2905 QCBOREncode_AddTDateString(pMe, QCBOR_ENCODE_AS_TAG, szDate);
2906}
2907
2908static inline void
2909QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pMe, const char *szLabel, const char *szDate)
2910{
2911 QCBOREncode_AddTDateStringToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, szDate);
2912}
2913
2914static inline void
2915QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, const char *szDate)
2916{
2917 QCBOREncode_AddTDateStringToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002918}
2919
2920
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002921static inline void
2922QCBOREncode_AddSimple(QCBOREncodeContext *pMe, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002923{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002924 QCBOREncode_AddType7(pMe, 0, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002925}
2926
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002927static inline void
2928QCBOREncode_AddSimpleToMap(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01002929{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002930 QCBOREncode_AddSZString(pMe, szLabel);
2931 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01002932}
2933
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002934static inline void
2935QCBOREncode_AddSimpleToMapN(QCBOREncodeContext *pMe, int nLabel, uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01002936{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002937 QCBOREncode_AddInt64(pMe, nLabel);
2938 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01002939}
2940
2941
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002942static inline void
2943QCBOREncode_AddBool(QCBOREncodeContext *pMe, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01002944{
2945 uint8_t uSimple = CBOR_SIMPLEV_FALSE;
2946 if(b) {
2947 uSimple = CBOR_SIMPLEV_TRUE;
2948 }
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002949 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01002950}
2951
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002952static inline void
2953QCBOREncode_AddBoolToMap(QCBOREncodeContext *pMe, const char *szLabel, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01002954{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002955 QCBOREncode_AddSZString(pMe, szLabel);
2956 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01002957}
2958
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002959static inline void
2960QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pMe, int64_t nLabel, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01002961{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002962 QCBOREncode_AddInt64(pMe, nLabel);
2963 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01002964}
2965
2966
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002967static inline void
2968QCBOREncode_AddNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01002969{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002970 QCBOREncode_AddSimple(pMe, CBOR_SIMPLEV_NULL);
Michael Eckel5c531332020-03-02 01:35:30 +01002971}
2972
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002973static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002974QCBOREncode_AddNULLToMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002975{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002976 QCBOREncode_AddSZString(pMe, szLabel);
2977 QCBOREncode_AddNULL(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01002978}
2979
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002980static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002981QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002982{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002983 QCBOREncode_AddInt64(pMe, nLabel);
2984 QCBOREncode_AddNULL(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01002985}
2986
2987
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002988static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002989QCBOREncode_AddUndef(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01002990{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002991 QCBOREncode_AddSimple(pMe, CBOR_SIMPLEV_UNDEF);
Michael Eckel5c531332020-03-02 01:35:30 +01002992}
2993
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002994static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002995QCBOREncode_AddUndefToMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002996{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002997 QCBOREncode_AddSZString(pMe, szLabel);
2998 QCBOREncode_AddUndef(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01002999}
3000
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003001static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003002QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003003{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003004 QCBOREncode_AddInt64(pMe, nLabel);
3005 QCBOREncode_AddUndef(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003006}
3007
3008
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003009static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003010QCBOREncode_OpenArray(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003011{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003012 QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
Michael Eckel5c531332020-03-02 01:35:30 +01003013}
3014
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003015static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003016QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003017{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003018 QCBOREncode_AddSZString(pMe, szLabel);
3019 QCBOREncode_OpenArray(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003020}
3021
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003022static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003023QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003024{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003025 QCBOREncode_AddInt64(pMe, nLabel);
3026 QCBOREncode_OpenArray(pMe);
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_CloseArray(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003031{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003032 QCBOREncode_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
Michael Eckel5c531332020-03-02 01:35:30 +01003033}
3034
3035
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003036static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003037QCBOREncode_OpenMap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003038{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003039 QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
Michael Eckel5c531332020-03-02 01:35:30 +01003040}
3041
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003042static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003043QCBOREncode_OpenMapInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003044{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003045 QCBOREncode_AddSZString(pMe, szLabel);
3046 QCBOREncode_OpenMap(pMe);
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_OpenMapInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003051{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003052 QCBOREncode_AddInt64(pMe, nLabel);
3053 QCBOREncode_OpenMap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003054}
3055
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003056static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003057QCBOREncode_CloseMap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003058{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003059 QCBOREncode_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
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_OpenArrayIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003064{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003065 QCBOREncode_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003066}
3067
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003068static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003069QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003070{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003071 QCBOREncode_AddSZString(pMe, szLabel);
3072 QCBOREncode_OpenArrayIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003073}
3074
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003075static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003076QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003077{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003078 QCBOREncode_AddInt64(pMe, nLabel);
3079 QCBOREncode_OpenArrayIndefiniteLength(pMe);
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_CloseArrayIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003084{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003085 QCBOREncode_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003086}
3087
3088
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003089static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003090QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003091{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003092 QCBOREncode_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003093}
3094
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003095static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003096QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003097{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003098 QCBOREncode_AddSZString(pMe, szLabel);
3099 QCBOREncode_OpenMapIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003100}
3101
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003102static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003103QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003104{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003105 QCBOREncode_AddInt64(pMe, nLabel);
3106 QCBOREncode_OpenMapIndefiniteLength(pMe);
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_CloseMapIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003111{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003112 QCBOREncode_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003113}
3114
3115
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003116static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003117QCBOREncode_BstrWrap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003118{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003119 QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_BYTE_STRING);
Michael Eckel5c531332020-03-02 01:35:30 +01003120}
3121
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003122static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003123QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003124{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003125 QCBOREncode_AddSZString(pMe, szLabel);
3126 QCBOREncode_BstrWrap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003127}
3128
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003129static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003130QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003131{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003132 QCBOREncode_AddInt64(pMe, nLabel);
3133 QCBOREncode_BstrWrap(pMe);
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_CloseBstrWrap(QCBOREncodeContext *pMe, UsefulBufC *pWrappedCBOR)
Michael Eckel5c531332020-03-02 01:35:30 +01003138{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003139 QCBOREncode_CloseBstrWrap2(pMe, true, pWrappedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01003140}
3141
3142
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003143static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003144QCBOREncode_AddEncoded(QCBOREncodeContext *pMe, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003145{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003146 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_RAW, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003147}
3148
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003149static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003150QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003151{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003152 QCBOREncode_AddSZString(pMe, szLabel);
3153 QCBOREncode_AddEncoded(pMe, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003154}
3155
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003156static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003157QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003158{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003159 QCBOREncode_AddInt64(pMe, nLabel);
3160 QCBOREncode_AddEncoded(pMe, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003161}
3162
3163
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003164static inline int
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003165QCBOREncode_IsBufferNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003166{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003167 return UsefulOutBuf_IsBufferNULL(&(pMe->OutBuf));
Michael Eckel5c531332020-03-02 01:35:30 +01003168}
3169
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003170static inline QCBORError
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003171QCBOREncode_GetErrorState(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003172{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003173 if(UsefulOutBuf_GetError(&(pMe->OutBuf))) {
Michael Eckel5c531332020-03-02 01:35:30 +01003174 // Items didn't fit in the buffer.
3175 // This check catches this condition for all the appends and inserts
3176 // so checks aren't needed when the appends and inserts are performed.
3177 // And of course UsefulBuf will never overrun the input buffer given
3178 // to it. No complex analysis of the error handling in this file is
3179 // needed to know that is true. Just read the UsefulBuf code.
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003180 pMe->uError = QCBOR_ERR_BUFFER_TOO_SMALL;
Michael Eckel5c531332020-03-02 01:35:30 +01003181 // QCBOR_ERR_BUFFER_TOO_SMALL masks other errors, but that is
3182 // OK. Once the caller fixes this, they'll be unmasked.
3183 }
3184
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003185 return (QCBORError)pMe->uError;
Michael Eckel5c531332020-03-02 01:35:30 +01003186}
3187
3188
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003189/* ========================================================================
3190 END OF PRIVATE INLINE IMPLEMENTATION
3191 ======================================================================== */
Michael Eckel5c531332020-03-02 01:35:30 +01003192
3193#ifdef __cplusplus
3194}
3195#endif
3196
Laurence Lundblade844bb5c2020-03-01 17:27:25 -08003197#endif /* qcbor_encode_h */