xref: /optee_os/core/lib/qcbor/inc/qcbor/qcbor_spiffy_decode.h (revision b586599be35c4311337a5d8db5f4b5e5c81a754d)
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