blob: 8f4f1cf8a75f1489e7f6d5c920fdfd6801e0caa0 [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
Laurence Lundbladeadaf5c22020-09-25 10:37:09 -0700491 Text lines in Internet protocols (on the wire) are delimited by
492 either a CRLF or just an LF. Officially many protocols specify CRLF,
493 but implementations often work with either. CBOR type 3 text can be
494 either line ending, even a mixture of both.
495
496 Operating systems usually have a line end convention. Windows uses
497 CRLF. Linux and MacOS use LF. Some applications on a given OS may
498 work with either and some may not.
499
500 The majority of use cases and CBOR protocols using type 3 text will
501 work with either line ending. However, some use cases or protocols
502 may not work with either in which case translation to and/or from the
503 local line end convention, typically that of the OS, is necessary.
504
505 QCBOR does no line ending translation for type 3 text when encoding
506 and decoding.
507
Michael Eckel5c531332020-03-02 01:35:30 +0100508 Error handling is the same as QCBOREncode_AddInt64().
509 */
510static void QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text);
511
512static void QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text);
513
514static void QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text);
515
516
517/**
518 @brief Add a UTF-8 text string to the encoded output.
519
520 @param[in] pCtx The encoding context to add the text to.
521 @param[in] szString Null-terminated text to add.
522
523 This works the same as QCBOREncode_AddText().
524 */
525static void QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString);
526
527static void QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString);
528
529static void QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString);
530
531
532/**
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700533 @brief Add a double-precision floating-point number to the encoded output.
Michael Eckel5c531332020-03-02 01:35:30 +0100534
535 @param[in] pCtx The encoding context to add the double to.
536 @param[in] dNum The double-precision number to add.
537
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700538 This encodes and outputs a floating-point number. CBOR major type 7
539 is used.
Michael Eckel5c531332020-03-02 01:35:30 +0100540
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700541 This implements preferred serialization, selectively encoding the
542 double-precision floating-point number as either double-precision,
543 single-precision or half-precision. Infinity, NaN and 0 are always
544 encoded as half-precision. If no precision will be lost in the
545 conversion to half-precision, then it will be converted and
546 encoded. If not and no precision will be lost in conversion to
547 single-precision, then it will be converted and encoded. If not, then
548 no conversion is performed, and it encoded as a double-precision.
Michael Eckel5c531332020-03-02 01:35:30 +0100549
550 Half-precision floating-point numbers take up 2 bytes, half that of
551 single-precision, one quarter of double-precision
552
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700553 This automatically reduces the size of encoded CBOR, maybe even by
554 four if most of values are 0, infinity or NaN.
Michael Eckel5c531332020-03-02 01:35:30 +0100555
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700556 When decoded, QCBOR will usually return these values as
557 double-precision.
558
559 It is possible to disable this preferred serialization when compiling
560 QCBOR. In that case, this functions the same as
561 QCBOREncode_AddDoubleNoPreferred().
Michael Eckel5c531332020-03-02 01:35:30 +0100562
563 Error handling is the same as QCBOREncode_AddInt64().
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700564
565 See also QCBOREncode_AddDoubleNoPreferred(), QCBOREncode_AddFloat()
566 and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
Michael Eckel5c531332020-03-02 01:35:30 +0100567 */
568void QCBOREncode_AddDouble(QCBOREncodeContext *pCtx, double dNum);
569
570static void QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
571
572static void QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
573
574
575/**
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700576 @brief Add a single-precision floating-point number to the encoded output.
577
578 @param[in] pCtx The encoding context to add the double to.
579 @param[in] fNum The single-precision number to add.
580
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700581 This is identical to QCBOREncode_AddDouble() except the input is
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700582 single-precision.
583
584 See also QCBOREncode_AddDouble(), QCBOREncode_AddDoubleNoPreferred(),
585 and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
586*/
587void QCBOREncode_AddFloat(QCBOREncodeContext *pCtx, float fNum);
588
589static void QCBOREncode_AddFloatToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
590
591static void QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700592
593
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700594/**
595 @brief Add a double-precision floating-point number without preferred encoding.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700596
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700597 @param[in] pCtx The encoding context to add the double to.
598 @param[in] dNum The double-precision number to add.
599
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700600 This always outputs the number as a 64-bit double-precision.
601 Preferred serialization is not used.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700602
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700603 Error handling is the same as QCBOREncode_AddInt64().
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700604
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700605 See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
606 QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700607*/
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700608void QCBOREncode_AddDoubleNoPreferred(QCBOREncodeContext *pCtx, double dNum);
609
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700610static void QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
611
612static void QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
613
614
615/**
616 @brief Add a single-precision floating-point number without preferred encoding.
617
618 @param[in] pCtx The encoding context to add the double to.
619 @param[in] fNum The single-precision number to add.
620
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700621 This always outputs the number as a 32-bit single-precision.
622 Preferred serialization is not used.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700623
624 Error handling is the same as QCBOREncode_AddInt64().
625
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700626 See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
627 QCBOREncode_AddDoubleNoPreferred() and @ref Floating-Point.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700628*/
629void QCBOREncode_AddFloatNoPreferred(QCBOREncodeContext *pCtx, float fNum);
630
631static void QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
632
633static void QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float fNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700634
635
Michael Eckel5c531332020-03-02 01:35:30 +0100636
637/**
638 @brief Add an optional tag.
639
640 @param[in] pCtx The encoding context to add the tag to.
641 @param[in] uTag The tag to add
642
643 This outputs a CBOR major type 6 item that tags the next data item
644 that is output usually to indicate it is some new data type.
645
646 For many of the common standard tags, a function to encode data using
647 it is provided and this is not needed. For example,
648 QCBOREncode_AddDateEpoch() already exists to output integers
649 representing dates with the right tag.
650
651 The tag is applied to the next data item added to the encoded
652 output. That data item that is to be tagged can be of any major CBOR
653 type. Any number of tags can be added to a data item by calling this
654 multiple times before the data item is added.
655
656 See @ref Tags-Overview for discussion of creating new non-standard
657 tags. See QCBORDecode_GetNext() for discussion of decoding custom
658 tags.
659*/
Laurence Lundblade6416a0f2020-09-19 23:26:34 -0700660void QCBOREncode_AddTag(QCBOREncodeContext *pCtx, uint64_t uTag);
Michael Eckel5c531332020-03-02 01:35:30 +0100661
662
663/**
664 @brief Add an epoch-based date.
665
666 @param[in] pCtx The encoding context to add the date to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700667 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700668 @param[in] nDate Number of seconds since 1970-01-01T00:00Z in UTC time.
Michael Eckel5c531332020-03-02 01:35:30 +0100669
670 As per RFC 7049 this is similar to UNIX/Linux/POSIX dates. This is
671 the most compact way to specify a date and time in CBOR. Note that
672 this is always UTC and does not include the time zone. Use
673 QCBOREncode_AddDateString() if you want to include the time zone.
674
675 The integer encoding rules apply here so the date will be encoded in
676 a minimal number of bytes. Until about the year 2106 these dates will
677 encode in 6 bytes -- one byte for the tag, one byte for the type and
678 4 bytes for the integer. After that it will encode to 10 bytes.
679
680 Negative values are supported for dates before 1970.
681
682 If you care about leap-seconds and that level of accuracy, make sure
683 the system you are running this code on does it correctly. This code
684 just takes the value passed in.
685
686 This implementation cannot encode fractional seconds using float or
687 double even though that is allowed by CBOR, but you can encode them
688 if you want to by calling QCBOREncode_AddDouble() and
689 QCBOREncode_AddTag().
690
691 Error handling is the same as QCBOREncode_AddInt64().
692 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700693static void QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pCtx,
694 uint8_t uTagRequirement,
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700695 int64_t nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -0700696
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700697static void QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pCtx,
698 const char *szLabel,
699 uint8_t uTagRequirement,
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700700 int64_t nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -0700701
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700702static void QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pCtx,
703 int64_t nLabel,
704 uint8_t uTagRequirement,
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700705 int64_t nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -0700706
707
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700708static void QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx,
709 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100710
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700711static void QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx,
712 const char *szLabel,
713 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100714
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700715static void QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx,
716 int64_t nLabel,
717 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100718
719
720/**
721 @brief Add a byte string to the encoded output.
722
723 @param[in] pCtx The encoding context to add the bytes to.
724 @param[in] Bytes Pointer and length of the input data.
725
726 Simply adds the bytes to the encoded output as CBOR major type 2.
727
728 If called with @c Bytes.len equal to 0, an empty string will be
729 added. When @c Bytes.len is 0, @c Bytes.ptr may be @c NULL.
730
731 Error handling is the same as QCBOREncode_AddInt64().
732 */
733static void QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
734
735static void QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
736
737static void QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
738
739
740
741/**
742 @brief Add a binary UUID to the encoded output.
743
744 @param[in] pCtx The encoding context to add the UUID to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700745 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100746 @param[in] Bytes Pointer and length of the binary UUID.
747
748 A binary UUID as defined in [RFC 4122]
749 (https://tools.ietf.org/html/rfc4122) is added to the output.
750
751 It is output as CBOR major type 2, a binary string, with tag @ref
752 CBOR_TAG_BIN_UUID indicating the binary string is a UUID.
753 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700754static void QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pCtx,
755 uint8_t uTagRequirement,
756 UsefulBufC Bytes);
757
758static void QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pCtx,
759 const char *szLabel,
760 uint8_t uTagRequirement,
761 UsefulBufC Bytes);
762
763static void QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pCtx,
764 int64_t nLabel,
765 uint8_t uTagRequirement,
766 UsefulBufC Bytes);
767
768
Michael Eckel5c531332020-03-02 01:35:30 +0100769static void QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
770
771static void QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
772
773static void QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
774
775
776/**
777 @brief Add a positive big number to the encoded output.
778
779 @param[in] pCtx The encoding context to add the big number to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700780 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100781 @param[in] Bytes Pointer and length of the big number.
782
783 Big numbers are integers larger than 64-bits. Their format is
784 described in [RFC 7049] (https://tools.ietf.org/html/rfc7049).
785
786 It is output as CBOR major type 2, a binary string, with tag @ref
787 CBOR_TAG_POS_BIGNUM indicating the binary string is a positive big
788 number.
789
790 Often big numbers are used to represent cryptographic keys, however,
791 COSE which defines representations for keys chose not to use this
792 particular type.
793 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700794static void QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pCtx,
795 uint8_t uTagRequirement,
796 UsefulBufC Bytes);
797
798static void QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pCtx,
799 const char *szLabel,
800 uint8_t uTagRequirement,
801 UsefulBufC Bytes);
802
803static void QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pCtx,
804 int64_t nLabel,
805 uint8_t uTagRequirement,
806 UsefulBufC Bytes);
807
808
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700809static void QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx,
810 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100811
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700812static void QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx,
813 const char *szLabel,
814 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100815
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700816static void QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx,
817 int64_t nLabel,
818 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100819
820
821/**
822 @brief Add a negative big number to the encoded output.
823
824 @param[in] pCtx The encoding context to add the big number to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700825 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100826 @param[in] Bytes Pointer and length of the big number.
827
828 Big numbers are integers larger than 64-bits. Their format is
829 described in [RFC 7049] (https://tools.ietf.org/html/rfc7049).
830
831 It is output as CBOR major type 2, a binary string, with tag @ref
832 CBOR_TAG_NEG_BIGNUM indicating the binary string is a negative big
833 number.
834
835 Often big numbers are used to represent cryptographic keys, however,
836 COSE which defines representations for keys chose not to use this
837 particular type.
838 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700839static void QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pCtx,
840 uint8_t uTagRequirement,
841 UsefulBufC Bytes);
842
843static void QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pCtx,
844 const char *szLabel,
845 uint8_t uTagRequirement,
846 UsefulBufC Bytes);
847
848static void QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pCtx,
849 int64_t nLabel,
850 uint8_t uTagRequirement,
851 UsefulBufC Bytes);
852
853
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700854static void QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx,
855 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100856
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700857static void QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx,
858 const char *szLabel,
859 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100860
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700861static void QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx,
862 int64_t nLabel,
863 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100864
865
866#ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
867/**
868 @brief Add a decimal fraction to the encoded output.
869
870 @param[in] pCtx The encoding context to add the decimal fraction to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700871 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100872 @param[in] nMantissa The mantissa.
873 @param[in] nBase10Exponent The exponent.
874
875 The value is nMantissa * 10 ^ nBase10Exponent.
876
877 A decimal fraction is good for exact representation of some values
878 that can't be represented exactly with standard C (IEEE 754)
879 floating-point numbers. Much larger and much smaller numbers can
880 also be represented than floating-point because of the larger number
881 of bits in the exponent.
882
883 The decimal fraction is conveyed as two integers, a mantissa and a
884 base-10 scaling factor.
885
886 For example, 273.15 is represented by the two integers 27315 and -2.
887
888 The exponent and mantissa have the range from @c INT64_MIN to
889 @c INT64_MAX for both encoding and decoding (CBOR allows @c -UINT64_MAX
890 to @c UINT64_MAX, but this implementation doesn't support this range to
891 reduce code size and interface complexity a little).
892
893 CBOR Preferred encoding of the integers is used, thus they will be encoded
894 in the smallest number of bytes possible.
895
896 See also QCBOREncode_AddDecimalFractionBigNum() for a decimal
897 fraction with arbitrarily large precision and QCBOREncode_AddBigFloat().
898
899 There is no representation of positive or negative infinity or NaN
900 (Not a Number). Use QCBOREncode_AddDouble() to encode them.
901
902 See @ref expAndMantissa for decoded representation.
903 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700904static void QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pCtx,
905 uint8_t uTagRequirement,
906 int64_t nMantissa,
907 int64_t nBase10Exponent);
908
909static void QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -0700910 const char *szLabel,
911 uint8_t uTagRequirement,
912 int64_t nMantissa,
913 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700914
915static void QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pCtx,
916 int64_t nLabel,
917 uint8_t uTagRequirement,
918 int64_t nMantissa,
919 int64_t nBase10Exponent);
920
921
Michael Eckel5c531332020-03-02 01:35:30 +0100922static void QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pCtx,
923 int64_t nMantissa,
924 int64_t nBase10Exponent);
925
926static void QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pCtx,
927 const char *szLabel,
928 int64_t nMantissa,
929 int64_t nBase10Exponent);
930
931static void QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pCtx,
932 int64_t nLabel,
933 int64_t nMantissa,
934 int64_t nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +0100935/**
936 @brief Add a decimal fraction with a big number mantissa to the encoded output.
937
938 @param[in] pCtx The encoding context to add the decimal fraction to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700939 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100940 @param[in] Mantissa The mantissa.
941 @param[in] bIsNegative false if mantissa is positive, true if negative.
942 @param[in] nBase10Exponent The exponent.
943
944 This is the same as QCBOREncode_AddDecimalFraction() except the
945 mantissa is a big number (See QCBOREncode_AddPositiveBignum())
946 allowing for arbitrarily large precision.
947
948 See @ref expAndMantissa for decoded representation.
949 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700950static void QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pCtx,
951 uint8_t uTagRequirement,
952 UsefulBufC Mantissa,
953 bool bIsNegative,
954 int64_t nBase10Exponent);
955
956static void QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -0700957 const char *szLabel,
958 uint8_t uTagRequirement,
959 UsefulBufC Mantissa,
960 bool bIsNegative,
961 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700962
963static void QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
964 int64_t nLabel,
965 uint8_t uTagRequirement,
966 UsefulBufC Mantissa,
967 bool bIsNegative,
968 int64_t nBase10Exponent);
969
970
Michael Eckel5c531332020-03-02 01:35:30 +0100971static void QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pCtx,
972 UsefulBufC Mantissa,
973 bool bIsNegative,
974 int64_t nBase10Exponent);
975
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700976static void QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -0700977 const char *szLabel,
978 UsefulBufC Mantissa,
979 bool bIsNegative,
980 int64_t nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +0100981
982static void QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
983 int64_t nLabel,
984 UsefulBufC Mantissa,
985 bool bIsNegative,
986 int64_t nBase10Exponent);
987
988/**
989 @brief Add a big floating-point number to the encoded output.
990
991 @param[in] pCtx The encoding context to add the bigfloat to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700992 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100993 @param[in] nMantissa The mantissa.
994 @param[in] nBase2Exponent The exponent.
995
996 The value is nMantissa * 2 ^ nBase2Exponent.
997
998 "Bigfloats", as CBOR terms them, are similar to IEEE floating-point
999 numbers in having a mantissa and base-2 exponent, but they are not
1000 supported by hardware or encoded the same. They explicitly use two
1001 CBOR-encoded integers to convey the mantissa and exponent, each of which
1002 can be 8, 16, 32 or 64 bits. With both the mantissa and exponent
1003 64 bits they can express more precision and a larger range than an
1004 IEEE double floating-point number. See
1005 QCBOREncode_AddBigFloatBigNum() for even more precision.
1006
1007 For example, 1.5 would be represented by a mantissa of 3 and an
1008 exponent of -1.
1009
1010 The exponent and mantissa have the range from @c INT64_MIN to
1011 @c INT64_MAX for both encoding and decoding (CBOR allows @c -UINT64_MAX
1012 to @c UINT64_MAX, but this implementation doesn't support this range to
1013 reduce code size and interface complexity a little).
1014
1015 CBOR Preferred encoding of the integers is used, thus they will be encoded
1016 in the smallest number of bytes possible.
1017
1018 This can also be used to represent floating-point numbers in
1019 environments that don't support IEEE 754.
1020
1021 See @ref expAndMantissa for decoded representation.
1022 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001023static void QCBOREncode_AddTBigFloat(QCBOREncodeContext *pCtx,
1024 uint8_t uTagRequirement,
1025 int64_t nMantissa,
1026 int64_t nBase2Exponent);
1027
1028static void QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001029 const char *szLabel,
1030 uint8_t uTagRequirement,
1031 int64_t nMantissa,
1032 int64_t nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001033
1034static void QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pCtx,
1035 int64_t nLabel,
1036 uint8_t uTagRequirement,
1037 int64_t nMantissa,
1038 int64_t nBase2Exponent);
1039
1040
Michael Eckel5c531332020-03-02 01:35:30 +01001041static void QCBOREncode_AddBigFloat(QCBOREncodeContext *pCtx,
1042 int64_t nMantissa,
1043 int64_t nBase2Exponent);
1044
1045static void QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pCtx,
1046 const char *szLabel,
1047 int64_t nMantissa,
1048 int64_t nBase2Exponent);
1049
1050static void QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pCtx,
1051 int64_t nLabel,
1052 int64_t nMantissa,
1053 int64_t nBase2Exponent);
1054
Michael Eckel5c531332020-03-02 01:35:30 +01001055/**
1056 @brief Add a big floating-point number with a big number mantissa to
1057 the encoded output.
1058
1059 @param[in] pCtx The encoding context to add the bigfloat to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001060 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001061 @param[in] Mantissa The mantissa.
1062 @param[in] bIsNegative false if mantissa is positive, true if negative.
1063 @param[in] nBase2Exponent The exponent.
1064
1065 This is the same as QCBOREncode_AddBigFloat() except the mantissa is
1066 a big number (See QCBOREncode_AddPositiveBignum()) allowing for
1067 arbitrary precision.
1068
1069 See @ref expAndMantissa for decoded representation.
1070 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001071static void QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pCtx,
1072 uint8_t uTagRequirement,
1073 UsefulBufC Mantissa,
1074 bool bIsNegative,
1075 int64_t nBase2Exponent);
1076
1077static void QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001078 const char *szLabel,
1079 uint8_t uTagRequirement,
1080 UsefulBufC Mantissa,
1081 bool bIsNegative,
1082 int64_t nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001083
1084static void QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1085 int64_t nLabel,
1086 uint8_t uTagRequirement,
1087 UsefulBufC Mantissa,
1088 bool bIsNegative,
1089 int64_t nBase2Exponent);
1090
1091
Michael Eckel5c531332020-03-02 01:35:30 +01001092static void QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pCtx,
1093 UsefulBufC Mantissa,
1094 bool bIsNegative,
1095 int64_t nBase2Exponent);
1096
1097static void QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pCtx,
1098 const char *szLabel,
1099 UsefulBufC Mantissa,
1100 bool bIsNegative,
1101 int64_t nBase2Exponent);
1102
1103static void QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1104 int64_t nLabel,
1105 UsefulBufC Mantissa,
1106 bool bIsNegative,
1107 int64_t nBase2Exponent);
1108#endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
1109
1110
1111/**
1112 @brief Add a text URI to the encoded output.
1113
1114 @param[in] pCtx The encoding context to add the URI to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001115 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001116 @param[in] URI Pointer and length of the URI.
1117
1118 The format of URI must be per [RFC 3986]
1119 (https://tools.ietf.org/html/rfc3986).
1120
1121 It is output as CBOR major type 3, a text string, with tag @ref
1122 CBOR_TAG_URI indicating the text string is a URI.
1123
1124 A URI in a NULL-terminated string, @c szURI, can be easily added with
1125 this code:
1126
1127 QCBOREncode_AddURI(pCtx, UsefulBuf_FromSZ(szURI));
1128 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001129static void QCBOREncode_AddTURI(QCBOREncodeContext *pCtx,
1130 uint8_t uTagRequirement,
1131 UsefulBufC URI);
1132
1133static void QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pCtx,
1134 const char *szLabel,
1135 uint8_t uTagRequirement,
1136 UsefulBufC URI);
1137
1138static void QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pCtx,
1139 int64_t nLabel,
1140 uint8_t uTagRequirement,
1141 UsefulBufC URI);
1142
1143
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001144static void QCBOREncode_AddURI(QCBOREncodeContext *pCtx,
1145 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001146
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001147static void QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx,
1148 const char *szLabel,
1149 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001150
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001151static void QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx,
1152 int64_t nLabel,
1153 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001154
1155
1156/**
1157 @brief Add Base64-encoded text to encoded output.
1158
1159 @param[in] pCtx The encoding context to add the base-64 text to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001160 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001161 @param[in] B64Text Pointer and length of the base-64 encoded text.
1162
1163 The text content is Base64 encoded data per [RFC 4648]
1164 (https://tools.ietf.org/html/rfc4648).
1165
1166 It is output as CBOR major type 3, a text string, with tag @ref
1167 CBOR_TAG_B64 indicating the text string is Base64 encoded.
1168 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001169static void QCBOREncode_AddTB64Text(QCBOREncodeContext *pCtx,
1170 uint8_t uTagRequirement,
1171 UsefulBufC B64Text);
1172
1173static void QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pCtx,
1174 const char *szLabel,
1175 uint8_t uTagRequirement,
1176 UsefulBufC B64Text);
1177
1178static void QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pCtx,
1179 int64_t nLabel,
1180 uint8_t uTagRequirement,
1181 UsefulBufC B64Text);
1182
1183
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001184static void QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx,
1185 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001186
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001187static void QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx,
1188 const char *szLabel,
1189 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001190
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001191static void QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx,
1192 int64_t nLabel,
1193 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001194
1195
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001196
Michael Eckel5c531332020-03-02 01:35:30 +01001197/**
1198 @brief Add base64url encoded data to encoded output.
1199
1200 @param[in] pCtx The encoding context to add the base64url to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001201 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001202 @param[in] B64Text Pointer and length of the base64url encoded text.
1203
1204 The text content is base64URL encoded text as per [RFC 4648]
1205 (https://tools.ietf.org/html/rfc4648).
1206
1207 It is output as CBOR major type 3, a text string, with tag @ref
1208 CBOR_TAG_B64URL indicating the text string is a Base64url encoded.
1209 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001210static void QCBOREncode_AddTB64URLText(QCBOREncodeContext *pCtx,
1211 uint8_t uTagRequirement,
1212 UsefulBufC B64Text);
1213
1214static void QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pCtx,
1215 const char *szLabel,
1216 uint8_t uTagRequirement,
1217 UsefulBufC B64Text);
1218
1219static void QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pCtx,
1220 int64_t nLabel,
1221 uint8_t uTagRequirement,
1222 UsefulBufC B64Text);
1223
1224
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001225static void QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx,
1226 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001227
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001228static void QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx,
1229 const char *szLabel,
1230 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001231
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001232static void QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx,
1233 int64_t nLabel,
1234 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001235
1236
1237/**
1238 @brief Add Perl Compatible Regular Expression.
1239
1240 @param[in] pCtx The encoding context to add the regular expression to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001241 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001242 @param[in] Regex Pointer and length of the regular expression.
1243
1244 The text content is Perl Compatible Regular
1245 Expressions (PCRE) / JavaScript syntax [ECMA262].
1246
1247 It is output as CBOR major type 3, a text string, with tag @ref
1248 CBOR_TAG_REGEX indicating the text string is a regular expression.
1249 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001250static void QCBOREncode_AddTRegex(QCBOREncodeContext *pCtx,
1251 uint8_t uTagRequirement,
1252 UsefulBufC Regex);
1253
1254static void QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pCtx,
1255 const char *szLabel,
1256 uint8_t uTagRequirement,
1257 UsefulBufC Regex);
1258
1259static void QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pCtx,
1260 int64_t nLabel,
1261 uint8_t uTagRequirement,
1262 UsefulBufC Regex);
1263
1264
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001265static void QCBOREncode_AddRegex(QCBOREncodeContext *pCtx,
1266 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001267
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001268static void QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx,
1269 const char *szLabel,
1270 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001271
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001272static void QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx,
1273 int64_t nLabel,
1274 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001275
1276
1277/**
Laurence Lundblade4982f412020-09-18 23:02:18 -07001278 @brief MIME encoded data to the encoded output.
Michael Eckel5c531332020-03-02 01:35:30 +01001279
Laurence Lundblade4982f412020-09-18 23:02:18 -07001280 @param[in] pCtx The encoding context to add the MIME data to.
1281 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1282 @ref QCBOR_ENCODE_AS_BORROWED.
1283 @param[in] MIMEData Pointer and length of the MIME data.
Michael Eckel5c531332020-03-02 01:35:30 +01001284
1285 The text content is in MIME format per [RFC 2045]
Laurence Lundblade4982f412020-09-18 23:02:18 -07001286 (https://tools.ietf.org/html/rfc2045) including the headers.
Michael Eckel5c531332020-03-02 01:35:30 +01001287
Laurence Lundblade4982f412020-09-18 23:02:18 -07001288 It is output as CBOR major type 2, a binary string, with tag @ref
1289 CBOR_TAG_BINARY_MIME indicating the string is MIME data. This
1290 outputs tag 257, not tag 36, as it can carry any type of MIME binary,
1291 7-bit, 8-bit, quoted-printable and base64 where tag 36 cannot.
1292
1293 Previous versions of QCBOR, those before spiffy decode, output tag
1294 36. Decoding supports both tag 36 and 257. (if the old behavior with
1295 tag 36 is needed, copy the inline functions below and change the tag
1296 number).
1297
1298 See also QCBORDecode_GetMIMEMessage() and
1299 @ref QCBOR_TYPE_BINARY_MIME.
Laurence Lundbladeadaf5c22020-09-25 10:37:09 -07001300
1301 This does no translation of line endings. See QCBOREncode_AddText()
1302 for a discussion of line endings in CBOR.
Michael Eckel5c531332020-03-02 01:35:30 +01001303 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001304static void QCBOREncode_AddTMIMEData(QCBOREncodeContext *pCtx,
1305 uint8_t uTagRequirement,
1306 UsefulBufC MIMEData);
1307
1308static void QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pCtx,
1309 const char *szLabel,
1310 uint8_t uTagRequirement,
1311 UsefulBufC MIMEData);
1312
1313static void QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pCtx,
1314 int64_t nLabel,
1315 uint8_t uTagRequirement,
1316 UsefulBufC MIMEData);
1317
1318
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001319static void QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx,
1320 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001321
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001322static void QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx,
1323 const char *szLabel,
1324 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001325
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001326static void QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx,
1327 int64_t nLabel,
1328 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001329
1330
1331/**
1332 @brief Add an RFC 3339 date string
1333
1334 @param[in] pCtx The encoding context to add the date to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001335 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001336 @param[in] szDate Null-terminated string with date to add.
1337
1338 The string szDate should be in the form of [RFC 3339]
1339 (https://tools.ietf.org/html/rfc3339) as defined by section 3.3 in
1340 [RFC 4287] (https://tools.ietf.org/html/rfc4287). This is as
1341 described in section 2.4.1 in [RFC 7049]
1342 (https://tools.ietf.org/html/rfc7049).
1343
1344 Note that this function doesn't validate the format of the date string
1345 at all. If you add an incorrect format date string, the generated
1346 CBOR will be incorrect and the receiver may not be able to handle it.
1347
1348 Error handling is the same as QCBOREncode_AddInt64().
1349 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001350static void QCBOREncode_AddTDateString(QCBOREncodeContext *pCtx,
1351 uint8_t uTagRequirement,
1352 const char *szDate);
1353
1354static void QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pCtx,
1355 const char *szLabel,
1356 uint8_t uTagRequirement,
1357 const char *szDate);
1358
1359static void QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pCtx,
1360 int64_t nLabel,
1361 uint8_t uTagRequirement,
1362 const char *szDate);
1363
1364
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001365static void QCBOREncode_AddDateString(QCBOREncodeContext *pCtx,
1366 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001367
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001368static void QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx,
1369 const char *szLabel,
1370 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001371
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001372static void QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx,
1373 int64_t nLabel,
1374 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001375
Michael Eckel5c531332020-03-02 01:35:30 +01001376/**
1377 @brief Add a standard Boolean.
1378
1379 @param[in] pCtx The encoding context to add the Boolean to.
1380 @param[in] b true or false from @c <stdbool.h>.
1381
1382 Adds a Boolean value as CBOR major type 7.
1383
1384 Error handling is the same as QCBOREncode_AddInt64().
1385 */
1386static void QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b);
1387
1388static void QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b);
1389
1390static void QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b);
1391
1392
1393
1394/**
1395 @brief Add a NULL to the encoded output.
1396
1397 @param[in] pCtx The encoding context to add the NULL to.
1398
1399 Adds the NULL value as CBOR major type 7.
1400
1401 This NULL doesn't have any special meaning in CBOR such as a
1402 terminating value for a string or an empty value.
1403
1404 Error handling is the same as QCBOREncode_AddInt64().
1405 */
1406static void QCBOREncode_AddNULL(QCBOREncodeContext *pCtx);
1407
1408static void QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1409
1410static void QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1411
1412
1413/**
1414 @brief Add an "undef" to the encoded output.
1415
1416 @param[in] pCtx The encoding context to add the "undef" to.
1417
1418 Adds the undef value as CBOR major type 7.
1419
1420 Note that this value will not translate to JSON.
1421
1422 This Undef doesn't have any special meaning in CBOR such as a
1423 terminating value for a string or an empty value.
1424
1425 Error handling is the same as QCBOREncode_AddInt64().
1426 */
1427static void QCBOREncode_AddUndef(QCBOREncodeContext *pCtx);
1428
1429static void QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1430
1431static void QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1432
1433
1434/**
1435 @brief Indicates that the next items added are in an array.
1436
1437 @param[in] pCtx The encoding context to open the array in.
1438
1439 Arrays are the basic CBOR aggregate or structure type. Call this
1440 function to start or open an array. Then call the various @c
1441 QCBOREncode_AddXxx() functions to add the items that go into the
1442 array. Then call QCBOREncode_CloseArray() when all items have been
1443 added. The data items in the array can be of any type and can be of
1444 mixed types.
1445
1446 Nesting of arrays and maps is allowed and supported just by calling
1447 QCBOREncode_OpenArray() again before calling
1448 QCBOREncode_CloseArray(). While CBOR has no limit on nesting, this
1449 implementation does in order to keep it smaller and simpler. The
1450 limit is @ref QCBOR_MAX_ARRAY_NESTING. This is the max number of
1451 times this can be called without calling
1452 QCBOREncode_CloseArray(). QCBOREncode_Finish() will return @ref
1453 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP when it is called as this function
1454 just sets an error state and returns no value when this occurs.
1455
1456 If you try to add more than @ref QCBOR_MAX_ITEMS_IN_ARRAY items to a
1457 single array or map, @ref QCBOR_ERR_ARRAY_TOO_LONG will be returned
1458 when QCBOREncode_Finish() is called.
1459
1460 An array itself must have a label if it is being added to a map.
1461 Note that array elements do not have labels (but map elements do).
1462
1463 An array itself may be tagged by calling QCBOREncode_AddTag() before this call.
1464 */
1465static void QCBOREncode_OpenArray(QCBOREncodeContext *pCtx);
1466
1467static void QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1468
1469static void QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1470
1471
1472/**
1473 @brief Close an open array.
1474
1475 @param[in] pCtx The encoding context to close the array in.
1476
1477 The closes an array opened by QCBOREncode_OpenArray(). It reduces
1478 nesting level by one. All arrays (and maps) must be closed before
1479 calling QCBOREncode_Finish().
1480
1481 When an error occurs as a result of this call, the encoder records
1482 the error and enters the error state. The error will be returned when
1483 QCBOREncode_Finish() is called.
1484
1485 If this has been called more times than QCBOREncode_OpenArray(), then
1486 @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when QCBOREncode_Finish()
1487 is called.
1488
1489 If this is called and it is not an array that is currently open, @ref
1490 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
1491 is called.
1492 */
1493static void QCBOREncode_CloseArray(QCBOREncodeContext *pCtx);
1494
1495
1496/**
1497 @brief Indicates that the next items added are in a map.
1498
1499 @param[in] pCtx The encoding context to open the map in.
1500
1501 See QCBOREncode_OpenArray() for more information, particularly error
1502 handling.
1503
1504 CBOR maps are an aggregate type where each item in the map consists
1505 of a label and a value. They are similar to JSON objects.
1506
1507 The value can be any CBOR type including another map.
1508
1509 The label can also be any CBOR type, but in practice they are
1510 typically, integers as this gives the most compact output. They might
1511 also be text strings which gives readability and translation to JSON.
1512
1513 Every @c QCBOREncode_AddXxx() call has one version that ends with @c
1514 InMap for adding items to maps with string labels and one that ends
1515 with @c InMapN that is for adding with integer labels.
1516
1517 RFC 7049 uses the term "key" instead of "label".
1518
1519 If you wish to use map labels that are neither integer labels nor
1520 text strings, then just call the QCBOREncode_AddXxx() function
1521 explicitly to add the label. Then call it again to add the value.
1522
1523 See the [RFC 7049] (https://tools.ietf.org/html/rfc7049) for a lot
1524 more information on creating maps.
1525 */
1526static void QCBOREncode_OpenMap(QCBOREncodeContext *pCtx);
1527
1528static void QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1529
1530static void QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1531
1532
1533
1534/**
1535 @brief Close an open map.
1536
1537 @param[in] pCtx The encoding context to close the map in .
1538
1539 This closes a map opened by QCBOREncode_OpenMap(). It reduces nesting
1540 level by one.
1541
1542 When an error occurs as a result of this call, the encoder records
1543 the error and enters the error state. The error will be returned when
1544 QCBOREncode_Finish() is called.
1545
1546 If this has been called more times than QCBOREncode_OpenMap(),
1547 then @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1548 QCBOREncode_Finish() is called.
1549
1550 If this is called and it is not a map that is currently open, @ref
1551 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
1552 is called.
1553 */
1554static void QCBOREncode_CloseMap(QCBOREncodeContext *pCtx);
1555
1556
1557/**
1558 @brief Indicate start of encoded CBOR to be wrapped in a bstr.
1559
1560 @param[in] pCtx The encoding context to open the bstr-wrapped CBOR in.
1561
1562 All added encoded items between this call and a call to
1563 QCBOREncode_CloseBstrWrap2() will be wrapped in a bstr. They will
1564 appear in the final output as a byte string. That byte string will
1565 contain encoded CBOR. This increases nesting level by one.
1566
1567 The typical use case is for encoded CBOR that is to be
1568 cryptographically hashed, as part of a [RFC 8152, COSE]
1569 (https://tools.ietf.org/html/rfc8152) implementation.
1570
1571 Using QCBOREncode_BstrWrap() and QCBOREncode_CloseBstrWrap2() avoids
1572 having to encode the items first in one buffer (e.g., the COSE
1573 payload) and then add that buffer as a bstr to another encoding
1574 (e.g. the COSE to-be-signed bytes, the @c Sig_structure) potentially
1575 halving the memory needed.
1576
1577 RFC 7049 states the purpose of this wrapping is to prevent code
1578 relaying the signed data but not verifying it from tampering with the
1579 signed data thus making the signature unverifiable. It is also quite
1580 beneficial for the signature verification code. Standard CBOR
1581 decoders usually do not give access to partially decoded CBOR as
1582 would be needed to check the signature of some CBOR. With this
1583 wrapping, standard CBOR decoders can be used to get to all the data
1584 needed for a signature verification.
1585 */
1586static void QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx);
1587
1588static void QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1589
1590static void QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1591
1592
1593/**
1594 @brief Close a wrapping bstr.
1595
1596 @param[in] pCtx The encoding context to close of bstr wrapping in.
1597 @param[in] bIncludeCBORHead Include the encoded CBOR head of the bstr
1598 as well as the bytes in @c pWrappedCBOR.
1599 @param[out] pWrappedCBOR A @ref UsefulBufC containing wrapped bytes.
1600
1601 The closes a wrapping bstr opened by QCBOREncode_BstrWrap(). It reduces
1602 nesting level by one.
1603
1604 A pointer and length of the enclosed encoded CBOR is returned in @c
1605 *pWrappedCBOR if it is not @c NULL. The main purpose of this is so
1606 this data can be hashed (e.g., with SHA-256) as part of a [RFC 8152,
1607 COSE] (https://tools.ietf.org/html/rfc8152)
1608 implementation. **WARNING**, this pointer and length should be used
1609 right away before any other calls to @c QCBOREncode_CloseXxx() as
1610 they will move data around and the pointer and length will no longer
1611 be to the correct encoded CBOR.
1612
1613 When an error occurs as a result of this call, the encoder records
1614 the error and enters the error state. The error will be returned when
1615 QCBOREncode_Finish() is called.
1616
1617 If this has been called more times than QCBOREncode_BstrWrap(), then
1618 @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1619 QCBOREncode_Finish() is called.
1620
1621 If this is called and it is not a wrapping bstr that is currently
1622 open, @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
1623 QCBOREncode_Finish() is called.
1624
1625 QCBOREncode_CloseBstrWrap() is a deprecated version of this function
1626 that is equivalent to the call with @c bIncludeCBORHead @c true.
1627 */
1628void QCBOREncode_CloseBstrWrap2(QCBOREncodeContext *pCtx, bool bIncludeCBORHead, UsefulBufC *pWrappedCBOR);
1629
1630static void QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR);
1631
1632
1633/**
1634 @brief Add some already-encoded CBOR bytes.
1635
1636 @param[in] pCtx The encoding context to add the already-encode CBOR to.
1637 @param[in] Encoded The already-encoded CBOR to add to the context.
1638
1639 The encoded CBOR being added must be fully conforming CBOR. It must
1640 be complete with no arrays or maps that are incomplete. While this
1641 encoder doesn't ever produce indefinite lengths, it is OK for the
1642 raw CBOR added here to have indefinite lengths.
1643
1644 The raw CBOR added here is not checked in anyway. If it is not
1645 conforming or has open arrays or such, the final encoded CBOR
1646 will probably be wrong or not what was intended.
1647
1648 If the encoded CBOR being added here contains multiple items, they
1649 must be enclosed in a map or array. At the top level the raw
1650 CBOR must be a single data item.
1651 */
1652static void QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded);
1653
1654static void QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded);
1655
1656static void QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded);
1657
1658
1659/**
1660 @brief Get the encoded result.
1661
1662 @param[in] pCtx The context to finish encoding with.
1663 @param[out] pEncodedCBOR Pointer and length of encoded CBOR.
1664
1665 @retval QCBOR_ERR_TOO_MANY_CLOSES Nesting error
1666
1667 @retval QCBOR_ERR_CLOSE_MISMATCH Nesting error
1668
1669 @retval QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN Nesting error
1670
1671 @retval QCBOR_ERR_BUFFER_TOO_LARGE Encoded output buffer size
1672
1673 @retval QCBOR_ERR_BUFFER_TOO_SMALL Encoded output buffer size
1674
1675 @retval QCBOR_ERR_ARRAY_NESTING_TOO_DEEP Implementation limit
1676
1677 @retval QCBOR_ERR_ARRAY_TOO_LONG Implementation limit
1678
1679 If this returns success @ref QCBOR_SUCCESS the encoding was a success
1680 and the return length is correct and complete.
1681
1682 If no buffer was passed to QCBOREncode_Init(), then only the length
1683 was computed. If a buffer was passed, then the encoded CBOR is in the
1684 buffer.
1685
1686 Encoding errors primarily manifest here as most other encoding function
1687 do no return an error. They just set the error state in the encode
1688 context after which no encoding function does anything.
1689
1690 Three types of errors manifest here. The first type are nesting
1691 errors where the number of @c QCBOREncode_OpenXxx() calls do not
1692 match the number @c QCBOREncode_CloseXxx() calls. The solution is to
1693 fix the calling code.
1694
1695 The second type of error is because the buffer given is either too
1696 small or too large. The remedy is to give a correctly sized buffer.
1697
1698 The third type are due to limits in this implementation. @ref
1699 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP can be worked around by encoding the
1700 CBOR in two (or more) phases and adding the CBOR from the first phase
1701 to the second with @c QCBOREncode_AddEncoded().
1702
1703 If an error is returned, the buffer may have partially encoded
1704 incorrect CBOR in it and it should not be used. Likewise, the length
1705 may be incorrect and should not be used.
1706
1707 Note that the error could have occurred in one of the many @c
1708 QCBOREncode_AddXxx() calls long before QCBOREncode_Finish() was
1709 called. This error handling reduces the CBOR implementation size but
1710 makes debugging harder.
1711
1712 This may be called multiple times. It will always return the same. It
1713 can also be interleaved with calls to QCBOREncode_FinishGetSize().
1714
1715 QCBOREncode_GetErrorState() can be called to get the current
1716 error state and abort encoding early as an optimization, but is
1717 is never required.
1718 */
1719QCBORError QCBOREncode_Finish(QCBOREncodeContext *pCtx, UsefulBufC *pEncodedCBOR);
1720
1721
1722/**
1723 @brief Get the encoded CBOR and error status.
1724
1725 @param[in] pCtx The context to finish encoding with.
1726 @param[out] uEncodedLen The length of the encoded or potentially
1727 encoded CBOR in bytes.
1728
1729 @return The same errors as QCBOREncode_Finish().
1730
1731 This functions the same as QCBOREncode_Finish(), but only returns the
1732 size of the encoded output.
1733 */
1734QCBORError QCBOREncode_FinishGetSize(QCBOREncodeContext *pCtx, size_t *uEncodedLen);
1735
1736
1737/**
1738 @brief Indicate whether output buffer is NULL or not.
1739
1740 @param[in] pCtx The encoding context.
1741
1742 @return 1 if the output buffer is @c NULL.
1743
1744 Sometimes a @c NULL input buffer is given to QCBOREncode_Init() so
1745 that the size of the generated CBOR can be calculated without
1746 allocating a buffer for it. This returns 1 when the output buffer is
1747 NULL and 0 when it is not.
1748*/
1749static int QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx);
1750
1751 /**
1752 @brief Get the encoding error state.
1753
1754 @param[in] pCtx The encoding context.
1755
Laurence Lundbladeabf5c572020-06-29 21:21:29 -07001756 @return One of @ref QCBORError. See return values from
Michael Eckel5c531332020-03-02 01:35:30 +01001757 QCBOREncode_Finish()
1758
1759 Normally encoding errors need only be handled at the end of encoding
1760 when QCBOREncode_Finish() is called. This can be called to get the
1761 error result before finish should there be a need to halt encoding
1762 before QCBOREncode_Finish() is called.
1763*/
1764static QCBORError QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx);
1765
1766
1767/**
1768 Encode the "head" of a CBOR data item.
1769
1770 @param buffer Buffer to output the encoded head to; must be
1771 @ref QCBOR_HEAD_BUFFER_SIZE bytes in size.
1772 @param uMajorType One of CBOR_MAJOR_TYPE_XX.
1773 @param uMinLen The minimum number of bytes to encode uNumber. Almost always
1774 this is 0 to use preferred minimal encoding. If this is 4,
1775 then even the values 0xffff and smaller will be encoded
1776 as in 4 bytes. This is used primarily when encoding a
1777 float or double put into uNumber as the leading zero bytes
1778 for them must be encoded.
1779 @param uNumber The numeric argument part of the CBOR head.
1780 @return Pointer and length of the encoded head or
1781 @NULLUsefulBufC if the output buffer is too small.
1782
1783 Callers to need to call this for normal CBOR encoding. Note that it doesn't even
1784 take a @ref QCBOREncodeContext argument.
1785
1786 This encodes the major type and argument part of a data item. The
1787 argument is an integer that is usually either the value or the length
1788 of the data item.
1789
1790 This is exposed in the public interface to allow hashing of some CBOR
1791 data types, bstr in particular, a chunk at a time so the full CBOR
1792 doesn't have to be encoded in a contiguous buffer.
1793
1794 For example, if you have a 100,000 byte binary blob in a buffer that
1795 needs to be a bstr encoded and then hashed. You could allocate a
1796 100,010 byte buffer and encode it normally. Alternatively, you can
1797 encode the head in a 10 byte buffer with this function, hash that and
1798 then hash the 100,000 bytes using the same hash context.
1799
1800 See also QCBOREncode_AddBytesLenOnly();
1801 */
1802UsefulBufC QCBOREncode_EncodeHead(UsefulBuf buffer,
1803 uint8_t uMajorType,
1804 uint8_t uMinLen,
1805 uint64_t uNumber);
1806
1807
Michael Eckel5c531332020-03-02 01:35:30 +01001808
1809
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001810/* =========================================================================
1811 BEGINNING OF PRIVATE INLINE IMPLEMENTATION
1812 ========================================================================= */
Michael Eckel5c531332020-03-02 01:35:30 +01001813
1814/**
1815 @brief Semi-private method to add a buffer full of bytes to encoded output
1816
1817 @param[in] pCtx The encoding context to add the integer to.
1818 @param[in] uMajorType The CBOR major type of the bytes.
1819 @param[in] Bytes The bytes to add.
1820
1821 Use QCBOREncode_AddText() or QCBOREncode_AddBytes() or
1822 QCBOREncode_AddEncoded() instead. They are inline functions that call
1823 this and supply the correct major type. This function is public to
1824 make the inline functions work to keep the overall code size down and
1825 because the C language has no way to make it private.
1826
1827 If this is called the major type should be @c
1828 CBOR_MAJOR_TYPE_TEXT_STRING, @c CBOR_MAJOR_TYPE_BYTE_STRING or @c
1829 CBOR_MAJOR_NONE_TYPE_RAW. The last one is special for adding
1830 already-encoded CBOR.
1831 */
1832void QCBOREncode_AddBuffer(QCBOREncodeContext *pCtx, uint8_t uMajorType, UsefulBufC Bytes);
1833
1834
1835/**
1836 @brief Semi-private method to open a map, array or bstr-wrapped CBOR
1837
1838 @param[in] pCtx The context to add to.
1839 @param[in] uMajorType The major CBOR type to close
1840
1841 Call QCBOREncode_OpenArray(), QCBOREncode_OpenMap() or
1842 QCBOREncode_BstrWrap() instead of this.
1843 */
1844void QCBOREncode_OpenMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType);
1845
1846
1847/**
1848 @brief Semi-private method to open a map, array with indefinite length
1849
1850 @param[in] pCtx The context to add to.
1851 @param[in] uMajorType The major CBOR type to close
1852
1853 Call QCBOREncode_OpenArrayIndefiniteLength() or
1854 QCBOREncode_OpenMapIndefiniteLength() instead of this.
1855 */
1856void QCBOREncode_OpenMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx, uint8_t uMajorType);
1857
1858
1859/**
1860 @brief Semi-private method to close a map, array or bstr wrapped CBOR
1861
1862 @param[in] pCtx The context to add to.
1863 @param[in] uMajorType The major CBOR type to close.
1864
1865 Call QCBOREncode_CloseArray() or QCBOREncode_CloseMap() instead of this.
1866 */
1867void QCBOREncode_CloseMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType);
1868
1869
1870/**
1871 @brief Semi-private method to close a map, array with indefinite length
1872
1873 @param[in] pCtx The context to add to.
1874 @param[in] uMajorType The major CBOR type to close.
1875
1876 Call QCBOREncode_CloseArrayIndefiniteLength() or
1877 QCBOREncode_CloseMapIndefiniteLength() instead of this.
1878 */
1879void QCBOREncode_CloseMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx,
1880 uint8_t uMajorType);
1881
1882
1883/**
1884 @brief Semi-private method to add simple types.
1885
1886 @param[in] pCtx The encoding context to add the simple value to.
1887 @param[in] uMinLen Minimum encoding size for uNum. Usually 0.
1888 @param[in] uNum One of CBOR_SIMPLEV_FALSE through _UNDEF or other.
1889
1890 This is used to add simple types like true and false.
1891
1892 Call QCBOREncode_AddBool(), QCBOREncode_AddNULL(),
1893 QCBOREncode_AddUndef() instead of this.
1894
1895 This function can add simple values that are not defined by CBOR
1896 yet. This expansion point in CBOR should not be used unless they are
1897 standardized.
1898
1899 Error handling is the same as QCBOREncode_AddInt64().
1900 */
1901void QCBOREncode_AddType7(QCBOREncodeContext *pCtx, uint8_t uMinLen, uint64_t uNum);
1902
1903
1904/**
1905 @brief Semi-private method to add bigfloats and decimal fractions.
1906
1907 @param[in] pCtx The encoding context to add the value to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001908 @param[in] uTag The type 6 tag indicating what this is to be.
Michael Eckel5c531332020-03-02 01:35:30 +01001909 @param[in] BigNumMantissa Is @ref NULLUsefulBufC if mantissa is an
1910 @c int64_t or the actual big number mantissa
1911 if not.
1912 @param[in] nMantissa The @c int64_t mantissa if it is not a big number.
1913 @param[in] nExponent The exponent.
1914
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001915 This outputs either the @ref CBOR_TAG_DECIMAL_FRACTION or @ref
1916 CBOR_TAG_BIGFLOAT tag. if @c uTag is @ref CBOR_TAG_INVALID64, then
1917 this outputs the "borrowed" content format.
Michael Eckel5c531332020-03-02 01:35:30 +01001918
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001919 The tag content output by this is an array with two members, the
1920 exponent and then the mantissa. The mantissa can be either a big
1921 number or an @c int64_t.
1922
1923 This implementation cannot output an exponent further from 0 than
1924 INT64_MAX.
1925
1926 To output a mantissa that is bewteen INT64_MAX and UINT64_MAX from 0,
1927 it must be as a big number.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001928
Michael Eckel5c531332020-03-02 01:35:30 +01001929 Typically, QCBOREncode_AddDecimalFraction(), QCBOREncode_AddBigFloat(),
1930 QCBOREncode_AddDecimalFractionBigNum() or QCBOREncode_AddBigFloatBigNum()
1931 is called instead of this.
1932 */
1933void QCBOREncode_AddExponentAndMantissa(QCBOREncodeContext *pCtx,
1934 uint64_t uTag,
1935 UsefulBufC BigNumMantissa,
1936 bool bBigNumIsNegative,
1937 int64_t nMantissa,
1938 int64_t nExponent);
1939
1940/**
1941 @brief Semi-private method to add only the type and length of a byte string.
1942
1943 @param[in] pCtx The context to initialize.
1944 @param[in] Bytes Pointer and length of the input data.
1945
1946 This is the same as QCBOREncode_AddBytes() except it only adds the
1947 CBOR encoding for the type and the length. It doesn't actually add
1948 the bytes. You can't actually produce correct CBOR with this and the
1949 rest of this API. It is only used for a special case where
1950 the valid CBOR is created manually by putting this type and length in
1951 and then adding the actual bytes. In particular, when only a hash of
1952 the encoded CBOR is needed, where the type and header are hashed
1953 separately and then the bytes is hashed. This makes it possible to
1954 implement COSE Sign1 with only one copy of the payload in the output
1955 buffer, rather than two, roughly cutting memory use in half.
1956
1957 This is only used for this odd case, but this is a supported
1958 tested function.
1959
1960 See also QCBOREncode_EncodeHead().
1961*/
1962static inline void QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
1963
1964static inline void QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
1965
1966static inline void QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
1967
1968
1969
1970
1971
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001972static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001973QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pMe, const char *szLabel, int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01001974{
1975 // Use _AddBuffer() because _AddSZString() is defined below, not above
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001976 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
1977 QCBOREncode_AddInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01001978}
1979
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001980static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001981QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pMe, int64_t nLabel, int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01001982{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001983 QCBOREncode_AddInt64(pMe, nLabel);
1984 QCBOREncode_AddInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01001985}
1986
1987
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001988static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001989QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pMe, const char *szLabel, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01001990{
1991 // Use _AddBuffer() because _AddSZString() is defined below, not above
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001992 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
1993 QCBOREncode_AddUInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01001994}
1995
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001996static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001997QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01001998{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001999 QCBOREncode_AddInt64(pMe, nLabel);
2000 QCBOREncode_AddUInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002001}
2002
2003
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002004static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002005QCBOREncode_AddText(QCBOREncodeContext *pMe, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002006{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002007 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002008}
2009
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002010static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002011QCBOREncode_AddTextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002012{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002013 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szLabel));
2014 QCBOREncode_AddText(pMe, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002015}
2016
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002017static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002018QCBOREncode_AddTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002019{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002020 QCBOREncode_AddInt64(pMe, nLabel);
2021 QCBOREncode_AddText(pMe, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002022}
2023
2024
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002025inline static void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002026QCBOREncode_AddSZString(QCBOREncodeContext *pMe, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002027{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002028 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szString));
Michael Eckel5c531332020-03-02 01:35:30 +01002029}
2030
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002031static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002032QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pMe, const char *szLabel, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002033{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002034 QCBOREncode_AddSZString(pMe, szLabel);
2035 QCBOREncode_AddSZString(pMe, szString);
Michael Eckel5c531332020-03-02 01:35:30 +01002036}
2037
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002038static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002039QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002040{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002041 QCBOREncode_AddInt64(pMe, nLabel);
2042 QCBOREncode_AddSZString(pMe, szString);
Michael Eckel5c531332020-03-02 01:35:30 +01002043}
2044
2045
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002046static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002047QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pMe, const char *szLabel, double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002048{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002049 QCBOREncode_AddSZString(pMe, szLabel);
2050 QCBOREncode_AddDouble(pMe, dNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002051}
2052
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002053static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002054QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pMe, int64_t nLabel, double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002055{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002056 QCBOREncode_AddInt64(pMe, nLabel);
2057 QCBOREncode_AddDouble(pMe, dNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002058}
2059
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002060static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002061QCBOREncode_AddFloatToMap(QCBOREncodeContext *pMe, const char *szLabel, float dNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002062{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002063 QCBOREncode_AddSZString(pMe, szLabel);
2064 QCBOREncode_AddFloat(pMe, dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002065}
2066
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002067static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002068QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pMe, int64_t nLabel, float fNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002069{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002070 QCBOREncode_AddInt64(pMe, nLabel);
2071 QCBOREncode_AddFloat(pMe, fNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002072}
2073
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002074static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002075QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pMe, const char *szLabel, double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002076{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002077 QCBOREncode_AddSZString(pMe, szLabel);
2078 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002079}
2080
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002081static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002082QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pMe, int64_t nLabel, double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002083{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002084 QCBOREncode_AddInt64(pMe, nLabel);
2085 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002086}
2087
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002088static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002089QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pMe, const char *szLabel, float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002090{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002091 QCBOREncode_AddSZString(pMe, szLabel);
2092 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002093}
2094
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002095static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002096QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pMe, int64_t nLabel, float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002097{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002098 QCBOREncode_AddInt64(pMe, nLabel);
2099 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002100}
2101
Michael Eckel5c531332020-03-02 01:35:30 +01002102
Laurence Lundblade9b334962020-08-27 10:55:53 -07002103
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002104static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002105QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pMe, uint8_t uTag, int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002106{
2107 if(uTag == QCBOR_ENCODE_AS_TAG) {
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002108 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_EPOCH);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002109 }
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002110 QCBOREncode_AddInt64(pMe, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002111}
2112
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002113static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002114QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTag, int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002115{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002116 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002117 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002118}
2119
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002120static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002121QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTag, int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002122{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002123 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002124 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002125}
2126
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002127static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002128QCBOREncode_AddDateEpoch(QCBOREncodeContext *pMe, int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002129{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002130 QCBOREncode_AddTDateEpoch(pMe, QCBOR_ENCODE_AS_TAG, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002131}
2132
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002133static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002134QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pMe, const char *szLabel, int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002135{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002136 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002137 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002138}
2139
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002140static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002141QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pMe, int64_t nLabel, int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002142{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002143 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002144 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002145}
2146
2147
Laurence Lundblade9b334962020-08-27 10:55:53 -07002148
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002149static inline void
2150QCBOREncode_AddBytes(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002151{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002152 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002153}
2154
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002155static inline void
2156QCBOREncode_AddBytesToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002157{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002158 QCBOREncode_AddSZString(pMe, szLabel);
2159 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002160}
2161
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002162static inline void
2163QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002164{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002165 QCBOREncode_AddInt64(pMe, nLabel);
2166 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002167}
2168
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002169static inline void
2170QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002171{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002172 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002173}
2174
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002175static inline void
2176QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002177{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002178 QCBOREncode_AddSZString(pMe, szLabel);
2179 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002180}
2181
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002182static inline void
2183QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002184{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002185 QCBOREncode_AddInt64(pMe, nLabel);
2186 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002187}
2188
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002189
2190static inline void
2191QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002192{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002193 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2194 QCBOREncode_AddTag(pMe, CBOR_TAG_BIN_UUID);
2195 }
2196 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002197}
2198
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002199static inline void
2200QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pMe,
2201 const char *szLabel,
2202 uint8_t uTagRequirement,
2203 UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002204{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002205 QCBOREncode_AddSZString(pMe, szLabel);
2206 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002207}
2208
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002209static inline void
2210QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002211{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002212 QCBOREncode_AddInt64(pMe, nLabel);
2213 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002214}
2215
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002216static inline void
2217QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002218{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002219 QCBOREncode_AddTBinaryUUID(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002220}
2221
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002222static inline void
2223QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002224{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002225 QCBOREncode_AddTBinaryUUIDToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002226}
2227
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002228static inline void
2229QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002230{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002231 QCBOREncode_AddTBinaryUUIDToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002232}
2233
2234
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002235static inline void
2236QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002237{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002238 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2239 QCBOREncode_AddTag(pMe, CBOR_TAG_POS_BIGNUM);
2240 }
2241 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002242}
2243
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002244static inline void
2245QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pMe,
2246 const char *szLabel,
2247 uint8_t uTagRequirement,
2248 UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002249{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002250 QCBOREncode_AddSZString(pMe, szLabel);
2251 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002252}
2253
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002254static inline void
2255QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002256{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002257 QCBOREncode_AddInt64(pMe, nLabel);
2258 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002259}
2260
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002261static inline void
2262QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2263{
2264 QCBOREncode_AddTPositiveBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2265}
2266
2267static inline void
2268QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2269{
2270 QCBOREncode_AddTPositiveBignumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2271}
2272
2273static inline void
2274QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2275{
2276 QCBOREncode_AddTPositiveBignumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2277}
2278
2279
2280static inline void
2281QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
2282{
2283 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2284 QCBOREncode_AddTag(pMe, CBOR_TAG_NEG_BIGNUM);
2285 }
2286 QCBOREncode_AddBytes(pMe, Bytes);
2287}
2288
2289static inline void
2290QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pMe,
2291 const char *szLabel,
2292 uint8_t uTagRequirement,
2293 UsefulBufC Bytes)
2294{
2295 QCBOREncode_AddSZString(pMe, szLabel);
2296 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2297}
2298
2299static inline void
2300QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
2301{
2302 QCBOREncode_AddInt64(pMe, nLabel);
2303 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2304}
2305
2306static inline void
2307QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2308{
2309 QCBOREncode_AddTNegativeBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2310}
2311
2312static inline void
2313QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2314{
2315 QCBOREncode_AddTNegativeBignumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2316}
2317
2318static inline void
2319QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2320{
2321 QCBOREncode_AddTNegativeBignumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2322}
2323
2324
Michael Eckel5c531332020-03-02 01:35:30 +01002325
2326#ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
2327
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002328static inline void
2329QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pMe,
2330 uint8_t uTagRequirement,
2331 int64_t nMantissa,
2332 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002333{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002334 uint64_t uTag;
2335 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2336 uTag = CBOR_TAG_DECIMAL_FRACTION;
2337 } else {
2338 uTag = CBOR_TAG_INVALID64;
2339 }
2340 QCBOREncode_AddExponentAndMantissa(pMe,
2341 uTag,
Michael Eckel5c531332020-03-02 01:35:30 +01002342 NULLUsefulBufC,
2343 false,
2344 nMantissa,
2345 nBase10Exponent);
2346}
2347
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002348static inline void
2349QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pMe,
2350 const char *szLabel,
2351 uint8_t uTagRequirement,
2352 int64_t nMantissa,
2353 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002354{
2355 QCBOREncode_AddSZString(pMe, szLabel);
2356 QCBOREncode_AddTDecimalFraction(pMe, uTagRequirement, nMantissa, nBase10Exponent);
2357}
2358
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002359static inline void
2360QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pMe,
2361 int64_t nLabel,
2362 uint8_t uTagRequirement,
2363 int64_t nMantissa,
2364 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002365{
2366 QCBOREncode_AddInt64(pMe, nLabel);
2367 QCBOREncode_AddTDecimalFraction(pMe, uTagRequirement, nMantissa, nBase10Exponent);
2368}
2369
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002370static inline void
2371QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pMe,
2372 int64_t nMantissa,
2373 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002374{
2375 QCBOREncode_AddTDecimalFraction(pMe, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
2376}
2377
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002378static inline void
2379QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pMe,
2380 const char *szLabel,
2381 int64_t nMantissa,
2382 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002383{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002384 QCBOREncode_AddTDecimalFractionToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002385}
2386
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002387static inline void
2388QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pMe,
2389 int64_t nLabel,
2390 int64_t nMantissa,
2391 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002392{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002393 QCBOREncode_AddTDecimalFractionToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002394}
2395
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002396
2397
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002398static inline void
2399QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pMe,
2400 uint8_t uTagRequirement,
2401 UsefulBufC Mantissa,
2402 bool bIsNegative,
2403 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002404{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002405 uint64_t uTag;
2406 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2407 uTag = CBOR_TAG_DECIMAL_FRACTION;
2408 } else {
2409 uTag = CBOR_TAG_INVALID64;
2410 }
2411 QCBOREncode_AddExponentAndMantissa(pMe,
2412 uTag,
Michael Eckel5c531332020-03-02 01:35:30 +01002413 Mantissa, bIsNegative,
2414 0,
2415 nBase10Exponent);
2416}
2417
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002418static inline void
2419QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
2420 const char *szLabel,
2421 uint8_t uTagRequirement,
2422 UsefulBufC Mantissa,
2423 bool bIsNegative,
2424 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002425{
2426 QCBOREncode_AddSZString(pMe, szLabel);
2427 QCBOREncode_AddTDecimalFractionBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase10Exponent);
2428}
2429
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002430static inline void
2431QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
2432 int64_t nLabel,
2433 uint8_t uTagRequirement,
2434 UsefulBufC Mantissa,
2435 bool bIsNegative,
2436 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002437{
2438 QCBOREncode_AddInt64(pMe, nLabel);
2439 QCBOREncode_AddTDecimalFractionBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase10Exponent);
2440}
2441
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002442static inline void
2443QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pMe,
2444 UsefulBufC Mantissa,
2445 bool bIsNegative,
2446 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002447{
2448 QCBOREncode_AddTDecimalFractionBigNum(pMe, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase10Exponent);
2449}
2450
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002451static inline void
2452QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
2453 const char *szLabel,
2454 UsefulBufC Mantissa,
2455 bool bIsNegative,
2456 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002457{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002458 QCBOREncode_AddTDecimalFractionBigNumToMapSZ(pMe,
2459 szLabel,
2460 QCBOR_ENCODE_AS_TAG,
2461 Mantissa,
2462 bIsNegative,
2463 nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002464}
2465
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002466static inline void
2467QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
2468 int64_t nLabel,
2469 UsefulBufC Mantissa,
2470 bool bIsNegative,
2471 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002472{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002473 QCBOREncode_AddTDecimalFractionBigNumToMapN(pMe,
2474 nLabel,
2475 QCBOR_ENCODE_AS_TAG,
2476 Mantissa,
2477 bIsNegative,
2478 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002479}
2480
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002481
2482
2483
2484
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002485static inline void
2486QCBOREncode_AddTBigFloat(QCBOREncodeContext *pMe,
2487 uint8_t uTagRequirement,
2488 int64_t nMantissa,
2489 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002490{
2491 uint64_t uTag;
2492 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2493 uTag = CBOR_TAG_BIGFLOAT;
2494 } else {
2495 uTag = CBOR_TAG_INVALID64;
2496 }
2497 QCBOREncode_AddExponentAndMantissa(pMe, uTag, NULLUsefulBufC, false, nMantissa, nBase2Exponent);
2498}
2499
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002500static inline void
2501QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pMe,
2502 const char *szLabel,
2503 uint8_t uTagRequirement,
2504 int64_t nMantissa,
2505 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002506{
2507 QCBOREncode_AddSZString(pMe, szLabel);
2508 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
2509}
2510
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002511static inline void
2512QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pMe,
2513 int64_t nLabel,
2514 uint8_t uTagRequirement,
2515 int64_t nMantissa,
2516 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002517{
2518 QCBOREncode_AddInt64(pMe, nLabel);
2519 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
2520}
2521
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002522static inline void
2523QCBOREncode_AddBigFloat(QCBOREncodeContext *pMe,
2524 int64_t nMantissa,
2525 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002526{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002527 QCBOREncode_AddTBigFloat(pMe, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002528}
2529
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002530static inline void
2531QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pMe,
2532 const char *szLabel,
2533 int64_t nMantissa,
2534 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002535{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002536 QCBOREncode_AddTBigFloatToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002537}
2538
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002539static inline void
2540QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pMe,
2541 int64_t nLabel,
2542 int64_t nMantissa,
2543 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002544{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002545 QCBOREncode_AddTBigFloatToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002546}
2547
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002548
2549
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002550static inline void
2551QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pMe,
2552 uint8_t uTagRequirement,
2553 UsefulBufC Mantissa,
2554 bool bIsNegative,
2555 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002556{
2557 uint64_t uTag;
2558 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2559 uTag = CBOR_TAG_BIGFLOAT;
2560 } else {
2561 uTag = CBOR_TAG_INVALID64;
2562 }
2563 QCBOREncode_AddExponentAndMantissa(pMe, uTag, Mantissa, bIsNegative, 0, nBase2Exponent);
2564}
2565
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002566static inline void
2567QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pMe,
2568 const char *szLabel,
2569 uint8_t uTagRequirement,
2570 UsefulBufC Mantissa,
2571 bool bIsNegative,
2572 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002573{
2574 QCBOREncode_AddSZString(pMe, szLabel);
2575 QCBOREncode_AddTBigFloatBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase2Exponent);
2576}
2577
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002578static inline void
2579QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
2580 int64_t nLabel,
2581 uint8_t uTagRequirement,
2582 UsefulBufC Mantissa,
2583 bool bIsNegative,
2584 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002585{
2586 QCBOREncode_AddInt64(pMe, nLabel);
2587 QCBOREncode_AddTBigFloatBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase2Exponent);
2588}
2589
2590
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002591static inline void
2592QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pMe,
2593 UsefulBufC Mantissa,
2594 bool bIsNegative,
2595 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002596{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002597 QCBOREncode_AddTBigFloatBigNum(pMe, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002598}
2599
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002600static inline void
2601QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pMe,
2602 const char *szLabel,
2603 UsefulBufC Mantissa,
2604 bool bIsNegative,
2605 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002606{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002607 QCBOREncode_AddTBigFloatBigNumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002608}
2609
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002610static inline void
2611QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
2612 int64_t nLabel,
2613 UsefulBufC Mantissa,
2614 bool bIsNegative,
2615 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002616{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002617 QCBOREncode_AddTBigFloatBigNumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002618}
2619#endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
2620
2621
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002622static inline void
2623QCBOREncode_AddTURI(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002624{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002625 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2626 QCBOREncode_AddTag(pMe, CBOR_TAG_URI);
2627 }
2628 QCBOREncode_AddText(pMe, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002629}
2630
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002631static inline void
2632QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002633{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002634 QCBOREncode_AddSZString(pMe, szLabel);
2635 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002636}
2637
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002638static inline void
2639QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002640{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002641 QCBOREncode_AddInt64(pMe, nLabel);
2642 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
2643}
2644
2645static inline void
2646QCBOREncode_AddURI(QCBOREncodeContext *pMe, UsefulBufC URI)
2647{
2648 QCBOREncode_AddTURI(pMe, QCBOR_ENCODE_AS_TAG, URI);
2649}
2650
2651static inline void
2652QCBOREncode_AddURIToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC URI)
2653{
2654 QCBOREncode_AddTURIToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, URI);
2655}
2656
2657static inline void
2658QCBOREncode_AddURIToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC URI)
2659{
2660 QCBOREncode_AddTURIToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002661}
2662
2663
2664
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002665static inline void
2666QCBOREncode_AddTB64Text(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002667{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002668 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2669 QCBOREncode_AddTag(pMe, CBOR_TAG_B64);
2670 }
2671 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002672}
2673
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002674static inline void
2675QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pMe,
2676 const char *szLabel,
2677 uint8_t uTagRequirement,
2678 UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002679{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002680 QCBOREncode_AddSZString(pMe, szLabel);
2681 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002682}
2683
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002684static inline void
2685QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002686{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002687 QCBOREncode_AddInt64(pMe, nLabel);
2688 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
2689}
2690
2691static inline void
2692QCBOREncode_AddB64Text(QCBOREncodeContext *pMe, UsefulBufC B64Text)
2693{
2694 QCBOREncode_AddTB64Text(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
2695}
2696
2697static inline void
2698QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC B64Text)
2699{
2700 QCBOREncode_AddTB64TextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
2701}
2702
2703static inline void
2704QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC B64Text)
2705{
2706 QCBOREncode_AddTB64TextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002707}
2708
2709
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002710
2711static inline void
2712QCBOREncode_AddTB64URLText(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002713{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002714 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2715 QCBOREncode_AddTag(pMe, CBOR_TAG_B64URL);
2716 }
2717 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002718}
2719
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002720static inline void
2721QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pMe,
2722 const char *szLabel,
2723 uint8_t uTagRequirement,
2724 UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002725{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002726 QCBOREncode_AddSZString(pMe, szLabel);
2727 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002728}
2729
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002730static inline void
2731QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002732{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002733 QCBOREncode_AddInt64(pMe, nLabel);
2734 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
2735}
2736
2737static inline void
2738QCBOREncode_AddB64URLText(QCBOREncodeContext *pMe, UsefulBufC B64Text)
2739{
2740 QCBOREncode_AddTB64URLText(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
2741}
2742
2743static inline void
2744QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC B64Text)
2745{
2746 QCBOREncode_AddTB64URLTextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
2747}
2748
2749static inline void
2750QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC B64Text)
2751{
2752 QCBOREncode_AddTB64URLTextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002753}
2754
2755
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002756
2757static inline void
2758QCBOREncode_AddTRegex(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002759{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002760 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2761 QCBOREncode_AddTag(pMe, CBOR_TAG_REGEX);
2762 }
2763 QCBOREncode_AddText(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002764}
2765
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002766static inline void
2767QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002768{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002769 QCBOREncode_AddSZString(pMe, szLabel);
2770 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002771}
2772
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002773static inline void
2774QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002775{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002776 QCBOREncode_AddInt64(pMe, nLabel);
2777 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
2778}
2779
2780static inline void
2781QCBOREncode_AddRegex(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2782{
2783 QCBOREncode_AddTRegex(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2784}
2785
2786static inline void
2787QCBOREncode_AddRegexToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2788{
2789 QCBOREncode_AddTRegexToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2790}
2791
2792static inline void
2793QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2794{
2795 QCBOREncode_AddTRegexToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2796
Michael Eckel5c531332020-03-02 01:35:30 +01002797}
2798
2799
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002800static inline void
2801QCBOREncode_AddTMIMEData(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01002802{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002803 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
Laurence Lundblade4982f412020-09-18 23:02:18 -07002804 QCBOREncode_AddTag(pMe, CBOR_TAG_BINARY_MIME);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002805 }
Laurence Lundblade4982f412020-09-18 23:02:18 -07002806 QCBOREncode_AddBytes(pMe, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01002807}
2808
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002809static inline void
2810QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pMe,
2811 const char *szLabel,
2812 uint8_t uTagRequirement,
2813 UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01002814{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002815 QCBOREncode_AddSZString(pMe, szLabel);
2816 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01002817}
2818
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002819static inline void
2820QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01002821{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002822 QCBOREncode_AddInt64(pMe, nLabel);
2823 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
2824}
2825
2826static inline void
2827QCBOREncode_AddMIMEData(QCBOREncodeContext *pMe, UsefulBufC MIMEData)
2828{
2829 QCBOREncode_AddTMIMEData(pMe, QCBOR_ENCODE_AS_TAG, MIMEData);
2830}
2831
2832static inline void
2833QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC MIMEData)
2834{
2835 QCBOREncode_AddTMIMEDataToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
2836}
2837
2838static inline void
2839QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC MIMEData)
2840{
2841 QCBOREncode_AddTMIMEDataToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01002842}
2843
2844
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002845static inline void
2846QCBOREncode_AddTDateString(QCBOREncodeContext *pMe, uint8_t uTagRequirement, const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002847{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002848 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2849 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_STRING);
2850 }
2851 QCBOREncode_AddSZString(pMe, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002852}
2853
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002854static inline void
2855QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pMe,
2856 const char *szLabel,
2857 uint8_t uTagRequirement,
2858 const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002859{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002860 QCBOREncode_AddSZString(pMe, szLabel);
2861 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002862}
2863
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002864static inline void
2865QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002866{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002867 QCBOREncode_AddInt64(pMe, nLabel);
2868 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
2869}
2870
2871static inline void
2872QCBOREncode_AddDateString(QCBOREncodeContext *pMe, const char *szDate)
2873{
2874 QCBOREncode_AddTDateString(pMe, QCBOR_ENCODE_AS_TAG, szDate);
2875}
2876
2877static inline void
2878QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pMe, const char *szLabel, const char *szDate)
2879{
2880 QCBOREncode_AddTDateStringToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, szDate);
2881}
2882
2883static inline void
2884QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, const char *szDate)
2885{
2886 QCBOREncode_AddTDateStringToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002887}
2888
2889
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002890static inline void
2891QCBOREncode_AddSimple(QCBOREncodeContext *pMe, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002892{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002893 QCBOREncode_AddType7(pMe, 0, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002894}
2895
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002896static inline void
2897QCBOREncode_AddSimpleToMap(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01002898{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002899 QCBOREncode_AddSZString(pMe, szLabel);
2900 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01002901}
2902
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002903static inline void
2904QCBOREncode_AddSimpleToMapN(QCBOREncodeContext *pMe, int nLabel, uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01002905{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002906 QCBOREncode_AddInt64(pMe, nLabel);
2907 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01002908}
2909
2910
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002911static inline void
2912QCBOREncode_AddBool(QCBOREncodeContext *pMe, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01002913{
2914 uint8_t uSimple = CBOR_SIMPLEV_FALSE;
2915 if(b) {
2916 uSimple = CBOR_SIMPLEV_TRUE;
2917 }
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002918 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01002919}
2920
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002921static inline void
2922QCBOREncode_AddBoolToMap(QCBOREncodeContext *pMe, const char *szLabel, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01002923{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002924 QCBOREncode_AddSZString(pMe, szLabel);
2925 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01002926}
2927
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002928static inline void
2929QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pMe, int64_t nLabel, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01002930{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002931 QCBOREncode_AddInt64(pMe, nLabel);
2932 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01002933}
2934
2935
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002936static inline void
2937QCBOREncode_AddNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01002938{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002939 QCBOREncode_AddSimple(pMe, CBOR_SIMPLEV_NULL);
Michael Eckel5c531332020-03-02 01:35:30 +01002940}
2941
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002942static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002943QCBOREncode_AddNULLToMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002944{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002945 QCBOREncode_AddSZString(pMe, szLabel);
2946 QCBOREncode_AddNULL(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01002947}
2948
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002949static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002950QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002951{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002952 QCBOREncode_AddInt64(pMe, nLabel);
2953 QCBOREncode_AddNULL(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01002954}
2955
2956
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002957static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002958QCBOREncode_AddUndef(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01002959{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002960 QCBOREncode_AddSimple(pMe, CBOR_SIMPLEV_UNDEF);
Michael Eckel5c531332020-03-02 01:35:30 +01002961}
2962
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002963static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002964QCBOREncode_AddUndefToMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002965{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002966 QCBOREncode_AddSZString(pMe, szLabel);
2967 QCBOREncode_AddUndef(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01002968}
2969
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002970static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002971QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002972{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002973 QCBOREncode_AddInt64(pMe, nLabel);
2974 QCBOREncode_AddUndef(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01002975}
2976
2977
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002978static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002979QCBOREncode_OpenArray(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01002980{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002981 QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
Michael Eckel5c531332020-03-02 01:35:30 +01002982}
2983
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002984static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002985QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002986{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002987 QCBOREncode_AddSZString(pMe, szLabel);
2988 QCBOREncode_OpenArray(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01002989}
2990
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002991static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002992QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002993{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002994 QCBOREncode_AddInt64(pMe, nLabel);
2995 QCBOREncode_OpenArray(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01002996}
2997
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002998static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002999QCBOREncode_CloseArray(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003000{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003001 QCBOREncode_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
Michael Eckel5c531332020-03-02 01:35:30 +01003002}
3003
3004
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003005static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003006QCBOREncode_OpenMap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003007{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003008 QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
Michael Eckel5c531332020-03-02 01:35:30 +01003009}
3010
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003011static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003012QCBOREncode_OpenMapInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003013{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003014 QCBOREncode_AddSZString(pMe, szLabel);
3015 QCBOREncode_OpenMap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003016}
3017
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003018static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003019QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003020{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003021 QCBOREncode_AddInt64(pMe, nLabel);
3022 QCBOREncode_OpenMap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003023}
3024
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003025static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003026QCBOREncode_CloseMap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003027{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003028 QCBOREncode_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
Michael Eckel5c531332020-03-02 01:35:30 +01003029}
3030
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003031static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003032QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003033{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003034 QCBOREncode_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003035}
3036
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003037static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003038QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003039{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003040 QCBOREncode_AddSZString(pMe, szLabel);
3041 QCBOREncode_OpenArrayIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003042}
3043
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003044static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003045QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003046{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003047 QCBOREncode_AddInt64(pMe, nLabel);
3048 QCBOREncode_OpenArrayIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003049}
3050
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003051static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003052QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003053{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003054 QCBOREncode_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003055}
3056
3057
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003058static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003059QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003060{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003061 QCBOREncode_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003062}
3063
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003064static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003065QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003066{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003067 QCBOREncode_AddSZString(pMe, szLabel);
3068 QCBOREncode_OpenMapIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003069}
3070
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003071static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003072QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003073{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003074 QCBOREncode_AddInt64(pMe, nLabel);
3075 QCBOREncode_OpenMapIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003076}
3077
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003078static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003079QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003080{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003081 QCBOREncode_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003082}
3083
3084
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003085static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003086QCBOREncode_BstrWrap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003087{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003088 QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_BYTE_STRING);
Michael Eckel5c531332020-03-02 01:35:30 +01003089}
3090
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003091static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003092QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003093{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003094 QCBOREncode_AddSZString(pMe, szLabel);
3095 QCBOREncode_BstrWrap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003096}
3097
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003098static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003099QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003100{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003101 QCBOREncode_AddInt64(pMe, nLabel);
3102 QCBOREncode_BstrWrap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003103}
3104
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003105static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003106QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pMe, UsefulBufC *pWrappedCBOR)
Michael Eckel5c531332020-03-02 01:35:30 +01003107{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003108 QCBOREncode_CloseBstrWrap2(pMe, true, pWrappedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01003109}
3110
3111
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003112static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003113QCBOREncode_AddEncoded(QCBOREncodeContext *pMe, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003114{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003115 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_RAW, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003116}
3117
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003118static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003119QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003120{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003121 QCBOREncode_AddSZString(pMe, szLabel);
3122 QCBOREncode_AddEncoded(pMe, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003123}
3124
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003125static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003126QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003127{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003128 QCBOREncode_AddInt64(pMe, nLabel);
3129 QCBOREncode_AddEncoded(pMe, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003130}
3131
3132
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003133static inline int
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003134QCBOREncode_IsBufferNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003135{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003136 return UsefulOutBuf_IsBufferNULL(&(pMe->OutBuf));
Michael Eckel5c531332020-03-02 01:35:30 +01003137}
3138
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003139static inline QCBORError
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003140QCBOREncode_GetErrorState(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003141{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003142 if(UsefulOutBuf_GetError(&(pMe->OutBuf))) {
Michael Eckel5c531332020-03-02 01:35:30 +01003143 // Items didn't fit in the buffer.
3144 // This check catches this condition for all the appends and inserts
3145 // so checks aren't needed when the appends and inserts are performed.
3146 // And of course UsefulBuf will never overrun the input buffer given
3147 // to it. No complex analysis of the error handling in this file is
3148 // needed to know that is true. Just read the UsefulBuf code.
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003149 pMe->uError = QCBOR_ERR_BUFFER_TOO_SMALL;
Michael Eckel5c531332020-03-02 01:35:30 +01003150 // QCBOR_ERR_BUFFER_TOO_SMALL masks other errors, but that is
3151 // OK. Once the caller fixes this, they'll be unmasked.
3152 }
3153
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003154 return (QCBORError)pMe->uError;
Michael Eckel5c531332020-03-02 01:35:30 +01003155}
3156
3157
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003158/* ========================================================================
3159 END OF PRIVATE INLINE IMPLEMENTATION
3160 ======================================================================== */
Michael Eckel5c531332020-03-02 01:35:30 +01003161
3162#ifdef __cplusplus
3163}
3164#endif
3165
Laurence Lundblade844bb5c2020-03-01 17:27:25 -08003166#endif /* qcbor_encode_h */