blob: 9ac8dc26ca190fc1e54d4600442516d38f0ddfe8 [file] [log] [blame]
Michael Eckel5c531332020-03-02 01:35:30 +01001/*==============================================================================
2 Copyright (c) 2016-2018, The Linux Foundation.
3 Copyright (c) 2018-2020, Laurence Lundblade.
4 All rights reserved.
5
6Redistribution and use in source and binary forms, with or without
7modification, are permitted provided that the following conditions are
8met:
9 * Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above
12 copyright notice, this list of conditions and the following
13 disclaimer in the documentation and/or other materials provided
14 with the distribution.
15 * Neither the name of The Linux Foundation nor the names of its
16 contributors, nor the name "Laurence Lundblade" may be used to
17 endorse or promote products derived from this software without
18 specific prior written permission.
19
20THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
21WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
23ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
24BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
30IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 =============================================================================*/
32
33
Laurence Lundblade844bb5c2020-03-01 17:27:25 -080034#ifndef qcbor_encode_h
35#define qcbor_encode_h
Michael Eckel5c531332020-03-02 01:35:30 +010036
37
Laurence Lundblade844bb5c2020-03-01 17:27:25 -080038#include "qcbor/qcbor_common.h"
39#include "qcbor/qcbor_private.h"
Michael Eckel5c531332020-03-02 01:35:30 +010040#include <stdbool.h>
Laurence Lundblade844bb5c2020-03-01 17:27:25 -080041
Michael Eckel5c531332020-03-02 01:35:30 +010042
43#ifdef __cplusplus
44extern "C" {
Dave Thaler12b23752020-03-27 01:23:08 -070045#if 0
Michael Eckel5c531332020-03-02 01:35:30 +010046} // Keep editor indention formatting happy
47#endif
48#endif
49
Michael Eckel5c531332020-03-02 01:35:30 +010050
51/**
Laurence Lundblade844bb5c2020-03-01 17:27:25 -080052 @file qcbor_encode.h
Michael Eckel5c531332020-03-02 01:35:30 +010053
54 Q C B O R E n c o d e / D e c o d e
55
56 This implements CBOR -- Concise Binary Object Representation as
57 defined in [RFC 7049] (https://tools.ietf.org/html/rfc7049). More
58 info is at http://cbor.io. This is a near-complete implementation of
59 the specification. Limitations are listed further down.
60
61 CBOR is intentionally designed to be translatable to JSON, but not
62 all CBOR can convert to JSON. See RFC 7049 for more info on how to
63 construct CBOR that is the most JSON friendly.
64
65 The memory model for encoding and decoding is that encoded CBOR must
66 be in a contiguous buffer in memory. During encoding the caller must
67 supply an output buffer and if the encoding would go off the end of
68 the buffer an error is returned. During decoding the caller supplies
69 the encoded CBOR in a contiguous buffer and the decoder returns
70 pointers and lengths into that buffer for strings.
71
72 This implementation does not require malloc. All data structures
73 passed in/out of the APIs can fit on the stack.
74
75 Decoding of indefinite-length strings is a special case that requires
76 a "string allocator" to allocate memory into which the segments of
77 the string are coalesced. Without this, decoding will error out if an
78 indefinite-length string is encountered (indefinite-length maps and
79 arrays do not require the string allocator). A simple string
80 allocator called MemPool is built-in and will work if supplied with a
81 block of memory to allocate. The string allocator can optionally use
82 malloc() or some other custom scheme.
83
84 Here are some terms and definitions:
85
86 - "Item", "Data Item": An integer or string or such. The basic "thing" that
87 CBOR is about. An array is an item itself that contains some items.
88
89 - "Array": An ordered sequence of items, the same as JSON.
90
91 - "Map": A collection of label/value pairs. Each pair is a data
92 item. A JSON "object" is the same as a CBOR "map".
93
94 - "Label": The data item in a pair in a map that names or identifies
95 the pair, not the value. This implementation refers to it as a
96 "label". JSON refers to it as the "name". The CBOR RFC refers to it
97 this as a "key". This implementation chooses label instead because
98 key is too easily confused with a cryptographic key. The COSE
99 standard, which uses CBOR, has also chosen to use the term "label"
100 rather than "key" for this same reason.
101
102 - "Key": See "Label" above.
103
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700104 - "Tag": A data item that is an explicitly labeled new data
105 type made up of the tagging integer and the tag content.
106 See @Tags-Overview and @Tag-Usage.
Michael Eckel5c531332020-03-02 01:35:30 +0100107
108 - "Initial Byte": The first byte of an encoded item. Encoding and
109 decoding of this byte is taken care of by the implementation.
110
111 - "Additional Info": In addition to the major type, all data items
112 have some other info. This is usually the length of the data but can
113 be several other things. Encoding and decoding of this is taken care
114 of by the implementation.
115
116 CBOR has two mechanisms for tagging and labeling the data values like
117 integers and strings. For example, an integer that represents
118 someone's birthday in epoch seconds since Jan 1, 1970 could be
119 encoded like this:
120
121 - First it is CBOR_MAJOR_TYPE_POSITIVE_INT (@ref QCBOR_TYPE_INT64),
122 the primitive positive integer.
123
124 - Next it has a "tag" @ref CBOR_TAG_DATE_EPOCH indicating the integer
125 represents a date in the form of the number of seconds since Jan 1,
126 1970.
127
128 - Last it has a string "label" like "BirthDate" indicating the
129 meaning of the data.
130
131 The encoded binary looks like this:
132
133 a1 # Map of 1 item
134 69 # Indicates text string of 9 bytes
135 426972746844617465 # The text "BirthDate"
136 c1 # Tags next integer as epoch date
137 1a # Indicates a 4-byte integer
138 580d4172 # unsigned integer date 1477263730
139
140 Implementors using this API will primarily work with
141 labels. Generally, tags are only needed for making up new data
142 types. This implementation covers most of the data types defined in
143 the RFC using tags. It also, allows for the use of custom tags if
144 necessary.
145
146 This implementation explicitly supports labels that are text strings
147 and integers. Text strings translate nicely into JSON objects and are
148 very readable. Integer labels are much less readable but can be very
149 compact. If they are in the range of 0 to 23, they take up only one
150 byte.
151
152 CBOR allows a label to be any type of data including an array or a
153 map. It is possible to use this API to construct and parse such
154 labels, but it is not explicitly supported.
155
156 A common encoding usage mode is to invoke the encoding twice. First
157 with no output buffer to compute the length of the needed output
158 buffer. Then the correct sized output buffer is allocated. Last the
159 encoder is invoked again, this time with the output buffer.
160
161 The double invocation is not required if the maximum output buffer
162 size can be predicted. This is usually possible for simple CBOR
163 structures. If the double invocation is implemented, it can be in a
164 loop or function as in the example code so that the code doesn't have
165 to actually be written twice, saving code size.
166
167 If a buffer too small to hold the encoded output is given, the error
168 @ref QCBOR_ERR_BUFFER_TOO_SMALL will be returned. Data will never be
169 written off the end of the output buffer no matter which functions
170 here are called or what parameters are passed to them.
171
172 The encoding error handling is simple. The only possible errors are
173 trying to encode structures that are too large or too complex. There
174 are no internal malloc calls so there will be no failures for out of
175 memory. The error state is tracked internally, so there is no need
176 to check for errors when encoding. Only the return code from
177 QCBOREncode_Finish() need be checked as once an error happens, the
178 encoder goes into an error state and calls to it to add more data
179 will do nothing. An error check is not needed after every data item
180 is added.
181
182 Encoding generally proceeds by calling QCBOREncode_Init(), calling
183 lots of @c QCBOREncode_AddXxx() functions and calling
184 QCBOREncode_Finish(). There are many @c QCBOREncode_AddXxx()
185 functions for various data types. The input buffers need only to be
186 valid during the @c QCBOREncode_AddXxx() calls as the data is copied
187 into the output buffer.
188
189 There are three `Add` functions for each data type. The first / main
190 one for the type is for adding the data item to an array. The second
191 one's name ends in `ToMap`, is used for adding data items to maps and
192 takes a string argument that is its label in the map. The third one
193 ends in `ToMapN`, is also used for adding data items to maps, and
194 takes an integer argument that is its label in the map.
195
196 The simplest aggregate type is an array, which is a simple ordered
197 set of items without labels the same as JSON arrays. Call
198 QCBOREncode_OpenArray() to open a new array, then various @c
199 QCBOREncode_AddXxx() functions to put items in the array and then
200 QCBOREncode_CloseArray(). Nesting to the limit @ref
201 QCBOR_MAX_ARRAY_NESTING is allowed. All opens must be matched by
202 closes or an encoding error will be returned.
203
204 The other aggregate type is a map which does use labels. The `Add`
205 functions that end in `ToMap` and `ToMapN` are convenient ways to add
206 labeled data items to a map. You can also call any type of `Add`
207 function once to add a label of any time and then call any type of
208 `Add` again to add its value.
209
210 Note that when you nest arrays or maps in a map, the nested array or
211 map has a label.
Laurence Lundblade2feb1e12020-07-15 03:50:45 -0700212
Laurence Lundbladee3553422020-05-02 11:11:17 -0700213 Many CBOR-based protocols start with an array or map. This makes them
214 self-delimiting. No external length or end marker is needed to know
215 the end. It is also possible not start this way, in which case this
216 it is usually called a CBOR sequence which is described in [RFC 8742] (https://tools.ietf.org/html/rfc8742 ).
217 This encoder supports either just by whether the first item added is an
218 array, map or other.
Michael Eckel5c531332020-03-02 01:35:30 +0100219
220 @anchor Tags-Overview
Laurence Lundblade9b334962020-08-27 10:55:53 -0700221
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700222 Any CBOR data item can be made into a tag to add semantics, define a new data
Michael Eckel5c531332020-03-02 01:35:30 +0100223 type or such. Some tags are fully standardized and some are just
224 registered. Others are not registered and used in a proprietary way.
225
226 Encoding and decoding of many of the registered tags is fully
227 implemented by QCBOR. It is also possible to encode and decode tags
228 that are not directly supported. For many use cases the built-in tag
229 support should be adequate.
230
231 For example, the registered epoch date tag is supported in encoding
232 by QCBOREncode_AddDateEpoch() and in decoding by @ref
233 QCBOR_TYPE_DATE_EPOCH and the @c epochDate member of @ref
234 QCBORItem. This is typical of the built-in tag support. There is an
235 API to encode data for it and a @c QCBOR_TYPE_XXX when it is decoded.
236
237 Tags are registered in the [IANA CBOR Tags Registry]
238 (https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml). There
239 are roughly three options to create a new tag. First, a public
240 specification can be created and the new tag registered with IANA.
241 This is the most formal. Second, the new tag can be registered with
242 IANA with just a short description rather than a full specification.
243 These tags must be greater than 256. Third, a tag can be used without
244 any IANA registration, though the registry should be checked to see
245 that the new value doesn't collide with one that is registered. The
246 value of these tags must be 256 or larger.
247
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700248 See also @ref CBORTags and @ref Tag-Usage
249
Michael Eckel5c531332020-03-02 01:35:30 +0100250 The encoding side of tags not built-in is handled by
251 QCBOREncode_AddTag() and is relatively simple. Tag decoding is more
252 complex and mainly handled by QCBORDecode_GetNext(). Decoding of the
253 structure of tagged data not built-in (if there is any) has to be
254 implemented by the caller.
255
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700256 @anchor Floating-Point
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700257 By default QCBOR fully supports IEEE 754 floating-point:
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700258 - Encode/decode of double, single and half-precision
259 - CBOR preferred serialization of floating-point
260 - Floating-point epoch dates
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700261
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700262 For the most part, the type double is used in the interface for
263 floating-point values. In the default configuration, all decoded
264 floating-point values are returned as a double.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700265
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700266 With CBOR preferred serialization, the encoder outputs the smallest
267 representation of the double or float that preserves precision. Zero,
268 NaN and infinity are always output as a half-precision, each taking
269 just 2 bytes. This reduces the number of bytes needed to encode
Laurence Lundblade4b270642020-08-14 12:53:07 -0700270 double and single-precision, especially if zero, NaN and infinity are
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700271 frequently used.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700272
Laurence Lundblade4b270642020-08-14 12:53:07 -0700273 To avoid use of preferred serialization in the standard configuration
274 when encoding, use QCBOREncode_AddDoubleNoPreferred() or
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700275 QCBOREncode_AddFloatNoPreferred().
276
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700277 This implementation of preferred floating-point serialization and
278 half-precision does not depend on the CPU having floating-point HW or
279 the compiler bringing in a (sometimes large) library to compensate
Laurence Lundblade4b270642020-08-14 12:53:07 -0700280 for lack of CPU support. This implementation uses shifts and masks
281 rather than floating-point functions.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700282
Laurence Lundblade4b270642020-08-14 12:53:07 -0700283 To reduce overall object code by about 900 bytes, define
284 QCBOR_DISABLE_PREFERRED_FLOAT. This will eliminate all support for
285 preferred serialization and half-precision. An error will be returned
286 when attempting to decode half-precision. A float will always be
287 encoded and decoded as 32-bits and a double will always be encoded
288 and decoded as 64 bits.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700289
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700290 Note that even if QCBOR_DISABLE_PREFERRED_FLOAT is not defined all
291 the float-point encoding object code can be avoided by never calling
Laurence Lundbladefe09bbf2020-07-16 12:14:51 -0700292 any functions that encode double or float. Just not calling
293 floating-point functions will reduce object code by about 500 bytes.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700294
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700295 On CPUs that have no floating-point hardware,
296 QCBOR_DISABLE_FLOAT_HW_USE should be defined in most cases. If it is
297 not, then the compiler will bring in possibly large software
Laurence Lundblade4b270642020-08-14 12:53:07 -0700298 libraries to compensate. Defining
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700299 QCBOR_DISABLE_FLOAT_HW_USE reduces object code size on CPUs with
Laurence Lundblade4b270642020-08-14 12:53:07 -0700300 floating-point hardware by a tiny amount and eliminates the need for <math.h>
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700301
Laurence Lundblade4b270642020-08-14 12:53:07 -0700302 When QCBOR_DISABLE_FLOAT_HW_USE is defined, trying to decoding
303 floating-point dates will give error @ref
304 QCBOR_ERR_FLOAT_DATE_DISABLED and decoded single-precision numbers
305 will be returned as @ref QCBOR_TYPE_FLOAT instead of converting them
306 to double as usual.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700307
308 If both QCBOR_DISABLE_FLOAT_HW_USE and QCBOR_DISABLE_PREFERRED_FLOAT
Laurence Lundblade4b270642020-08-14 12:53:07 -0700309 are defined, then the only thing QCBOR can do is encode/decode a C
310 float type as 32-bits and a C double type as 64-bits. Floating-point
311 epoch dates will be unsupported.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700312
Michael Eckel5c531332020-03-02 01:35:30 +0100313 Summary Limits of this implementation:
314 - The entire encoded CBOR must fit into contiguous memory.
315 - Max size of encoded / decoded CBOR data is @c UINT32_MAX (4GB).
316 - Max array / map nesting level when encoding / decoding is
317 @ref QCBOR_MAX_ARRAY_NESTING (this is typically 15).
318 - Max items in an array or map when encoding / decoding is
319 @ref QCBOR_MAX_ITEMS_IN_ARRAY (typically 65,536).
320 - Does not directly support labels in maps other than text strings & integers.
321 - Does not directly support integer labels greater than @c INT64_MAX.
322 - Epoch dates limited to @c INT64_MAX (+/- 292 billion years).
323 - Exponents for bigfloats and decimal integers are limited to @c INT64_MAX.
324 - Tags on labels are ignored during decoding.
325 - There is no duplicate detection of map labels (but duplicates are passed on).
326 - Works only on 32- and 64-bit CPUs (modifications could make it work
327 on 16-bit CPUs).
328
329 The public interface uses @c size_t for all lengths. Internally the
330 implementation uses 32-bit lengths by design to use less memory and
331 fit structures on the stack. This limits the encoded CBOR it can work
332 with to size @c UINT32_MAX (4GB) which should be enough.
333
334 This implementation assumes two's compliment integer machines. @c
335 <stdint.h> also requires this. It is possible to modify this
336 implementation for another integer representation, but all modern
337 machines seem to be two's compliment.
338
339 */
340
341
Michael Eckel5c531332020-03-02 01:35:30 +0100342/*
343 The size of the buffer to be passed to QCBOREncode_EncodeHead(). It is one
344 byte larger than sizeof(uint64_t) + 1, the actual maximum size of the
345 head of a CBOR data item. because QCBOREncode_EncodeHead() needs
346 one extra byte to work.
347 */
348#define QCBOR_HEAD_BUFFER_SIZE (sizeof(uint64_t) + 2)
349
Michael Eckel5c531332020-03-02 01:35:30 +0100350
Laurence Lundblade9b334962020-08-27 10:55:53 -0700351/**
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700352 Output the full CBOR tag. See @ref CBORTags, @ref Tag-Usage and @ref Tags-Overview.
Laurence Lundblade9b334962020-08-27 10:55:53 -0700353 */
354#define QCBOR_ENCODE_AS_TAG 0
355
356/**
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700357 Output only the 'borrowed' content format for the relevant tag.
358 See @ref CBORTags, @ref Tag-Usage and @ref Tags-Overview.
Laurence Lundblade9b334962020-08-27 10:55:53 -0700359 */
360#define QCBOR_ENCODE_AS_BORROWED 1
361
Michael Eckel5c531332020-03-02 01:35:30 +0100362
363/**
364 QCBOREncodeContext is the data type that holds context for all the
365 encoding functions. It is less than 200 bytes, so it can go on the
366 stack. The contents are opaque, and the caller should not access
367 internal members. A context may be re used serially as long as it is
368 re initialized.
369 */
370typedef struct _QCBOREncodeContext QCBOREncodeContext;
371
372
373/**
374 Initialize the encoder to prepare to encode some CBOR.
375
376 @param[in,out] pCtx The encoder context to initialize.
377 @param[in] Storage The buffer into which this encoded result
378 will be placed.
379
380 Call this once at the start of an encoding of a CBOR structure. Then
381 call the various @c QCBOREncode_AddXxx() functions to add the data
382 items. Then call QCBOREncode_Finish().
383
384 The maximum output buffer is @c UINT32_MAX (4GB). This is not a
385 practical limit in any way and reduces the memory needed by the
386 implementation. The error @ref QCBOR_ERR_BUFFER_TOO_LARGE will be
387 returned by QCBOREncode_Finish() if a larger buffer length is passed
388 in.
389
390 If this is called with @c Storage.ptr as @c NULL and @c Storage.len a
391 large value like @c UINT32_MAX, all the QCBOREncode_AddXxx()
392 functions and QCBOREncode_Finish() can still be called. No data will
393 be encoded, but the length of what would be encoded will be
394 calculated. The length of the encoded structure will be handed back
395 in the call to QCBOREncode_Finish(). You can then allocate a buffer
396 of that size and call all the encoding again, this time to fill in
397 the buffer.
398
399 A @ref QCBOREncodeContext can be reused over and over as long as
400 QCBOREncode_Init() is called.
401 */
402void QCBOREncode_Init(QCBOREncodeContext *pCtx, UsefulBuf Storage);
403
404
405/**
406 @brief Add a signed 64-bit integer to the encoded output.
407
408 @param[in] pCtx The encoding context to add the integer to.
409 @param[in] nNum The integer to add.
410
411 The integer will be encoded and added to the CBOR output.
412
413 This function figures out the size and the sign and encodes in the
414 correct minimal CBOR. Specifically, it will select CBOR major type 0
415 or 1 based on sign and will encode to 1, 2, 4 or 8 bytes depending on
416 the value of the integer. Values less than 24 effectively encode to
417 one byte because they are encoded in with the CBOR major type. This
418 is a neat and efficient characteristic of CBOR that can be taken
419 advantage of when designing CBOR-based protocols. If integers like
420 tags can be kept between -23 and 23 they will be encoded in one byte
421 including the major type.
422
423 If you pass a smaller int, say an @c int16_t or a small value, say
424 100, the encoding will still be CBOR's most compact that can
425 represent the value. For example, CBOR always encodes the value 0 as
426 one byte, 0x00. The representation as 0x00 includes identification of
427 the type as an integer too as the major type for an integer is 0. See
428 [RFC 7049] (https://tools.ietf.org/html/rfc7049) Appendix A for more
429 examples of CBOR encoding. This compact encoding is also canonical
430 CBOR as per section 3.9 in RFC 7049.
431
432 There are no functions to add @c int16_t or @c int32_t because they
433 are not necessary because this always encodes to the smallest number
434 of bytes based on the value (If this code is running on a 32-bit
435 machine having a way to add 32-bit integers would reduce code size
436 some).
437
438 If the encoding context is in an error state, this will do
439 nothing. If an error occurs when adding this integer, the internal
440 error flag will be set, and the error will be returned when
441 QCBOREncode_Finish() is called.
442
443 See also QCBOREncode_AddUInt64().
444 */
445void QCBOREncode_AddInt64(QCBOREncodeContext *pCtx, int64_t nNum);
446
447static void QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum);
448
449static void QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum);
450
451
452/**
453 @brief Add an unsigned 64-bit integer to the encoded output.
454
455 @param[in] pCtx The encoding context to add the integer to.
456 @param[in] uNum The integer to add.
457
458 The integer will be encoded and added to the CBOR output.
459
460 The only reason so use this function is for integers larger than @c
461 INT64_MAX and smaller than @c UINT64_MAX. Otherwise
462 QCBOREncode_AddInt64() will work fine.
463
464 Error handling is the same as for QCBOREncode_AddInt64().
465 */
466void QCBOREncode_AddUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
467
468static void QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum);
469
470static void QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum);
471
472
473/**
474 @brief Add a UTF-8 text string to the encoded output.
475
476 @param[in] pCtx The encoding context to add the text to.
477 @param[in] Text Pointer and length of text to add.
478
479 The text passed in must be unencoded UTF-8 according to [RFC 3629]
480 (https://tools.ietf.org/html/rfc3629). There is no NULL
481 termination. The text is added as CBOR major type 3.
482
483 If called with @c nBytesLen equal to 0, an empty string will be
484 added. When @c nBytesLen is 0, @c pBytes may be @c NULL.
485
486 Note that the restriction of the buffer length to a @c uint32_t is
487 entirely intentional as this encoder is not capable of encoding
488 lengths greater. This limit to 4GB for a text string should not be a
489 problem.
490
491 Error handling is the same as QCBOREncode_AddInt64().
492 */
493static void QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text);
494
495static void QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text);
496
497static void QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text);
498
499
500/**
501 @brief Add a UTF-8 text string to the encoded output.
502
503 @param[in] pCtx The encoding context to add the text to.
504 @param[in] szString Null-terminated text to add.
505
506 This works the same as QCBOREncode_AddText().
507 */
508static void QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString);
509
510static void QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString);
511
512static void QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString);
513
514
515/**
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700516 @brief Add a double-precision floating-point number to the encoded output.
Michael Eckel5c531332020-03-02 01:35:30 +0100517
518 @param[in] pCtx The encoding context to add the double to.
519 @param[in] dNum The double-precision number to add.
520
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700521 This encodes and outputs a floating-point number. CBOR major type 7
522 is used.
Michael Eckel5c531332020-03-02 01:35:30 +0100523
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700524 This implements preferred serialization, selectively encoding the
525 double-precision floating-point number as either double-precision,
526 single-precision or half-precision. Infinity, NaN and 0 are always
527 encoded as half-precision. If no precision will be lost in the
528 conversion to half-precision, then it will be converted and
529 encoded. If not and no precision will be lost in conversion to
530 single-precision, then it will be converted and encoded. If not, then
531 no conversion is performed, and it encoded as a double-precision.
Michael Eckel5c531332020-03-02 01:35:30 +0100532
533 Half-precision floating-point numbers take up 2 bytes, half that of
534 single-precision, one quarter of double-precision
535
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700536 This automatically reduces the size of encoded CBOR, maybe even by
537 four if most of values are 0, infinity or NaN.
Michael Eckel5c531332020-03-02 01:35:30 +0100538
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700539 When decoded, QCBOR will usually return these values as
540 double-precision.
541
542 It is possible to disable this preferred serialization when compiling
543 QCBOR. In that case, this functions the same as
544 QCBOREncode_AddDoubleNoPreferred().
Michael Eckel5c531332020-03-02 01:35:30 +0100545
546 Error handling is the same as QCBOREncode_AddInt64().
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700547
548 See also QCBOREncode_AddDoubleNoPreferred(), QCBOREncode_AddFloat()
549 and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
Michael Eckel5c531332020-03-02 01:35:30 +0100550 */
551void QCBOREncode_AddDouble(QCBOREncodeContext *pCtx, double dNum);
552
553static void QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
554
555static void QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
556
557
558/**
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700559 @brief Add a single-precision floating-point number to the encoded output.
560
561 @param[in] pCtx The encoding context to add the double to.
562 @param[in] fNum The single-precision number to add.
563
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700564 This is identical to QCBOREncode_AddDouble() except the input is
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700565 single-precision.
566
567 See also QCBOREncode_AddDouble(), QCBOREncode_AddDoubleNoPreferred(),
568 and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
569*/
570void QCBOREncode_AddFloat(QCBOREncodeContext *pCtx, float fNum);
571
572static void QCBOREncode_AddFloatToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
573
574static void QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700575
576
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700577/**
578 @brief Add a double-precision floating-point number without preferred encoding.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700579
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700580 @param[in] pCtx The encoding context to add the double to.
581 @param[in] dNum The double-precision number to add.
582
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700583 This always outputs the number as a 64-bit double-precision.
584 Preferred serialization is not used.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700585
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700586 Error handling is the same as QCBOREncode_AddInt64().
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700587
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700588 See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
589 QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700590*/
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700591void QCBOREncode_AddDoubleNoPreferred(QCBOREncodeContext *pCtx, double dNum);
592
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700593static void QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
594
595static void QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
596
597
598/**
599 @brief Add a single-precision floating-point number without preferred encoding.
600
601 @param[in] pCtx The encoding context to add the double to.
602 @param[in] fNum The single-precision number to add.
603
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700604 This always outputs the number as a 32-bit single-precision.
605 Preferred serialization is not used.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700606
607 Error handling is the same as QCBOREncode_AddInt64().
608
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700609 See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
610 QCBOREncode_AddDoubleNoPreferred() and @ref Floating-Point.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700611*/
612void QCBOREncode_AddFloatNoPreferred(QCBOREncodeContext *pCtx, float fNum);
613
614static void QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
615
616static void QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float fNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700617
618
Michael Eckel5c531332020-03-02 01:35:30 +0100619
620/**
621 @brief Add an optional tag.
622
623 @param[in] pCtx The encoding context to add the tag to.
624 @param[in] uTag The tag to add
625
626 This outputs a CBOR major type 6 item that tags the next data item
627 that is output usually to indicate it is some new data type.
628
629 For many of the common standard tags, a function to encode data using
630 it is provided and this is not needed. For example,
631 QCBOREncode_AddDateEpoch() already exists to output integers
632 representing dates with the right tag.
633
634 The tag is applied to the next data item added to the encoded
635 output. That data item that is to be tagged can be of any major CBOR
636 type. Any number of tags can be added to a data item by calling this
637 multiple times before the data item is added.
638
639 See @ref Tags-Overview for discussion of creating new non-standard
640 tags. See QCBORDecode_GetNext() for discussion of decoding custom
641 tags.
642*/
643void QCBOREncode_AddTag(QCBOREncodeContext *pCtx,uint64_t uTag);
644
645
646/**
647 @brief Add an epoch-based date.
648
649 @param[in] pCtx The encoding context to add the date to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700650 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100651 @param[in] date Number of seconds since 1970-01-01T00:00Z in UTC time.
652
653 As per RFC 7049 this is similar to UNIX/Linux/POSIX dates. This is
654 the most compact way to specify a date and time in CBOR. Note that
655 this is always UTC and does not include the time zone. Use
656 QCBOREncode_AddDateString() if you want to include the time zone.
657
658 The integer encoding rules apply here so the date will be encoded in
659 a minimal number of bytes. Until about the year 2106 these dates will
660 encode in 6 bytes -- one byte for the tag, one byte for the type and
661 4 bytes for the integer. After that it will encode to 10 bytes.
662
663 Negative values are supported for dates before 1970.
664
665 If you care about leap-seconds and that level of accuracy, make sure
666 the system you are running this code on does it correctly. This code
667 just takes the value passed in.
668
669 This implementation cannot encode fractional seconds using float or
670 double even though that is allowed by CBOR, but you can encode them
671 if you want to by calling QCBOREncode_AddDouble() and
672 QCBOREncode_AddTag().
673
674 Error handling is the same as QCBOREncode_AddInt64().
675 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700676static void QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pCtx,
677 uint8_t uTagRequirement,
678 int64_t date);
Laurence Lundblade9b334962020-08-27 10:55:53 -0700679
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700680static void QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pCtx,
681 const char *szLabel,
682 uint8_t uTagRequirement,
683 int64_t date);
Laurence Lundblade9b334962020-08-27 10:55:53 -0700684
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700685static void QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pCtx,
686 int64_t nLabel,
687 uint8_t uTagRequirement,
688 int64_t date);
Laurence Lundblade9b334962020-08-27 10:55:53 -0700689
690
Michael Eckel5c531332020-03-02 01:35:30 +0100691static void QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx, int64_t date);
692
693static void QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t date);
694
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700695static void QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t date);
Michael Eckel5c531332020-03-02 01:35:30 +0100696
697
698/**
699 @brief Add a byte string to the encoded output.
700
701 @param[in] pCtx The encoding context to add the bytes to.
702 @param[in] Bytes Pointer and length of the input data.
703
704 Simply adds the bytes to the encoded output as CBOR major type 2.
705
706 If called with @c Bytes.len equal to 0, an empty string will be
707 added. When @c Bytes.len is 0, @c Bytes.ptr may be @c NULL.
708
709 Error handling is the same as QCBOREncode_AddInt64().
710 */
711static void QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
712
713static void QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
714
715static void QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
716
717
718
719/**
720 @brief Add a binary UUID to the encoded output.
721
722 @param[in] pCtx The encoding context to add the UUID to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700723 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100724 @param[in] Bytes Pointer and length of the binary UUID.
725
726 A binary UUID as defined in [RFC 4122]
727 (https://tools.ietf.org/html/rfc4122) is added to the output.
728
729 It is output as CBOR major type 2, a binary string, with tag @ref
730 CBOR_TAG_BIN_UUID indicating the binary string is a UUID.
731 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700732static void QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pCtx,
733 uint8_t uTagRequirement,
734 UsefulBufC Bytes);
735
736static void QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pCtx,
737 const char *szLabel,
738 uint8_t uTagRequirement,
739 UsefulBufC Bytes);
740
741static void QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pCtx,
742 int64_t nLabel,
743 uint8_t uTagRequirement,
744 UsefulBufC Bytes);
745
746
Michael Eckel5c531332020-03-02 01:35:30 +0100747static void QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
748
749static void QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
750
751static void QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
752
753
754/**
755 @brief Add a positive big number to the encoded output.
756
757 @param[in] pCtx The encoding context to add the big number to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700758 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100759 @param[in] Bytes Pointer and length of the big number.
760
761 Big numbers are integers larger than 64-bits. Their format is
762 described in [RFC 7049] (https://tools.ietf.org/html/rfc7049).
763
764 It is output as CBOR major type 2, a binary string, with tag @ref
765 CBOR_TAG_POS_BIGNUM indicating the binary string is a positive big
766 number.
767
768 Often big numbers are used to represent cryptographic keys, however,
769 COSE which defines representations for keys chose not to use this
770 particular type.
771 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700772static void QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pCtx,
773 uint8_t uTagRequirement,
774 UsefulBufC Bytes);
775
776static void QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pCtx,
777 const char *szLabel,
778 uint8_t uTagRequirement,
779 UsefulBufC Bytes);
780
781static void QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pCtx,
782 int64_t nLabel,
783 uint8_t uTagRequirement,
784 UsefulBufC Bytes);
785
786
Michael Eckel5c531332020-03-02 01:35:30 +0100787static void QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
788
789static void QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
790
791static void QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
792
793
794/**
795 @brief Add a negative big number to the encoded output.
796
797 @param[in] pCtx The encoding context to add the big number to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700798 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100799 @param[in] Bytes Pointer and length of the big number.
800
801 Big numbers are integers larger than 64-bits. Their format is
802 described in [RFC 7049] (https://tools.ietf.org/html/rfc7049).
803
804 It is output as CBOR major type 2, a binary string, with tag @ref
805 CBOR_TAG_NEG_BIGNUM indicating the binary string is a negative big
806 number.
807
808 Often big numbers are used to represent cryptographic keys, however,
809 COSE which defines representations for keys chose not to use this
810 particular type.
811 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700812static void QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pCtx,
813 uint8_t uTagRequirement,
814 UsefulBufC Bytes);
815
816static void QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pCtx,
817 const char *szLabel,
818 uint8_t uTagRequirement,
819 UsefulBufC Bytes);
820
821static void QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pCtx,
822 int64_t nLabel,
823 uint8_t uTagRequirement,
824 UsefulBufC Bytes);
825
826
Michael Eckel5c531332020-03-02 01:35:30 +0100827static void QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
828
829static void QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
830
831static void QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
832
833
834#ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
835/**
836 @brief Add a decimal fraction to the encoded output.
837
838 @param[in] pCtx The encoding context to add the decimal fraction to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700839 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100840 @param[in] nMantissa The mantissa.
841 @param[in] nBase10Exponent The exponent.
842
843 The value is nMantissa * 10 ^ nBase10Exponent.
844
845 A decimal fraction is good for exact representation of some values
846 that can't be represented exactly with standard C (IEEE 754)
847 floating-point numbers. Much larger and much smaller numbers can
848 also be represented than floating-point because of the larger number
849 of bits in the exponent.
850
851 The decimal fraction is conveyed as two integers, a mantissa and a
852 base-10 scaling factor.
853
854 For example, 273.15 is represented by the two integers 27315 and -2.
855
856 The exponent and mantissa have the range from @c INT64_MIN to
857 @c INT64_MAX for both encoding and decoding (CBOR allows @c -UINT64_MAX
858 to @c UINT64_MAX, but this implementation doesn't support this range to
859 reduce code size and interface complexity a little).
860
861 CBOR Preferred encoding of the integers is used, thus they will be encoded
862 in the smallest number of bytes possible.
863
864 See also QCBOREncode_AddDecimalFractionBigNum() for a decimal
865 fraction with arbitrarily large precision and QCBOREncode_AddBigFloat().
866
867 There is no representation of positive or negative infinity or NaN
868 (Not a Number). Use QCBOREncode_AddDouble() to encode them.
869
870 See @ref expAndMantissa for decoded representation.
871 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700872static void QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pCtx,
873 uint8_t uTagRequirement,
874 int64_t nMantissa,
875 int64_t nBase10Exponent);
876
877static void QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pCtx,
878 const char *szLabel,
879 uint8_t uTagRequirement,
880 int64_t nMantissa,
881 int64_t nBase10Exponent);
882
883static void QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pCtx,
884 int64_t nLabel,
885 uint8_t uTagRequirement,
886 int64_t nMantissa,
887 int64_t nBase10Exponent);
888
889
Michael Eckel5c531332020-03-02 01:35:30 +0100890static void QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pCtx,
891 int64_t nMantissa,
892 int64_t nBase10Exponent);
893
894static void QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pCtx,
895 const char *szLabel,
896 int64_t nMantissa,
897 int64_t nBase10Exponent);
898
899static void QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pCtx,
900 int64_t nLabel,
901 int64_t nMantissa,
902 int64_t nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +0100903/**
904 @brief Add a decimal fraction with a big number mantissa to the encoded output.
905
906 @param[in] pCtx The encoding context to add the decimal fraction to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700907 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100908 @param[in] Mantissa The mantissa.
909 @param[in] bIsNegative false if mantissa is positive, true if negative.
910 @param[in] nBase10Exponent The exponent.
911
912 This is the same as QCBOREncode_AddDecimalFraction() except the
913 mantissa is a big number (See QCBOREncode_AddPositiveBignum())
914 allowing for arbitrarily large precision.
915
916 See @ref expAndMantissa for decoded representation.
917 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700918static void QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pCtx,
919 uint8_t uTagRequirement,
920 UsefulBufC Mantissa,
921 bool bIsNegative,
922 int64_t nBase10Exponent);
923
924static void QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
925 const char *szLabel,
926 uint8_t uTagRequirement,
927 UsefulBufC Mantissa,
928 bool bIsNegative,
929 int64_t nBase10Exponent);
930
931static void QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
932 int64_t nLabel,
933 uint8_t uTagRequirement,
934 UsefulBufC Mantissa,
935 bool bIsNegative,
936 int64_t nBase10Exponent);
937
938
Michael Eckel5c531332020-03-02 01:35:30 +0100939static void QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pCtx,
940 UsefulBufC Mantissa,
941 bool bIsNegative,
942 int64_t nBase10Exponent);
943
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700944static void QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
Michael Eckel5c531332020-03-02 01:35:30 +0100945 const char *szLabel,
946 UsefulBufC Mantissa,
947 bool bIsNegative,
948 int64_t nBase10Exponent);
949
950static void QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
951 int64_t nLabel,
952 UsefulBufC Mantissa,
953 bool bIsNegative,
954 int64_t nBase10Exponent);
955
956/**
957 @brief Add a big floating-point number to the encoded output.
958
959 @param[in] pCtx The encoding context to add the bigfloat to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700960 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100961 @param[in] nMantissa The mantissa.
962 @param[in] nBase2Exponent The exponent.
963
964 The value is nMantissa * 2 ^ nBase2Exponent.
965
966 "Bigfloats", as CBOR terms them, are similar to IEEE floating-point
967 numbers in having a mantissa and base-2 exponent, but they are not
968 supported by hardware or encoded the same. They explicitly use two
969 CBOR-encoded integers to convey the mantissa and exponent, each of which
970 can be 8, 16, 32 or 64 bits. With both the mantissa and exponent
971 64 bits they can express more precision and a larger range than an
972 IEEE double floating-point number. See
973 QCBOREncode_AddBigFloatBigNum() for even more precision.
974
975 For example, 1.5 would be represented by a mantissa of 3 and an
976 exponent of -1.
977
978 The exponent and mantissa have the range from @c INT64_MIN to
979 @c INT64_MAX for both encoding and decoding (CBOR allows @c -UINT64_MAX
980 to @c UINT64_MAX, but this implementation doesn't support this range to
981 reduce code size and interface complexity a little).
982
983 CBOR Preferred encoding of the integers is used, thus they will be encoded
984 in the smallest number of bytes possible.
985
986 This can also be used to represent floating-point numbers in
987 environments that don't support IEEE 754.
988
989 See @ref expAndMantissa for decoded representation.
990 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700991static void QCBOREncode_AddTBigFloat(QCBOREncodeContext *pCtx,
992 uint8_t uTagRequirement,
993 int64_t nMantissa,
994 int64_t nBase2Exponent);
995
996static void QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pCtx,
997 const char *szLabel,
998 uint8_t uTagRequirement,
999 int64_t nMantissa,
1000 int64_t nBase2Exponent);
1001
1002static void QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pCtx,
1003 int64_t nLabel,
1004 uint8_t uTagRequirement,
1005 int64_t nMantissa,
1006 int64_t nBase2Exponent);
1007
1008
Michael Eckel5c531332020-03-02 01:35:30 +01001009static void QCBOREncode_AddBigFloat(QCBOREncodeContext *pCtx,
1010 int64_t nMantissa,
1011 int64_t nBase2Exponent);
1012
1013static void QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pCtx,
1014 const char *szLabel,
1015 int64_t nMantissa,
1016 int64_t nBase2Exponent);
1017
1018static void QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pCtx,
1019 int64_t nLabel,
1020 int64_t nMantissa,
1021 int64_t nBase2Exponent);
1022
Michael Eckel5c531332020-03-02 01:35:30 +01001023/**
1024 @brief Add a big floating-point number with a big number mantissa to
1025 the encoded output.
1026
1027 @param[in] pCtx The encoding context to add the bigfloat to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001028 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001029 @param[in] Mantissa The mantissa.
1030 @param[in] bIsNegative false if mantissa is positive, true if negative.
1031 @param[in] nBase2Exponent The exponent.
1032
1033 This is the same as QCBOREncode_AddBigFloat() except the mantissa is
1034 a big number (See QCBOREncode_AddPositiveBignum()) allowing for
1035 arbitrary precision.
1036
1037 See @ref expAndMantissa for decoded representation.
1038 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001039static void QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pCtx,
1040 uint8_t uTagRequirement,
1041 UsefulBufC Mantissa,
1042 bool bIsNegative,
1043 int64_t nBase2Exponent);
1044
1045static void QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pCtx,
1046 const char *szLabel,
1047 uint8_t uTagRequirement,
1048 UsefulBufC Mantissa,
1049 bool bIsNegative,
1050 int64_t nBase2Exponent);
1051
1052static void QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1053 int64_t nLabel,
1054 uint8_t uTagRequirement,
1055 UsefulBufC Mantissa,
1056 bool bIsNegative,
1057 int64_t nBase2Exponent);
1058
1059
Michael Eckel5c531332020-03-02 01:35:30 +01001060static void QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pCtx,
1061 UsefulBufC Mantissa,
1062 bool bIsNegative,
1063 int64_t nBase2Exponent);
1064
1065static void QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pCtx,
1066 const char *szLabel,
1067 UsefulBufC Mantissa,
1068 bool bIsNegative,
1069 int64_t nBase2Exponent);
1070
1071static void QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1072 int64_t nLabel,
1073 UsefulBufC Mantissa,
1074 bool bIsNegative,
1075 int64_t nBase2Exponent);
1076#endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
1077
1078
1079/**
1080 @brief Add a text URI to the encoded output.
1081
1082 @param[in] pCtx The encoding context to add the URI to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001083 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001084 @param[in] URI Pointer and length of the URI.
1085
1086 The format of URI must be per [RFC 3986]
1087 (https://tools.ietf.org/html/rfc3986).
1088
1089 It is output as CBOR major type 3, a text string, with tag @ref
1090 CBOR_TAG_URI indicating the text string is a URI.
1091
1092 A URI in a NULL-terminated string, @c szURI, can be easily added with
1093 this code:
1094
1095 QCBOREncode_AddURI(pCtx, UsefulBuf_FromSZ(szURI));
1096 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001097static void QCBOREncode_AddTURI(QCBOREncodeContext *pCtx,
1098 uint8_t uTagRequirement,
1099 UsefulBufC URI);
1100
1101static void QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pCtx,
1102 const char *szLabel,
1103 uint8_t uTagRequirement,
1104 UsefulBufC URI);
1105
1106static void QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pCtx,
1107 int64_t nLabel,
1108 uint8_t uTagRequirement,
1109 UsefulBufC URI);
1110
1111
Michael Eckel5c531332020-03-02 01:35:30 +01001112static void QCBOREncode_AddURI(QCBOREncodeContext *pCtx, UsefulBufC URI);
1113
1114static void QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC URI);
1115
1116static void QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC URI);
1117
1118
1119/**
1120 @brief Add Base64-encoded text to encoded output.
1121
1122 @param[in] pCtx The encoding context to add the base-64 text to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001123 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001124 @param[in] B64Text Pointer and length of the base-64 encoded text.
1125
1126 The text content is Base64 encoded data per [RFC 4648]
1127 (https://tools.ietf.org/html/rfc4648).
1128
1129 It is output as CBOR major type 3, a text string, with tag @ref
1130 CBOR_TAG_B64 indicating the text string is Base64 encoded.
1131 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001132static void QCBOREncode_AddTB64Text(QCBOREncodeContext *pCtx,
1133 uint8_t uTagRequirement,
1134 UsefulBufC B64Text);
1135
1136static void QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pCtx,
1137 const char *szLabel,
1138 uint8_t uTagRequirement,
1139 UsefulBufC B64Text);
1140
1141static void QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pCtx,
1142 int64_t nLabel,
1143 uint8_t uTagRequirement,
1144 UsefulBufC B64Text);
1145
1146
Michael Eckel5c531332020-03-02 01:35:30 +01001147static void QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx, UsefulBufC B64Text);
1148
1149static void QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text);
1150
1151static void QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text);
1152
1153
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001154
Michael Eckel5c531332020-03-02 01:35:30 +01001155/**
1156 @brief Add base64url encoded data to encoded output.
1157
1158 @param[in] pCtx The encoding context to add the base64url to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001159 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001160 @param[in] B64Text Pointer and length of the base64url encoded text.
1161
1162 The text content is base64URL encoded text as per [RFC 4648]
1163 (https://tools.ietf.org/html/rfc4648).
1164
1165 It is output as CBOR major type 3, a text string, with tag @ref
1166 CBOR_TAG_B64URL indicating the text string is a Base64url encoded.
1167 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001168static void QCBOREncode_AddTB64URLText(QCBOREncodeContext *pCtx,
1169 uint8_t uTagRequirement,
1170 UsefulBufC B64Text);
1171
1172static void QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pCtx,
1173 const char *szLabel,
1174 uint8_t uTagRequirement,
1175 UsefulBufC B64Text);
1176
1177static void QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pCtx,
1178 int64_t nLabel,
1179 uint8_t uTagRequirement,
1180 UsefulBufC B64Text);
1181
1182
Michael Eckel5c531332020-03-02 01:35:30 +01001183static void QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx, UsefulBufC B64Text);
1184
1185static void QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text);
1186
1187static void QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text);
1188
1189
1190/**
1191 @brief Add Perl Compatible Regular Expression.
1192
1193 @param[in] pCtx The encoding context to add the regular expression to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001194 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001195 @param[in] Regex Pointer and length of the regular expression.
1196
1197 The text content is Perl Compatible Regular
1198 Expressions (PCRE) / JavaScript syntax [ECMA262].
1199
1200 It is output as CBOR major type 3, a text string, with tag @ref
1201 CBOR_TAG_REGEX indicating the text string is a regular expression.
1202 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001203static void QCBOREncode_AddTRegex(QCBOREncodeContext *pCtx,
1204 uint8_t uTagRequirement,
1205 UsefulBufC Regex);
1206
1207static void QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pCtx,
1208 const char *szLabel,
1209 uint8_t uTagRequirement,
1210 UsefulBufC Regex);
1211
1212static void QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pCtx,
1213 int64_t nLabel,
1214 uint8_t uTagRequirement,
1215 UsefulBufC Regex);
1216
1217
Michael Eckel5c531332020-03-02 01:35:30 +01001218static void QCBOREncode_AddRegex(QCBOREncodeContext *pCtx, UsefulBufC Regex);
1219
1220static void QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Regex);
1221
1222static void QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Regex);
1223
1224
1225/**
1226 @brief MIME encoded text to the encoded output.
1227
1228 @param[in] pCtx The encoding context to add the MIME data to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001229 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001230 @param[in] MIMEData Pointer and length of the regular expression.
1231
1232 The text content is in MIME format per [RFC 2045]
1233 (https://tools.ietf.org/html/rfc2045) including the headers. Note
1234 that this only supports text-format MIME. Binary MIME is not
1235 supported.
1236
1237 It is output as CBOR major type 3, a text string, with tag
1238 @ref CBOR_TAG_MIME indicating the text string is MIME data.
1239 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001240static void QCBOREncode_AddTMIMEData(QCBOREncodeContext *pCtx,
1241 uint8_t uTagRequirement,
1242 UsefulBufC MIMEData);
1243
1244static void QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pCtx,
1245 const char *szLabel,
1246 uint8_t uTagRequirement,
1247 UsefulBufC MIMEData);
1248
1249static void QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pCtx,
1250 int64_t nLabel,
1251 uint8_t uTagRequirement,
1252 UsefulBufC MIMEData);
1253
1254
Michael Eckel5c531332020-03-02 01:35:30 +01001255static void QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx, UsefulBufC MIMEData);
1256
1257static void QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC MIMEData);
1258
1259static void QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC MIMEData);
1260
1261
1262/**
1263 @brief Add an RFC 3339 date string
1264
1265 @param[in] pCtx The encoding context to add the date to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001266 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001267 @param[in] szDate Null-terminated string with date to add.
1268
1269 The string szDate should be in the form of [RFC 3339]
1270 (https://tools.ietf.org/html/rfc3339) as defined by section 3.3 in
1271 [RFC 4287] (https://tools.ietf.org/html/rfc4287). This is as
1272 described in section 2.4.1 in [RFC 7049]
1273 (https://tools.ietf.org/html/rfc7049).
1274
1275 Note that this function doesn't validate the format of the date string
1276 at all. If you add an incorrect format date string, the generated
1277 CBOR will be incorrect and the receiver may not be able to handle it.
1278
1279 Error handling is the same as QCBOREncode_AddInt64().
1280 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001281static void QCBOREncode_AddTDateString(QCBOREncodeContext *pCtx,
1282 uint8_t uTagRequirement,
1283 const char *szDate);
1284
1285static void QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pCtx,
1286 const char *szLabel,
1287 uint8_t uTagRequirement,
1288 const char *szDate);
1289
1290static void QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pCtx,
1291 int64_t nLabel,
1292 uint8_t uTagRequirement,
1293 const char *szDate);
1294
1295
Michael Eckel5c531332020-03-02 01:35:30 +01001296static void QCBOREncode_AddDateString(QCBOREncodeContext *pCtx, const char *szDate);
1297
1298static void QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szDate);
1299
1300static void QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szDate);
1301
Michael Eckel5c531332020-03-02 01:35:30 +01001302/**
1303 @brief Add a standard Boolean.
1304
1305 @param[in] pCtx The encoding context to add the Boolean to.
1306 @param[in] b true or false from @c <stdbool.h>.
1307
1308 Adds a Boolean value as CBOR major type 7.
1309
1310 Error handling is the same as QCBOREncode_AddInt64().
1311 */
1312static void QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b);
1313
1314static void QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b);
1315
1316static void QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b);
1317
1318
1319
1320/**
1321 @brief Add a NULL to the encoded output.
1322
1323 @param[in] pCtx The encoding context to add the NULL to.
1324
1325 Adds the NULL value as CBOR major type 7.
1326
1327 This NULL doesn't have any special meaning in CBOR such as a
1328 terminating value for a string or an empty value.
1329
1330 Error handling is the same as QCBOREncode_AddInt64().
1331 */
1332static void QCBOREncode_AddNULL(QCBOREncodeContext *pCtx);
1333
1334static void QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1335
1336static void QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1337
1338
1339/**
1340 @brief Add an "undef" to the encoded output.
1341
1342 @param[in] pCtx The encoding context to add the "undef" to.
1343
1344 Adds the undef value as CBOR major type 7.
1345
1346 Note that this value will not translate to JSON.
1347
1348 This Undef doesn't have any special meaning in CBOR such as a
1349 terminating value for a string or an empty value.
1350
1351 Error handling is the same as QCBOREncode_AddInt64().
1352 */
1353static void QCBOREncode_AddUndef(QCBOREncodeContext *pCtx);
1354
1355static void QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1356
1357static void QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1358
1359
1360/**
1361 @brief Indicates that the next items added are in an array.
1362
1363 @param[in] pCtx The encoding context to open the array in.
1364
1365 Arrays are the basic CBOR aggregate or structure type. Call this
1366 function to start or open an array. Then call the various @c
1367 QCBOREncode_AddXxx() functions to add the items that go into the
1368 array. Then call QCBOREncode_CloseArray() when all items have been
1369 added. The data items in the array can be of any type and can be of
1370 mixed types.
1371
1372 Nesting of arrays and maps is allowed and supported just by calling
1373 QCBOREncode_OpenArray() again before calling
1374 QCBOREncode_CloseArray(). While CBOR has no limit on nesting, this
1375 implementation does in order to keep it smaller and simpler. The
1376 limit is @ref QCBOR_MAX_ARRAY_NESTING. This is the max number of
1377 times this can be called without calling
1378 QCBOREncode_CloseArray(). QCBOREncode_Finish() will return @ref
1379 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP when it is called as this function
1380 just sets an error state and returns no value when this occurs.
1381
1382 If you try to add more than @ref QCBOR_MAX_ITEMS_IN_ARRAY items to a
1383 single array or map, @ref QCBOR_ERR_ARRAY_TOO_LONG will be returned
1384 when QCBOREncode_Finish() is called.
1385
1386 An array itself must have a label if it is being added to a map.
1387 Note that array elements do not have labels (but map elements do).
1388
1389 An array itself may be tagged by calling QCBOREncode_AddTag() before this call.
1390 */
1391static void QCBOREncode_OpenArray(QCBOREncodeContext *pCtx);
1392
1393static void QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1394
1395static void QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1396
1397
1398/**
1399 @brief Close an open array.
1400
1401 @param[in] pCtx The encoding context to close the array in.
1402
1403 The closes an array opened by QCBOREncode_OpenArray(). It reduces
1404 nesting level by one. All arrays (and maps) must be closed before
1405 calling QCBOREncode_Finish().
1406
1407 When an error occurs as a result of this call, the encoder records
1408 the error and enters the error state. The error will be returned when
1409 QCBOREncode_Finish() is called.
1410
1411 If this has been called more times than QCBOREncode_OpenArray(), then
1412 @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when QCBOREncode_Finish()
1413 is called.
1414
1415 If this is called and it is not an array that is currently open, @ref
1416 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
1417 is called.
1418 */
1419static void QCBOREncode_CloseArray(QCBOREncodeContext *pCtx);
1420
1421
1422/**
1423 @brief Indicates that the next items added are in a map.
1424
1425 @param[in] pCtx The encoding context to open the map in.
1426
1427 See QCBOREncode_OpenArray() for more information, particularly error
1428 handling.
1429
1430 CBOR maps are an aggregate type where each item in the map consists
1431 of a label and a value. They are similar to JSON objects.
1432
1433 The value can be any CBOR type including another map.
1434
1435 The label can also be any CBOR type, but in practice they are
1436 typically, integers as this gives the most compact output. They might
1437 also be text strings which gives readability and translation to JSON.
1438
1439 Every @c QCBOREncode_AddXxx() call has one version that ends with @c
1440 InMap for adding items to maps with string labels and one that ends
1441 with @c InMapN that is for adding with integer labels.
1442
1443 RFC 7049 uses the term "key" instead of "label".
1444
1445 If you wish to use map labels that are neither integer labels nor
1446 text strings, then just call the QCBOREncode_AddXxx() function
1447 explicitly to add the label. Then call it again to add the value.
1448
1449 See the [RFC 7049] (https://tools.ietf.org/html/rfc7049) for a lot
1450 more information on creating maps.
1451 */
1452static void QCBOREncode_OpenMap(QCBOREncodeContext *pCtx);
1453
1454static void QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1455
1456static void QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1457
1458
1459
1460/**
1461 @brief Close an open map.
1462
1463 @param[in] pCtx The encoding context to close the map in .
1464
1465 This closes a map opened by QCBOREncode_OpenMap(). It reduces nesting
1466 level by one.
1467
1468 When an error occurs as a result of this call, the encoder records
1469 the error and enters the error state. The error will be returned when
1470 QCBOREncode_Finish() is called.
1471
1472 If this has been called more times than QCBOREncode_OpenMap(),
1473 then @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1474 QCBOREncode_Finish() is called.
1475
1476 If this is called and it is not a map that is currently open, @ref
1477 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
1478 is called.
1479 */
1480static void QCBOREncode_CloseMap(QCBOREncodeContext *pCtx);
1481
1482
1483/**
1484 @brief Indicate start of encoded CBOR to be wrapped in a bstr.
1485
1486 @param[in] pCtx The encoding context to open the bstr-wrapped CBOR in.
1487
1488 All added encoded items between this call and a call to
1489 QCBOREncode_CloseBstrWrap2() will be wrapped in a bstr. They will
1490 appear in the final output as a byte string. That byte string will
1491 contain encoded CBOR. This increases nesting level by one.
1492
1493 The typical use case is for encoded CBOR that is to be
1494 cryptographically hashed, as part of a [RFC 8152, COSE]
1495 (https://tools.ietf.org/html/rfc8152) implementation.
1496
1497 Using QCBOREncode_BstrWrap() and QCBOREncode_CloseBstrWrap2() avoids
1498 having to encode the items first in one buffer (e.g., the COSE
1499 payload) and then add that buffer as a bstr to another encoding
1500 (e.g. the COSE to-be-signed bytes, the @c Sig_structure) potentially
1501 halving the memory needed.
1502
1503 RFC 7049 states the purpose of this wrapping is to prevent code
1504 relaying the signed data but not verifying it from tampering with the
1505 signed data thus making the signature unverifiable. It is also quite
1506 beneficial for the signature verification code. Standard CBOR
1507 decoders usually do not give access to partially decoded CBOR as
1508 would be needed to check the signature of some CBOR. With this
1509 wrapping, standard CBOR decoders can be used to get to all the data
1510 needed for a signature verification.
1511 */
1512static void QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx);
1513
1514static void QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1515
1516static void QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1517
1518
1519/**
1520 @brief Close a wrapping bstr.
1521
1522 @param[in] pCtx The encoding context to close of bstr wrapping in.
1523 @param[in] bIncludeCBORHead Include the encoded CBOR head of the bstr
1524 as well as the bytes in @c pWrappedCBOR.
1525 @param[out] pWrappedCBOR A @ref UsefulBufC containing wrapped bytes.
1526
1527 The closes a wrapping bstr opened by QCBOREncode_BstrWrap(). It reduces
1528 nesting level by one.
1529
1530 A pointer and length of the enclosed encoded CBOR is returned in @c
1531 *pWrappedCBOR if it is not @c NULL. The main purpose of this is so
1532 this data can be hashed (e.g., with SHA-256) as part of a [RFC 8152,
1533 COSE] (https://tools.ietf.org/html/rfc8152)
1534 implementation. **WARNING**, this pointer and length should be used
1535 right away before any other calls to @c QCBOREncode_CloseXxx() as
1536 they will move data around and the pointer and length will no longer
1537 be to the correct encoded CBOR.
1538
1539 When an error occurs as a result of this call, the encoder records
1540 the error and enters the error state. The error will be returned when
1541 QCBOREncode_Finish() is called.
1542
1543 If this has been called more times than QCBOREncode_BstrWrap(), then
1544 @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1545 QCBOREncode_Finish() is called.
1546
1547 If this is called and it is not a wrapping bstr that is currently
1548 open, @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
1549 QCBOREncode_Finish() is called.
1550
1551 QCBOREncode_CloseBstrWrap() is a deprecated version of this function
1552 that is equivalent to the call with @c bIncludeCBORHead @c true.
1553 */
1554void QCBOREncode_CloseBstrWrap2(QCBOREncodeContext *pCtx, bool bIncludeCBORHead, UsefulBufC *pWrappedCBOR);
1555
1556static void QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR);
1557
1558
1559/**
1560 @brief Add some already-encoded CBOR bytes.
1561
1562 @param[in] pCtx The encoding context to add the already-encode CBOR to.
1563 @param[in] Encoded The already-encoded CBOR to add to the context.
1564
1565 The encoded CBOR being added must be fully conforming CBOR. It must
1566 be complete with no arrays or maps that are incomplete. While this
1567 encoder doesn't ever produce indefinite lengths, it is OK for the
1568 raw CBOR added here to have indefinite lengths.
1569
1570 The raw CBOR added here is not checked in anyway. If it is not
1571 conforming or has open arrays or such, the final encoded CBOR
1572 will probably be wrong or not what was intended.
1573
1574 If the encoded CBOR being added here contains multiple items, they
1575 must be enclosed in a map or array. At the top level the raw
1576 CBOR must be a single data item.
1577 */
1578static void QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded);
1579
1580static void QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded);
1581
1582static void QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded);
1583
1584
1585/**
1586 @brief Get the encoded result.
1587
1588 @param[in] pCtx The context to finish encoding with.
1589 @param[out] pEncodedCBOR Pointer and length of encoded CBOR.
1590
1591 @retval QCBOR_ERR_TOO_MANY_CLOSES Nesting error
1592
1593 @retval QCBOR_ERR_CLOSE_MISMATCH Nesting error
1594
1595 @retval QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN Nesting error
1596
1597 @retval QCBOR_ERR_BUFFER_TOO_LARGE Encoded output buffer size
1598
1599 @retval QCBOR_ERR_BUFFER_TOO_SMALL Encoded output buffer size
1600
1601 @retval QCBOR_ERR_ARRAY_NESTING_TOO_DEEP Implementation limit
1602
1603 @retval QCBOR_ERR_ARRAY_TOO_LONG Implementation limit
1604
1605 If this returns success @ref QCBOR_SUCCESS the encoding was a success
1606 and the return length is correct and complete.
1607
1608 If no buffer was passed to QCBOREncode_Init(), then only the length
1609 was computed. If a buffer was passed, then the encoded CBOR is in the
1610 buffer.
1611
1612 Encoding errors primarily manifest here as most other encoding function
1613 do no return an error. They just set the error state in the encode
1614 context after which no encoding function does anything.
1615
1616 Three types of errors manifest here. The first type are nesting
1617 errors where the number of @c QCBOREncode_OpenXxx() calls do not
1618 match the number @c QCBOREncode_CloseXxx() calls. The solution is to
1619 fix the calling code.
1620
1621 The second type of error is because the buffer given is either too
1622 small or too large. The remedy is to give a correctly sized buffer.
1623
1624 The third type are due to limits in this implementation. @ref
1625 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP can be worked around by encoding the
1626 CBOR in two (or more) phases and adding the CBOR from the first phase
1627 to the second with @c QCBOREncode_AddEncoded().
1628
1629 If an error is returned, the buffer may have partially encoded
1630 incorrect CBOR in it and it should not be used. Likewise, the length
1631 may be incorrect and should not be used.
1632
1633 Note that the error could have occurred in one of the many @c
1634 QCBOREncode_AddXxx() calls long before QCBOREncode_Finish() was
1635 called. This error handling reduces the CBOR implementation size but
1636 makes debugging harder.
1637
1638 This may be called multiple times. It will always return the same. It
1639 can also be interleaved with calls to QCBOREncode_FinishGetSize().
1640
1641 QCBOREncode_GetErrorState() can be called to get the current
1642 error state and abort encoding early as an optimization, but is
1643 is never required.
1644 */
1645QCBORError QCBOREncode_Finish(QCBOREncodeContext *pCtx, UsefulBufC *pEncodedCBOR);
1646
1647
1648/**
1649 @brief Get the encoded CBOR and error status.
1650
1651 @param[in] pCtx The context to finish encoding with.
1652 @param[out] uEncodedLen The length of the encoded or potentially
1653 encoded CBOR in bytes.
1654
1655 @return The same errors as QCBOREncode_Finish().
1656
1657 This functions the same as QCBOREncode_Finish(), but only returns the
1658 size of the encoded output.
1659 */
1660QCBORError QCBOREncode_FinishGetSize(QCBOREncodeContext *pCtx, size_t *uEncodedLen);
1661
1662
1663/**
1664 @brief Indicate whether output buffer is NULL or not.
1665
1666 @param[in] pCtx The encoding context.
1667
1668 @return 1 if the output buffer is @c NULL.
1669
1670 Sometimes a @c NULL input buffer is given to QCBOREncode_Init() so
1671 that the size of the generated CBOR can be calculated without
1672 allocating a buffer for it. This returns 1 when the output buffer is
1673 NULL and 0 when it is not.
1674*/
1675static int QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx);
1676
1677 /**
1678 @brief Get the encoding error state.
1679
1680 @param[in] pCtx The encoding context.
1681
Laurence Lundbladeabf5c572020-06-29 21:21:29 -07001682 @return One of @ref QCBORError. See return values from
Michael Eckel5c531332020-03-02 01:35:30 +01001683 QCBOREncode_Finish()
1684
1685 Normally encoding errors need only be handled at the end of encoding
1686 when QCBOREncode_Finish() is called. This can be called to get the
1687 error result before finish should there be a need to halt encoding
1688 before QCBOREncode_Finish() is called.
1689*/
1690static QCBORError QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx);
1691
1692
1693/**
1694 Encode the "head" of a CBOR data item.
1695
1696 @param buffer Buffer to output the encoded head to; must be
1697 @ref QCBOR_HEAD_BUFFER_SIZE bytes in size.
1698 @param uMajorType One of CBOR_MAJOR_TYPE_XX.
1699 @param uMinLen The minimum number of bytes to encode uNumber. Almost always
1700 this is 0 to use preferred minimal encoding. If this is 4,
1701 then even the values 0xffff and smaller will be encoded
1702 as in 4 bytes. This is used primarily when encoding a
1703 float or double put into uNumber as the leading zero bytes
1704 for them must be encoded.
1705 @param uNumber The numeric argument part of the CBOR head.
1706 @return Pointer and length of the encoded head or
1707 @NULLUsefulBufC if the output buffer is too small.
1708
1709 Callers to need to call this for normal CBOR encoding. Note that it doesn't even
1710 take a @ref QCBOREncodeContext argument.
1711
1712 This encodes the major type and argument part of a data item. The
1713 argument is an integer that is usually either the value or the length
1714 of the data item.
1715
1716 This is exposed in the public interface to allow hashing of some CBOR
1717 data types, bstr in particular, a chunk at a time so the full CBOR
1718 doesn't have to be encoded in a contiguous buffer.
1719
1720 For example, if you have a 100,000 byte binary blob in a buffer that
1721 needs to be a bstr encoded and then hashed. You could allocate a
1722 100,010 byte buffer and encode it normally. Alternatively, you can
1723 encode the head in a 10 byte buffer with this function, hash that and
1724 then hash the 100,000 bytes using the same hash context.
1725
1726 See also QCBOREncode_AddBytesLenOnly();
1727 */
1728UsefulBufC QCBOREncode_EncodeHead(UsefulBuf buffer,
1729 uint8_t uMajorType,
1730 uint8_t uMinLen,
1731 uint64_t uNumber);
1732
1733
Michael Eckel5c531332020-03-02 01:35:30 +01001734
1735
1736/* ===========================================================================
1737 BEGINNING OF PRIVATE INLINE IMPLEMENTATION
1738
1739 =========================================================================== */
1740
1741/**
1742 @brief Semi-private method to add a buffer full of bytes to encoded output
1743
1744 @param[in] pCtx The encoding context to add the integer to.
1745 @param[in] uMajorType The CBOR major type of the bytes.
1746 @param[in] Bytes The bytes to add.
1747
1748 Use QCBOREncode_AddText() or QCBOREncode_AddBytes() or
1749 QCBOREncode_AddEncoded() instead. They are inline functions that call
1750 this and supply the correct major type. This function is public to
1751 make the inline functions work to keep the overall code size down and
1752 because the C language has no way to make it private.
1753
1754 If this is called the major type should be @c
1755 CBOR_MAJOR_TYPE_TEXT_STRING, @c CBOR_MAJOR_TYPE_BYTE_STRING or @c
1756 CBOR_MAJOR_NONE_TYPE_RAW. The last one is special for adding
1757 already-encoded CBOR.
1758 */
1759void QCBOREncode_AddBuffer(QCBOREncodeContext *pCtx, uint8_t uMajorType, UsefulBufC Bytes);
1760
1761
1762/**
1763 @brief Semi-private method to open a map, array or bstr-wrapped CBOR
1764
1765 @param[in] pCtx The context to add to.
1766 @param[in] uMajorType The major CBOR type to close
1767
1768 Call QCBOREncode_OpenArray(), QCBOREncode_OpenMap() or
1769 QCBOREncode_BstrWrap() instead of this.
1770 */
1771void QCBOREncode_OpenMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType);
1772
1773
1774/**
1775 @brief Semi-private method to open a map, array with indefinite length
1776
1777 @param[in] pCtx The context to add to.
1778 @param[in] uMajorType The major CBOR type to close
1779
1780 Call QCBOREncode_OpenArrayIndefiniteLength() or
1781 QCBOREncode_OpenMapIndefiniteLength() instead of this.
1782 */
1783void QCBOREncode_OpenMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx, uint8_t uMajorType);
1784
1785
1786/**
1787 @brief Semi-private method to close a map, array or bstr wrapped CBOR
1788
1789 @param[in] pCtx The context to add to.
1790 @param[in] uMajorType The major CBOR type to close.
1791
1792 Call QCBOREncode_CloseArray() or QCBOREncode_CloseMap() instead of this.
1793 */
1794void QCBOREncode_CloseMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType);
1795
1796
1797/**
1798 @brief Semi-private method to close a map, array with indefinite length
1799
1800 @param[in] pCtx The context to add to.
1801 @param[in] uMajorType The major CBOR type to close.
1802
1803 Call QCBOREncode_CloseArrayIndefiniteLength() or
1804 QCBOREncode_CloseMapIndefiniteLength() instead of this.
1805 */
1806void QCBOREncode_CloseMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx,
1807 uint8_t uMajorType);
1808
1809
1810/**
1811 @brief Semi-private method to add simple types.
1812
1813 @param[in] pCtx The encoding context to add the simple value to.
1814 @param[in] uMinLen Minimum encoding size for uNum. Usually 0.
1815 @param[in] uNum One of CBOR_SIMPLEV_FALSE through _UNDEF or other.
1816
1817 This is used to add simple types like true and false.
1818
1819 Call QCBOREncode_AddBool(), QCBOREncode_AddNULL(),
1820 QCBOREncode_AddUndef() instead of this.
1821
1822 This function can add simple values that are not defined by CBOR
1823 yet. This expansion point in CBOR should not be used unless they are
1824 standardized.
1825
1826 Error handling is the same as QCBOREncode_AddInt64().
1827 */
1828void QCBOREncode_AddType7(QCBOREncodeContext *pCtx, uint8_t uMinLen, uint64_t uNum);
1829
1830
1831/**
1832 @brief Semi-private method to add bigfloats and decimal fractions.
1833
1834 @param[in] pCtx The encoding context to add the value to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001835 @param[in] uTag The type 6 tag indicating what this is to be.
Michael Eckel5c531332020-03-02 01:35:30 +01001836 @param[in] BigNumMantissa Is @ref NULLUsefulBufC if mantissa is an
1837 @c int64_t or the actual big number mantissa
1838 if not.
1839 @param[in] nMantissa The @c int64_t mantissa if it is not a big number.
1840 @param[in] nExponent The exponent.
1841
1842 This adds a tagged array with two members, the mantissa and exponent. The
1843 mantissa can be either a big number or an @c int64_t.
1844
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001845 If @c uTag is @ref CBOR_INVALID_TAG64, then only the mantissa and exponent
1846 content will be encoded. See TODO: finish this.
1847
Michael Eckel5c531332020-03-02 01:35:30 +01001848 Typically, QCBOREncode_AddDecimalFraction(), QCBOREncode_AddBigFloat(),
1849 QCBOREncode_AddDecimalFractionBigNum() or QCBOREncode_AddBigFloatBigNum()
1850 is called instead of this.
1851 */
1852void QCBOREncode_AddExponentAndMantissa(QCBOREncodeContext *pCtx,
1853 uint64_t uTag,
1854 UsefulBufC BigNumMantissa,
1855 bool bBigNumIsNegative,
1856 int64_t nMantissa,
1857 int64_t nExponent);
1858
1859/**
1860 @brief Semi-private method to add only the type and length of a byte string.
1861
1862 @param[in] pCtx The context to initialize.
1863 @param[in] Bytes Pointer and length of the input data.
1864
1865 This is the same as QCBOREncode_AddBytes() except it only adds the
1866 CBOR encoding for the type and the length. It doesn't actually add
1867 the bytes. You can't actually produce correct CBOR with this and the
1868 rest of this API. It is only used for a special case where
1869 the valid CBOR is created manually by putting this type and length in
1870 and then adding the actual bytes. In particular, when only a hash of
1871 the encoded CBOR is needed, where the type and header are hashed
1872 separately and then the bytes is hashed. This makes it possible to
1873 implement COSE Sign1 with only one copy of the payload in the output
1874 buffer, rather than two, roughly cutting memory use in half.
1875
1876 This is only used for this odd case, but this is a supported
1877 tested function.
1878
1879 See also QCBOREncode_EncodeHead().
1880*/
1881static inline void QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
1882
1883static inline void QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
1884
1885static inline void QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
1886
1887
1888
1889
1890
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001891static inline void
1892QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01001893{
1894 // Use _AddBuffer() because _AddSZString() is defined below, not above
1895 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
1896 QCBOREncode_AddInt64(pCtx, uNum);
1897}
1898
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001899static inline void
1900QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01001901{
1902 QCBOREncode_AddInt64(pCtx, nLabel);
1903 QCBOREncode_AddInt64(pCtx, uNum);
1904}
1905
1906
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001907static inline void
1908QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01001909{
1910 // Use _AddBuffer() because _AddSZString() is defined below, not above
1911 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
1912 QCBOREncode_AddUInt64(pCtx, uNum);
1913}
1914
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001915static inline void
1916QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01001917{
1918 QCBOREncode_AddInt64(pCtx, nLabel);
1919 QCBOREncode_AddUInt64(pCtx, uNum);
1920}
1921
1922
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001923static inline void
1924QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01001925{
1926 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, Text);
1927}
1928
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001929static inline void
1930QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01001931{
1932 // Use _AddBuffer() because _AddSZString() is defined below, not above
1933 QCBOREncode_AddText(pCtx, UsefulBuf_FromSZ(szLabel));
1934 QCBOREncode_AddText(pCtx, Text);
1935}
1936
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001937static inline void
1938QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01001939{
1940 QCBOREncode_AddInt64(pCtx, nLabel);
1941 QCBOREncode_AddText(pCtx, Text);
1942}
1943
1944
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001945inline static void
1946QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01001947{
1948 QCBOREncode_AddText(pCtx, UsefulBuf_FromSZ(szString));
1949}
1950
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001951static inline void
1952QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01001953{
1954 QCBOREncode_AddSZString(pCtx, szLabel);
1955 QCBOREncode_AddSZString(pCtx, szString);
1956}
1957
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001958static inline void
1959QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01001960{
1961 QCBOREncode_AddInt64(pCtx, nLabel);
1962 QCBOREncode_AddSZString(pCtx, szString);
1963}
1964
1965
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001966static inline void
1967QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01001968{
1969 QCBOREncode_AddSZString(pCtx, szLabel);
1970 QCBOREncode_AddDouble(pCtx, dNum);
1971}
1972
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001973static inline void
1974QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01001975{
1976 QCBOREncode_AddInt64(pCtx, nLabel);
1977 QCBOREncode_AddDouble(pCtx, dNum);
1978}
1979
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001980static inline void
1981QCBOREncode_AddFloatToMap(QCBOREncodeContext *pCtx, const char *szLabel, float dNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07001982{
1983 QCBOREncode_AddSZString(pCtx, szLabel);
1984 QCBOREncode_AddFloat(pCtx, dNum);
1985}
1986
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001987static inline void
1988QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float fNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07001989{
1990 QCBOREncode_AddInt64(pCtx, nLabel);
1991 QCBOREncode_AddFloat(pCtx, fNum);
1992}
1993
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001994static inline void
1995QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07001996{
1997 QCBOREncode_AddSZString(pCtx, szLabel);
1998 QCBOREncode_AddDoubleNoPreferred(pCtx, dNum);
1999}
2000
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002001static inline void
2002QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002003{
2004 QCBOREncode_AddInt64(pCtx, nLabel);
2005 QCBOREncode_AddDoubleNoPreferred(pCtx, dNum);
2006}
2007
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002008static inline void
2009QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002010{
2011 QCBOREncode_AddSZString(pCtx, szLabel);
2012 QCBOREncode_AddFloatNoPreferred(pCtx, dNum);
2013}
2014
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002015static inline void
2016QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002017{
2018 QCBOREncode_AddInt64(pCtx, nLabel);
2019 QCBOREncode_AddFloatNoPreferred(pCtx, dNum);
2020}
2021
Michael Eckel5c531332020-03-02 01:35:30 +01002022
Laurence Lundblade9b334962020-08-27 10:55:53 -07002023
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002024static inline void
2025QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pMe, uint8_t uTag, int64_t date)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002026{
2027 if(uTag == QCBOR_ENCODE_AS_TAG) {
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002028 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_EPOCH);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002029 }
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002030 QCBOREncode_AddInt64(pMe, date);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002031}
2032
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002033static inline void
2034QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTag, int64_t date)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002035{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002036 QCBOREncode_AddSZString(pMe, szLabel);
2037 QCBOREncode_AddTDateEpoch(pMe, uTag, date);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002038}
2039
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002040static inline void
2041QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTag, int64_t date)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002042{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002043 QCBOREncode_AddInt64(pMe, nLabel);
2044 QCBOREncode_AddTDateEpoch(pMe, uTag, date);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002045}
2046
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002047static inline void
2048QCBOREncode_AddDateEpoch(QCBOREncodeContext *pMe, int64_t date)
Michael Eckel5c531332020-03-02 01:35:30 +01002049{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002050 QCBOREncode_AddTDateEpoch(pMe, QCBOR_ENCODE_AS_TAG, date);
Michael Eckel5c531332020-03-02 01:35:30 +01002051}
2052
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002053static inline void
2054QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pMe, const char *szLabel, int64_t date)
Michael Eckel5c531332020-03-02 01:35:30 +01002055{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002056 QCBOREncode_AddSZString(pMe, szLabel);
2057 QCBOREncode_AddDateEpoch(pMe, date);
Michael Eckel5c531332020-03-02 01:35:30 +01002058}
2059
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002060static inline void
2061QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pMe, int64_t nLabel, int64_t date)
Michael Eckel5c531332020-03-02 01:35:30 +01002062{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002063 QCBOREncode_AddInt64(pMe, nLabel);
2064 QCBOREncode_AddDateEpoch(pMe, date);
Michael Eckel5c531332020-03-02 01:35:30 +01002065}
2066
2067
Laurence Lundblade9b334962020-08-27 10:55:53 -07002068
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002069static inline void
2070QCBOREncode_AddBytes(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002071{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002072 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002073}
2074
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002075static inline void
2076QCBOREncode_AddBytesToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002077{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002078 QCBOREncode_AddSZString(pMe, szLabel);
2079 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002080}
2081
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002082static inline void
2083QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002084{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002085 QCBOREncode_AddInt64(pMe, nLabel);
2086 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002087}
2088
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002089static inline void
2090QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002091{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002092 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002093}
2094
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002095static inline void
2096QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002097{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002098 QCBOREncode_AddSZString(pMe, szLabel);
2099 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002100}
2101
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002102static inline void
2103QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002104{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002105 QCBOREncode_AddInt64(pMe, nLabel);
2106 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002107}
2108
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002109
2110static inline void
2111QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002112{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002113 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2114 QCBOREncode_AddTag(pMe, CBOR_TAG_BIN_UUID);
2115 }
2116 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002117}
2118
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002119static inline void
2120QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pMe,
2121 const char *szLabel,
2122 uint8_t uTagRequirement,
2123 UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002124{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002125 QCBOREncode_AddSZString(pMe, szLabel);
2126 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002127}
2128
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002129static inline void
2130QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002131{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002132 QCBOREncode_AddInt64(pMe, nLabel);
2133 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002134}
2135
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002136static inline void
2137QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002138{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002139 QCBOREncode_AddTBinaryUUID(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002140}
2141
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002142static inline void
2143QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002144{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002145 QCBOREncode_AddTBinaryUUIDToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002146}
2147
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002148static inline void
2149QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002150{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002151 QCBOREncode_AddTBinaryUUIDToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002152}
2153
2154
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002155static inline void
2156QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002157{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002158 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2159 QCBOREncode_AddTag(pMe, CBOR_TAG_POS_BIGNUM);
2160 }
2161 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002162}
2163
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002164static inline void
2165QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pMe,
2166 const char *szLabel,
2167 uint8_t uTagRequirement,
2168 UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002169{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002170 QCBOREncode_AddSZString(pMe, szLabel);
2171 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002172}
2173
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002174static inline void
2175QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002176{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002177 QCBOREncode_AddInt64(pMe, nLabel);
2178 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002179}
2180
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002181static inline void
2182QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2183{
2184 QCBOREncode_AddTPositiveBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2185}
2186
2187static inline void
2188QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2189{
2190 QCBOREncode_AddTPositiveBignumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2191}
2192
2193static inline void
2194QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2195{
2196 QCBOREncode_AddTPositiveBignumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2197}
2198
2199
2200static inline void
2201QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
2202{
2203 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2204 QCBOREncode_AddTag(pMe, CBOR_TAG_NEG_BIGNUM);
2205 }
2206 QCBOREncode_AddBytes(pMe, Bytes);
2207}
2208
2209static inline void
2210QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pMe,
2211 const char *szLabel,
2212 uint8_t uTagRequirement,
2213 UsefulBufC Bytes)
2214{
2215 QCBOREncode_AddSZString(pMe, szLabel);
2216 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2217}
2218
2219static inline void
2220QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
2221{
2222 QCBOREncode_AddInt64(pMe, nLabel);
2223 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2224}
2225
2226static inline void
2227QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2228{
2229 QCBOREncode_AddTNegativeBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2230}
2231
2232static inline void
2233QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2234{
2235 QCBOREncode_AddTNegativeBignumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2236}
2237
2238static inline void
2239QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2240{
2241 QCBOREncode_AddTNegativeBignumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2242}
2243
2244
Michael Eckel5c531332020-03-02 01:35:30 +01002245
2246#ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
2247
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002248static inline void QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pMe,
2249 uint8_t uTagRequirement,
2250 int64_t nMantissa,
2251 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002252{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002253 uint64_t uTag;
2254 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2255 uTag = CBOR_TAG_DECIMAL_FRACTION;
2256 } else {
2257 uTag = CBOR_TAG_INVALID64;
2258 }
2259 QCBOREncode_AddExponentAndMantissa(pMe,
2260 uTag,
Michael Eckel5c531332020-03-02 01:35:30 +01002261 NULLUsefulBufC,
2262 false,
2263 nMantissa,
2264 nBase10Exponent);
2265}
2266
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002267static inline void QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pMe,
2268 const char *szLabel,
2269 uint8_t uTagRequirement,
2270 int64_t nMantissa,
2271 int64_t nBase10Exponent)
2272{
2273 QCBOREncode_AddSZString(pMe, szLabel);
2274 QCBOREncode_AddTDecimalFraction(pMe, uTagRequirement, nMantissa, nBase10Exponent);
2275}
2276
2277static inline void QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pMe,
2278 int64_t nLabel,
2279 uint8_t uTagRequirement,
2280 int64_t nMantissa,
2281 int64_t nBase10Exponent)
2282{
2283 QCBOREncode_AddInt64(pMe, nLabel);
2284 QCBOREncode_AddTDecimalFraction(pMe, uTagRequirement, nMantissa, nBase10Exponent);
2285}
2286
2287static inline void QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pMe,
2288 int64_t nMantissa,
2289 int64_t nBase10Exponent)
2290{
2291 QCBOREncode_AddTDecimalFraction(pMe, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
2292}
2293
2294static inline void QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pMe,
Michael Eckel5c531332020-03-02 01:35:30 +01002295 const char *szLabel,
2296 int64_t nMantissa,
2297 int64_t nBase10Exponent)
2298{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002299 QCBOREncode_AddTDecimalFractionToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002300}
2301
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002302static inline void QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pMe,
Michael Eckel5c531332020-03-02 01:35:30 +01002303 int64_t nLabel,
2304 int64_t nMantissa,
2305 int64_t nBase10Exponent)
2306{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002307 QCBOREncode_AddTDecimalFractionToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002308}
2309
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002310
2311
2312
2313
2314
2315static inline void QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pMe,
2316 uint8_t uTagRequirement,
2317 UsefulBufC Mantissa,
2318 bool bIsNegative,
2319 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002320{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002321 uint64_t uTag;
2322 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2323 uTag = CBOR_TAG_DECIMAL_FRACTION;
2324 } else {
2325 uTag = CBOR_TAG_INVALID64;
2326 }
2327 QCBOREncode_AddExponentAndMantissa(pMe,
2328 uTag,
Michael Eckel5c531332020-03-02 01:35:30 +01002329 Mantissa, bIsNegative,
2330 0,
2331 nBase10Exponent);
2332}
2333
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002334static inline void QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
2335 const char *szLabel,
2336 uint8_t uTagRequirement,
2337 UsefulBufC Mantissa,
2338 bool bIsNegative,
2339 int64_t nBase10Exponent)
2340{
2341 QCBOREncode_AddSZString(pMe, szLabel);
2342 QCBOREncode_AddTDecimalFractionBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase10Exponent);
2343}
2344
2345static inline void QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
2346 int64_t nLabel,
2347 uint8_t uTagRequirement,
2348 UsefulBufC Mantissa,
2349 bool bIsNegative,
2350 int64_t nBase10Exponent)
2351{
2352 QCBOREncode_AddInt64(pMe, nLabel);
2353 QCBOREncode_AddTDecimalFractionBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase10Exponent);
2354}
2355
2356static inline void QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pMe,
2357 UsefulBufC Mantissa,
2358 bool bIsNegative,
2359 int64_t nBase10Exponent)
2360{
2361 QCBOREncode_AddTDecimalFractionBigNum(pMe, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase10Exponent);
2362}
2363
2364static inline void QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
Michael Eckel5c531332020-03-02 01:35:30 +01002365 const char *szLabel,
2366 UsefulBufC Mantissa,
2367 bool bIsNegative,
2368 int64_t nBase10Exponent)
2369{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002370 QCBOREncode_AddTDecimalFractionBigNumToMapSZ(pMe,
2371 szLabel,
2372 QCBOR_ENCODE_AS_TAG,
2373 Mantissa,
2374 bIsNegative,
2375 nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002376}
2377
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002378static inline void QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
Michael Eckel5c531332020-03-02 01:35:30 +01002379 int64_t nLabel,
2380 UsefulBufC Mantissa,
2381 bool bIsNegative,
2382 int64_t nBase2Exponent)
2383{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002384 QCBOREncode_AddTDecimalFractionBigNumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002385}
2386
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002387
2388
2389
2390
2391static inline void QCBOREncode_AddTBigFloat(QCBOREncodeContext *pMe,
2392 uint8_t uTagRequirement,
2393 int64_t nMantissa,
2394 int64_t nBase2Exponent)
2395{
2396 uint64_t uTag;
2397 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2398 uTag = CBOR_TAG_BIGFLOAT;
2399 } else {
2400 uTag = CBOR_TAG_INVALID64;
2401 }
2402 QCBOREncode_AddExponentAndMantissa(pMe, uTag, NULLUsefulBufC, false, nMantissa, nBase2Exponent);
2403}
2404
2405static inline void QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pMe,
2406 const char *szLabel,
2407 uint8_t uTagRequirement,
2408 int64_t nMantissa,
2409 int64_t nBase2Exponent)
2410{
2411 QCBOREncode_AddSZString(pMe, szLabel);
2412 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
2413}
2414
2415static inline void QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pMe,
2416 int64_t nLabel,
2417 uint8_t uTagRequirement,
2418 int64_t nMantissa,
2419 int64_t nBase2Exponent)
2420{
2421 QCBOREncode_AddInt64(pMe, nLabel);
2422 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
2423}
2424
2425static inline void QCBOREncode_AddBigFloat(QCBOREncodeContext *pMe,
Michael Eckel5c531332020-03-02 01:35:30 +01002426 int64_t nMantissa,
2427 int64_t nBase2Exponent)
2428{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002429 QCBOREncode_AddTBigFloat(pMe, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002430}
2431
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002432static inline void QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pMe,
Michael Eckel5c531332020-03-02 01:35:30 +01002433 const char *szLabel,
2434 int64_t nMantissa,
2435 int64_t nBase2Exponent)
2436{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002437 QCBOREncode_AddTBigFloatToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002438}
2439
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002440static inline void QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pMe,
Michael Eckel5c531332020-03-02 01:35:30 +01002441 int64_t nLabel,
2442 int64_t nMantissa,
2443 int64_t nBase2Exponent)
2444{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002445 QCBOREncode_AddTBigFloatToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002446}
2447
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002448
2449
2450static inline void QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pMe,
2451 uint8_t uTagRequirement,
2452 UsefulBufC Mantissa,
2453 bool bIsNegative,
2454 int64_t nBase2Exponent)
2455{
2456 uint64_t uTag;
2457 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2458 uTag = CBOR_TAG_BIGFLOAT;
2459 } else {
2460 uTag = CBOR_TAG_INVALID64;
2461 }
2462 QCBOREncode_AddExponentAndMantissa(pMe, uTag, Mantissa, bIsNegative, 0, nBase2Exponent);
2463}
2464
2465static inline void QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pMe,
2466 const char *szLabel,
2467 uint8_t uTagRequirement,
2468 UsefulBufC Mantissa,
2469 bool bIsNegative,
2470 int64_t nBase2Exponent)
2471{
2472 QCBOREncode_AddSZString(pMe, szLabel);
2473 QCBOREncode_AddTBigFloatBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase2Exponent);
2474}
2475
2476static inline void QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
2477 int64_t nLabel,
2478 uint8_t uTagRequirement,
2479 UsefulBufC Mantissa,
2480 bool bIsNegative,
2481 int64_t nBase2Exponent)
2482{
2483 QCBOREncode_AddInt64(pMe, nLabel);
2484 QCBOREncode_AddTBigFloatBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase2Exponent);
2485}
2486
2487
2488static inline void QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pMe,
Michael Eckel5c531332020-03-02 01:35:30 +01002489 UsefulBufC Mantissa,
2490 bool bIsNegative,
2491 int64_t nBase2Exponent)
2492{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002493 QCBOREncode_AddTBigFloatBigNum(pMe, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002494}
2495
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002496static inline void QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pMe,
Michael Eckel5c531332020-03-02 01:35:30 +01002497 const char *szLabel,
2498 UsefulBufC Mantissa,
2499 bool bIsNegative,
2500 int64_t nBase2Exponent)
2501{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002502 QCBOREncode_AddTBigFloatBigNumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002503}
2504
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002505static inline void QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
Michael Eckel5c531332020-03-02 01:35:30 +01002506 int64_t nLabel,
2507 UsefulBufC Mantissa,
2508 bool bIsNegative,
2509 int64_t nBase2Exponent)
2510{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002511 QCBOREncode_AddTBigFloatBigNumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002512}
2513#endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
2514
2515
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002516static inline void
2517QCBOREncode_AddTURI(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002518{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002519 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2520 QCBOREncode_AddTag(pMe, CBOR_TAG_URI);
2521 }
2522 QCBOREncode_AddText(pMe, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002523}
2524
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002525static inline void
2526QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002527{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002528 QCBOREncode_AddSZString(pMe, szLabel);
2529 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002530}
2531
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002532static inline void
2533QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002534{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002535 QCBOREncode_AddInt64(pMe, nLabel);
2536 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
2537}
2538
2539static inline void
2540QCBOREncode_AddURI(QCBOREncodeContext *pMe, UsefulBufC URI)
2541{
2542 QCBOREncode_AddTURI(pMe, QCBOR_ENCODE_AS_TAG, URI);
2543}
2544
2545static inline void
2546QCBOREncode_AddURIToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC URI)
2547{
2548 QCBOREncode_AddTURIToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, URI);
2549}
2550
2551static inline void
2552QCBOREncode_AddURIToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC URI)
2553{
2554 QCBOREncode_AddTURIToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002555}
2556
2557
2558
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002559static inline void
2560QCBOREncode_AddTB64Text(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002561{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002562 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2563 QCBOREncode_AddTag(pMe, CBOR_TAG_B64);
2564 }
2565 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002566}
2567
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002568static inline void
2569QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pMe,
2570 const char *szLabel,
2571 uint8_t uTagRequirement,
2572 UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002573{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002574 QCBOREncode_AddSZString(pMe, szLabel);
2575 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002576}
2577
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002578static inline void
2579QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002580{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002581 QCBOREncode_AddInt64(pMe, nLabel);
2582 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
2583}
2584
2585static inline void
2586QCBOREncode_AddB64Text(QCBOREncodeContext *pMe, UsefulBufC B64Text)
2587{
2588 QCBOREncode_AddTB64Text(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
2589}
2590
2591static inline void
2592QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC B64Text)
2593{
2594 QCBOREncode_AddTB64TextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
2595}
2596
2597static inline void
2598QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC B64Text)
2599{
2600 QCBOREncode_AddTB64TextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002601}
2602
2603
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002604
2605static inline void
2606QCBOREncode_AddTB64URLText(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002607{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002608 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2609 QCBOREncode_AddTag(pMe, CBOR_TAG_B64URL);
2610 }
2611 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002612}
2613
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002614static inline void
2615QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pMe,
2616 const char *szLabel,
2617 uint8_t uTagRequirement,
2618 UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002619{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002620 QCBOREncode_AddSZString(pMe, szLabel);
2621 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002622}
2623
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002624static inline void
2625QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002626{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002627 QCBOREncode_AddInt64(pMe, nLabel);
2628 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
2629}
2630
2631static inline void
2632QCBOREncode_AddB64URLText(QCBOREncodeContext *pMe, UsefulBufC B64Text)
2633{
2634 QCBOREncode_AddTB64URLText(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
2635}
2636
2637static inline void
2638QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC B64Text)
2639{
2640 QCBOREncode_AddTB64URLTextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
2641}
2642
2643static inline void
2644QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC B64Text)
2645{
2646 QCBOREncode_AddTB64URLTextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002647}
2648
2649
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002650
2651static inline void
2652QCBOREncode_AddTRegex(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002653{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002654 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2655 QCBOREncode_AddTag(pMe, CBOR_TAG_REGEX);
2656 }
2657 QCBOREncode_AddText(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002658}
2659
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002660static inline void
2661QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002662{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002663 QCBOREncode_AddSZString(pMe, szLabel);
2664 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002665}
2666
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002667static inline void
2668QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002669{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002670 QCBOREncode_AddInt64(pMe, nLabel);
2671 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
2672}
2673
2674static inline void
2675QCBOREncode_AddRegex(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2676{
2677 QCBOREncode_AddTRegex(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2678}
2679
2680static inline void
2681QCBOREncode_AddRegexToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2682{
2683 QCBOREncode_AddTRegexToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2684}
2685
2686static inline void
2687QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2688{
2689 QCBOREncode_AddTRegexToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2690
Michael Eckel5c531332020-03-02 01:35:30 +01002691}
2692
2693
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002694static inline void
2695QCBOREncode_AddTMIMEData(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01002696{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002697 // TODO: add support for binary MIME.
2698 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2699 QCBOREncode_AddTag(pMe, CBOR_TAG_MIME);
2700 }
2701 QCBOREncode_AddText(pMe, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01002702}
2703
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002704static inline void
2705QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pMe,
2706 const char *szLabel,
2707 uint8_t uTagRequirement,
2708 UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01002709{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002710 QCBOREncode_AddSZString(pMe, szLabel);
2711 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01002712}
2713
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002714static inline void
2715QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01002716{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002717 QCBOREncode_AddInt64(pMe, nLabel);
2718 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
2719}
2720
2721static inline void
2722QCBOREncode_AddMIMEData(QCBOREncodeContext *pMe, UsefulBufC MIMEData)
2723{
2724 QCBOREncode_AddTMIMEData(pMe, QCBOR_ENCODE_AS_TAG, MIMEData);
2725}
2726
2727static inline void
2728QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC MIMEData)
2729{
2730 QCBOREncode_AddTMIMEDataToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
2731}
2732
2733static inline void
2734QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC MIMEData)
2735{
2736 QCBOREncode_AddTMIMEDataToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01002737}
2738
2739
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002740static inline void
2741QCBOREncode_AddTDateString(QCBOREncodeContext *pMe, uint8_t uTagRequirement, const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002742{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002743 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2744 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_STRING);
2745 }
2746 QCBOREncode_AddSZString(pMe, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002747}
2748
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002749static inline void
2750QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pMe,
2751 const char *szLabel,
2752 uint8_t uTagRequirement,
2753 const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002754{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002755 QCBOREncode_AddSZString(pMe, szLabel);
2756 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002757}
2758
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002759static inline void
2760QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002761{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002762 QCBOREncode_AddInt64(pMe, nLabel);
2763 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
2764}
2765
2766static inline void
2767QCBOREncode_AddDateString(QCBOREncodeContext *pMe, const char *szDate)
2768{
2769 QCBOREncode_AddTDateString(pMe, QCBOR_ENCODE_AS_TAG, szDate);
2770}
2771
2772static inline void
2773QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pMe, const char *szLabel, const char *szDate)
2774{
2775 QCBOREncode_AddTDateStringToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, szDate);
2776}
2777
2778static inline void
2779QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, const char *szDate)
2780{
2781 QCBOREncode_AddTDateStringToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002782}
2783
2784
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002785static inline void
2786QCBOREncode_AddSimple(QCBOREncodeContext *pMe, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002787{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002788 QCBOREncode_AddType7(pMe, 0, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002789}
2790
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002791static inline void
2792QCBOREncode_AddSimpleToMap(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01002793{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002794 QCBOREncode_AddSZString(pMe, szLabel);
2795 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01002796}
2797
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002798static inline void
2799QCBOREncode_AddSimpleToMapN(QCBOREncodeContext *pMe, int nLabel, uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01002800{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002801 QCBOREncode_AddInt64(pMe, nLabel);
2802 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01002803}
2804
2805
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002806static inline void
2807QCBOREncode_AddBool(QCBOREncodeContext *pMe, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01002808{
2809 uint8_t uSimple = CBOR_SIMPLEV_FALSE;
2810 if(b) {
2811 uSimple = CBOR_SIMPLEV_TRUE;
2812 }
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002813 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01002814}
2815
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002816static inline void
2817QCBOREncode_AddBoolToMap(QCBOREncodeContext *pMe, const char *szLabel, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01002818{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002819 QCBOREncode_AddSZString(pMe, szLabel);
2820 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01002821}
2822
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002823static inline void
2824QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pMe, int64_t nLabel, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01002825{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002826 QCBOREncode_AddInt64(pMe, nLabel);
2827 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01002828}
2829
2830
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002831static inline void
2832QCBOREncode_AddNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01002833{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002834 QCBOREncode_AddSimple(pMe, CBOR_SIMPLEV_NULL);
Michael Eckel5c531332020-03-02 01:35:30 +01002835}
2836
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002837static inline void
2838QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002839{
2840 QCBOREncode_AddSZString(pCtx, szLabel);
2841 QCBOREncode_AddNULL(pCtx);
2842}
2843
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002844static inline void
2845QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002846{
2847 QCBOREncode_AddInt64(pCtx, nLabel);
2848 QCBOREncode_AddNULL(pCtx);
2849}
2850
2851
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002852static inline void
2853QCBOREncode_AddUndef(QCBOREncodeContext *pCtx)
Michael Eckel5c531332020-03-02 01:35:30 +01002854{
2855 QCBOREncode_AddSimple(pCtx, CBOR_SIMPLEV_UNDEF);
2856}
2857
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002858static inline void
2859QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002860{
2861 QCBOREncode_AddSZString(pCtx, szLabel);
2862 QCBOREncode_AddUndef(pCtx);
2863}
2864
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002865static inline void
2866QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002867{
2868 QCBOREncode_AddInt64(pCtx, nLabel);
2869 QCBOREncode_AddUndef(pCtx);
2870}
2871
2872
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002873static inline void
2874QCBOREncode_OpenArray(QCBOREncodeContext *pCtx)
Michael Eckel5c531332020-03-02 01:35:30 +01002875{
2876 QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_ARRAY);
2877}
2878
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002879static inline void
2880QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002881{
2882 QCBOREncode_AddSZString(pCtx, szLabel);
2883 QCBOREncode_OpenArray(pCtx);
2884}
2885
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002886static inline void
2887QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002888{
2889 QCBOREncode_AddInt64(pCtx, nLabel);
2890 QCBOREncode_OpenArray(pCtx);
2891}
2892
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002893static inline void
2894QCBOREncode_CloseArray(QCBOREncodeContext *pCtx)
Michael Eckel5c531332020-03-02 01:35:30 +01002895{
2896 QCBOREncode_CloseMapOrArray(pCtx, CBOR_MAJOR_TYPE_ARRAY);
2897}
2898
2899
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002900static inline void
2901QCBOREncode_OpenMap(QCBOREncodeContext *pCtx)
Michael Eckel5c531332020-03-02 01:35:30 +01002902{
2903 QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_MAP);
2904}
2905
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002906static inline void
2907QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002908{
2909 QCBOREncode_AddSZString(pCtx, szLabel);
2910 QCBOREncode_OpenMap(pCtx);
2911}
2912
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002913static inline void
2914QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002915{
2916 QCBOREncode_AddInt64(pCtx, nLabel);
2917 QCBOREncode_OpenMap(pCtx);
2918}
2919
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002920static inline void
2921QCBOREncode_CloseMap(QCBOREncodeContext *pCtx)
Michael Eckel5c531332020-03-02 01:35:30 +01002922{
2923 QCBOREncode_CloseMapOrArray(pCtx, CBOR_MAJOR_TYPE_MAP);
2924}
2925
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002926static inline void
2927QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pCtx)
Michael Eckel5c531332020-03-02 01:35:30 +01002928{
2929 QCBOREncode_OpenMapOrArrayIndefiniteLength(pCtx, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
2930}
2931
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002932static inline void
2933QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pCtx, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002934{
2935 QCBOREncode_AddSZString(pCtx, szLabel);
2936 QCBOREncode_OpenArrayIndefiniteLength(pCtx);
2937}
2938
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002939static inline void
2940QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002941{
2942 QCBOREncode_AddInt64(pCtx, nLabel);
2943 QCBOREncode_OpenArrayIndefiniteLength(pCtx);
2944}
2945
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002946static inline void
2947QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pCtx)
Michael Eckel5c531332020-03-02 01:35:30 +01002948{
2949 QCBOREncode_CloseMapOrArrayIndefiniteLength(pCtx, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
2950}
2951
2952
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002953static inline void
2954QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pCtx)
Michael Eckel5c531332020-03-02 01:35:30 +01002955{
2956 QCBOREncode_OpenMapOrArrayIndefiniteLength(pCtx, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
2957}
2958
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002959static inline void
2960QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pCtx, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002961{
2962 QCBOREncode_AddSZString(pCtx, szLabel);
2963 QCBOREncode_OpenMapIndefiniteLength(pCtx);
2964}
2965
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002966static inline void
2967QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002968{
2969 QCBOREncode_AddInt64(pCtx, nLabel);
2970 QCBOREncode_OpenMapIndefiniteLength(pCtx);
2971}
2972
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002973static inline void
2974QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pCtx)
Michael Eckel5c531332020-03-02 01:35:30 +01002975{
2976 QCBOREncode_CloseMapOrArrayIndefiniteLength(pCtx, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
2977}
2978
2979
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002980static inline void
2981QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx)
Michael Eckel5c531332020-03-02 01:35:30 +01002982{
2983 QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_BYTE_STRING);
2984}
2985
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002986static inline void
2987QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002988{
2989 QCBOREncode_AddSZString(pCtx, szLabel);
2990 QCBOREncode_BstrWrap(pCtx);
2991}
2992
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002993static inline void
2994QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01002995{
2996 QCBOREncode_AddInt64(pCtx, nLabel);
2997 QCBOREncode_BstrWrap(pCtx);
2998}
2999
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003000static inline void
3001QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR)
Michael Eckel5c531332020-03-02 01:35:30 +01003002{
3003 QCBOREncode_CloseBstrWrap2(pCtx, true, pWrappedCBOR);
3004}
3005
3006
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003007static inline void
3008QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003009{
3010 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_NONE_TYPE_RAW, Encoded);
3011}
3012
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003013static inline void
3014QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003015{
3016 QCBOREncode_AddSZString(pCtx, szLabel);
3017 QCBOREncode_AddEncoded(pCtx, Encoded);
3018}
3019
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003020static inline void
3021QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003022{
3023 QCBOREncode_AddInt64(pCtx, nLabel);
3024 QCBOREncode_AddEncoded(pCtx, Encoded);
3025}
3026
3027
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003028static inline int
3029QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx)
Michael Eckel5c531332020-03-02 01:35:30 +01003030{
3031 return UsefulOutBuf_IsBufferNULL(&(pCtx->OutBuf));
3032}
3033
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003034static inline QCBORError
3035QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx)
Michael Eckel5c531332020-03-02 01:35:30 +01003036{
3037 if(UsefulOutBuf_GetError(&(pCtx->OutBuf))) {
3038 // Items didn't fit in the buffer.
3039 // This check catches this condition for all the appends and inserts
3040 // so checks aren't needed when the appends and inserts are performed.
3041 // And of course UsefulBuf will never overrun the input buffer given
3042 // to it. No complex analysis of the error handling in this file is
3043 // needed to know that is true. Just read the UsefulBuf code.
3044 pCtx->uError = QCBOR_ERR_BUFFER_TOO_SMALL;
3045 // QCBOR_ERR_BUFFER_TOO_SMALL masks other errors, but that is
3046 // OK. Once the caller fixes this, they'll be unmasked.
3047 }
3048
3049 return (QCBORError)pCtx->uError;
3050}
3051
3052
3053/* ===========================================================================
3054 END OF PRIVATE INLINE IMPLEMENTATION
3055
3056 =========================================================================== */
3057
3058#ifdef __cplusplus
3059}
3060#endif
3061
Laurence Lundblade844bb5c2020-03-01 17:27:25 -08003062#endif /* qcbor_encode_h */