blob: d72a002fb00d4ebb12dad52e8b12e9558e238ea2 [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
54 Q C B O R E n c o d e / D e c o d e
55
56 This implements CBOR -- Concise Binary Object Representation as
57 defined in [RFC 7049] (https://tools.ietf.org/html/rfc7049). More
58 info is at http://cbor.io. This is a near-complete implementation of
59 the specification. Limitations are listed further down.
60
61 CBOR is intentionally designed to be translatable to JSON, but not
62 all CBOR can convert to JSON. See RFC 7049 for more info on how to
63 construct CBOR that is the most JSON friendly.
64
65 The memory model for encoding and decoding is that encoded CBOR must
66 be in a contiguous buffer in memory. During encoding the caller must
67 supply an output buffer and if the encoding would go off the end of
68 the buffer an error is returned. During decoding the caller supplies
69 the encoded CBOR in a contiguous buffer and the decoder returns
70 pointers and lengths into that buffer for strings.
71
72 This implementation does not require malloc. All data structures
73 passed in/out of the APIs can fit on the stack.
74
75 Decoding of indefinite-length strings is a special case that requires
76 a "string allocator" to allocate memory into which the segments of
77 the string are coalesced. Without this, decoding will error out if an
78 indefinite-length string is encountered (indefinite-length maps and
79 arrays do not require the string allocator). A simple string
80 allocator called MemPool is built-in and will work if supplied with a
81 block of memory to allocate. The string allocator can optionally use
82 malloc() or some other custom scheme.
83
84 Here are some terms and definitions:
85
86 - "Item", "Data Item": An integer or string or such. The basic "thing" that
87 CBOR is about. An array is an item itself that contains some items.
88
89 - "Array": An ordered sequence of items, the same as JSON.
90
91 - "Map": A collection of label/value pairs. Each pair is a data
92 item. A JSON "object" is the same as a CBOR "map".
93
94 - "Label": The data item in a pair in a map that names or identifies
95 the pair, not the value. This implementation refers to it as a
96 "label". JSON refers to it as the "name". The CBOR RFC refers to it
97 this as a "key". This implementation chooses label instead because
98 key is too easily confused with a cryptographic key. The COSE
99 standard, which uses CBOR, has also chosen to use the term "label"
100 rather than "key" for this same reason.
101
102 - "Key": See "Label" above.
103
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700104 - "Tag": A data item that is an explicitly labeled new data
105 type made up of the tagging integer and the tag content.
106 See @Tags-Overview and @Tag-Usage.
Michael Eckel5c531332020-03-02 01:35:30 +0100107
108 - "Initial Byte": The first byte of an encoded item. Encoding and
109 decoding of this byte is taken care of by the implementation.
110
111 - "Additional Info": In addition to the major type, all data items
112 have some other info. This is usually the length of the data but can
113 be several other things. Encoding and decoding of this is taken care
114 of by the implementation.
115
116 CBOR has two mechanisms for tagging and labeling the data values like
117 integers and strings. For example, an integer that represents
118 someone's birthday in epoch seconds since Jan 1, 1970 could be
119 encoded like this:
120
121 - First it is CBOR_MAJOR_TYPE_POSITIVE_INT (@ref QCBOR_TYPE_INT64),
122 the primitive positive integer.
123
124 - Next it has a "tag" @ref CBOR_TAG_DATE_EPOCH indicating the integer
125 represents a date in the form of the number of seconds since Jan 1,
126 1970.
127
128 - Last it has a string "label" like "BirthDate" indicating the
129 meaning of the data.
130
131 The encoded binary looks like this:
132
133 a1 # Map of 1 item
134 69 # Indicates text string of 9 bytes
135 426972746844617465 # The text "BirthDate"
136 c1 # Tags next integer as epoch date
137 1a # Indicates a 4-byte integer
138 580d4172 # unsigned integer date 1477263730
139
140 Implementors using this API will primarily work with
141 labels. Generally, tags are only needed for making up new data
142 types. This implementation covers most of the data types defined in
143 the RFC using tags. It also, allows for the use of custom tags if
144 necessary.
145
146 This implementation explicitly supports labels that are text strings
147 and integers. Text strings translate nicely into JSON objects and are
148 very readable. Integer labels are much less readable but can be very
149 compact. If they are in the range of 0 to 23, they take up only one
150 byte.
151
152 CBOR allows a label to be any type of data including an array or a
153 map. It is possible to use this API to construct and parse such
154 labels, but it is not explicitly supported.
155
156 A common encoding usage mode is to invoke the encoding twice. First
157 with no output buffer to compute the length of the needed output
158 buffer. Then the correct sized output buffer is allocated. Last the
159 encoder is invoked again, this time with the output buffer.
160
161 The double invocation is not required if the maximum output buffer
162 size can be predicted. This is usually possible for simple CBOR
163 structures. If the double invocation is implemented, it can be in a
164 loop or function as in the example code so that the code doesn't have
165 to actually be written twice, saving code size.
166
167 If a buffer too small to hold the encoded output is given, the error
168 @ref QCBOR_ERR_BUFFER_TOO_SMALL will be returned. Data will never be
169 written off the end of the output buffer no matter which functions
170 here are called or what parameters are passed to them.
171
172 The encoding error handling is simple. The only possible errors are
173 trying to encode structures that are too large or too complex. There
174 are no internal malloc calls so there will be no failures for out of
175 memory. The error state is tracked internally, so there is no need
176 to check for errors when encoding. Only the return code from
177 QCBOREncode_Finish() need be checked as once an error happens, the
178 encoder goes into an error state and calls to it to add more data
179 will do nothing. An error check is not needed after every data item
180 is added.
181
182 Encoding generally proceeds by calling QCBOREncode_Init(), calling
183 lots of @c QCBOREncode_AddXxx() functions and calling
184 QCBOREncode_Finish(). There are many @c QCBOREncode_AddXxx()
185 functions for various data types. The input buffers need only to be
186 valid during the @c QCBOREncode_AddXxx() calls as the data is copied
187 into the output buffer.
188
189 There are three `Add` functions for each data type. The first / main
190 one for the type is for adding the data item to an array. The second
191 one's name ends in `ToMap`, is used for adding data items to maps and
192 takes a string argument that is its label in the map. The third one
193 ends in `ToMapN`, is also used for adding data items to maps, and
194 takes an integer argument that is its label in the map.
195
196 The simplest aggregate type is an array, which is a simple ordered
197 set of items without labels the same as JSON arrays. Call
198 QCBOREncode_OpenArray() to open a new array, then various @c
199 QCBOREncode_AddXxx() functions to put items in the array and then
200 QCBOREncode_CloseArray(). Nesting to the limit @ref
201 QCBOR_MAX_ARRAY_NESTING is allowed. All opens must be matched by
202 closes or an encoding error will be returned.
203
204 The other aggregate type is a map which does use labels. The `Add`
205 functions that end in `ToMap` and `ToMapN` are convenient ways to add
206 labeled data items to a map. You can also call any type of `Add`
207 function once to add a label of any time and then call any type of
208 `Add` again to add its value.
209
210 Note that when you nest arrays or maps in a map, the nested array or
211 map has a label.
Laurence Lundblade2feb1e12020-07-15 03:50:45 -0700212
Laurence Lundbladee3553422020-05-02 11:11:17 -0700213 Many CBOR-based protocols start with an array or map. This makes them
214 self-delimiting. No external length or end marker is needed to know
215 the end. It is also possible not start this way, in which case this
216 it is usually called a CBOR sequence which is described in [RFC 8742] (https://tools.ietf.org/html/rfc8742 ).
217 This encoder supports either just by whether the first item added is an
218 array, map or other.
Michael Eckel5c531332020-03-02 01:35:30 +0100219
220 @anchor Tags-Overview
Laurence Lundblade9b334962020-08-27 10:55:53 -0700221
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700222 Any CBOR data item can be made into a tag to add semantics, define a new data
Michael Eckel5c531332020-03-02 01:35:30 +0100223 type or such. Some tags are fully standardized and some are just
224 registered. Others are not registered and used in a proprietary way.
225
226 Encoding and decoding of many of the registered tags is fully
227 implemented by QCBOR. It is also possible to encode and decode tags
228 that are not directly supported. For many use cases the built-in tag
229 support should be adequate.
230
231 For example, the registered epoch date tag is supported in encoding
232 by QCBOREncode_AddDateEpoch() and in decoding by @ref
233 QCBOR_TYPE_DATE_EPOCH and the @c epochDate member of @ref
234 QCBORItem. This is typical of the built-in tag support. There is an
235 API to encode data for it and a @c QCBOR_TYPE_XXX when it is decoded.
236
237 Tags are registered in the [IANA CBOR Tags Registry]
238 (https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml). There
239 are roughly three options to create a new tag. First, a public
240 specification can be created and the new tag registered with IANA.
241 This is the most formal. Second, the new tag can be registered with
242 IANA with just a short description rather than a full specification.
243 These tags must be greater than 256. Third, a tag can be used without
244 any IANA registration, though the registry should be checked to see
245 that the new value doesn't collide with one that is registered. The
246 value of these tags must be 256 or larger.
247
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700248 See also @ref CBORTags and @ref Tag-Usage
249
Michael Eckel5c531332020-03-02 01:35:30 +0100250 The encoding side of tags not built-in is handled by
251 QCBOREncode_AddTag() and is relatively simple. Tag decoding is more
252 complex and mainly handled by QCBORDecode_GetNext(). Decoding of the
253 structure of tagged data not built-in (if there is any) has to be
254 implemented by the caller.
255
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700256 @anchor Floating-Point
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700257 By default QCBOR fully supports IEEE 754 floating-point:
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700258 - Encode/decode of double, single and half-precision
259 - CBOR preferred serialization of floating-point
260 - Floating-point epoch dates
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700261
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700262 For the most part, the type double is used in the interface for
263 floating-point values. In the default configuration, all decoded
264 floating-point values are returned as a double.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700265
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700266 With CBOR preferred serialization, the encoder outputs the smallest
267 representation of the double or float that preserves precision. Zero,
268 NaN and infinity are always output as a half-precision, each taking
269 just 2 bytes. This reduces the number of bytes needed to encode
Laurence Lundblade4b270642020-08-14 12:53:07 -0700270 double and single-precision, especially if zero, NaN and infinity are
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700271 frequently used.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700272
Laurence Lundblade4b270642020-08-14 12:53:07 -0700273 To avoid use of preferred serialization in the standard configuration
274 when encoding, use QCBOREncode_AddDoubleNoPreferred() or
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700275 QCBOREncode_AddFloatNoPreferred().
276
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700277 This implementation of preferred floating-point serialization and
278 half-precision does not depend on the CPU having floating-point HW or
279 the compiler bringing in a (sometimes large) library to compensate
Laurence Lundblade4b270642020-08-14 12:53:07 -0700280 for lack of CPU support. This implementation uses shifts and masks
281 rather than floating-point functions.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700282
Laurence Lundblade4b270642020-08-14 12:53:07 -0700283 To reduce overall object code by about 900 bytes, define
284 QCBOR_DISABLE_PREFERRED_FLOAT. This will eliminate all support for
285 preferred serialization and half-precision. An error will be returned
286 when attempting to decode half-precision. A float will always be
287 encoded and decoded as 32-bits and a double will always be encoded
288 and decoded as 64 bits.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700289
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700290 Note that even if QCBOR_DISABLE_PREFERRED_FLOAT is not defined all
291 the float-point encoding object code can be avoided by never calling
Laurence Lundbladefe09bbf2020-07-16 12:14:51 -0700292 any functions that encode double or float. Just not calling
293 floating-point functions will reduce object code by about 500 bytes.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700294
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700295 On CPUs that have no floating-point hardware,
296 QCBOR_DISABLE_FLOAT_HW_USE should be defined in most cases. If it is
297 not, then the compiler will bring in possibly large software
Laurence Lundblade4b270642020-08-14 12:53:07 -0700298 libraries to compensate. Defining
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700299 QCBOR_DISABLE_FLOAT_HW_USE reduces object code size on CPUs with
Laurence Lundblade4b270642020-08-14 12:53:07 -0700300 floating-point hardware by a tiny amount and eliminates the need for <math.h>
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700301
Laurence Lundblade4b270642020-08-14 12:53:07 -0700302 When QCBOR_DISABLE_FLOAT_HW_USE is defined, trying to decoding
303 floating-point dates will give error @ref
304 QCBOR_ERR_FLOAT_DATE_DISABLED and decoded single-precision numbers
305 will be returned as @ref QCBOR_TYPE_FLOAT instead of converting them
306 to double as usual.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700307
308 If both QCBOR_DISABLE_FLOAT_HW_USE and QCBOR_DISABLE_PREFERRED_FLOAT
Laurence Lundblade4b270642020-08-14 12:53:07 -0700309 are defined, then the only thing QCBOR can do is encode/decode a C
310 float type as 32-bits and a C double type as 64-bits. Floating-point
311 epoch dates will be unsupported.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700312
Michael Eckel5c531332020-03-02 01:35:30 +0100313 Summary Limits of this implementation:
314 - The entire encoded CBOR must fit into contiguous memory.
315 - Max size of encoded / decoded CBOR data is @c UINT32_MAX (4GB).
316 - Max array / map nesting level when encoding / decoding is
317 @ref QCBOR_MAX_ARRAY_NESTING (this is typically 15).
318 - Max items in an array or map when encoding / decoding is
319 @ref QCBOR_MAX_ITEMS_IN_ARRAY (typically 65,536).
320 - Does not directly support labels in maps other than text strings & integers.
321 - Does not directly support integer labels greater than @c INT64_MAX.
322 - Epoch dates limited to @c INT64_MAX (+/- 292 billion years).
323 - Exponents for bigfloats and decimal integers are limited to @c INT64_MAX.
324 - Tags on labels are ignored during decoding.
325 - There is no duplicate detection of map labels (but duplicates are passed on).
326 - Works only on 32- and 64-bit CPUs (modifications could make it work
327 on 16-bit CPUs).
328
329 The public interface uses @c size_t for all lengths. Internally the
330 implementation uses 32-bit lengths by design to use less memory and
331 fit structures on the stack. This limits the encoded CBOR it can work
332 with to size @c UINT32_MAX (4GB) which should be enough.
333
334 This implementation assumes two's compliment integer machines. @c
335 <stdint.h> also requires this. It is possible to modify this
336 implementation for another integer representation, but all modern
337 machines seem to be two's compliment.
338
339 */
340
341
Michael Eckel5c531332020-03-02 01:35:30 +0100342/*
343 The size of the buffer to be passed to QCBOREncode_EncodeHead(). It is one
344 byte larger than sizeof(uint64_t) + 1, the actual maximum size of the
345 head of a CBOR data item. because QCBOREncode_EncodeHead() needs
346 one extra byte to work.
347 */
348#define QCBOR_HEAD_BUFFER_SIZE (sizeof(uint64_t) + 2)
349
Michael Eckel5c531332020-03-02 01:35:30 +0100350
Laurence Lundblade9b334962020-08-27 10:55:53 -0700351/**
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700352 Output the full CBOR tag. See @ref CBORTags, @ref Tag-Usage and @ref Tags-Overview.
Laurence Lundblade9b334962020-08-27 10:55:53 -0700353 */
354#define QCBOR_ENCODE_AS_TAG 0
355
356/**
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700357 Output only the 'borrowed' content format for the relevant tag.
358 See @ref CBORTags, @ref Tag-Usage and @ref Tags-Overview.
Laurence Lundblade9b334962020-08-27 10:55:53 -0700359 */
360#define QCBOR_ENCODE_AS_BORROWED 1
361
Michael Eckel5c531332020-03-02 01:35:30 +0100362
363/**
364 QCBOREncodeContext is the data type that holds context for all the
365 encoding functions. It is less than 200 bytes, so it can go on the
366 stack. The contents are opaque, and the caller should not access
367 internal members. A context may be re used serially as long as it is
368 re initialized.
369 */
370typedef struct _QCBOREncodeContext QCBOREncodeContext;
371
372
373/**
374 Initialize the encoder to prepare to encode some CBOR.
375
376 @param[in,out] pCtx The encoder context to initialize.
377 @param[in] Storage The buffer into which this encoded result
378 will be placed.
379
380 Call this once at the start of an encoding of a CBOR structure. Then
381 call the various @c QCBOREncode_AddXxx() functions to add the data
382 items. Then call QCBOREncode_Finish().
383
384 The maximum output buffer is @c UINT32_MAX (4GB). This is not a
385 practical limit in any way and reduces the memory needed by the
386 implementation. The error @ref QCBOR_ERR_BUFFER_TOO_LARGE will be
387 returned by QCBOREncode_Finish() if a larger buffer length is passed
388 in.
389
390 If this is called with @c Storage.ptr as @c NULL and @c Storage.len a
391 large value like @c UINT32_MAX, all the QCBOREncode_AddXxx()
392 functions and QCBOREncode_Finish() can still be called. No data will
393 be encoded, but the length of what would be encoded will be
394 calculated. The length of the encoded structure will be handed back
395 in the call to QCBOREncode_Finish(). You can then allocate a buffer
396 of that size and call all the encoding again, this time to fill in
397 the buffer.
398
399 A @ref QCBOREncodeContext can be reused over and over as long as
400 QCBOREncode_Init() is called.
401 */
402void QCBOREncode_Init(QCBOREncodeContext *pCtx, UsefulBuf Storage);
403
404
405/**
406 @brief Add a signed 64-bit integer to the encoded output.
407
408 @param[in] pCtx The encoding context to add the integer to.
409 @param[in] nNum The integer to add.
410
411 The integer will be encoded and added to the CBOR output.
412
413 This function figures out the size and the sign and encodes in the
414 correct minimal CBOR. Specifically, it will select CBOR major type 0
415 or 1 based on sign and will encode to 1, 2, 4 or 8 bytes depending on
416 the value of the integer. Values less than 24 effectively encode to
417 one byte because they are encoded in with the CBOR major type. This
418 is a neat and efficient characteristic of CBOR that can be taken
419 advantage of when designing CBOR-based protocols. If integers like
420 tags can be kept between -23 and 23 they will be encoded in one byte
421 including the major type.
422
423 If you pass a smaller int, say an @c int16_t or a small value, say
424 100, the encoding will still be CBOR's most compact that can
425 represent the value. For example, CBOR always encodes the value 0 as
426 one byte, 0x00. The representation as 0x00 includes identification of
427 the type as an integer too as the major type for an integer is 0. See
428 [RFC 7049] (https://tools.ietf.org/html/rfc7049) Appendix A for more
429 examples of CBOR encoding. This compact encoding is also canonical
430 CBOR as per section 3.9 in RFC 7049.
431
432 There are no functions to add @c int16_t or @c int32_t because they
433 are not necessary because this always encodes to the smallest number
434 of bytes based on the value (If this code is running on a 32-bit
435 machine having a way to add 32-bit integers would reduce code size
436 some).
437
438 If the encoding context is in an error state, this will do
439 nothing. If an error occurs when adding this integer, the internal
440 error flag will be set, and the error will be returned when
441 QCBOREncode_Finish() is called.
442
443 See also QCBOREncode_AddUInt64().
444 */
445void QCBOREncode_AddInt64(QCBOREncodeContext *pCtx, int64_t nNum);
446
447static void QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum);
448
449static void QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum);
450
451
452/**
453 @brief Add an unsigned 64-bit integer to the encoded output.
454
455 @param[in] pCtx The encoding context to add the integer to.
456 @param[in] uNum The integer to add.
457
458 The integer will be encoded and added to the CBOR output.
459
460 The only reason so use this function is for integers larger than @c
461 INT64_MAX and smaller than @c UINT64_MAX. Otherwise
462 QCBOREncode_AddInt64() will work fine.
463
464 Error handling is the same as for QCBOREncode_AddInt64().
465 */
466void QCBOREncode_AddUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
467
468static void QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum);
469
470static void QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum);
471
472
473/**
474 @brief Add a UTF-8 text string to the encoded output.
475
476 @param[in] pCtx The encoding context to add the text to.
477 @param[in] Text Pointer and length of text to add.
478
479 The text passed in must be unencoded UTF-8 according to [RFC 3629]
480 (https://tools.ietf.org/html/rfc3629). There is no NULL
481 termination. The text is added as CBOR major type 3.
482
483 If called with @c nBytesLen equal to 0, an empty string will be
484 added. When @c nBytesLen is 0, @c pBytes may be @c NULL.
485
486 Note that the restriction of the buffer length to a @c uint32_t is
487 entirely intentional as this encoder is not capable of encoding
488 lengths greater. This limit to 4GB for a text string should not be a
489 problem.
490
491 Error handling is the same as QCBOREncode_AddInt64().
492 */
493static void QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text);
494
495static void QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text);
496
497static void QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text);
498
499
500/**
501 @brief Add a UTF-8 text string to the encoded output.
502
503 @param[in] pCtx The encoding context to add the text to.
504 @param[in] szString Null-terminated text to add.
505
506 This works the same as QCBOREncode_AddText().
507 */
508static void QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString);
509
510static void QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString);
511
512static void QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString);
513
514
515/**
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700516 @brief Add a double-precision floating-point number to the encoded output.
Michael Eckel5c531332020-03-02 01:35:30 +0100517
518 @param[in] pCtx The encoding context to add the double to.
519 @param[in] dNum The double-precision number to add.
520
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700521 This encodes and outputs a floating-point number. CBOR major type 7
522 is used.
Michael Eckel5c531332020-03-02 01:35:30 +0100523
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700524 This implements preferred serialization, selectively encoding the
525 double-precision floating-point number as either double-precision,
526 single-precision or half-precision. Infinity, NaN and 0 are always
527 encoded as half-precision. If no precision will be lost in the
528 conversion to half-precision, then it will be converted and
529 encoded. If not and no precision will be lost in conversion to
530 single-precision, then it will be converted and encoded. If not, then
531 no conversion is performed, and it encoded as a double-precision.
Michael Eckel5c531332020-03-02 01:35:30 +0100532
533 Half-precision floating-point numbers take up 2 bytes, half that of
534 single-precision, one quarter of double-precision
535
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700536 This automatically reduces the size of encoded CBOR, maybe even by
537 four if most of values are 0, infinity or NaN.
Michael Eckel5c531332020-03-02 01:35:30 +0100538
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700539 When decoded, QCBOR will usually return these values as
540 double-precision.
541
542 It is possible to disable this preferred serialization when compiling
543 QCBOR. In that case, this functions the same as
544 QCBOREncode_AddDoubleNoPreferred().
Michael Eckel5c531332020-03-02 01:35:30 +0100545
546 Error handling is the same as QCBOREncode_AddInt64().
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700547
548 See also QCBOREncode_AddDoubleNoPreferred(), QCBOREncode_AddFloat()
549 and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
Michael Eckel5c531332020-03-02 01:35:30 +0100550 */
551void QCBOREncode_AddDouble(QCBOREncodeContext *pCtx, double dNum);
552
553static void QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
554
555static void QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
556
557
558/**
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700559 @brief Add a single-precision floating-point number to the encoded output.
560
561 @param[in] pCtx The encoding context to add the double to.
562 @param[in] fNum The single-precision number to add.
563
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700564 This is identical to QCBOREncode_AddDouble() except the input is
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700565 single-precision.
566
567 See also QCBOREncode_AddDouble(), QCBOREncode_AddDoubleNoPreferred(),
568 and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
569*/
570void QCBOREncode_AddFloat(QCBOREncodeContext *pCtx, float fNum);
571
572static void QCBOREncode_AddFloatToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
573
574static void QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700575
576
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700577/**
578 @brief Add a double-precision floating-point number without preferred encoding.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700579
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700580 @param[in] pCtx The encoding context to add the double to.
581 @param[in] dNum The double-precision number to add.
582
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700583 This always outputs the number as a 64-bit double-precision.
584 Preferred serialization is not used.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700585
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700586 Error handling is the same as QCBOREncode_AddInt64().
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700587
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700588 See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
589 QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700590*/
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700591void QCBOREncode_AddDoubleNoPreferred(QCBOREncodeContext *pCtx, double dNum);
592
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700593static void QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
594
595static void QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
596
597
598/**
599 @brief Add a single-precision floating-point number without preferred encoding.
600
601 @param[in] pCtx The encoding context to add the double to.
602 @param[in] fNum The single-precision number to add.
603
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700604 This always outputs the number as a 32-bit single-precision.
605 Preferred serialization is not used.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700606
607 Error handling is the same as QCBOREncode_AddInt64().
608
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700609 See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
610 QCBOREncode_AddDoubleNoPreferred() and @ref Floating-Point.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700611*/
612void QCBOREncode_AddFloatNoPreferred(QCBOREncodeContext *pCtx, float fNum);
613
614static void QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
615
616static void QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float fNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700617
618
Michael Eckel5c531332020-03-02 01:35:30 +0100619
620/**
621 @brief Add an optional tag.
622
623 @param[in] pCtx The encoding context to add the tag to.
624 @param[in] uTag The tag to add
625
626 This outputs a CBOR major type 6 item that tags the next data item
627 that is output usually to indicate it is some new data type.
628
629 For many of the common standard tags, a function to encode data using
630 it is provided and this is not needed. For example,
631 QCBOREncode_AddDateEpoch() already exists to output integers
632 representing dates with the right tag.
633
634 The tag is applied to the next data item added to the encoded
635 output. That data item that is to be tagged can be of any major CBOR
636 type. Any number of tags can be added to a data item by calling this
637 multiple times before the data item is added.
638
639 See @ref Tags-Overview for discussion of creating new non-standard
640 tags. See QCBORDecode_GetNext() for discussion of decoding custom
641 tags.
642*/
643void QCBOREncode_AddTag(QCBOREncodeContext *pCtx,uint64_t uTag);
644
645
646/**
647 @brief Add an epoch-based date.
648
649 @param[in] pCtx The encoding context to add the date to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700650 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700651 @param[in] nDate Number of seconds since 1970-01-01T00:00Z in UTC time.
Michael Eckel5c531332020-03-02 01:35:30 +0100652
653 As per RFC 7049 this is similar to UNIX/Linux/POSIX dates. This is
654 the most compact way to specify a date and time in CBOR. Note that
655 this is always UTC and does not include the time zone. Use
656 QCBOREncode_AddDateString() if you want to include the time zone.
657
658 The integer encoding rules apply here so the date will be encoded in
659 a minimal number of bytes. Until about the year 2106 these dates will
660 encode in 6 bytes -- one byte for the tag, one byte for the type and
661 4 bytes for the integer. After that it will encode to 10 bytes.
662
663 Negative values are supported for dates before 1970.
664
665 If you care about leap-seconds and that level of accuracy, make sure
666 the system you are running this code on does it correctly. This code
667 just takes the value passed in.
668
669 This implementation cannot encode fractional seconds using float or
670 double even though that is allowed by CBOR, but you can encode them
671 if you want to by calling QCBOREncode_AddDouble() and
672 QCBOREncode_AddTag().
673
674 Error handling is the same as QCBOREncode_AddInt64().
675 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700676static void QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pCtx,
677 uint8_t uTagRequirement,
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700678 int64_t nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -0700679
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700680static void QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pCtx,
681 const char *szLabel,
682 uint8_t uTagRequirement,
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700683 int64_t nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -0700684
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700685static void QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pCtx,
686 int64_t nLabel,
687 uint8_t uTagRequirement,
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700688 int64_t nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -0700689
690
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700691static void QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx,
692 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100693
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700694static void QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx,
695 const char *szLabel,
696 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100697
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700698static void QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx,
699 int64_t nLabel,
700 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100701
702
703/**
704 @brief Add a byte string to the encoded output.
705
706 @param[in] pCtx The encoding context to add the bytes to.
707 @param[in] Bytes Pointer and length of the input data.
708
709 Simply adds the bytes to the encoded output as CBOR major type 2.
710
711 If called with @c Bytes.len equal to 0, an empty string will be
712 added. When @c Bytes.len is 0, @c Bytes.ptr may be @c NULL.
713
714 Error handling is the same as QCBOREncode_AddInt64().
715 */
716static void QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
717
718static void QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
719
720static void QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
721
722
723
724/**
725 @brief Add a binary UUID to the encoded output.
726
727 @param[in] pCtx The encoding context to add the UUID to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700728 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100729 @param[in] Bytes Pointer and length of the binary UUID.
730
731 A binary UUID as defined in [RFC 4122]
732 (https://tools.ietf.org/html/rfc4122) is added to the output.
733
734 It is output as CBOR major type 2, a binary string, with tag @ref
735 CBOR_TAG_BIN_UUID indicating the binary string is a UUID.
736 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700737static void QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pCtx,
738 uint8_t uTagRequirement,
739 UsefulBufC Bytes);
740
741static void QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pCtx,
742 const char *szLabel,
743 uint8_t uTagRequirement,
744 UsefulBufC Bytes);
745
746static void QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pCtx,
747 int64_t nLabel,
748 uint8_t uTagRequirement,
749 UsefulBufC Bytes);
750
751
Michael Eckel5c531332020-03-02 01:35:30 +0100752static void QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
753
754static void QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
755
756static void QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
757
758
759/**
760 @brief Add a positive big number to the encoded output.
761
762 @param[in] pCtx The encoding context to add the big number to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700763 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100764 @param[in] Bytes Pointer and length of the big number.
765
766 Big numbers are integers larger than 64-bits. Their format is
767 described in [RFC 7049] (https://tools.ietf.org/html/rfc7049).
768
769 It is output as CBOR major type 2, a binary string, with tag @ref
770 CBOR_TAG_POS_BIGNUM indicating the binary string is a positive big
771 number.
772
773 Often big numbers are used to represent cryptographic keys, however,
774 COSE which defines representations for keys chose not to use this
775 particular type.
776 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700777static void QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pCtx,
778 uint8_t uTagRequirement,
779 UsefulBufC Bytes);
780
781static void QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pCtx,
782 const char *szLabel,
783 uint8_t uTagRequirement,
784 UsefulBufC Bytes);
785
786static void QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pCtx,
787 int64_t nLabel,
788 uint8_t uTagRequirement,
789 UsefulBufC Bytes);
790
791
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700792static void QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx,
793 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100794
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700795static void QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx,
796 const char *szLabel,
797 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100798
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700799static void QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx,
800 int64_t nLabel,
801 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100802
803
804/**
805 @brief Add a negative big number to the encoded output.
806
807 @param[in] pCtx The encoding context to add the big number to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700808 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100809 @param[in] Bytes Pointer and length of the big number.
810
811 Big numbers are integers larger than 64-bits. Their format is
812 described in [RFC 7049] (https://tools.ietf.org/html/rfc7049).
813
814 It is output as CBOR major type 2, a binary string, with tag @ref
815 CBOR_TAG_NEG_BIGNUM indicating the binary string is a negative big
816 number.
817
818 Often big numbers are used to represent cryptographic keys, however,
819 COSE which defines representations for keys chose not to use this
820 particular type.
821 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700822static void QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pCtx,
823 uint8_t uTagRequirement,
824 UsefulBufC Bytes);
825
826static void QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pCtx,
827 const char *szLabel,
828 uint8_t uTagRequirement,
829 UsefulBufC Bytes);
830
831static void QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pCtx,
832 int64_t nLabel,
833 uint8_t uTagRequirement,
834 UsefulBufC Bytes);
835
836
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700837static void QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx,
838 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100839
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700840static void QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx,
841 const char *szLabel,
842 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100843
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700844static void QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx,
845 int64_t nLabel,
846 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100847
848
849#ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
850/**
851 @brief Add a decimal fraction to the encoded output.
852
853 @param[in] pCtx The encoding context to add the decimal fraction to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700854 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100855 @param[in] nMantissa The mantissa.
856 @param[in] nBase10Exponent The exponent.
857
858 The value is nMantissa * 10 ^ nBase10Exponent.
859
860 A decimal fraction is good for exact representation of some values
861 that can't be represented exactly with standard C (IEEE 754)
862 floating-point numbers. Much larger and much smaller numbers can
863 also be represented than floating-point because of the larger number
864 of bits in the exponent.
865
866 The decimal fraction is conveyed as two integers, a mantissa and a
867 base-10 scaling factor.
868
869 For example, 273.15 is represented by the two integers 27315 and -2.
870
871 The exponent and mantissa have the range from @c INT64_MIN to
872 @c INT64_MAX for both encoding and decoding (CBOR allows @c -UINT64_MAX
873 to @c UINT64_MAX, but this implementation doesn't support this range to
874 reduce code size and interface complexity a little).
875
876 CBOR Preferred encoding of the integers is used, thus they will be encoded
877 in the smallest number of bytes possible.
878
879 See also QCBOREncode_AddDecimalFractionBigNum() for a decimal
880 fraction with arbitrarily large precision and QCBOREncode_AddBigFloat().
881
882 There is no representation of positive or negative infinity or NaN
883 (Not a Number). Use QCBOREncode_AddDouble() to encode them.
884
885 See @ref expAndMantissa for decoded representation.
886 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700887static void QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pCtx,
888 uint8_t uTagRequirement,
889 int64_t nMantissa,
890 int64_t nBase10Exponent);
891
892static void QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pCtx,
893 const char *szLabel,
894 uint8_t uTagRequirement,
895 int64_t nMantissa,
896 int64_t nBase10Exponent);
897
898static void QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pCtx,
899 int64_t nLabel,
900 uint8_t uTagRequirement,
901 int64_t nMantissa,
902 int64_t nBase10Exponent);
903
904
Michael Eckel5c531332020-03-02 01:35:30 +0100905static void QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pCtx,
906 int64_t nMantissa,
907 int64_t nBase10Exponent);
908
909static void QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pCtx,
910 const char *szLabel,
911 int64_t nMantissa,
912 int64_t nBase10Exponent);
913
914static void QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pCtx,
915 int64_t nLabel,
916 int64_t nMantissa,
917 int64_t nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +0100918/**
919 @brief Add a decimal fraction with a big number mantissa to the encoded output.
920
921 @param[in] pCtx The encoding context to add the decimal fraction to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700922 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100923 @param[in] Mantissa The mantissa.
924 @param[in] bIsNegative false if mantissa is positive, true if negative.
925 @param[in] nBase10Exponent The exponent.
926
927 This is the same as QCBOREncode_AddDecimalFraction() except the
928 mantissa is a big number (See QCBOREncode_AddPositiveBignum())
929 allowing for arbitrarily large precision.
930
931 See @ref expAndMantissa for decoded representation.
932 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700933static void QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pCtx,
934 uint8_t uTagRequirement,
935 UsefulBufC Mantissa,
936 bool bIsNegative,
937 int64_t nBase10Exponent);
938
939static void QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
940 const char *szLabel,
941 uint8_t uTagRequirement,
942 UsefulBufC Mantissa,
943 bool bIsNegative,
944 int64_t nBase10Exponent);
945
946static void QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
947 int64_t nLabel,
948 uint8_t uTagRequirement,
949 UsefulBufC Mantissa,
950 bool bIsNegative,
951 int64_t nBase10Exponent);
952
953
Michael Eckel5c531332020-03-02 01:35:30 +0100954static void QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pCtx,
955 UsefulBufC Mantissa,
956 bool bIsNegative,
957 int64_t nBase10Exponent);
958
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700959static void QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
Michael Eckel5c531332020-03-02 01:35:30 +0100960 const char *szLabel,
961 UsefulBufC Mantissa,
962 bool bIsNegative,
963 int64_t nBase10Exponent);
964
965static void QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
966 int64_t nLabel,
967 UsefulBufC Mantissa,
968 bool bIsNegative,
969 int64_t nBase10Exponent);
970
971/**
972 @brief Add a big floating-point number to the encoded output.
973
974 @param[in] pCtx The encoding context to add the bigfloat to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700975 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100976 @param[in] nMantissa The mantissa.
977 @param[in] nBase2Exponent The exponent.
978
979 The value is nMantissa * 2 ^ nBase2Exponent.
980
981 "Bigfloats", as CBOR terms them, are similar to IEEE floating-point
982 numbers in having a mantissa and base-2 exponent, but they are not
983 supported by hardware or encoded the same. They explicitly use two
984 CBOR-encoded integers to convey the mantissa and exponent, each of which
985 can be 8, 16, 32 or 64 bits. With both the mantissa and exponent
986 64 bits they can express more precision and a larger range than an
987 IEEE double floating-point number. See
988 QCBOREncode_AddBigFloatBigNum() for even more precision.
989
990 For example, 1.5 would be represented by a mantissa of 3 and an
991 exponent of -1.
992
993 The exponent and mantissa have the range from @c INT64_MIN to
994 @c INT64_MAX for both encoding and decoding (CBOR allows @c -UINT64_MAX
995 to @c UINT64_MAX, but this implementation doesn't support this range to
996 reduce code size and interface complexity a little).
997
998 CBOR Preferred encoding of the integers is used, thus they will be encoded
999 in the smallest number of bytes possible.
1000
1001 This can also be used to represent floating-point numbers in
1002 environments that don't support IEEE 754.
1003
1004 See @ref expAndMantissa for decoded representation.
1005 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001006static void QCBOREncode_AddTBigFloat(QCBOREncodeContext *pCtx,
1007 uint8_t uTagRequirement,
1008 int64_t nMantissa,
1009 int64_t nBase2Exponent);
1010
1011static void QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pCtx,
1012 const char *szLabel,
1013 uint8_t uTagRequirement,
1014 int64_t nMantissa,
1015 int64_t nBase2Exponent);
1016
1017static void QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pCtx,
1018 int64_t nLabel,
1019 uint8_t uTagRequirement,
1020 int64_t nMantissa,
1021 int64_t nBase2Exponent);
1022
1023
Michael Eckel5c531332020-03-02 01:35:30 +01001024static void QCBOREncode_AddBigFloat(QCBOREncodeContext *pCtx,
1025 int64_t nMantissa,
1026 int64_t nBase2Exponent);
1027
1028static void QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pCtx,
1029 const char *szLabel,
1030 int64_t nMantissa,
1031 int64_t nBase2Exponent);
1032
1033static void QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pCtx,
1034 int64_t nLabel,
1035 int64_t nMantissa,
1036 int64_t nBase2Exponent);
1037
Michael Eckel5c531332020-03-02 01:35:30 +01001038/**
1039 @brief Add a big floating-point number with a big number mantissa to
1040 the encoded output.
1041
1042 @param[in] pCtx The encoding context to add the bigfloat to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001043 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001044 @param[in] Mantissa The mantissa.
1045 @param[in] bIsNegative false if mantissa is positive, true if negative.
1046 @param[in] nBase2Exponent The exponent.
1047
1048 This is the same as QCBOREncode_AddBigFloat() except the mantissa is
1049 a big number (See QCBOREncode_AddPositiveBignum()) allowing for
1050 arbitrary precision.
1051
1052 See @ref expAndMantissa for decoded representation.
1053 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001054static void QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pCtx,
1055 uint8_t uTagRequirement,
1056 UsefulBufC Mantissa,
1057 bool bIsNegative,
1058 int64_t nBase2Exponent);
1059
1060static void QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pCtx,
1061 const char *szLabel,
1062 uint8_t uTagRequirement,
1063 UsefulBufC Mantissa,
1064 bool bIsNegative,
1065 int64_t nBase2Exponent);
1066
1067static void QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1068 int64_t nLabel,
1069 uint8_t uTagRequirement,
1070 UsefulBufC Mantissa,
1071 bool bIsNegative,
1072 int64_t nBase2Exponent);
1073
1074
Michael Eckel5c531332020-03-02 01:35:30 +01001075static void QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pCtx,
1076 UsefulBufC Mantissa,
1077 bool bIsNegative,
1078 int64_t nBase2Exponent);
1079
1080static void QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pCtx,
1081 const char *szLabel,
1082 UsefulBufC Mantissa,
1083 bool bIsNegative,
1084 int64_t nBase2Exponent);
1085
1086static void QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1087 int64_t nLabel,
1088 UsefulBufC Mantissa,
1089 bool bIsNegative,
1090 int64_t nBase2Exponent);
1091#endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
1092
1093
1094/**
1095 @brief Add a text URI to the encoded output.
1096
1097 @param[in] pCtx The encoding context to add the URI to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001098 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001099 @param[in] URI Pointer and length of the URI.
1100
1101 The format of URI must be per [RFC 3986]
1102 (https://tools.ietf.org/html/rfc3986).
1103
1104 It is output as CBOR major type 3, a text string, with tag @ref
1105 CBOR_TAG_URI indicating the text string is a URI.
1106
1107 A URI in a NULL-terminated string, @c szURI, can be easily added with
1108 this code:
1109
1110 QCBOREncode_AddURI(pCtx, UsefulBuf_FromSZ(szURI));
1111 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001112static void QCBOREncode_AddTURI(QCBOREncodeContext *pCtx,
1113 uint8_t uTagRequirement,
1114 UsefulBufC URI);
1115
1116static void QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pCtx,
1117 const char *szLabel,
1118 uint8_t uTagRequirement,
1119 UsefulBufC URI);
1120
1121static void QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pCtx,
1122 int64_t nLabel,
1123 uint8_t uTagRequirement,
1124 UsefulBufC URI);
1125
1126
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001127static void QCBOREncode_AddURI(QCBOREncodeContext *pCtx,
1128 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001129
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001130static void QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx,
1131 const char *szLabel,
1132 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001133
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001134static void QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx,
1135 int64_t nLabel,
1136 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001137
1138
1139/**
1140 @brief Add Base64-encoded text to encoded output.
1141
1142 @param[in] pCtx The encoding context to add the base-64 text to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001143 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001144 @param[in] B64Text Pointer and length of the base-64 encoded text.
1145
1146 The text content is Base64 encoded data per [RFC 4648]
1147 (https://tools.ietf.org/html/rfc4648).
1148
1149 It is output as CBOR major type 3, a text string, with tag @ref
1150 CBOR_TAG_B64 indicating the text string is Base64 encoded.
1151 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001152static void QCBOREncode_AddTB64Text(QCBOREncodeContext *pCtx,
1153 uint8_t uTagRequirement,
1154 UsefulBufC B64Text);
1155
1156static void QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pCtx,
1157 const char *szLabel,
1158 uint8_t uTagRequirement,
1159 UsefulBufC B64Text);
1160
1161static void QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pCtx,
1162 int64_t nLabel,
1163 uint8_t uTagRequirement,
1164 UsefulBufC B64Text);
1165
1166
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001167static void QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx,
1168 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001169
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001170static void QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx,
1171 const char *szLabel,
1172 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001173
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001174static void QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx,
1175 int64_t nLabel,
1176 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001177
1178
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001179
Michael Eckel5c531332020-03-02 01:35:30 +01001180/**
1181 @brief Add base64url encoded data to encoded output.
1182
1183 @param[in] pCtx The encoding context to add the base64url to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001184 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001185 @param[in] B64Text Pointer and length of the base64url encoded text.
1186
1187 The text content is base64URL encoded text as per [RFC 4648]
1188 (https://tools.ietf.org/html/rfc4648).
1189
1190 It is output as CBOR major type 3, a text string, with tag @ref
1191 CBOR_TAG_B64URL indicating the text string is a Base64url encoded.
1192 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001193static void QCBOREncode_AddTB64URLText(QCBOREncodeContext *pCtx,
1194 uint8_t uTagRequirement,
1195 UsefulBufC B64Text);
1196
1197static void QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pCtx,
1198 const char *szLabel,
1199 uint8_t uTagRequirement,
1200 UsefulBufC B64Text);
1201
1202static void QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pCtx,
1203 int64_t nLabel,
1204 uint8_t uTagRequirement,
1205 UsefulBufC B64Text);
1206
1207
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001208static void QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx,
1209 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001210
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001211static void QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx,
1212 const char *szLabel,
1213 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001214
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001215static void QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx,
1216 int64_t nLabel,
1217 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001218
1219
1220/**
1221 @brief Add Perl Compatible Regular Expression.
1222
1223 @param[in] pCtx The encoding context to add the regular expression to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001224 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001225 @param[in] Regex Pointer and length of the regular expression.
1226
1227 The text content is Perl Compatible Regular
1228 Expressions (PCRE) / JavaScript syntax [ECMA262].
1229
1230 It is output as CBOR major type 3, a text string, with tag @ref
1231 CBOR_TAG_REGEX indicating the text string is a regular expression.
1232 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001233static void QCBOREncode_AddTRegex(QCBOREncodeContext *pCtx,
1234 uint8_t uTagRequirement,
1235 UsefulBufC Regex);
1236
1237static void QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pCtx,
1238 const char *szLabel,
1239 uint8_t uTagRequirement,
1240 UsefulBufC Regex);
1241
1242static void QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pCtx,
1243 int64_t nLabel,
1244 uint8_t uTagRequirement,
1245 UsefulBufC Regex);
1246
1247
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001248static void QCBOREncode_AddRegex(QCBOREncodeContext *pCtx,
1249 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001250
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001251static void QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx,
1252 const char *szLabel,
1253 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001254
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001255static void QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx,
1256 int64_t nLabel,
1257 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001258
1259
1260/**
Laurence Lundblade4982f412020-09-18 23:02:18 -07001261 @brief MIME encoded data to the encoded output.
Michael Eckel5c531332020-03-02 01:35:30 +01001262
Laurence Lundblade4982f412020-09-18 23:02:18 -07001263 @param[in] pCtx The encoding context to add the MIME data to.
1264 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1265 @ref QCBOR_ENCODE_AS_BORROWED.
1266 @param[in] MIMEData Pointer and length of the MIME data.
Michael Eckel5c531332020-03-02 01:35:30 +01001267
1268 The text content is in MIME format per [RFC 2045]
Laurence Lundblade4982f412020-09-18 23:02:18 -07001269 (https://tools.ietf.org/html/rfc2045) including the headers.
Michael Eckel5c531332020-03-02 01:35:30 +01001270
Laurence Lundblade4982f412020-09-18 23:02:18 -07001271 It is output as CBOR major type 2, a binary string, with tag @ref
1272 CBOR_TAG_BINARY_MIME indicating the string is MIME data. This
1273 outputs tag 257, not tag 36, as it can carry any type of MIME binary,
1274 7-bit, 8-bit, quoted-printable and base64 where tag 36 cannot.
1275
1276 Previous versions of QCBOR, those before spiffy decode, output tag
1277 36. Decoding supports both tag 36 and 257. (if the old behavior with
1278 tag 36 is needed, copy the inline functions below and change the tag
1279 number).
1280
1281 See also QCBORDecode_GetMIMEMessage() and
1282 @ref QCBOR_TYPE_BINARY_MIME.
Michael Eckel5c531332020-03-02 01:35:30 +01001283 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001284static void QCBOREncode_AddTMIMEData(QCBOREncodeContext *pCtx,
1285 uint8_t uTagRequirement,
1286 UsefulBufC MIMEData);
1287
1288static void QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pCtx,
1289 const char *szLabel,
1290 uint8_t uTagRequirement,
1291 UsefulBufC MIMEData);
1292
1293static void QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pCtx,
1294 int64_t nLabel,
1295 uint8_t uTagRequirement,
1296 UsefulBufC MIMEData);
1297
1298
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001299static void QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx,
1300 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001301
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001302static void QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx,
1303 const char *szLabel,
1304 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001305
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001306static void QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx,
1307 int64_t nLabel,
1308 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001309
1310
1311/**
1312 @brief Add an RFC 3339 date string
1313
1314 @param[in] pCtx The encoding context to add the date to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001315 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001316 @param[in] szDate Null-terminated string with date to add.
1317
1318 The string szDate should be in the form of [RFC 3339]
1319 (https://tools.ietf.org/html/rfc3339) as defined by section 3.3 in
1320 [RFC 4287] (https://tools.ietf.org/html/rfc4287). This is as
1321 described in section 2.4.1 in [RFC 7049]
1322 (https://tools.ietf.org/html/rfc7049).
1323
1324 Note that this function doesn't validate the format of the date string
1325 at all. If you add an incorrect format date string, the generated
1326 CBOR will be incorrect and the receiver may not be able to handle it.
1327
1328 Error handling is the same as QCBOREncode_AddInt64().
1329 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001330static void QCBOREncode_AddTDateString(QCBOREncodeContext *pCtx,
1331 uint8_t uTagRequirement,
1332 const char *szDate);
1333
1334static void QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pCtx,
1335 const char *szLabel,
1336 uint8_t uTagRequirement,
1337 const char *szDate);
1338
1339static void QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pCtx,
1340 int64_t nLabel,
1341 uint8_t uTagRequirement,
1342 const char *szDate);
1343
1344
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001345static void QCBOREncode_AddDateString(QCBOREncodeContext *pCtx,
1346 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001347
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001348static void QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx,
1349 const char *szLabel,
1350 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001351
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001352static void QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx,
1353 int64_t nLabel,
1354 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001355
Michael Eckel5c531332020-03-02 01:35:30 +01001356/**
1357 @brief Add a standard Boolean.
1358
1359 @param[in] pCtx The encoding context to add the Boolean to.
1360 @param[in] b true or false from @c <stdbool.h>.
1361
1362 Adds a Boolean value as CBOR major type 7.
1363
1364 Error handling is the same as QCBOREncode_AddInt64().
1365 */
1366static void QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b);
1367
1368static void QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b);
1369
1370static void QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b);
1371
1372
1373
1374/**
1375 @brief Add a NULL to the encoded output.
1376
1377 @param[in] pCtx The encoding context to add the NULL to.
1378
1379 Adds the NULL value as CBOR major type 7.
1380
1381 This NULL doesn't have any special meaning in CBOR such as a
1382 terminating value for a string or an empty value.
1383
1384 Error handling is the same as QCBOREncode_AddInt64().
1385 */
1386static void QCBOREncode_AddNULL(QCBOREncodeContext *pCtx);
1387
1388static void QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1389
1390static void QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1391
1392
1393/**
1394 @brief Add an "undef" to the encoded output.
1395
1396 @param[in] pCtx The encoding context to add the "undef" to.
1397
1398 Adds the undef value as CBOR major type 7.
1399
1400 Note that this value will not translate to JSON.
1401
1402 This Undef doesn't have any special meaning in CBOR such as a
1403 terminating value for a string or an empty value.
1404
1405 Error handling is the same as QCBOREncode_AddInt64().
1406 */
1407static void QCBOREncode_AddUndef(QCBOREncodeContext *pCtx);
1408
1409static void QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1410
1411static void QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1412
1413
1414/**
1415 @brief Indicates that the next items added are in an array.
1416
1417 @param[in] pCtx The encoding context to open the array in.
1418
1419 Arrays are the basic CBOR aggregate or structure type. Call this
1420 function to start or open an array. Then call the various @c
1421 QCBOREncode_AddXxx() functions to add the items that go into the
1422 array. Then call QCBOREncode_CloseArray() when all items have been
1423 added. The data items in the array can be of any type and can be of
1424 mixed types.
1425
1426 Nesting of arrays and maps is allowed and supported just by calling
1427 QCBOREncode_OpenArray() again before calling
1428 QCBOREncode_CloseArray(). While CBOR has no limit on nesting, this
1429 implementation does in order to keep it smaller and simpler. The
1430 limit is @ref QCBOR_MAX_ARRAY_NESTING. This is the max number of
1431 times this can be called without calling
1432 QCBOREncode_CloseArray(). QCBOREncode_Finish() will return @ref
1433 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP when it is called as this function
1434 just sets an error state and returns no value when this occurs.
1435
1436 If you try to add more than @ref QCBOR_MAX_ITEMS_IN_ARRAY items to a
1437 single array or map, @ref QCBOR_ERR_ARRAY_TOO_LONG will be returned
1438 when QCBOREncode_Finish() is called.
1439
1440 An array itself must have a label if it is being added to a map.
1441 Note that array elements do not have labels (but map elements do).
1442
1443 An array itself may be tagged by calling QCBOREncode_AddTag() before this call.
1444 */
1445static void QCBOREncode_OpenArray(QCBOREncodeContext *pCtx);
1446
1447static void QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1448
1449static void QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1450
1451
1452/**
1453 @brief Close an open array.
1454
1455 @param[in] pCtx The encoding context to close the array in.
1456
1457 The closes an array opened by QCBOREncode_OpenArray(). It reduces
1458 nesting level by one. All arrays (and maps) must be closed before
1459 calling QCBOREncode_Finish().
1460
1461 When an error occurs as a result of this call, the encoder records
1462 the error and enters the error state. The error will be returned when
1463 QCBOREncode_Finish() is called.
1464
1465 If this has been called more times than QCBOREncode_OpenArray(), then
1466 @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when QCBOREncode_Finish()
1467 is called.
1468
1469 If this is called and it is not an array that is currently open, @ref
1470 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
1471 is called.
1472 */
1473static void QCBOREncode_CloseArray(QCBOREncodeContext *pCtx);
1474
1475
1476/**
1477 @brief Indicates that the next items added are in a map.
1478
1479 @param[in] pCtx The encoding context to open the map in.
1480
1481 See QCBOREncode_OpenArray() for more information, particularly error
1482 handling.
1483
1484 CBOR maps are an aggregate type where each item in the map consists
1485 of a label and a value. They are similar to JSON objects.
1486
1487 The value can be any CBOR type including another map.
1488
1489 The label can also be any CBOR type, but in practice they are
1490 typically, integers as this gives the most compact output. They might
1491 also be text strings which gives readability and translation to JSON.
1492
1493 Every @c QCBOREncode_AddXxx() call has one version that ends with @c
1494 InMap for adding items to maps with string labels and one that ends
1495 with @c InMapN that is for adding with integer labels.
1496
1497 RFC 7049 uses the term "key" instead of "label".
1498
1499 If you wish to use map labels that are neither integer labels nor
1500 text strings, then just call the QCBOREncode_AddXxx() function
1501 explicitly to add the label. Then call it again to add the value.
1502
1503 See the [RFC 7049] (https://tools.ietf.org/html/rfc7049) for a lot
1504 more information on creating maps.
1505 */
1506static void QCBOREncode_OpenMap(QCBOREncodeContext *pCtx);
1507
1508static void QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1509
1510static void QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1511
1512
1513
1514/**
1515 @brief Close an open map.
1516
1517 @param[in] pCtx The encoding context to close the map in .
1518
1519 This closes a map opened by QCBOREncode_OpenMap(). It reduces nesting
1520 level by one.
1521
1522 When an error occurs as a result of this call, the encoder records
1523 the error and enters the error state. The error will be returned when
1524 QCBOREncode_Finish() is called.
1525
1526 If this has been called more times than QCBOREncode_OpenMap(),
1527 then @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1528 QCBOREncode_Finish() is called.
1529
1530 If this is called and it is not a map that is currently open, @ref
1531 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
1532 is called.
1533 */
1534static void QCBOREncode_CloseMap(QCBOREncodeContext *pCtx);
1535
1536
1537/**
1538 @brief Indicate start of encoded CBOR to be wrapped in a bstr.
1539
1540 @param[in] pCtx The encoding context to open the bstr-wrapped CBOR in.
1541
1542 All added encoded items between this call and a call to
1543 QCBOREncode_CloseBstrWrap2() will be wrapped in a bstr. They will
1544 appear in the final output as a byte string. That byte string will
1545 contain encoded CBOR. This increases nesting level by one.
1546
1547 The typical use case is for encoded CBOR that is to be
1548 cryptographically hashed, as part of a [RFC 8152, COSE]
1549 (https://tools.ietf.org/html/rfc8152) implementation.
1550
1551 Using QCBOREncode_BstrWrap() and QCBOREncode_CloseBstrWrap2() avoids
1552 having to encode the items first in one buffer (e.g., the COSE
1553 payload) and then add that buffer as a bstr to another encoding
1554 (e.g. the COSE to-be-signed bytes, the @c Sig_structure) potentially
1555 halving the memory needed.
1556
1557 RFC 7049 states the purpose of this wrapping is to prevent code
1558 relaying the signed data but not verifying it from tampering with the
1559 signed data thus making the signature unverifiable. It is also quite
1560 beneficial for the signature verification code. Standard CBOR
1561 decoders usually do not give access to partially decoded CBOR as
1562 would be needed to check the signature of some CBOR. With this
1563 wrapping, standard CBOR decoders can be used to get to all the data
1564 needed for a signature verification.
1565 */
1566static void QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx);
1567
1568static void QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1569
1570static void QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1571
1572
1573/**
1574 @brief Close a wrapping bstr.
1575
1576 @param[in] pCtx The encoding context to close of bstr wrapping in.
1577 @param[in] bIncludeCBORHead Include the encoded CBOR head of the bstr
1578 as well as the bytes in @c pWrappedCBOR.
1579 @param[out] pWrappedCBOR A @ref UsefulBufC containing wrapped bytes.
1580
1581 The closes a wrapping bstr opened by QCBOREncode_BstrWrap(). It reduces
1582 nesting level by one.
1583
1584 A pointer and length of the enclosed encoded CBOR is returned in @c
1585 *pWrappedCBOR if it is not @c NULL. The main purpose of this is so
1586 this data can be hashed (e.g., with SHA-256) as part of a [RFC 8152,
1587 COSE] (https://tools.ietf.org/html/rfc8152)
1588 implementation. **WARNING**, this pointer and length should be used
1589 right away before any other calls to @c QCBOREncode_CloseXxx() as
1590 they will move data around and the pointer and length will no longer
1591 be to the correct encoded CBOR.
1592
1593 When an error occurs as a result of this call, the encoder records
1594 the error and enters the error state. The error will be returned when
1595 QCBOREncode_Finish() is called.
1596
1597 If this has been called more times than QCBOREncode_BstrWrap(), then
1598 @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1599 QCBOREncode_Finish() is called.
1600
1601 If this is called and it is not a wrapping bstr that is currently
1602 open, @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
1603 QCBOREncode_Finish() is called.
1604
1605 QCBOREncode_CloseBstrWrap() is a deprecated version of this function
1606 that is equivalent to the call with @c bIncludeCBORHead @c true.
1607 */
1608void QCBOREncode_CloseBstrWrap2(QCBOREncodeContext *pCtx, bool bIncludeCBORHead, UsefulBufC *pWrappedCBOR);
1609
1610static void QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR);
1611
1612
1613/**
1614 @brief Add some already-encoded CBOR bytes.
1615
1616 @param[in] pCtx The encoding context to add the already-encode CBOR to.
1617 @param[in] Encoded The already-encoded CBOR to add to the context.
1618
1619 The encoded CBOR being added must be fully conforming CBOR. It must
1620 be complete with no arrays or maps that are incomplete. While this
1621 encoder doesn't ever produce indefinite lengths, it is OK for the
1622 raw CBOR added here to have indefinite lengths.
1623
1624 The raw CBOR added here is not checked in anyway. If it is not
1625 conforming or has open arrays or such, the final encoded CBOR
1626 will probably be wrong or not what was intended.
1627
1628 If the encoded CBOR being added here contains multiple items, they
1629 must be enclosed in a map or array. At the top level the raw
1630 CBOR must be a single data item.
1631 */
1632static void QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded);
1633
1634static void QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded);
1635
1636static void QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded);
1637
1638
1639/**
1640 @brief Get the encoded result.
1641
1642 @param[in] pCtx The context to finish encoding with.
1643 @param[out] pEncodedCBOR Pointer and length of encoded CBOR.
1644
1645 @retval QCBOR_ERR_TOO_MANY_CLOSES Nesting error
1646
1647 @retval QCBOR_ERR_CLOSE_MISMATCH Nesting error
1648
1649 @retval QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN Nesting error
1650
1651 @retval QCBOR_ERR_BUFFER_TOO_LARGE Encoded output buffer size
1652
1653 @retval QCBOR_ERR_BUFFER_TOO_SMALL Encoded output buffer size
1654
1655 @retval QCBOR_ERR_ARRAY_NESTING_TOO_DEEP Implementation limit
1656
1657 @retval QCBOR_ERR_ARRAY_TOO_LONG Implementation limit
1658
1659 If this returns success @ref QCBOR_SUCCESS the encoding was a success
1660 and the return length is correct and complete.
1661
1662 If no buffer was passed to QCBOREncode_Init(), then only the length
1663 was computed. If a buffer was passed, then the encoded CBOR is in the
1664 buffer.
1665
1666 Encoding errors primarily manifest here as most other encoding function
1667 do no return an error. They just set the error state in the encode
1668 context after which no encoding function does anything.
1669
1670 Three types of errors manifest here. The first type are nesting
1671 errors where the number of @c QCBOREncode_OpenXxx() calls do not
1672 match the number @c QCBOREncode_CloseXxx() calls. The solution is to
1673 fix the calling code.
1674
1675 The second type of error is because the buffer given is either too
1676 small or too large. The remedy is to give a correctly sized buffer.
1677
1678 The third type are due to limits in this implementation. @ref
1679 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP can be worked around by encoding the
1680 CBOR in two (or more) phases and adding the CBOR from the first phase
1681 to the second with @c QCBOREncode_AddEncoded().
1682
1683 If an error is returned, the buffer may have partially encoded
1684 incorrect CBOR in it and it should not be used. Likewise, the length
1685 may be incorrect and should not be used.
1686
1687 Note that the error could have occurred in one of the many @c
1688 QCBOREncode_AddXxx() calls long before QCBOREncode_Finish() was
1689 called. This error handling reduces the CBOR implementation size but
1690 makes debugging harder.
1691
1692 This may be called multiple times. It will always return the same. It
1693 can also be interleaved with calls to QCBOREncode_FinishGetSize().
1694
1695 QCBOREncode_GetErrorState() can be called to get the current
1696 error state and abort encoding early as an optimization, but is
1697 is never required.
1698 */
1699QCBORError QCBOREncode_Finish(QCBOREncodeContext *pCtx, UsefulBufC *pEncodedCBOR);
1700
1701
1702/**
1703 @brief Get the encoded CBOR and error status.
1704
1705 @param[in] pCtx The context to finish encoding with.
1706 @param[out] uEncodedLen The length of the encoded or potentially
1707 encoded CBOR in bytes.
1708
1709 @return The same errors as QCBOREncode_Finish().
1710
1711 This functions the same as QCBOREncode_Finish(), but only returns the
1712 size of the encoded output.
1713 */
1714QCBORError QCBOREncode_FinishGetSize(QCBOREncodeContext *pCtx, size_t *uEncodedLen);
1715
1716
1717/**
1718 @brief Indicate whether output buffer is NULL or not.
1719
1720 @param[in] pCtx The encoding context.
1721
1722 @return 1 if the output buffer is @c NULL.
1723
1724 Sometimes a @c NULL input buffer is given to QCBOREncode_Init() so
1725 that the size of the generated CBOR can be calculated without
1726 allocating a buffer for it. This returns 1 when the output buffer is
1727 NULL and 0 when it is not.
1728*/
1729static int QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx);
1730
1731 /**
1732 @brief Get the encoding error state.
1733
1734 @param[in] pCtx The encoding context.
1735
Laurence Lundbladeabf5c572020-06-29 21:21:29 -07001736 @return One of @ref QCBORError. See return values from
Michael Eckel5c531332020-03-02 01:35:30 +01001737 QCBOREncode_Finish()
1738
1739 Normally encoding errors need only be handled at the end of encoding
1740 when QCBOREncode_Finish() is called. This can be called to get the
1741 error result before finish should there be a need to halt encoding
1742 before QCBOREncode_Finish() is called.
1743*/
1744static QCBORError QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx);
1745
1746
1747/**
1748 Encode the "head" of a CBOR data item.
1749
1750 @param buffer Buffer to output the encoded head to; must be
1751 @ref QCBOR_HEAD_BUFFER_SIZE bytes in size.
1752 @param uMajorType One of CBOR_MAJOR_TYPE_XX.
1753 @param uMinLen The minimum number of bytes to encode uNumber. Almost always
1754 this is 0 to use preferred minimal encoding. If this is 4,
1755 then even the values 0xffff and smaller will be encoded
1756 as in 4 bytes. This is used primarily when encoding a
1757 float or double put into uNumber as the leading zero bytes
1758 for them must be encoded.
1759 @param uNumber The numeric argument part of the CBOR head.
1760 @return Pointer and length of the encoded head or
1761 @NULLUsefulBufC if the output buffer is too small.
1762
1763 Callers to need to call this for normal CBOR encoding. Note that it doesn't even
1764 take a @ref QCBOREncodeContext argument.
1765
1766 This encodes the major type and argument part of a data item. The
1767 argument is an integer that is usually either the value or the length
1768 of the data item.
1769
1770 This is exposed in the public interface to allow hashing of some CBOR
1771 data types, bstr in particular, a chunk at a time so the full CBOR
1772 doesn't have to be encoded in a contiguous buffer.
1773
1774 For example, if you have a 100,000 byte binary blob in a buffer that
1775 needs to be a bstr encoded and then hashed. You could allocate a
1776 100,010 byte buffer and encode it normally. Alternatively, you can
1777 encode the head in a 10 byte buffer with this function, hash that and
1778 then hash the 100,000 bytes using the same hash context.
1779
1780 See also QCBOREncode_AddBytesLenOnly();
1781 */
1782UsefulBufC QCBOREncode_EncodeHead(UsefulBuf buffer,
1783 uint8_t uMajorType,
1784 uint8_t uMinLen,
1785 uint64_t uNumber);
1786
1787
Michael Eckel5c531332020-03-02 01:35:30 +01001788
1789
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001790/* =========================================================================
1791 BEGINNING OF PRIVATE INLINE IMPLEMENTATION
1792 ========================================================================= */
Michael Eckel5c531332020-03-02 01:35:30 +01001793
1794/**
1795 @brief Semi-private method to add a buffer full of bytes to encoded output
1796
1797 @param[in] pCtx The encoding context to add the integer to.
1798 @param[in] uMajorType The CBOR major type of the bytes.
1799 @param[in] Bytes The bytes to add.
1800
1801 Use QCBOREncode_AddText() or QCBOREncode_AddBytes() or
1802 QCBOREncode_AddEncoded() instead. They are inline functions that call
1803 this and supply the correct major type. This function is public to
1804 make the inline functions work to keep the overall code size down and
1805 because the C language has no way to make it private.
1806
1807 If this is called the major type should be @c
1808 CBOR_MAJOR_TYPE_TEXT_STRING, @c CBOR_MAJOR_TYPE_BYTE_STRING or @c
1809 CBOR_MAJOR_NONE_TYPE_RAW. The last one is special for adding
1810 already-encoded CBOR.
1811 */
1812void QCBOREncode_AddBuffer(QCBOREncodeContext *pCtx, uint8_t uMajorType, UsefulBufC Bytes);
1813
1814
1815/**
1816 @brief Semi-private method to open a map, array or bstr-wrapped CBOR
1817
1818 @param[in] pCtx The context to add to.
1819 @param[in] uMajorType The major CBOR type to close
1820
1821 Call QCBOREncode_OpenArray(), QCBOREncode_OpenMap() or
1822 QCBOREncode_BstrWrap() instead of this.
1823 */
1824void QCBOREncode_OpenMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType);
1825
1826
1827/**
1828 @brief Semi-private method to open a map, array with indefinite length
1829
1830 @param[in] pCtx The context to add to.
1831 @param[in] uMajorType The major CBOR type to close
1832
1833 Call QCBOREncode_OpenArrayIndefiniteLength() or
1834 QCBOREncode_OpenMapIndefiniteLength() instead of this.
1835 */
1836void QCBOREncode_OpenMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx, uint8_t uMajorType);
1837
1838
1839/**
1840 @brief Semi-private method to close a map, array or bstr wrapped CBOR
1841
1842 @param[in] pCtx The context to add to.
1843 @param[in] uMajorType The major CBOR type to close.
1844
1845 Call QCBOREncode_CloseArray() or QCBOREncode_CloseMap() instead of this.
1846 */
1847void QCBOREncode_CloseMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType);
1848
1849
1850/**
1851 @brief Semi-private method to close a map, array with indefinite length
1852
1853 @param[in] pCtx The context to add to.
1854 @param[in] uMajorType The major CBOR type to close.
1855
1856 Call QCBOREncode_CloseArrayIndefiniteLength() or
1857 QCBOREncode_CloseMapIndefiniteLength() instead of this.
1858 */
1859void QCBOREncode_CloseMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx,
1860 uint8_t uMajorType);
1861
1862
1863/**
1864 @brief Semi-private method to add simple types.
1865
1866 @param[in] pCtx The encoding context to add the simple value to.
1867 @param[in] uMinLen Minimum encoding size for uNum. Usually 0.
1868 @param[in] uNum One of CBOR_SIMPLEV_FALSE through _UNDEF or other.
1869
1870 This is used to add simple types like true and false.
1871
1872 Call QCBOREncode_AddBool(), QCBOREncode_AddNULL(),
1873 QCBOREncode_AddUndef() instead of this.
1874
1875 This function can add simple values that are not defined by CBOR
1876 yet. This expansion point in CBOR should not be used unless they are
1877 standardized.
1878
1879 Error handling is the same as QCBOREncode_AddInt64().
1880 */
1881void QCBOREncode_AddType7(QCBOREncodeContext *pCtx, uint8_t uMinLen, uint64_t uNum);
1882
1883
1884/**
1885 @brief Semi-private method to add bigfloats and decimal fractions.
1886
1887 @param[in] pCtx The encoding context to add the value to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001888 @param[in] uTag The type 6 tag indicating what this is to be.
Michael Eckel5c531332020-03-02 01:35:30 +01001889 @param[in] BigNumMantissa Is @ref NULLUsefulBufC if mantissa is an
1890 @c int64_t or the actual big number mantissa
1891 if not.
1892 @param[in] nMantissa The @c int64_t mantissa if it is not a big number.
1893 @param[in] nExponent The exponent.
1894
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001895 This outputs either the @ref CBOR_TAG_DECIMAL_FRACTION or @ref
1896 CBOR_TAG_BIGFLOAT tag. if @c uTag is @ref CBOR_TAG_INVALID64, then
1897 this outputs the "borrowed" content format.
Michael Eckel5c531332020-03-02 01:35:30 +01001898
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001899 The tag content output by this is an array with two members, the
1900 exponent and then the mantissa. The mantissa can be either a big
1901 number or an @c int64_t.
1902
1903 This implementation cannot output an exponent further from 0 than
1904 INT64_MAX.
1905
1906 To output a mantissa that is bewteen INT64_MAX and UINT64_MAX from 0,
1907 it must be as a big number.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001908
Michael Eckel5c531332020-03-02 01:35:30 +01001909 Typically, QCBOREncode_AddDecimalFraction(), QCBOREncode_AddBigFloat(),
1910 QCBOREncode_AddDecimalFractionBigNum() or QCBOREncode_AddBigFloatBigNum()
1911 is called instead of this.
1912 */
1913void QCBOREncode_AddExponentAndMantissa(QCBOREncodeContext *pCtx,
1914 uint64_t uTag,
1915 UsefulBufC BigNumMantissa,
1916 bool bBigNumIsNegative,
1917 int64_t nMantissa,
1918 int64_t nExponent);
1919
1920/**
1921 @brief Semi-private method to add only the type and length of a byte string.
1922
1923 @param[in] pCtx The context to initialize.
1924 @param[in] Bytes Pointer and length of the input data.
1925
1926 This is the same as QCBOREncode_AddBytes() except it only adds the
1927 CBOR encoding for the type and the length. It doesn't actually add
1928 the bytes. You can't actually produce correct CBOR with this and the
1929 rest of this API. It is only used for a special case where
1930 the valid CBOR is created manually by putting this type and length in
1931 and then adding the actual bytes. In particular, when only a hash of
1932 the encoded CBOR is needed, where the type and header are hashed
1933 separately and then the bytes is hashed. This makes it possible to
1934 implement COSE Sign1 with only one copy of the payload in the output
1935 buffer, rather than two, roughly cutting memory use in half.
1936
1937 This is only used for this odd case, but this is a supported
1938 tested function.
1939
1940 See also QCBOREncode_EncodeHead().
1941*/
1942static inline void QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
1943
1944static inline void QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
1945
1946static inline void QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
1947
1948
1949
1950
1951
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001952static inline void
1953QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01001954{
1955 // Use _AddBuffer() because _AddSZString() is defined below, not above
1956 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
1957 QCBOREncode_AddInt64(pCtx, uNum);
1958}
1959
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001960static inline void
1961QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01001962{
1963 QCBOREncode_AddInt64(pCtx, nLabel);
1964 QCBOREncode_AddInt64(pCtx, uNum);
1965}
1966
1967
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001968static inline void
1969QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01001970{
1971 // Use _AddBuffer() because _AddSZString() is defined below, not above
1972 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
1973 QCBOREncode_AddUInt64(pCtx, uNum);
1974}
1975
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001976static inline void
1977QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01001978{
1979 QCBOREncode_AddInt64(pCtx, nLabel);
1980 QCBOREncode_AddUInt64(pCtx, uNum);
1981}
1982
1983
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001984static inline void
1985QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01001986{
1987 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, Text);
1988}
1989
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001990static inline void
1991QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01001992{
1993 // Use _AddBuffer() because _AddSZString() is defined below, not above
1994 QCBOREncode_AddText(pCtx, UsefulBuf_FromSZ(szLabel));
1995 QCBOREncode_AddText(pCtx, Text);
1996}
1997
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001998static inline void
1999QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002000{
2001 QCBOREncode_AddInt64(pCtx, nLabel);
2002 QCBOREncode_AddText(pCtx, Text);
2003}
2004
2005
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002006inline static void
2007QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002008{
2009 QCBOREncode_AddText(pCtx, UsefulBuf_FromSZ(szString));
2010}
2011
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002012static inline void
2013QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002014{
2015 QCBOREncode_AddSZString(pCtx, szLabel);
2016 QCBOREncode_AddSZString(pCtx, szString);
2017}
2018
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002019static inline void
2020QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002021{
2022 QCBOREncode_AddInt64(pCtx, nLabel);
2023 QCBOREncode_AddSZString(pCtx, szString);
2024}
2025
2026
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002027static inline void
2028QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002029{
2030 QCBOREncode_AddSZString(pCtx, szLabel);
2031 QCBOREncode_AddDouble(pCtx, dNum);
2032}
2033
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002034static inline void
2035QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002036{
2037 QCBOREncode_AddInt64(pCtx, nLabel);
2038 QCBOREncode_AddDouble(pCtx, dNum);
2039}
2040
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002041static inline void
2042QCBOREncode_AddFloatToMap(QCBOREncodeContext *pCtx, const char *szLabel, float dNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002043{
2044 QCBOREncode_AddSZString(pCtx, szLabel);
2045 QCBOREncode_AddFloat(pCtx, dNum);
2046}
2047
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002048static inline void
2049QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float fNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002050{
2051 QCBOREncode_AddInt64(pCtx, nLabel);
2052 QCBOREncode_AddFloat(pCtx, fNum);
2053}
2054
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002055static inline void
2056QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002057{
2058 QCBOREncode_AddSZString(pCtx, szLabel);
2059 QCBOREncode_AddDoubleNoPreferred(pCtx, dNum);
2060}
2061
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002062static inline void
2063QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002064{
2065 QCBOREncode_AddInt64(pCtx, nLabel);
2066 QCBOREncode_AddDoubleNoPreferred(pCtx, dNum);
2067}
2068
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002069static inline void
2070QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002071{
2072 QCBOREncode_AddSZString(pCtx, szLabel);
2073 QCBOREncode_AddFloatNoPreferred(pCtx, dNum);
2074}
2075
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002076static inline void
2077QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002078{
2079 QCBOREncode_AddInt64(pCtx, nLabel);
2080 QCBOREncode_AddFloatNoPreferred(pCtx, dNum);
2081}
2082
Michael Eckel5c531332020-03-02 01:35:30 +01002083
Laurence Lundblade9b334962020-08-27 10:55:53 -07002084
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002085static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002086QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pMe, uint8_t uTag, int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002087{
2088 if(uTag == QCBOR_ENCODE_AS_TAG) {
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002089 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_EPOCH);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002090 }
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002091 QCBOREncode_AddInt64(pMe, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002092}
2093
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002094static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002095QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTag, int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002096{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002097 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002098 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002099}
2100
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002101static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002102QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTag, int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002103{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002104 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002105 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002106}
2107
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002108static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002109QCBOREncode_AddDateEpoch(QCBOREncodeContext *pMe, int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002110{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002111 QCBOREncode_AddTDateEpoch(pMe, QCBOR_ENCODE_AS_TAG, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002112}
2113
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002114static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002115QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pMe, const char *szLabel, int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002116{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002117 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002118 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002119}
2120
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002121static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002122QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pMe, int64_t nLabel, int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002123{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002124 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002125 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002126}
2127
2128
Laurence Lundblade9b334962020-08-27 10:55:53 -07002129
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002130static inline void
2131QCBOREncode_AddBytes(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002132{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002133 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002134}
2135
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002136static inline void
2137QCBOREncode_AddBytesToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002138{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002139 QCBOREncode_AddSZString(pMe, szLabel);
2140 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002141}
2142
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002143static inline void
2144QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002145{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002146 QCBOREncode_AddInt64(pMe, nLabel);
2147 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002148}
2149
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002150static inline void
2151QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002152{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002153 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002154}
2155
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002156static inline void
2157QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002158{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002159 QCBOREncode_AddSZString(pMe, szLabel);
2160 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002161}
2162
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002163static inline void
2164QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002165{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002166 QCBOREncode_AddInt64(pMe, nLabel);
2167 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002168}
2169
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002170
2171static inline void
2172QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002173{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002174 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2175 QCBOREncode_AddTag(pMe, CBOR_TAG_BIN_UUID);
2176 }
2177 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002178}
2179
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002180static inline void
2181QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pMe,
2182 const char *szLabel,
2183 uint8_t uTagRequirement,
2184 UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002185{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002186 QCBOREncode_AddSZString(pMe, szLabel);
2187 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002188}
2189
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002190static inline void
2191QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002192{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002193 QCBOREncode_AddInt64(pMe, nLabel);
2194 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002195}
2196
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002197static inline void
2198QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002199{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002200 QCBOREncode_AddTBinaryUUID(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002201}
2202
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002203static inline void
2204QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002205{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002206 QCBOREncode_AddTBinaryUUIDToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002207}
2208
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002209static inline void
2210QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002211{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002212 QCBOREncode_AddTBinaryUUIDToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002213}
2214
2215
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002216static inline void
2217QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002218{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002219 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2220 QCBOREncode_AddTag(pMe, CBOR_TAG_POS_BIGNUM);
2221 }
2222 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002223}
2224
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002225static inline void
2226QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pMe,
2227 const char *szLabel,
2228 uint8_t uTagRequirement,
2229 UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002230{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002231 QCBOREncode_AddSZString(pMe, szLabel);
2232 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002233}
2234
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002235static inline void
2236QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002237{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002238 QCBOREncode_AddInt64(pMe, nLabel);
2239 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002240}
2241
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002242static inline void
2243QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2244{
2245 QCBOREncode_AddTPositiveBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2246}
2247
2248static inline void
2249QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2250{
2251 QCBOREncode_AddTPositiveBignumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2252}
2253
2254static inline void
2255QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2256{
2257 QCBOREncode_AddTPositiveBignumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2258}
2259
2260
2261static inline void
2262QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
2263{
2264 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2265 QCBOREncode_AddTag(pMe, CBOR_TAG_NEG_BIGNUM);
2266 }
2267 QCBOREncode_AddBytes(pMe, Bytes);
2268}
2269
2270static inline void
2271QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pMe,
2272 const char *szLabel,
2273 uint8_t uTagRequirement,
2274 UsefulBufC Bytes)
2275{
2276 QCBOREncode_AddSZString(pMe, szLabel);
2277 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2278}
2279
2280static inline void
2281QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
2282{
2283 QCBOREncode_AddInt64(pMe, nLabel);
2284 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2285}
2286
2287static inline void
2288QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2289{
2290 QCBOREncode_AddTNegativeBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2291}
2292
2293static inline void
2294QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2295{
2296 QCBOREncode_AddTNegativeBignumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2297}
2298
2299static inline void
2300QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2301{
2302 QCBOREncode_AddTNegativeBignumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2303}
2304
2305
Michael Eckel5c531332020-03-02 01:35:30 +01002306
2307#ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
2308
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002309static inline void
2310QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pMe,
2311 uint8_t uTagRequirement,
2312 int64_t nMantissa,
2313 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002314{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002315 uint64_t uTag;
2316 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2317 uTag = CBOR_TAG_DECIMAL_FRACTION;
2318 } else {
2319 uTag = CBOR_TAG_INVALID64;
2320 }
2321 QCBOREncode_AddExponentAndMantissa(pMe,
2322 uTag,
Michael Eckel5c531332020-03-02 01:35:30 +01002323 NULLUsefulBufC,
2324 false,
2325 nMantissa,
2326 nBase10Exponent);
2327}
2328
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002329static inline void
2330QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pMe,
2331 const char *szLabel,
2332 uint8_t uTagRequirement,
2333 int64_t nMantissa,
2334 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002335{
2336 QCBOREncode_AddSZString(pMe, szLabel);
2337 QCBOREncode_AddTDecimalFraction(pMe, uTagRequirement, nMantissa, nBase10Exponent);
2338}
2339
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002340static inline void
2341QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pMe,
2342 int64_t nLabel,
2343 uint8_t uTagRequirement,
2344 int64_t nMantissa,
2345 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002346{
2347 QCBOREncode_AddInt64(pMe, nLabel);
2348 QCBOREncode_AddTDecimalFraction(pMe, uTagRequirement, nMantissa, nBase10Exponent);
2349}
2350
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002351static inline void
2352QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pMe,
2353 int64_t nMantissa,
2354 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002355{
2356 QCBOREncode_AddTDecimalFraction(pMe, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
2357}
2358
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002359static inline void
2360QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pMe,
2361 const char *szLabel,
2362 int64_t nMantissa,
2363 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002364{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002365 QCBOREncode_AddTDecimalFractionToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002366}
2367
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002368static inline void
2369QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pMe,
2370 int64_t nLabel,
2371 int64_t nMantissa,
2372 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002373{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002374 QCBOREncode_AddTDecimalFractionToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002375}
2376
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002377
2378
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002379static inline void
2380QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pMe,
2381 uint8_t uTagRequirement,
2382 UsefulBufC Mantissa,
2383 bool bIsNegative,
2384 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002385{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002386 uint64_t uTag;
2387 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2388 uTag = CBOR_TAG_DECIMAL_FRACTION;
2389 } else {
2390 uTag = CBOR_TAG_INVALID64;
2391 }
2392 QCBOREncode_AddExponentAndMantissa(pMe,
2393 uTag,
Michael Eckel5c531332020-03-02 01:35:30 +01002394 Mantissa, bIsNegative,
2395 0,
2396 nBase10Exponent);
2397}
2398
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002399static inline void
2400QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
2401 const char *szLabel,
2402 uint8_t uTagRequirement,
2403 UsefulBufC Mantissa,
2404 bool bIsNegative,
2405 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002406{
2407 QCBOREncode_AddSZString(pMe, szLabel);
2408 QCBOREncode_AddTDecimalFractionBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase10Exponent);
2409}
2410
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002411static inline void
2412QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
2413 int64_t nLabel,
2414 uint8_t uTagRequirement,
2415 UsefulBufC Mantissa,
2416 bool bIsNegative,
2417 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002418{
2419 QCBOREncode_AddInt64(pMe, nLabel);
2420 QCBOREncode_AddTDecimalFractionBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase10Exponent);
2421}
2422
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002423static inline void
2424QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pMe,
2425 UsefulBufC Mantissa,
2426 bool bIsNegative,
2427 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002428{
2429 QCBOREncode_AddTDecimalFractionBigNum(pMe, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase10Exponent);
2430}
2431
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002432static inline void
2433QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
2434 const char *szLabel,
2435 UsefulBufC Mantissa,
2436 bool bIsNegative,
2437 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002438{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002439 QCBOREncode_AddTDecimalFractionBigNumToMapSZ(pMe,
2440 szLabel,
2441 QCBOR_ENCODE_AS_TAG,
2442 Mantissa,
2443 bIsNegative,
2444 nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002445}
2446
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002447static inline void
2448QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
2449 int64_t nLabel,
2450 UsefulBufC Mantissa,
2451 bool bIsNegative,
2452 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002453{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002454 QCBOREncode_AddTDecimalFractionBigNumToMapN(pMe,
2455 nLabel,
2456 QCBOR_ENCODE_AS_TAG,
2457 Mantissa,
2458 bIsNegative,
2459 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002460}
2461
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002462
2463
2464
2465
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002466static inline void
2467QCBOREncode_AddTBigFloat(QCBOREncodeContext *pMe,
2468 uint8_t uTagRequirement,
2469 int64_t nMantissa,
2470 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002471{
2472 uint64_t uTag;
2473 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2474 uTag = CBOR_TAG_BIGFLOAT;
2475 } else {
2476 uTag = CBOR_TAG_INVALID64;
2477 }
2478 QCBOREncode_AddExponentAndMantissa(pMe, uTag, NULLUsefulBufC, false, nMantissa, nBase2Exponent);
2479}
2480
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002481static inline void
2482QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pMe,
2483 const char *szLabel,
2484 uint8_t uTagRequirement,
2485 int64_t nMantissa,
2486 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002487{
2488 QCBOREncode_AddSZString(pMe, szLabel);
2489 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
2490}
2491
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002492static inline void
2493QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pMe,
2494 int64_t nLabel,
2495 uint8_t uTagRequirement,
2496 int64_t nMantissa,
2497 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002498{
2499 QCBOREncode_AddInt64(pMe, nLabel);
2500 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
2501}
2502
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002503static inline void
2504QCBOREncode_AddBigFloat(QCBOREncodeContext *pMe,
2505 int64_t nMantissa,
2506 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002507{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002508 QCBOREncode_AddTBigFloat(pMe, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002509}
2510
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002511static inline void
2512QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pMe,
2513 const char *szLabel,
2514 int64_t nMantissa,
2515 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002516{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002517 QCBOREncode_AddTBigFloatToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002518}
2519
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002520static inline void
2521QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pMe,
2522 int64_t nLabel,
2523 int64_t nMantissa,
2524 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002525{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002526 QCBOREncode_AddTBigFloatToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002527}
2528
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002529
2530
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002531static inline void
2532QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pMe,
2533 uint8_t uTagRequirement,
2534 UsefulBufC Mantissa,
2535 bool bIsNegative,
2536 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002537{
2538 uint64_t uTag;
2539 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2540 uTag = CBOR_TAG_BIGFLOAT;
2541 } else {
2542 uTag = CBOR_TAG_INVALID64;
2543 }
2544 QCBOREncode_AddExponentAndMantissa(pMe, uTag, Mantissa, bIsNegative, 0, nBase2Exponent);
2545}
2546
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002547static inline void
2548QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pMe,
2549 const char *szLabel,
2550 uint8_t uTagRequirement,
2551 UsefulBufC Mantissa,
2552 bool bIsNegative,
2553 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002554{
2555 QCBOREncode_AddSZString(pMe, szLabel);
2556 QCBOREncode_AddTBigFloatBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase2Exponent);
2557}
2558
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002559static inline void
2560QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
2561 int64_t nLabel,
2562 uint8_t uTagRequirement,
2563 UsefulBufC Mantissa,
2564 bool bIsNegative,
2565 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002566{
2567 QCBOREncode_AddInt64(pMe, nLabel);
2568 QCBOREncode_AddTBigFloatBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase2Exponent);
2569}
2570
2571
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002572static inline void
2573QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pMe,
2574 UsefulBufC Mantissa,
2575 bool bIsNegative,
2576 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002577{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002578 QCBOREncode_AddTBigFloatBigNum(pMe, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002579}
2580
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002581static inline void
2582QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pMe,
2583 const char *szLabel,
2584 UsefulBufC Mantissa,
2585 bool bIsNegative,
2586 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002587{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002588 QCBOREncode_AddTBigFloatBigNumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002589}
2590
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002591static inline void
2592QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
2593 int64_t nLabel,
2594 UsefulBufC Mantissa,
2595 bool bIsNegative,
2596 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002597{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002598 QCBOREncode_AddTBigFloatBigNumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002599}
2600#endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
2601
2602
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002603static inline void
2604QCBOREncode_AddTURI(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002605{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002606 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2607 QCBOREncode_AddTag(pMe, CBOR_TAG_URI);
2608 }
2609 QCBOREncode_AddText(pMe, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002610}
2611
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002612static inline void
2613QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002614{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002615 QCBOREncode_AddSZString(pMe, szLabel);
2616 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002617}
2618
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002619static inline void
2620QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002621{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002622 QCBOREncode_AddInt64(pMe, nLabel);
2623 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
2624}
2625
2626static inline void
2627QCBOREncode_AddURI(QCBOREncodeContext *pMe, UsefulBufC URI)
2628{
2629 QCBOREncode_AddTURI(pMe, QCBOR_ENCODE_AS_TAG, URI);
2630}
2631
2632static inline void
2633QCBOREncode_AddURIToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC URI)
2634{
2635 QCBOREncode_AddTURIToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, URI);
2636}
2637
2638static inline void
2639QCBOREncode_AddURIToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC URI)
2640{
2641 QCBOREncode_AddTURIToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002642}
2643
2644
2645
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002646static inline void
2647QCBOREncode_AddTB64Text(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002648{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002649 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2650 QCBOREncode_AddTag(pMe, CBOR_TAG_B64);
2651 }
2652 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002653}
2654
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002655static inline void
2656QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pMe,
2657 const char *szLabel,
2658 uint8_t uTagRequirement,
2659 UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002660{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002661 QCBOREncode_AddSZString(pMe, szLabel);
2662 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002663}
2664
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002665static inline void
2666QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002667{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002668 QCBOREncode_AddInt64(pMe, nLabel);
2669 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
2670}
2671
2672static inline void
2673QCBOREncode_AddB64Text(QCBOREncodeContext *pMe, UsefulBufC B64Text)
2674{
2675 QCBOREncode_AddTB64Text(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
2676}
2677
2678static inline void
2679QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC B64Text)
2680{
2681 QCBOREncode_AddTB64TextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
2682}
2683
2684static inline void
2685QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC B64Text)
2686{
2687 QCBOREncode_AddTB64TextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002688}
2689
2690
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002691
2692static inline void
2693QCBOREncode_AddTB64URLText(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002694{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002695 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2696 QCBOREncode_AddTag(pMe, CBOR_TAG_B64URL);
2697 }
2698 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002699}
2700
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002701static inline void
2702QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pMe,
2703 const char *szLabel,
2704 uint8_t uTagRequirement,
2705 UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002706{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002707 QCBOREncode_AddSZString(pMe, szLabel);
2708 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002709}
2710
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002711static inline void
2712QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002713{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002714 QCBOREncode_AddInt64(pMe, nLabel);
2715 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
2716}
2717
2718static inline void
2719QCBOREncode_AddB64URLText(QCBOREncodeContext *pMe, UsefulBufC B64Text)
2720{
2721 QCBOREncode_AddTB64URLText(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
2722}
2723
2724static inline void
2725QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC B64Text)
2726{
2727 QCBOREncode_AddTB64URLTextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
2728}
2729
2730static inline void
2731QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC B64Text)
2732{
2733 QCBOREncode_AddTB64URLTextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002734}
2735
2736
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002737
2738static inline void
2739QCBOREncode_AddTRegex(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002740{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002741 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2742 QCBOREncode_AddTag(pMe, CBOR_TAG_REGEX);
2743 }
2744 QCBOREncode_AddText(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002745}
2746
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002747static inline void
2748QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002749{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002750 QCBOREncode_AddSZString(pMe, szLabel);
2751 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002752}
2753
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002754static inline void
2755QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002756{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002757 QCBOREncode_AddInt64(pMe, nLabel);
2758 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
2759}
2760
2761static inline void
2762QCBOREncode_AddRegex(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2763{
2764 QCBOREncode_AddTRegex(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2765}
2766
2767static inline void
2768QCBOREncode_AddRegexToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2769{
2770 QCBOREncode_AddTRegexToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2771}
2772
2773static inline void
2774QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2775{
2776 QCBOREncode_AddTRegexToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2777
Michael Eckel5c531332020-03-02 01:35:30 +01002778}
2779
2780
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002781static inline void
2782QCBOREncode_AddTMIMEData(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01002783{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002784 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
Laurence Lundblade4982f412020-09-18 23:02:18 -07002785 QCBOREncode_AddTag(pMe, CBOR_TAG_BINARY_MIME);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002786 }
Laurence Lundblade4982f412020-09-18 23:02:18 -07002787 QCBOREncode_AddBytes(pMe, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01002788}
2789
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002790static inline void
2791QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pMe,
2792 const char *szLabel,
2793 uint8_t uTagRequirement,
2794 UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01002795{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002796 QCBOREncode_AddSZString(pMe, szLabel);
2797 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01002798}
2799
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002800static inline void
2801QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01002802{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002803 QCBOREncode_AddInt64(pMe, nLabel);
2804 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
2805}
2806
2807static inline void
2808QCBOREncode_AddMIMEData(QCBOREncodeContext *pMe, UsefulBufC MIMEData)
2809{
2810 QCBOREncode_AddTMIMEData(pMe, QCBOR_ENCODE_AS_TAG, MIMEData);
2811}
2812
2813static inline void
2814QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC MIMEData)
2815{
2816 QCBOREncode_AddTMIMEDataToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
2817}
2818
2819static inline void
2820QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC MIMEData)
2821{
2822 QCBOREncode_AddTMIMEDataToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01002823}
2824
2825
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002826static inline void
2827QCBOREncode_AddTDateString(QCBOREncodeContext *pMe, uint8_t uTagRequirement, const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002828{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002829 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2830 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_STRING);
2831 }
2832 QCBOREncode_AddSZString(pMe, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002833}
2834
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002835static inline void
2836QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pMe,
2837 const char *szLabel,
2838 uint8_t uTagRequirement,
2839 const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002840{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002841 QCBOREncode_AddSZString(pMe, szLabel);
2842 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002843}
2844
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002845static inline void
2846QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002847{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002848 QCBOREncode_AddInt64(pMe, nLabel);
2849 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
2850}
2851
2852static inline void
2853QCBOREncode_AddDateString(QCBOREncodeContext *pMe, const char *szDate)
2854{
2855 QCBOREncode_AddTDateString(pMe, QCBOR_ENCODE_AS_TAG, szDate);
2856}
2857
2858static inline void
2859QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pMe, const char *szLabel, const char *szDate)
2860{
2861 QCBOREncode_AddTDateStringToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, szDate);
2862}
2863
2864static inline void
2865QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, const char *szDate)
2866{
2867 QCBOREncode_AddTDateStringToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002868}
2869
2870
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002871static inline void
2872QCBOREncode_AddSimple(QCBOREncodeContext *pMe, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002873{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002874 QCBOREncode_AddType7(pMe, 0, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002875}
2876
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002877static inline void
2878QCBOREncode_AddSimpleToMap(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01002879{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002880 QCBOREncode_AddSZString(pMe, szLabel);
2881 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01002882}
2883
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002884static inline void
2885QCBOREncode_AddSimpleToMapN(QCBOREncodeContext *pMe, int nLabel, uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01002886{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002887 QCBOREncode_AddInt64(pMe, nLabel);
2888 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01002889}
2890
2891
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002892static inline void
2893QCBOREncode_AddBool(QCBOREncodeContext *pMe, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01002894{
2895 uint8_t uSimple = CBOR_SIMPLEV_FALSE;
2896 if(b) {
2897 uSimple = CBOR_SIMPLEV_TRUE;
2898 }
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002899 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01002900}
2901
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002902static inline void
2903QCBOREncode_AddBoolToMap(QCBOREncodeContext *pMe, const char *szLabel, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01002904{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002905 QCBOREncode_AddSZString(pMe, szLabel);
2906 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01002907}
2908
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002909static inline void
2910QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pMe, int64_t nLabel, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01002911{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002912 QCBOREncode_AddInt64(pMe, nLabel);
2913 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01002914}
2915
2916
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002917static inline void
2918QCBOREncode_AddNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01002919{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002920 QCBOREncode_AddSimple(pMe, CBOR_SIMPLEV_NULL);
Michael Eckel5c531332020-03-02 01:35:30 +01002921}
2922
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002923static inline void
2924QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002925{
2926 QCBOREncode_AddSZString(pCtx, szLabel);
2927 QCBOREncode_AddNULL(pCtx);
2928}
2929
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002930static inline void
2931QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002932{
2933 QCBOREncode_AddInt64(pCtx, nLabel);
2934 QCBOREncode_AddNULL(pCtx);
2935}
2936
2937
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002938static inline void
2939QCBOREncode_AddUndef(QCBOREncodeContext *pCtx)
Michael Eckel5c531332020-03-02 01:35:30 +01002940{
2941 QCBOREncode_AddSimple(pCtx, CBOR_SIMPLEV_UNDEF);
2942}
2943
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002944static inline void
2945QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002946{
2947 QCBOREncode_AddSZString(pCtx, szLabel);
2948 QCBOREncode_AddUndef(pCtx);
2949}
2950
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002951static inline void
2952QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002953{
2954 QCBOREncode_AddInt64(pCtx, nLabel);
2955 QCBOREncode_AddUndef(pCtx);
2956}
2957
2958
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002959static inline void
2960QCBOREncode_OpenArray(QCBOREncodeContext *pCtx)
Michael Eckel5c531332020-03-02 01:35:30 +01002961{
2962 QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_ARRAY);
2963}
2964
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002965static inline void
2966QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002967{
2968 QCBOREncode_AddSZString(pCtx, szLabel);
2969 QCBOREncode_OpenArray(pCtx);
2970}
2971
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002972static inline void
2973QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002974{
2975 QCBOREncode_AddInt64(pCtx, nLabel);
2976 QCBOREncode_OpenArray(pCtx);
2977}
2978
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002979static inline void
2980QCBOREncode_CloseArray(QCBOREncodeContext *pCtx)
Michael Eckel5c531332020-03-02 01:35:30 +01002981{
2982 QCBOREncode_CloseMapOrArray(pCtx, CBOR_MAJOR_TYPE_ARRAY);
2983}
2984
2985
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002986static inline void
2987QCBOREncode_OpenMap(QCBOREncodeContext *pCtx)
Michael Eckel5c531332020-03-02 01:35:30 +01002988{
2989 QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_MAP);
2990}
2991
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002992static inline void
2993QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002994{
2995 QCBOREncode_AddSZString(pCtx, szLabel);
2996 QCBOREncode_OpenMap(pCtx);
2997}
2998
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002999static inline void
3000QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003001{
3002 QCBOREncode_AddInt64(pCtx, nLabel);
3003 QCBOREncode_OpenMap(pCtx);
3004}
3005
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003006static inline void
3007QCBOREncode_CloseMap(QCBOREncodeContext *pCtx)
Michael Eckel5c531332020-03-02 01:35:30 +01003008{
3009 QCBOREncode_CloseMapOrArray(pCtx, CBOR_MAJOR_TYPE_MAP);
3010}
3011
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003012static inline void
3013QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pCtx)
Michael Eckel5c531332020-03-02 01:35:30 +01003014{
3015 QCBOREncode_OpenMapOrArrayIndefiniteLength(pCtx, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
3016}
3017
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003018static inline void
3019QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pCtx, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003020{
3021 QCBOREncode_AddSZString(pCtx, szLabel);
3022 QCBOREncode_OpenArrayIndefiniteLength(pCtx);
3023}
3024
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003025static inline void
3026QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003027{
3028 QCBOREncode_AddInt64(pCtx, nLabel);
3029 QCBOREncode_OpenArrayIndefiniteLength(pCtx);
3030}
3031
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003032static inline void
3033QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pCtx)
Michael Eckel5c531332020-03-02 01:35:30 +01003034{
3035 QCBOREncode_CloseMapOrArrayIndefiniteLength(pCtx, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
3036}
3037
3038
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003039static inline void
3040QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pCtx)
Michael Eckel5c531332020-03-02 01:35:30 +01003041{
3042 QCBOREncode_OpenMapOrArrayIndefiniteLength(pCtx, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
3043}
3044
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003045static inline void
3046QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pCtx, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003047{
3048 QCBOREncode_AddSZString(pCtx, szLabel);
3049 QCBOREncode_OpenMapIndefiniteLength(pCtx);
3050}
3051
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003052static inline void
3053QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003054{
3055 QCBOREncode_AddInt64(pCtx, nLabel);
3056 QCBOREncode_OpenMapIndefiniteLength(pCtx);
3057}
3058
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003059static inline void
3060QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pCtx)
Michael Eckel5c531332020-03-02 01:35:30 +01003061{
3062 QCBOREncode_CloseMapOrArrayIndefiniteLength(pCtx, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
3063}
3064
3065
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003066static inline void
3067QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx)
Michael Eckel5c531332020-03-02 01:35:30 +01003068{
3069 QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_BYTE_STRING);
3070}
3071
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003072static inline void
3073QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003074{
3075 QCBOREncode_AddSZString(pCtx, szLabel);
3076 QCBOREncode_BstrWrap(pCtx);
3077}
3078
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003079static inline void
3080QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003081{
3082 QCBOREncode_AddInt64(pCtx, nLabel);
3083 QCBOREncode_BstrWrap(pCtx);
3084}
3085
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003086static inline void
3087QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR)
Michael Eckel5c531332020-03-02 01:35:30 +01003088{
3089 QCBOREncode_CloseBstrWrap2(pCtx, true, pWrappedCBOR);
3090}
3091
3092
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003093static inline void
3094QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003095{
3096 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_NONE_TYPE_RAW, Encoded);
3097}
3098
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003099static inline void
3100QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003101{
3102 QCBOREncode_AddSZString(pCtx, szLabel);
3103 QCBOREncode_AddEncoded(pCtx, Encoded);
3104}
3105
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003106static inline void
3107QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003108{
3109 QCBOREncode_AddInt64(pCtx, nLabel);
3110 QCBOREncode_AddEncoded(pCtx, Encoded);
3111}
3112
3113
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003114static inline int
3115QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx)
Michael Eckel5c531332020-03-02 01:35:30 +01003116{
3117 return UsefulOutBuf_IsBufferNULL(&(pCtx->OutBuf));
3118}
3119
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003120static inline QCBORError
3121QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx)
Michael Eckel5c531332020-03-02 01:35:30 +01003122{
3123 if(UsefulOutBuf_GetError(&(pCtx->OutBuf))) {
3124 // Items didn't fit in the buffer.
3125 // This check catches this condition for all the appends and inserts
3126 // so checks aren't needed when the appends and inserts are performed.
3127 // And of course UsefulBuf will never overrun the input buffer given
3128 // to it. No complex analysis of the error handling in this file is
3129 // needed to know that is true. Just read the UsefulBuf code.
3130 pCtx->uError = QCBOR_ERR_BUFFER_TOO_SMALL;
3131 // QCBOR_ERR_BUFFER_TOO_SMALL masks other errors, but that is
3132 // OK. Once the caller fixes this, they'll be unmasked.
3133 }
3134
3135 return (QCBORError)pCtx->uError;
3136}
3137
3138
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003139/* ========================================================================
3140 END OF PRIVATE INLINE IMPLEMENTATION
3141 ======================================================================== */
Michael Eckel5c531332020-03-02 01:35:30 +01003142
3143#ifdef __cplusplus
3144}
3145#endif
3146
Laurence Lundblade844bb5c2020-03-01 17:27:25 -08003147#endif /* qcbor_encode_h */