blob: 46fa578315d2da1ca87b419dad41ceb3c76be1f6 [file] [log] [blame]
Michael Eckel5c531332020-03-02 01:35:30 +01001/*==============================================================================
2 Copyright (c) 2016-2018, The Linux Foundation.
3 Copyright (c) 2018-2020, Laurence Lundblade.
4 All rights reserved.
5
6Redistribution and use in source and binary forms, with or without
7modification, are permitted provided that the following conditions are
8met:
9 * Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above
12 copyright notice, this list of conditions and the following
13 disclaimer in the documentation and/or other materials provided
14 with the distribution.
15 * Neither the name of The Linux Foundation nor the names of its
16 contributors, nor the name "Laurence Lundblade" may be used to
17 endorse or promote products derived from this software without
18 specific prior written permission.
19
20THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
21WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
23ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
24BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
30IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 =============================================================================*/
32
33
Laurence Lundblade844bb5c2020-03-01 17:27:25 -080034#ifndef qcbor_encode_h
35#define qcbor_encode_h
Michael Eckel5c531332020-03-02 01:35:30 +010036
37
Laurence Lundblade844bb5c2020-03-01 17:27:25 -080038#include "qcbor/qcbor_common.h"
39#include "qcbor/qcbor_private.h"
Michael Eckel5c531332020-03-02 01:35:30 +010040#include <stdbool.h>
Laurence Lundblade844bb5c2020-03-01 17:27:25 -080041
Michael Eckel5c531332020-03-02 01:35:30 +010042
43#ifdef __cplusplus
44extern "C" {
Dave Thaler12b23752020-03-27 01:23:08 -070045#if 0
Michael Eckel5c531332020-03-02 01:35:30 +010046} // Keep editor indention formatting happy
47#endif
48#endif
49
Michael Eckel5c531332020-03-02 01:35:30 +010050
51/**
Laurence Lundblade844bb5c2020-03-01 17:27:25 -080052 @file qcbor_encode.h
Michael Eckel5c531332020-03-02 01:35:30 +010053
54 Q C B O R E n c o d e / D e c o d e
55
56 This implements CBOR -- Concise Binary Object Representation as
57 defined in [RFC 7049] (https://tools.ietf.org/html/rfc7049). More
58 info is at http://cbor.io. This is a near-complete implementation of
59 the specification. Limitations are listed further down.
60
61 CBOR is intentionally designed to be translatable to JSON, but not
62 all CBOR can convert to JSON. See RFC 7049 for more info on how to
63 construct CBOR that is the most JSON friendly.
64
65 The memory model for encoding and decoding is that encoded CBOR must
66 be in a contiguous buffer in memory. During encoding the caller must
67 supply an output buffer and if the encoding would go off the end of
68 the buffer an error is returned. During decoding the caller supplies
69 the encoded CBOR in a contiguous buffer and the decoder returns
70 pointers and lengths into that buffer for strings.
71
72 This implementation does not require malloc. All data structures
73 passed in/out of the APIs can fit on the stack.
74
75 Decoding of indefinite-length strings is a special case that requires
76 a "string allocator" to allocate memory into which the segments of
77 the string are coalesced. Without this, decoding will error out if an
78 indefinite-length string is encountered (indefinite-length maps and
79 arrays do not require the string allocator). A simple string
80 allocator called MemPool is built-in and will work if supplied with a
81 block of memory to allocate. The string allocator can optionally use
82 malloc() or some other custom scheme.
83
84 Here are some terms and definitions:
85
86 - "Item", "Data Item": An integer or string or such. The basic "thing" that
87 CBOR is about. An array is an item itself that contains some items.
88
89 - "Array": An ordered sequence of items, the same as JSON.
90
91 - "Map": A collection of label/value pairs. Each pair is a data
92 item. A JSON "object" is the same as a CBOR "map".
93
94 - "Label": The data item in a pair in a map that names or identifies
95 the pair, not the value. This implementation refers to it as a
96 "label". JSON refers to it as the "name". The CBOR RFC refers to it
97 this as a "key". This implementation chooses label instead because
98 key is too easily confused with a cryptographic key. The COSE
99 standard, which uses CBOR, has also chosen to use the term "label"
100 rather than "key" for this same reason.
101
102 - "Key": See "Label" above.
103
104 - "Tag": Optional integer that can be added before each data item
105 usually to indicate it is new or more specific data type. For
106 example, a tag can indicate an integer is a date, or that a map is to
107 be considered a type (analogous to a typedef in C).
108
109 - "Initial Byte": The first byte of an encoded item. Encoding and
110 decoding of this byte is taken care of by the implementation.
111
112 - "Additional Info": In addition to the major type, all data items
113 have some other info. This is usually the length of the data but can
114 be several other things. Encoding and decoding of this is taken care
115 of by the implementation.
116
117 CBOR has two mechanisms for tagging and labeling the data values like
118 integers and strings. For example, an integer that represents
119 someone's birthday in epoch seconds since Jan 1, 1970 could be
120 encoded like this:
121
122 - First it is CBOR_MAJOR_TYPE_POSITIVE_INT (@ref QCBOR_TYPE_INT64),
123 the primitive positive integer.
124
125 - Next it has a "tag" @ref CBOR_TAG_DATE_EPOCH indicating the integer
126 represents a date in the form of the number of seconds since Jan 1,
127 1970.
128
129 - Last it has a string "label" like "BirthDate" indicating the
130 meaning of the data.
131
132 The encoded binary looks like this:
133
134 a1 # Map of 1 item
135 69 # Indicates text string of 9 bytes
136 426972746844617465 # The text "BirthDate"
137 c1 # Tags next integer as epoch date
138 1a # Indicates a 4-byte integer
139 580d4172 # unsigned integer date 1477263730
140
141 Implementors using this API will primarily work with
142 labels. Generally, tags are only needed for making up new data
143 types. This implementation covers most of the data types defined in
144 the RFC using tags. It also, allows for the use of custom tags if
145 necessary.
146
147 This implementation explicitly supports labels that are text strings
148 and integers. Text strings translate nicely into JSON objects and are
149 very readable. Integer labels are much less readable but can be very
150 compact. If they are in the range of 0 to 23, they take up only one
151 byte.
152
153 CBOR allows a label to be any type of data including an array or a
154 map. It is possible to use this API to construct and parse such
155 labels, but it is not explicitly supported.
156
157 A common encoding usage mode is to invoke the encoding twice. First
158 with no output buffer to compute the length of the needed output
159 buffer. Then the correct sized output buffer is allocated. Last the
160 encoder is invoked again, this time with the output buffer.
161
162 The double invocation is not required if the maximum output buffer
163 size can be predicted. This is usually possible for simple CBOR
164 structures. If the double invocation is implemented, it can be in a
165 loop or function as in the example code so that the code doesn't have
166 to actually be written twice, saving code size.
167
168 If a buffer too small to hold the encoded output is given, the error
169 @ref QCBOR_ERR_BUFFER_TOO_SMALL will be returned. Data will never be
170 written off the end of the output buffer no matter which functions
171 here are called or what parameters are passed to them.
172
173 The encoding error handling is simple. The only possible errors are
174 trying to encode structures that are too large or too complex. There
175 are no internal malloc calls so there will be no failures for out of
176 memory. The error state is tracked internally, so there is no need
177 to check for errors when encoding. Only the return code from
178 QCBOREncode_Finish() need be checked as once an error happens, the
179 encoder goes into an error state and calls to it to add more data
180 will do nothing. An error check is not needed after every data item
181 is added.
182
183 Encoding generally proceeds by calling QCBOREncode_Init(), calling
184 lots of @c QCBOREncode_AddXxx() functions and calling
185 QCBOREncode_Finish(). There are many @c QCBOREncode_AddXxx()
186 functions for various data types. The input buffers need only to be
187 valid during the @c QCBOREncode_AddXxx() calls as the data is copied
188 into the output buffer.
189
190 There are three `Add` functions for each data type. The first / main
191 one for the type is for adding the data item to an array. The second
192 one's name ends in `ToMap`, is used for adding data items to maps and
193 takes a string argument that is its label in the map. The third one
194 ends in `ToMapN`, is also used for adding data items to maps, and
195 takes an integer argument that is its label in the map.
196
197 The simplest aggregate type is an array, which is a simple ordered
198 set of items without labels the same as JSON arrays. Call
199 QCBOREncode_OpenArray() to open a new array, then various @c
200 QCBOREncode_AddXxx() functions to put items in the array and then
201 QCBOREncode_CloseArray(). Nesting to the limit @ref
202 QCBOR_MAX_ARRAY_NESTING is allowed. All opens must be matched by
203 closes or an encoding error will be returned.
204
205 The other aggregate type is a map which does use labels. The `Add`
206 functions that end in `ToMap` and `ToMapN` are convenient ways to add
207 labeled data items to a map. You can also call any type of `Add`
208 function once to add a label of any time and then call any type of
209 `Add` again to add its value.
210
211 Note that when you nest arrays or maps in a map, the nested array or
212 map has a label.
Laurence Lundbladee3553422020-05-02 11:11:17 -0700213
214 Many CBOR-based protocols start with an array or map. This makes them
215 self-delimiting. No external length or end marker is needed to know
216 the end. It is also possible not start this way, in which case this
217 it is usually called a CBOR sequence which is described in [RFC 8742] (https://tools.ietf.org/html/rfc8742 ).
218 This encoder supports either just by whether the first item added is an
219 array, map or other.
Michael Eckel5c531332020-03-02 01:35:30 +0100220
221 @anchor Tags-Overview
222 Any CBOR data item can be tagged to add semantics, define a new data
223 type or such. Some tags are fully standardized and some are just
224 registered. Others are not registered and used in a proprietary way.
225
226 Encoding and decoding of many of the registered tags is fully
227 implemented by QCBOR. It is also possible to encode and decode tags
228 that are not directly supported. For many use cases the built-in tag
229 support should be adequate.
230
231 For example, the registered epoch date tag is supported in encoding
232 by QCBOREncode_AddDateEpoch() and in decoding by @ref
233 QCBOR_TYPE_DATE_EPOCH and the @c epochDate member of @ref
234 QCBORItem. This is typical of the built-in tag support. There is an
235 API to encode data for it and a @c QCBOR_TYPE_XXX when it is decoded.
236
237 Tags are registered in the [IANA CBOR Tags Registry]
238 (https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml). There
239 are roughly three options to create a new tag. First, a public
240 specification can be created and the new tag registered with IANA.
241 This is the most formal. Second, the new tag can be registered with
242 IANA with just a short description rather than a full specification.
243 These tags must be greater than 256. Third, a tag can be used without
244 any IANA registration, though the registry should be checked to see
245 that the new value doesn't collide with one that is registered. The
246 value of these tags must be 256 or larger.
247
248 The encoding side of tags not built-in is handled by
249 QCBOREncode_AddTag() and is relatively simple. Tag decoding is more
250 complex and mainly handled by QCBORDecode_GetNext(). Decoding of the
251 structure of tagged data not built-in (if there is any) has to be
252 implemented by the caller.
253
254 Summary Limits of this implementation:
255 - The entire encoded CBOR must fit into contiguous memory.
256 - Max size of encoded / decoded CBOR data is @c UINT32_MAX (4GB).
257 - Max array / map nesting level when encoding / decoding is
258 @ref QCBOR_MAX_ARRAY_NESTING (this is typically 15).
259 - Max items in an array or map when encoding / decoding is
260 @ref QCBOR_MAX_ITEMS_IN_ARRAY (typically 65,536).
261 - Does not directly support labels in maps other than text strings & integers.
262 - Does not directly support integer labels greater than @c INT64_MAX.
263 - Epoch dates limited to @c INT64_MAX (+/- 292 billion years).
264 - Exponents for bigfloats and decimal integers are limited to @c INT64_MAX.
265 - Tags on labels are ignored during decoding.
266 - There is no duplicate detection of map labels (but duplicates are passed on).
267 - Works only on 32- and 64-bit CPUs (modifications could make it work
268 on 16-bit CPUs).
269
270 The public interface uses @c size_t for all lengths. Internally the
271 implementation uses 32-bit lengths by design to use less memory and
272 fit structures on the stack. This limits the encoded CBOR it can work
273 with to size @c UINT32_MAX (4GB) which should be enough.
274
275 This implementation assumes two's compliment integer machines. @c
276 <stdint.h> also requires this. It is possible to modify this
277 implementation for another integer representation, but all modern
278 machines seem to be two's compliment.
279
280 */
281
282
Michael Eckel5c531332020-03-02 01:35:30 +0100283/*
284 The size of the buffer to be passed to QCBOREncode_EncodeHead(). It is one
285 byte larger than sizeof(uint64_t) + 1, the actual maximum size of the
286 head of a CBOR data item. because QCBOREncode_EncodeHead() needs
287 one extra byte to work.
288 */
289#define QCBOR_HEAD_BUFFER_SIZE (sizeof(uint64_t) + 2)
290
Michael Eckel5c531332020-03-02 01:35:30 +0100291
292
293/**
294 QCBOREncodeContext is the data type that holds context for all the
295 encoding functions. It is less than 200 bytes, so it can go on the
296 stack. The contents are opaque, and the caller should not access
297 internal members. A context may be re used serially as long as it is
298 re initialized.
299 */
300typedef struct _QCBOREncodeContext QCBOREncodeContext;
301
302
303/**
304 Initialize the encoder to prepare to encode some CBOR.
305
306 @param[in,out] pCtx The encoder context to initialize.
307 @param[in] Storage The buffer into which this encoded result
308 will be placed.
309
310 Call this once at the start of an encoding of a CBOR structure. Then
311 call the various @c QCBOREncode_AddXxx() functions to add the data
312 items. Then call QCBOREncode_Finish().
313
314 The maximum output buffer is @c UINT32_MAX (4GB). This is not a
315 practical limit in any way and reduces the memory needed by the
316 implementation. The error @ref QCBOR_ERR_BUFFER_TOO_LARGE will be
317 returned by QCBOREncode_Finish() if a larger buffer length is passed
318 in.
319
320 If this is called with @c Storage.ptr as @c NULL and @c Storage.len a
321 large value like @c UINT32_MAX, all the QCBOREncode_AddXxx()
322 functions and QCBOREncode_Finish() can still be called. No data will
323 be encoded, but the length of what would be encoded will be
324 calculated. The length of the encoded structure will be handed back
325 in the call to QCBOREncode_Finish(). You can then allocate a buffer
326 of that size and call all the encoding again, this time to fill in
327 the buffer.
328
329 A @ref QCBOREncodeContext can be reused over and over as long as
330 QCBOREncode_Init() is called.
331 */
332void QCBOREncode_Init(QCBOREncodeContext *pCtx, UsefulBuf Storage);
333
334
335/**
336 @brief Add a signed 64-bit integer to the encoded output.
337
338 @param[in] pCtx The encoding context to add the integer to.
339 @param[in] nNum The integer to add.
340
341 The integer will be encoded and added to the CBOR output.
342
343 This function figures out the size and the sign and encodes in the
344 correct minimal CBOR. Specifically, it will select CBOR major type 0
345 or 1 based on sign and will encode to 1, 2, 4 or 8 bytes depending on
346 the value of the integer. Values less than 24 effectively encode to
347 one byte because they are encoded in with the CBOR major type. This
348 is a neat and efficient characteristic of CBOR that can be taken
349 advantage of when designing CBOR-based protocols. If integers like
350 tags can be kept between -23 and 23 they will be encoded in one byte
351 including the major type.
352
353 If you pass a smaller int, say an @c int16_t or a small value, say
354 100, the encoding will still be CBOR's most compact that can
355 represent the value. For example, CBOR always encodes the value 0 as
356 one byte, 0x00. The representation as 0x00 includes identification of
357 the type as an integer too as the major type for an integer is 0. See
358 [RFC 7049] (https://tools.ietf.org/html/rfc7049) Appendix A for more
359 examples of CBOR encoding. This compact encoding is also canonical
360 CBOR as per section 3.9 in RFC 7049.
361
362 There are no functions to add @c int16_t or @c int32_t because they
363 are not necessary because this always encodes to the smallest number
364 of bytes based on the value (If this code is running on a 32-bit
365 machine having a way to add 32-bit integers would reduce code size
366 some).
367
368 If the encoding context is in an error state, this will do
369 nothing. If an error occurs when adding this integer, the internal
370 error flag will be set, and the error will be returned when
371 QCBOREncode_Finish() is called.
372
373 See also QCBOREncode_AddUInt64().
374 */
375void QCBOREncode_AddInt64(QCBOREncodeContext *pCtx, int64_t nNum);
376
377static void QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum);
378
379static void QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum);
380
381
382/**
383 @brief Add an unsigned 64-bit integer to the encoded output.
384
385 @param[in] pCtx The encoding context to add the integer to.
386 @param[in] uNum The integer to add.
387
388 The integer will be encoded and added to the CBOR output.
389
390 The only reason so use this function is for integers larger than @c
391 INT64_MAX and smaller than @c UINT64_MAX. Otherwise
392 QCBOREncode_AddInt64() will work fine.
393
394 Error handling is the same as for QCBOREncode_AddInt64().
395 */
396void QCBOREncode_AddUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
397
398static void QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum);
399
400static void QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum);
401
402
403/**
404 @brief Add a UTF-8 text string to the encoded output.
405
406 @param[in] pCtx The encoding context to add the text to.
407 @param[in] Text Pointer and length of text to add.
408
409 The text passed in must be unencoded UTF-8 according to [RFC 3629]
410 (https://tools.ietf.org/html/rfc3629). There is no NULL
411 termination. The text is added as CBOR major type 3.
412
413 If called with @c nBytesLen equal to 0, an empty string will be
414 added. When @c nBytesLen is 0, @c pBytes may be @c NULL.
415
416 Note that the restriction of the buffer length to a @c uint32_t is
417 entirely intentional as this encoder is not capable of encoding
418 lengths greater. This limit to 4GB for a text string should not be a
419 problem.
420
421 Error handling is the same as QCBOREncode_AddInt64().
422 */
423static void QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text);
424
425static void QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text);
426
427static void QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text);
428
429
430/**
431 @brief Add a UTF-8 text string to the encoded output.
432
433 @param[in] pCtx The encoding context to add the text to.
434 @param[in] szString Null-terminated text to add.
435
436 This works the same as QCBOREncode_AddText().
437 */
438static void QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString);
439
440static void QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString);
441
442static void QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString);
443
444
445/**
446 @brief Add a floating-point number to the encoded output.
447
448 @param[in] pCtx The encoding context to add the double to.
449 @param[in] dNum The double-precision number to add.
450
451 This outputs a floating-point number with CBOR major type 7.
452
453 This will selectively encode the double-precision floating-point
454 number as either double-precision, single-precision or
455 half-precision. It will always encode infinity, NaN and 0 has half
456 precision. If no precision will be lost in the conversion to
457 half-precision, then it will be converted and encoded. If not and no
458 precision will be lost in conversion to single-precision, then it
459 will be converted and encoded. If not, then no conversion is
460 performed, and it encoded as a double.
461
462 Half-precision floating-point numbers take up 2 bytes, half that of
463 single-precision, one quarter of double-precision
464
465 This automatically reduces the size of encoded messages a lot, maybe
466 even by four if most of values are 0, infinity or NaN.
467
468 On decode, these will always be returned as a double.
469
470 Error handling is the same as QCBOREncode_AddInt64().
471 */
472void QCBOREncode_AddDouble(QCBOREncodeContext *pCtx, double dNum);
473
474static void QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
475
476static void QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
477
478
479/**
480 @brief Add an optional tag.
481
482 @param[in] pCtx The encoding context to add the tag to.
483 @param[in] uTag The tag to add
484
485 This outputs a CBOR major type 6 item that tags the next data item
486 that is output usually to indicate it is some new data type.
487
488 For many of the common standard tags, a function to encode data using
489 it is provided and this is not needed. For example,
490 QCBOREncode_AddDateEpoch() already exists to output integers
491 representing dates with the right tag.
492
493 The tag is applied to the next data item added to the encoded
494 output. That data item that is to be tagged can be of any major CBOR
495 type. Any number of tags can be added to a data item by calling this
496 multiple times before the data item is added.
497
498 See @ref Tags-Overview for discussion of creating new non-standard
499 tags. See QCBORDecode_GetNext() for discussion of decoding custom
500 tags.
501*/
502void QCBOREncode_AddTag(QCBOREncodeContext *pCtx,uint64_t uTag);
503
504
505/**
506 @brief Add an epoch-based date.
507
508 @param[in] pCtx The encoding context to add the date to.
509 @param[in] date Number of seconds since 1970-01-01T00:00Z in UTC time.
510
511 As per RFC 7049 this is similar to UNIX/Linux/POSIX dates. This is
512 the most compact way to specify a date and time in CBOR. Note that
513 this is always UTC and does not include the time zone. Use
514 QCBOREncode_AddDateString() if you want to include the time zone.
515
516 The integer encoding rules apply here so the date will be encoded in
517 a minimal number of bytes. Until about the year 2106 these dates will
518 encode in 6 bytes -- one byte for the tag, one byte for the type and
519 4 bytes for the integer. After that it will encode to 10 bytes.
520
521 Negative values are supported for dates before 1970.
522
523 If you care about leap-seconds and that level of accuracy, make sure
524 the system you are running this code on does it correctly. This code
525 just takes the value passed in.
526
527 This implementation cannot encode fractional seconds using float or
528 double even though that is allowed by CBOR, but you can encode them
529 if you want to by calling QCBOREncode_AddDouble() and
530 QCBOREncode_AddTag().
531
532 Error handling is the same as QCBOREncode_AddInt64().
533 */
534static void QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx, int64_t date);
535
536static void QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t date);
537
538static void QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t date);
539
540
541/**
542 @brief Add a byte string to the encoded output.
543
544 @param[in] pCtx The encoding context to add the bytes to.
545 @param[in] Bytes Pointer and length of the input data.
546
547 Simply adds the bytes to the encoded output as CBOR major type 2.
548
549 If called with @c Bytes.len equal to 0, an empty string will be
550 added. When @c Bytes.len is 0, @c Bytes.ptr may be @c NULL.
551
552 Error handling is the same as QCBOREncode_AddInt64().
553 */
554static void QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
555
556static void QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
557
558static void QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
559
560
561
562/**
563 @brief Add a binary UUID to the encoded output.
564
565 @param[in] pCtx The encoding context to add the UUID to.
566 @param[in] Bytes Pointer and length of the binary UUID.
567
568 A binary UUID as defined in [RFC 4122]
569 (https://tools.ietf.org/html/rfc4122) is added to the output.
570
571 It is output as CBOR major type 2, a binary string, with tag @ref
572 CBOR_TAG_BIN_UUID indicating the binary string is a UUID.
573 */
574static void QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
575
576static void QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
577
578static void QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
579
580
581/**
582 @brief Add a positive big number to the encoded output.
583
584 @param[in] pCtx The encoding context to add the big number to.
585 @param[in] Bytes Pointer and length of the big number.
586
587 Big numbers are integers larger than 64-bits. Their format is
588 described in [RFC 7049] (https://tools.ietf.org/html/rfc7049).
589
590 It is output as CBOR major type 2, a binary string, with tag @ref
591 CBOR_TAG_POS_BIGNUM indicating the binary string is a positive big
592 number.
593
594 Often big numbers are used to represent cryptographic keys, however,
595 COSE which defines representations for keys chose not to use this
596 particular type.
597 */
598static void QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
599
600static void QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
601
602static void QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
603
604
605/**
606 @brief Add a negative big number to the encoded output.
607
608 @param[in] pCtx The encoding context to add the big number to.
609 @param[in] Bytes Pointer and length of the big number.
610
611 Big numbers are integers larger than 64-bits. Their format is
612 described in [RFC 7049] (https://tools.ietf.org/html/rfc7049).
613
614 It is output as CBOR major type 2, a binary string, with tag @ref
615 CBOR_TAG_NEG_BIGNUM indicating the binary string is a negative big
616 number.
617
618 Often big numbers are used to represent cryptographic keys, however,
619 COSE which defines representations for keys chose not to use this
620 particular type.
621 */
622static void QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
623
624static void QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
625
626static void QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
627
628
629#ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
630/**
631 @brief Add a decimal fraction to the encoded output.
632
633 @param[in] pCtx The encoding context to add the decimal fraction to.
634 @param[in] nMantissa The mantissa.
635 @param[in] nBase10Exponent The exponent.
636
637 The value is nMantissa * 10 ^ nBase10Exponent.
638
639 A decimal fraction is good for exact representation of some values
640 that can't be represented exactly with standard C (IEEE 754)
641 floating-point numbers. Much larger and much smaller numbers can
642 also be represented than floating-point because of the larger number
643 of bits in the exponent.
644
645 The decimal fraction is conveyed as two integers, a mantissa and a
646 base-10 scaling factor.
647
648 For example, 273.15 is represented by the two integers 27315 and -2.
649
650 The exponent and mantissa have the range from @c INT64_MIN to
651 @c INT64_MAX for both encoding and decoding (CBOR allows @c -UINT64_MAX
652 to @c UINT64_MAX, but this implementation doesn't support this range to
653 reduce code size and interface complexity a little).
654
655 CBOR Preferred encoding of the integers is used, thus they will be encoded
656 in the smallest number of bytes possible.
657
658 See also QCBOREncode_AddDecimalFractionBigNum() for a decimal
659 fraction with arbitrarily large precision and QCBOREncode_AddBigFloat().
660
661 There is no representation of positive or negative infinity or NaN
662 (Not a Number). Use QCBOREncode_AddDouble() to encode them.
663
664 See @ref expAndMantissa for decoded representation.
665 */
666static void QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pCtx,
667 int64_t nMantissa,
668 int64_t nBase10Exponent);
669
670static void QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pCtx,
671 const char *szLabel,
672 int64_t nMantissa,
673 int64_t nBase10Exponent);
674
675static void QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pCtx,
676 int64_t nLabel,
677 int64_t nMantissa,
678 int64_t nBase10Exponent);
679
680/**
681 @brief Add a decimal fraction with a big number mantissa to the encoded output.
682
683 @param[in] pCtx The encoding context to add the decimal fraction to.
684 @param[in] Mantissa The mantissa.
685 @param[in] bIsNegative false if mantissa is positive, true if negative.
686 @param[in] nBase10Exponent The exponent.
687
688 This is the same as QCBOREncode_AddDecimalFraction() except the
689 mantissa is a big number (See QCBOREncode_AddPositiveBignum())
690 allowing for arbitrarily large precision.
691
692 See @ref expAndMantissa for decoded representation.
693 */
694static void QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pCtx,
695 UsefulBufC Mantissa,
696 bool bIsNegative,
697 int64_t nBase10Exponent);
698
699static void QCBOREncode_AddDecimalFractionBigNumToMap(QCBOREncodeContext *pCtx,
700 const char *szLabel,
701 UsefulBufC Mantissa,
702 bool bIsNegative,
703 int64_t nBase10Exponent);
704
705static void QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
706 int64_t nLabel,
707 UsefulBufC Mantissa,
708 bool bIsNegative,
709 int64_t nBase10Exponent);
710
711/**
712 @brief Add a big floating-point number to the encoded output.
713
714 @param[in] pCtx The encoding context to add the bigfloat to.
715 @param[in] nMantissa The mantissa.
716 @param[in] nBase2Exponent The exponent.
717
718 The value is nMantissa * 2 ^ nBase2Exponent.
719
720 "Bigfloats", as CBOR terms them, are similar to IEEE floating-point
721 numbers in having a mantissa and base-2 exponent, but they are not
722 supported by hardware or encoded the same. They explicitly use two
723 CBOR-encoded integers to convey the mantissa and exponent, each of which
724 can be 8, 16, 32 or 64 bits. With both the mantissa and exponent
725 64 bits they can express more precision and a larger range than an
726 IEEE double floating-point number. See
727 QCBOREncode_AddBigFloatBigNum() for even more precision.
728
729 For example, 1.5 would be represented by a mantissa of 3 and an
730 exponent of -1.
731
732 The exponent and mantissa have the range from @c INT64_MIN to
733 @c INT64_MAX for both encoding and decoding (CBOR allows @c -UINT64_MAX
734 to @c UINT64_MAX, but this implementation doesn't support this range to
735 reduce code size and interface complexity a little).
736
737 CBOR Preferred encoding of the integers is used, thus they will be encoded
738 in the smallest number of bytes possible.
739
740 This can also be used to represent floating-point numbers in
741 environments that don't support IEEE 754.
742
743 See @ref expAndMantissa for decoded representation.
744 */
745static void QCBOREncode_AddBigFloat(QCBOREncodeContext *pCtx,
746 int64_t nMantissa,
747 int64_t nBase2Exponent);
748
749static void QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pCtx,
750 const char *szLabel,
751 int64_t nMantissa,
752 int64_t nBase2Exponent);
753
754static void QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pCtx,
755 int64_t nLabel,
756 int64_t nMantissa,
757 int64_t nBase2Exponent);
758
759
760/**
761 @brief Add a big floating-point number with a big number mantissa to
762 the encoded output.
763
764 @param[in] pCtx The encoding context to add the bigfloat to.
765 @param[in] Mantissa The mantissa.
766 @param[in] bIsNegative false if mantissa is positive, true if negative.
767 @param[in] nBase2Exponent The exponent.
768
769 This is the same as QCBOREncode_AddBigFloat() except the mantissa is
770 a big number (See QCBOREncode_AddPositiveBignum()) allowing for
771 arbitrary precision.
772
773 See @ref expAndMantissa for decoded representation.
774 */
775static void QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pCtx,
776 UsefulBufC Mantissa,
777 bool bIsNegative,
778 int64_t nBase2Exponent);
779
780static void QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pCtx,
781 const char *szLabel,
782 UsefulBufC Mantissa,
783 bool bIsNegative,
784 int64_t nBase2Exponent);
785
786static void QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
787 int64_t nLabel,
788 UsefulBufC Mantissa,
789 bool bIsNegative,
790 int64_t nBase2Exponent);
791#endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
792
793
794/**
795 @brief Add a text URI to the encoded output.
796
797 @param[in] pCtx The encoding context to add the URI to.
798 @param[in] URI Pointer and length of the URI.
799
800 The format of URI must be per [RFC 3986]
801 (https://tools.ietf.org/html/rfc3986).
802
803 It is output as CBOR major type 3, a text string, with tag @ref
804 CBOR_TAG_URI indicating the text string is a URI.
805
806 A URI in a NULL-terminated string, @c szURI, can be easily added with
807 this code:
808
809 QCBOREncode_AddURI(pCtx, UsefulBuf_FromSZ(szURI));
810 */
811static void QCBOREncode_AddURI(QCBOREncodeContext *pCtx, UsefulBufC URI);
812
813static void QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC URI);
814
815static void QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC URI);
816
817
818/**
819 @brief Add Base64-encoded text to encoded output.
820
821 @param[in] pCtx The encoding context to add the base-64 text to.
822 @param[in] B64Text Pointer and length of the base-64 encoded text.
823
824 The text content is Base64 encoded data per [RFC 4648]
825 (https://tools.ietf.org/html/rfc4648).
826
827 It is output as CBOR major type 3, a text string, with tag @ref
828 CBOR_TAG_B64 indicating the text string is Base64 encoded.
829 */
830static void QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx, UsefulBufC B64Text);
831
832static void QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text);
833
834static void QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text);
835
836
837/**
838 @brief Add base64url encoded data to encoded output.
839
840 @param[in] pCtx The encoding context to add the base64url to.
841 @param[in] B64Text Pointer and length of the base64url encoded text.
842
843 The text content is base64URL encoded text as per [RFC 4648]
844 (https://tools.ietf.org/html/rfc4648).
845
846 It is output as CBOR major type 3, a text string, with tag @ref
847 CBOR_TAG_B64URL indicating the text string is a Base64url encoded.
848 */
849static void QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx, UsefulBufC B64Text);
850
851static void QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text);
852
853static void QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text);
854
855
856/**
857 @brief Add Perl Compatible Regular Expression.
858
859 @param[in] pCtx The encoding context to add the regular expression to.
860 @param[in] Regex Pointer and length of the regular expression.
861
862 The text content is Perl Compatible Regular
863 Expressions (PCRE) / JavaScript syntax [ECMA262].
864
865 It is output as CBOR major type 3, a text string, with tag @ref
866 CBOR_TAG_REGEX indicating the text string is a regular expression.
867 */
868static void QCBOREncode_AddRegex(QCBOREncodeContext *pCtx, UsefulBufC Regex);
869
870static void QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Regex);
871
872static void QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Regex);
873
874
875/**
876 @brief MIME encoded text to the encoded output.
877
878 @param[in] pCtx The encoding context to add the MIME data to.
879 @param[in] MIMEData Pointer and length of the regular expression.
880
881 The text content is in MIME format per [RFC 2045]
882 (https://tools.ietf.org/html/rfc2045) including the headers. Note
883 that this only supports text-format MIME. Binary MIME is not
884 supported.
885
886 It is output as CBOR major type 3, a text string, with tag
887 @ref CBOR_TAG_MIME indicating the text string is MIME data.
888 */
889static void QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx, UsefulBufC MIMEData);
890
891static void QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC MIMEData);
892
893static void QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC MIMEData);
894
895
896/**
897 @brief Add an RFC 3339 date string
898
899 @param[in] pCtx The encoding context to add the date to.
900 @param[in] szDate Null-terminated string with date to add.
901
902 The string szDate should be in the form of [RFC 3339]
903 (https://tools.ietf.org/html/rfc3339) as defined by section 3.3 in
904 [RFC 4287] (https://tools.ietf.org/html/rfc4287). This is as
905 described in section 2.4.1 in [RFC 7049]
906 (https://tools.ietf.org/html/rfc7049).
907
908 Note that this function doesn't validate the format of the date string
909 at all. If you add an incorrect format date string, the generated
910 CBOR will be incorrect and the receiver may not be able to handle it.
911
912 Error handling is the same as QCBOREncode_AddInt64().
913 */
914static void QCBOREncode_AddDateString(QCBOREncodeContext *pCtx, const char *szDate);
915
916static void QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szDate);
917
918static void QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szDate);
919
920
921/**
922 @brief Add a standard Boolean.
923
924 @param[in] pCtx The encoding context to add the Boolean to.
925 @param[in] b true or false from @c <stdbool.h>.
926
927 Adds a Boolean value as CBOR major type 7.
928
929 Error handling is the same as QCBOREncode_AddInt64().
930 */
931static void QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b);
932
933static void QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b);
934
935static void QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b);
936
937
938
939/**
940 @brief Add a NULL to the encoded output.
941
942 @param[in] pCtx The encoding context to add the NULL to.
943
944 Adds the NULL value as CBOR major type 7.
945
946 This NULL doesn't have any special meaning in CBOR such as a
947 terminating value for a string or an empty value.
948
949 Error handling is the same as QCBOREncode_AddInt64().
950 */
951static void QCBOREncode_AddNULL(QCBOREncodeContext *pCtx);
952
953static void QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel);
954
955static void QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
956
957
958/**
959 @brief Add an "undef" to the encoded output.
960
961 @param[in] pCtx The encoding context to add the "undef" to.
962
963 Adds the undef value as CBOR major type 7.
964
965 Note that this value will not translate to JSON.
966
967 This Undef doesn't have any special meaning in CBOR such as a
968 terminating value for a string or an empty value.
969
970 Error handling is the same as QCBOREncode_AddInt64().
971 */
972static void QCBOREncode_AddUndef(QCBOREncodeContext *pCtx);
973
974static void QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel);
975
976static void QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
977
978
979/**
980 @brief Indicates that the next items added are in an array.
981
982 @param[in] pCtx The encoding context to open the array in.
983
984 Arrays are the basic CBOR aggregate or structure type. Call this
985 function to start or open an array. Then call the various @c
986 QCBOREncode_AddXxx() functions to add the items that go into the
987 array. Then call QCBOREncode_CloseArray() when all items have been
988 added. The data items in the array can be of any type and can be of
989 mixed types.
990
991 Nesting of arrays and maps is allowed and supported just by calling
992 QCBOREncode_OpenArray() again before calling
993 QCBOREncode_CloseArray(). While CBOR has no limit on nesting, this
994 implementation does in order to keep it smaller and simpler. The
995 limit is @ref QCBOR_MAX_ARRAY_NESTING. This is the max number of
996 times this can be called without calling
997 QCBOREncode_CloseArray(). QCBOREncode_Finish() will return @ref
998 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP when it is called as this function
999 just sets an error state and returns no value when this occurs.
1000
1001 If you try to add more than @ref QCBOR_MAX_ITEMS_IN_ARRAY items to a
1002 single array or map, @ref QCBOR_ERR_ARRAY_TOO_LONG will be returned
1003 when QCBOREncode_Finish() is called.
1004
1005 An array itself must have a label if it is being added to a map.
1006 Note that array elements do not have labels (but map elements do).
1007
1008 An array itself may be tagged by calling QCBOREncode_AddTag() before this call.
1009 */
1010static void QCBOREncode_OpenArray(QCBOREncodeContext *pCtx);
1011
1012static void QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1013
1014static void QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1015
1016
1017/**
1018 @brief Close an open array.
1019
1020 @param[in] pCtx The encoding context to close the array in.
1021
1022 The closes an array opened by QCBOREncode_OpenArray(). It reduces
1023 nesting level by one. All arrays (and maps) must be closed before
1024 calling QCBOREncode_Finish().
1025
1026 When an error occurs as a result of this call, the encoder records
1027 the error and enters the error state. The error will be returned when
1028 QCBOREncode_Finish() is called.
1029
1030 If this has been called more times than QCBOREncode_OpenArray(), then
1031 @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when QCBOREncode_Finish()
1032 is called.
1033
1034 If this is called and it is not an array that is currently open, @ref
1035 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
1036 is called.
1037 */
1038static void QCBOREncode_CloseArray(QCBOREncodeContext *pCtx);
1039
1040
1041/**
1042 @brief Indicates that the next items added are in a map.
1043
1044 @param[in] pCtx The encoding context to open the map in.
1045
1046 See QCBOREncode_OpenArray() for more information, particularly error
1047 handling.
1048
1049 CBOR maps are an aggregate type where each item in the map consists
1050 of a label and a value. They are similar to JSON objects.
1051
1052 The value can be any CBOR type including another map.
1053
1054 The label can also be any CBOR type, but in practice they are
1055 typically, integers as this gives the most compact output. They might
1056 also be text strings which gives readability and translation to JSON.
1057
1058 Every @c QCBOREncode_AddXxx() call has one version that ends with @c
1059 InMap for adding items to maps with string labels and one that ends
1060 with @c InMapN that is for adding with integer labels.
1061
1062 RFC 7049 uses the term "key" instead of "label".
1063
1064 If you wish to use map labels that are neither integer labels nor
1065 text strings, then just call the QCBOREncode_AddXxx() function
1066 explicitly to add the label. Then call it again to add the value.
1067
1068 See the [RFC 7049] (https://tools.ietf.org/html/rfc7049) for a lot
1069 more information on creating maps.
1070 */
1071static void QCBOREncode_OpenMap(QCBOREncodeContext *pCtx);
1072
1073static void QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1074
1075static void QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1076
1077
1078
1079/**
1080 @brief Close an open map.
1081
1082 @param[in] pCtx The encoding context to close the map in .
1083
1084 This closes a map opened by QCBOREncode_OpenMap(). It reduces nesting
1085 level by one.
1086
1087 When an error occurs as a result of this call, the encoder records
1088 the error and enters the error state. The error will be returned when
1089 QCBOREncode_Finish() is called.
1090
1091 If this has been called more times than QCBOREncode_OpenMap(),
1092 then @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1093 QCBOREncode_Finish() is called.
1094
1095 If this is called and it is not a map that is currently open, @ref
1096 QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
1097 is called.
1098 */
1099static void QCBOREncode_CloseMap(QCBOREncodeContext *pCtx);
1100
1101
1102/**
1103 @brief Indicate start of encoded CBOR to be wrapped in a bstr.
1104
1105 @param[in] pCtx The encoding context to open the bstr-wrapped CBOR in.
1106
1107 All added encoded items between this call and a call to
1108 QCBOREncode_CloseBstrWrap2() will be wrapped in a bstr. They will
1109 appear in the final output as a byte string. That byte string will
1110 contain encoded CBOR. This increases nesting level by one.
1111
1112 The typical use case is for encoded CBOR that is to be
1113 cryptographically hashed, as part of a [RFC 8152, COSE]
1114 (https://tools.ietf.org/html/rfc8152) implementation.
1115
1116 Using QCBOREncode_BstrWrap() and QCBOREncode_CloseBstrWrap2() avoids
1117 having to encode the items first in one buffer (e.g., the COSE
1118 payload) and then add that buffer as a bstr to another encoding
1119 (e.g. the COSE to-be-signed bytes, the @c Sig_structure) potentially
1120 halving the memory needed.
1121
1122 RFC 7049 states the purpose of this wrapping is to prevent code
1123 relaying the signed data but not verifying it from tampering with the
1124 signed data thus making the signature unverifiable. It is also quite
1125 beneficial for the signature verification code. Standard CBOR
1126 decoders usually do not give access to partially decoded CBOR as
1127 would be needed to check the signature of some CBOR. With this
1128 wrapping, standard CBOR decoders can be used to get to all the data
1129 needed for a signature verification.
1130 */
1131static void QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx);
1132
1133static void QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
1134
1135static void QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
1136
1137
1138/**
1139 @brief Close a wrapping bstr.
1140
1141 @param[in] pCtx The encoding context to close of bstr wrapping in.
1142 @param[in] bIncludeCBORHead Include the encoded CBOR head of the bstr
1143 as well as the bytes in @c pWrappedCBOR.
1144 @param[out] pWrappedCBOR A @ref UsefulBufC containing wrapped bytes.
1145
1146 The closes a wrapping bstr opened by QCBOREncode_BstrWrap(). It reduces
1147 nesting level by one.
1148
1149 A pointer and length of the enclosed encoded CBOR is returned in @c
1150 *pWrappedCBOR if it is not @c NULL. The main purpose of this is so
1151 this data can be hashed (e.g., with SHA-256) as part of a [RFC 8152,
1152 COSE] (https://tools.ietf.org/html/rfc8152)
1153 implementation. **WARNING**, this pointer and length should be used
1154 right away before any other calls to @c QCBOREncode_CloseXxx() as
1155 they will move data around and the pointer and length will no longer
1156 be to the correct encoded CBOR.
1157
1158 When an error occurs as a result of this call, the encoder records
1159 the error and enters the error state. The error will be returned when
1160 QCBOREncode_Finish() is called.
1161
1162 If this has been called more times than QCBOREncode_BstrWrap(), then
1163 @ref QCBOR_ERR_TOO_MANY_CLOSES will be returned when
1164 QCBOREncode_Finish() is called.
1165
1166 If this is called and it is not a wrapping bstr that is currently
1167 open, @ref QCBOR_ERR_CLOSE_MISMATCH will be returned when
1168 QCBOREncode_Finish() is called.
1169
1170 QCBOREncode_CloseBstrWrap() is a deprecated version of this function
1171 that is equivalent to the call with @c bIncludeCBORHead @c true.
1172 */
1173void QCBOREncode_CloseBstrWrap2(QCBOREncodeContext *pCtx, bool bIncludeCBORHead, UsefulBufC *pWrappedCBOR);
1174
1175static void QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR);
1176
1177
1178/**
1179 @brief Add some already-encoded CBOR bytes.
1180
1181 @param[in] pCtx The encoding context to add the already-encode CBOR to.
1182 @param[in] Encoded The already-encoded CBOR to add to the context.
1183
1184 The encoded CBOR being added must be fully conforming CBOR. It must
1185 be complete with no arrays or maps that are incomplete. While this
1186 encoder doesn't ever produce indefinite lengths, it is OK for the
1187 raw CBOR added here to have indefinite lengths.
1188
1189 The raw CBOR added here is not checked in anyway. If it is not
1190 conforming or has open arrays or such, the final encoded CBOR
1191 will probably be wrong or not what was intended.
1192
1193 If the encoded CBOR being added here contains multiple items, they
1194 must be enclosed in a map or array. At the top level the raw
1195 CBOR must be a single data item.
1196 */
1197static void QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded);
1198
1199static void QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded);
1200
1201static void QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded);
1202
1203
1204/**
1205 @brief Get the encoded result.
1206
1207 @param[in] pCtx The context to finish encoding with.
1208 @param[out] pEncodedCBOR Pointer and length of encoded CBOR.
1209
1210 @retval QCBOR_ERR_TOO_MANY_CLOSES Nesting error
1211
1212 @retval QCBOR_ERR_CLOSE_MISMATCH Nesting error
1213
1214 @retval QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN Nesting error
1215
1216 @retval QCBOR_ERR_BUFFER_TOO_LARGE Encoded output buffer size
1217
1218 @retval QCBOR_ERR_BUFFER_TOO_SMALL Encoded output buffer size
1219
1220 @retval QCBOR_ERR_ARRAY_NESTING_TOO_DEEP Implementation limit
1221
1222 @retval QCBOR_ERR_ARRAY_TOO_LONG Implementation limit
1223
1224 If this returns success @ref QCBOR_SUCCESS the encoding was a success
1225 and the return length is correct and complete.
1226
1227 If no buffer was passed to QCBOREncode_Init(), then only the length
1228 was computed. If a buffer was passed, then the encoded CBOR is in the
1229 buffer.
1230
1231 Encoding errors primarily manifest here as most other encoding function
1232 do no return an error. They just set the error state in the encode
1233 context after which no encoding function does anything.
1234
1235 Three types of errors manifest here. The first type are nesting
1236 errors where the number of @c QCBOREncode_OpenXxx() calls do not
1237 match the number @c QCBOREncode_CloseXxx() calls. The solution is to
1238 fix the calling code.
1239
1240 The second type of error is because the buffer given is either too
1241 small or too large. The remedy is to give a correctly sized buffer.
1242
1243 The third type are due to limits in this implementation. @ref
1244 QCBOR_ERR_ARRAY_NESTING_TOO_DEEP can be worked around by encoding the
1245 CBOR in two (or more) phases and adding the CBOR from the first phase
1246 to the second with @c QCBOREncode_AddEncoded().
1247
1248 If an error is returned, the buffer may have partially encoded
1249 incorrect CBOR in it and it should not be used. Likewise, the length
1250 may be incorrect and should not be used.
1251
1252 Note that the error could have occurred in one of the many @c
1253 QCBOREncode_AddXxx() calls long before QCBOREncode_Finish() was
1254 called. This error handling reduces the CBOR implementation size but
1255 makes debugging harder.
1256
1257 This may be called multiple times. It will always return the same. It
1258 can also be interleaved with calls to QCBOREncode_FinishGetSize().
1259
1260 QCBOREncode_GetErrorState() can be called to get the current
1261 error state and abort encoding early as an optimization, but is
1262 is never required.
1263 */
1264QCBORError QCBOREncode_Finish(QCBOREncodeContext *pCtx, UsefulBufC *pEncodedCBOR);
1265
1266
1267/**
1268 @brief Get the encoded CBOR and error status.
1269
1270 @param[in] pCtx The context to finish encoding with.
1271 @param[out] uEncodedLen The length of the encoded or potentially
1272 encoded CBOR in bytes.
1273
1274 @return The same errors as QCBOREncode_Finish().
1275
1276 This functions the same as QCBOREncode_Finish(), but only returns the
1277 size of the encoded output.
1278 */
1279QCBORError QCBOREncode_FinishGetSize(QCBOREncodeContext *pCtx, size_t *uEncodedLen);
1280
1281
1282/**
1283 @brief Indicate whether output buffer is NULL or not.
1284
1285 @param[in] pCtx The encoding context.
1286
1287 @return 1 if the output buffer is @c NULL.
1288
1289 Sometimes a @c NULL input buffer is given to QCBOREncode_Init() so
1290 that the size of the generated CBOR can be calculated without
1291 allocating a buffer for it. This returns 1 when the output buffer is
1292 NULL and 0 when it is not.
1293*/
1294static int QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx);
1295
1296 /**
1297 @brief Get the encoding error state.
1298
1299 @param[in] pCtx The encoding context.
1300
1301 @return One of \ref QCBORError. See return values from
1302 QCBOREncode_Finish()
1303
1304 Normally encoding errors need only be handled at the end of encoding
1305 when QCBOREncode_Finish() is called. This can be called to get the
1306 error result before finish should there be a need to halt encoding
1307 before QCBOREncode_Finish() is called.
1308*/
1309static QCBORError QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx);
1310
1311
1312/**
1313 Encode the "head" of a CBOR data item.
1314
1315 @param buffer Buffer to output the encoded head to; must be
1316 @ref QCBOR_HEAD_BUFFER_SIZE bytes in size.
1317 @param uMajorType One of CBOR_MAJOR_TYPE_XX.
1318 @param uMinLen The minimum number of bytes to encode uNumber. Almost always
1319 this is 0 to use preferred minimal encoding. If this is 4,
1320 then even the values 0xffff and smaller will be encoded
1321 as in 4 bytes. This is used primarily when encoding a
1322 float or double put into uNumber as the leading zero bytes
1323 for them must be encoded.
1324 @param uNumber The numeric argument part of the CBOR head.
1325 @return Pointer and length of the encoded head or
1326 @NULLUsefulBufC if the output buffer is too small.
1327
1328 Callers to need to call this for normal CBOR encoding. Note that it doesn't even
1329 take a @ref QCBOREncodeContext argument.
1330
1331 This encodes the major type and argument part of a data item. The
1332 argument is an integer that is usually either the value or the length
1333 of the data item.
1334
1335 This is exposed in the public interface to allow hashing of some CBOR
1336 data types, bstr in particular, a chunk at a time so the full CBOR
1337 doesn't have to be encoded in a contiguous buffer.
1338
1339 For example, if you have a 100,000 byte binary blob in a buffer that
1340 needs to be a bstr encoded and then hashed. You could allocate a
1341 100,010 byte buffer and encode it normally. Alternatively, you can
1342 encode the head in a 10 byte buffer with this function, hash that and
1343 then hash the 100,000 bytes using the same hash context.
1344
1345 See also QCBOREncode_AddBytesLenOnly();
1346 */
1347UsefulBufC QCBOREncode_EncodeHead(UsefulBuf buffer,
1348 uint8_t uMajorType,
1349 uint8_t uMinLen,
1350 uint64_t uNumber);
1351
1352
Michael Eckel5c531332020-03-02 01:35:30 +01001353
1354
1355/* ===========================================================================
1356 BEGINNING OF PRIVATE INLINE IMPLEMENTATION
1357
1358 =========================================================================== */
1359
1360/**
1361 @brief Semi-private method to add a buffer full of bytes to encoded output
1362
1363 @param[in] pCtx The encoding context to add the integer to.
1364 @param[in] uMajorType The CBOR major type of the bytes.
1365 @param[in] Bytes The bytes to add.
1366
1367 Use QCBOREncode_AddText() or QCBOREncode_AddBytes() or
1368 QCBOREncode_AddEncoded() instead. They are inline functions that call
1369 this and supply the correct major type. This function is public to
1370 make the inline functions work to keep the overall code size down and
1371 because the C language has no way to make it private.
1372
1373 If this is called the major type should be @c
1374 CBOR_MAJOR_TYPE_TEXT_STRING, @c CBOR_MAJOR_TYPE_BYTE_STRING or @c
1375 CBOR_MAJOR_NONE_TYPE_RAW. The last one is special for adding
1376 already-encoded CBOR.
1377 */
1378void QCBOREncode_AddBuffer(QCBOREncodeContext *pCtx, uint8_t uMajorType, UsefulBufC Bytes);
1379
1380
1381/**
1382 @brief Semi-private method to open a map, array or bstr-wrapped CBOR
1383
1384 @param[in] pCtx The context to add to.
1385 @param[in] uMajorType The major CBOR type to close
1386
1387 Call QCBOREncode_OpenArray(), QCBOREncode_OpenMap() or
1388 QCBOREncode_BstrWrap() instead of this.
1389 */
1390void QCBOREncode_OpenMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType);
1391
1392
1393/**
1394 @brief Semi-private method to open a map, array with indefinite length
1395
1396 @param[in] pCtx The context to add to.
1397 @param[in] uMajorType The major CBOR type to close
1398
1399 Call QCBOREncode_OpenArrayIndefiniteLength() or
1400 QCBOREncode_OpenMapIndefiniteLength() instead of this.
1401 */
1402void QCBOREncode_OpenMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx, uint8_t uMajorType);
1403
1404
1405/**
1406 @brief Semi-private method to close a map, array or bstr wrapped CBOR
1407
1408 @param[in] pCtx The context to add to.
1409 @param[in] uMajorType The major CBOR type to close.
1410
1411 Call QCBOREncode_CloseArray() or QCBOREncode_CloseMap() instead of this.
1412 */
1413void QCBOREncode_CloseMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType);
1414
1415
1416/**
1417 @brief Semi-private method to close a map, array with indefinite length
1418
1419 @param[in] pCtx The context to add to.
1420 @param[in] uMajorType The major CBOR type to close.
1421
1422 Call QCBOREncode_CloseArrayIndefiniteLength() or
1423 QCBOREncode_CloseMapIndefiniteLength() instead of this.
1424 */
1425void QCBOREncode_CloseMapOrArrayIndefiniteLength(QCBOREncodeContext *pCtx,
1426 uint8_t uMajorType);
1427
1428
1429/**
1430 @brief Semi-private method to add simple types.
1431
1432 @param[in] pCtx The encoding context to add the simple value to.
1433 @param[in] uMinLen Minimum encoding size for uNum. Usually 0.
1434 @param[in] uNum One of CBOR_SIMPLEV_FALSE through _UNDEF or other.
1435
1436 This is used to add simple types like true and false.
1437
1438 Call QCBOREncode_AddBool(), QCBOREncode_AddNULL(),
1439 QCBOREncode_AddUndef() instead of this.
1440
1441 This function can add simple values that are not defined by CBOR
1442 yet. This expansion point in CBOR should not be used unless they are
1443 standardized.
1444
1445 Error handling is the same as QCBOREncode_AddInt64().
1446 */
1447void QCBOREncode_AddType7(QCBOREncodeContext *pCtx, uint8_t uMinLen, uint64_t uNum);
1448
1449
1450/**
1451 @brief Semi-private method to add bigfloats and decimal fractions.
1452
1453 @param[in] pCtx The encoding context to add the value to.
1454 @param[in] uTag The type 6 tag indicating what this is to be
1455 @param[in] BigNumMantissa Is @ref NULLUsefulBufC if mantissa is an
1456 @c int64_t or the actual big number mantissa
1457 if not.
1458 @param[in] nMantissa The @c int64_t mantissa if it is not a big number.
1459 @param[in] nExponent The exponent.
1460
1461 This adds a tagged array with two members, the mantissa and exponent. The
1462 mantissa can be either a big number or an @c int64_t.
1463
1464 Typically, QCBOREncode_AddDecimalFraction(), QCBOREncode_AddBigFloat(),
1465 QCBOREncode_AddDecimalFractionBigNum() or QCBOREncode_AddBigFloatBigNum()
1466 is called instead of this.
1467 */
1468void QCBOREncode_AddExponentAndMantissa(QCBOREncodeContext *pCtx,
1469 uint64_t uTag,
1470 UsefulBufC BigNumMantissa,
1471 bool bBigNumIsNegative,
1472 int64_t nMantissa,
1473 int64_t nExponent);
1474
1475/**
1476 @brief Semi-private method to add only the type and length of a byte string.
1477
1478 @param[in] pCtx The context to initialize.
1479 @param[in] Bytes Pointer and length of the input data.
1480
1481 This is the same as QCBOREncode_AddBytes() except it only adds the
1482 CBOR encoding for the type and the length. It doesn't actually add
1483 the bytes. You can't actually produce correct CBOR with this and the
1484 rest of this API. It is only used for a special case where
1485 the valid CBOR is created manually by putting this type and length in
1486 and then adding the actual bytes. In particular, when only a hash of
1487 the encoded CBOR is needed, where the type and header are hashed
1488 separately and then the bytes is hashed. This makes it possible to
1489 implement COSE Sign1 with only one copy of the payload in the output
1490 buffer, rather than two, roughly cutting memory use in half.
1491
1492 This is only used for this odd case, but this is a supported
1493 tested function.
1494
1495 See also QCBOREncode_EncodeHead().
1496*/
1497static inline void QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
1498
1499static inline void QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
1500
1501static inline void QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
1502
1503
1504
1505
1506
1507static inline void QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum)
1508{
1509 // Use _AddBuffer() because _AddSZString() is defined below, not above
1510 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
1511 QCBOREncode_AddInt64(pCtx, uNum);
1512}
1513
1514static inline void QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum)
1515{
1516 QCBOREncode_AddInt64(pCtx, nLabel);
1517 QCBOREncode_AddInt64(pCtx, uNum);
1518}
1519
1520
1521static inline void QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum)
1522{
1523 // Use _AddBuffer() because _AddSZString() is defined below, not above
1524 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
1525 QCBOREncode_AddUInt64(pCtx, uNum);
1526}
1527
1528static inline void QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum)
1529{
1530 QCBOREncode_AddInt64(pCtx, nLabel);
1531 QCBOREncode_AddUInt64(pCtx, uNum);
1532}
1533
1534
1535static inline void QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text)
1536{
1537 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, Text);
1538}
1539
1540static inline void QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text)
1541{
1542 // Use _AddBuffer() because _AddSZString() is defined below, not above
1543 QCBOREncode_AddText(pCtx, UsefulBuf_FromSZ(szLabel));
1544 QCBOREncode_AddText(pCtx, Text);
1545}
1546
1547static inline void QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text)
1548{
1549 QCBOREncode_AddInt64(pCtx, nLabel);
1550 QCBOREncode_AddText(pCtx, Text);
1551}
1552
1553
1554inline static void QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString)
1555{
1556 QCBOREncode_AddText(pCtx, UsefulBuf_FromSZ(szString));
1557}
1558
1559static inline void QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString)
1560{
1561 QCBOREncode_AddSZString(pCtx, szLabel);
1562 QCBOREncode_AddSZString(pCtx, szString);
1563}
1564
1565static inline void QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString)
1566{
1567 QCBOREncode_AddInt64(pCtx, nLabel);
1568 QCBOREncode_AddSZString(pCtx, szString);
1569}
1570
1571
1572static inline void QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum)
1573{
1574 QCBOREncode_AddSZString(pCtx, szLabel);
1575 QCBOREncode_AddDouble(pCtx, dNum);
1576}
1577
1578static inline void QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum)
1579{
1580 QCBOREncode_AddInt64(pCtx, nLabel);
1581 QCBOREncode_AddDouble(pCtx, dNum);
1582}
1583
1584
1585static inline void QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx, int64_t date)
1586{
1587 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_EPOCH);
1588 QCBOREncode_AddInt64(pCtx, date);
1589}
1590
1591static inline void QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t date)
1592{
1593 QCBOREncode_AddSZString(pCtx, szLabel);
1594 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_EPOCH);
1595 QCBOREncode_AddInt64(pCtx, date);
1596}
1597
1598static inline void QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t date)
1599{
1600 QCBOREncode_AddInt64(pCtx, nLabel);
1601 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_EPOCH);
1602 QCBOREncode_AddInt64(pCtx, date);
1603}
1604
1605
1606static inline void QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
1607{
1608 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes);
1609}
1610
1611static inline void QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
1612{
1613 QCBOREncode_AddSZString(pCtx, szLabel);
1614 QCBOREncode_AddBytes(pCtx, Bytes);
1615}
1616
1617static inline void QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
1618{
1619 QCBOREncode_AddInt64(pCtx, nLabel);
1620 QCBOREncode_AddBytes(pCtx, Bytes);
1621}
1622
1623static inline void QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
1624{
1625 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY, Bytes);
1626}
1627
1628static inline void QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
1629{
1630 QCBOREncode_AddSZString(pCtx, szLabel);
1631 QCBOREncode_AddBytesLenOnly(pCtx, Bytes);
1632}
1633
1634static inline void QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
1635{
1636 QCBOREncode_AddInt64(pCtx, nLabel);
1637 QCBOREncode_AddBytesLenOnly(pCtx, Bytes);
1638}
1639
1640static inline void QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
1641{
1642 QCBOREncode_AddTag(pCtx, CBOR_TAG_BIN_UUID);
1643 QCBOREncode_AddBytes(pCtx, Bytes);
1644}
1645
1646static inline void QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
1647{
1648 QCBOREncode_AddSZString(pCtx, szLabel);
1649 QCBOREncode_AddTag(pCtx, CBOR_TAG_BIN_UUID);
1650 QCBOREncode_AddBytes(pCtx, Bytes);
1651}
1652
1653static inline void QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
1654{
1655 QCBOREncode_AddInt64(pCtx, nLabel);
1656 QCBOREncode_AddTag(pCtx, CBOR_TAG_BIN_UUID);
1657 QCBOREncode_AddBytes(pCtx, Bytes);
1658}
1659
1660
1661static inline void QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
1662{
1663 QCBOREncode_AddTag(pCtx, CBOR_TAG_POS_BIGNUM);
1664 QCBOREncode_AddBytes(pCtx, Bytes);
1665}
1666
1667static inline void QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
1668{
1669 QCBOREncode_AddSZString(pCtx, szLabel);
1670 QCBOREncode_AddTag(pCtx, CBOR_TAG_POS_BIGNUM);
1671 QCBOREncode_AddBytes(pCtx, Bytes);
1672}
1673
1674static inline void QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
1675{
1676 QCBOREncode_AddInt64(pCtx, nLabel);
1677 QCBOREncode_AddTag(pCtx, CBOR_TAG_POS_BIGNUM);
1678 QCBOREncode_AddBytes(pCtx, Bytes);
1679}
1680
1681
1682static inline void QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
1683{
1684 QCBOREncode_AddTag(pCtx, CBOR_TAG_NEG_BIGNUM);
1685 QCBOREncode_AddBytes(pCtx, Bytes);
1686}
1687
1688static inline void QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
1689{
1690 QCBOREncode_AddSZString(pCtx, szLabel);
1691 QCBOREncode_AddTag(pCtx, CBOR_TAG_NEG_BIGNUM);
1692 QCBOREncode_AddBytes(pCtx, Bytes);
1693}
1694
1695static inline void QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
1696{
1697 QCBOREncode_AddInt64(pCtx, nLabel);
1698 QCBOREncode_AddTag(pCtx, CBOR_TAG_NEG_BIGNUM);
1699 QCBOREncode_AddBytes(pCtx, Bytes);
1700}
1701
1702
1703#ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
1704
1705static inline void QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pCtx,
1706 int64_t nMantissa,
1707 int64_t nBase10Exponent)
1708{
1709 QCBOREncode_AddExponentAndMantissa(pCtx,
1710 CBOR_TAG_DECIMAL_FRACTION,
1711 NULLUsefulBufC,
1712 false,
1713 nMantissa,
1714 nBase10Exponent);
1715}
1716
1717static inline void QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pCtx,
1718 const char *szLabel,
1719 int64_t nMantissa,
1720 int64_t nBase10Exponent)
1721{
1722 QCBOREncode_AddSZString(pCtx, szLabel);
1723 QCBOREncode_AddDecimalFraction(pCtx, nMantissa, nBase10Exponent);
1724}
1725
1726static inline void QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pCtx,
1727 int64_t nLabel,
1728 int64_t nMantissa,
1729 int64_t nBase10Exponent)
1730{
1731 QCBOREncode_AddInt64(pCtx, nLabel);
1732 QCBOREncode_AddDecimalFraction(pCtx, nMantissa, nBase10Exponent);
1733}
1734
1735static inline void QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pCtx,
1736 UsefulBufC Mantissa,
1737 bool bIsNegative,
1738 int64_t nBase10Exponent)
1739{
1740 QCBOREncode_AddExponentAndMantissa(pCtx,
1741 CBOR_TAG_DECIMAL_FRACTION,
1742 Mantissa, bIsNegative,
1743 0,
1744 nBase10Exponent);
1745}
1746
1747static inline void QCBOREncode_AddDecimalFractionBigNumToMap(QCBOREncodeContext *pCtx,
1748 const char *szLabel,
1749 UsefulBufC Mantissa,
1750 bool bIsNegative,
1751 int64_t nBase10Exponent)
1752{
1753 QCBOREncode_AddSZString(pCtx, szLabel);
1754 QCBOREncode_AddDecimalFractionBigNum(pCtx, Mantissa, bIsNegative, nBase10Exponent);
1755}
1756
1757static inline void QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
1758 int64_t nLabel,
1759 UsefulBufC Mantissa,
1760 bool bIsNegative,
1761 int64_t nBase2Exponent)
1762{
1763 QCBOREncode_AddInt64(pCtx, nLabel);
1764 QCBOREncode_AddDecimalFractionBigNum(pCtx, Mantissa, bIsNegative, nBase2Exponent);
1765}
1766
1767static inline void QCBOREncode_AddBigFloat(QCBOREncodeContext *pCtx,
1768 int64_t nMantissa,
1769 int64_t nBase2Exponent)
1770{
1771 QCBOREncode_AddExponentAndMantissa(pCtx, CBOR_TAG_BIGFLOAT, NULLUsefulBufC, false, nMantissa, nBase2Exponent);
1772}
1773
1774static inline void QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pCtx,
1775 const char *szLabel,
1776 int64_t nMantissa,
1777 int64_t nBase2Exponent)
1778{
1779 QCBOREncode_AddSZString(pCtx, szLabel);
1780 QCBOREncode_AddBigFloat(pCtx, nMantissa, nBase2Exponent);
1781}
1782
1783static inline void QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pCtx,
1784 int64_t nLabel,
1785 int64_t nMantissa,
1786 int64_t nBase2Exponent)
1787{
1788 QCBOREncode_AddInt64(pCtx, nLabel);
1789 QCBOREncode_AddBigFloat(pCtx, nMantissa, nBase2Exponent);
1790}
1791
1792static inline void QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pCtx,
1793 UsefulBufC Mantissa,
1794 bool bIsNegative,
1795 int64_t nBase2Exponent)
1796{
1797 QCBOREncode_AddExponentAndMantissa(pCtx, CBOR_TAG_BIGFLOAT, Mantissa, bIsNegative, 0, nBase2Exponent);
1798}
1799
1800static inline void QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pCtx,
1801 const char *szLabel,
1802 UsefulBufC Mantissa,
1803 bool bIsNegative,
1804 int64_t nBase2Exponent)
1805{
1806 QCBOREncode_AddSZString(pCtx, szLabel);
1807 QCBOREncode_AddBigFloatBigNum(pCtx, Mantissa, bIsNegative, nBase2Exponent);
1808}
1809
1810static inline void QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
1811 int64_t nLabel,
1812 UsefulBufC Mantissa,
1813 bool bIsNegative,
1814 int64_t nBase2Exponent)
1815{
1816 QCBOREncode_AddInt64(pCtx, nLabel);
1817 QCBOREncode_AddBigFloatBigNum(pCtx, Mantissa, bIsNegative, nBase2Exponent);
1818}
1819#endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
1820
1821
1822static inline void QCBOREncode_AddURI(QCBOREncodeContext *pCtx, UsefulBufC URI)
1823{
1824 QCBOREncode_AddTag(pCtx, CBOR_TAG_URI);
1825 QCBOREncode_AddText(pCtx, URI);
1826}
1827
1828static inline void QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC URI)
1829{
1830 QCBOREncode_AddSZString(pCtx, szLabel);
1831 QCBOREncode_AddTag(pCtx, CBOR_TAG_URI);
1832 QCBOREncode_AddText(pCtx, URI);
1833}
1834
1835static inline void QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC URI)
1836{
1837 QCBOREncode_AddInt64(pCtx, nLabel);
1838 QCBOREncode_AddTag(pCtx, CBOR_TAG_URI);
1839 QCBOREncode_AddText(pCtx, URI);
1840}
1841
1842
1843
1844static inline void QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx, UsefulBufC B64Text)
1845{
1846 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64);
1847 QCBOREncode_AddText(pCtx, B64Text);
1848}
1849
1850static inline void QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text)
1851{
1852 QCBOREncode_AddSZString(pCtx, szLabel);
1853 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64);
1854 QCBOREncode_AddText(pCtx, B64Text);
1855}
1856
1857static inline void QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text)
1858{
1859 QCBOREncode_AddInt64(pCtx, nLabel);
1860 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64);
1861 QCBOREncode_AddText(pCtx, B64Text);
1862}
1863
1864
1865static inline void QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx, UsefulBufC B64Text)
1866{
1867 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64URL);
1868 QCBOREncode_AddText(pCtx, B64Text);
1869}
1870
1871static inline void QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text)
1872{
1873 QCBOREncode_AddSZString(pCtx, szLabel);
1874 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64URL);
1875 QCBOREncode_AddText(pCtx, B64Text);
1876}
1877
1878static inline void QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text)
1879{
1880 QCBOREncode_AddInt64(pCtx, nLabel);
1881 QCBOREncode_AddTag(pCtx, CBOR_TAG_B64URL);
1882 QCBOREncode_AddText(pCtx, B64Text);
1883}
1884
1885
1886static inline void QCBOREncode_AddRegex(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
1887{
1888 QCBOREncode_AddTag(pCtx, CBOR_TAG_REGEX);
1889 QCBOREncode_AddText(pCtx, Bytes);
1890}
1891
1892static inline void QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
1893{
1894 QCBOREncode_AddSZString(pCtx, szLabel);
1895 QCBOREncode_AddTag(pCtx, CBOR_TAG_REGEX);
1896 QCBOREncode_AddText(pCtx, Bytes);
1897}
1898
1899static inline void QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
1900{
1901 QCBOREncode_AddInt64(pCtx, nLabel);
1902 QCBOREncode_AddTag(pCtx, CBOR_TAG_REGEX);
1903 QCBOREncode_AddText(pCtx, Bytes);
1904}
1905
1906
1907static inline void QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx, UsefulBufC MIMEData)
1908{
1909 QCBOREncode_AddTag(pCtx, CBOR_TAG_MIME);
1910 QCBOREncode_AddText(pCtx, MIMEData);
1911}
1912
1913static inline void QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC MIMEData)
1914{
1915 QCBOREncode_AddSZString(pCtx, szLabel);
1916 QCBOREncode_AddTag(pCtx, CBOR_TAG_MIME);
1917 QCBOREncode_AddText(pCtx, MIMEData);
1918}
1919
1920static inline void QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC MIMEData)
1921{
1922 QCBOREncode_AddInt64(pCtx, nLabel);
1923 QCBOREncode_AddTag(pCtx, CBOR_TAG_MIME);
1924 QCBOREncode_AddText(pCtx, MIMEData);
1925}
1926
1927
1928static inline void QCBOREncode_AddDateString(QCBOREncodeContext *pCtx, const char *szDate)
1929{
1930 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_STRING);
1931 QCBOREncode_AddSZString(pCtx, szDate);
1932}
1933
1934static inline void QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szDate)
1935{
1936 QCBOREncode_AddSZString(pCtx, szLabel);
1937 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_STRING);
1938 QCBOREncode_AddSZString(pCtx, szDate);
1939}
1940
1941static inline void QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szDate)
1942{
1943 QCBOREncode_AddInt64(pCtx, nLabel);
1944 QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_STRING);
1945 QCBOREncode_AddSZString(pCtx, szDate);
1946}
1947
1948
1949static inline void QCBOREncode_AddSimple(QCBOREncodeContext *pCtx, uint64_t uNum)
1950{
1951 QCBOREncode_AddType7(pCtx, 0, uNum);
1952}
1953
1954static inline void QCBOREncode_AddSimpleToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint8_t uSimple)
1955{
1956 QCBOREncode_AddSZString(pCtx, szLabel);
1957 QCBOREncode_AddSimple(pCtx, uSimple);
1958}
1959
1960static inline void QCBOREncode_AddSimpleToMapN(QCBOREncodeContext *pCtx, int nLabel, uint8_t uSimple)
1961{
1962 QCBOREncode_AddInt64(pCtx, nLabel);
1963 QCBOREncode_AddSimple(pCtx, uSimple);
1964}
1965
1966
1967static inline void QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b)
1968{
1969 uint8_t uSimple = CBOR_SIMPLEV_FALSE;
1970 if(b) {
1971 uSimple = CBOR_SIMPLEV_TRUE;
1972 }
1973 QCBOREncode_AddSimple(pCtx, uSimple);
1974}
1975
1976static inline void QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b)
1977{
1978 QCBOREncode_AddSZString(pCtx, szLabel);
1979 QCBOREncode_AddBool(pCtx, b);
1980}
1981
1982static inline void QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b)
1983{
1984 QCBOREncode_AddInt64(pCtx, nLabel);
1985 QCBOREncode_AddBool(pCtx, b);
1986}
1987
1988
1989static inline void QCBOREncode_AddNULL(QCBOREncodeContext *pCtx)
1990{
1991 QCBOREncode_AddSimple(pCtx, CBOR_SIMPLEV_NULL);
1992}
1993
1994static inline void QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel)
1995{
1996 QCBOREncode_AddSZString(pCtx, szLabel);
1997 QCBOREncode_AddNULL(pCtx);
1998}
1999
2000static inline void QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
2001{
2002 QCBOREncode_AddInt64(pCtx, nLabel);
2003 QCBOREncode_AddNULL(pCtx);
2004}
2005
2006
2007static inline void QCBOREncode_AddUndef(QCBOREncodeContext *pCtx)
2008{
2009 QCBOREncode_AddSimple(pCtx, CBOR_SIMPLEV_UNDEF);
2010}
2011
2012static inline void QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel)
2013{
2014 QCBOREncode_AddSZString(pCtx, szLabel);
2015 QCBOREncode_AddUndef(pCtx);
2016}
2017
2018static inline void QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
2019{
2020 QCBOREncode_AddInt64(pCtx, nLabel);
2021 QCBOREncode_AddUndef(pCtx);
2022}
2023
2024
2025static inline void QCBOREncode_OpenArray(QCBOREncodeContext *pCtx)
2026{
2027 QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_ARRAY);
2028}
2029
2030static inline void QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel)
2031{
2032 QCBOREncode_AddSZString(pCtx, szLabel);
2033 QCBOREncode_OpenArray(pCtx);
2034}
2035
2036static inline void QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
2037{
2038 QCBOREncode_AddInt64(pCtx, nLabel);
2039 QCBOREncode_OpenArray(pCtx);
2040}
2041
2042static inline void QCBOREncode_CloseArray(QCBOREncodeContext *pCtx)
2043{
2044 QCBOREncode_CloseMapOrArray(pCtx, CBOR_MAJOR_TYPE_ARRAY);
2045}
2046
2047
2048static inline void QCBOREncode_OpenMap(QCBOREncodeContext *pCtx)
2049{
2050 QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_MAP);
2051}
2052
2053static inline void QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel)
2054{
2055 QCBOREncode_AddSZString(pCtx, szLabel);
2056 QCBOREncode_OpenMap(pCtx);
2057}
2058
2059static inline void QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
2060{
2061 QCBOREncode_AddInt64(pCtx, nLabel);
2062 QCBOREncode_OpenMap(pCtx);
2063}
2064
2065static inline void QCBOREncode_CloseMap(QCBOREncodeContext *pCtx)
2066{
2067 QCBOREncode_CloseMapOrArray(pCtx, CBOR_MAJOR_TYPE_MAP);
2068}
2069
2070static inline void QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pCtx)
2071{
2072 QCBOREncode_OpenMapOrArrayIndefiniteLength(pCtx, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
2073}
2074
2075static inline void QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pCtx, const char *szLabel)
2076{
2077 QCBOREncode_AddSZString(pCtx, szLabel);
2078 QCBOREncode_OpenArrayIndefiniteLength(pCtx);
2079}
2080
2081static inline void QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
2082{
2083 QCBOREncode_AddInt64(pCtx, nLabel);
2084 QCBOREncode_OpenArrayIndefiniteLength(pCtx);
2085}
2086
2087static inline void QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pCtx)
2088{
2089 QCBOREncode_CloseMapOrArrayIndefiniteLength(pCtx, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
2090}
2091
2092
2093static inline void QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pCtx)
2094{
2095 QCBOREncode_OpenMapOrArrayIndefiniteLength(pCtx, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
2096}
2097
2098static inline void QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pCtx, const char *szLabel)
2099{
2100 QCBOREncode_AddSZString(pCtx, szLabel);
2101 QCBOREncode_OpenMapIndefiniteLength(pCtx);
2102}
2103
2104static inline void QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
2105{
2106 QCBOREncode_AddInt64(pCtx, nLabel);
2107 QCBOREncode_OpenMapIndefiniteLength(pCtx);
2108}
2109
2110static inline void QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pCtx)
2111{
2112 QCBOREncode_CloseMapOrArrayIndefiniteLength(pCtx, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
2113}
2114
2115
2116static inline void QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx)
2117{
2118 QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_BYTE_STRING);
2119}
2120
2121static inline void QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel)
2122{
2123 QCBOREncode_AddSZString(pCtx, szLabel);
2124 QCBOREncode_BstrWrap(pCtx);
2125}
2126
2127static inline void QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
2128{
2129 QCBOREncode_AddInt64(pCtx, nLabel);
2130 QCBOREncode_BstrWrap(pCtx);
2131}
2132
2133static inline void QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR)
2134{
2135 QCBOREncode_CloseBstrWrap2(pCtx, true, pWrappedCBOR);
2136}
2137
2138
2139static inline void QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded)
2140{
2141 QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_NONE_TYPE_RAW, Encoded);
2142}
2143
2144static inline void QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded)
2145{
2146 QCBOREncode_AddSZString(pCtx, szLabel);
2147 QCBOREncode_AddEncoded(pCtx, Encoded);
2148}
2149
2150static inline void QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded)
2151{
2152 QCBOREncode_AddInt64(pCtx, nLabel);
2153 QCBOREncode_AddEncoded(pCtx, Encoded);
2154}
2155
2156
2157static inline int QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx)
2158{
2159 return UsefulOutBuf_IsBufferNULL(&(pCtx->OutBuf));
2160}
2161
2162static inline QCBORError QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx)
2163{
2164 if(UsefulOutBuf_GetError(&(pCtx->OutBuf))) {
2165 // Items didn't fit in the buffer.
2166 // This check catches this condition for all the appends and inserts
2167 // so checks aren't needed when the appends and inserts are performed.
2168 // And of course UsefulBuf will never overrun the input buffer given
2169 // to it. No complex analysis of the error handling in this file is
2170 // needed to know that is true. Just read the UsefulBuf code.
2171 pCtx->uError = QCBOR_ERR_BUFFER_TOO_SMALL;
2172 // QCBOR_ERR_BUFFER_TOO_SMALL masks other errors, but that is
2173 // OK. Once the caller fixes this, they'll be unmasked.
2174 }
2175
2176 return (QCBORError)pCtx->uError;
2177}
2178
2179
2180/* ===========================================================================
2181 END OF PRIVATE INLINE IMPLEMENTATION
2182
2183 =========================================================================== */
2184
2185#ifdef __cplusplus
2186}
2187#endif
2188
Laurence Lundblade844bb5c2020-03-01 17:27:25 -08002189#endif /* qcbor_encode_h */