1 // SPDX-License-Identifier: BSD-3-Clause
2 /* ==========================================================================
3 * qcbor_spiffy_decode.h -- higher-level easier-to-use CBOR decoding.
4 *
5 * Copyright (c) 2020-2024, Laurence Lundblade. All rights reserved.
6 * Copyright (c) 2021, Arm Limited. All rights reserved.
7 *
8 * SPDX-License-Identifier: BSD-3-Clause
9 *
10 * See BSD-3-Clause license in README.md
11 *
12 * Forked from qcbor_decode.h on 7/23/2020
13 * ========================================================================== */
14 #ifndef qcbor_spiffy_decode_h
15 #define qcbor_spiffy_decode_h
16
17
18 #include "qcbor/qcbor_decode.h"
19
20
21 #ifdef __cplusplus
22 extern "C" {
23 #if 0
24 } // Keep editor indention formatting happy
25 #endif
26 #endif
27
28
29 /**
30 * @file qcbor_spiffy_decode.h
31 *
32 * @anchor SpiffyDecode
33 * # Spiffy Decode
34 *
35 * This section discusses spiffy decoding assuming familiarity with
36 * the general description of decoding in the
37 * @ref BasicDecode section.
38 *
39 * Spiffy decode is extra decode features over and above the @ref
40 * BasicDecode features that generally are easier to use, mirror the
41 * encoding functions better and can result in smaller code size for
42 * larger and more complex CBOR protocols. In particular, spiffy
43 * decode facilitates getting the next data item of a specific type,
44 * setting an error if it is not of that type. It facilitates
45 * explicitly entering and exiting arrays and maps. It facilates
46 * fetching items by label from a map including duplicate label
47 * detection.
48 *
49 * Encoded CBOR can be viewed to have a tree structure where the leaf
50 * nodes are non-aggregate types like integers and strings and the
51 * intermediate nodes are either arrays or maps. Fundamentally, all
52 * decoding is a pre-order traversal of the tree. Calling
53 * QCBORDecode_GetNext() repeatedly will perform this.
54 *
55 * This pre-order traversal gives natural decoding of arrays where the
56 * array members are taken in order, but does not give natural decoding
57 * of maps where access by label is usually preferred. Using the
58 * QCBORDecode_EnterMap() and QCBORDecode_GetXxxxInMapX() methods like
59 * QCBORDecode_GetInt64InMapN(), map items can be accessed by
60 * label. QCBORDecode_EnterMap() bounds decoding to a particular
61 * map. QCBORDecode_GetXxxxInMapX() methods allows decoding the item of
62 * a particular label in the particular map. This can be used with
63 * nested maps by using QCBORDecode_EnterMapFromMapX().
64 *
65 * When QCBORDecode_EnterMap() is called, pre-order traversal
66 * continues to work. There is a cursor that is run over the tree with
67 * calls to QCBORDecode_GetNext(). Attempts to use
68 * QCBORDecode_GetNext() beyond the end of the map will give the
69 * @ref QCBOR_ERR_NO_MORE_ITEMS error.
70 *
71 * Use of the traversal cursor can be mixed with the fetching of items
72 * by label with some caveats. When a non-aggregate item like an
73 * integer or string is fetched by label, the traversal cursor is
74 * unaffected so the mixing can be done freely. When an aggregate
75 * item is entered by label (by QCBORDecode_EnterMapFromMapN() and
76 * similar), the traversal cursor is set to the item after the
77 * subordinate aggregate item when it is exited. This will not matter
78 * to many use cases. Use cases that mix can be sure to separate
79 * traversal by the cursor from fetching by label.
80 * QCBORDecode_Rewind() may be useful to reset the traversal cursor
81 * after fetching aggregate items by label.
82 *
83 * (This behavior was incorrectly documented in QCBOR 1.2 and prior
84 * which described aggregate and non-aggregate as behaving the same.
85 * Rather than changing to make aggregate and non-aggregate
86 * consistent, the behavior is retained and documented because 1) it
87 * is usable as is, 2) a change would bring backward compatibility
88 * issues, 3) the change would increase the decode context size and
89 * code size. In QCBOR 1.3 test cases were added to validate the
90 * behavior. No problems were uncovered.)
91 *
92 * QCBORDecode_EnterArray() can be used to narrow the traversal to the
93 * extent of the array.
94 *
95 * All the QCBORDecode_GetXxxxInMapX() methods support duplicate label
96 * detection and will result in an error if the map has duplicate
97 * labels.
98 *
99 * All the QCBORDecode_GetXxxxInMapX() methods are implemented by
100 * performing the pre-order traversal of the map to find the labeled
101 * item everytime it is called. It doesn't build up a hash table, a
102 * binary search tree or some other efficiently searchable structure
103 * internally. For small maps this is fine and for high-speed CPUs
104 * this is fine, but for large, perhaps deeply nested, maps on slow
105 * CPUs, it may have performance issues (these have not be
106 * quantified). One way ease this is to use
107 * QCBORDecode_GetItemsInMap() which allows decoding of a list of
108 * items expected in an map in one traveral.
109 *
110 * @anchor Tag-Usage
111 * ## Tag Usage
112 *
113 * Data types beyond the basic CBOR types of numbers, strings, maps and
114 * arrays are called tags. The main registry of these new types is in
115 * the IANA CBOR tags registry. These new types may be simple such a
116 * number that is to be interpreted as a date, or of moderate complexity
117 * such as defining a decimal fraction that is an array containing a
118 * mantissa and exponent, or complex such as format for signing and
119 * encryption.
120 *
121 * When a tag occurs in a protocol it is encoded as an integer tag
122 * number plus the content of the tag.
123 *
124 * The content format of a tag may also be "borrowed". For example, a
125 * protocol definition may say that a particular data item is an epoch
126 * date just like tag 1, but not actually tag 1. In practice the
127 * difference is the presence or absence of the integer tag number in
128 * the encoded CBOR.
129 *
130 * The decoding functions for these new types takes a tag requirement
131 * parameter to say whether the item is a tag, is just borrowing the
132 * content format and is not a tag, or whether either is OK.
133 *
134 * If the parameter indicates the item must be a tag (@ref
135 * QCBOR_TAG_REQUIREMENT_TAG), then @ref QCBOR_ERR_UNEXPECTED_TYPE is
136 * set if it is not one of the expected tag types. To decode correctly
137 * the contents of the tag must also be of the correct type. For
138 * example, to decode an epoch date tag the content must be an integer
139 * or floating-point value.
140 *
141 * If the parameter indicates it should not be a tag
142 * (@ref QCBOR_TAG_REQUIREMENT_NOT_A_TAG), then
143 * @ref QCBOR_ERR_UNEXPECTED_TYPE set if it is a tag or the type of the
144 * encoded CBOR is not what is expected. In the example of an epoch
145 * date, the data type must be an integer or floating-point value. This
146 * is the case where the content format of a tag is borrowed.
147 *
148 * The parameter can also indicate that either a tag or no tag is
149 * allowed ( @ref QCBOR_TAG_REQUIREMENT_OPTIONAL_TAG ). A good protocol
150 * design should however be clear and choose one or the other and not
151 * need this option. This is a way to implement "be liberal in what you
152 * accept", however these days that is less in favor. See
153 * https://tools.ietf.org/id/draft-thomson-postel-was-wrong-03.html.
154 *
155 * Map searching works with indefinite length strings. A string
156 * allocator must be set up the same as for any handling of indefinite
157 * length strings. However, It currently over-allocates memory from the
158 * string pool and thus requires a much larger string pool than it
159 * should. The over-allocation happens every time a map is searched by
160 * label. (This may be corrected in the future).
161 */
162
163
164
165
166 /** The data item must be a tag of the expected type. It is an error
167 * if it is not. For example when calling QCBORDecode_GetEpochDate(),
168 * the data item must be an @ref CBOR_TAG_DATE_EPOCH tag. See
169 * @ref Tag-Usage. */
170 #define QCBOR_TAG_REQUIREMENT_TAG 0
171
172 /** The data item must be of the type expected for content data type
173 * being fetched. It is an error if it is not. For example, when
174 * calling QCBORDecode_GetEpochDate() and it must not be an @ref
175 * CBOR_TAG_DATE_EPOCH tag. See @ref Tag-Usage. */
176 #define QCBOR_TAG_REQUIREMENT_NOT_A_TAG 1
177
178 /** Either of the above two are allowed. This allows implementation of
179 * being liberal in what you receive, but it is better if CBOR-based
180 * protocols pick one and stick to and not required the reciever to
181 * take either. See @ref Tag-Usage. */
182 #define QCBOR_TAG_REQUIREMENT_OPTIONAL_TAG 2
183
184 /** Add this into the above value if other tags not processed by QCBOR
185 * are to be allowed to surround the data item. See @ref Tag-Usage. */
186 #define QCBOR_TAG_REQUIREMENT_ALLOW_ADDITIONAL_TAGS 0x80
187
188
189
190
191 /** Conversion will proceed if the CBOR item to be decoded is an
192 * integer or either type 0 (unsigned) or type 1 (negative). */
193 #define QCBOR_CONVERT_TYPE_XINT64 0x01
194 /** Conversion will proceed if the CBOR item to be decoded is either
195 * double, single or half-precision floating-point (major type 7). */
196 #define QCBOR_CONVERT_TYPE_FLOAT 0x02
197 /** Conversion will proceed if the CBOR item to be decoded is a big
198 * number, positive or negative (tag 2 or tag 3). */
199 #define QCBOR_CONVERT_TYPE_BIG_NUM 0x04
200 /** Conversion will proceed if the CBOR item to be decoded is a
201 * decimal fraction (tag 4). */
202 #define QCBOR_CONVERT_TYPE_DECIMAL_FRACTION 0x08
203 /** Conversion will proceed if the CBOR item to be decoded is a big
204 * float (tag 5). */
205 #define QCBOR_CONVERT_TYPE_BIGFLOAT 0x10
206
207
208
209
210 /**
211 * @brief Decode next item into a signed 64-bit integer.
212 *
213 * @param[in] pCtx The decode context.
214 * @param[out] pnValue The returned 64-bit signed integer.
215 *
216 * The CBOR data item to decode must be a positive or negative integer
217 * (CBOR major type 0 or 1). If not @ref QCBOR_ERR_UNEXPECTED_TYPE is set.
218 *
219 * If the CBOR integer is either too large or too small to fit in an
220 * int64_t, the error @ref QCBOR_ERR_INT_OVERFLOW or
221 * @ref QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW is set. Note that type 0
222 * unsigned integers can be larger than will fit in an int64_t and
223 * type 1 negative integers can be smaller than will fit in an
224 * int64_t.
225 *
226 * Please see @ref Decode-Errors-Overview "Decode Errors Overview".
227 *
228 * See also QCBORDecode_GetUInt64(), QCBORDecode_GetInt64Convert(),
229 * QCBORDecode_GetInt64ConvertAll() and QCBORDecode_GetDoubleConvert()
230 */
231 static void
232 QCBORDecode_GetInt64(QCBORDecodeContext *pCtx,
233 int64_t *pnValue);
234
235 static void
236 QCBORDecode_GetInt64InMapN(QCBORDecodeContext *pCtx,
237 int64_t nLabel,
238 int64_t *pnValue);
239
240 static void
241 QCBORDecode_GetInt64InMapSZ(QCBORDecodeContext *pCtx,
242 const char *szLabel,
243 int64_t *pnValue);
244
245
246 /**
247 * @brief Decode next item into a signed 64-bit integer with basic conversions.
248 *
249 * @param[in] pCtx The decode context.
250 * @param[in] uConvertTypes The integer conversion options.
251 * @param[out] pnValue The returned 64-bit signed integer.
252 *
253 * @c uConvertTypes controls what conversions this will perform and
254 * thus what CBOR types will be decoded. @c uConvertType is a bit map
255 * listing the conversions to be allowed. This function supports
256 * @ref QCBOR_CONVERT_TYPE_XINT64 and @ref QCBOR_CONVERT_TYPE_FLOAT
257 * conversions.
258 *
259 * Please see @ref Decode-Errors-Overview "Decode Errors Overview".
260 *
261 * If the CBOR data type can never be convered by this function or the
262 * conversion was not selected in @c uConversionTypes
263 * @ref QCBOR_ERR_UNEXPECTED_TYPE is set.
264 *
265 * When converting floating-point values, the integer is rounded to
266 * the nearest integer using llround(). By default, floating-point
267 * suport is enabled for QCBOR.
268 *
269 * If floating-point HW use is disabled this will set
270 * @ref QCBOR_ERR_HW_FLOAT_DISABLED if a single-precision number is
271 * encountered. If half-precision support is disabled, this will set
272 * @ref QCBOR_ERR_HALF_PRECISION_DISABLED if a half-precision number
273 * is encountered.
274 *
275 * If floating-point usage is disabled this will set
276 * @ref QCBOR_ERR_ALL_FLOAT_DISABLED if a floating point value is
277 * encountered.
278 *
279 * See also QCBORDecode_GetInt64ConvertAll() which will perform the
280 * same conversions as this and a lot more at the cost of adding more
281 * object code to your executable.
282 */
283 static void
284 QCBORDecode_GetInt64Convert(QCBORDecodeContext *pCtx,
285 uint32_t uConvertTypes,
286 int64_t *pnValue);
287
288 static void
289 QCBORDecode_GetInt64ConvertInMapN(QCBORDecodeContext *pCtx,
290 int64_t nLabel,
291 uint32_t uConvertTypes,
292 int64_t *pnValue);
293
294 static void
295 QCBORDecode_GetInt64ConvertInMapSZ(QCBORDecodeContext *pCtx,
296 const char *szLabel,
297 uint32_t uConvertTypes,
298 int64_t *pnValue);
299
300
301 /**
302 * @brief Decode next item into a signed 64-bit integer with conversions.
303 *
304 * @param[in] pCtx The decode context.
305 * @param[in] uConvertTypes The integer conversion options.
306 * @param[out] pnValue The returned 64-bit signed integer.
307 *
308 * This is the same as QCBORDecode_GetInt64Convert() but additionally
309 * supports conversion from positive and negative bignums, decimal
310 * fractions and big floats, including decimal fractions and big floats
311 * that use bignums. The conversion types supported are
312 * @ref QCBOR_CONVERT_TYPE_XINT64, @ref QCBOR_CONVERT_TYPE_FLOAT,
313 * @ref QCBOR_CONVERT_TYPE_BIG_NUM,
314 * @ref QCBOR_CONVERT_TYPE_DECIMAL_FRACTION and
315 * @ref QCBOR_CONVERT_TYPE_BIGFLOAT.
316 *
317 * Please see @ref Decode-Errors-Overview "Decode Errors Overview".
318 *
319 * Note that most these types can support numbers much larger that can
320 * be represented by in a 64-bit integer, so
321 * @ref QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW may often be encountered.
322 *
323 * When converting bignums and decimal fractions,
324 * @ref QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW will be set if the result
325 * is below 1, unless the mantissa is zero, in which case the
326 * coversion is successful and the value of 0 is returned.
327 *
328 * See also QCBORDecode_GetInt64ConvertAll() which does some of these
329 * conversions, but links in much less object code. See also
330 * QCBORDecode_GetUInt64ConvertAll().
331 *
332 * This relies on CBOR tags to identify big numbers, decimal fractions
333 * and big floats. It will not attempt to decode non-tag CBOR that might
334 * be one of these. (If QCBOR_DISABLE_TAGS is set, this is effectively
335 * the same as QCBORDecode_GetInt64Convert() because all the additional
336 * number types this decodes are tags).
337 */
338 void
339 QCBORDecode_GetInt64ConvertAll(QCBORDecodeContext *pCtx,
340 uint32_t uConvertTypes,
341 int64_t *pnValue);
342
343 void
344 QCBORDecode_GetInt64ConvertAllInMapN(QCBORDecodeContext *pCtx,
345 int64_t nLabel,
346 uint32_t uConvertTypes,
347 int64_t *pnValue);
348
349 void
350 QCBORDecode_GetInt64ConvertAllInMapSZ(QCBORDecodeContext *pCtx,
351 const char *szLabel,
352 uint32_t uConvertTypes,
353 int64_t *pnValue);
354
355
356 /**
357 * @brief Decode next item into an unsigned 64-bit integer.
358 *
359 * @param[in] pCtx The decode context.
360 * @param[out] puValue The returned 64-bit unsigned integer.
361 *
362 * This is the same as QCBORDecode_GetInt64(), but returns an unsigned integer
363 * and thus can only decode CBOR positive integers.
364 * @ref QCBOR_ERR_NUMBER_SIGN_CONVERSION is set if the input is a negative
365 * integer.
366 *
367 * Please see @ref Decode-Errors-Overview "Decode Errors Overview".
368 *
369 * See also QCBORDecode_GetUInt64Convert() and QCBORDecode_GetUInt64ConvertAll().
370 */
371 static void
372 QCBORDecode_GetUInt64(QCBORDecodeContext *pCtx,
373 uint64_t *puValue);
374
375 static void
376 QCBORDecode_GetUInt64InMapN(QCBORDecodeContext *pCtx,
377 int64_t nLabel,
378 uint64_t *puValue);
379
380 static void
381 QCBORDecode_GetUInt64InMapSZ(QCBORDecodeContext *pCtx,
382 const char *szLabel,
383 uint64_t *puValue);
384
385
386 /**
387 * @brief Decode next item as an unsigned 64-bit integer with basic conversions.
388 *
389 * @param[in] pCtx The decode context.
390 * @param[in] uConvertTypes The integer conversion options.
391 * @param[out] puValue The returned 64-bit unsigned integer.
392 *
393 * This is the same as QCBORDecode_GetInt64Convert(), but returns an
394 * unsigned integer and thus sets @ref QCBOR_ERR_NUMBER_SIGN_CONVERSION
395 * if the value to be decoded is negatve.
396 *
397 * If floating-point HW use is disabled this will set
398 * @ref QCBOR_ERR_HW_FLOAT_DISABLED if a single-precision number is
399 * encountered. If half-precision support is disabled, this will set
400 * @ref QCBOR_ERR_HALF_PRECISION_DISABLED if a half-precision number
401 * is encountered.
402 *
403 * If floating-point usage is disabled this will set
404 * @ref QCBOR_ERR_ALL_FLOAT_DISABLED if a floating point value is
405 * encountered.
406 *
407 * See also QCBORDecode_GetUInt64Convert() and
408 * QCBORDecode_GetUInt64ConvertAll().
409 */
410 static void
411 QCBORDecode_GetUInt64Convert(QCBORDecodeContext *pCtx,
412 uint32_t uConvertTypes,
413 uint64_t *puValue);
414
415 static void
416 QCBORDecode_GetUInt64ConvertInMapN(QCBORDecodeContext *pCtx,
417 int64_t nLabel,
418 uint32_t uConvertTypes,
419 uint64_t *puValue);
420
421 static void
422 QCBORDecode_GetUInt64ConvertInMapSZ(QCBORDecodeContext *pCtx,
423 const char *szLabel,
424 uint32_t uConvertTypes,
425 uint64_t *puValue);
426
427
428 /**
429 * @brief Decode next item into an unsigned 64-bit integer with conversions
430 *
431 * @param[in] pCtx The decode context.
432 * @param[in] uConvertTypes The integer conversion options.
433 * @param[out] puValue The returned 64-bit unsigned integer.
434 *
435 * This is the same as QCBORDecode_GetInt64ConvertAll(), but returns
436 * an unsigned integer and thus sets @ref QCBOR_ERR_NUMBER_SIGN_CONVERSION
437 * if the value to be decoded is negatve.
438 *
439 * See also QCBORDecode_GetUInt64() and QCBORDecode_GetUInt64Convert().
440 */
441 void
442 QCBORDecode_GetUInt64ConvertAll(QCBORDecodeContext *pCtx,
443 uint32_t uConvertTypes,
444 uint64_t *puValue);
445
446 void
447 QCBORDecode_GetUInt64ConvertAllInMapN(QCBORDecodeContext *pCtx,
448 int64_t nLabel,
449 uint32_t uConvertTypes,
450 uint64_t *puValue);
451
452 void
453 QCBORDecode_GetUInt64ConvertAllInMapSZ(QCBORDecodeContext *pCtx,
454 const char *szLabel,
455 uint32_t uConvertTypes,
456 uint64_t *puValue);
457
458
459
460
461 /**
462 * @brief Decode the next item as a byte string
463 *
464 * @param[in] pCtx The decode context.
465 * @param[out] pBytes The decoded byte string.
466 *
467 * The CBOR item to decode must be a byte string, CBOR type 2.
468 *
469 * Please see @ref Decode-Errors-Overview "Decode Errors Overview".
470 *
471 * If the CBOR item to decode is not a byte string, the
472 * @ref QCBOR_ERR_UNEXPECTED_TYPE error is set.
473 */
474 static void
475 QCBORDecode_GetByteString(QCBORDecodeContext *pCtx,
476 UsefulBufC *pBytes);
477
478 static void
479 QCBORDecode_GetByteStringInMapN(QCBORDecodeContext *pCtx,
480 int64_t nLabel,
481 UsefulBufC *pBytes);
482
483 static void
484 QCBORDecode_GetByteStringInMapSZ(QCBORDecodeContext *pCtx,
485 const char *szLabel,
486 UsefulBufC *pBytes);
487
488
489 /**
490 * @brief Decode the next item as a text string.
491 *
492 * @param[in] pCtx The decode context.
493 * @param[out] pText The decoded byte string.
494 *
495 * The CBOR item to decode must be a text string, CBOR type 3.
496 *
497 * Please see @ref Decode-Errors-Overview "Decode Errors Overview".
498 * It the CBOR item to decode is not a text string, the
499 * @ref QCBOR_ERR_UNEXPECTED_TYPE error is set.
500 *
501 * This does no translation of line endings. See QCBOREncode_AddText()
502 * for a discussion of line endings in CBOR.
503 */
504 static void
505 QCBORDecode_GetTextString(QCBORDecodeContext *pCtx,
506 UsefulBufC *pText);
507
508 static void
509 QCBORDecode_GetTextStringInMapN(QCBORDecodeContext *pCtx,
510 int64_t nLabel,
511 UsefulBufC *pText);
512
513 static void
514 QCBORDecode_GetTextStringInMapSZ(QCBORDecodeContext *pCtx,
515 const char *szLabel,
516 UsefulBufC *pText);
517
518
519
520
521 #ifndef USEFULBUF_DISABLE_ALL_FLOAT
522 /**
523 * @brief Decode next item into a double floating-point value.
524 *
525 * @param[in] pCtx The decode context.
526 * @param[out] pValue The returned floating-point value.
527 *
528 * The CBOR data item to decode must be a half-precision,
529 * single-precision or double-precision floating-point value. If not
530 * @ref QCBOR_ERR_UNEXPECTED_TYPE is set.
531 *
532 * If floating-point HW use is disabled this will set
533 * @ref QCBOR_ERR_HW_FLOAT_DISABLED if a single-precision number is
534 * encountered. If half-precision support is disabled, this will set
535 * @ref QCBOR_ERR_HALF_PRECISION_DISABLED if a half-precision number
536 * is encountered.
537 *
538 * Please see @ref Decode-Errors-Overview "Decode Errors Overview".
539 *
540 * See also QCBORDecode_GetDoubleConvert() and
541 * QCBORDecode_GetDoubleConvertAll().
542 */
543 static void
544 QCBORDecode_GetDouble(QCBORDecodeContext *pCtx,
545 double *pValue);
546
547 static void
548 QCBORDecode_GetDoubleInMapN(QCBORDecodeContext *pCtx,
549 int64_t nLabel,
550 double *pdValue);
551
552 static void
553 QCBORDecode_GetDoubleInMapSZ(QCBORDecodeContext *pCtx,
554 const char *szLabel,
555 double *pdValue);
556
557
558 /**
559 * @brief Decode next item into a double floating-point with basic conversion.
560 *
561 * @param[in] pCtx The decode context.
562 * @param[in] uConvertTypes The integer conversion options.
563 * @param[out] pdValue The returned floating-point value.
564 *
565 * This will decode CBOR integer and floating-point numbers, returning
566 * them as a double floating-point number. This function supports
567
568 * @ref QCBOR_CONVERT_TYPE_XINT64 and @ref QCBOR_CONVERT_TYPE_FLOAT
569 * conversions. If the encoded CBOR is not one of the requested types
570 * or a type not supported by this function, @ref QCBOR_ERR_UNEXPECTED_TYPE
571 * is set.
572 *
573 * Please see @ref Decode-Errors-Overview "Decode Errors Overview".
574 *
575 * If floating-point HW use is disabled this will set
576 * @ref QCBOR_ERR_HW_FLOAT_DISABLED if a single-precision number is
577 * encountered. If half-precision support is disabled, this will set
578 * @ref QCBOR_ERR_HALF_PRECISION_DISABLED if a half-precision number is
579 * encountered.
580 *
581 * Positive and negative integers can always be converted to
582 * floating-point, so this will never error on CBOR major type 0 or 1.
583 *
584 * Note that a large 64-bit integer can have more precision (64 bits)
585 * than even a double floating-point (52 bits) value, so there is loss
586 * of precision in some conversions.
587 *
588 * See also QCBORDecode_GetDouble() and QCBORDecode_GetDoubleConvertAll().
589 */
590 static void
591 QCBORDecode_GetDoubleConvert(QCBORDecodeContext *pCtx,
592 uint32_t uConvertTypes,
593 double *pdValue);
594
595 static void
596 QCBORDecode_GetDoubleConvertInMapN(QCBORDecodeContext *pCtx,
597 int64_t nLabel,
598 uint32_t uConvertTypes,
599 double *pdValue);
600
601 static void
602 QCBORDecode_GetDoubleConvertInMapSZ(QCBORDecodeContext *pCtx,
603 const char *szLabel,
604 uint32_t uConvertTypes,
605 double *pdValue);
606
607
608 /**
609 * @brief Decode next item as a double floating-point value with conversion.
610 *
611 * @param[in] pCtx The decode context.
612 * @param[in] uConvertTypes The integer conversion options.
613 * @param[out] pdValue The returned floating-point value.
614 *
615 * This is the same as QCBORDecode_GetDoubleConvert() but supports
616 * many more conversions at the cost of linking in more object
617 * code. The conversion types supported are @ref QCBOR_CONVERT_TYPE_XINT64,
618 * @ref QCBOR_CONVERT_TYPE_FLOAT, @ref QCBOR_CONVERT_TYPE_BIG_NUM,
619 * @ref QCBOR_CONVERT_TYPE_DECIMAL_FRACTION and
620 * @ref QCBOR_CONVERT_TYPE_BIGFLOAT.
621 *
622 * Big numbers, decimal fractions and big floats that are too small or
623 * too large to be reprented as a double floating-point number will be
624 * returned as plus or minus zero or infinity rather than setting an
625 * under or overflow error.
626 *
627 * There is often loss of precision in the conversion.
628 *
629 * See also QCBORDecode_GetDoubleConvert() and QCBORDecode_GetDoubleConvert().
630 */
631 void
632 QCBORDecode_GetDoubleConvertAll(QCBORDecodeContext *pCtx,
633 uint32_t uConvertTypes,
634 double *pdValue);
635
636 void
637 QCBORDecode_GetDoubleConvertAllInMapN(QCBORDecodeContext *pCtx,
638 int64_t nLabel,
639 uint32_t uConvertTypes,
640 double *pdValue);
641
642 void
643 QCBORDecode_GetDoubleConvertAllInMapSZ(QCBORDecodeContext *pCtx,
644 const char *szLabel,
645 uint32_t uConvertTypes,
646 double *pdValue);
647 #endif /* USEFULBUF_DISABLE_ALL_FLOAT */
648
649
650
651
652 /**
653 * @brief Enter an array for decoding in bounded mode.
654 *
655 * @param[in] pCtx The decode context.
656 * @param[out] pItem The optionally returned QCBORItem that has the
657 * label and tags for the array. May be @c NULL (and
658 * usually is).
659 *
660 * This enters an array for decoding in bounded mode. The items in
661 * the array are decoded in order the same as when not in bounded mode,
662 * but the decoding will not proceed past the end or the array.
663 *
664 * The typical way to iterate over items in an array is to call
665 * QCBORDecode_VGetNext() until QCBORDecode_GetError() returns
666 * @ref QCBOR_ERR_NO_MORE_ITEMS. Other methods like QCBORDecode_GetInt64(),
667 * QCBORDecode_GetBignum() and such may also called until
668 * QCBORDecode_GetError() doesn't return QCBOR_SUCCESS.
669 *
670 * Another option is to get the array item count from
671 * @c pItem->val.uCount, but note that that will not work with
672 * indefinte-length arrays, where as QCBORDecode_GetError() will.
673 *
674 * Nested decoding of arrays may be handled by calling
675 * QCBORDecode_EnterArray() or by using QCBORDecode_VGetNext() to
676 * descend into and back out of the nested array.
677 *
678 * QCBORDecode_Rewind() can be called to restart decoding from the
679 * first item in the array.
680 *
681 * When all decoding in an array is complete, QCBORDecode_ExitArray() must
682 * be called. It is a decoding error to not have a corresponding call
683 * to QCBORDecode_ExitArray() for every call to QCBORDecode_EnterArray().
684 * If not, @ref QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN will be returned when
685 * QCBORDecode_Finish() is called.
686 *
687 * After QCBORDecode_ExitArray() is called the traversal cusor is at
688 * the item right after the array. This is true whether or not all
689 * items in the array were consumed. QCBORDecode_ExitArray() can even
690 * be called right after QCBORDecode_EnterArray() as a way to skip
691 * over an array and all its contents.
692 *
693 * This works the same for definite and indefinite length arrays.
694 *
695 * Please see @ref Decode-Errors-Overview "Decode Errors Overview".
696 *
697 * If attempting to enter a data item that is not an array
698 * @ref QCBOR_ERR_UNEXPECTED_TYPE wil be set.
699 *
700 * Nested arrays and maps may be entered to a depth of
701 * @ref QCBOR_MAX_ARRAY_NESTING.
702 *
703 * See also QCBORDecode_ExitArray(), QCBORDecode_EnterMap(),
704 * QCBORDecode_EnterBstrWrapped() and QCBORDecode_GetArray().
705 */
706 static void
707 QCBORDecode_EnterArray(QCBORDecodeContext *pCtx, QCBORItem *pItem);
708
709 void
710 QCBORDecode_EnterArrayFromMapN(QCBORDecodeContext *pMe, int64_t uLabel);
711
712 void
713 QCBORDecode_EnterArrayFromMapSZ(QCBORDecodeContext *pMe, const char *szLabel);
714
715
716 /**
717 * @brief Exit an array that has been enetered.
718 *
719 * @param[in] pCtx The decode context.
720 *
721 * An array must have been entered for this to succeed.
722 *
723 * The items in the array that was entered do not have to have been
724 * consumed for this to succeed.
725 *
726 * This sets the traversal cursor to the item after the
727 * array that was exited.
728 *
729 * This will result in an error if any item in the array is not well
730 * formed (since all items in the array must be decoded to find its
731 * end), or there are not enough items in the array.
732 */
733 static void
734 QCBORDecode_ExitArray(QCBORDecodeContext *pCtx);
735
736
737
738 /**
739 * @brief Get the encoded bytes that make up an array.
740 *
741 * @param[in] pCtx The decode context.
742 * @param[out] pItem Place to return the item.
743 * @param[out] pEncodedCBOR Place to return pointer and length of the array.
744 *
745 * The next item to decode must be an array.
746 *
747 * The encoded bytes of the array will be returned. They can be
748 * decoded by another decoder instance.
749 *
750 * @c pItem will have the label and tags for the array. It is filled
751 * in the same as if QCBORDecode_GetNext() were called on the array item. In
752 * particular, the array count will be filled in for definite-length
753 * arrays and set to @c UINT16_MAX for indefinite-length arrays.
754 *
755 * This works on both definite and indefinite length arrays (unless
756 * indefinite length array decoding has been disabled).
757 *
758 * The pointer returned is to the data item that opens the array. The
759 * length in bytes includes it and all the member data items. If the array
760 * occurs in another map and thus has a label, the label is not included
761 * in what is returned.
762 *
763 * If the array is preceeded by tags, those encoded tags are included
764 * in the encoded CBOR that is returned.
765 *
766 * QCBORDecode_GetArray() consumes the entire array and leaves the
767 * traversal cursor at the item after the array.
768 * QCBORDecode_GetArrayFromMapN() and QCBORDecode_GetArrayFromMapSZ()
769 * don't affect the traversal cursor.
770 *
771 * This traverses the whole array and every subordinate array or map in
772 * it. This is necessary to determine the length of the array.
773 *
774 * This will fail if any item in the array is not well-formed.
775 *
776 * This uses a few hundred bytes of stack, more than most methods.
777 *
778 * See also QCBORDecode_EnterArray().
779 */
780 static void
781 QCBORDecode_GetArray(QCBORDecodeContext *pCtx,
782 QCBORItem *pItem,
783 UsefulBufC *pEncodedCBOR);
784
785 static void
786 QCBORDecode_GetArrayFromMapN(QCBORDecodeContext *pCtx,
787 int64_t nLabel,
788 QCBORItem *pItem,
789 UsefulBufC *pEncodedCBOR);
790
791 static void
792 QCBORDecode_GetArrayFromMapSZ(QCBORDecodeContext *pCtx,
793 const char *szLabel,
794 QCBORItem *pItem,
795 UsefulBufC *pEncodedCBOR);
796
797
798 /**
799 * @brief Enter a map for decoding and searching.
800 *
801 * @param[in] pCtx The decode context.
802 * @param[out] pItem The optionally returned QCBORItem that has the
803 * label and tags for the map. May be @c NULL (and
804 * usually is).
805 *
806 * The next item in the CBOR input must be map or this sets an error.
807 *
808 * This puts the decoder in bounded mode which narrows decoding to the
809 * map entered and enables getting items by label.
810 *
811 * All items in the map must be well-formed to be able to search it by
812 * label because a full traversal is done for each search. If not, the
813 * search will retun an error for the item that is not well-formed.
814 * This will be the first non-well-formed item which may not be the
815 * item with the label that is the target of the search.
816 *
817 * Nested maps can be decoded like this by entering each map in turn.
818 *
819 * Call QCBORDecode_ExitMap() to exit the current map decoding
820 * level. When all map decoding layers are exited then bounded mode is
821 * fully exited.
822 *
823 * While in bounded mode, QCBORDecode_GetNext() works as usual on the
824 * map and the traversal cursor is maintained. It starts out
825 * at the first item in the map just entered. Attempts to get items
826 * off the end of the map will give error @ref QCBOR_ERR_NO_MORE_ITEMS
827 * rather going to the next item after the map as it would when not in
828 * bounded mode.
829 *
830 * It is possible to mix use of the traversal cursor with the fetching
831 * of items in a map by label with the caveat that fetching
832 * non-aggregate items by label behaves differently from entering subordinate
833 * aggregate items by label. See dicussion in @ref SpiffyDecode.
834 *
835 * Exiting leaves the traversal cursor at the data item following the
836 * last entry in the map or at the end of the input CBOR if there
837 * nothing after the map.
838 *
839 * Entering and Exiting a map is a way to skip over an entire map and
840 * its contents. After QCBORDecode_ExitMap(), the traversal
841 * cursor will be at the first item after the map.
842 *
843 * Please see @ref Decode-Errors-Overview "Decode Errors Overview".
844 *
845 * See also QCBORDecode_EnterArray() and
846 * QCBORDecode_EnterBstrWrapped(). Entering and exiting any nested
847 * combination of maps, arrays and bstr-wrapped CBOR is supported up
848 * to the maximum of @ref QCBOR_MAX_ARRAY_NESTING.
849 *
850 * See also QCBORDecode_GetMap().
851 */
852 static void
853 QCBORDecode_EnterMap(QCBORDecodeContext *pCtx, QCBORItem *pItem);
854
855 void
856 QCBORDecode_EnterMapFromMapN(QCBORDecodeContext *pCtx, int64_t nLabel);
857
858 void
859 QCBORDecode_EnterMapFromMapSZ(QCBORDecodeContext *pCtx, const char *szLabel);
860
861
862 /**
863 * @brief Exit a map that has been enetered.
864 *
865 * @param[in] pCtx The decode context.
866 *
867 * A map must have been entered for this to succeed.
868 *
869 * The items in the map that was entered do not have to have been
870 * consumed for this to succeed.
871 *
872 * This sets the traversal cursor to the item after the map
873 * that was exited.
874 *
875 * This will result in an error if any item in the map is not well
876 * formed (since all items in the map must be decoded to find its
877 * end), or there are not enough items in the map.
878 */
879 static void
880 QCBORDecode_ExitMap(QCBORDecodeContext *pCtx);
881
882
883 /**
884 * @brief Get the bytes that make up a map.
885 *
886 * @param[in] pCtx The decode context.
887 * @param[out] pItem Place to return the item.
888 * @param[out] pEncodedCBOR Place to return pointer and length of the map.
889 *
890 * The next item to decode must be a map.
891 *
892 * The encoded bytes of the map will be returned. They can be
893 * decoded by another decoder instance.
894 *
895 * @c pItem will have the label and tags for the array. It is filled
896 * in the same as if QCBORDecode_GetNext() were called on the map item. In
897 * particular, the map count will be filled in for definite-length
898 * maps and set to @c UINT16_MAX for indefinite-length maps.
899 *
900 * This works on both definite and indefinite length maps (unless
901 * indefinite length map decoding has been disabled).
902 *
903 * The pointer returned is to the data item that opens the map. The
904 * length in bytes includes it and all the member data items. If the map
905 * occurs in another map and thus has a label, the label is not included
906 * in what is returned.
907 *
908 * If the map is preceeded by tags, those encoded tags are included in
909 * the encoded CBOR that is returned.
910 *
911 * QCBORDecode_GetMap() consumes the entire array and leaves the
912 * traversal cursor at the item after the map.
913 * QCBORDecode_GetMapFromMapN() and QCBORDecode_GetMapFromMapSZ()
914 * don't affect the traversal cursor.
915 *
916 * This traverses the whole map and every subordinate array or map in
917 * it. This is necessary to determine the length of the map. The
918 * traversal cursor is left at the first item after the map.
919 *
920 * This will fail if any item in the map is not well-formed.
921 *
922 * This uses a few hundred bytes of stack, more than most methods.
923 *
924 * See also QCBORDecode_EnterMap().
925 */
926 static void
927 QCBORDecode_GetMap(QCBORDecodeContext *pCtx,
928 QCBORItem *pItem,
929 UsefulBufC *pEncodedCBOR);
930
931 static void
932 QCBORDecode_GetMapFromMapN(QCBORDecodeContext *pCtx,
933 int64_t nLabel,
934 QCBORItem *pItem,
935 UsefulBufC *pEncodedCBOR);
936
937 static void
938 QCBORDecode_GetMapFromMapSZ(QCBORDecodeContext *pCtx,
939 const char *szLabel,
940 QCBORItem *pItem,
941 UsefulBufC *pEncodedCBOR);
942
943
944 /**
945 * @brief Reset traversal cursor to start of map, array, byte-string
946 * wrapped CBOR or start of input.
947 *
948 * @param[in] pCtx The decode context.
949 *
950 * If an array, map or wrapping byte string has been entered this sets
951 * the traversal cursor to its beginning. If several arrays, maps or
952 * byte strings have been entered, this sets the traversal cursor to
953 * the beginning of the one most recently entered.
954 *
955 * If no map or array has been entered, this resets the traversal
956 * cursor to the beginning of the input CBOR.
957 *
958 * This also resets the error state.
959 */
960 void
961 QCBORDecode_Rewind(QCBORDecodeContext *pCtx);
962
963
964 /**
965 * @brief Get an item in map by label and type.
966 *
967 * @param[in] pCtx The decode context.
968 * @param[in] nLabel The integer label.
969 * @param[in] uQcborType The QCBOR type. One of @c QCBOR_TYPE_XXX.
970 * @param[out] pItem The returned item.
971 *
972 * A map must have been entered to use this. If not
973 * @ref QCBOR_ERR_MAP_NOT_ENTERED is set.
974 *
975 * The map is searched for an item of the requested label and type.
976 * @ref QCBOR_TYPE_ANY can be given to search for the label without
977 * matching the type.
978 *
979 * This will always search the entire map. This will always perform
980 * duplicate label detection, setting @ref QCBOR_ERR_DUPLICATE_LABEL
981 * if there is more than one occurance of the label being searched
982 * for.
983 *
984 * Duplicate label detection is performed for the item being sought
985 * and only for the item being sought.
986 *
987 * This performs a full decode of every item in the map being
988 * searched which involves a full traversal of every item. For maps
989 * with little nesting, this is of little consequence, but may be of
990 * consequence for large deeply nested CBOR structures on slow CPUs.
991 *
992 * The position of the traversal cursor is not changed.
993 *
994 * Please see @ref Decode-Errors-Overview "Decode Errors Overview".
995 *
996 * See also QCBORDecode_GetItemsInMap() for error discussion.
997 */
998 void
999 QCBORDecode_GetItemInMapN(QCBORDecodeContext *pCtx,
1000 int64_t nLabel,
1001 uint8_t uQcborType,
1002 QCBORItem *pItem);
1003
1004 void
1005 QCBORDecode_GetItemInMapSZ(QCBORDecodeContext *pCtx,
1006 const char *szLabel,
1007 uint8_t uQcborType,
1008 QCBORItem *pItem);
1009
1010
1011 /**
1012 * @brief Get a group of labeled items all at once from a map
1013 *
1014 * @param[in] pCtx The decode context.
1015 * @param[in,out] pItemList On input, the items to search for. On output,
1016 * the returne *d items.
1017 *
1018 * This gets several labeled items out of a map.
1019 *
1020 * @c pItemList is an array of items terminated by an item with @c
1021 * uLabelType @ref QCBOR_TYPE_NONE.
1022 *
1023 * On input the labels to search for are in the @c uLabelType and
1024 * label fields in the items in @c pItemList.
1025 *
1026 * Also on input are the requested QCBOR types in the field
1027 * @c uDataType. To match any type, searching just by label,
1028 * @c uDataType can be @ref QCBOR_TYPE_ANY.
1029 *
1030 * This is a CPU-efficient way to decode a bunch of items in a map. It
1031 * is more efficient than scanning each individually because the map
1032 * only needs to be traversed once.
1033 *
1034 * This will return maps and arrays that are in the map, but provides
1035 * no way to descend into and decode them. Use
1036 * QCBORDecode_EnterMapinMapN(), QCBORDecode_EnterArrayInMapN() and
1037 * such to descend into and process maps and arrays.
1038 *
1039 * The position of the traversal cursor is not changed.
1040 *
1041 * Please see @ref Decode-Errors-Overview "Decode Errors Overview".
1042 *
1043 * The following errors are set:
1044 *
1045 * @ref QCBOR_ERR_MAP_NOT_ENTERED when calling this without previousl
1046 * calling QCBORDecode_EnterMap() or other methods to enter a map.
1047 *
1048 * @ref QCBOR_ERR_DUPLICATE_LABEL when one of the labels being searched
1049 * for is duplicate.
1050 *
1051 * @ref QCBOR_ERR_HIT_END or other errors classifed as not-well-formed
1052 * by QCBORDecode_IsNotWellFormed() as it is not possible to traverse
1053 * maps that have any non-well formed items.
1054 *
1055 * @ref QCBOR_ERR_UNEXPECTED_TYPE when the type of an item found by
1056 * matching a label is not the type requested.
1057 *
1058 * @ref QCBOR_ERR_ARRAY_NESTING_TOO_DEEP and other implementation
1059 * limit errors as it is not possible to travere a map beyond the
1060 * limits of the implementation.
1061 *
1062 * The error may occur on items that are not being searched for. For
1063 * example, it is impossible to traverse over a map that has an array in
1064 * it that is not closed or over array and map nesting deeper than this
1065 * implementation can track.
1066 *
1067 * See also QCBORDecode_GetItemInMapN().
1068 */
1069 void
1070 QCBORDecode_GetItemsInMap(QCBORDecodeContext *pCtx, QCBORItem *pItemList);
1071
1072
1073 /**
1074 * @brief Per-item callback for map searching.
1075 *
1076 * @param[in] pCallbackCtx Pointer to the caller-defined context for the callback.
1077 * @param[in] pItem The item from the map.
1078 *
1079 * The error set is intended for QCBOR errors, not general protocol
1080 * decoding errors. If this sets other than @ref QCBOR_SUCCESS, the
1081 * search will stop and the value it returns will be set in
1082 * QCBORDecode_GetItemsInMapWithCallback(). The special error,
1083 * @ref QCBOR_ERR_CALLBACK_FAIL, can be returned to indicate some
1084 * protocol processing error that is not a CBOR error. The specific
1085 * details of the protocol processing error can be returned the call
1086 * back context.
1087 */
1088 typedef QCBORError (*QCBORItemCallback)(void *pCallbackCtx,
1089 const QCBORItem *pItem);
1090
1091
1092 /**
1093 * @brief Get a group of labeled items all at once from a map with a callback.
1094 *
1095 * @param[in] pCtx The decode context.
1096 * @param[in,out] pItemList On input, the items to search for. On output,
1097 * the returne *d items.
1098 * @param[in,out] pCallbackCtx Pointer to a context structure for
1099 * @ref QCBORItemCallback
1100 * @param[in] pfCB Pointer to function of type
1101 * @ref QCBORItemCallback that is called on
1102 * unmatched items.
1103 *
1104 * This searchs a map like QCBORDecode_GetItemsInMap(), but calls a
1105 * callback on items not matched rather than ignoring them. If @c
1106 * pItemList is empty, the call back will be called on every item in the
1107 * map.
1108 *
1109 * Like QCBORDecode_GetItemsInMap(), this only matches and calls back on
1110 * the items at the top level of the map entered. Items in nested
1111 * maps and arrays are skipped over and not candidate for matching or the
1112 * callback.
1113 *
1114 * See QCBORItemCallback() for error handling.
1115 */
1116 void
1117 QCBORDecode_GetItemsInMapWithCallback(QCBORDecodeContext *pCtx,
1118 QCBORItem *pItemList,
1119 void *pCallbackCtx,
1120 QCBORItemCallback pfCB);
1121
1122
1123
1124
1125 /**
1126 * @brief Decode the next item as a Boolean.
1127 *
1128 * @param[in] pCtx The decode context.
1129 * @param[out] pbBool The decoded byte string.
1130 *
1131 * The CBOR item to decode must be either the CBOR simple value (CBOR
1132 * type 7) @c true or @c false.
1133 *
1134 * Please see @ref Decode-Errors-Overview "Decode Errors Overview". If
1135 * the CBOR item to decode is not true or false the @ref
1136 * QCBOR_ERR_UNEXPECTED_TYPE error is set.
1137 */
1138 void
1139 QCBORDecode_GetBool(QCBORDecodeContext *pCtx, bool *pbBool);
1140
1141 void
1142 QCBORDecode_GetBoolInMapN(QCBORDecodeContext *pCtx,
1143 int64_t nLabel,
1144 bool *pbBool);
1145
1146 void
1147 QCBORDecode_GetBoolInMapSZ(QCBORDecodeContext *pCtx,
1148 const char *szLabel,
1149 bool *pbBool);
1150
1151
1152 /**
1153 * @brief Decode the next item as a null.
1154 *
1155 * @param[in] pCtx The decode context.
1156 *
1157 * The CBOR item to decode must be the CBOR simple value (CBOR type 7)
1158 * @c null. The reason to call this is to see if an error is returned
1159 * or not indicating whether the item is a CBOR null. If it is not
1160 * then the @ref QCBOR_ERR_UNEXPECTED_TYPE error is set.
1161 */
1162 static void
1163 QCBORDecode_GetNull(QCBORDecodeContext *pCtx);
1164
1165 static void
1166 QCBORDecode_GetNullInMapN(QCBORDecodeContext *pCtx,
1167 int64_t nLabel);
1168
1169 static void
1170 QCBORDecode_GetNullInMapSZ(QCBORDecodeContext *pCtx,
1171 const char *szLabel);
1172
1173
1174 /**
1175 * @brief Decode the next item as a CBOR "undefined" item.
1176 *
1177 * @param[in] pCtx The decode context.
1178 *
1179 * The CBOR item to decode must be the CBOR simple value (CBOR type 7)
1180 * @c undefined. The reason to call this is to see if an error is
1181 * returned or not indicating whether the item is a CBOR undefed
1182 * item. If it is not then the @ref QCBOR_ERR_UNEXPECTED_TYPE error is
1183 * set.
1184 */
1185 static void
1186 QCBORDecode_GetUndefined(QCBORDecodeContext *pCtx);
1187
1188 static void
1189 QCBORDecode_GetUndefinedInMapN(QCBORDecodeContext *pCtx,
1190 int64_t nLabel);
1191
1192 static void
1193 QCBORDecode_GetUndefinedInMapSZ(QCBORDecodeContext *pCtx,
1194 const char *szLabel);
1195
1196
1197 /**
1198 * @brief Decode the next item as a CBOR simple value.
1199 *
1200 * @param[in] pCtx The decode context.
1201 * @param[out] puSimpleValue The simplle value returned.
1202 *
1203 * The purpose of this is to get a CBOR simple value other than a
1204 * Boolean, NULL or "undefined", but this works on all simple
1205 * values. See QCBOREncode_AddSimple() for more details on simple
1206 * values in general.
1207 *
1208 * See QCBORDecode_GetBool(), QCBORDecode_GetNull(),
1209 * QCBORDecode_GetUndefined() for the preferred way of getting those
1210 * simple values.
1211 */
1212 void
1213 QCBORDecode_GetSimple(QCBORDecodeContext *pCtx, uint8_t *puSimpleValue);
1214
1215 void
1216 QCBORDecode_GetSimpleInMapN(QCBORDecodeContext *pCtx,
1217 int64_t nLabel,
1218 uint8_t *puSimpleValue);
1219
1220 void
1221 QCBORDecode_GetSimpleInMapSZ(QCBORDecodeContext *pCtx,
1222 const char *szLabel,
1223 uint8_t *puSimpleValue);
1224
1225
1226
1227
1228 /**
1229 * @brief Decode the next item as a date string.
1230 *
1231 * @param[in] pCtx The decode context.
1232 * @param[in] uTagRequirement One of @c QCBOR_TAG_REQUIREMENT_XXX.
1233 * @param[out] pDateString The decoded date.
1234 *
1235 * This decodes the standard CBOR date/time string tag, integer tag
1236 * number of 0, or encoded CBOR that is not a tag, but borrows the
1237 * date string content format.
1238 *
1239 * Please see @ref Decode-Errors-Overview "Decode Errors Overview".
1240 *
1241 * See @ref Tag-Usage for discussion on tag requirements.
1242 *
1243 * See also @ref CBOR_TAG_DATE_STRING, QCBOREncode_AddDateString() and
1244 * @ref QCBOR_TYPE_DATE_STRING.
1245 */
1246 static void
1247 QCBORDecode_GetDateString(QCBORDecodeContext *pCtx,
1248 uint8_t uTagRequirement,
1249 UsefulBufC *pDateString);
1250
1251 static void
1252 QCBORDecode_GetDateStringInMapN(QCBORDecodeContext *pCtx,
1253 int64_t nLabel,
1254 uint8_t uTagRequirement,
1255 UsefulBufC *pDateString);
1256
1257 static void
1258 QCBORDecode_GetDateStringInMapSZ(QCBORDecodeContext *pCtx,
1259 const char *szLabel,
1260 uint8_t uTagRequirement,
1261 UsefulBufC *pDateString);
1262
1263
1264 /**
1265 * @brief Decode the next item as a date-only string.
1266 *
1267 * @param[in] pCtx The decode context.
1268 * @param[in] uTagRequirement One of @c QCBOR_TAG_REQUIREMENT_XXX.
1269 * @param[out] pDateString The decoded date.
1270 *
1271 * This decodes the CBOR date-only string tag, integer tag number of
1272 * 1004, or encoded CBOR that is not a tag, but borrows the date-only
1273 * string content format. An example of the format is "1985-04-12".
1274 *
1275 * Please see @ref Decode-Errors-Overview "Decode Errors Overview".
1276 *
1277 * See @ref Tag-Usage for discussion on tag requirements.
1278 *
1279 * See also @ref CBOR_TAG_DAYS_STRING, QCBOREncode_AddDaysString() and
1280 * @ref QCBOR_TYPE_DAYS_STRING.
1281 */
1282 static void
1283 QCBORDecode_GetDaysString(QCBORDecodeContext *pCtx,
1284 uint8_t uTagRequirement,
1285 UsefulBufC *pDateString);
1286
1287 static void
1288 QCBORDecode_GetDaysStringInMapN(QCBORDecodeContext *pCtx,
1289 int64_t nLabel,
1290 uint8_t uTagRequirement,
1291 UsefulBufC *pDateString);
1292
1293 static void
1294 QCBORDecode_GetDaysStringInMapSZ(QCBORDecodeContext *pCtx,
1295 const char *szLabel,
1296 uint8_t uTagRequirement,
1297 UsefulBufC *pDateString);
1298
1299
1300 /**
1301 * @brief Decode the next item as an epoch date.
1302 *
1303 * @param[in] pCtx The decode context.
1304 * @param[in] uTagRequirement One of @c QCBOR_TAG_REQUIREMENT_XXX.
1305 * @param[out] pnTime The decoded epoch date.
1306 *
1307 * This decodes the standard CBOR epoch date/time tag, integer tag
1308 * number of 1. This will also decode any integer or floating-point
1309 * number as an epoch date (a tag 1 epoch date is just an integer or
1310 * floating-point number).
1311 *
1312 * This will set @ref QCBOR_ERR_DATE_OVERFLOW if the input integer
1313 * will not fit in an @c int64_t. Note that an @c int64_t can
1314 * represent a range of over 500 billion years with one second
1315 * resolution.
1316 *
1317 * Floating-point dates are always returned as an @c int64_t. The
1318 * fractional part is discarded.
1319 *
1320 * If the input is a floating-point date and the QCBOR library is
1321 * compiled with some or all floating-point features disabled, the
1322 * following errors will be set. If the input is half-precision and
1323 * half-precision is disabled @ref QCBOR_ERR_HALF_PRECISION_DISABLED
1324 * is set. This function needs hardware floating-point to convert the
1325 * floating-point value to an integer so if HW floating point is
1326 * disabled @ref QCBOR_ERR_HW_FLOAT_DISABLED is set. If all
1327 * floating-point is disabled then @ref QCBOR_ERR_ALL_FLOAT_DISABLED
1328 * is set. A previous version of this function would return
1329 * @ref QCBOR_ERR_FLOAT_DATE_DISABLED in some, but not all, cases when
1330 * floating-point decoding was disabled.
1331 *
1332 * Floating-point dates that are plus infinity, minus infinity or NaN
1333 * (not-a-number) will result in the @ref QCBOR_ERR_DATE_OVERFLOW
1334 * error.
1335 *
1336 * Please see @ref Decode-Errors-Overview "Decode Errors Overview".
1337 *
1338 * See @ref Tag-Usage for discussion on tag requirements.
1339 *
1340 * See also @ref CBOR_TAG_DATE_EPOCH, QCBOREncode_AddDateEpoch() and
1341 * @ref QCBOR_TYPE_DATE_EPOCH.
1342 */
1343 void
1344 QCBORDecode_GetEpochDate(QCBORDecodeContext *pCtx,
1345 uint8_t uTagRequirement,
1346 int64_t *pnTime);
1347
1348 void
1349 QCBORDecode_GetEpochDateInMapN(QCBORDecodeContext *pCtx,
1350 int64_t nLabel,
1351 uint8_t uTagRequirement,
1352 int64_t *pnTime);
1353
1354 void
1355 QCBORDecode_GetEpochDateInMapSZ(QCBORDecodeContext *pCtx,
1356 const char *szLabel,
1357 uint8_t uTagRequirement,
1358 int64_t *pnTime);
1359
1360
1361 /**
1362 * @brief Decode the next item as an days-count epoch date.
1363 *
1364 * @param[in] pCtx The decode context.
1365 * @param[in] uTagRequirement One of @c QCBOR_TAG_REQUIREMENT_XXX.
1366 * @param[out] pnDays The decoded epoch date.
1367 *
1368 * This decodes the CBOR epoch date tag, integer tag number of 100, or
1369 * encoded CBOR that is not a tag, but borrows the content format. The
1370 * date is the number of days (not number of seconds) before or after
1371 * Jan 1, 1970.
1372 *
1373 * Please see @ref Decode-Errors-Overview "Decode Errors Overview".
1374 *
1375 * See @ref Tag-Usage for discussion on tag requirements.
1376 *
1377 * See also @ref CBOR_TAG_DAYS_EPOCH, QCBOREncode_AddTDaysEpoch() and
1378 * @ref QCBOR_TYPE_DAYS_EPOCH.
1379 */
1380 void
1381 QCBORDecode_GetEpochDays(QCBORDecodeContext *pCtx,
1382 uint8_t uTagRequirement,
1383 int64_t *pnDays);
1384
1385 void
1386 QCBORDecode_GetEpochDaysInMapN(QCBORDecodeContext *pCtx,
1387 int64_t nLabel,
1388 uint8_t uTagRequirement,
1389 int64_t *pnDays);
1390
1391 void
1392 QCBORDecode_GetEpochDaysInMapSZ(QCBORDecodeContext *pCtx,
1393 const char *szLabel,
1394 uint8_t uTagRequirement,
1395 int64_t *pnDays);
1396
1397
1398
1399
1400 /**
1401 * @brief Decode the next item as a big number.
1402 *
1403 * @param[in] pCtx The decode context.
1404 * @param[in] uTagRequirement One of @c QCBOR_TAG_REQUIREMENT_XXX.
1405 * @param[out] pValue The returned big number.
1406 * @param[out] pbIsNegative Is @c true if the big number is negative. This
1407 * is only valid when @c uTagRequirement is
1408 * @ref QCBOR_TAG_REQUIREMENT_TAG.
1409 *
1410 * This decodes a standard CBOR big number, integer tag number of 2 or
1411 * 3, or encoded CBOR that is not a tag, but borrows the content
1412 * format.
1413 *
1414 * Please see @ref Decode-Errors-Overview "Decode Errors Overview".
1415 *
1416 * The big number is in network byte order. The first byte in @c
1417 * pValue is the most significant byte. There may be leading zeros.
1418 *
1419 * The negative value is computed as -1 - n, where n is the postive
1420 * big number in @c pValue. There is no standard representation for
1421 * big numbers, positive or negative in C, so this implementation
1422 * leaves it up to the caller to apply this computation for negative
1423 * big numbers.
1424 *
1425 * See @ref Tag-Usage for discussion on tag requirements.
1426 *
1427 * Determination of the sign of the big number depends on the tag
1428 * requirement of the protocol using the big number. If the protocol
1429 * requires tagging, @ref QCBOR_TAG_REQUIREMENT_TAG, then the sign
1430 * indication is in the protocol and @c pbIsNegative indicates the
1431 * sign. If the protocol doesn't use a tag, @ref QCBOR_TAG_REQUIREMENT_NOT_A_TAG,
1432 * then the protocol design must have some way of indicating the sign.
1433 *
1434 * See also QCBORDecode_GetInt64ConvertAll(),
1435 * QCBORDecode_GetUInt64ConvertAll() and
1436 * QCBORDecode_GetDoubleConvertAll() which can convert big numbers.
1437 *
1438 * See also @ref CBOR_TAG_POS_BIGNUM, @ref CBOR_TAG_NEG_BIGNUM,
1439 * QCBOREncode_AddPositiveBignum(), QCBOREncode_AddNegativeBignum(),
1440 * @ref QCBOR_TYPE_POSBIGNUM and @ref QCBOR_TYPE_NEGBIGNUM.
1441 */
1442 // Improvement: Add function that converts integers and other to big nums
1443 void
1444 QCBORDecode_GetBignum(QCBORDecodeContext *pCtx,
1445 uint8_t uTagRequirement,
1446 UsefulBufC *pValue,
1447 bool *pbIsNegative);
1448
1449 void
1450 QCBORDecode_GetBignumInMapN(QCBORDecodeContext *pCtx,
1451 int64_t nLabel,
1452 uint8_t uTagRequirement,
1453 UsefulBufC *pValue,
1454 bool *pbIsNegative);
1455
1456 void
1457 QCBORDecode_GetBignumInMapSZ(QCBORDecodeContext *pCtx,
1458 const char *szLabel,
1459 uint8_t uTagRequirement,
1460 UsefulBufC *pValue,
1461 bool *pbIsNegative);
1462
1463
1464
1465
1466 #ifndef QCBOR_DISABLE_EXP_AND_MANTISSA
1467 /**
1468 * @brief Decode the next item as a decimal fraction.
1469 *
1470 * @param[in] pCtx The decode context.
1471 * @param[in] uTagRequirement One of @c QCBOR_TAG_REQUIREMENT_XXX.
1472 * @param[out] pnMantissa The mantissa.
1473 * @param[out] pnExponent The base 10 exponent.
1474 *
1475 * This decodes a standard CBOR decimal fraction, integer tag number
1476 * of 4, or encoded CBOR that is not a tag, but borrows the content
1477 * format.
1478 *
1479 * Please see @ref Decode-Errors-Overview "Decode Errors Overview".
1480 *
1481 * The value of this is computed by:
1482 *
1483 * mantissa * ( 10 ** exponent )
1484 *
1485 * In the encoded CBOR, the mantissa and exponent may be of CBOR type
1486 * 0 (positive integer), type 1 (negative integer), type 2 tag 2
1487 * (positive big number) or type 2 tag 3 (negative big number). This
1488 * implementation will attempt to convert all of these to an @c
1489 * int64_t. If the value won't fit, @ref QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW
1490 * or @ref QCBOR_ERR_BAD_EXP_AND_MANTISSA will be set.
1491 *
1492 * This implementation limits the exponent to between @c INT64_MIN and
1493 * @c INT64_MAX while CBOR allows the range of @c -UINT64_MAX to
1494 * @c UINT64_MAX.
1495 *
1496 * Various format and type issues will result in
1497 * @ref QCBOR_ERR_BAD_EXP_AND_MANTISSA being set.
1498 *
1499 * See @ref Tag-Usage for discussion on tag requirements.
1500 *
1501 * See also QCBORDecode_GetInt64ConvertAll(),
1502 * QCBORDecode_GetUInt64ConvertAll() and
1503 * QCBORDecode_GetDoubleConvertAll() which can convert big numbers.
1504 *
1505 * See also @ref CBOR_TAG_DECIMAL_FRACTION,
1506 * QCBOREncode_AddDecimalFraction(), @ref QCBOR_TYPE_DECIMAL_FRACTION
1507 * and QCBORDecode_GetDecimalFractionBig().
1508 *
1509 * If QCBOR_DISABLE_TAGS is set, the only input this will decode is an
1510 * array of two integers. It will set an error if the the array is
1511 * preceded by by a tag number or if the mantissa is a big number.
1512 */
1513 void
1514 QCBORDecode_GetDecimalFraction(QCBORDecodeContext *pCtx,
1515 uint8_t uTagRequirement,
1516 int64_t *pnMantissa,
1517 int64_t *pnExponent);
1518
1519 void
1520 QCBORDecode_GetDecimalFractionInMapN(QCBORDecodeContext *pCtx,
1521 int64_t nLabel,
1522 uint8_t uTagRequirement,
1523 int64_t *pnMantissa,
1524 int64_t *pnExponent);
1525
1526 void
1527 QCBORDecode_GetDecimalFractionInMapSZ(QCBORDecodeContext *pMe,
1528 const char *szLabel,
1529 uint8_t uTagRequirement,
1530 int64_t *pnMantissa,
1531 int64_t *pnExponent);
1532
1533
1534 /**
1535 * @brief Decode the next item as a decimal fraction with a big number mantissa.
1536 *
1537 * @param[in] pCtx The decode context.
1538 * @param[in] uTagRequirement One of @c QCBOR_TAG_REQUIREMENT_XXX.
1539 * @param[in] MantissaBuffer The buffer in which to put the mantissa.
1540 * @param[out] pMantissa The big num mantissa.
1541 * @param[out] pbMantissaIsNegative Is @c true if @c pMantissa is negative.
1542 * @param[out] pnExponent The base 10 exponent.
1543 *
1544 * This is the same as QCBORDecode_GetDecimalFraction() except the
1545 * mantissa is returned as a big number.
1546 *
1547 * In the encoded CBOR, the mantissa may be a type 0 (positive
1548 * integer), type 1 (negative integer), type 2 tag 2 (positive big
1549 * number) or type 2 tag 3 (negative big number). This implementation
1550 * will convert all these to a big number. The limit to this
1551 * conversion is the size of @c MantissaBuffer.
1552 *
1553 * See also QCBORDecode_GetInt64ConvertAll(),
1554 * QCBORDecode_GetUInt64ConvertAll() and
1555 * QCBORDecode_GetDoubleConvertAll() which can convert decimal
1556 * fractions.
1557 *
1558 * See also @ref CBOR_TAG_DECIMAL_FRACTION,
1559 * QCBOREncode_AddDecimalFraction(), @ref QCBOR_TYPE_DECIMAL_FRACTION
1560 * and QCBORDecode_GetDecimalFraction().
1561 */
1562 void
1563 QCBORDecode_GetDecimalFractionBig(QCBORDecodeContext *pCtx,
1564 uint8_t uTagRequirement,
1565 UsefulBuf MantissaBuffer,
1566 UsefulBufC *pMantissa,
1567 bool *pbMantissaIsNegative,
1568 int64_t *pnExponent);
1569
1570 void
1571 QCBORDecode_GetDecimalFractionBigInMapN(QCBORDecodeContext *pCtx,
1572 int64_t nLabel,
1573 uint8_t uTagRequirement,
1574 UsefulBuf MantissaBuffer,
1575 UsefulBufC *pbMantissaIsNegative,
1576 bool *pbIsNegative,
1577 int64_t *pnExponent);
1578
1579 void
1580 QCBORDecode_GetDecimalFractionBigInMapSZ(QCBORDecodeContext *pCtx,
1581 const char *szLabel,
1582 uint8_t uTagRequirement,
1583 UsefulBuf MantissaBuffer,
1584 UsefulBufC *pMantissa,
1585 bool *pbMantissaIsNegative,
1586 int64_t *pnExponent);
1587
1588
1589 /**
1590 * @brief Decode the next item as a big float.
1591 *
1592 * @param[in] pCtx The decode context.
1593 * @param[in] uTagRequirement One of @c QCBOR_TAG_REQUIREMENT_XXX.
1594 * @param[out] pnMantissa The mantissa.
1595 * @param[out] pnExponent The base 2 exponent.
1596 *
1597 * This decodes a standard CBOR big float, integer tag number of 5, or
1598 * encoded CBOR that is not a tag, but borrows the content format.
1599 *
1600 * This is the same as QCBORDecode_GetDecimalFraction() with the
1601 * important distinction that the value is computed by:
1602 *
1603 * mantissa * ( 2 ** exponent )
1604 *
1605 * If the mantissa is a tag that is a positive or negative big number,
1606 * this will attempt to fit it into the int64_t that @c pnMantissa is
1607 * and set an overflow error if it doesn't fit.
1608 *
1609 * See also QCBORDecode_GetInt64ConvertAll(),
1610 * QCBORDecode_GetUInt64ConvertAll() and
1611 * QCBORDecode_GetDoubleConvertAll() which can convert big floats.
1612 *
1613 * See also @ref CBOR_TAG_BIGFLOAT, QCBOREncode_AddBigFloat(), @ref
1614 * QCBOR_TYPE_BIGFLOAT and QCBORDecode_GetBigFloatBig().
1615 */
1616 void
1617 QCBORDecode_GetBigFloat(QCBORDecodeContext *pCtx,
1618 uint8_t uTagRequirement,
1619 int64_t *pnMantissa,
1620 int64_t *pnExponent);
1621
1622 void
1623 QCBORDecode_GetBigFloatInMapN(QCBORDecodeContext *pCtx,
1624 int64_t nLabel,
1625 uint8_t uTagRequirement,
1626 int64_t *pnMantissa,
1627 int64_t *pnExponent);
1628
1629 void
1630 QCBORDecode_GetBigFloatInMapSZ(QCBORDecodeContext *pCtx,
1631 const char *szLabel,
1632 uint8_t uTagRequirement,
1633 int64_t *pnMantissa,
1634 int64_t *pnExponent);
1635
1636
1637 /**
1638 * @brief Decode the next item as a big float with a big number mantissa.
1639 *
1640 * @param[in] pCtx The decode context.
1641 * @param[in] uTagRequirement One of @c QCBOR_TAG_REQUIREMENT_XXX.
1642 * @param[in] MantissaBuffer The buffer in which to put the mantissa.
1643 * @param[out] pMantissa The big num mantissa.
1644 * @param[out] pbMantissaIsNegative Is @c true if @c pMantissa is negative.
1645 * @param[out] pnExponent The base 2 exponent.
1646 *
1647 * This is the same as QCBORDecode_GetDecimalFractionBig() with the
1648 * important distinction that the value is computed by:
1649 *
1650 * mantissa * ( 2 ** exponent )
1651 *
1652 * See also QCBORDecode_GetInt64ConvertAll(),
1653 * QCBORDecode_GetUInt64ConvertAll() and
1654 * QCBORDecode_GetDoubleConvertAll() which can convert big floats.
1655 *
1656 * See also @ref CBOR_TAG_BIGFLOAT, QCBOREncode_AddBigFloat(),
1657 * @ref QCBOR_TYPE_BIGFLOAT and QCBORDecode_GetBigFloat().
1658 */
1659 void
1660 QCBORDecode_GetBigFloatBig(QCBORDecodeContext *pCtx,
1661 uint8_t uTagRequirement,
1662 UsefulBuf MantissaBuffer,
1663 UsefulBufC *pMantissa,
1664 bool *pbMantissaIsNegative,
1665 int64_t *pnExponent);
1666
1667 void
1668 QCBORDecode_GetBigFloatBigInMapN(QCBORDecodeContext *pCtx,
1669 int64_t nLabel,
1670 uint8_t uTagRequirement,
1671 UsefulBuf MantissaBuffer,
1672 UsefulBufC *pMantissa,
1673 bool *pbMantissaIsNegative,
1674 int64_t *pnExponent);
1675
1676 void
1677 QCBORDecode_GetBigFloatBigInMapSZ(QCBORDecodeContext *pCtx,
1678 const char *szLabel,
1679 uint8_t uTagRequirement,
1680 UsefulBuf MantissaBuffer,
1681 UsefulBufC *pMantissa,
1682 bool *pbMantissaIsNegative,
1683 int64_t *pnExponent);
1684 #endif /* #ifndef QCBOR_DISABLE_EXP_AND_MANTISSA */
1685
1686
1687
1688
1689 /**
1690 * @brief Decode the next item as a URI.
1691 *
1692 * @param[in] pCtx The decode context.
1693 * @param[in] uTagRequirement One of @c QCBOR_TAG_REQUIREMENT_XXX.
1694 * @param[out] pURI The decoded URI.
1695 *
1696 * This decodes a standard CBOR URI tag, integer tag number of 32, or
1697 * encoded CBOR that is not a tag, that is a URI encoded in a text
1698 * string.
1699 *
1700 * Please see @ref Decode-Errors-Overview "Decode Errors Overview".
1701 *
1702 * See @ref Tag-Usage for discussion on tag requirements.
1703 *
1704 * See also @ref CBOR_TAG_URI, QCBOREncode_AddURI() and
1705 * @ref QCBOR_TYPE_URI.
1706 */
1707 static void
1708 QCBORDecode_GetURI(QCBORDecodeContext *pCtx,
1709 uint8_t uTagRequirement,
1710 UsefulBufC *pURI);
1711
1712 static void
1713 QCBORDecode_GetURIInMapN(QCBORDecodeContext *pCtx,
1714 int64_t nLabel,
1715 uint8_t uTagRequirement,
1716 UsefulBufC *pURI);
1717
1718 static void
1719 QCBORDecode_GetURIInMapSZ(QCBORDecodeContext *pCtx,
1720 const char * szLabel,
1721 uint8_t uTagRequirement,
1722 UsefulBufC *pURI);
1723
1724
1725 /**
1726 * @brief Decode the next item as base64 encoded text.
1727 *
1728 * @param[in] pCtx The decode context.
1729 * @param[in] uTagRequirement One of @c QCBOR_TAG_REQUIREMENT_XXX.
1730 * @param[out] pB64Text The decoded base64 text.
1731 *
1732 * This decodes a standard CBOR base64 tag, integer tag number of 34,
1733 * or encoded CBOR that is not a tag, that is base64 encoded bytes
1734 * encoded in a text string.
1735 *
1736 * Please see @ref Decode-Errors-Overview "Decode Errors Overview".
1737 *
1738 * See @ref Tag-Usage for discussion on tag requirements.
1739 *
1740 * Note that this does not actually remove the base64 encoding.
1741 *
1742 * See also @ref CBOR_TAG_B64, QCBOREncode_AddB64Text() and
1743 * @ref QCBOR_TYPE_BASE64.
1744 */
1745 static void
1746 QCBORDecode_GetB64(QCBORDecodeContext *pCtx,
1747 uint8_t uTagRequirement,
1748 UsefulBufC *pB64Text);
1749
1750 static void
1751 QCBORDecode_GetB64InMapN(QCBORDecodeContext *pCtx,
1752 int64_t nLabel,
1753 uint8_t uTagRequirement,
1754 UsefulBufC *pB64Text);
1755
1756 static void
1757 QCBORDecode_GetB64InMapSZ(QCBORDecodeContext *pCtx,
1758 const char *szLabel,
1759 uint8_t uTagRequirement,
1760 UsefulBufC *pB64Text);
1761
1762 /**
1763 * @brief Decode the next item as base64URL encoded text.
1764 *
1765 * @param[in] pCtx The decode context.
1766 * @param[in] uTagRequirement One of @c QCBOR_TAG_REQUIREMENT_XXX.
1767 * @param[out] pB64Text The decoded base64 text.
1768 *
1769 * This decodes a standard CBOR base64url tag, integer tag number of
1770 * 33, or encoded CBOR that is not a tag, that is base64url encoded
1771 * bytes encoded in a text string.
1772 *
1773 * Please see @ref Decode-Errors-Overview "Decode Errors Overview".
1774 *
1775 * See @ref Tag-Usage for discussion on tag requirements.
1776 *
1777 * Note that this does not actually remove the base64url encoding.
1778 *
1779 * See also @ref CBOR_TAG_B64URL, QCBOREncode_AddB64URLText() and
1780 * @ref QCBOR_TYPE_BASE64URL.
1781 */
1782 static void
1783 QCBORDecode_GetB64URL(QCBORDecodeContext *pCtx,
1784 uint8_t uTagRequirement,
1785 UsefulBufC *pB64Text);
1786
1787 static void
1788 QCBORDecode_GetB64URLInMapN(QCBORDecodeContext *pCtx,
1789 int64_t nLabel,
1790 uint8_t uTagRequirement,
1791 UsefulBufC *pB64Text);
1792
1793 static void
1794 QCBORDecode_GetB64URLInMapSZ(QCBORDecodeContext *pCtx,
1795 const char *szLabel,
1796 uint8_t uTagRequirement,
1797 UsefulBufC *pB64Text);
1798
1799 /**
1800 * @brief Decode the next item as a regular expression.
1801 *
1802 * @param[in] pCtx The decode context.
1803 * @param[in] uTagRequirement One of @c QCBOR_TAG_REQUIREMENT_XXX.
1804 * @param[out] pRegex The decoded regular expression.
1805 *
1806 * This decodes a standard CBOR regex tag, integer tag number of 35,
1807 * or encoded CBOR that is not a tag, that is a PERL-compatible
1808 * regular expression encoded in a text string.
1809 *
1810 * Please see @ref Decode-Errors-Overview "Decode Errors Overview".
1811 *
1812 * See @ref Tag-Usage for discussion on tag requirements.
1813 *
1814 * See also @ref CBOR_TAG_REGEX, QCBOREncode_AddRegex() and
1815 * @ref QCBOR_TYPE_REGEX.
1816 */
1817 static void
1818 QCBORDecode_GetRegex(QCBORDecodeContext *pCtx,
1819 uint8_t uTagRequirement,
1820 UsefulBufC *pRegex);
1821
1822 static void
1823 QCBORDecode_GetRegexInMapN(QCBORDecodeContext *pCtx,
1824 int64_t nLabel,
1825 uint8_t uTagRequirement,
1826 UsefulBufC *pRegex);
1827
1828 static void
1829 QCBORDecode_GetRegexInMapSZ(QCBORDecodeContext *pCtx,
1830 const char * szLabel,
1831 uint8_t uTagRequirement,
1832 UsefulBufC *pRegex);
1833
1834
1835 /**
1836 * @brief Decode the next item as a MIME message.
1837 *
1838 * @param[in] pCtx The decode context.
1839 * @param[in] uTagRequirement One of @c QCBOR_TAG_REQUIREMENT_XXX.
1840 * @param[out] pMessage The decoded regular expression.
1841 * @param[out] pbIsTag257 @c true if tag was 257. May be @c NULL.
1842 *
1843 * This decodes the standard CBOR MIME and binary MIME tags, integer
1844 * tag numbers of 36 or 257, or encoded CBOR that is not a tag, that
1845 * is a MIME message encoded in a text or binary string.
1846 *
1847 * Please see @ref Decode-Errors-Overview "Decode Errors Overview".
1848 *
1849 * See @ref Tag-Usage for discussion on tag requirements.
1850 *
1851 * The MIME message itself is not parsed.
1852 *
1853 * This decodes both tag 36 and 257. If it is tag 257, pbIsTag257 is
1854 * @c true. The difference between the two is that tag 36 is utf8 and
1855 * tag 257 is a byte string that can carry binary MIME. QCBOR
1856 * processes them exactly the same. Possibly the difference can be
1857 * ignored. NULL can be passed to have no value returned.
1858 *
1859 * See also @ref CBOR_TAG_MIME, @ref CBOR_TAG_BINARY_MIME,
1860 * QCBOREncode_AddTMIMEData(), @ref QCBOR_TYPE_MIME and
1861 * @ref QCBOR_TYPE_BINARY_MIME.
1862 *
1863 * This does no translation of line endings. See QCBOREncode_AddText()
1864 * for a discussion of line endings in CBOR.
1865 */
1866 static void
1867 QCBORDecode_GetMIMEMessage(QCBORDecodeContext *pCtx,
1868 uint8_t uTagRequirement,
1869 UsefulBufC *pMessage,
1870 bool *pbIsTag257);
1871
1872 static void
1873 QCBORDecode_GetMIMEMessageInMapN(QCBORDecodeContext *pCtx,
1874 int64_t nLabel,
1875 uint8_t uTagRequirement,
1876 UsefulBufC *pMessage,
1877 bool *pbIsTag257);
1878
1879
1880 static void
1881 QCBORDecode_GetMIMEMessageInMapSZ(QCBORDecodeContext *pCtx,
1882 const char *szLabel,
1883 uint8_t uTagRequirement,
1884 UsefulBufC *pMessage,
1885 bool *pbIsTag257);
1886
1887 /**
1888 * @brief Decode the next item as a UUID.
1889 *
1890 * @param[in] pCtx The decode context.
1891 * @param[in] uTagRequirement One of @c QCBOR_TAG_REQUIREMENT_XXX.
1892 * @param[out] pUUID The decoded UUID
1893 *
1894 * This decodes a standard CBOR UUID tag, integer tag number of 37, or
1895 * encoded CBOR that is not a tag, that is a UUID encoded in a byte
1896 * string.
1897 *
1898 * Please see @ref Decode-Errors-Overview "Decode Errors Overview".
1899 *
1900 * See @ref Tag-Usage for discussion on tag requirements.
1901 *
1902 * See also @ref CBOR_TAG_BIN_UUID, QCBOREncode_AddBinaryUUID() and
1903 * @ref QCBOR_TYPE_UUID.
1904 */
1905 static void
1906 QCBORDecode_GetBinaryUUID(QCBORDecodeContext *pCtx,
1907 uint8_t uTagRequirement,
1908 UsefulBufC *pUUID);
1909
1910 static void
1911 QCBORDecode_GetBinaryUUIDInMapN(QCBORDecodeContext *pCtx,
1912 int64_t nLabel,
1913 uint8_t uTagRequirement,
1914 UsefulBufC *pUUID);
1915
1916 static void
1917 QCBORDecode_GetBinaryUUIDInMapSZ(QCBORDecodeContext *pCtx,
1918 const char *szLabel,
1919 uint8_t uTagRequirement,
1920 UsefulBufC *pUUID);
1921
1922
1923
1924 /**
1925 * @brief Decode some byte-string wrapped CBOR.
1926 *
1927 * @param[in] pCtx The decode context.
1928 * @param[in] uTagRequirement One of @c QCBOR_TAG_REQUIREMENT_XXX.
1929 * @param[out] pBstr Pointer and length of byte-string wrapped CBOR (optional).
1930 *
1931 * This is for use on some CBOR that has been wrapped in a byte
1932 * string. There are several ways that this can occur.
1933 *
1934 * First is tag 24 and tag 63. Tag 24 wraps a single CBOR data item
1935 * and 63 a CBOR sequence. This implementation doesn't distinguish
1936 * between the two (it would be more code and doesn't seem important).
1937 *
1938 * The @ref Tag-Usage discussion on the tag requirement applies here
1939 * just the same as any other tag.
1940 *
1941 * In other cases, CBOR is wrapped in a byte string, but it is
1942 * identified as CBOR by other means. The contents of a COSE payload
1943 * are one example of that. They can be identified by the COSE content
1944 * type, or they can be identified as CBOR indirectly by the protocol
1945 * that uses COSE. for example, if a blob of CBOR is identified as a
1946 * CWT, then the COSE payload is CBOR. To enter into CBOR of this
1947 * type use the @ref QCBOR_TAG_REQUIREMENT_NOT_A_TAG as the \c
1948 * uTagRequirement argument.
1949 *
1950 * Note that byte string wrapped CBOR can also be decoded by getting
1951 * the byte string with QCBORDecode_GetItem() or
1952 * QCBORDecode_GetByteString() and feeding it into another instance of
1953 * QCBORDecode. Doing it with this function has the advantage of using
1954 * less memory as another instance of QCBORDecode is not necessary.
1955 *
1956 * When the wrapped CBOR is entered with this function, the pre-order
1957 * traversal and such are bounded to the wrapped
1958 * CBOR. QCBORDecode_ExitBstrWrapped() must be called to resume
1959 * processing CBOR outside the wrapped CBOR.
1960 *
1961 * This does not work on indefinite-length strings. The
1962 * error @ref QCBOR_ERR_CANNOT_ENTER_ALLOCATED_STRING will be set.
1963 *
1964 * If @c pBstr is not @c NULL the pointer and length of the wrapped
1965 * CBOR will be returned. This is usually not needed, but sometimes
1966 * useful, particularly in the case of verifying signed data like the
1967 * COSE payload. This is usually the pointer and length of the data is
1968 * that is hashed or MACed.
1969 *
1970 * Please see @ref Decode-Errors-Overview "Decode Errors Overview".
1971 *
1972 * See also QCBORDecode_ExitBstrWrapped(), QCBORDecode_EnterMap() and
1973 * QCBORDecode_EnterArray().
1974 */
1975 void
1976 QCBORDecode_EnterBstrWrapped(QCBORDecodeContext *pCtx,
1977 uint8_t uTagRequirement,
1978 UsefulBufC *pBstr);
1979
1980 void
1981 QCBORDecode_EnterBstrWrappedFromMapN(QCBORDecodeContext *pCtx,
1982 int64_t nLabel,
1983 uint8_t uTagRequirement,
1984 UsefulBufC *pBstr);
1985
1986 void
1987 QCBORDecode_EnterBstrWrappedFromMapSZ(QCBORDecodeContext *pCtx,
1988 const char *szLabel,
1989 uint8_t uTagRequirement,
1990 UsefulBufC *pBstr);
1991
1992
1993 /**
1994 * @brief Exit some bstr-wrapped CBOR has been enetered.
1995 *
1996 * @param[in] pCtx The decode context.
1997 *
1998 * Bstr-wrapped CBOR must have been entered for this to succeed.
1999 *
2000 * The items in the wrapped CBOR that was entered do not have to have
2001 * been consumed for this to succeed.
2002 *
2003 * The this sets the traversal cursor to the item after the
2004 * byte string that was exited.
2005 */
2006 void
2007 QCBORDecode_ExitBstrWrapped(QCBORDecodeContext *pCtx);
2008
2009
2010
2011
2012 /* ===========================================================================
2013 BEGINNING OF PRIVATE INLINE IMPLEMENTATION
2014 ========================================================================== */
2015
2016
2017 /* Semi-private funcion used by public inline functions. See qcbor_decode.c */
2018 void
2019 QCBORDecode_Private_GetUInt64Convert(QCBORDecodeContext *pCtx,
2020 uint32_t uConvertTypes,
2021 uint64_t *puValue,
2022 QCBORItem *pItem);
2023
2024
2025 /* Semi-private funcion used by public inline functions. See qcbor_decode.c */
2026 void
2027 QCBORDecode_Private_GetUInt64ConvertInMapN(QCBORDecodeContext *pCtx,
2028 int64_t nLabel,
2029 uint32_t uConvertTypes,
2030 uint64_t *puValue,
2031 QCBORItem *pItem);
2032
2033
2034 /* Semi-private funcion used by public inline functions. See qcbor_decode.c */
2035 void
2036 QCBORDecode_Private_GetUInt64ConvertInMapSZ(QCBORDecodeContext *pCtx,
2037 const char *szLabel,
2038 uint32_t uConvertTypes,
2039 uint64_t *puValue,
2040 QCBORItem *pItem);
2041
2042 /* Semi-private funcion used by public inline functions. See qcbor_decode.c */
2043 void
2044 QCBORDecode_Private_EnterBoundedMapOrArray(QCBORDecodeContext *pCtx,
2045 uint8_t uType,
2046 QCBORItem *pItem);
2047
2048 /* Semi-private funcion used by public inline functions. See qcbor_decode.c */
2049 void
2050 QCBORDecode_Private_ExitBoundedMapOrArray(QCBORDecodeContext *pCtx,
2051 uint8_t uType);
2052
2053
2054 /* Semi-private funcion used by public inline functions. See qcbor_decode.c */
2055 void
2056 QCBORDecode_Private_GetInt64Convert(QCBORDecodeContext *pCtx,
2057 uint32_t uConvertTypes,
2058 int64_t *pnValue,
2059 QCBORItem *pItem);
2060
2061 /* Semi-private funcion used by public inline functions. See qcbor_decode.c */
2062 void
2063 QCBORDecode_Private_GetInt64ConvertInMapN(QCBORDecodeContext *pCtx,
2064 int64_t nLabel,
2065 uint32_t uConvertTypes,
2066 int64_t *pnValue,
2067 QCBORItem *pItem);
2068
2069 /* Semi-private funcion used by public inline functions. See qcbor_decode.c */
2070 void
2071 QCBORDecode_Private_GetInt64ConvertInMapSZ(QCBORDecodeContext *pCtx,
2072 const char *szLabel,
2073 uint32_t uConvertTypes,
2074 int64_t *pnValue,
2075 QCBORItem *pItem);
2076
2077
2078 #ifndef USEFULBUF_DISABLE_ALL_FLOAT
2079 /* Semi-private funcion used by public inline functions. See qcbor_decode.c */
2080 void
2081 QCBORDecode_Private_GetDoubleConvert(QCBORDecodeContext *pCtx,
2082 uint32_t uConvertTypes,
2083 double *pValue,
2084 QCBORItem *pItem);
2085
2086 /* Semi-private funcion used by public inline functions. See qcbor_decode.c */
2087 void
2088 QCBORDecode_Private_GetDoubleConvertInMapN(QCBORDecodeContext *pCtx,
2089 int64_t nLabel,
2090 uint32_t uConvertTypes,
2091 double *pdValue,
2092 QCBORItem *pItem);
2093
2094 /* Semi-private funcion used by public inline functions. See qcbor_decode.c */
2095 void
2096 QCBORDecode_Private_GetDoubleConvertInMapSZ(QCBORDecodeContext *pCtx,
2097 const char *szLabel,
2098 uint32_t uConvertTypes,
2099 double *pdValue,
2100 QCBORItem *pItem);
2101 #endif /* !USEFULBUF_DISABLE_ALL_FLOAT */
2102
2103 #define QCBOR_TAGSPEC_NUM_TYPES 4
2104 /* Semi-private data structure (which might change).
2105 *
2106 * See QCBOR_Private_CheckTagRequirement() which uses this to check the
2107 * type of an item to be decoded as a tag or tag content.
2108 *
2109 * Improvement: Carefully understand what compilers do with this,
2110 * particularly initialization and see if it can be optimized so there
2111 * is less code and maybe so it can be smaller.
2112 */
2113 typedef struct {
2114 /* One of QCBOR_TAGSPEC_MATCH_xxx */
2115 uint8_t uTagRequirement;
2116 /* The tagged type translated into QCBOR_TYPE_XXX. Used to match
2117 * explicit tagging */
2118 uint8_t uTaggedTypes[QCBOR_TAGSPEC_NUM_TYPES];
2119 /* The types of the content, which are used to match implicit
2120 * tagging */
2121 uint8_t uAllowedContentTypes[QCBOR_TAGSPEC_NUM_TYPES];
2122 } QCBOR_Private_TagSpec;
2123
2124
2125 /* Semi-private funcion used by public inline functions. See qcbor_decode.c */
2126 void
2127 QCBORDecode_Private_GetTaggedString(QCBORDecodeContext *pCtx,
2128 QCBOR_Private_TagSpec TagSpec,
2129 UsefulBufC *pBstr);
2130
2131
2132 /* Semi-private funcion used by public inline functions. See qcbor_decode.c */
2133 void
2134 QCBORDecode_Private_GetTaggedStringInMapN(QCBORDecodeContext *pCtx,
2135 int64_t nLabel,
2136 QCBOR_Private_TagSpec TagSpec,
2137 UsefulBufC *pString);
2138
2139 /* Semi-private funcion used by public inline functions. See qcbor_decode.c */
2140 void
2141 QCBORDecode_Private_GetTaggedStringInMapSZ(QCBORDecodeContext *pCtx,
2142 const char *szLabel,
2143 QCBOR_Private_TagSpec TagSpec,
2144 UsefulBufC *pString);
2145
2146
2147 /* Semi-private funcion used by public inline functions. See qcbor_decode.c */
2148 QCBORError
2149 QCBORDecode_Private_GetMIME(uint8_t uTagRequirement,
2150 const QCBORItem *pItem,
2151 UsefulBufC *pMessage,
2152 bool *pbIsTag257);
2153
2154
2155
2156
2157
2158 static inline void
QCBORDecode_GetUInt64Convert(QCBORDecodeContext * pMe,const uint32_t uConvertTypes,uint64_t * puValue)2159 QCBORDecode_GetUInt64Convert(QCBORDecodeContext *pMe,
2160 const uint32_t uConvertTypes,
2161 uint64_t *puValue)
2162 {
2163 QCBORItem Item;
2164 QCBORDecode_Private_GetUInt64Convert(pMe, uConvertTypes, puValue, &Item);
2165 }
2166
2167 static inline void
QCBORDecode_GetUInt64ConvertInMapN(QCBORDecodeContext * pMe,const int64_t nLabel,const uint32_t uConvertTypes,uint64_t * puValue)2168 QCBORDecode_GetUInt64ConvertInMapN(QCBORDecodeContext *pMe,
2169 const int64_t nLabel,
2170 const uint32_t uConvertTypes,
2171 uint64_t *puValue)
2172 {
2173 QCBORItem Item;
2174 QCBORDecode_Private_GetUInt64ConvertInMapN(pMe,
2175 nLabel,
2176 uConvertTypes,
2177 puValue,
2178 &Item);
2179 }
2180
2181 static inline void
QCBORDecode_GetUInt64ConvertInMapSZ(QCBORDecodeContext * pMe,const char * szLabel,const uint32_t uConvertTypes,uint64_t * puValue)2182 QCBORDecode_GetUInt64ConvertInMapSZ(QCBORDecodeContext *pMe,
2183 const char *szLabel,
2184 const uint32_t uConvertTypes,
2185 uint64_t *puValue)
2186 {
2187 QCBORItem Item;
2188 QCBORDecode_Private_GetUInt64ConvertInMapSZ(pMe,
2189 szLabel,
2190 uConvertTypes,
2191 puValue,
2192 &Item);
2193 }
2194
2195 static inline void
QCBORDecode_GetUInt64(QCBORDecodeContext * pMe,uint64_t * puValue)2196 QCBORDecode_GetUInt64(QCBORDecodeContext *pMe, uint64_t *puValue)
2197 {
2198 QCBORDecode_GetUInt64Convert(pMe, QCBOR_CONVERT_TYPE_XINT64, puValue);
2199 }
2200
2201 static inline void
QCBORDecode_GetUInt64InMapN(QCBORDecodeContext * pMe,const int64_t nLabel,uint64_t * puValue)2202 QCBORDecode_GetUInt64InMapN(QCBORDecodeContext *pMe,
2203 const int64_t nLabel,
2204 uint64_t *puValue)
2205 {
2206 QCBORDecode_GetUInt64ConvertInMapN(pMe,
2207 nLabel,
2208 QCBOR_CONVERT_TYPE_XINT64,
2209 puValue);
2210 }
2211
2212 static inline void
QCBORDecode_GetUInt64InMapSZ(QCBORDecodeContext * pMe,const char * szLabel,uint64_t * puValue)2213 QCBORDecode_GetUInt64InMapSZ(QCBORDecodeContext *pMe,
2214 const char *szLabel,
2215 uint64_t *puValue)
2216 {
2217 QCBORDecode_GetUInt64ConvertInMapSZ(pMe,
2218 szLabel,
2219 QCBOR_CONVERT_TYPE_XINT64,
2220 puValue);
2221 }
2222
2223
2224 static inline void
QCBORDecode_EnterMap(QCBORDecodeContext * pMe,QCBORItem * pItem)2225 QCBORDecode_EnterMap(QCBORDecodeContext *pMe, QCBORItem *pItem) {
2226 QCBORDecode_Private_EnterBoundedMapOrArray(pMe, QCBOR_TYPE_MAP, pItem);
2227 }
2228
2229 static inline void
QCBORDecode_EnterArray(QCBORDecodeContext * pMe,QCBORItem * pItem)2230 QCBORDecode_EnterArray(QCBORDecodeContext *pMe, QCBORItem *pItem) {
2231 QCBORDecode_Private_EnterBoundedMapOrArray(pMe, QCBOR_TYPE_ARRAY, pItem);
2232 }
2233
2234
2235 static inline void
QCBORDecode_ExitArray(QCBORDecodeContext * pMe)2236 QCBORDecode_ExitArray(QCBORDecodeContext *pMe)
2237 {
2238 QCBORDecode_Private_ExitBoundedMapOrArray(pMe, QCBOR_TYPE_ARRAY);
2239 }
2240
2241 static inline void
QCBORDecode_ExitMap(QCBORDecodeContext * pMe)2242 QCBORDecode_ExitMap(QCBORDecodeContext *pMe)
2243 {
2244 QCBORDecode_Private_ExitBoundedMapOrArray(pMe, QCBOR_TYPE_MAP);
2245 }
2246
2247
2248 /* Semi-private funcion used by public inline functions. See qcbor_decode.c */
2249 void
2250 QCBORDecode_Private_GetArrayOrMap(QCBORDecodeContext *pCtx,
2251 uint8_t uType,
2252 QCBORItem *pItem,
2253 UsefulBufC *pEncodedCBOR);
2254
2255
2256 /* Semi-private funcion used by public inline functions. See qcbor_decode.c */
2257 void
2258 QCBORDecode_Private_SearchAndGetArrayOrMap(QCBORDecodeContext *pCtx,
2259 QCBORItem *pTarget,
2260 QCBORItem *pItem,
2261 UsefulBufC *pEncodedCBOR);
2262
2263
2264 static inline void
QCBORDecode_GetArray(QCBORDecodeContext * pMe,QCBORItem * pItem,UsefulBufC * pEncodedCBOR)2265 QCBORDecode_GetArray(QCBORDecodeContext *pMe,
2266 QCBORItem *pItem,
2267 UsefulBufC *pEncodedCBOR)
2268 {
2269 QCBORDecode_Private_GetArrayOrMap(pMe, QCBOR_TYPE_ARRAY, pItem, pEncodedCBOR);
2270 }
2271
2272
2273 static inline void
QCBORDecode_GetArrayFromMapN(QCBORDecodeContext * pMe,int64_t nLabel,QCBORItem * pItem,UsefulBufC * pEncodedCBOR)2274 QCBORDecode_GetArrayFromMapN(QCBORDecodeContext *pMe,
2275 int64_t nLabel,
2276 QCBORItem *pItem,
2277 UsefulBufC *pEncodedCBOR)
2278 {
2279 QCBORItem OneItemSeach[2];
2280 OneItemSeach[0].uLabelType = QCBOR_TYPE_INT64;
2281 OneItemSeach[0].label.int64 = nLabel;
2282 OneItemSeach[0].uDataType = QCBOR_TYPE_ARRAY;
2283 OneItemSeach[1].uLabelType = QCBOR_TYPE_NONE;
2284
2285 QCBORDecode_Private_SearchAndGetArrayOrMap(pMe, OneItemSeach, pItem, pEncodedCBOR);
2286 }
2287
2288
2289 static inline void
QCBORDecode_GetArrayFromMapSZ(QCBORDecodeContext * pMe,const char * szLabel,QCBORItem * pItem,UsefulBufC * pEncodedCBOR)2290 QCBORDecode_GetArrayFromMapSZ(QCBORDecodeContext *pMe,
2291 const char *szLabel,
2292 QCBORItem *pItem,
2293 UsefulBufC *pEncodedCBOR)
2294 {
2295 #ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
2296 QCBORItem OneItemSeach[2];
2297 OneItemSeach[0].uLabelType = QCBOR_TYPE_TEXT_STRING;
2298 OneItemSeach[0].label.string = UsefulBuf_FromSZ(szLabel);
2299 OneItemSeach[0].uDataType = QCBOR_TYPE_ARRAY;
2300 OneItemSeach[1].uLabelType = QCBOR_TYPE_NONE;
2301
2302 QCBORDecode_Private_SearchAndGetArrayOrMap(pMe, OneItemSeach, pItem, pEncodedCBOR);
2303 #else
2304 (void)szLabel;
2305 (void)pItem;
2306 (void)pEncodedCBOR;
2307 pMe->uLastError = QCBOR_ERR_MAP_LABEL_TYPE;
2308 #endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
2309 }
2310
2311 static inline void
QCBORDecode_GetMap(QCBORDecodeContext * pMe,QCBORItem * pItem,UsefulBufC * pEncodedCBOR)2312 QCBORDecode_GetMap(QCBORDecodeContext *pMe,
2313 QCBORItem *pItem,
2314 UsefulBufC *pEncodedCBOR)
2315 {
2316 QCBORDecode_Private_GetArrayOrMap(pMe, QCBOR_TYPE_MAP, pItem, pEncodedCBOR);
2317 }
2318
2319
2320 static inline void
QCBORDecode_GetMapFromMapN(QCBORDecodeContext * pMe,int64_t nLabel,QCBORItem * pItem,UsefulBufC * pEncodedCBOR)2321 QCBORDecode_GetMapFromMapN(QCBORDecodeContext *pMe,
2322 int64_t nLabel,
2323 QCBORItem *pItem,
2324 UsefulBufC *pEncodedCBOR)
2325 {
2326 QCBORItem OneItemSeach[2];
2327 OneItemSeach[0].uLabelType = QCBOR_TYPE_INT64;
2328 OneItemSeach[0].label.int64 = nLabel;
2329 OneItemSeach[0].uDataType = QCBOR_TYPE_MAP;
2330 OneItemSeach[1].uLabelType = QCBOR_TYPE_NONE;
2331
2332 QCBORDecode_Private_SearchAndGetArrayOrMap(pMe, OneItemSeach, pItem, pEncodedCBOR);
2333 }
2334
2335
2336 static inline void
QCBORDecode_GetMapFromMapSZ(QCBORDecodeContext * pMe,const char * szLabel,QCBORItem * pItem,UsefulBufC * pEncodedCBOR)2337 QCBORDecode_GetMapFromMapSZ(QCBORDecodeContext *pMe,
2338 const char *szLabel,
2339 QCBORItem *pItem,
2340 UsefulBufC *pEncodedCBOR)
2341 {
2342 #ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
2343 QCBORItem OneItemSeach[2];
2344 OneItemSeach[0].uLabelType = QCBOR_TYPE_TEXT_STRING;
2345 OneItemSeach[0].label.string = UsefulBuf_FromSZ(szLabel);
2346 OneItemSeach[0].uDataType = QCBOR_TYPE_MAP;
2347 OneItemSeach[1].uLabelType = QCBOR_TYPE_NONE;
2348
2349 QCBORDecode_Private_SearchAndGetArrayOrMap(pMe, OneItemSeach, pItem, pEncodedCBOR);
2350 #else
2351 (void)szLabel;
2352 (void)pItem;
2353 (void)pEncodedCBOR;
2354 pMe->uLastError = QCBOR_ERR_MAP_LABEL_TYPE;
2355 #endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
2356 }
2357
2358
2359
2360 static inline void
QCBORDecode_GetInt64Convert(QCBORDecodeContext * pMe,const uint32_t uConvertTypes,int64_t * pnValue)2361 QCBORDecode_GetInt64Convert(QCBORDecodeContext *pMe,
2362 const uint32_t uConvertTypes,
2363 int64_t *pnValue)
2364 {
2365 QCBORItem Item;
2366 QCBORDecode_Private_GetInt64Convert(pMe, uConvertTypes, pnValue, &Item);
2367 }
2368
2369 static inline void
QCBORDecode_GetInt64ConvertInMapN(QCBORDecodeContext * pMe,const int64_t nLabel,const uint32_t uConvertTypes,int64_t * pnValue)2370 QCBORDecode_GetInt64ConvertInMapN(QCBORDecodeContext *pMe,
2371 const int64_t nLabel,
2372 const uint32_t uConvertTypes,
2373 int64_t *pnValue)
2374 {
2375 QCBORItem Item;
2376 QCBORDecode_Private_GetInt64ConvertInMapN(pMe,
2377 nLabel,
2378 uConvertTypes,
2379 pnValue,
2380 &Item);
2381 }
2382
2383 static inline void
QCBORDecode_GetInt64ConvertInMapSZ(QCBORDecodeContext * pMe,const char * szLabel,const uint32_t uConvertTypes,int64_t * pnValue)2384 QCBORDecode_GetInt64ConvertInMapSZ(QCBORDecodeContext *pMe,
2385 const char *szLabel,
2386 const uint32_t uConvertTypes,
2387 int64_t *pnValue)
2388 {
2389 QCBORItem Item;
2390 QCBORDecode_Private_GetInt64ConvertInMapSZ(pMe,
2391 szLabel,
2392 uConvertTypes,
2393 pnValue,
2394 &Item);
2395 }
2396
2397 static inline void
QCBORDecode_GetInt64(QCBORDecodeContext * pMe,int64_t * pnValue)2398 QCBORDecode_GetInt64(QCBORDecodeContext *pMe, int64_t *pnValue)
2399 {
2400 QCBORDecode_GetInt64Convert(pMe, QCBOR_CONVERT_TYPE_XINT64, pnValue);
2401 }
2402
2403 static inline void
QCBORDecode_GetInt64InMapN(QCBORDecodeContext * pMe,const int64_t nLabel,int64_t * pnValue)2404 QCBORDecode_GetInt64InMapN(QCBORDecodeContext *pMe,
2405 const int64_t nLabel,
2406 int64_t *pnValue)
2407 {
2408 QCBORDecode_GetInt64ConvertInMapN(pMe,
2409 nLabel,
2410 QCBOR_CONVERT_TYPE_XINT64,
2411 pnValue);
2412 }
2413
2414 static inline void
QCBORDecode_GetInt64InMapSZ(QCBORDecodeContext * pMe,const char * szLabel,int64_t * pnValue)2415 QCBORDecode_GetInt64InMapSZ(QCBORDecodeContext *pMe,
2416 const char *szLabel,
2417 int64_t *pnValue)
2418 {
2419 QCBORDecode_GetInt64ConvertInMapSZ(pMe,
2420 szLabel,
2421 QCBOR_CONVERT_TYPE_XINT64,
2422 pnValue);
2423 }
2424
2425
2426
2427
2428
2429 #ifndef USEFULBUF_DISABLE_ALL_FLOAT
2430 static inline void
QCBORDecode_GetDoubleConvert(QCBORDecodeContext * pMe,const uint32_t uConvertTypes,double * pdValue)2431 QCBORDecode_GetDoubleConvert(QCBORDecodeContext *pMe,
2432 const uint32_t uConvertTypes,
2433 double *pdValue)
2434 {
2435 QCBORItem Item;
2436 QCBORDecode_Private_GetDoubleConvert(pMe, uConvertTypes, pdValue, &Item);
2437 }
2438
2439 static inline void
QCBORDecode_GetDoubleConvertInMapN(QCBORDecodeContext * pMe,const int64_t nLabel,uint32_t uConvertTypes,double * pdValue)2440 QCBORDecode_GetDoubleConvertInMapN(QCBORDecodeContext *pMe,
2441 const int64_t nLabel,
2442 uint32_t uConvertTypes,
2443 double *pdValue)
2444 {
2445 QCBORItem Item;
2446 QCBORDecode_Private_GetDoubleConvertInMapN(pMe,
2447 nLabel,
2448 uConvertTypes,
2449 pdValue,
2450 &Item);
2451 }
2452
2453 static inline void
QCBORDecode_GetDoubleConvertInMapSZ(QCBORDecodeContext * pMe,const char * szLabel,const uint32_t uConvertTypes,double * pdValue)2454 QCBORDecode_GetDoubleConvertInMapSZ(QCBORDecodeContext *pMe,
2455 const char *szLabel,
2456 const uint32_t uConvertTypes,
2457 double *pdValue)
2458 {
2459 QCBORItem Item;
2460 QCBORDecode_Private_GetDoubleConvertInMapSZ(pMe,
2461 szLabel,
2462 uConvertTypes,
2463 pdValue,
2464 &Item);
2465 }
2466
2467 static inline void
QCBORDecode_GetDouble(QCBORDecodeContext * pMe,double * pValue)2468 QCBORDecode_GetDouble(QCBORDecodeContext *pMe, double *pValue)
2469 {
2470 QCBORDecode_GetDoubleConvert(pMe, QCBOR_CONVERT_TYPE_FLOAT, pValue);
2471 }
2472
2473 static inline void
QCBORDecode_GetDoubleInMapN(QCBORDecodeContext * pMe,const int64_t nLabel,double * pdValue)2474 QCBORDecode_GetDoubleInMapN(QCBORDecodeContext *pMe,
2475 const int64_t nLabel,
2476 double *pdValue)
2477 {
2478 QCBORDecode_GetDoubleConvertInMapN(pMe,
2479 nLabel,
2480 QCBOR_CONVERT_TYPE_FLOAT,
2481 pdValue);
2482 }
2483
2484 static inline void
QCBORDecode_GetDoubleInMapSZ(QCBORDecodeContext * pMe,const char * szLabel,double * pdValue)2485 QCBORDecode_GetDoubleInMapSZ(QCBORDecodeContext *pMe,
2486 const char *szLabel,
2487 double *pdValue)
2488 {
2489 QCBORDecode_GetDoubleConvertInMapSZ(pMe,
2490 szLabel,
2491 QCBOR_CONVERT_TYPE_FLOAT,
2492 pdValue);
2493 }
2494 #endif /* USEFULBUF_DISABLE_ALL_FLOAT */
2495
2496
2497
2498
2499
2500 static inline void
QCBORDecode_GetByteString(QCBORDecodeContext * pMe,UsefulBufC * pValue)2501 QCBORDecode_GetByteString(QCBORDecodeContext *pMe, UsefulBufC *pValue)
2502 {
2503 // Complier should make this just a 64-bit integer parameter
2504 const QCBOR_Private_TagSpec TagSpec =
2505 {
2506 QCBOR_TAG_REQUIREMENT_NOT_A_TAG,
2507 {QCBOR_TYPE_BYTE_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE},
2508 {QCBOR_TYPE_BYTE_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
2509 };
2510
2511 QCBORDecode_Private_GetTaggedString(pMe, TagSpec, pValue);
2512 }
2513
2514 static inline void
QCBORDecode_GetByteStringInMapN(QCBORDecodeContext * pMe,const int64_t nLabel,UsefulBufC * pBstr)2515 QCBORDecode_GetByteStringInMapN(QCBORDecodeContext *pMe,
2516 const int64_t nLabel,
2517 UsefulBufC *pBstr)
2518 {
2519 const QCBOR_Private_TagSpec TagSpec =
2520 {
2521 QCBOR_TAG_REQUIREMENT_NOT_A_TAG,
2522 {QCBOR_TYPE_BYTE_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE},
2523 {QCBOR_TYPE_BYTE_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
2524 };
2525 QCBORDecode_Private_GetTaggedStringInMapN(pMe, nLabel, TagSpec, pBstr);
2526 }
2527
2528 static inline void
QCBORDecode_GetByteStringInMapSZ(QCBORDecodeContext * pMe,const char * szLabel,UsefulBufC * pBstr)2529 QCBORDecode_GetByteStringInMapSZ(QCBORDecodeContext *pMe,
2530 const char *szLabel,
2531 UsefulBufC *pBstr)
2532 {
2533 const QCBOR_Private_TagSpec TagSpec =
2534 {
2535 QCBOR_TAG_REQUIREMENT_NOT_A_TAG,
2536 {QCBOR_TYPE_BYTE_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE},
2537 {QCBOR_TYPE_BYTE_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
2538 };
2539
2540 QCBORDecode_Private_GetTaggedStringInMapSZ(pMe, szLabel, TagSpec, pBstr);
2541 }
2542
2543
2544 static inline void
QCBORDecode_GetTextString(QCBORDecodeContext * pMe,UsefulBufC * pValue)2545 QCBORDecode_GetTextString(QCBORDecodeContext *pMe, UsefulBufC *pValue)
2546 {
2547 // Complier should make this just 64-bit integer parameter
2548 const QCBOR_Private_TagSpec TagSpec =
2549 {
2550 QCBOR_TAG_REQUIREMENT_NOT_A_TAG,
2551 {QCBOR_TYPE_TEXT_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE},
2552 {QCBOR_TYPE_TEXT_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
2553 };
2554
2555 QCBORDecode_Private_GetTaggedString(pMe, TagSpec, pValue);
2556 }
2557
2558 static inline void
QCBORDecode_GetTextStringInMapN(QCBORDecodeContext * pMe,const int64_t nLabel,UsefulBufC * pText)2559 QCBORDecode_GetTextStringInMapN(QCBORDecodeContext *pMe,
2560 const int64_t nLabel,
2561 UsefulBufC *pText)
2562 {
2563 // This TagSpec only matches text strings; it also should optimize down
2564 // to passing a 64-bit integer
2565 const QCBOR_Private_TagSpec TagSpec =
2566 {
2567 QCBOR_TAG_REQUIREMENT_NOT_A_TAG,
2568 {QCBOR_TYPE_TEXT_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE},
2569 {QCBOR_TYPE_TEXT_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
2570 };
2571
2572 QCBORDecode_Private_GetTaggedStringInMapN(pMe, nLabel, TagSpec, pText);
2573 }
2574
2575 static inline void
QCBORDecode_GetTextStringInMapSZ(QCBORDecodeContext * pMe,const char * szLabel,UsefulBufC * pText)2576 QCBORDecode_GetTextStringInMapSZ(QCBORDecodeContext *pMe,
2577 const char *szLabel,
2578 UsefulBufC *pText)
2579 {
2580 const QCBOR_Private_TagSpec TagSpec =
2581 {
2582 QCBOR_TAG_REQUIREMENT_NOT_A_TAG,
2583 {QCBOR_TYPE_TEXT_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE},
2584 {QCBOR_TYPE_TEXT_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
2585 };
2586
2587 QCBORDecode_Private_GetTaggedStringInMapSZ(pMe, szLabel, TagSpec, pText);
2588 }
2589
2590 static inline void
QCBORDecode_GetNull(QCBORDecodeContext * pMe)2591 QCBORDecode_GetNull(QCBORDecodeContext *pMe)
2592 {
2593 QCBORItem item;
2594
2595 QCBORDecode_VGetNext(pMe, &item);
2596 if(pMe->uLastError == QCBOR_SUCCESS && item.uDataType != QCBOR_TYPE_NULL) {
2597 pMe->uLastError = QCBOR_ERR_UNEXPECTED_TYPE;
2598 }
2599 }
2600
2601 static inline void
QCBORDecode_GetNullInMapN(QCBORDecodeContext * pMe,const int64_t nLabel)2602 QCBORDecode_GetNullInMapN(QCBORDecodeContext *pMe,
2603 const int64_t nLabel)
2604 {
2605 QCBORItem Item;
2606 QCBORDecode_GetItemInMapN(pMe, nLabel, QCBOR_TYPE_NULL, &Item);
2607 }
2608
2609 static inline void
QCBORDecode_GetNullInMapSZ(QCBORDecodeContext * pMe,const char * szLabel)2610 QCBORDecode_GetNullInMapSZ(QCBORDecodeContext *pMe,
2611 const char *szLabel)
2612 {
2613 QCBORItem Item;
2614 QCBORDecode_GetItemInMapSZ(pMe, szLabel, QCBOR_TYPE_NULL, &Item);
2615 }
2616
2617 static inline void
QCBORDecode_GetUndefined(QCBORDecodeContext * pMe)2618 QCBORDecode_GetUndefined(QCBORDecodeContext *pMe)
2619 {
2620 QCBORItem item;
2621
2622 QCBORDecode_VGetNext(pMe, &item);
2623 if(pMe->uLastError == QCBOR_SUCCESS && item.uDataType != QCBOR_TYPE_UNDEF) {
2624 pMe->uLastError = QCBOR_ERR_UNEXPECTED_TYPE;
2625 }
2626 }
2627
2628 static inline void
QCBORDecode_GetUndefinedInMapN(QCBORDecodeContext * pMe,const int64_t nLabel)2629 QCBORDecode_GetUndefinedInMapN(QCBORDecodeContext *pMe,
2630 const int64_t nLabel)
2631 {
2632 QCBORItem Item;
2633 QCBORDecode_GetItemInMapN(pMe, nLabel, QCBOR_TYPE_UNDEF, &Item);
2634 }
2635
2636 static inline void
QCBORDecode_GetUndefinedInMapSZ(QCBORDecodeContext * pMe,const char * szLabel)2637 QCBORDecode_GetUndefinedInMapSZ(QCBORDecodeContext *pMe,
2638 const char *szLabel)
2639 {
2640 QCBORItem Item;
2641 QCBORDecode_GetItemInMapSZ(pMe, szLabel, QCBOR_TYPE_UNDEF, &Item);
2642 }
2643
2644
2645
2646 static inline void
QCBORDecode_GetDateString(QCBORDecodeContext * pMe,const uint8_t uTagRequirement,UsefulBufC * pValue)2647 QCBORDecode_GetDateString(QCBORDecodeContext *pMe,
2648 const uint8_t uTagRequirement,
2649 UsefulBufC *pValue)
2650 {
2651 const QCBOR_Private_TagSpec TagSpec =
2652 {
2653 uTagRequirement,
2654 {QCBOR_TYPE_DATE_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE},
2655 {QCBOR_TYPE_TEXT_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
2656 };
2657
2658 QCBORDecode_Private_GetTaggedString(pMe, TagSpec, pValue);
2659 }
2660
2661 static inline void
QCBORDecode_GetDateStringInMapN(QCBORDecodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,UsefulBufC * pText)2662 QCBORDecode_GetDateStringInMapN(QCBORDecodeContext *pMe,
2663 const int64_t nLabel,
2664 const uint8_t uTagRequirement,
2665 UsefulBufC *pText)
2666 {
2667 const QCBOR_Private_TagSpec TagSpec =
2668 {
2669 uTagRequirement,
2670 {QCBOR_TYPE_DATE_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE},
2671 {QCBOR_TYPE_TEXT_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
2672 };
2673
2674 QCBORDecode_Private_GetTaggedStringInMapN(pMe, nLabel, TagSpec, pText);
2675 }
2676
2677 static inline void
QCBORDecode_GetDateStringInMapSZ(QCBORDecodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,UsefulBufC * pText)2678 QCBORDecode_GetDateStringInMapSZ(QCBORDecodeContext *pMe,
2679 const char *szLabel,
2680 const uint8_t uTagRequirement,
2681 UsefulBufC *pText)
2682 {
2683 const QCBOR_Private_TagSpec TagSpec =
2684 {
2685 uTagRequirement,
2686 {QCBOR_TYPE_DATE_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE},
2687 {QCBOR_TYPE_TEXT_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
2688 };
2689
2690 QCBORDecode_Private_GetTaggedStringInMapSZ(pMe, szLabel, TagSpec, pText);
2691 }
2692
2693 static inline void
QCBORDecode_GetDaysString(QCBORDecodeContext * pMe,const uint8_t uTagRequirement,UsefulBufC * pValue)2694 QCBORDecode_GetDaysString(QCBORDecodeContext *pMe,
2695 const uint8_t uTagRequirement,
2696 UsefulBufC *pValue)
2697 {
2698 const QCBOR_Private_TagSpec TagSpec =
2699 {
2700 uTagRequirement,
2701 {QCBOR_TYPE_DAYS_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE},
2702 {QCBOR_TYPE_TEXT_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
2703 };
2704
2705 QCBORDecode_Private_GetTaggedString(pMe, TagSpec, pValue);
2706 }
2707
2708 static inline void
QCBORDecode_GetDaysStringInMapN(QCBORDecodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,UsefulBufC * pText)2709 QCBORDecode_GetDaysStringInMapN(QCBORDecodeContext *pMe,
2710 const int64_t nLabel,
2711 const uint8_t uTagRequirement,
2712 UsefulBufC *pText)
2713 {
2714 const QCBOR_Private_TagSpec TagSpec =
2715 {
2716 uTagRequirement,
2717 {QCBOR_TYPE_DAYS_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE},
2718 {QCBOR_TYPE_TEXT_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
2719 };
2720
2721 QCBORDecode_Private_GetTaggedStringInMapN(pMe, nLabel, TagSpec, pText);
2722 }
2723
2724 static inline void
QCBORDecode_GetDaysStringInMapSZ(QCBORDecodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,UsefulBufC * pText)2725 QCBORDecode_GetDaysStringInMapSZ(QCBORDecodeContext *pMe,
2726 const char *szLabel,
2727 const uint8_t uTagRequirement,
2728 UsefulBufC *pText)
2729 {
2730 const QCBOR_Private_TagSpec TagSpec =
2731 {
2732 uTagRequirement,
2733 {QCBOR_TYPE_DAYS_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE},
2734 {QCBOR_TYPE_TEXT_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
2735 };
2736
2737 QCBORDecode_Private_GetTaggedStringInMapSZ(pMe, szLabel, TagSpec, pText);
2738 }
2739
2740
2741
2742 static inline void
QCBORDecode_GetURI(QCBORDecodeContext * pMe,const uint8_t uTagRequirement,UsefulBufC * pUUID)2743 QCBORDecode_GetURI(QCBORDecodeContext *pMe,
2744 const uint8_t uTagRequirement,
2745 UsefulBufC *pUUID)
2746 {
2747 const QCBOR_Private_TagSpec TagSpec =
2748 {
2749 uTagRequirement,
2750 {QCBOR_TYPE_URI, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE},
2751 {QCBOR_TYPE_TEXT_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
2752 };
2753
2754 QCBORDecode_Private_GetTaggedString(pMe, TagSpec, pUUID);
2755 }
2756
2757 static inline void
QCBORDecode_GetURIInMapN(QCBORDecodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,UsefulBufC * pUUID)2758 QCBORDecode_GetURIInMapN(QCBORDecodeContext *pMe,
2759 const int64_t nLabel,
2760 const uint8_t uTagRequirement,
2761 UsefulBufC *pUUID)
2762 {
2763 const QCBOR_Private_TagSpec TagSpec =
2764 {
2765 uTagRequirement,
2766 {QCBOR_TYPE_URI, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE},
2767 {QCBOR_TYPE_TEXT_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
2768 };
2769
2770 QCBORDecode_Private_GetTaggedStringInMapN(pMe, nLabel, TagSpec, pUUID);
2771 }
2772
2773 static inline void
QCBORDecode_GetURIInMapSZ(QCBORDecodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,UsefulBufC * pUUID)2774 QCBORDecode_GetURIInMapSZ(QCBORDecodeContext *pMe,
2775 const char *szLabel,
2776 const uint8_t uTagRequirement,
2777 UsefulBufC *pUUID)
2778 {
2779 const QCBOR_Private_TagSpec TagSpec =
2780 {
2781 uTagRequirement,
2782 {QCBOR_TYPE_URI, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE},
2783 {QCBOR_TYPE_TEXT_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
2784 };
2785
2786 QCBORDecode_Private_GetTaggedStringInMapSZ(pMe, szLabel, TagSpec, pUUID);
2787 }
2788
2789
2790 static inline void
QCBORDecode_GetB64(QCBORDecodeContext * pMe,const uint8_t uTagRequirement,UsefulBufC * pB64Text)2791 QCBORDecode_GetB64(QCBORDecodeContext *pMe,
2792 const uint8_t uTagRequirement,
2793 UsefulBufC *pB64Text)
2794 {
2795 const QCBOR_Private_TagSpec TagSpec =
2796 {
2797 uTagRequirement,
2798 {QCBOR_TYPE_BASE64, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE},
2799 {QCBOR_TYPE_TEXT_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
2800 };
2801
2802 QCBORDecode_Private_GetTaggedString(pMe, TagSpec, pB64Text);
2803 }
2804
2805 static inline void
QCBORDecode_GetB64InMapN(QCBORDecodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,UsefulBufC * pB64Text)2806 QCBORDecode_GetB64InMapN(QCBORDecodeContext *pMe,
2807 const int64_t nLabel,
2808 const uint8_t uTagRequirement,
2809 UsefulBufC *pB64Text)
2810 {
2811 const QCBOR_Private_TagSpec TagSpec =
2812 {
2813 uTagRequirement,
2814 {QCBOR_TYPE_BASE64, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE},
2815 {QCBOR_TYPE_TEXT_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
2816 };
2817
2818 QCBORDecode_Private_GetTaggedStringInMapN(pMe, nLabel, TagSpec, pB64Text);
2819 }
2820
2821 static inline void
QCBORDecode_GetB64InMapSZ(QCBORDecodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,UsefulBufC * pB64Text)2822 QCBORDecode_GetB64InMapSZ(QCBORDecodeContext *pMe,
2823 const char *szLabel,
2824 const uint8_t uTagRequirement,
2825 UsefulBufC *pB64Text)
2826 {
2827 const QCBOR_Private_TagSpec TagSpec =
2828 {
2829 uTagRequirement,
2830 {QCBOR_TYPE_BASE64, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE},
2831 {QCBOR_TYPE_TEXT_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
2832 };
2833 QCBORDecode_Private_GetTaggedStringInMapSZ(pMe, szLabel, TagSpec, pB64Text);
2834 }
2835
2836
2837 static inline void
QCBORDecode_GetB64URL(QCBORDecodeContext * pMe,const uint8_t uTagRequirement,UsefulBufC * pB64Text)2838 QCBORDecode_GetB64URL(QCBORDecodeContext *pMe,
2839 const uint8_t uTagRequirement,
2840 UsefulBufC *pB64Text)
2841 {
2842 const QCBOR_Private_TagSpec TagSpec =
2843 {
2844 uTagRequirement,
2845 {QCBOR_TYPE_BASE64URL, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE},
2846 {QCBOR_TYPE_TEXT_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
2847 };
2848
2849 QCBORDecode_Private_GetTaggedString(pMe, TagSpec, pB64Text);
2850 }
2851
2852 static inline void
QCBORDecode_GetB64URLInMapN(QCBORDecodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,UsefulBufC * pB64Text)2853 QCBORDecode_GetB64URLInMapN(QCBORDecodeContext *pMe,
2854 const int64_t nLabel,
2855 const uint8_t uTagRequirement,
2856 UsefulBufC *pB64Text)
2857 {
2858 const QCBOR_Private_TagSpec TagSpec =
2859 {
2860 uTagRequirement,
2861 {QCBOR_TYPE_BASE64URL, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE},
2862 {QCBOR_TYPE_TEXT_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
2863 };
2864
2865 QCBORDecode_Private_GetTaggedStringInMapN(pMe, nLabel, TagSpec, pB64Text);
2866 }
2867
2868 static inline void
QCBORDecode_GetB64URLInMapSZ(QCBORDecodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,UsefulBufC * pB64Text)2869 QCBORDecode_GetB64URLInMapSZ(QCBORDecodeContext *pMe,
2870 const char *szLabel,
2871 const uint8_t uTagRequirement,
2872 UsefulBufC *pB64Text)
2873 {
2874 const QCBOR_Private_TagSpec TagSpec =
2875 {
2876 uTagRequirement,
2877 {QCBOR_TYPE_BASE64URL, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE},
2878 {QCBOR_TYPE_TEXT_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
2879 };
2880
2881 QCBORDecode_Private_GetTaggedStringInMapSZ(pMe, szLabel, TagSpec, pB64Text);
2882 }
2883
2884
2885 static inline void
QCBORDecode_GetRegex(QCBORDecodeContext * pMe,const uint8_t uTagRequirement,UsefulBufC * pRegex)2886 QCBORDecode_GetRegex(QCBORDecodeContext *pMe,
2887 const uint8_t uTagRequirement,
2888 UsefulBufC *pRegex)
2889 {
2890 const QCBOR_Private_TagSpec TagSpec =
2891 {
2892 uTagRequirement,
2893 {QCBOR_TYPE_REGEX, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE},
2894 {QCBOR_TYPE_TEXT_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
2895 };
2896
2897 QCBORDecode_Private_GetTaggedString(pMe, TagSpec, pRegex);
2898 }
2899
2900 static inline void
QCBORDecode_GetRegexInMapN(QCBORDecodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,UsefulBufC * pRegex)2901 QCBORDecode_GetRegexInMapN(QCBORDecodeContext *pMe,
2902 const int64_t nLabel,
2903 const uint8_t uTagRequirement,
2904 UsefulBufC *pRegex)
2905 {
2906 const QCBOR_Private_TagSpec TagSpec =
2907 {
2908 uTagRequirement,
2909 {QCBOR_TYPE_REGEX, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE},
2910 {QCBOR_TYPE_TEXT_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
2911 };
2912
2913 QCBORDecode_Private_GetTaggedStringInMapN(pMe, nLabel, TagSpec, pRegex);
2914 }
2915
2916 static inline void
QCBORDecode_GetRegexInMapSZ(QCBORDecodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,UsefulBufC * pRegex)2917 QCBORDecode_GetRegexInMapSZ(QCBORDecodeContext *pMe,
2918 const char * szLabel,
2919 const uint8_t uTagRequirement,
2920 UsefulBufC *pRegex)
2921 {
2922 const QCBOR_Private_TagSpec TagSpec =
2923 {
2924 uTagRequirement,
2925 {QCBOR_TYPE_REGEX, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE},
2926 {QCBOR_TYPE_TEXT_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
2927 };
2928
2929 QCBORDecode_Private_GetTaggedStringInMapSZ(pMe, szLabel, TagSpec, pRegex);
2930 }
2931
2932
2933 static inline void
QCBORDecode_GetMIMEMessage(QCBORDecodeContext * pMe,const uint8_t uTagRequirement,UsefulBufC * pMessage,bool * pbIsTag257)2934 QCBORDecode_GetMIMEMessage(QCBORDecodeContext *pMe,
2935 const uint8_t uTagRequirement,
2936 UsefulBufC *pMessage,
2937 bool *pbIsTag257)
2938 {
2939 if(pMe->uLastError != QCBOR_SUCCESS) {
2940 /* Already in error state, do nothing */
2941 return;
2942 }
2943
2944 QCBORItem Item;
2945 QCBORError uError = QCBORDecode_GetNext(pMe, &Item);
2946 if(uError != QCBOR_SUCCESS) {
2947 pMe->uLastError = (uint8_t)uError;
2948 return;
2949 }
2950
2951 pMe->uLastError = (uint8_t)QCBORDecode_Private_GetMIME(uTagRequirement,
2952 &Item,
2953 pMessage,
2954 pbIsTag257);
2955 }
2956
2957 static inline void
QCBORDecode_GetMIMEMessageInMapN(QCBORDecodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,UsefulBufC * pMessage,bool * pbIsTag257)2958 QCBORDecode_GetMIMEMessageInMapN(QCBORDecodeContext *pMe,
2959 const int64_t nLabel,
2960 const uint8_t uTagRequirement,
2961 UsefulBufC *pMessage,
2962 bool *pbIsTag257)
2963 {
2964 QCBORItem Item;
2965 QCBORDecode_GetItemInMapN(pMe, nLabel, QCBOR_TYPE_ANY, &Item);
2966
2967 if(pMe->uLastError == QCBOR_SUCCESS) {
2968 pMe->uLastError = (uint8_t)QCBORDecode_Private_GetMIME(uTagRequirement,
2969 &Item,
2970 pMessage,
2971 pbIsTag257);
2972 }
2973 }
2974
2975 static inline void
QCBORDecode_GetMIMEMessageInMapSZ(QCBORDecodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,UsefulBufC * pMessage,bool * pbIsTag257)2976 QCBORDecode_GetMIMEMessageInMapSZ(QCBORDecodeContext *pMe,
2977 const char *szLabel,
2978 const uint8_t uTagRequirement,
2979 UsefulBufC *pMessage,
2980 bool *pbIsTag257)
2981 {
2982 QCBORItem Item;
2983 QCBORDecode_GetItemInMapSZ(pMe, szLabel, QCBOR_TYPE_ANY, &Item);
2984
2985 if(pMe->uLastError == QCBOR_SUCCESS) {
2986 pMe->uLastError = (uint8_t)QCBORDecode_Private_GetMIME(uTagRequirement,
2987 &Item,
2988 pMessage,
2989 pbIsTag257);
2990 }
2991 }
2992
2993
2994 static inline void
QCBORDecode_GetBinaryUUID(QCBORDecodeContext * pMe,const uint8_t uTagRequirement,UsefulBufC * pUUID)2995 QCBORDecode_GetBinaryUUID(QCBORDecodeContext *pMe,
2996 const uint8_t uTagRequirement,
2997 UsefulBufC *pUUID)
2998 {
2999 const QCBOR_Private_TagSpec TagSpec =
3000 {
3001 uTagRequirement,
3002 {QCBOR_TYPE_UUID, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE},
3003 {QCBOR_TYPE_BYTE_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
3004 };
3005
3006 QCBORDecode_Private_GetTaggedString(pMe, TagSpec, pUUID);
3007 }
3008
3009 static inline void
QCBORDecode_GetBinaryUUIDInMapN(QCBORDecodeContext * pMe,const int64_t nLabel,const uint8_t uTagRequirement,UsefulBufC * pUUID)3010 QCBORDecode_GetBinaryUUIDInMapN(QCBORDecodeContext *pMe,
3011 const int64_t nLabel,
3012 const uint8_t uTagRequirement,
3013 UsefulBufC *pUUID)
3014 {
3015 const QCBOR_Private_TagSpec TagSpec =
3016 {
3017 uTagRequirement,
3018 {QCBOR_TYPE_UUID, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE},
3019 {QCBOR_TYPE_BYTE_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
3020 };
3021
3022 QCBORDecode_Private_GetTaggedStringInMapN(pMe, nLabel, TagSpec, pUUID);
3023 }
3024
3025 static inline void
QCBORDecode_GetBinaryUUIDInMapSZ(QCBORDecodeContext * pMe,const char * szLabel,const uint8_t uTagRequirement,UsefulBufC * pUUID)3026 QCBORDecode_GetBinaryUUIDInMapSZ(QCBORDecodeContext *pMe,
3027 const char *szLabel,
3028 const uint8_t uTagRequirement,
3029 UsefulBufC *pUUID)
3030 {
3031 const QCBOR_Private_TagSpec TagSpec =
3032 {
3033 uTagRequirement,
3034 {QCBOR_TYPE_UUID, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE},
3035 {QCBOR_TYPE_BYTE_STRING, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
3036 };
3037
3038 QCBORDecode_Private_GetTaggedStringInMapSZ(pMe, szLabel, TagSpec, pUUID);
3039 }
3040
3041
3042 #ifdef __cplusplus
3043 }
3044 #endif
3045
3046 #endif /* qcbor_spiffy_decode_h */
3047