blob: 969deee31be599e10137c3f325fd5a7693941bb9 [file] [log] [blame]
Michael Eckel5c531332020-03-02 01:35:30 +01001/*==============================================================================
2 Copyright (c) 2016-2018, The Linux Foundation.
Laurence Lundbladeb9702452021-03-08 21:02:57 -08003 Copyright (c) 2018-2021, Laurence Lundblade.
Michael Eckel5c531332020-03-02 01:35:30 +01004 All rights reserved.
5
6Redistribution and use in source and binary forms, with or without
7modification, are permitted provided that the following conditions are
8met:
9 * Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above
12 copyright notice, this list of conditions and the following
13 disclaimer in the documentation and/or other materials provided
14 with the distribution.
15 * Neither the name of The Linux Foundation nor the names of its
16 contributors, nor the name "Laurence Lundblade" may be used to
17 endorse or promote products derived from this software without
18 specific prior written permission.
19
20THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
21WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
23ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
24BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
30IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 =============================================================================*/
32
33
Laurence Lundblade844bb5c2020-03-01 17:27:25 -080034#ifndef qcbor_encode_h
35#define qcbor_encode_h
Michael Eckel5c531332020-03-02 01:35:30 +010036
37
Laurence Lundblade844bb5c2020-03-01 17:27:25 -080038#include "qcbor/qcbor_common.h"
39#include "qcbor/qcbor_private.h"
Michael Eckel5c531332020-03-02 01:35:30 +010040#include <stdbool.h>
Laurence Lundblade844bb5c2020-03-01 17:27:25 -080041
Michael Eckel5c531332020-03-02 01:35:30 +010042
43#ifdef __cplusplus
44extern "C" {
Dave Thaler12b23752020-03-27 01:23:08 -070045#if 0
Michael Eckel5c531332020-03-02 01:35:30 +010046} // Keep editor indention formatting happy
47#endif
48#endif
49
Michael Eckel5c531332020-03-02 01:35:30 +010050
51/**
Laurence Lundblade844bb5c2020-03-01 17:27:25 -080052 @file qcbor_encode.h
Michael Eckel5c531332020-03-02 01:35:30 +010053
Laurence Lundblade9a3b6252020-10-21 21:30:31 -070054 @anchor Overview
55
56 # QCBOR Overview
Michael Eckel5c531332020-03-02 01:35:30 +010057
58 This implements CBOR -- Concise Binary Object Representation as
Laurence Lundbladec02e13e2020-12-06 05:45:41 -080059 defined in [RFC 8949] (https://tools.ietf.org/html/rfc8949). More
Laurence Lundblade18e1d522020-10-22 02:18:41 -070060 information is at http://cbor.io. This is a near-complete implementation of
61 the specification. [RFC 8742] (https://tools.ietf.org/html/rfc8742) CBOR
62 Sequences is also supported. Limitations are listed further down.
Michael Eckel5c531332020-03-02 01:35:30 +010063
Laurence Lundblade9a3b6252020-10-21 21:30:31 -070064 See @ref Encoding for general discussion on encoding,
65 @ref BasicDecode for general discussion on the basic decode features
66 and @ref SpiffyDecode for general discussion on the easier-to-use
67 decoder functions.
68
Michael Eckel5c531332020-03-02 01:35:30 +010069 CBOR is intentionally designed to be translatable to JSON, but not
Laurence Lundbladec02e13e2020-12-06 05:45:41 -080070 all CBOR can convert to JSON. See RFC 8949 for more info on how to
Michael Eckel5c531332020-03-02 01:35:30 +010071 construct CBOR that is the most JSON friendly.
72
73 The memory model for encoding and decoding is that encoded CBOR must
74 be in a contiguous buffer in memory. During encoding the caller must
75 supply an output buffer and if the encoding would go off the end of
76 the buffer an error is returned. During decoding the caller supplies
77 the encoded CBOR in a contiguous buffer and the decoder returns
78 pointers and lengths into that buffer for strings.
79
80 This implementation does not require malloc. All data structures
81 passed in/out of the APIs can fit on the stack.
82
83 Decoding of indefinite-length strings is a special case that requires
84 a "string allocator" to allocate memory into which the segments of
85 the string are coalesced. Without this, decoding will error out if an
86 indefinite-length string is encountered (indefinite-length maps and
87 arrays do not require the string allocator). A simple string
88 allocator called MemPool is built-in and will work if supplied with a
89 block of memory to allocate. The string allocator can optionally use
90 malloc() or some other custom scheme.
91
92 Here are some terms and definitions:
93
94 - "Item", "Data Item": An integer or string or such. The basic "thing" that
95 CBOR is about. An array is an item itself that contains some items.
96
97 - "Array": An ordered sequence of items, the same as JSON.
98
99 - "Map": A collection of label/value pairs. Each pair is a data
100 item. A JSON "object" is the same as a CBOR "map".
101
102 - "Label": The data item in a pair in a map that names or identifies
103 the pair, not the value. This implementation refers to it as a
104 "label". JSON refers to it as the "name". The CBOR RFC refers to it
105 this as a "key". This implementation chooses label instead because
106 key is too easily confused with a cryptographic key. The COSE
107 standard, which uses CBOR, has also chosen to use the term "label"
108 rather than "key" for this same reason.
109
110 - "Key": See "Label" above.
111
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700112 - "Tag": A data item that is an explicitly labeled new data
113 type made up of the tagging integer and the tag content.
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700114 See @ref Tags-Overview and @ref Tag-Usage.
Michael Eckel5c531332020-03-02 01:35:30 +0100115
116 - "Initial Byte": The first byte of an encoded item. Encoding and
117 decoding of this byte is taken care of by the implementation.
118
119 - "Additional Info": In addition to the major type, all data items
120 have some other info. This is usually the length of the data but can
121 be several other things. Encoding and decoding of this is taken care
122 of by the implementation.
123
124 CBOR has two mechanisms for tagging and labeling the data values like
125 integers and strings. For example, an integer that represents
126 someone's birthday in epoch seconds since Jan 1, 1970 could be
127 encoded like this:
128
129 - First it is CBOR_MAJOR_TYPE_POSITIVE_INT (@ref QCBOR_TYPE_INT64),
130 the primitive positive integer.
131
132 - Next it has a "tag" @ref CBOR_TAG_DATE_EPOCH indicating the integer
133 represents a date in the form of the number of seconds since Jan 1,
134 1970.
135
136 - Last it has a string "label" like "BirthDate" indicating the
137 meaning of the data.
138
139 The encoded binary looks like this:
140
141 a1 # Map of 1 item
142 69 # Indicates text string of 9 bytes
143 426972746844617465 # The text "BirthDate"
144 c1 # Tags next integer as epoch date
145 1a # Indicates a 4-byte integer
146 580d4172 # unsigned integer date 1477263730
147
148 Implementors using this API will primarily work with
149 labels. Generally, tags are only needed for making up new data
150 types. This implementation covers most of the data types defined in
151 the RFC using tags. It also, allows for the use of custom tags if
152 necessary.
153
154 This implementation explicitly supports labels that are text strings
155 and integers. Text strings translate nicely into JSON objects and are
156 very readable. Integer labels are much less readable but can be very
157 compact. If they are in the range of 0 to 23, they take up only one
158 byte.
159
160 CBOR allows a label to be any type of data including an array or a
161 map. It is possible to use this API to construct and parse such
162 labels, but it is not explicitly supported.
163
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700164 @anchor Encoding
165
166 ## Encoding
167
Michael Eckel5c531332020-03-02 01:35:30 +0100168 A common encoding usage mode is to invoke the encoding twice. First
169 with no output buffer to compute the length of the needed output
170 buffer. Then the correct sized output buffer is allocated. Last the
171 encoder is invoked again, this time with the output buffer.
172
173 The double invocation is not required if the maximum output buffer
174 size can be predicted. This is usually possible for simple CBOR
175 structures. If the double invocation is implemented, it can be in a
176 loop or function as in the example code so that the code doesn't have
177 to actually be written twice, saving code size.
178
179 If a buffer too small to hold the encoded output is given, the error
180 @ref QCBOR_ERR_BUFFER_TOO_SMALL will be returned. Data will never be
181 written off the end of the output buffer no matter which functions
182 here are called or what parameters are passed to them.
183
184 The encoding error handling is simple. The only possible errors are
185 trying to encode structures that are too large or too complex. There
186 are no internal malloc calls so there will be no failures for out of
187 memory. The error state is tracked internally, so there is no need
188 to check for errors when encoding. Only the return code from
189 QCBOREncode_Finish() need be checked as once an error happens, the
190 encoder goes into an error state and calls to it to add more data
191 will do nothing. An error check is not needed after every data item
192 is added.
193
194 Encoding generally proceeds by calling QCBOREncode_Init(), calling
195 lots of @c QCBOREncode_AddXxx() functions and calling
196 QCBOREncode_Finish(). There are many @c QCBOREncode_AddXxx()
197 functions for various data types. The input buffers need only to be
198 valid during the @c QCBOREncode_AddXxx() calls as the data is copied
199 into the output buffer.
200
201 There are three `Add` functions for each data type. The first / main
202 one for the type is for adding the data item to an array. The second
203 one's name ends in `ToMap`, is used for adding data items to maps and
204 takes a string argument that is its label in the map. The third one
205 ends in `ToMapN`, is also used for adding data items to maps, and
206 takes an integer argument that is its label in the map.
207
208 The simplest aggregate type is an array, which is a simple ordered
209 set of items without labels the same as JSON arrays. Call
210 QCBOREncode_OpenArray() to open a new array, then various @c
211 QCBOREncode_AddXxx() functions to put items in the array and then
212 QCBOREncode_CloseArray(). Nesting to the limit @ref
213 QCBOR_MAX_ARRAY_NESTING is allowed. All opens must be matched by
214 closes or an encoding error will be returned.
215
216 The other aggregate type is a map which does use labels. The `Add`
217 functions that end in `ToMap` and `ToMapN` are convenient ways to add
218 labeled data items to a map. You can also call any type of `Add`
219 function once to add a label of any time and then call any type of
220 `Add` again to add its value.
221
222 Note that when you nest arrays or maps in a map, the nested array or
223 map has a label.
Laurence Lundblade2feb1e12020-07-15 03:50:45 -0700224
Laurence Lundbladee3553422020-05-02 11:11:17 -0700225 Many CBOR-based protocols start with an array or map. This makes them
226 self-delimiting. No external length or end marker is needed to know
227 the end. It is also possible not start this way, in which case this
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700228 it is usually called a CBOR sequence which is described in
229 [RFC 8742] (https://tools.ietf.org/html/rfc8742). This encoder supports
230 either just by whether the first item added is an array, map or other.
Michael Eckel5c531332020-03-02 01:35:30 +0100231
Laurence Lundbladeda97bf42020-11-05 03:38:50 -0800232 If QCBOR is compiled with QCBOR_DISABLE_ENCODE_USAGE_GUARDS defined,
233 the errors QCBOR_ERR_CLOSE_MISMATCH, QCBOR_ERR_ARRAY_TOO_LONG,
234 QCBOR_ERR_TOO_MANY_CLOSES, QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN, and
235 QCBOR_ERR_ENCODE_UNSUPPORTED will never be returned. It is up to the
236 caller to make sure that opened maps, arrays and byte-string wrapping
237 is closed correctly and that QCBOREncode_AddType7() is called
238 correctly. With this defined, it is easier to make a mistake when
239 authoring the encoding of a protocol that will output not well formed
240 CBOR, but as long as the calling code is correct, it is safe to
241 disable these checks. Bounds checking that prevents security issues
242 in the code is still enforced. This define reduces the size of
243 encoding object code by about 150 bytes.
244
Michael Eckel5c531332020-03-02 01:35:30 +0100245 @anchor Tags-Overview
Laurence Lundblade9b334962020-08-27 10:55:53 -0700246
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700247 ## Tags Overview
248
249 Any CBOR data item can be made into a tag to add semantics, define a
250 new data type or such. Some tags are fully standardized and some are
251 just registered. Others are not registered and used in a proprietary
252 way.
Michael Eckel5c531332020-03-02 01:35:30 +0100253
254 Encoding and decoding of many of the registered tags is fully
255 implemented by QCBOR. It is also possible to encode and decode tags
256 that are not directly supported. For many use cases the built-in tag
257 support should be adequate.
258
259 For example, the registered epoch date tag is supported in encoding
260 by QCBOREncode_AddDateEpoch() and in decoding by @ref
261 QCBOR_TYPE_DATE_EPOCH and the @c epochDate member of @ref
262 QCBORItem. This is typical of the built-in tag support. There is an
263 API to encode data for it and a @c QCBOR_TYPE_XXX when it is decoded.
264
265 Tags are registered in the [IANA CBOR Tags Registry]
266 (https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml). There
267 are roughly three options to create a new tag. First, a public
268 specification can be created and the new tag registered with IANA.
269 This is the most formal. Second, the new tag can be registered with
270 IANA with just a short description rather than a full specification.
271 These tags must be greater than 256. Third, a tag can be used without
272 any IANA registration, though the registry should be checked to see
273 that the new value doesn't collide with one that is registered. The
274 value of these tags must be 256 or larger.
275
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700276 See also @ref CBORTags and @ref Tag-Usage
277
Michael Eckel5c531332020-03-02 01:35:30 +0100278 The encoding side of tags not built-in is handled by
279 QCBOREncode_AddTag() and is relatively simple. Tag decoding is more
280 complex and mainly handled by QCBORDecode_GetNext(). Decoding of the
281 structure of tagged data not built-in (if there is any) has to be
282 implemented by the caller.
283
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700284 @anchor Floating-Point
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700285
286 ## Floating-Point
287
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700288 By default QCBOR fully supports IEEE 754 floating-point:
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700289 - Encode/decode of double, single and half-precision
290 - CBOR preferred serialization of floating-point
291 - Floating-point epoch dates
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700292
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700293 For the most part, the type double is used in the interface for
294 floating-point values. In the default configuration, all decoded
295 floating-point values are returned as a double.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700296
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700297 With CBOR preferred serialization, the encoder outputs the smallest
298 representation of the double or float that preserves precision. Zero,
299 NaN and infinity are always output as a half-precision, each taking
300 just 2 bytes. This reduces the number of bytes needed to encode
Laurence Lundblade4b270642020-08-14 12:53:07 -0700301 double and single-precision, especially if zero, NaN and infinity are
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700302 frequently used.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700303
Laurence Lundblade4b270642020-08-14 12:53:07 -0700304 To avoid use of preferred serialization in the standard configuration
305 when encoding, use QCBOREncode_AddDoubleNoPreferred() or
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700306 QCBOREncode_AddFloatNoPreferred().
307
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700308 This implementation of preferred floating-point serialization and
309 half-precision does not depend on the CPU having floating-point HW or
310 the compiler bringing in a (sometimes large) library to compensate
Laurence Lundblade4b270642020-08-14 12:53:07 -0700311 for lack of CPU support. This implementation uses shifts and masks
312 rather than floating-point functions.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700313
Laurence Lundblade4b270642020-08-14 12:53:07 -0700314 To reduce overall object code by about 900 bytes, define
315 QCBOR_DISABLE_PREFERRED_FLOAT. This will eliminate all support for
316 preferred serialization and half-precision. An error will be returned
317 when attempting to decode half-precision. A float will always be
318 encoded and decoded as 32-bits and a double will always be encoded
319 and decoded as 64 bits.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700320
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700321 Note that even if QCBOR_DISABLE_PREFERRED_FLOAT is not defined all
322 the float-point encoding object code can be avoided by never calling
Laurence Lundbladefe09bbf2020-07-16 12:14:51 -0700323 any functions that encode double or float. Just not calling
324 floating-point functions will reduce object code by about 500 bytes.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700325
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700326 On CPUs that have no floating-point hardware,
327 QCBOR_DISABLE_FLOAT_HW_USE should be defined in most cases. If it is
328 not, then the compiler will bring in possibly large software
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700329 libraries to compensate. Defining QCBOR_DISABLE_FLOAT_HW_USE reduces
330 object code size on CPUs with floating-point hardware by a tiny
331 amount and eliminates the need for <math.h>
Laurence Lundblade5fb6ab42020-07-16 03:28:47 -0700332
Laurence Lundblade4b270642020-08-14 12:53:07 -0700333 When QCBOR_DISABLE_FLOAT_HW_USE is defined, trying to decoding
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700334 floating-point dates will give error
335 @ref QCBOR_ERR_FLOAT_DATE_DISABLED and decoded single-precision
336 numbers will be returned as @ref QCBOR_TYPE_FLOAT instead of
337 converting them to double as usual.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700338
339 If both QCBOR_DISABLE_FLOAT_HW_USE and QCBOR_DISABLE_PREFERRED_FLOAT
Laurence Lundblade4b270642020-08-14 12:53:07 -0700340 are defined, then the only thing QCBOR can do is encode/decode a C
341 float type as 32-bits and a C double type as 64-bits. Floating-point
342 epoch dates will be unsupported.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700343
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700344 ## Limitations
345
Michael Eckel5c531332020-03-02 01:35:30 +0100346 Summary Limits of this implementation:
347 - The entire encoded CBOR must fit into contiguous memory.
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700348 - Max size of encoded / decoded CBOR data is a few bytes less than @c UINT32_MAX (4GB).
Michael Eckel5c531332020-03-02 01:35:30 +0100349 - Max array / map nesting level when encoding / decoding is
350 @ref QCBOR_MAX_ARRAY_NESTING (this is typically 15).
351 - Max items in an array or map when encoding / decoding is
352 @ref QCBOR_MAX_ITEMS_IN_ARRAY (typically 65,536).
353 - Does not directly support labels in maps other than text strings & integers.
354 - Does not directly support integer labels greater than @c INT64_MAX.
355 - Epoch dates limited to @c INT64_MAX (+/- 292 billion years).
356 - Exponents for bigfloats and decimal integers are limited to @c INT64_MAX.
357 - Tags on labels are ignored during decoding.
Laurence Lundblade9a3b6252020-10-21 21:30:31 -0700358 - The maximum tag nesting is @c QCBOR_MAX_TAGS_PER_ITEM (typically 4).
Michael Eckel5c531332020-03-02 01:35:30 +0100359 - Works only on 32- and 64-bit CPUs (modifications could make it work
360 on 16-bit CPUs).
361
362 The public interface uses @c size_t for all lengths. Internally the
363 implementation uses 32-bit lengths by design to use less memory and
364 fit structures on the stack. This limits the encoded CBOR it can work
365 with to size @c UINT32_MAX (4GB) which should be enough.
366
367 This implementation assumes two's compliment integer machines. @c
368 <stdint.h> also requires this. It is possible to modify this
369 implementation for another integer representation, but all modern
370 machines seem to be two's compliment.
Michael Eckel5c531332020-03-02 01:35:30 +0100371 */
372
373
Laurence Lundblade825164e2020-10-22 20:18:06 -0700374/**
Michael Eckel5c531332020-03-02 01:35:30 +0100375 The size of the buffer to be passed to QCBOREncode_EncodeHead(). It is one
376 byte larger than sizeof(uint64_t) + 1, the actual maximum size of the
Laurence Lundblade825164e2020-10-22 20:18:06 -0700377 head of a CBOR data item because QCBOREncode_EncodeHead() needs
Michael Eckel5c531332020-03-02 01:35:30 +0100378 one extra byte to work.
379 */
380#define QCBOR_HEAD_BUFFER_SIZE (sizeof(uint64_t) + 2)
381
Michael Eckel5c531332020-03-02 01:35:30 +0100382
Laurence Lundblade9b334962020-08-27 10:55:53 -0700383/**
Laurence Lundblade825164e2020-10-22 20:18:06 -0700384 Output the full CBOR tag. See @ref CBORTags, @ref Tag-Usage and
385 @ref Tags-Overview.
Laurence Lundblade9b334962020-08-27 10:55:53 -0700386 */
387#define QCBOR_ENCODE_AS_TAG 0
388
389/**
Laurence Lundblade825164e2020-10-22 20:18:06 -0700390 Output only the 'borrowed' content format for the relevant tag.
391 See @ref CBORTags, @ref Tag-Usage and @ref Tags-Overview.
Laurence Lundblade9b334962020-08-27 10:55:53 -0700392 */
393#define QCBOR_ENCODE_AS_BORROWED 1
394
Michael Eckel5c531332020-03-02 01:35:30 +0100395
396/**
397 QCBOREncodeContext is the data type that holds context for all the
398 encoding functions. It is less than 200 bytes, so it can go on the
399 stack. The contents are opaque, and the caller should not access
400 internal members. A context may be re used serially as long as it is
401 re initialized.
402 */
403typedef struct _QCBOREncodeContext QCBOREncodeContext;
404
405
406/**
407 Initialize the encoder to prepare to encode some CBOR.
408
409 @param[in,out] pCtx The encoder context to initialize.
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800410 @param[in] Storage The buffer into which the encoded result
411 will be written.
Michael Eckel5c531332020-03-02 01:35:30 +0100412
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800413 Call this once at the start of an encoding of some CBOR. Then call
414 the many functions like QCBOREncode_AddInt64() and
415 QCBOREncode_AddText() to add the different data items. Finally, call
416 QCBOREncode_Finish() to get the pointer and length of the encoded
417 result.
Michael Eckel5c531332020-03-02 01:35:30 +0100418
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800419 The primary purpose of this function is to give the pointer and
420 length of the output buffer into which the encoded CBOR will be
421 written. This is done with a @ref UsefulBuf structure, which is just
422 a pointer and length (it is equivalent to two parameters, one a
423 pointer and one a length, but a little prettier).
Michael Eckel5c531332020-03-02 01:35:30 +0100424
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800425 The output buffer can be allocated any way (malloc, stack,
426 static). It is just some memory that QCBOR writes to. The length must
427 be the length of the allocated buffer. QCBOR will never write past
428 that length, but might write up to that length. If the buffer is too
429 small, encoding will go into an error state and not write anything
430 further.
431
432 If allocating on the stack the convenience macro
433 UsefulBuf_MAKE_STACK_UB() can be used, but its use is not required.
434
435 Since there is no reallocation or such, the output buffer must be
436 correctly sized when passed in here. It is OK, but wasteful if it is
437 too large. One way to pick the size is to figure out the maximum size
438 that will ever be needed and hard code a buffer of that size.
439
440 Another way to do it is to have QCBOR calculate it for you. To do
441 this set @c Storage.ptr to @c NULL and @c Storage.len to @c
442 UINT32_MAX. Then call all the functions to add the CBOR exactly as if
443 encoding for real. Then call QCBOREncode_Finish(). The pointer
444 returned will be @c NULL, but the length returned is that of what would
445 be encoded. Once the length is obtained, allocate a buffer of that
446 size, call QCBOREncode_Init() again with the real buffer. Call all
447 the add functions again and finally, QCBOREncode_Finish() to obtain
448 the final result. This uses almost twice the CPU time, but that is
449 usually not an issue.
450
451 See QCBOREncode_Finish() for how the pointer and length for the
452 encoded CBOR is returned.
453
454 The maximum output buffer size allowed is @c UINT32_MAX (4GB). The
455 error @ref QCBOR_ERR_BUFFER_TOO_LARGE will be returned by
456 QCBOREncode_Finish() if a larger buffer length is passed in.
Michael Eckel5c531332020-03-02 01:35:30 +0100457
458 A @ref QCBOREncodeContext can be reused over and over as long as
Laurence Lundblade8510f8c2020-12-01 11:31:16 -0800459 QCBOREncode_Init() is called before each use.
Michael Eckel5c531332020-03-02 01:35:30 +0100460 */
461void QCBOREncode_Init(QCBOREncodeContext *pCtx, UsefulBuf Storage);
462
463
464/**
465 @brief Add a signed 64-bit integer to the encoded output.
466
467 @param[in] pCtx The encoding context to add the integer to.
468 @param[in] nNum The integer to add.
469
470 The integer will be encoded and added to the CBOR output.
471
472 This function figures out the size and the sign and encodes in the
473 correct minimal CBOR. Specifically, it will select CBOR major type 0
474 or 1 based on sign and will encode to 1, 2, 4 or 8 bytes depending on
475 the value of the integer. Values less than 24 effectively encode to
476 one byte because they are encoded in with the CBOR major type. This
477 is a neat and efficient characteristic of CBOR that can be taken
478 advantage of when designing CBOR-based protocols. If integers like
479 tags can be kept between -23 and 23 they will be encoded in one byte
480 including the major type.
481
482 If you pass a smaller int, say an @c int16_t or a small value, say
483 100, the encoding will still be CBOR's most compact that can
484 represent the value. For example, CBOR always encodes the value 0 as
485 one byte, 0x00. The representation as 0x00 includes identification of
486 the type as an integer too as the major type for an integer is 0. See
Laurence Lundbladec02e13e2020-12-06 05:45:41 -0800487 [RFC 8949] (https://tools.ietf.org/html/rfc8949) Appendix A for more
488 examples of CBOR encoding. This compact encoding is also preferred
489 serialization CBOR as per section 34.1 in RFC 8949.
Michael Eckel5c531332020-03-02 01:35:30 +0100490
491 There are no functions to add @c int16_t or @c int32_t because they
492 are not necessary because this always encodes to the smallest number
493 of bytes based on the value (If this code is running on a 32-bit
494 machine having a way to add 32-bit integers would reduce code size
495 some).
496
497 If the encoding context is in an error state, this will do
498 nothing. If an error occurs when adding this integer, the internal
499 error flag will be set, and the error will be returned when
500 QCBOREncode_Finish() is called.
501
502 See also QCBOREncode_AddUInt64().
503 */
504void QCBOREncode_AddInt64(QCBOREncodeContext *pCtx, int64_t nNum);
505
506static void QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum);
507
508static void QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum);
509
510
511/**
512 @brief Add an unsigned 64-bit integer to the encoded output.
513
514 @param[in] pCtx The encoding context to add the integer to.
515 @param[in] uNum The integer to add.
516
517 The integer will be encoded and added to the CBOR output.
518
519 The only reason so use this function is for integers larger than @c
520 INT64_MAX and smaller than @c UINT64_MAX. Otherwise
521 QCBOREncode_AddInt64() will work fine.
522
523 Error handling is the same as for QCBOREncode_AddInt64().
524 */
525void QCBOREncode_AddUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
526
527static void QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum);
528
529static void QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum);
530
531
532/**
533 @brief Add a UTF-8 text string to the encoded output.
534
535 @param[in] pCtx The encoding context to add the text to.
536 @param[in] Text Pointer and length of text to add.
537
538 The text passed in must be unencoded UTF-8 according to [RFC 3629]
539 (https://tools.ietf.org/html/rfc3629). There is no NULL
540 termination. The text is added as CBOR major type 3.
541
542 If called with @c nBytesLen equal to 0, an empty string will be
543 added. When @c nBytesLen is 0, @c pBytes may be @c NULL.
544
545 Note that the restriction of the buffer length to a @c uint32_t is
546 entirely intentional as this encoder is not capable of encoding
547 lengths greater. This limit to 4GB for a text string should not be a
548 problem.
549
Laurence Lundbladeadaf5c22020-09-25 10:37:09 -0700550 Text lines in Internet protocols (on the wire) are delimited by
551 either a CRLF or just an LF. Officially many protocols specify CRLF,
552 but implementations often work with either. CBOR type 3 text can be
553 either line ending, even a mixture of both.
554
555 Operating systems usually have a line end convention. Windows uses
556 CRLF. Linux and MacOS use LF. Some applications on a given OS may
557 work with either and some may not.
558
559 The majority of use cases and CBOR protocols using type 3 text will
560 work with either line ending. However, some use cases or protocols
561 may not work with either in which case translation to and/or from the
562 local line end convention, typically that of the OS, is necessary.
563
564 QCBOR does no line ending translation for type 3 text when encoding
565 and decoding.
566
Michael Eckel5c531332020-03-02 01:35:30 +0100567 Error handling is the same as QCBOREncode_AddInt64().
568 */
569static void QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text);
570
571static void QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text);
572
573static void QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text);
574
575
576/**
577 @brief Add a UTF-8 text string to the encoded output.
578
579 @param[in] pCtx The encoding context to add the text to.
580 @param[in] szString Null-terminated text to add.
581
582 This works the same as QCBOREncode_AddText().
583 */
584static void QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString);
585
586static void QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString);
587
588static void QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString);
589
590
591/**
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700592 @brief Add a double-precision floating-point number to the encoded output.
Michael Eckel5c531332020-03-02 01:35:30 +0100593
594 @param[in] pCtx The encoding context to add the double to.
595 @param[in] dNum The double-precision number to add.
596
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700597 This encodes and outputs a floating-point number. CBOR major type 7
598 is used.
Michael Eckel5c531332020-03-02 01:35:30 +0100599
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700600 This implements preferred serialization, selectively encoding the
601 double-precision floating-point number as either double-precision,
602 single-precision or half-precision. Infinity, NaN and 0 are always
603 encoded as half-precision. If no precision will be lost in the
604 conversion to half-precision, then it will be converted and
605 encoded. If not and no precision will be lost in conversion to
606 single-precision, then it will be converted and encoded. If not, then
607 no conversion is performed, and it encoded as a double-precision.
Michael Eckel5c531332020-03-02 01:35:30 +0100608
609 Half-precision floating-point numbers take up 2 bytes, half that of
610 single-precision, one quarter of double-precision
611
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700612 This automatically reduces the size of encoded CBOR, maybe even by
613 four if most of values are 0, infinity or NaN.
Michael Eckel5c531332020-03-02 01:35:30 +0100614
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700615 When decoded, QCBOR will usually return these values as
616 double-precision.
617
618 It is possible to disable this preferred serialization when compiling
619 QCBOR. In that case, this functions the same as
620 QCBOREncode_AddDoubleNoPreferred().
Michael Eckel5c531332020-03-02 01:35:30 +0100621
622 Error handling is the same as QCBOREncode_AddInt64().
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700623
624 See also QCBOREncode_AddDoubleNoPreferred(), QCBOREncode_AddFloat()
625 and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
Michael Eckel5c531332020-03-02 01:35:30 +0100626 */
627void QCBOREncode_AddDouble(QCBOREncodeContext *pCtx, double dNum);
628
629static void QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
630
631static void QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
632
633
634/**
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700635 @brief Add a single-precision floating-point number to the encoded output.
636
637 @param[in] pCtx The encoding context to add the double to.
638 @param[in] fNum The single-precision number to add.
639
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700640 This is identical to QCBOREncode_AddDouble() except the input is
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700641 single-precision.
642
643 See also QCBOREncode_AddDouble(), QCBOREncode_AddDoubleNoPreferred(),
644 and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
645*/
646void QCBOREncode_AddFloat(QCBOREncodeContext *pCtx, float fNum);
647
648static void QCBOREncode_AddFloatToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
649
650static void QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700651
652
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700653/**
654 @brief Add a double-precision floating-point number without preferred encoding.
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700655
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700656 @param[in] pCtx The encoding context to add the double to.
657 @param[in] dNum The double-precision number to add.
658
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700659 This always outputs the number as a 64-bit double-precision.
660 Preferred serialization is not used.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700661
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700662 Error handling is the same as QCBOREncode_AddInt64().
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700663
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700664 See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
665 QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700666*/
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700667void QCBOREncode_AddDoubleNoPreferred(QCBOREncodeContext *pCtx, double dNum);
668
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700669static void QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
670
671static void QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
672
673
674/**
675 @brief Add a single-precision floating-point number without preferred encoding.
676
677 @param[in] pCtx The encoding context to add the double to.
678 @param[in] fNum The single-precision number to add.
679
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700680 This always outputs the number as a 32-bit single-precision.
681 Preferred serialization is not used.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700682
683 Error handling is the same as QCBOREncode_AddInt64().
684
Laurence Lundblade3ed0bca2020-07-14 22:50:10 -0700685 See also QCBOREncode_AddDouble(), QCBOREncode_AddFloat(), and
686 QCBOREncode_AddDoubleNoPreferred() and @ref Floating-Point.
Laurence Lundblade32f3e622020-07-13 20:35:11 -0700687*/
688void QCBOREncode_AddFloatNoPreferred(QCBOREncodeContext *pCtx, float fNum);
689
690static void QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, float fNum);
691
692static void QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float fNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -0700693
694
Michael Eckel5c531332020-03-02 01:35:30 +0100695/**
696 @brief Add an optional tag.
697
698 @param[in] pCtx The encoding context to add the tag to.
699 @param[in] uTag The tag to add
700
701 This outputs a CBOR major type 6 item that tags the next data item
702 that is output usually to indicate it is some new data type.
703
704 For many of the common standard tags, a function to encode data using
705 it is provided and this is not needed. For example,
706 QCBOREncode_AddDateEpoch() already exists to output integers
707 representing dates with the right tag.
708
709 The tag is applied to the next data item added to the encoded
710 output. That data item that is to be tagged can be of any major CBOR
711 type. Any number of tags can be added to a data item by calling this
712 multiple times before the data item is added.
713
714 See @ref Tags-Overview for discussion of creating new non-standard
715 tags. See QCBORDecode_GetNext() for discussion of decoding custom
716 tags.
717*/
Laurence Lundblade6416a0f2020-09-19 23:26:34 -0700718void QCBOREncode_AddTag(QCBOREncodeContext *pCtx, uint64_t uTag);
Michael Eckel5c531332020-03-02 01:35:30 +0100719
720
721/**
722 @brief Add an epoch-based date.
723
724 @param[in] pCtx The encoding context to add the date to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700725 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700726 @param[in] nDate Number of seconds since 1970-01-01T00:00Z in UTC time.
Michael Eckel5c531332020-03-02 01:35:30 +0100727
Laurence Lundbladec02e13e2020-12-06 05:45:41 -0800728 As per RFC 8949 this is similar to UNIX/Linux/POSIX dates. This is
Michael Eckel5c531332020-03-02 01:35:30 +0100729 the most compact way to specify a date and time in CBOR. Note that
730 this is always UTC and does not include the time zone. Use
731 QCBOREncode_AddDateString() if you want to include the time zone.
732
Laurence Lundblade46d63e92021-05-13 11:37:10 -0700733 The preferred integer encoding rules apply here so the date will be encoded in
Michael Eckel5c531332020-03-02 01:35:30 +0100734 a minimal number of bytes. Until about the year 2106 these dates will
735 encode in 6 bytes -- one byte for the tag, one byte for the type and
736 4 bytes for the integer. After that it will encode to 10 bytes.
737
738 Negative values are supported for dates before 1970.
739
740 If you care about leap-seconds and that level of accuracy, make sure
741 the system you are running this code on does it correctly. This code
742 just takes the value passed in.
743
744 This implementation cannot encode fractional seconds using float or
745 double even though that is allowed by CBOR, but you can encode them
Laurence Lundblade46d63e92021-05-13 11:37:10 -0700746 if you want to by calling QCBOREncode_AddTag() and QCBOREncode_AddDouble().
Michael Eckel5c531332020-03-02 01:35:30 +0100747
748 Error handling is the same as QCBOREncode_AddInt64().
Laurence Lundblade46d63e92021-05-13 11:37:10 -0700749
750 See also QCBOREncode_AddTDaysEpoch().
Michael Eckel5c531332020-03-02 01:35:30 +0100751 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700752static void QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pCtx,
753 uint8_t uTagRequirement,
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700754 int64_t nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -0700755
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700756static void QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pCtx,
757 const char *szLabel,
758 uint8_t uTagRequirement,
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700759 int64_t nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -0700760
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700761static void QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pCtx,
762 int64_t nLabel,
763 uint8_t uTagRequirement,
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700764 int64_t nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -0700765
766
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700767static void QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx,
768 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100769
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700770static void QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx,
771 const char *szLabel,
772 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100773
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700774static void QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx,
775 int64_t nLabel,
776 int64_t nDate);
Michael Eckel5c531332020-03-02 01:35:30 +0100777
778
Laurence Lundblade46d63e92021-05-13 11:37:10 -0700779
780/**
781 @brief Add an epoch-based day-count date.
782
783 @param[in] pCtx The encoding context to add the date to.
784 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
785 @ref QCBOR_ENCODE_AS_BORROWED.
786 @param[in] nDays Number of days before or after 1970-01-0.
787
788 This date format is described in
789 [RFC 8943] (https://tools.ietf.org/html/rfc8943).
790
791 The integer encoding rules apply here so the date will be encoded in
792 a minimal number of bytes. Until about the year 2149 these dates will
793 encode in 4 bytes -- one byte for the tag, one byte for the type and
794 2 bytes for the integer.
795
796 See also QCBOREncode_AddTDateEpoch().
797
798*/
799static void QCBOREncode_AddTDaysEpoch(QCBOREncodeContext *pCtx,
800 uint8_t uTagRequirement,
801 int64_t nDays);
802
803static void QCBOREncode_AddTDaysEpochToMapSZ(QCBOREncodeContext *pCtx,
804 const char *szLabel,
805 uint8_t uTagRequirement,
806 int64_t nDays);
807
808static void QCBOREncode_AddTDaysEpochToMapN(QCBOREncodeContext *pCtx,
809 int64_t nLabel,
810 uint8_t uTagRequirement,
811 int64_t nDays);
812
813
814
815
Michael Eckel5c531332020-03-02 01:35:30 +0100816/**
817 @brief Add a byte string to the encoded output.
818
819 @param[in] pCtx The encoding context to add the bytes to.
820 @param[in] Bytes Pointer and length of the input data.
821
822 Simply adds the bytes to the encoded output as CBOR major type 2.
823
824 If called with @c Bytes.len equal to 0, an empty string will be
825 added. When @c Bytes.len is 0, @c Bytes.ptr may be @c NULL.
826
827 Error handling is the same as QCBOREncode_AddInt64().
828 */
829static void QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
830
831static void QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
832
833static void QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
834
835
Michael Eckel5c531332020-03-02 01:35:30 +0100836/**
837 @brief Add a binary UUID to the encoded output.
838
839 @param[in] pCtx The encoding context to add the UUID to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700840 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100841 @param[in] Bytes Pointer and length of the binary UUID.
842
843 A binary UUID as defined in [RFC 4122]
844 (https://tools.ietf.org/html/rfc4122) is added to the output.
845
846 It is output as CBOR major type 2, a binary string, with tag @ref
847 CBOR_TAG_BIN_UUID indicating the binary string is a UUID.
848 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700849static void QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pCtx,
850 uint8_t uTagRequirement,
851 UsefulBufC Bytes);
852
853static void QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pCtx,
854 const char *szLabel,
855 uint8_t uTagRequirement,
856 UsefulBufC Bytes);
857
858static void QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pCtx,
859 int64_t nLabel,
860 uint8_t uTagRequirement,
861 UsefulBufC Bytes);
862
863
Michael Eckel5c531332020-03-02 01:35:30 +0100864static void QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
865
866static void QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
867
868static void QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
869
870
871/**
872 @brief Add a positive big number to the encoded output.
873
874 @param[in] pCtx The encoding context to add the big number to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700875 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100876 @param[in] Bytes Pointer and length of the big number.
877
878 Big numbers are integers larger than 64-bits. Their format is
Laurence Lundbladec02e13e2020-12-06 05:45:41 -0800879 described in [RFC 8949] (https://tools.ietf.org/html/rfc8949).
Michael Eckel5c531332020-03-02 01:35:30 +0100880
881 It is output as CBOR major type 2, a binary string, with tag @ref
882 CBOR_TAG_POS_BIGNUM indicating the binary string is a positive big
883 number.
884
885 Often big numbers are used to represent cryptographic keys, however,
886 COSE which defines representations for keys chose not to use this
887 particular type.
888 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700889static void QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pCtx,
890 uint8_t uTagRequirement,
891 UsefulBufC Bytes);
892
893static void QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pCtx,
894 const char *szLabel,
895 uint8_t uTagRequirement,
896 UsefulBufC Bytes);
897
898static void QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pCtx,
899 int64_t nLabel,
900 uint8_t uTagRequirement,
901 UsefulBufC Bytes);
902
903
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700904static void QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx,
905 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100906
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700907static void QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx,
908 const char *szLabel,
909 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100910
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700911static void QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx,
912 int64_t nLabel,
913 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100914
915
916/**
917 @brief Add a negative big number to the encoded output.
918
919 @param[in] pCtx The encoding context to add the big number to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700920 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100921 @param[in] Bytes Pointer and length of the big number.
922
923 Big numbers are integers larger than 64-bits. Their format is
Laurence Lundbladec02e13e2020-12-06 05:45:41 -0800924 described in [RFC 8949] (https://tools.ietf.org/html/rfc8949).
Michael Eckel5c531332020-03-02 01:35:30 +0100925
926 It is output as CBOR major type 2, a binary string, with tag @ref
927 CBOR_TAG_NEG_BIGNUM indicating the binary string is a negative big
928 number.
929
930 Often big numbers are used to represent cryptographic keys, however,
931 COSE which defines representations for keys chose not to use this
932 particular type.
933 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700934static void QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pCtx,
935 uint8_t uTagRequirement,
936 UsefulBufC Bytes);
937
938static void QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pCtx,
939 const char *szLabel,
940 uint8_t uTagRequirement,
941 UsefulBufC Bytes);
942
943static void QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pCtx,
944 int64_t nLabel,
945 uint8_t uTagRequirement,
946 UsefulBufC Bytes);
947
948
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700949static void QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx,
950 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100951
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700952static void QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx,
953 const char *szLabel,
954 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100955
Laurence Lundblade45d5e482020-09-15 21:15:15 -0700956static void QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx,
957 int64_t nLabel,
958 UsefulBufC Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +0100959
960
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -0700961#ifndef QCBOR_DISABLE_EXP_AND_MANTISSA
Michael Eckel5c531332020-03-02 01:35:30 +0100962/**
963 @brief Add a decimal fraction to the encoded output.
964
965 @param[in] pCtx The encoding context to add the decimal fraction to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700966 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +0100967 @param[in] nMantissa The mantissa.
968 @param[in] nBase10Exponent The exponent.
969
970 The value is nMantissa * 10 ^ nBase10Exponent.
971
972 A decimal fraction is good for exact representation of some values
973 that can't be represented exactly with standard C (IEEE 754)
974 floating-point numbers. Much larger and much smaller numbers can
975 also be represented than floating-point because of the larger number
976 of bits in the exponent.
977
978 The decimal fraction is conveyed as two integers, a mantissa and a
979 base-10 scaling factor.
980
981 For example, 273.15 is represented by the two integers 27315 and -2.
982
983 The exponent and mantissa have the range from @c INT64_MIN to
984 @c INT64_MAX for both encoding and decoding (CBOR allows @c -UINT64_MAX
985 to @c UINT64_MAX, but this implementation doesn't support this range to
986 reduce code size and interface complexity a little).
987
988 CBOR Preferred encoding of the integers is used, thus they will be encoded
989 in the smallest number of bytes possible.
990
991 See also QCBOREncode_AddDecimalFractionBigNum() for a decimal
992 fraction with arbitrarily large precision and QCBOREncode_AddBigFloat().
993
994 There is no representation of positive or negative infinity or NaN
995 (Not a Number). Use QCBOREncode_AddDouble() to encode them.
996
997 See @ref expAndMantissa for decoded representation.
998 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -0700999static void QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pCtx,
1000 uint8_t uTagRequirement,
1001 int64_t nMantissa,
1002 int64_t nBase10Exponent);
1003
1004static void QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001005 const char *szLabel,
1006 uint8_t uTagRequirement,
1007 int64_t nMantissa,
1008 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001009
1010static void QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pCtx,
1011 int64_t nLabel,
1012 uint8_t uTagRequirement,
1013 int64_t nMantissa,
1014 int64_t nBase10Exponent);
1015
1016
Michael Eckel5c531332020-03-02 01:35:30 +01001017static void QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pCtx,
1018 int64_t nMantissa,
1019 int64_t nBase10Exponent);
1020
1021static void QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pCtx,
1022 const char *szLabel,
1023 int64_t nMantissa,
1024 int64_t nBase10Exponent);
1025
1026static void QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pCtx,
1027 int64_t nLabel,
1028 int64_t nMantissa,
1029 int64_t nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01001030/**
1031 @brief Add a decimal fraction with a big number mantissa to the encoded output.
1032
1033 @param[in] pCtx The encoding context to add the decimal fraction to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001034 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001035 @param[in] Mantissa The mantissa.
1036 @param[in] bIsNegative false if mantissa is positive, true if negative.
1037 @param[in] nBase10Exponent The exponent.
1038
1039 This is the same as QCBOREncode_AddDecimalFraction() except the
1040 mantissa is a big number (See QCBOREncode_AddPositiveBignum())
1041 allowing for arbitrarily large precision.
1042
1043 See @ref expAndMantissa for decoded representation.
1044 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001045static void QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pCtx,
1046 uint8_t uTagRequirement,
1047 UsefulBufC Mantissa,
1048 bool bIsNegative,
1049 int64_t nBase10Exponent);
1050
1051static void QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001052 const char *szLabel,
1053 uint8_t uTagRequirement,
1054 UsefulBufC Mantissa,
1055 bool bIsNegative,
1056 int64_t nBase10Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001057
1058static void QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
1059 int64_t nLabel,
1060 uint8_t uTagRequirement,
1061 UsefulBufC Mantissa,
1062 bool bIsNegative,
1063 int64_t nBase10Exponent);
1064
1065
Michael Eckel5c531332020-03-02 01:35:30 +01001066static void QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pCtx,
1067 UsefulBufC Mantissa,
1068 bool bIsNegative,
1069 int64_t nBase10Exponent);
1070
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001071static void QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001072 const char *szLabel,
1073 UsefulBufC Mantissa,
1074 bool bIsNegative,
1075 int64_t nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01001076
1077static void QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
1078 int64_t nLabel,
1079 UsefulBufC Mantissa,
1080 bool bIsNegative,
1081 int64_t nBase10Exponent);
1082
1083/**
1084 @brief Add a big floating-point number to the encoded output.
1085
1086 @param[in] pCtx The encoding context to add the bigfloat to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001087 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001088 @param[in] nMantissa The mantissa.
1089 @param[in] nBase2Exponent The exponent.
1090
1091 The value is nMantissa * 2 ^ nBase2Exponent.
1092
1093 "Bigfloats", as CBOR terms them, are similar to IEEE floating-point
1094 numbers in having a mantissa and base-2 exponent, but they are not
1095 supported by hardware or encoded the same. They explicitly use two
1096 CBOR-encoded integers to convey the mantissa and exponent, each of which
1097 can be 8, 16, 32 or 64 bits. With both the mantissa and exponent
1098 64 bits they can express more precision and a larger range than an
1099 IEEE double floating-point number. See
1100 QCBOREncode_AddBigFloatBigNum() for even more precision.
1101
1102 For example, 1.5 would be represented by a mantissa of 3 and an
1103 exponent of -1.
1104
1105 The exponent and mantissa have the range from @c INT64_MIN to
1106 @c INT64_MAX for both encoding and decoding (CBOR allows @c -UINT64_MAX
1107 to @c UINT64_MAX, but this implementation doesn't support this range to
1108 reduce code size and interface complexity a little).
1109
1110 CBOR Preferred encoding of the integers is used, thus they will be encoded
1111 in the smallest number of bytes possible.
1112
1113 This can also be used to represent floating-point numbers in
1114 environments that don't support IEEE 754.
1115
1116 See @ref expAndMantissa for decoded representation.
1117 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001118static void QCBOREncode_AddTBigFloat(QCBOREncodeContext *pCtx,
1119 uint8_t uTagRequirement,
1120 int64_t nMantissa,
1121 int64_t nBase2Exponent);
1122
1123static void QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001124 const char *szLabel,
1125 uint8_t uTagRequirement,
1126 int64_t nMantissa,
1127 int64_t nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001128
1129static void QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pCtx,
1130 int64_t nLabel,
1131 uint8_t uTagRequirement,
1132 int64_t nMantissa,
1133 int64_t nBase2Exponent);
1134
1135
Michael Eckel5c531332020-03-02 01:35:30 +01001136static void QCBOREncode_AddBigFloat(QCBOREncodeContext *pCtx,
1137 int64_t nMantissa,
1138 int64_t nBase2Exponent);
1139
1140static void QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pCtx,
1141 const char *szLabel,
1142 int64_t nMantissa,
1143 int64_t nBase2Exponent);
1144
1145static void QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pCtx,
1146 int64_t nLabel,
1147 int64_t nMantissa,
1148 int64_t nBase2Exponent);
1149
Michael Eckel5c531332020-03-02 01:35:30 +01001150/**
1151 @brief Add a big floating-point number with a big number mantissa to
1152 the encoded output.
1153
1154 @param[in] pCtx The encoding context to add the bigfloat to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001155 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001156 @param[in] Mantissa The mantissa.
1157 @param[in] bIsNegative false if mantissa is positive, true if negative.
1158 @param[in] nBase2Exponent The exponent.
1159
1160 This is the same as QCBOREncode_AddBigFloat() except the mantissa is
1161 a big number (See QCBOREncode_AddPositiveBignum()) allowing for
1162 arbitrary precision.
1163
1164 See @ref expAndMantissa for decoded representation.
1165 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001166static void QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pCtx,
1167 uint8_t uTagRequirement,
1168 UsefulBufC Mantissa,
1169 bool bIsNegative,
1170 int64_t nBase2Exponent);
1171
1172static void QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pCtx,
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07001173 const char *szLabel,
1174 uint8_t uTagRequirement,
1175 UsefulBufC Mantissa,
1176 bool bIsNegative,
1177 int64_t nBase2Exponent);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001178
1179static void QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1180 int64_t nLabel,
1181 uint8_t uTagRequirement,
1182 UsefulBufC Mantissa,
1183 bool bIsNegative,
1184 int64_t nBase2Exponent);
1185
1186
Michael Eckel5c531332020-03-02 01:35:30 +01001187static void QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pCtx,
1188 UsefulBufC Mantissa,
1189 bool bIsNegative,
1190 int64_t nBase2Exponent);
1191
1192static void QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pCtx,
1193 const char *szLabel,
1194 UsefulBufC Mantissa,
1195 bool bIsNegative,
1196 int64_t nBase2Exponent);
1197
1198static void QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1199 int64_t nLabel,
1200 UsefulBufC Mantissa,
1201 bool bIsNegative,
1202 int64_t nBase2Exponent);
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07001203#endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
Michael Eckel5c531332020-03-02 01:35:30 +01001204
1205
1206/**
1207 @brief Add a text URI to the encoded output.
1208
1209 @param[in] pCtx The encoding context to add the URI to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001210 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001211 @param[in] URI Pointer and length of the URI.
1212
1213 The format of URI must be per [RFC 3986]
1214 (https://tools.ietf.org/html/rfc3986).
1215
1216 It is output as CBOR major type 3, a text string, with tag @ref
1217 CBOR_TAG_URI indicating the text string is a URI.
1218
1219 A URI in a NULL-terminated string, @c szURI, can be easily added with
1220 this code:
1221
1222 QCBOREncode_AddURI(pCtx, UsefulBuf_FromSZ(szURI));
1223 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001224static void QCBOREncode_AddTURI(QCBOREncodeContext *pCtx,
1225 uint8_t uTagRequirement,
1226 UsefulBufC URI);
1227
1228static void QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pCtx,
1229 const char *szLabel,
1230 uint8_t uTagRequirement,
1231 UsefulBufC URI);
1232
1233static void QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pCtx,
1234 int64_t nLabel,
1235 uint8_t uTagRequirement,
1236 UsefulBufC URI);
1237
1238
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001239static void QCBOREncode_AddURI(QCBOREncodeContext *pCtx,
1240 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001241
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001242static void QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx,
1243 const char *szLabel,
1244 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001245
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001246static void QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx,
1247 int64_t nLabel,
1248 UsefulBufC URI);
Michael Eckel5c531332020-03-02 01:35:30 +01001249
1250
1251/**
1252 @brief Add Base64-encoded text to encoded output.
1253
1254 @param[in] pCtx The encoding context to add the base-64 text to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001255 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001256 @param[in] B64Text Pointer and length of the base-64 encoded text.
1257
1258 The text content is Base64 encoded data per [RFC 4648]
1259 (https://tools.ietf.org/html/rfc4648).
1260
1261 It is output as CBOR major type 3, a text string, with tag @ref
1262 CBOR_TAG_B64 indicating the text string is Base64 encoded.
1263 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001264static void QCBOREncode_AddTB64Text(QCBOREncodeContext *pCtx,
1265 uint8_t uTagRequirement,
1266 UsefulBufC B64Text);
1267
1268static void QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pCtx,
1269 const char *szLabel,
1270 uint8_t uTagRequirement,
1271 UsefulBufC B64Text);
1272
1273static void QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pCtx,
1274 int64_t nLabel,
1275 uint8_t uTagRequirement,
1276 UsefulBufC B64Text);
1277
1278
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001279static void QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx,
1280 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001281
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001282static void QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx,
1283 const char *szLabel,
1284 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001285
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001286static void QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx,
1287 int64_t nLabel,
1288 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001289
1290
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001291
Michael Eckel5c531332020-03-02 01:35:30 +01001292/**
1293 @brief Add base64url encoded data to encoded output.
1294
1295 @param[in] pCtx The encoding context to add the base64url to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001296 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001297 @param[in] B64Text Pointer and length of the base64url encoded text.
1298
1299 The text content is base64URL encoded text as per [RFC 4648]
1300 (https://tools.ietf.org/html/rfc4648).
1301
1302 It is output as CBOR major type 3, a text string, with tag @ref
1303 CBOR_TAG_B64URL indicating the text string is a Base64url encoded.
1304 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001305static void QCBOREncode_AddTB64URLText(QCBOREncodeContext *pCtx,
1306 uint8_t uTagRequirement,
1307 UsefulBufC B64Text);
1308
1309static void QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pCtx,
1310 const char *szLabel,
1311 uint8_t uTagRequirement,
1312 UsefulBufC B64Text);
1313
1314static void QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pCtx,
1315 int64_t nLabel,
1316 uint8_t uTagRequirement,
1317 UsefulBufC B64Text);
1318
1319
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001320static void QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx,
1321 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001322
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001323static void QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx,
1324 const char *szLabel,
1325 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001326
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001327static void QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx,
1328 int64_t nLabel,
1329 UsefulBufC B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01001330
1331
1332/**
1333 @brief Add Perl Compatible Regular Expression.
1334
1335 @param[in] pCtx The encoding context to add the regular expression to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001336 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001337 @param[in] Regex Pointer and length of the regular expression.
1338
1339 The text content is Perl Compatible Regular
1340 Expressions (PCRE) / JavaScript syntax [ECMA262].
1341
1342 It is output as CBOR major type 3, a text string, with tag @ref
1343 CBOR_TAG_REGEX indicating the text string is a regular expression.
1344 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001345static void QCBOREncode_AddTRegex(QCBOREncodeContext *pCtx,
1346 uint8_t uTagRequirement,
1347 UsefulBufC Regex);
1348
1349static void QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pCtx,
1350 const char *szLabel,
1351 uint8_t uTagRequirement,
1352 UsefulBufC Regex);
1353
1354static void QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pCtx,
1355 int64_t nLabel,
1356 uint8_t uTagRequirement,
1357 UsefulBufC Regex);
1358
1359
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001360static void QCBOREncode_AddRegex(QCBOREncodeContext *pCtx,
1361 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001362
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001363static void QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx,
1364 const char *szLabel,
1365 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001366
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001367static void QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx,
1368 int64_t nLabel,
1369 UsefulBufC Regex);
Michael Eckel5c531332020-03-02 01:35:30 +01001370
1371
1372/**
Laurence Lundblade4982f412020-09-18 23:02:18 -07001373 @brief MIME encoded data to the encoded output.
Michael Eckel5c531332020-03-02 01:35:30 +01001374
Laurence Lundblade4982f412020-09-18 23:02:18 -07001375 @param[in] pCtx The encoding context to add the MIME data to.
1376 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1377 @ref QCBOR_ENCODE_AS_BORROWED.
1378 @param[in] MIMEData Pointer and length of the MIME data.
Michael Eckel5c531332020-03-02 01:35:30 +01001379
1380 The text content is in MIME format per [RFC 2045]
Laurence Lundblade4982f412020-09-18 23:02:18 -07001381 (https://tools.ietf.org/html/rfc2045) including the headers.
Michael Eckel5c531332020-03-02 01:35:30 +01001382
Laurence Lundblade4982f412020-09-18 23:02:18 -07001383 It is output as CBOR major type 2, a binary string, with tag @ref
1384 CBOR_TAG_BINARY_MIME indicating the string is MIME data. This
1385 outputs tag 257, not tag 36, as it can carry any type of MIME binary,
1386 7-bit, 8-bit, quoted-printable and base64 where tag 36 cannot.
1387
1388 Previous versions of QCBOR, those before spiffy decode, output tag
1389 36. Decoding supports both tag 36 and 257. (if the old behavior with
1390 tag 36 is needed, copy the inline functions below and change the tag
1391 number).
1392
1393 See also QCBORDecode_GetMIMEMessage() and
1394 @ref QCBOR_TYPE_BINARY_MIME.
Laurence Lundbladeadaf5c22020-09-25 10:37:09 -07001395
1396 This does no translation of line endings. See QCBOREncode_AddText()
1397 for a discussion of line endings in CBOR.
Michael Eckel5c531332020-03-02 01:35:30 +01001398 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001399static void QCBOREncode_AddTMIMEData(QCBOREncodeContext *pCtx,
1400 uint8_t uTagRequirement,
1401 UsefulBufC MIMEData);
1402
1403static void QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pCtx,
1404 const char *szLabel,
1405 uint8_t uTagRequirement,
1406 UsefulBufC MIMEData);
1407
1408static void QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pCtx,
1409 int64_t nLabel,
1410 uint8_t uTagRequirement,
1411 UsefulBufC MIMEData);
1412
1413
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001414static void QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx,
1415 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001416
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001417static void QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx,
1418 const char *szLabel,
1419 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001420
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001421static void QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx,
1422 int64_t nLabel,
1423 UsefulBufC MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01001424
1425
1426/**
1427 @brief Add an RFC 3339 date string
1428
1429 @param[in] pCtx The encoding context to add the date to.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001430 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
Michael Eckel5c531332020-03-02 01:35:30 +01001431 @param[in] szDate Null-terminated string with date to add.
1432
1433 The string szDate should be in the form of [RFC 3339]
1434 (https://tools.ietf.org/html/rfc3339) as defined by section 3.3 in
1435 [RFC 4287] (https://tools.ietf.org/html/rfc4287). This is as
Laurence Lundbladec02e13e2020-12-06 05:45:41 -08001436 described in section 3.4.1 in [RFC 8949]
1437 (https://tools.ietf.org/html/rfc8949).
Michael Eckel5c531332020-03-02 01:35:30 +01001438
1439 Note that this function doesn't validate the format of the date string
1440 at all. If you add an incorrect format date string, the generated
1441 CBOR will be incorrect and the receiver may not be able to handle it.
1442
1443 Error handling is the same as QCBOREncode_AddInt64().
Laurence Lundblade46d63e92021-05-13 11:37:10 -07001444
1445 See also QCBOREncode_AddTDayString().
Michael Eckel5c531332020-03-02 01:35:30 +01001446 */
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07001447static void QCBOREncode_AddTDateString(QCBOREncodeContext *pCtx,
1448 uint8_t uTagRequirement,
1449 const char *szDate);
1450
1451static void QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pCtx,
1452 const char *szLabel,
1453 uint8_t uTagRequirement,
1454 const char *szDate);
1455
1456static void QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pCtx,
1457 int64_t nLabel,
1458 uint8_t uTagRequirement,
1459 const char *szDate);
1460
1461
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001462static void QCBOREncode_AddDateString(QCBOREncodeContext *pCtx,
1463 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001464
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001465static void QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx,
1466 const char *szLabel,
1467 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001468
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001469static void QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx,
1470 int64_t nLabel,
1471 const char *szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01001472
Laurence Lundblade46d63e92021-05-13 11:37:10 -07001473
1474/**
1475 @brief Add a date-only string.
1476
1477 @param[in] pCtx The encoding context to add the date to.
1478 @param[in] uTagRequirement Either @ref QCBOR_ENCODE_AS_TAG or
1479 @ref QCBOR_ENCODE_AS_BORROWED.
1480 @param[in] szDate Null-terminated string with date to add.
1481
1482 This date format is described in
1483 [RFC 8943] (https://tools.ietf.org/html/rfc8943), but that mainly
1484 references RFC 3339. The string szDate must be in the forrm
1485 specified the ABNF for a full-date in
1486 [RFC 3339] (https://tools.ietf.org/html/rfc3339). Examples of this
1487 are "1985-04-12" and "1937-01-01". The time and the time zone are
1488 never included.
1489
1490 Note that this function doesn't validate the format of the date
1491 string at all. If you add an incorrect format date string, the
1492 generated CBOR will be incorrect and the receiver may not be able to
1493 handle it.
1494
1495 Error handling is the same as QCBOREncode_AddInt64().
1496
1497 See also QCBOREncode_AddTDateString().
1498 */
1499static void
1500QCBOREncode_AddTDaysString(QCBOREncodeContext *pCtx,
1501 uint8_t uTagRequirement,
1502 const char *szDate);
1503
1504static void
1505QCBOREncode_AddTDaysStringToMapSZ(QCBOREncodeContext *pCtx,
1506 const char *szLabel,
1507 uint8_t uTagRequirement,
1508 const char *szDate);
1509
1510static void
1511QCBOREncode_AddTDaysStringToMapN(QCBOREncodeContext *pCtx,
1512 int64_t nLabel,
1513 uint8_t uTagRequirement,
1514 const char *szDate);
1515
1516
Michael Eckel5c531332020-03-02 01:35:30 +01001517/**
1518 @brief Add a standard Boolean.
1519
1520 @param[in] pCtx The encoding context to add the Boolean to.
1521 @param[in] b true or false from @c <stdbool.h>.
1522
1523 Adds a Boolean value as CBOR major type 7.
1524
1525 Error handling is the same as QCBOREncode_AddInt64().
1526 */
1527static void QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b);
1528
1529static void QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b);
1530
1531static void QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b);
1532
1533
1534
1535/**
1536 @brief Add a NULL to the encoded output.
1537
1538 @param[in] pCtx The encoding context to add the NULL to.
1539
1540 Adds the NULL value as CBOR major type 7.
1541
1542 This NULL doesn't have any special meaning in CBOR such as a
1543 terminating value for a string or an empty value.
1544
1545 Error handling is the same as QCBOREncode_AddInt64().
1546 */
1547static void QCBOREncode_AddNULL(QCBOREncodeContext *pCtx);
1548
1549static void QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1550
1551static void QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1552
1553
1554/**
1555 @brief Add an "undef" to the encoded output.
1556
1557 @param[in] pCtx The encoding context to add the "undef" to.
1558
1559 Adds the undef value as CBOR major type 7.
1560
1561 Note that this value will not translate to JSON.
1562
1563 This Undef doesn't have any special meaning in CBOR such as a
1564 terminating value for a string or an empty value.
1565
1566 Error handling is the same as QCBOREncode_AddInt64().
1567 */
1568static void QCBOREncode_AddUndef(QCBOREncodeContext *pCtx);
1569
1570static void QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel);
1571
1572static void QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1573
1574
1575/**
1576 @brief Indicates that the next items added are in an array.
1577
1578 @param[in] pCtx The encoding context to open the array in.
1579
1580 Arrays are the basic CBOR aggregate or structure type. Call this
1581 function to start or open an array. Then call the various @c
1582 QCBOREncode_AddXxx() functions to add the items that go into the
1583 array. Then call QCBOREncode_CloseArray() when all items have been
1584 added. The data items in the array can be of any type and can be of
1585 mixed types.
1586
1587 Nesting of arrays and maps is allowed and supported just by calling
1588 QCBOREncode_OpenArray() again before calling
1589 QCBOREncode_CloseArray(). While CBOR has no limit on nesting, this
1590 implementation does in order to keep it smaller and simpler. The
1591 limit is @ref QCBOR_MAX_ARRAY_NESTING. This is the max number of
1592 times this can be called without calling
1593 QCBOREncode_CloseArray(). QCBOREncode_Finish() will return @ref
1594 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP when it is called as this function
1595 just sets an error state and returns no value when this occurs.
1596
1597 If you try to add more than @ref QCBOR_MAX_ITEMS_IN_ARRAY items to a
1598 single array or map, @ref QCBOR_ERR_ARRAY_TOO_LONG will be returned
1599 when QCBOREncode_Finish() is called.
1600
1601 An array itself must have a label if it is being added to a map.
1602 Note that array elements do not have labels (but map elements do).
1603
1604 An array itself may be tagged by calling QCBOREncode_AddTag() before this call.
1605 */
1606static void QCBOREncode_OpenArray(QCBOREncodeContext *pCtx);
1607
1608static void QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1609
1610static void QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1611
1612
1613/**
1614 @brief Close an open array.
1615
1616 @param[in] pCtx The encoding context to close the array in.
1617
1618 The closes an array opened by QCBOREncode_OpenArray(). It reduces
1619 nesting level by one. All arrays (and maps) must be closed before
1620 calling QCBOREncode_Finish().
1621
1622 When an error occurs as a result of this call, the encoder records
1623 the error and enters the error state. The error will be returned when
1624 QCBOREncode_Finish() is called.
1625
1626 If this has been called more times than QCBOREncode_OpenArray(), then
1627 @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when QCBOREncode_Finish()
1628 is called.
1629
1630 If this is called and it is not an array that is currently open, @ref
1631 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
1632 is called.
1633 */
1634static void QCBOREncode_CloseArray(QCBOREncodeContext *pCtx);
1635
1636
1637/**
1638 @brief Indicates that the next items added are in a map.
1639
1640 @param[in] pCtx The encoding context to open the map in.
1641
1642 See QCBOREncode_OpenArray() for more information, particularly error
1643 handling.
1644
1645 CBOR maps are an aggregate type where each item in the map consists
1646 of a label and a value. They are similar to JSON objects.
1647
1648 The value can be any CBOR type including another map.
1649
1650 The label can also be any CBOR type, but in practice they are
1651 typically, integers as this gives the most compact output. They might
1652 also be text strings which gives readability and translation to JSON.
1653
1654 Every @c QCBOREncode_AddXxx() call has one version that ends with @c
1655 InMap for adding items to maps with string labels and one that ends
1656 with @c InMapN that is for adding with integer labels.
1657
Laurence Lundbladec02e13e2020-12-06 05:45:41 -08001658 RFC 8949 uses the term "key" instead of "label".
Michael Eckel5c531332020-03-02 01:35:30 +01001659
1660 If you wish to use map labels that are neither integer labels nor
1661 text strings, then just call the QCBOREncode_AddXxx() function
1662 explicitly to add the label. Then call it again to add the value.
1663
Laurence Lundbladec02e13e2020-12-06 05:45:41 -08001664 See the [RFC 8949] (https://tools.ietf.org/html/rfc8949) for a lot
Michael Eckel5c531332020-03-02 01:35:30 +01001665 more information on creating maps.
1666 */
1667static void QCBOREncode_OpenMap(QCBOREncodeContext *pCtx);
1668
1669static void QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1670
1671static void QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1672
1673
Michael Eckel5c531332020-03-02 01:35:30 +01001674/**
1675 @brief Close an open map.
1676
1677 @param[in] pCtx The encoding context to close the map in .
1678
1679 This closes a map opened by QCBOREncode_OpenMap(). It reduces nesting
1680 level by one.
1681
1682 When an error occurs as a result of this call, the encoder records
1683 the error and enters the error state. The error will be returned when
1684 QCBOREncode_Finish() is called.
1685
1686 If this has been called more times than QCBOREncode_OpenMap(),
1687 then @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1688 QCBOREncode_Finish() is called.
1689
1690 If this is called and it is not a map that is currently open, @ref
1691 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
1692 is called.
1693 */
1694static void QCBOREncode_CloseMap(QCBOREncodeContext *pCtx);
1695
1696
1697/**
1698 @brief Indicate start of encoded CBOR to be wrapped in a bstr.
1699
1700 @param[in] pCtx The encoding context to open the bstr-wrapped CBOR in.
1701
1702 All added encoded items between this call and a call to
1703 QCBOREncode_CloseBstrWrap2() will be wrapped in a bstr. They will
1704 appear in the final output as a byte string. That byte string will
1705 contain encoded CBOR. This increases nesting level by one.
1706
1707 The typical use case is for encoded CBOR that is to be
1708 cryptographically hashed, as part of a [RFC 8152, COSE]
Laurence Lundbladec02e13e2020-12-06 05:45:41 -08001709 (https://tools.ietf.org/html/rfc8152) implementation. The
1710 wrapping byte string is taken as input by the hash function
1711 (which is why it is returned by QCBOREncode_CloseBstrWrap2()).
1712 It is also easy to recover on decoding with standard CBOR
1713 decoders.
Michael Eckel5c531332020-03-02 01:35:30 +01001714
1715 Using QCBOREncode_BstrWrap() and QCBOREncode_CloseBstrWrap2() avoids
1716 having to encode the items first in one buffer (e.g., the COSE
1717 payload) and then add that buffer as a bstr to another encoding
1718 (e.g. the COSE to-be-signed bytes, the @c Sig_structure) potentially
1719 halving the memory needed.
1720
Laurence Lundbladec02e13e2020-12-06 05:45:41 -08001721 CBOR by nature must be decoded item by item in order from the start.
1722 By wrapping some CBOR in a byte string, the decoding of that wrapped
1723 CBOR can be skipped. This is another use of wrapping, perhaps
1724 because the CBOR is large and deeply nested. Perhaps APIs for
1725 handling one defined CBOR message that is being embedded in another
1726 only take input as a byte string. Perhaps the desire is to be able
1727 to decode the out layer even in the wrapped has errors.
Michael Eckel5c531332020-03-02 01:35:30 +01001728 */
1729static void QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx);
1730
1731static void QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1732
1733static void QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1734
1735
1736/**
1737 @brief Close a wrapping bstr.
1738
1739 @param[in] pCtx The encoding context to close of bstr wrapping in.
1740 @param[in] bIncludeCBORHead Include the encoded CBOR head of the bstr
1741 as well as the bytes in @c pWrappedCBOR.
1742 @param[out] pWrappedCBOR A @ref UsefulBufC containing wrapped bytes.
1743
1744 The closes a wrapping bstr opened by QCBOREncode_BstrWrap(). It reduces
1745 nesting level by one.
1746
1747 A pointer and length of the enclosed encoded CBOR is returned in @c
1748 *pWrappedCBOR if it is not @c NULL. The main purpose of this is so
1749 this data can be hashed (e.g., with SHA-256) as part of a [RFC 8152,
1750 COSE] (https://tools.ietf.org/html/rfc8152)
1751 implementation. **WARNING**, this pointer and length should be used
1752 right away before any other calls to @c QCBOREncode_CloseXxx() as
1753 they will move data around and the pointer and length will no longer
1754 be to the correct encoded CBOR.
1755
1756 When an error occurs as a result of this call, the encoder records
1757 the error and enters the error state. The error will be returned when
1758 QCBOREncode_Finish() is called.
1759
1760 If this has been called more times than QCBOREncode_BstrWrap(), then
1761 @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1762 QCBOREncode_Finish() is called.
1763
1764 If this is called and it is not a wrapping bstr that is currently
1765 open, @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
1766 QCBOREncode_Finish() is called.
1767
1768 QCBOREncode_CloseBstrWrap() is a deprecated version of this function
1769 that is equivalent to the call with @c bIncludeCBORHead @c true.
1770 */
1771void QCBOREncode_CloseBstrWrap2(QCBOREncodeContext *pCtx, bool bIncludeCBORHead, UsefulBufC *pWrappedCBOR);
1772
1773static void QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR);
1774
1775
1776/**
Laurence Lundblade8d3b8552021-06-10 11:11:54 -07001777 * @brief Cancel byte string wrapping.
1778 *
1779 * @param[in] pCtx The encoding context.
1780 *
1781 * This cancels QCBOREncode_BstrWrap() making tghe encoding as if it
1782 * were never called.
1783 *
1784 * WARNING: This does not work on QCBOREncode_BstrWrapInMap()
1785 * or QCBOREncode_BstrWrapInMapN() and there is no error detection
1786 * of an attempt at their use.
1787 *
1788 * This only works if nothing has been added into the wrapped byte
1789 * string. If something has been added, this sets the error
1790 * @ref QCBOR_ERR_CANNOT_CANCEL.
1791 */
1792void QCBOREncode_CancelBstrWrap(QCBOREncodeContext *pCtx);
1793
1794
1795/**
Michael Eckel5c531332020-03-02 01:35:30 +01001796 @brief Add some already-encoded CBOR bytes.
1797
1798 @param[in] pCtx The encoding context to add the already-encode CBOR to.
1799 @param[in] Encoded The already-encoded CBOR to add to the context.
1800
1801 The encoded CBOR being added must be fully conforming CBOR. It must
1802 be complete with no arrays or maps that are incomplete. While this
1803 encoder doesn't ever produce indefinite lengths, it is OK for the
1804 raw CBOR added here to have indefinite lengths.
1805
1806 The raw CBOR added here is not checked in anyway. If it is not
1807 conforming or has open arrays or such, the final encoded CBOR
1808 will probably be wrong or not what was intended.
1809
1810 If the encoded CBOR being added here contains multiple items, they
1811 must be enclosed in a map or array. At the top level the raw
1812 CBOR must be a single data item.
1813 */
1814static void QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded);
1815
1816static void QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded);
1817
1818static void QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded);
1819
1820
1821/**
1822 @brief Get the encoded result.
1823
1824 @param[in] pCtx The context to finish encoding with.
Laurence Lundblade8510f8c2020-12-01 11:31:16 -08001825 @param[out] pEncodedCBOR Structure in which the pointer and length of the encoded
1826 CBOR is returned.
Michael Eckel5c531332020-03-02 01:35:30 +01001827
Laurence Lundbladeb9702452021-03-08 21:02:57 -08001828 @retval QCBOR_SUCCESS Encoded CBOR is returned.
1829
Michael Eckel5c531332020-03-02 01:35:30 +01001830 @retval QCBOR_ERR_TOO_MANY_CLOSES Nesting error
1831
1832 @retval QCBOR_ERR_CLOSE_MISMATCH Nesting error
1833
1834 @retval QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN Nesting error
1835
1836 @retval QCBOR_ERR_BUFFER_TOO_LARGE Encoded output buffer size
1837
1838 @retval QCBOR_ERR_BUFFER_TOO_SMALL Encoded output buffer size
1839
1840 @retval QCBOR_ERR_ARRAY_NESTING_TOO_DEEP Implementation limit
1841
1842 @retval QCBOR_ERR_ARRAY_TOO_LONG Implementation limit
1843
Laurence Lundblade8510f8c2020-12-01 11:31:16 -08001844 On success, the pointer and length of the encoded CBOR are returned
1845 in @c *pEncodedCBOR. The pointer is the same pointer that was passed
1846 in to QCBOREncode_Init(). Note that it is not const when passed to
1847 QCBOREncode_Init(), but it is const when returned here. The length
1848 will be smaller than or equal to the length passed in when
1849 QCBOREncode_Init() as this is the length of the actual result, not
1850 the size of the buffer it was written to.
Michael Eckel5c531332020-03-02 01:35:30 +01001851
Laurence Lundblade8510f8c2020-12-01 11:31:16 -08001852 If a @c NULL was passed for @c Storage.ptr when QCBOREncode_Init()
1853 was called, @c NULL will be returned here, but the length will be
1854 that of the CBOR that would have been encoded.
Michael Eckel5c531332020-03-02 01:35:30 +01001855
1856 Encoding errors primarily manifest here as most other encoding function
1857 do no return an error. They just set the error state in the encode
1858 context after which no encoding function does anything.
1859
1860 Three types of errors manifest here. The first type are nesting
1861 errors where the number of @c QCBOREncode_OpenXxx() calls do not
1862 match the number @c QCBOREncode_CloseXxx() calls. The solution is to
1863 fix the calling code.
1864
1865 The second type of error is because the buffer given is either too
1866 small or too large. The remedy is to give a correctly sized buffer.
1867
1868 The third type are due to limits in this implementation. @ref
1869 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP can be worked around by encoding the
1870 CBOR in two (or more) phases and adding the CBOR from the first phase
1871 to the second with @c QCBOREncode_AddEncoded().
1872
1873 If an error is returned, the buffer may have partially encoded
1874 incorrect CBOR in it and it should not be used. Likewise, the length
1875 may be incorrect and should not be used.
1876
1877 Note that the error could have occurred in one of the many @c
1878 QCBOREncode_AddXxx() calls long before QCBOREncode_Finish() was
1879 called. This error handling reduces the CBOR implementation size but
1880 makes debugging harder.
1881
1882 This may be called multiple times. It will always return the same. It
1883 can also be interleaved with calls to QCBOREncode_FinishGetSize().
1884
1885 QCBOREncode_GetErrorState() can be called to get the current
Laurence Lundblade8510f8c2020-12-01 11:31:16 -08001886 error state in order to abort encoding early as an optimization, but
1887 calling it is is never required.
Michael Eckel5c531332020-03-02 01:35:30 +01001888 */
1889QCBORError QCBOREncode_Finish(QCBOREncodeContext *pCtx, UsefulBufC *pEncodedCBOR);
1890
1891
1892/**
1893 @brief Get the encoded CBOR and error status.
1894
1895 @param[in] pCtx The context to finish encoding with.
1896 @param[out] uEncodedLen The length of the encoded or potentially
1897 encoded CBOR in bytes.
1898
1899 @return The same errors as QCBOREncode_Finish().
1900
1901 This functions the same as QCBOREncode_Finish(), but only returns the
1902 size of the encoded output.
1903 */
1904QCBORError QCBOREncode_FinishGetSize(QCBOREncodeContext *pCtx, size_t *uEncodedLen);
1905
1906
1907/**
1908 @brief Indicate whether output buffer is NULL or not.
1909
1910 @param[in] pCtx The encoding context.
1911
1912 @return 1 if the output buffer is @c NULL.
1913
1914 Sometimes a @c NULL input buffer is given to QCBOREncode_Init() so
1915 that the size of the generated CBOR can be calculated without
1916 allocating a buffer for it. This returns 1 when the output buffer is
1917 NULL and 0 when it is not.
1918*/
1919static int QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx);
1920
Laurence Lundblade825164e2020-10-22 20:18:06 -07001921
1922/**
Michael Eckel5c531332020-03-02 01:35:30 +01001923 @brief Get the encoding error state.
1924
1925 @param[in] pCtx The encoding context.
1926
Laurence Lundbladeabf5c572020-06-29 21:21:29 -07001927 @return One of @ref QCBORError. See return values from
Michael Eckel5c531332020-03-02 01:35:30 +01001928 QCBOREncode_Finish()
1929
1930 Normally encoding errors need only be handled at the end of encoding
1931 when QCBOREncode_Finish() is called. This can be called to get the
1932 error result before finish should there be a need to halt encoding
1933 before QCBOREncode_Finish() is called.
1934*/
1935static QCBORError QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx);
1936
1937
1938/**
1939 Encode the "head" of a CBOR data item.
1940
1941 @param buffer Buffer to output the encoded head to; must be
1942 @ref QCBOR_HEAD_BUFFER_SIZE bytes in size.
1943 @param uMajorType One of CBOR_MAJOR_TYPE_XX.
1944 @param uMinLen The minimum number of bytes to encode uNumber. Almost always
1945 this is 0 to use preferred minimal encoding. If this is 4,
1946 then even the values 0xffff and smaller will be encoded
Laurence Lundblade98427e92020-09-28 21:33:23 -07001947 in 4 bytes. This is used primarily when encoding a
Michael Eckel5c531332020-03-02 01:35:30 +01001948 float or double put into uNumber as the leading zero bytes
1949 for them must be encoded.
1950 @param uNumber The numeric argument part of the CBOR head.
1951 @return Pointer and length of the encoded head or
Laurence Lundblade9a3b6252020-10-21 21:30:31 -07001952 @ref NULLUsefulBufC if the output buffer is too small.
Michael Eckel5c531332020-03-02 01:35:30 +01001953
Laurence Lundblade98427e92020-09-28 21:33:23 -07001954 Callers do not to need to call this for normal CBOR encoding. Note that it doesn't even
Michael Eckel5c531332020-03-02 01:35:30 +01001955 take a @ref QCBOREncodeContext argument.
1956
1957 This encodes the major type and argument part of a data item. The
1958 argument is an integer that is usually either the value or the length
1959 of the data item.
1960
1961 This is exposed in the public interface to allow hashing of some CBOR
1962 data types, bstr in particular, a chunk at a time so the full CBOR
1963 doesn't have to be encoded in a contiguous buffer.
1964
1965 For example, if you have a 100,000 byte binary blob in a buffer that
1966 needs to be a bstr encoded and then hashed. You could allocate a
1967 100,010 byte buffer and encode it normally. Alternatively, you can
1968 encode the head in a 10 byte buffer with this function, hash that and
1969 then hash the 100,000 bytes using the same hash context.
1970
1971 See also QCBOREncode_AddBytesLenOnly();
1972 */
1973UsefulBufC QCBOREncode_EncodeHead(UsefulBuf buffer,
1974 uint8_t uMajorType,
1975 uint8_t uMinLen,
1976 uint64_t uNumber);
1977
1978
Michael Eckel5c531332020-03-02 01:35:30 +01001979
1980
Laurence Lundblade45d5e482020-09-15 21:15:15 -07001981/* =========================================================================
1982 BEGINNING OF PRIVATE INLINE IMPLEMENTATION
1983 ========================================================================= */
Michael Eckel5c531332020-03-02 01:35:30 +01001984
1985/**
1986 @brief Semi-private method to add a buffer full of bytes to encoded output
1987
1988 @param[in] pCtx The encoding context to add the integer to.
1989 @param[in] uMajorType The CBOR major type of the bytes.
1990 @param[in] Bytes The bytes to add.
1991
1992 Use QCBOREncode_AddText() or QCBOREncode_AddBytes() or
1993 QCBOREncode_AddEncoded() instead. They are inline functions that call
1994 this and supply the correct major type. This function is public to
1995 make the inline functions work to keep the overall code size down and
1996 because the C language has no way to make it private.
1997
1998 If this is called the major type should be @c
1999 CBOR_MAJOR_TYPE_TEXT_STRING, @c CBOR_MAJOR_TYPE_BYTE_STRING or @c
2000 CBOR_MAJOR_NONE_TYPE_RAW. The last one is special for adding
2001 already-encoded CBOR.
2002 */
2003void QCBOREncode_AddBuffer(QCBOREncodeContext *pCtx, uint8_t uMajorType, UsefulBufC Bytes);
2004
2005
2006/**
2007 @brief Semi-private method to open a map, array or bstr-wrapped CBOR
2008
2009 @param[in] pCtx The context to add to.
2010 @param[in] uMajorType The major CBOR type to close
2011
2012 Call QCBOREncode_OpenArray(), QCBOREncode_OpenMap() or
2013 QCBOREncode_BstrWrap() instead of this.
2014 */
2015void QCBOREncode_OpenMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType);
2016
2017
2018/**
2019 @brief Semi-private method to open a map, array with indefinite length
2020
2021 @param[in] pCtx The context to add to.
2022 @param[in] uMajorType The major CBOR type to close
2023
2024 Call QCBOREncode_OpenArrayIndefiniteLength() or
2025 QCBOREncode_OpenMapIndefiniteLength() instead of this.
2026 */
2027void QCBOREncode_OpenMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx, uint8_t uMajorType);
2028
2029
2030/**
2031 @brief Semi-private method to close a map, array or bstr wrapped CBOR
2032
2033 @param[in] pCtx The context to add to.
2034 @param[in] uMajorType The major CBOR type to close.
2035
2036 Call QCBOREncode_CloseArray() or QCBOREncode_CloseMap() instead of this.
2037 */
2038void QCBOREncode_CloseMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType);
2039
2040
2041/**
2042 @brief Semi-private method to close a map, array with indefinite length
2043
2044 @param[in] pCtx The context to add to.
2045 @param[in] uMajorType The major CBOR type to close.
2046
2047 Call QCBOREncode_CloseArrayIndefiniteLength() or
2048 QCBOREncode_CloseMapIndefiniteLength() instead of this.
2049 */
2050void QCBOREncode_CloseMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx,
2051 uint8_t uMajorType);
2052
2053
2054/**
2055 @brief Semi-private method to add simple types.
2056
2057 @param[in] pCtx The encoding context to add the simple value to.
2058 @param[in] uMinLen Minimum encoding size for uNum. Usually 0.
2059 @param[in] uNum One of CBOR_SIMPLEV_FALSE through _UNDEF or other.
2060
2061 This is used to add simple types like true and false.
2062
2063 Call QCBOREncode_AddBool(), QCBOREncode_AddNULL(),
2064 QCBOREncode_AddUndef() instead of this.
2065
2066 This function can add simple values that are not defined by CBOR
2067 yet. This expansion point in CBOR should not be used unless they are
2068 standardized.
2069
2070 Error handling is the same as QCBOREncode_AddInt64().
2071 */
2072void QCBOREncode_AddType7(QCBOREncodeContext *pCtx, uint8_t uMinLen, uint64_t uNum);
2073
2074
2075/**
2076 @brief Semi-private method to add bigfloats and decimal fractions.
2077
Laurence Lundblade1fa579b2020-11-25 00:31:37 -08002078 @param[in] pCtx The encoding context to add the value to.
2079 @param[in] uTag The type 6 tag indicating what this is to be.
2080 @param[in] BigNumMantissa Is @ref NULLUsefulBufC if mantissa is an
2081 @c int64_t or the actual big number mantissa
2082 if not.
2083 @param[in] bBigNumIsNegative This is @c true if the big number is negative.
2084 @param[in] nMantissa The @c int64_t mantissa if it is not a big number.
2085 @param[in] nExponent The exponent.
Michael Eckel5c531332020-03-02 01:35:30 +01002086
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002087 This outputs either the @ref CBOR_TAG_DECIMAL_FRACTION or @ref
2088 CBOR_TAG_BIGFLOAT tag. if @c uTag is @ref CBOR_TAG_INVALID64, then
2089 this outputs the "borrowed" content format.
Michael Eckel5c531332020-03-02 01:35:30 +01002090
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002091 The tag content output by this is an array with two members, the
2092 exponent and then the mantissa. The mantissa can be either a big
2093 number or an @c int64_t.
2094
2095 This implementation cannot output an exponent further from 0 than
Laurence Lundblade9a3b6252020-10-21 21:30:31 -07002096 @c INT64_MAX.
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002097
Laurence Lundblade1fa579b2020-11-25 00:31:37 -08002098 To output a mantissa that is between INT64_MAX and UINT64_MAX from 0,
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002099 it must be as a big number.
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002100
Michael Eckel5c531332020-03-02 01:35:30 +01002101 Typically, QCBOREncode_AddDecimalFraction(), QCBOREncode_AddBigFloat(),
2102 QCBOREncode_AddDecimalFractionBigNum() or QCBOREncode_AddBigFloatBigNum()
2103 is called instead of this.
2104 */
2105void QCBOREncode_AddExponentAndMantissa(QCBOREncodeContext *pCtx,
2106 uint64_t uTag,
2107 UsefulBufC BigNumMantissa,
2108 bool bBigNumIsNegative,
2109 int64_t nMantissa,
2110 int64_t nExponent);
2111
2112/**
2113 @brief Semi-private method to add only the type and length of a byte string.
2114
2115 @param[in] pCtx The context to initialize.
2116 @param[in] Bytes Pointer and length of the input data.
2117
2118 This is the same as QCBOREncode_AddBytes() except it only adds the
2119 CBOR encoding for the type and the length. It doesn't actually add
2120 the bytes. You can't actually produce correct CBOR with this and the
2121 rest of this API. It is only used for a special case where
2122 the valid CBOR is created manually by putting this type and length in
2123 and then adding the actual bytes. In particular, when only a hash of
2124 the encoded CBOR is needed, where the type and header are hashed
2125 separately and then the bytes is hashed. This makes it possible to
2126 implement COSE Sign1 with only one copy of the payload in the output
2127 buffer, rather than two, roughly cutting memory use in half.
2128
2129 This is only used for this odd case, but this is a supported
2130 tested function.
2131
2132 See also QCBOREncode_EncodeHead().
2133*/
2134static inline void QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
2135
2136static inline void QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
2137
2138static inline void QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
2139
2140
2141
2142
2143
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002144static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002145QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pMe, const char *szLabel, int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002146{
2147 // Use _AddBuffer() because _AddSZString() is defined below, not above
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002148 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
2149 QCBOREncode_AddInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002150}
2151
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002152static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002153QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pMe, int64_t nLabel, int64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002154{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002155 QCBOREncode_AddInt64(pMe, nLabel);
2156 QCBOREncode_AddInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002157}
2158
2159
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002160static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002161QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pMe, const char *szLabel, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002162{
2163 // Use _AddBuffer() because _AddSZString() is defined below, not above
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002164 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
2165 QCBOREncode_AddUInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002166}
2167
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002168static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002169QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002170{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002171 QCBOREncode_AddInt64(pMe, nLabel);
2172 QCBOREncode_AddUInt64(pMe, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002173}
2174
2175
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002176static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002177QCBOREncode_AddText(QCBOREncodeContext *pMe, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002178{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002179 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002180}
2181
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002182static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002183QCBOREncode_AddTextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002184{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002185 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szLabel));
2186 QCBOREncode_AddText(pMe, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002187}
2188
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002189static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002190QCBOREncode_AddTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002191{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002192 QCBOREncode_AddInt64(pMe, nLabel);
2193 QCBOREncode_AddText(pMe, Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002194}
2195
2196
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002197inline static void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002198QCBOREncode_AddSZString(QCBOREncodeContext *pMe, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002199{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002200 QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szString));
Michael Eckel5c531332020-03-02 01:35:30 +01002201}
2202
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002203static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002204QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pMe, const char *szLabel, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002205{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002206 QCBOREncode_AddSZString(pMe, szLabel);
2207 QCBOREncode_AddSZString(pMe, szString);
Michael Eckel5c531332020-03-02 01:35:30 +01002208}
2209
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002210static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002211QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, const char *szString)
Michael Eckel5c531332020-03-02 01:35:30 +01002212{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002213 QCBOREncode_AddInt64(pMe, nLabel);
2214 QCBOREncode_AddSZString(pMe, szString);
Michael Eckel5c531332020-03-02 01:35:30 +01002215}
2216
2217
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002218static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002219QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pMe, const char *szLabel, double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002220{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002221 QCBOREncode_AddSZString(pMe, szLabel);
2222 QCBOREncode_AddDouble(pMe, dNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002223}
2224
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002225static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002226QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pMe, int64_t nLabel, double dNum)
Michael Eckel5c531332020-03-02 01:35:30 +01002227{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002228 QCBOREncode_AddInt64(pMe, nLabel);
2229 QCBOREncode_AddDouble(pMe, dNum);
Michael Eckel5c531332020-03-02 01:35:30 +01002230}
2231
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002232static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002233QCBOREncode_AddFloatToMap(QCBOREncodeContext *pMe, const char *szLabel, float dNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002234{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002235 QCBOREncode_AddSZString(pMe, szLabel);
2236 QCBOREncode_AddFloat(pMe, dNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002237}
2238
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002239static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002240QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pMe, int64_t nLabel, float fNum)
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002241{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002242 QCBOREncode_AddInt64(pMe, nLabel);
2243 QCBOREncode_AddFloat(pMe, fNum);
Laurence Lundbladeb275cdc2020-07-12 12:34:38 -07002244}
2245
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002246static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002247QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pMe, const char *szLabel, double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002248{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002249 QCBOREncode_AddSZString(pMe, szLabel);
2250 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002251}
2252
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002253static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002254QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pMe, int64_t nLabel, double dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002255{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002256 QCBOREncode_AddInt64(pMe, nLabel);
2257 QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002258}
2259
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002260static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002261QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pMe, const char *szLabel, float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002262{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002263 QCBOREncode_AddSZString(pMe, szLabel);
2264 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002265}
2266
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002267static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002268QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pMe, int64_t nLabel, float dNum)
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002269{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07002270 QCBOREncode_AddInt64(pMe, nLabel);
2271 QCBOREncode_AddFloatNoPreferred(pMe, dNum);
Laurence Lundblade32f3e622020-07-13 20:35:11 -07002272}
2273
Michael Eckel5c531332020-03-02 01:35:30 +01002274
Laurence Lundblade9b334962020-08-27 10:55:53 -07002275
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002276static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002277QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pMe, uint8_t uTag, int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002278{
2279 if(uTag == QCBOR_ENCODE_AS_TAG) {
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002280 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_EPOCH);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002281 }
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002282 QCBOREncode_AddInt64(pMe, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002283}
2284
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002285static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002286QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTag, int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002287{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002288 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002289 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002290}
2291
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002292static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002293QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTag, int64_t nDate)
Laurence Lundblade9b334962020-08-27 10:55:53 -07002294{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002295 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002296 QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
Laurence Lundblade9b334962020-08-27 10:55:53 -07002297}
2298
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002299static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002300QCBOREncode_AddDateEpoch(QCBOREncodeContext *pMe, int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002301{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002302 QCBOREncode_AddTDateEpoch(pMe, QCBOR_ENCODE_AS_TAG, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002303}
2304
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002305static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002306QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pMe, const char *szLabel, int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002307{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002308 QCBOREncode_AddSZString(pMe, szLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002309 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002310}
2311
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002312static inline void
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002313QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pMe, int64_t nLabel, int64_t nDate)
Michael Eckel5c531332020-03-02 01:35:30 +01002314{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002315 QCBOREncode_AddInt64(pMe, nLabel);
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002316 QCBOREncode_AddDateEpoch(pMe, nDate);
Michael Eckel5c531332020-03-02 01:35:30 +01002317}
2318
2319
Laurence Lundblade46d63e92021-05-13 11:37:10 -07002320static inline void
2321QCBOREncode_AddTDaysEpoch(QCBOREncodeContext *pMe, uint8_t uTag, int64_t nDays)
2322{
2323 if(uTag == QCBOR_ENCODE_AS_TAG) {
2324 QCBOREncode_AddTag(pMe, CBOR_TAG_DAYS_EPOCH);
2325 }
2326 QCBOREncode_AddInt64(pMe, nDays);
2327}
2328
2329static inline void
2330QCBOREncode_AddTDaysEpochToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTag, int64_t nDays)
2331{
2332 QCBOREncode_AddSZString(pMe, szLabel);
2333 QCBOREncode_AddTDaysEpoch(pMe, uTag, nDays);
2334}
2335
2336static inline void
2337QCBOREncode_AddTDaysEpochToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTag, int64_t nDays)
2338{
2339 QCBOREncode_AddInt64(pMe, nLabel);
2340 QCBOREncode_AddTDaysEpoch(pMe, uTag, nDays);
2341}
2342
Laurence Lundblade9b334962020-08-27 10:55:53 -07002343
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002344static inline void
2345QCBOREncode_AddBytes(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002346{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002347 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002348}
2349
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002350static inline void
2351QCBOREncode_AddBytesToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002352{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002353 QCBOREncode_AddSZString(pMe, szLabel);
2354 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002355}
2356
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002357static inline void
2358QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002359{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002360 QCBOREncode_AddInt64(pMe, nLabel);
2361 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002362}
2363
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002364static inline void
2365QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002366{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002367 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002368}
2369
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002370static inline void
2371QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002372{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002373 QCBOREncode_AddSZString(pMe, szLabel);
2374 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002375}
2376
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002377static inline void
2378QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002379{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002380 QCBOREncode_AddInt64(pMe, nLabel);
2381 QCBOREncode_AddBytesLenOnly(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002382}
2383
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002384
2385static inline void
2386QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002387{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002388 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2389 QCBOREncode_AddTag(pMe, CBOR_TAG_BIN_UUID);
2390 }
2391 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002392}
2393
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002394static inline void
2395QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pMe,
2396 const char *szLabel,
2397 uint8_t uTagRequirement,
2398 UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002399{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002400 QCBOREncode_AddSZString(pMe, szLabel);
2401 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002402}
2403
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002404static inline void
2405QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002406{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002407 QCBOREncode_AddInt64(pMe, nLabel);
2408 QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002409}
2410
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002411static inline void
2412QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pMe, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002413{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002414 QCBOREncode_AddTBinaryUUID(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002415}
2416
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002417static inline void
2418QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002419{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002420 QCBOREncode_AddTBinaryUUIDToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002421}
2422
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002423static inline void
2424QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002425{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002426 QCBOREncode_AddTBinaryUUIDToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002427}
2428
2429
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002430static inline void
2431QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002432{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002433 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2434 QCBOREncode_AddTag(pMe, CBOR_TAG_POS_BIGNUM);
2435 }
2436 QCBOREncode_AddBytes(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002437}
2438
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002439static inline void
2440QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pMe,
2441 const char *szLabel,
2442 uint8_t uTagRequirement,
2443 UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002444{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002445 QCBOREncode_AddSZString(pMe, szLabel);
2446 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002447}
2448
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002449static inline void
2450QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002451{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002452 QCBOREncode_AddInt64(pMe, nLabel);
2453 QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002454}
2455
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002456static inline void
2457QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2458{
2459 QCBOREncode_AddTPositiveBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2460}
2461
2462static inline void
2463QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2464{
2465 QCBOREncode_AddTPositiveBignumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2466}
2467
2468static inline void
2469QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2470{
2471 QCBOREncode_AddTPositiveBignumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2472}
2473
2474
2475static inline void
2476QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
2477{
2478 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2479 QCBOREncode_AddTag(pMe, CBOR_TAG_NEG_BIGNUM);
2480 }
2481 QCBOREncode_AddBytes(pMe, Bytes);
2482}
2483
2484static inline void
2485QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pMe,
2486 const char *szLabel,
2487 uint8_t uTagRequirement,
2488 UsefulBufC Bytes)
2489{
2490 QCBOREncode_AddSZString(pMe, szLabel);
2491 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2492}
2493
2494static inline void
2495QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
2496{
2497 QCBOREncode_AddInt64(pMe, nLabel);
2498 QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
2499}
2500
2501static inline void
2502QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2503{
2504 QCBOREncode_AddTNegativeBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2505}
2506
2507static inline void
2508QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2509{
2510 QCBOREncode_AddTNegativeBignumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2511}
2512
2513static inline void
2514QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2515{
2516 QCBOREncode_AddTNegativeBignumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2517}
2518
2519
Michael Eckel5c531332020-03-02 01:35:30 +01002520
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07002521#ifndef QCBOR_DISABLE_EXP_AND_MANTISSA
Michael Eckel5c531332020-03-02 01:35:30 +01002522
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002523static inline void
2524QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pMe,
2525 uint8_t uTagRequirement,
2526 int64_t nMantissa,
2527 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002528{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002529 uint64_t uTag;
2530 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2531 uTag = CBOR_TAG_DECIMAL_FRACTION;
2532 } else {
2533 uTag = CBOR_TAG_INVALID64;
2534 }
2535 QCBOREncode_AddExponentAndMantissa(pMe,
2536 uTag,
Michael Eckel5c531332020-03-02 01:35:30 +01002537 NULLUsefulBufC,
2538 false,
2539 nMantissa,
2540 nBase10Exponent);
2541}
2542
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002543static inline void
2544QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pMe,
2545 const char *szLabel,
2546 uint8_t uTagRequirement,
2547 int64_t nMantissa,
2548 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002549{
2550 QCBOREncode_AddSZString(pMe, szLabel);
2551 QCBOREncode_AddTDecimalFraction(pMe, uTagRequirement, nMantissa, nBase10Exponent);
2552}
2553
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002554static inline void
2555QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pMe,
2556 int64_t nLabel,
2557 uint8_t uTagRequirement,
2558 int64_t nMantissa,
2559 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002560{
2561 QCBOREncode_AddInt64(pMe, nLabel);
2562 QCBOREncode_AddTDecimalFraction(pMe, uTagRequirement, nMantissa, nBase10Exponent);
2563}
2564
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002565static inline void
2566QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pMe,
2567 int64_t nMantissa,
2568 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002569{
2570 QCBOREncode_AddTDecimalFraction(pMe, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
2571}
2572
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002573static inline void
2574QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pMe,
2575 const char *szLabel,
2576 int64_t nMantissa,
2577 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002578{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002579 QCBOREncode_AddTDecimalFractionToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002580}
2581
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002582static inline void
2583QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pMe,
2584 int64_t nLabel,
2585 int64_t nMantissa,
2586 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002587{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002588 QCBOREncode_AddTDecimalFractionToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002589}
2590
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002591
2592
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002593static inline void
2594QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pMe,
2595 uint8_t uTagRequirement,
2596 UsefulBufC Mantissa,
2597 bool bIsNegative,
2598 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002599{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002600 uint64_t uTag;
2601 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2602 uTag = CBOR_TAG_DECIMAL_FRACTION;
2603 } else {
2604 uTag = CBOR_TAG_INVALID64;
2605 }
2606 QCBOREncode_AddExponentAndMantissa(pMe,
2607 uTag,
Michael Eckel5c531332020-03-02 01:35:30 +01002608 Mantissa, bIsNegative,
2609 0,
2610 nBase10Exponent);
2611}
2612
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002613static inline void
2614QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
2615 const char *szLabel,
2616 uint8_t uTagRequirement,
2617 UsefulBufC Mantissa,
2618 bool bIsNegative,
2619 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002620{
2621 QCBOREncode_AddSZString(pMe, szLabel);
2622 QCBOREncode_AddTDecimalFractionBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase10Exponent);
2623}
2624
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002625static inline void
2626QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
2627 int64_t nLabel,
2628 uint8_t uTagRequirement,
2629 UsefulBufC Mantissa,
2630 bool bIsNegative,
2631 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002632{
2633 QCBOREncode_AddInt64(pMe, nLabel);
2634 QCBOREncode_AddTDecimalFractionBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase10Exponent);
2635}
2636
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002637static inline void
2638QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pMe,
2639 UsefulBufC Mantissa,
2640 bool bIsNegative,
2641 int64_t nBase10Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002642{
2643 QCBOREncode_AddTDecimalFractionBigNum(pMe, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase10Exponent);
2644}
2645
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002646static inline void
2647QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
2648 const char *szLabel,
2649 UsefulBufC Mantissa,
2650 bool bIsNegative,
2651 int64_t nBase10Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002652{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002653 QCBOREncode_AddTDecimalFractionBigNumToMapSZ(pMe,
2654 szLabel,
2655 QCBOR_ENCODE_AS_TAG,
2656 Mantissa,
2657 bIsNegative,
2658 nBase10Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002659}
2660
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002661static inline void
2662QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
2663 int64_t nLabel,
2664 UsefulBufC Mantissa,
2665 bool bIsNegative,
2666 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002667{
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002668 QCBOREncode_AddTDecimalFractionBigNumToMapN(pMe,
2669 nLabel,
2670 QCBOR_ENCODE_AS_TAG,
2671 Mantissa,
2672 bIsNegative,
2673 nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002674}
2675
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002676
2677
2678
2679
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002680static inline void
2681QCBOREncode_AddTBigFloat(QCBOREncodeContext *pMe,
2682 uint8_t uTagRequirement,
2683 int64_t nMantissa,
2684 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002685{
2686 uint64_t uTag;
2687 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2688 uTag = CBOR_TAG_BIGFLOAT;
2689 } else {
2690 uTag = CBOR_TAG_INVALID64;
2691 }
2692 QCBOREncode_AddExponentAndMantissa(pMe, uTag, NULLUsefulBufC, false, nMantissa, nBase2Exponent);
2693}
2694
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002695static inline void
2696QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pMe,
2697 const char *szLabel,
2698 uint8_t uTagRequirement,
2699 int64_t nMantissa,
2700 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002701{
2702 QCBOREncode_AddSZString(pMe, szLabel);
2703 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
2704}
2705
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002706static inline void
2707QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pMe,
2708 int64_t nLabel,
2709 uint8_t uTagRequirement,
2710 int64_t nMantissa,
2711 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002712{
2713 QCBOREncode_AddInt64(pMe, nLabel);
2714 QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
2715}
2716
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002717static inline void
2718QCBOREncode_AddBigFloat(QCBOREncodeContext *pMe,
2719 int64_t nMantissa,
2720 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002721{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002722 QCBOREncode_AddTBigFloat(pMe, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002723}
2724
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002725static inline void
2726QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pMe,
2727 const char *szLabel,
2728 int64_t nMantissa,
2729 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002730{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002731 QCBOREncode_AddTBigFloatToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002732}
2733
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002734static inline void
2735QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pMe,
2736 int64_t nLabel,
2737 int64_t nMantissa,
2738 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002739{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002740 QCBOREncode_AddTBigFloatToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002741}
2742
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002743
2744
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002745static inline void
2746QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pMe,
2747 uint8_t uTagRequirement,
2748 UsefulBufC Mantissa,
2749 bool bIsNegative,
2750 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002751{
2752 uint64_t uTag;
2753 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2754 uTag = CBOR_TAG_BIGFLOAT;
2755 } else {
2756 uTag = CBOR_TAG_INVALID64;
2757 }
2758 QCBOREncode_AddExponentAndMantissa(pMe, uTag, Mantissa, bIsNegative, 0, nBase2Exponent);
2759}
2760
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002761static inline void
2762QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pMe,
2763 const char *szLabel,
2764 uint8_t uTagRequirement,
2765 UsefulBufC Mantissa,
2766 bool bIsNegative,
2767 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002768{
2769 QCBOREncode_AddSZString(pMe, szLabel);
2770 QCBOREncode_AddTBigFloatBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase2Exponent);
2771}
2772
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002773static inline void
2774QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
2775 int64_t nLabel,
2776 uint8_t uTagRequirement,
2777 UsefulBufC Mantissa,
2778 bool bIsNegative,
2779 int64_t nBase2Exponent)
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002780{
2781 QCBOREncode_AddInt64(pMe, nLabel);
2782 QCBOREncode_AddTBigFloatBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase2Exponent);
2783}
2784
2785
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002786static inline void
2787QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pMe,
2788 UsefulBufC Mantissa,
2789 bool bIsNegative,
2790 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002791{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002792 QCBOREncode_AddTBigFloatBigNum(pMe, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002793}
2794
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002795static inline void
2796QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pMe,
2797 const char *szLabel,
2798 UsefulBufC Mantissa,
2799 bool bIsNegative,
2800 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002801{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002802 QCBOREncode_AddTBigFloatBigNumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002803}
2804
Laurence Lundblade45d5e482020-09-15 21:15:15 -07002805static inline void
2806QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
2807 int64_t nLabel,
2808 UsefulBufC Mantissa,
2809 bool bIsNegative,
2810 int64_t nBase2Exponent)
Michael Eckel5c531332020-03-02 01:35:30 +01002811{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002812 QCBOREncode_AddTBigFloatBigNumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
Michael Eckel5c531332020-03-02 01:35:30 +01002813}
Laurence Lundbladedd6e76e2021-03-10 01:54:01 -07002814#endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
Michael Eckel5c531332020-03-02 01:35:30 +01002815
2816
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002817static inline void
2818QCBOREncode_AddTURI(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002819{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002820 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2821 QCBOREncode_AddTag(pMe, CBOR_TAG_URI);
2822 }
2823 QCBOREncode_AddText(pMe, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002824}
2825
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002826static inline void
2827QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002828{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002829 QCBOREncode_AddSZString(pMe, szLabel);
2830 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002831}
2832
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002833static inline void
2834QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC URI)
Michael Eckel5c531332020-03-02 01:35:30 +01002835{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002836 QCBOREncode_AddInt64(pMe, nLabel);
2837 QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
2838}
2839
2840static inline void
2841QCBOREncode_AddURI(QCBOREncodeContext *pMe, UsefulBufC URI)
2842{
2843 QCBOREncode_AddTURI(pMe, QCBOR_ENCODE_AS_TAG, URI);
2844}
2845
2846static inline void
2847QCBOREncode_AddURIToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC URI)
2848{
2849 QCBOREncode_AddTURIToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, URI);
2850}
2851
2852static inline void
2853QCBOREncode_AddURIToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC URI)
2854{
2855 QCBOREncode_AddTURIToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, URI);
Michael Eckel5c531332020-03-02 01:35:30 +01002856}
2857
2858
2859
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002860static inline void
2861QCBOREncode_AddTB64Text(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002862{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002863 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2864 QCBOREncode_AddTag(pMe, CBOR_TAG_B64);
2865 }
2866 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002867}
2868
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002869static inline void
2870QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pMe,
2871 const char *szLabel,
2872 uint8_t uTagRequirement,
2873 UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002874{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002875 QCBOREncode_AddSZString(pMe, szLabel);
2876 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002877}
2878
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002879static inline void
2880QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002881{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002882 QCBOREncode_AddInt64(pMe, nLabel);
2883 QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
2884}
2885
2886static inline void
2887QCBOREncode_AddB64Text(QCBOREncodeContext *pMe, UsefulBufC B64Text)
2888{
2889 QCBOREncode_AddTB64Text(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
2890}
2891
2892static inline void
2893QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC B64Text)
2894{
2895 QCBOREncode_AddTB64TextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
2896}
2897
2898static inline void
2899QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC B64Text)
2900{
2901 QCBOREncode_AddTB64TextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002902}
2903
2904
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002905
2906static inline void
2907QCBOREncode_AddTB64URLText(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002908{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002909 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2910 QCBOREncode_AddTag(pMe, CBOR_TAG_B64URL);
2911 }
2912 QCBOREncode_AddText(pMe, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002913}
2914
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002915static inline void
2916QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pMe,
2917 const char *szLabel,
2918 uint8_t uTagRequirement,
2919 UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002920{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002921 QCBOREncode_AddSZString(pMe, szLabel);
2922 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002923}
2924
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002925static inline void
2926QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC B64Text)
Michael Eckel5c531332020-03-02 01:35:30 +01002927{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002928 QCBOREncode_AddInt64(pMe, nLabel);
2929 QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
2930}
2931
2932static inline void
2933QCBOREncode_AddB64URLText(QCBOREncodeContext *pMe, UsefulBufC B64Text)
2934{
2935 QCBOREncode_AddTB64URLText(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
2936}
2937
2938static inline void
2939QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC B64Text)
2940{
2941 QCBOREncode_AddTB64URLTextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
2942}
2943
2944static inline void
2945QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC B64Text)
2946{
2947 QCBOREncode_AddTB64URLTextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
Michael Eckel5c531332020-03-02 01:35:30 +01002948}
2949
2950
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002951
2952static inline void
2953QCBOREncode_AddTRegex(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002954{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002955 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
2956 QCBOREncode_AddTag(pMe, CBOR_TAG_REGEX);
2957 }
2958 QCBOREncode_AddText(pMe, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002959}
2960
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002961static inline void
2962QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002963{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002964 QCBOREncode_AddSZString(pMe, szLabel);
2965 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
Michael Eckel5c531332020-03-02 01:35:30 +01002966}
2967
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002968static inline void
2969QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
Michael Eckel5c531332020-03-02 01:35:30 +01002970{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002971 QCBOREncode_AddInt64(pMe, nLabel);
2972 QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
2973}
2974
2975static inline void
2976QCBOREncode_AddRegex(QCBOREncodeContext *pMe, UsefulBufC Bytes)
2977{
2978 QCBOREncode_AddTRegex(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
2979}
2980
2981static inline void
2982QCBOREncode_AddRegexToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
2983{
2984 QCBOREncode_AddTRegexToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2985}
2986
2987static inline void
2988QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
2989{
2990 QCBOREncode_AddTRegexToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
2991
Michael Eckel5c531332020-03-02 01:35:30 +01002992}
2993
2994
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002995static inline void
2996QCBOREncode_AddTMIMEData(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01002997{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07002998 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
Laurence Lundblade4982f412020-09-18 23:02:18 -07002999 QCBOREncode_AddTag(pMe, CBOR_TAG_BINARY_MIME);
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003000 }
Laurence Lundblade4982f412020-09-18 23:02:18 -07003001 QCBOREncode_AddBytes(pMe, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01003002}
3003
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003004static inline void
3005QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pMe,
3006 const char *szLabel,
3007 uint8_t uTagRequirement,
3008 UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01003009{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003010 QCBOREncode_AddSZString(pMe, szLabel);
3011 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01003012}
3013
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003014static inline void
3015QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC MIMEData)
Michael Eckel5c531332020-03-02 01:35:30 +01003016{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003017 QCBOREncode_AddInt64(pMe, nLabel);
3018 QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
3019}
3020
3021static inline void
3022QCBOREncode_AddMIMEData(QCBOREncodeContext *pMe, UsefulBufC MIMEData)
3023{
3024 QCBOREncode_AddTMIMEData(pMe, QCBOR_ENCODE_AS_TAG, MIMEData);
3025}
3026
3027static inline void
3028QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC MIMEData)
3029{
3030 QCBOREncode_AddTMIMEDataToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
3031}
3032
3033static inline void
3034QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC MIMEData)
3035{
3036 QCBOREncode_AddTMIMEDataToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
Michael Eckel5c531332020-03-02 01:35:30 +01003037}
3038
3039
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003040static inline void
3041QCBOREncode_AddTDateString(QCBOREncodeContext *pMe, uint8_t uTagRequirement, const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01003042{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003043 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3044 QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_STRING);
3045 }
3046 QCBOREncode_AddSZString(pMe, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01003047}
3048
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003049static inline void
3050QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pMe,
3051 const char *szLabel,
3052 uint8_t uTagRequirement,
3053 const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01003054{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003055 QCBOREncode_AddSZString(pMe, szLabel);
3056 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01003057}
3058
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003059static inline void
3060QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, const char *szDate)
Michael Eckel5c531332020-03-02 01:35:30 +01003061{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003062 QCBOREncode_AddInt64(pMe, nLabel);
3063 QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
3064}
3065
3066static inline void
3067QCBOREncode_AddDateString(QCBOREncodeContext *pMe, const char *szDate)
3068{
3069 QCBOREncode_AddTDateString(pMe, QCBOR_ENCODE_AS_TAG, szDate);
3070}
3071
3072static inline void
3073QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pMe, const char *szLabel, const char *szDate)
3074{
3075 QCBOREncode_AddTDateStringToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, szDate);
3076}
3077
3078static inline void
3079QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, const char *szDate)
3080{
3081 QCBOREncode_AddTDateStringToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, szDate);
Michael Eckel5c531332020-03-02 01:35:30 +01003082}
3083
3084
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003085static inline void
Laurence Lundblade46d63e92021-05-13 11:37:10 -07003086QCBOREncode_AddTDaysString(QCBOREncodeContext *pMe, uint8_t uTagRequirement, const char *szDate)
3087{
3088 if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
3089 QCBOREncode_AddTag(pMe, CBOR_TAG_DAYS_STRING);
3090 }
3091 QCBOREncode_AddSZString(pMe, szDate);
3092}
3093
3094static inline void
3095QCBOREncode_AddTDaysStringToMapSZ(QCBOREncodeContext *pMe,
3096 const char *szLabel,
3097 uint8_t uTagRequirement,
3098 const char *szDate)
3099{
3100 QCBOREncode_AddSZString(pMe, szLabel);
3101 QCBOREncode_AddTDaysString(pMe, uTagRequirement, szDate);
3102}
3103
3104static inline void
3105QCBOREncode_AddTDaysStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, const char *szDate)
3106{
3107 QCBOREncode_AddInt64(pMe, nLabel);
3108 QCBOREncode_AddTDaysString(pMe, uTagRequirement, szDate);
3109}
3110
3111
3112
3113static inline void
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003114QCBOREncode_AddSimple(QCBOREncodeContext *pMe, uint64_t uNum)
Michael Eckel5c531332020-03-02 01:35:30 +01003115{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003116 QCBOREncode_AddType7(pMe, 0, uNum);
Michael Eckel5c531332020-03-02 01:35:30 +01003117}
3118
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003119static inline void
3120QCBOREncode_AddSimpleToMap(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01003121{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003122 QCBOREncode_AddSZString(pMe, szLabel);
3123 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01003124}
3125
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003126static inline void
3127QCBOREncode_AddSimpleToMapN(QCBOREncodeContext *pMe, int nLabel, uint8_t uSimple)
Michael Eckel5c531332020-03-02 01:35:30 +01003128{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003129 QCBOREncode_AddInt64(pMe, nLabel);
3130 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01003131}
3132
3133
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003134static inline void
3135QCBOREncode_AddBool(QCBOREncodeContext *pMe, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01003136{
3137 uint8_t uSimple = CBOR_SIMPLEV_FALSE;
3138 if(b) {
3139 uSimple = CBOR_SIMPLEV_TRUE;
3140 }
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003141 QCBOREncode_AddSimple(pMe, uSimple);
Michael Eckel5c531332020-03-02 01:35:30 +01003142}
3143
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003144static inline void
3145QCBOREncode_AddBoolToMap(QCBOREncodeContext *pMe, const char *szLabel, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01003146{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003147 QCBOREncode_AddSZString(pMe, szLabel);
3148 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01003149}
3150
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003151static inline void
3152QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pMe, int64_t nLabel, bool b)
Michael Eckel5c531332020-03-02 01:35:30 +01003153{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003154 QCBOREncode_AddInt64(pMe, nLabel);
3155 QCBOREncode_AddBool(pMe, b);
Michael Eckel5c531332020-03-02 01:35:30 +01003156}
3157
3158
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003159static inline void
3160QCBOREncode_AddNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003161{
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003162 QCBOREncode_AddSimple(pMe, CBOR_SIMPLEV_NULL);
Michael Eckel5c531332020-03-02 01:35:30 +01003163}
3164
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003165static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003166QCBOREncode_AddNULLToMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003167{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003168 QCBOREncode_AddSZString(pMe, szLabel);
3169 QCBOREncode_AddNULL(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003170}
3171
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003172static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003173QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003174{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003175 QCBOREncode_AddInt64(pMe, nLabel);
3176 QCBOREncode_AddNULL(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003177}
3178
3179
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003180static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003181QCBOREncode_AddUndef(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003182{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003183 QCBOREncode_AddSimple(pMe, CBOR_SIMPLEV_UNDEF);
Michael Eckel5c531332020-03-02 01:35:30 +01003184}
3185
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003186static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003187QCBOREncode_AddUndefToMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003188{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003189 QCBOREncode_AddSZString(pMe, szLabel);
3190 QCBOREncode_AddUndef(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003191}
3192
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003193static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003194QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003195{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003196 QCBOREncode_AddInt64(pMe, nLabel);
3197 QCBOREncode_AddUndef(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003198}
3199
3200
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003201static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003202QCBOREncode_OpenArray(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003203{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003204 QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
Michael Eckel5c531332020-03-02 01:35:30 +01003205}
3206
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003207static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003208QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003209{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003210 QCBOREncode_AddSZString(pMe, szLabel);
3211 QCBOREncode_OpenArray(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003212}
3213
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003214static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003215QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003216{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003217 QCBOREncode_AddInt64(pMe, nLabel);
3218 QCBOREncode_OpenArray(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003219}
3220
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003221static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003222QCBOREncode_CloseArray(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003223{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003224 QCBOREncode_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
Michael Eckel5c531332020-03-02 01:35:30 +01003225}
3226
3227
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003228static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003229QCBOREncode_OpenMap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003230{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003231 QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
Michael Eckel5c531332020-03-02 01:35:30 +01003232}
3233
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003234static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003235QCBOREncode_OpenMapInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003236{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003237 QCBOREncode_AddSZString(pMe, szLabel);
3238 QCBOREncode_OpenMap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003239}
3240
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003241static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003242QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003243{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003244 QCBOREncode_AddInt64(pMe, nLabel);
3245 QCBOREncode_OpenMap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003246}
3247
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003248static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003249QCBOREncode_CloseMap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003250{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003251 QCBOREncode_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
Michael Eckel5c531332020-03-02 01:35:30 +01003252}
3253
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003254static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003255QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003256{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003257 QCBOREncode_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003258}
3259
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003260static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003261QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003262{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003263 QCBOREncode_AddSZString(pMe, szLabel);
3264 QCBOREncode_OpenArrayIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003265}
3266
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003267static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003268QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003269{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003270 QCBOREncode_AddInt64(pMe, nLabel);
3271 QCBOREncode_OpenArrayIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003272}
3273
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003274static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003275QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003276{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003277 QCBOREncode_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003278}
3279
3280
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003281static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003282QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003283{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003284 QCBOREncode_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003285}
3286
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003287static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003288QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003289{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003290 QCBOREncode_AddSZString(pMe, szLabel);
3291 QCBOREncode_OpenMapIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003292}
3293
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003294static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003295QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003296{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003297 QCBOREncode_AddInt64(pMe, nLabel);
3298 QCBOREncode_OpenMapIndefiniteLength(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003299}
3300
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003301static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003302QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003303{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003304 QCBOREncode_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
Michael Eckel5c531332020-03-02 01:35:30 +01003305}
3306
3307
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003308static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003309QCBOREncode_BstrWrap(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003310{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003311 QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_BYTE_STRING);
Michael Eckel5c531332020-03-02 01:35:30 +01003312}
3313
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003314static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003315QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pMe, const char *szLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003316{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003317 QCBOREncode_AddSZString(pMe, szLabel);
3318 QCBOREncode_BstrWrap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003319}
3320
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003321static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003322QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
Michael Eckel5c531332020-03-02 01:35:30 +01003323{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003324 QCBOREncode_AddInt64(pMe, nLabel);
3325 QCBOREncode_BstrWrap(pMe);
Michael Eckel5c531332020-03-02 01:35:30 +01003326}
3327
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003328static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003329QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pMe, UsefulBufC *pWrappedCBOR)
Michael Eckel5c531332020-03-02 01:35:30 +01003330{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003331 QCBOREncode_CloseBstrWrap2(pMe, true, pWrappedCBOR);
Michael Eckel5c531332020-03-02 01:35:30 +01003332}
3333
3334
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003335static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003336QCBOREncode_AddEncoded(QCBOREncodeContext *pMe, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003337{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003338 QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_RAW, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003339}
3340
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003341static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003342QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003343{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003344 QCBOREncode_AddSZString(pMe, szLabel);
3345 QCBOREncode_AddEncoded(pMe, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003346}
3347
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003348static inline void
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003349QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Encoded)
Michael Eckel5c531332020-03-02 01:35:30 +01003350{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003351 QCBOREncode_AddInt64(pMe, nLabel);
3352 QCBOREncode_AddEncoded(pMe, Encoded);
Michael Eckel5c531332020-03-02 01:35:30 +01003353}
3354
3355
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003356static inline int
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003357QCBOREncode_IsBufferNULL(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003358{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003359 return UsefulOutBuf_IsBufferNULL(&(pMe->OutBuf));
Michael Eckel5c531332020-03-02 01:35:30 +01003360}
3361
Laurence Lundbladeae66d3f2020-09-14 18:12:08 -07003362static inline QCBORError
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003363QCBOREncode_GetErrorState(QCBOREncodeContext *pMe)
Michael Eckel5c531332020-03-02 01:35:30 +01003364{
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003365 if(UsefulOutBuf_GetError(&(pMe->OutBuf))) {
Michael Eckel5c531332020-03-02 01:35:30 +01003366 // Items didn't fit in the buffer.
3367 // This check catches this condition for all the appends and inserts
3368 // so checks aren't needed when the appends and inserts are performed.
3369 // And of course UsefulBuf will never overrun the input buffer given
3370 // to it. No complex analysis of the error handling in this file is
3371 // needed to know that is true. Just read the UsefulBuf code.
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003372 pMe->uError = QCBOR_ERR_BUFFER_TOO_SMALL;
Michael Eckel5c531332020-03-02 01:35:30 +01003373 // QCBOR_ERR_BUFFER_TOO_SMALL masks other errors, but that is
3374 // OK. Once the caller fixes this, they'll be unmasked.
3375 }
3376
Laurence Lundblade6416a0f2020-09-19 23:26:34 -07003377 return (QCBORError)pMe->uError;
Michael Eckel5c531332020-03-02 01:35:30 +01003378}
3379
3380
Laurence Lundblade45d5e482020-09-15 21:15:15 -07003381/* ========================================================================
3382 END OF PRIVATE INLINE IMPLEMENTATION
3383 ======================================================================== */
Michael Eckel5c531332020-03-02 01:35:30 +01003384
3385#ifdef __cplusplus
3386}
3387#endif
3388
Laurence Lundblade844bb5c2020-03-01 17:27:25 -08003389#endif /* qcbor_encode_h */