split qcbor.h into four separate headers (#34)
This is to make it much easier to read the header files.
Backwards compatibility with qcbor.h is retained, but use of qcbor/qcbor_encode.h and qcbor/qcbor_decode.h is preferred now.
Signed-off-by: Laurence Lundblade <lgl@securitytheory.com>
diff --git a/inc/qcbor.h b/inc/qcbor.h
index e5b23e6..377bade 100644
--- a/inc/qcbor.h
+++ b/inc/qcbor.h
@@ -1 +1,41 @@
-#include "qcbor/qcbor.h"
+/*==============================================================================
+ Copyright (c) 2016-2018, The Linux Foundation.
+ Copyright (c) 2018-2020, Laurence Lundblade.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors, nor the name "Laurence Lundblade" may be used to
+ endorse or promote products derived from this software without
+ specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ =============================================================================*/
+
+/**
+ * @file qcbor.h
+ *
+ * Backwards compatibility for includers of qcbor.h (which has been split
+ * into four include files).
+ */
+
+#include "qcbor/qcbor_encode.h"
+#include "qcbor/qcbor_decode.h"
diff --git a/inc/qcbor/qcbor_common.h b/inc/qcbor/qcbor_common.h
new file mode 100644
index 0000000..e926aaa
--- /dev/null
+++ b/inc/qcbor/qcbor_common.h
@@ -0,0 +1,353 @@
+/*==============================================================================
+ Copyright (c) 2016-2018, The Linux Foundation.
+ Copyright (c) 2018-2020, Laurence Lundblade.
+ All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors, nor the name "Laurence Lundblade" may be used to
+ endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ =============================================================================*/
+
+
+#ifndef qcbor_common_h
+#define qcbor_common_h
+
+
+/* Standard CBOR Major type for positive integers of various lengths */
+#define CBOR_MAJOR_TYPE_POSITIVE_INT 0
+
+/* Standard CBOR Major type for negative integer of various lengths */
+#define CBOR_MAJOR_TYPE_NEGATIVE_INT 1
+
+/* Standard CBOR Major type for an array of arbitrary 8-bit bytes. */
+#define CBOR_MAJOR_TYPE_BYTE_STRING 2
+
+/* Standard CBOR Major type for a UTF-8 string. Note this is true 8-bit UTF8
+ with no encoding and no NULL termination */
+#define CBOR_MAJOR_TYPE_TEXT_STRING 3
+
+/* Standard CBOR Major type for an ordered array of other CBOR data items */
+#define CBOR_MAJOR_TYPE_ARRAY 4
+
+/* Standard CBOR Major type for CBOR MAP. Maps an array of pairs. The
+ first item in the pair is the "label" (key, name or identfier) and the second
+ item is the value. */
+#define CBOR_MAJOR_TYPE_MAP 5
+
+/* Standard CBOR optional tagging. This tags things like dates and URLs */
+#define CBOR_MAJOR_TYPE_OPTIONAL 6
+
+/* Standard CBOR extra simple types like floats and the values true and false */
+#define CBOR_MAJOR_TYPE_SIMPLE 7
+
+
+/*
+ These are special values for the AdditionalInfo bits that are part of
+ the first byte. Mostly they encode the length of the data item.
+ */
+#define LEN_IS_ONE_BYTE 24
+#define LEN_IS_TWO_BYTES 25
+#define LEN_IS_FOUR_BYTES 26
+#define LEN_IS_EIGHT_BYTES 27
+#define ADDINFO_RESERVED1 28
+#define ADDINFO_RESERVED2 29
+#define ADDINFO_RESERVED3 30
+#define LEN_IS_INDEFINITE 31
+
+
+/*
+ 24 is a special number for CBOR. Integers and lengths
+ less than it are encoded in the same byte as the major type.
+ */
+#define CBOR_TWENTY_FOUR 24
+
+
+/*
+ Tags that are used with CBOR_MAJOR_TYPE_OPTIONAL. These
+ are types defined in RFC 7049 and some additional ones
+ in the IANA CBOR tags registry.
+ */
+/** See QCBOREncode_AddDateString(). */
+#define CBOR_TAG_DATE_STRING 0
+/** See QCBOREncode_AddDateEpoch(). */
+#define CBOR_TAG_DATE_EPOCH 1
+/** See QCBOREncode_AddPositiveBignum(). */
+#define CBOR_TAG_POS_BIGNUM 2
+/** See QCBOREncode_AddNegativeBignum(). */
+#define CBOR_TAG_NEG_BIGNUM 3
+/** CBOR tag for a two-element array representing a fraction with a
+ mantissa and base-10 scaling factor. See QCBOREncode_AddDecimalFraction()
+ and @ref expAndMantissa.
+ */
+#define CBOR_TAG_DECIMAL_FRACTION 4
+/** CBOR tag for a two-element array representing a fraction with a
+ mantissa and base-2 scaling factor. See QCBOREncode_AddBigFloat()
+ and @ref expAndMantissa. */
+#define CBOR_TAG_BIGFLOAT 5
+/** Tag for COSE format encryption with no recipient
+ identification. See [RFC 8152, COSE]
+ (https://tools.ietf.org/html/rfc8152). No API is provided for this
+ tag. */
+#define CBOR_TAG_COSE_ENCRYPTO 16
+/** Tag for COSE format MAC'd data with no recipient
+ identification. See [RFC 8152, COSE]
+ (https://tools.ietf.org/html/rfc8152). No API is provided for this
+ tag.*/
+#define CBOR_TAG_COSE_MAC0 17
+/** Tag for COSE format single signature signing. No API is provided
+ for this tag. See [RFC 8152, COSE]
+ (https://tools.ietf.org/html/rfc8152). */
+#define CBOR_TAG_COSE_SIGN1 18
+/** A hint that the following byte string should be encoded in
+ Base64URL when converting to JSON or similar text-based
+ representations. Call @c
+ QCBOREncode_AddTag(pCtx,CBOR_TAG_ENC_AS_B64URL) before the call to
+ QCBOREncode_AddBytes(). */
+#define CBOR_TAG_ENC_AS_B64URL 21
+/** A hint that the following byte string should be encoded in Base64
+ when converting to JSON or similar text-based
+ representations. Call @c
+ QCBOREncode_AddTag(pCtx,CBOR_TAG_ENC_AS_B64) before the call to
+ QCBOREncode_AddBytes(). */
+#define CBOR_TAG_ENC_AS_B64 22
+/** A hint that the following byte string should be encoded in base-16
+ format per [RFC 4648] (https://tools.ietf.org/html/rfc4648) when
+ converting to JSON or similar text-based
+ representations. Essentially, Base-16 encoding is the standard
+ case- insensitive hex encoding and may be referred to as
+ "hex". Call @c QCBOREncode_AddTag(pCtx,CBOR_TAG_ENC_AS_B16) before
+ the call to QCBOREncode_AddBytes(). */
+#define CBOR_TAG_ENC_AS_B16 23
+/** Tag to indicate a byte string contains encoded CBOR. No API is
+ provided for this tag. */
+#define CBOR_TAG_CBOR 24
+/** See QCBOREncode_AddURI(). */
+#define CBOR_TAG_URI 32
+/** See QCBOREncode_AddB64URLText(). */
+#define CBOR_TAG_B64URL 33
+/** See QCBOREncode_AddB64Text(). */
+#define CBOR_TAG_B64 34
+/** See QCBOREncode_AddRegex(). */
+#define CBOR_TAG_REGEX 35
+/** See QCBOREncode_AddMIMEData(). */
+#define CBOR_TAG_MIME 36
+/** See QCBOREncode_AddBinaryUUID(). */
+#define CBOR_TAG_BIN_UUID 37
+/** The data is a CBOR Web Token per [RFC 8392]
+ (https://tools.ietf.org/html/rfc8932). No API is provided for this
+ tag. */
+#define CBOR_TAG_CWT 61
+/** Tag for COSE format encryption. See [RFC 8152, COSE]
+ (https://tools.ietf.org/html/rfc8152). No API is provided for this
+ tag. */
+#define CBOR_TAG_ENCRYPT 96
+/** Tag for COSE format MAC. See [RFC 8152, COSE]
+ (https://tools.ietf.org/html/rfc8152). No API is provided for this
+ tag. */
+#define CBOR_TAG_MAC 97
+/** Tag for COSE format signed data. See [RFC 8152, COSE]
+ (https://tools.ietf.org/html/rfc8152). No API is provided for this
+ tag. */
+#define CBOR_TAG_SIGN 98
+/** World geographic coordinates. See ISO 6709, [RFC 5870]
+ (https://tools.ietf.org/html/rfc5870) and WGS-84. No API is
+ provided for this tag. */
+#define CBOR_TAG_GEO_COORD 103
+/** The magic number, self-described CBOR. No API is provided for this
+ tag. */
+#define CBOR_TAG_CBOR_MAGIC 55799
+
+#define CBOR_TAG_NONE UINT64_MAX
+
+
+/*
+ Values for the 5 bits for items of major type 7
+ */
+#define CBOR_SIMPLEV_FALSE 20
+#define CBOR_SIMPLEV_TRUE 21
+#define CBOR_SIMPLEV_NULL 22
+#define CBOR_SIMPLEV_UNDEF 23
+#define CBOR_SIMPLEV_ONEBYTE 24
+#define HALF_PREC_FLOAT 25
+#define SINGLE_PREC_FLOAT 26
+#define DOUBLE_PREC_FLOAT 27
+#define CBOR_SIMPLE_BREAK 31
+#define CBOR_SIMPLEV_RESERVED_START CBOR_SIMPLEV_ONEBYTE
+#define CBOR_SIMPLEV_RESERVED_END CBOR_SIMPLE_BREAK
+
+
+
+
+/**
+ Error codes returned by QCBOR Encoder and Decoder.
+ */
+typedef enum {
+ /** The encode or decode completely correctly. */
+ QCBOR_SUCCESS = 0,
+
+ /** The buffer provided for the encoded output when doing encoding
+ was too small and the encoded output will not fit. Also, when
+ the buffer given to QCBORDecode_SetMemPool() is too small. */
+ QCBOR_ERR_BUFFER_TOO_SMALL = 1,
+
+ /** During encoding or decoding, the array or map nesting was
+ deeper than this implementation can handle. Note that in the
+ interest of code size and memory use, this implementation has a
+ hard limit on array nesting. The limit is defined as the
+ constant @ref QCBOR_MAX_ARRAY_NESTING. */
+ QCBOR_ERR_ARRAY_NESTING_TOO_DEEP = 2,
+
+ /** During decoding or encoding, the array or map had too many
+ items in it. This limit @ref QCBOR_MAX_ITEMS_IN_ARRAY,
+ typically 65,535. */
+ QCBOR_ERR_ARRAY_TOO_LONG = 3,
+
+ /** During encoding, more arrays or maps were closed than
+ opened. This is a coding error on the part of the caller of the
+ encoder. */
+ QCBOR_ERR_TOO_MANY_CLOSES = 4,
+
+ /** During decoding, some CBOR construct was encountered that this
+ decoder doesn't support, primarily this is the reserved
+ additional info values, 28 through 30. During encoding,
+ an attempt to create simple value between 24 and 31. */
+ QCBOR_ERR_UNSUPPORTED = 5,
+
+ /** During decoding, hit the end of the given data to decode. For
+ example, a byte string of 100 bytes was expected, but the end
+ of the input was hit before finding those 100 bytes. Corrupted
+ CBOR input will often result in this error. See also @ref
+ QCBOR_ERR_NO_MORE_ITEMS.
+ */
+ QCBOR_ERR_HIT_END = 6,
+
+ /** During encoding, the length of the encoded CBOR exceeded @c
+ UINT32_MAX. */
+ QCBOR_ERR_BUFFER_TOO_LARGE = 7,
+
+ /** During decoding, an integer smaller than INT64_MIN was received
+ (CBOR can represent integers smaller than INT64_MIN, but C
+ cannot). */
+ QCBOR_ERR_INT_OVERFLOW = 8,
+
+ /** During decoding, the label for a map entry is bad. What causes
+ this error depends on the decoding mode. */
+ QCBOR_ERR_MAP_LABEL_TYPE = 9,
+
+ /** During encoding or decoding, the number of array or map opens
+ was not matched by the number of closes. */
+ QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN = 10,
+
+ /** During decoding, a date greater than +- 292 billion years from
+ Jan 1 1970 encountered during parsing. */
+ QCBOR_ERR_DATE_OVERFLOW = 11,
+
+ /** During decoding, the CBOR is not valid, primarily a simple type
+ is encoded in a prohibited way. */
+ QCBOR_ERR_BAD_TYPE_7 = 12,
+
+ /** Optional tagging that doesn't make sense (an integer is tagged
+ as a date string) or can't be handled. */
+ QCBOR_ERR_BAD_OPT_TAG = 13,
+
+ /** Returned by QCBORDecode_Finish() if all the inputs bytes have
+ not been consumed. */
+ QCBOR_ERR_EXTRA_BYTES = 14,
+
+ /** During encoding, @c QCBOREncode_CloseXxx() called with a
+ different type than is currently open. */
+ QCBOR_ERR_CLOSE_MISMATCH = 15,
+
+ /** Unable to decode an indefinite-length string because no string
+ allocator was configured. See QCBORDecode_SetMemPool() or
+ QCBORDecode_SetUpAllocator(). */
+ QCBOR_ERR_NO_STRING_ALLOCATOR = 16,
+
+ /** One of the chunks in an indefinite-length string is not of the
+ type of the start of the string. */
+ QCBOR_ERR_INDEFINITE_STRING_CHUNK = 17,
+
+ /** Error allocating space for a string, usually for an
+ indefinite-length string. */
+ QCBOR_ERR_STRING_ALLOCATE = 18,
+
+ /** During decoding, a break occurred outside an indefinite-length
+ item. */
+ QCBOR_ERR_BAD_BREAK = 19,
+
+ /** During decoding, too many tags in the caller-configured tag
+ list, or not enough space in @ref QCBORTagListOut. */
+ QCBOR_ERR_TOO_MANY_TAGS = 20,
+
+ /** An integer type is encoded with a bad length (an indefinite length) */
+ QCBOR_ERR_BAD_INT = 21,
+
+ /** All well-formed data items have been consumed and there are no
+ more. If parsing a CBOR stream this indicates the non-error
+ end of the stream. If parsing a CBOR stream / sequence, this
+ probably indicates that some data items expected are not present.
+ See also @ref QCBOR_ERR_HIT_END. */
+ QCBOR_ERR_NO_MORE_ITEMS = 22,
+
+ /** Something is wrong with a decimal fraction or bigfloat such as
+ it not consisting of an array with two integers */
+ QCBOR_ERR_BAD_EXP_AND_MANTISSA = 23,
+
+ /** When decoding, a string's size is greater than size_t. In all but some
+ very strange situations this is because of corrupt input CBOR and
+ should be treated as such. The strange situation is a CPU with a very
+ small size_t (e.g., a 16-bit CPU) and a large string (e.g., > 65KB).
+ */
+ QCBOR_ERR_STRING_TOO_LONG = 24
+
+} QCBORError;
+
+
+
+
+/**
+ The maximum nesting of arrays and maps when encoding or decoding. The
+ error @ref QCBOR_ERR_ARRAY_NESTING_TOO_DEEP will be returned on
+ encoding of decoding if it is exceeded.
+ */
+#define QCBOR_MAX_ARRAY_NESTING QCBOR_MAX_ARRAY_NESTING1
+
+
+/**
+ The maximum number of items in a single array or map when encoding of
+ decoding.
+ */
+// -1 is because the value UINT16_MAX is used to track indefinite-length arrays
+#define QCBOR_MAX_ITEMS_IN_ARRAY (UINT16_MAX-1)
+
+
+/**
+ The maximum number of tags that can be in @ref QCBORTagListIn and passed to
+ QCBORDecode_SetCallerConfiguredTagList()
+ */
+#define QCBOR_MAX_CUSTOM_TAGS 16
+
+
+#endif /* qcbor_common_h */
diff --git a/inc/qcbor/qcbor_decode.h b/inc/qcbor/qcbor_decode.h
new file mode 100644
index 0000000..b028e4c
--- /dev/null
+++ b/inc/qcbor/qcbor_decode.h
@@ -0,0 +1,940 @@
+/*==============================================================================
+ Copyright (c) 2016-2018, The Linux Foundation.
+ Copyright (c) 2018-2020, Laurence Lundblade.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors, nor the name "Laurence Lundblade" may be used to
+ endorse or promote products derived from this software without
+ specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ =============================================================================*/
+
+
+#ifndef qcbor_decode_h
+#define qcbor_decode_h
+
+
+#include "qcbor/qcbor_common.h"
+#include "qcbor/qcbor_private.h"
+#include <stdbool.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#ifdef 0
+} // Keep editor indention formatting happy
+#endif
+#endif
+
+
+/**
+ The decode mode options.
+ */
+typedef enum {
+ /** See QCBORDecode_Init() */
+ QCBOR_DECODE_MODE_NORMAL = 0,
+ /** See QCBORDecode_Init() */
+ QCBOR_DECODE_MODE_MAP_STRINGS_ONLY = 1,
+ /** See QCBORDecode_Init() */
+ QCBOR_DECODE_MODE_MAP_AS_ARRAY = 2
+} QCBORDecodeMode;
+
+
+
+
+
+/* Do not renumber these. Code depends on some of these values. */
+/** The data type is unknown, unset or invalid. */
+#define QCBOR_TYPE_NONE 0
+/** Type for an integer that decoded either between @c INT64_MIN and
+ @c INT32_MIN or @c INT32_MAX and @c INT64_MAX. Data is in member
+ @c val.int64. */
+#define QCBOR_TYPE_INT64 2
+/** Type for an integer that decoded to a more than @c INT64_MAX and
+ @c UINT64_MAX. Data is in member @c val.uint64. */
+#define QCBOR_TYPE_UINT64 3
+/** Type for an array. The number of items in the array is in @c
+ val.uCount. */
+#define QCBOR_TYPE_ARRAY 4
+/** Type for a map; number of items in map is in @c val.uCount. */
+#define QCBOR_TYPE_MAP 5
+/** Type for a buffer full of bytes. Data is in @c val.string. */
+#define QCBOR_TYPE_BYTE_STRING 6
+/** Type for a UTF-8 string. It is not NULL-terminated. Data is in @c
+ val.string. */
+#define QCBOR_TYPE_TEXT_STRING 7
+/** Type for a positive big number. Data is in @c val.bignum, a
+ pointer and a length. */
+#define QCBOR_TYPE_POSBIGNUM 9
+/** Type for a negative big number. Data is in @c val.bignum, a
+ pointer and a length. */
+#define QCBOR_TYPE_NEGBIGNUM 10
+/** Type for [RFC 3339] (https://tools.ietf.org/html/rfc3339) date
+ string, possibly with time zone. Data is in @c val.dateString */
+#define QCBOR_TYPE_DATE_STRING 11
+/** Type for integer seconds since Jan 1970 + floating-point
+ fraction. Data is in @c val.epochDate */
+#define QCBOR_TYPE_DATE_EPOCH 12
+/** A simple type that this CBOR implementation doesn't know about;
+ Type is in @c val.uSimple. */
+#define QCBOR_TYPE_UKNOWN_SIMPLE 13
+
+/** A decimal fraction made of decimal exponent and integer mantissa.
+ See @ref expAndMantissa and QCBOREncode_AddDecimalFraction(). */
+#define QCBOR_TYPE_DECIMAL_FRACTION 14
+
+/** A decimal fraction made of decimal exponent and positive big
+ number mantissa. See @ref expAndMantissa and
+ QCBOREncode_AddDecimalFractionBigNum(). */
+#define QCBOR_TYPE_DECIMAL_FRACTION_POS_BIGNUM 15
+
+/** A decimal fraction made of decimal exponent and negative big
+ number mantissa. See @ref expAndMantissa and
+ QCBOREncode_AddDecimalFractionBigNum(). */
+#define QCBOR_TYPE_DECIMAL_FRACTION_NEG_BIGNUM 16
+
+/** A floating-point number made of base-2 exponent and integer
+ mantissa. See @ref expAndMantissa and
+ QCBOREncode_AddBigFloat(). */
+#define QCBOR_TYPE_BIGFLOAT 17
+
+/** A floating-point number made of base-2 exponent and positive big
+ number mantissa. See @ref expAndMantissa and
+ QCBOREncode_AddBigFloatBigNum(). */
+#define QCBOR_TYPE_BIGFLOAT_POS_BIGNUM 18
+
+/** A floating-point number made of base-2 exponent and negative big
+ number mantissa. See @ref expAndMantissa and
+ QCBOREncode_AddBigFloatBigNum(). */
+#define QCBOR_TYPE_BIGFLOAT_NEG_BIGNUM 19
+
+/** Type for the value false. */
+#define QCBOR_TYPE_FALSE 20
+/** Type for the value true. */
+#define QCBOR_TYPE_TRUE 21
+/** Type for the value null. */
+#define QCBOR_TYPE_NULL 22
+/** Type for the value undef. */
+#define QCBOR_TYPE_UNDEF 23
+/** Type for a floating-point number. Data is in @c val.float. */
+#define QCBOR_TYPE_FLOAT 26
+/** Type for a double floating-point number. Data is in @c val.double. */
+#define QCBOR_TYPE_DOUBLE 27
+/** For @ref QCBOR_DECODE_MODE_MAP_AS_ARRAY decode mode, a map that is
+ being traversed as an array. See QCBORDecode_Init() */
+#define QCBOR_TYPE_MAP_AS_ARRAY 32
+
+#define QCBOR_TYPE_BREAK 31 // Used internally; never returned
+
+#define QCBOR_TYPE_OPTTAG 254 // Used internally; never returned
+
+
+
+/*
+ Approx Size of this:
+ 8 + 8 + 1 + 1 + 1 + (1 padding) + (4 padding) = 24 for first part
+ (20 on a 32-bit machine)
+ 16 bytes for the val union
+ 16 bytes for label union
+ total = 56 bytes (52 bytes on 32-bit machine)
+ */
+
+/**
+ The main data structure that holds the type, value and other info for
+ a decoded item returned by QCBORDecode_GetNext() and
+ QCBORDecode_GetNextWithTags().
+ */
+typedef struct _QCBORItem {
+ /** Tells what element of the @c val union to use. One of @c
+ QCBOR_TYPE_XXXX */
+ uint8_t uDataType;
+ /** How deep the nesting from arrays and maps are. 0 is the top
+ level with no arrays or maps entered. */
+ uint8_t uNestingLevel;
+ /** Tells what element of the label union to use. */
+ uint8_t uLabelType;
+ /** 1 if allocated with string allocator, 0 if not. See
+ QCBORDecode_SetMemPool() or QCBORDecode_SetUpAllocator() */
+ uint8_t uDataAlloc;
+ /** Like @c uDataAlloc, but for label. */
+ uint8_t uLabelAlloc;
+ /** If not equal to @c uNestingLevel, this item closed out at least
+ one map/array */
+ uint8_t uNextNestLevel;
+
+ /** The union holding the item's value. Select union member based
+ on @c uDataType */
+ union {
+ /** The value for @c uDataType @ref QCBOR_TYPE_INT64. */
+ int64_t int64;
+ /** The value for uDataType @ref QCBOR_TYPE_UINT64. */
+ uint64_t uint64;
+ /** The value for @c uDataType @ref QCBOR_TYPE_BYTE_STRING and
+ @ref QCBOR_TYPE_TEXT_STRING. */
+ UsefulBufC string;
+ /** The "value" for @c uDataType @ref QCBOR_TYPE_ARRAY or @ref
+ QCBOR_TYPE_MAP -- the number of items in the array or map.
+ It is @c UINT16_MAX when decoding indefinite-lengths maps
+ and arrays. */
+ uint16_t uCount;
+ /** The value for @c uDataType @ref QCBOR_TYPE_DOUBLE. */
+ double dfnum;
+ /** The value for @c uDataType @ref QCBOR_TYPE_DATE_EPOCH. */
+ struct {
+ int64_t nSeconds;
+ double fSecondsFraction;
+ } epochDate;
+ /** The value for @c uDataType @ref QCBOR_TYPE_DATE_STRING. */
+ UsefulBufC dateString;
+ /** The value for @c uDataType @ref QCBOR_TYPE_POSBIGNUM and
+ @ref QCBOR_TYPE_NEGBIGNUM. */
+ UsefulBufC bigNum;
+ /** The integer value for unknown simple types. */
+ uint8_t uSimple;
+#ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
+ /** @anchor expAndMantissa
+
+ The value for bigfloats and decimal fractions. The use of the
+ fields in this structure depend on @c uDataType.
+
+ When @c uDataType is a @c DECIMAL_FRACTION, the exponent is
+ base-10. When it is a @c BIG_FLOAT it is base-2.
+
+ When @c uDataType is a @c POS_BIGNUM or a @c NEG_BIGNUM then the
+ @c bigNum part of @c Mantissa is valid. Otherwise the
+ @c nInt part of @c Mantissa is valid.
+
+ See @ref QCBOR_TYPE_DECIMAL_FRACTION,
+ @ref QCBOR_TYPE_DECIMAL_FRACTION_POS_BIGNUM,
+ @ref QCBOR_TYPE_DECIMAL_FRACTION_NEG_BIGNUM,
+ @ref QCBOR_TYPE_BIGFLOAT, @ref QCBOR_TYPE_BIGFLOAT_POS_BIGNUM,
+ and @ref QCBOR_TYPE_BIGFLOAT_NEG_BIGNUM.
+
+ Also see QCBOREncode_AddDecimalFraction(), QCBOREncode_AddBigFloat(),
+ QCBOREncode_AddDecimalFractionBigNum() and
+ QCBOREncode_AddBigFloatBigNum().
+ */
+ struct {
+ int64_t nExponent;
+ union {
+ int64_t nInt;
+ UsefulBufC bigNum;
+ } Mantissa;
+ } expAndMantissa;
+#endif
+ uint64_t uTagV; // Used internally during decoding
+ } val;
+
+ /** Union holding the different label types selected based on @c
+ uLabelType */
+ union {
+ /** The label for @c uLabelType @ref QCBOR_TYPE_BYTE_STRING and
+ @ref QCBOR_TYPE_TEXT_STRING */
+ UsefulBufC string;
+ /** The label for @c uLabelType for @ref QCBOR_TYPE_INT64 */
+ int64_t int64;
+ /** The label for @c uLabelType for @ref QCBOR_TYPE_UINT64 */
+ uint64_t uint64;
+ } label;
+
+ /** Bit indicating which tags (major type 6) on this item. See
+ QCBORDecode_IsTagged(). */
+ uint64_t uTagBits;
+
+} QCBORItem;
+
+
+
+/**
+ @brief The type defining what a string allocator function must do.
+
+ @param[in] pAllocateCxt Pointer to context for the particular
+ allocator implementation What is in the
+ context is dependent on how a particular
+ string allocator works. Typically, it
+ will contain a pointer to the memory pool
+ and some booking keeping data.
+ @param[in] pOldMem Points to some memory allocated by the
+ allocator that is either to be freed or
+ to be reallocated to be larger. It is
+ @c NULL for new allocations and when called as
+ a destructor to clean up the whole
+ allocation.
+ @param[in] uNewSize Size of memory to be allocated or new
+ size of chunk to be reallocated. Zero for
+ a new allocation or when called as a
+ destructor.
+
+ @return Either the allocated buffer is returned, or @ref
+ NULLUsefulBufC. @ref NULLUsefulBufC is returned on a failed
+ allocation and in the two cases where there is nothing to
+ return.
+
+ This is called in one of four modes:
+
+ Allocate -- @c uNewSize is the amount to allocate. @c pOldMem is @c
+ NULL.
+
+ Free -- @c uNewSize is 0. @c pOldMem points to the memory to be
+ freed. When the decoder calls this, it will always be the most
+ recent block that was either allocated or reallocated.
+
+ Reallocate -- @c pOldMem is the block to reallocate. @c uNewSize is
+ its new size. When the decoder calls this, it will always be the
+ most recent block that was either allocated or reallocated.
+
+ Destruct -- @c pOldMem is @c NULL and @c uNewSize is 0. This is called
+ when the decoding is complete by QCBORDecode_Finish(). Usually the
+ strings allocated by a string allocator are in use after the decoding
+ is completed so this usually will not free those strings. Many string
+ allocators will not need to do anything in this mode.
+
+ The strings allocated by this will have @c uDataAlloc set to true in
+ the @ref QCBORItem when they are returned. The user of the strings
+ will have to free them. How they free them, depends on the string
+ allocator.
+
+ If QCBORDecode_SetMemPool() is called, the internal MemPool will be
+ used. It has its own internal implementation of this function, so
+ one does not need to be implemented.
+ */
+typedef UsefulBuf (* QCBORStringAllocate)(void *pAllocateCxt, void *pOldMem, size_t uNewSize);
+
+
+/**
+ This only matters if you use the built-in string allocator by setting
+ it up with QCBORDecode_SetMemPool(). This is the size of the overhead
+ needed by QCBORDecode_SetMemPool(). The amount of memory available
+ for decoded strings will be the size of the buffer given to
+ QCBORDecode_SetMemPool() less this amount.
+
+ If you write your own string allocator or use the separately
+ available malloc based string allocator, this size will not apply.
+ */
+#define QCBOR_DECODE_MIN_MEM_POOL_SIZE 8
+
+
+/**
+ This is used by QCBORDecode_SetCallerConfiguredTagList() to set a
+ list of tags beyond the built-in ones.
+
+ See also QCBORDecode_GetNext() for general description of tag
+ decoding.
+ */
+typedef struct {
+ /** The number of tags in the @c puTags. The maximum size is @ref
+ QCBOR_MAX_CUSTOM_TAGS. */
+ uint8_t uNumTags;
+ /** An array of tags to add to recognize in addition to the
+ built-in ones. */
+ const uint64_t *puTags;
+} QCBORTagListIn;
+
+
+/**
+ This is for QCBORDecode_GetNextWithTags() to be able to return the
+ full list of tags on an item. It is not needed for most CBOR protocol
+ implementations. Its primary use is for pretty-printing CBOR or
+ protocol conversion to another format.
+
+ On input, @c puTags points to a buffer to be filled in and
+ uNumAllocated is the number of @c uint64_t values in the buffer.
+
+ On output the buffer contains the tags for the item. @c uNumUsed
+ tells how many there are.
+ */
+typedef struct {
+ uint8_t uNumUsed;
+ uint8_t uNumAllocated;
+ uint64_t *puTags;
+} QCBORTagListOut;
+
+
+/**
+ QCBORDecodeContext is the data type that holds context decoding the
+ data items for some received CBOR. It is about 100 bytes, so it can
+ go on the stack. The contents are opaque, and the caller should not
+ access any internal items. A context may be re used serially as long
+ as it is re initialized.
+ */
+typedef struct _QCBORDecodeContext QCBORDecodeContext;
+
+
+/**
+ Initialize the CBOR decoder context.
+
+ @param[in] pCtx The context to initialize.
+ @param[in] EncodedCBOR The buffer with CBOR encoded bytes to be decoded.
+ @param[in] nMode See below and @ref QCBORDecodeMode.
+
+ Initialize context for a pre-order traversal of the encoded CBOR
+ tree.
+
+ Most CBOR decoding can be completed by calling this function to start
+ and QCBORDecode_GetNext() in a loop.
+
+ If indefinite-length strings are to be decoded, then
+ QCBORDecode_SetMemPool() or QCBORDecode_SetUpAllocator() must be
+ called to set up a string allocator.
+
+ If tags other than built-in tags are to be recognized and recorded in
+ @c uTagBits, then QCBORDecode_SetCallerConfiguredTagList() must be
+ called. The built-in tags are those for which a macro of the form @c
+ CBOR_TAG_XXX is defined.
+
+ Three decoding modes are supported. In normal mode, @ref
+ QCBOR_DECODE_MODE_NORMAL, maps are decoded and strings and integers
+ are accepted as map labels. If a label is other than these, the error
+ @ref QCBOR_ERR_MAP_LABEL_TYPE is returned by QCBORDecode_GetNext().
+
+ In strings-only mode, @ref QCBOR_DECODE_MODE_MAP_STRINGS_ONLY, only
+ text strings are accepted for map labels. This lines up with CBOR
+ that converts to JSON. The error @ref QCBOR_ERR_MAP_LABEL_TYPE is
+ returned by QCBORDecode_GetNext() if anything but a text string label
+ is encountered.
+
+ In @ref QCBOR_DECODE_MODE_MAP_AS_ARRAY maps are treated as special
+ arrays. They will be return with special @c uDataType @ref
+ QCBOR_TYPE_MAP_AS_ARRAY and @c uCount, the number of items, will be
+ double what it would be for a normal map because the labels are also
+ counted. This mode is useful for decoding CBOR that has labels that
+ are not integers or text strings, but the caller must manage much of
+ the map decoding.
+ */
+void QCBORDecode_Init(QCBORDecodeContext *pCtx, UsefulBufC EncodedCBOR, QCBORDecodeMode nMode);
+
+
+/**
+ @brief Set up the MemPool string allocator for indefinite-length strings.
+
+ @param[in] pCtx The decode context.
+ @param[in] MemPool The pointer and length of the memory pool.
+ @param[in] bAllStrings If true, all strings, even of definite
+ length, will be allocated with the string
+ allocator.
+
+ @return Error if the MemPool was less than @ref QCBOR_DECODE_MIN_MEM_POOL_SIZE.
+
+ indefinite-length strings (text and byte) cannot be decoded unless
+ there is a string allocator configured. MemPool is a simple built-in
+ string allocator that allocates bytes from a memory pool handed to it
+ by calling this function. The memory pool is just a pointer and
+ length for some block of memory that is to be used for string
+ allocation. It can come from the stack, heap or other.
+
+ The memory pool must be @ref QCBOR_DECODE_MIN_MEM_POOL_SIZE plus
+ space for all the strings allocated. There is no overhead per string
+ allocated. A conservative way to size this buffer is to make it the
+ same size as the CBOR being decoded plus @ref
+ QCBOR_DECODE_MIN_MEM_POOL_SIZE.
+
+ This memory pool is used for all indefinite-length strings that are
+ text strings or byte strings, including strings used as labels.
+
+ The pointers to strings in @ref QCBORItem will point into the memory
+ pool set here. They do not need to be individually freed. Just
+ discard the buffer when they are no longer needed.
+
+ If @c bAllStrings is set, then the size will be the overhead plus the
+ space to hold **all** strings, definite and indefinite-length, value
+ or label. The advantage of this is that after the decode is complete,
+ the original memory holding the encoded CBOR does not need to remain
+ valid.
+
+ If this function is never called because there is no need to support
+ indefinite-length strings, the internal MemPool implementation should
+ be dead-stripped by the loader and not add to code size.
+ */
+QCBORError QCBORDecode_SetMemPool(QCBORDecodeContext *pCtx, UsefulBuf MemPool, bool bAllStrings);
+
+
+/**
+ @brief Sets up a custom string allocator for indefinite-length strings
+
+ @param[in] pCtx The decoder context to set up an
+ allocator for.
+ @param[in] pfAllocateFunction Pointer to function that will be
+ called by QCBOR for allocations and
+ frees.
+ @param[in] pAllocateContext Context passed to @c
+ pfAllocateFunction.
+ @param[in] bAllStrings If true, all strings, even of definite
+ length, will be allocated with the
+ string allocator.
+
+ indefinite-length strings (text and byte) cannot be decoded unless
+ there a string allocator is configured. QCBORDecode_SetUpAllocator()
+ allows the caller to configure an external string allocator
+ implementation if the internal string allocator is not suitable. See
+ QCBORDecode_SetMemPool() to configure the internal allocator. Note
+ that the internal allocator is not automatically set up.
+
+ The string allocator configured here can be a custom one designed and
+ implemented by the caller. See @ref QCBORStringAllocate for the
+ requirements for a string allocator implementation.
+
+ A malloc-based string external allocator can be obtained by calling
+ @c QCBORDecode_MakeMallocStringAllocator(). It will return a function
+ and pointer that can be given here as @c pAllocatorFunction and @c
+ pAllocatorContext. It uses standard @c malloc() so @c free() must be
+ called on all strings marked by @c uDataAlloc @c == @c 1 or @c
+ uLabelAlloc @c == @c 1 in @ref QCBORItem.
+
+ Note that an older version of this function took an allocator
+ structure, rather than single function and pointer. The older
+ version @c QCBORDecode_MakeMallocStringAllocator() also implemented
+ the older interface.
+ */
+void QCBORDecode_SetUpAllocator(QCBORDecodeContext *pCtx,
+ QCBORStringAllocate pfAllocateFunction,
+ void *pAllocateContext,
+ bool bAllStrings);
+
+/**
+ @brief Configure list of caller-selected tags to be recognized.
+
+ @param[in] pCtx The decode context.
+ @param[out] pTagList Structure holding the list of tags to configure.
+
+ This is used to tell the decoder about tags beyond those that are
+ built-in that should be recognized. The built-in tags are those with
+ macros of the form @c CBOR_TAG_XXX.
+
+ The list pointed to by @c pTagList must persist during decoding. No
+ copy of it is made.
+
+ The maximum number of tags that can be added is @ref
+ QCBOR_MAX_CUSTOM_TAGS. If a list larger than this is given, the
+ error will be returned when QCBORDecode_GetNext() is called, not
+ here.
+
+ See description of @ref QCBORTagListIn.
+ */
+void QCBORDecode_SetCallerConfiguredTagList(QCBORDecodeContext *pCtx, const QCBORTagListIn *pTagList);
+
+
+/**
+ @brief Gets the next item (integer, byte string, array...) in
+ preorder traversal of CBOR tree.
+
+ @param[in] pCtx The decoder context.
+ @param[out] pDecodedItem Holds the CBOR item just decoded.
+
+ @retval QCBOR_ERR_INDEFINITE_STRING_CHUNK Not well-formed, one of the
+ chunks in indefinite-length
+ string is wrong type.
+
+ @retval QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN Not well-formed, array or map
+ not closed.
+
+ @retval QCBOR_ERR_UNSUPPORTED Not well-formed, input contains
+ unsupported CBOR.
+
+ @retval QCBOR_ERR_HIT_END Not well-formed, unexpectedly ran out
+ of bytes.
+
+ @retval QCBOR_ERR_BAD_TYPE_7 Not well-formed, bad simple type value.
+
+ @retval QCBOR_ERR_BAD_BREAK Not well-formed, break occurs where
+ not allowed.
+
+ @retval QCBOR_ERR_EXTRA_BYTES Not well-formed, unprocessed bytes at
+ the end.
+
+ @retval QCBOR_ERR_BAD_INT Not well-formed, length of integer is
+ bad.
+
+ @retval QCBOR_ERR_BAD_OPT_TAG Invalid CBOR, tag on wrong type.
+
+ @retval QCBOR_ERR_ARRAY_TOO_LONG Implementation limit, array or map
+ too long.
+
+ @retval QCBOR_ERR_INT_OVERFLOW Implementation limit, negative
+ integer too large.
+
+ @retval QCBOR_ERR_DATE_OVERFLOW Implementation limit, date larger
+ than can be handled.
+
+ @retval QCBOR_ERR_ARRAY_NESTING_TOO_DEEP Implementation limit, nesting
+ too deep.
+
+ @retval QCBOR_ERR_STRING_ALLOCATE Resource exhaustion, string allocator
+ failed.
+
+ @retval QCBOR_ERR_MAP_LABEL_TYPE Configuration error / Implementation
+ limit encountered a map label this is
+ not a string on an integer.
+
+ @retval QCBOR_ERR_NO_STRING_ALLOCATOR Configuration error, encountered
+ indefinite-length string with no
+ allocator configured.
+ @retval QCBOR_ERR_NO_MORE_ITEMS No more bytes to decode. The previous
+ item was successfully decoded. This
+ is usually how the non-error end of
+ a CBOR stream / sequence is detected.
+
+ @c pDecodedItem is filled in with the value parsed. Generally, the
+ following data is returned in the structure:
+
+ - @c uDataType which indicates which member of the @c val union the
+ data is in. This decoder figures out the type based on the CBOR
+ major type, the CBOR "additionalInfo", the CBOR optional tags and
+ the value of the integer.
+
+ - The value of the item, which might be an integer, a pointer and a
+ length, the count of items in an array, a floating-point number or
+ other.
+
+ - The nesting level for maps and arrays.
+
+ - The label for an item in a map, which may be a text or byte string
+ or an integer.
+
+ - The CBOR optional tag or tags.
+
+ See documentation on in the data type @ref _QCBORItem for all the
+ details on what is returned.
+
+ This function handles arrays and maps. When first encountered a @ref
+ QCBORItem will be returned with major type @ref QCBOR_TYPE_ARRAY or
+ @ref QCBOR_TYPE_MAP. @c QCBORItem.val.uCount will indicate the number
+ of Items in the array or map. Typically, an implementation will call
+ QCBORDecode_GetNext() in a for loop to fetch them all. When decoding
+ indefinite-length maps and arrays, @c QCBORItem.val.uCount is @c
+ UINT16_MAX and @c uNextNestLevel must be used to know when the end of
+ a map or array is reached.
+
+ Nesting level 0 is the outside top-most nesting level. For example,
+ in a CBOR structure with two items, an integer and a byte string
+ only, both would be at nesting level 0. A CBOR structure with an
+ array open, an integer and a byte string, would have the integer and
+ byte string as nesting level 1.
+
+ Here is an example of how the nesting level is reported with no arrays
+ or maps at all.
+
+ @verbatim
+ CBOR Structure Nesting Level
+ Integer 0
+ Byte String 0
+ @endverbatim
+
+ Here is an example of how the nesting level is reported with a simple
+ array and some top-level items.
+
+ @verbatim
+ Integer 0
+ Array (with 2 items) 0
+ Byte String 1
+ Byte string 1
+ Integer 0
+ @endverbatim
+
+
+ Here's a more complex example
+ @verbatim
+
+ Map with 2 items 0
+ Text string 1
+ Array with 3 integers 1
+ integer 2
+ integer 2
+ integer 2
+ text string 1
+ byte string 1
+ @endverbatim
+
+ In @ref _QCBORItem, @c uNextNestLevel is the nesting level for the
+ next call to QCBORDecode_GetNext(). It indicates if any maps or
+ arrays were closed out during the processing of the just-fetched @ref
+ QCBORItem. This processing includes a look-ahead for any breaks that
+ close out indefinite-length arrays or maps. This value is needed to
+ be able to understand the hierarchical structure. If @c
+ uNextNestLevel is not equal to @c uNestLevel the end of the current
+ map or array has been encountered. This works the same for both
+ definite and indefinite-length arrays.
+
+ This decoder support CBOR type 6 tagging. The decoding of particular
+ given tag value may be supported in one of three different ways.
+
+ First, some common tags are fully and transparently supported by
+ automatically decoding them and returning them in a @ref QCBORItem.
+ These tags have a @c QCBOR_TYPE_XXX associated with them and manifest
+ pretty much the same as a standard CBOR type. @ref
+ QCBOR_TYPE_DATE_EPOCH and the @c epochDate member of @ref QCBORItem
+ is an example.
+
+ Second are tags that are automatically recognized, but not decoded.
+ These are tags that have a @c \#define of the form @c CBOR_TAG_XXX.
+ These are recorded in the @c uTagBits member of @ref QCBORItem. There
+ is an internal table that maps each bit to a particular tag value
+ allowing up to 64 tags on an individual item to be reported (it is
+ rare to have more than one or two). To find out if a particular tag
+ value is set call QCBORDecode_IsTagged() on the @ref QCBORItem. See
+ also QCBORDecode_GetNextWithTags().
+
+ Third are tags that are not automatically recognized, because they
+ are proprietary, custom or more recently registered with [IANA]
+ (https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml). The
+ internal mapping table has to be configured to recognize these. Call
+ QCBORDecode_SetCallerConfiguredTagList() to do that. Then
+ QCBORDecode_IsTagged() will work with them.
+
+ The actual decoding of tags supported in the second and third way
+ must be handled by the caller. Often this is simply verifying that
+ the expected tag is present on a map, byte string or such. In other
+ cases, there might a complicated map structure to decode.
+
+ See @ref Tags-Overview for a description of how to go about creating
+ custom tags.
+
+ This tag decoding design is to be open-ended and flexible to be able
+ to handle newly defined tags, while using very little memory, in
+ particular keeping @ref QCBORItem as small as possible.
+
+ If any error occurs, \c uDataType and \c uLabelType will be set
+ to \ref QCBOR_TYPE_NONE. If there is no need to know the specific
+ error, \ref QCBOR_TYPE_NONE can be checked for and the return value
+ ignored.
+
+ Errors fall in several categories as noted in list above:
+
+ - Not well-formed errors are those where there is something
+ syntactically and fundamentally wrong with the CBOR being
+ decoded. Encoding should stop completely.
+
+ - Invalid CBOR is well-formed, but still not correct. It is probably
+ best to stop decoding, but not necessary.
+
+ - This implementation has some size limits. They should rarely be
+ encountered. If they are it may because something is wrong with the
+ CBOR, for example an array size is incorrect.
+
+ - Resource exhaustion. This only occurs when a string allocator is
+ configured to handle indefinite-length strings as other than that,
+ this implementation does no dynamic memory allocation.
+
+ - There are a few CBOR constructs that are not handled without some
+ extra configuration. These are indefinite length strings and maps
+ with labels that are not strings or integers. See QCBORDecode_Init().
+
+ */
+QCBORError QCBORDecode_GetNext(QCBORDecodeContext *pCtx, QCBORItem *pDecodedItem);
+
+
+/**
+ @brief Gets the next item including full list of tags for item.
+
+ @param[in] pCtx The decoder context.
+ @param[out] pDecodedItem Holds the CBOR item just decoded.
+ @param[in,out] pTagList On input array to put tags in; on output
+ the tags on this item. See
+ @ref QCBORTagListOut.
+
+ @return See return values for QCBORDecode_GetNext().
+
+ @retval QCBOR_ERR_TOO_MANY_TAGS The size of @c pTagList is too small.
+
+ This works the same as QCBORDecode_GetNext() except that it also
+ returns the full list of tags for the data item. This function should
+ only be needed when parsing CBOR to print it out or convert it to
+ some other format. It should not be needed to implement a CBOR-based
+ protocol. See QCBORDecode_GetNext() for the main description of tag
+ decoding.
+
+ Tags will be returned here whether or not they are in the built-in or
+ caller-configured tag lists.
+
+ CBOR has no upper bound of limit on the number of tags that can be
+ associated with a data item though in practice the number of tags on
+ an item will usually be small, perhaps less than five. This will
+ return @ref QCBOR_ERR_TOO_MANY_TAGS if the array in @c pTagList is
+ too small to hold all the tags for the item.
+
+ (This function is separate from QCBORDecode_GetNext() so as to not
+ have to make @ref QCBORItem large enough to be able to hold a full
+ list of tags. Even a list of five tags would nearly double its size
+ because tags can be a @c uint64_t ).
+ */
+QCBORError QCBORDecode_GetNextWithTags(QCBORDecodeContext *pCtx, QCBORItem *pDecodedItem, QCBORTagListOut *pTagList);
+
+
+/**
+ @brief Determine if a CBOR item was tagged with a particular tag
+
+ @param[in] pCtx The decoder context.
+ @param[in] pItem The CBOR item to check.
+ @param[in] uTag The tag to check, one of @c CBOR_TAG_XXX.
+
+ @return 1 if it was tagged, 0 if not
+
+ See QCBORDecode_GetNext() for the main description of tag
+ handling. For tags that are not fully decoded a bit corresponding to
+ the tag is set in in @c uTagBits in the @ref QCBORItem. The
+ particular bit depends on an internal mapping table. This function
+ checks for set bits against the mapping table.
+
+ Typically, a protocol implementation just wants to know if a
+ particular tag is present. That is what this provides. To get the
+ full list of tags on a data item, see QCBORDecode_GetNextWithTags().
+
+ Also see QCBORDecode_SetCallerConfiguredTagList() for the means to
+ add new tags to the internal list so they can be checked for with
+ this function.
+ */
+int QCBORDecode_IsTagged(QCBORDecodeContext *pCtx, const QCBORItem *pItem, uint64_t uTag);
+
+
+/**
+ Check whether all the bytes have been decoded and maps and arrays closed.
+
+ @param[in] pCtx The context to check.
+
+ @return An error or @ref QCBOR_SUCCESS.
+
+ This tells you if all the bytes given to QCBORDecode_Init() have been
+ consumed and whether all maps and arrays were closed. The decode is
+ considered to be incorrect or incomplete if not and an error will be
+ returned.
+ */
+QCBORError QCBORDecode_Finish(QCBORDecodeContext *pCtx);
+
+
+
+
+/**
+ @brief Convert int64_t to smaller integers safely.
+
+ @param [in] src An @c int64_t.
+ @param [out] dest A smaller sized integer to convert to.
+
+ @return 0 on success -1 if not
+
+ When decoding an integer, the CBOR decoder will return the value as
+ an int64_t unless the integer is in the range of @c INT64_MAX and @c
+ UINT64_MAX. That is, unless the value is so large that it can only be
+ represented as a @c uint64_t, it will be an @c int64_t.
+
+ CBOR itself doesn't size the individual integers it carries at
+ all. The only limits it puts on the major integer types is that they
+ are 8 bytes or less in length. Then encoders like this one use the
+ smallest number of 1, 2, 4 or 8 bytes to represent the integer based
+ on its value. There is thus no notion that one data item in CBOR is
+ a 1-byte integer and another is a 4-byte integer.
+
+ The interface to this CBOR encoder only uses 64-bit integers. Some
+ CBOR protocols or implementations of CBOR protocols may not want to
+ work with something smaller than a 64-bit integer. Perhaps an array
+ of 1000 integers needs to be sent and none has a value larger than
+ 50,000 and are represented as @c uint16_t.
+
+ The sending / encoding side is easy. Integers are temporarily widened
+ to 64-bits as a parameter passing through QCBOREncode_AddInt64() and
+ encoded in the smallest way possible for their value, possibly in
+ less than an @c uint16_t.
+
+ On the decoding side the integers will be returned at @c int64_t even if
+ they are small and were represented by only 1 or 2 bytes in the
+ encoded CBOR. The functions here will convert integers to a small
+ representation with an overflow check.
+
+ (The decoder could have support 8 different integer types and
+ represented the integer with the smallest type automatically, but
+ this would have made the decoder more complex and code calling the
+ decoder more complex in most use cases. In most use cases on 64-bit
+ machines it is no burden to carry around even small integers as
+ 64-bit values).
+ */
+static inline int QCBOR_Int64ToInt32(int64_t src, int32_t *dest)
+{
+ if(src > INT32_MAX || src < INT32_MIN) {
+ return -1;
+ } else {
+ *dest = (int32_t) src;
+ }
+ return 0;
+}
+
+static inline int QCBOR_Int64ToInt16(int64_t src, int16_t *dest)
+{
+ if(src > INT16_MAX || src < INT16_MIN) {
+ return -1;
+ } else {
+ *dest = (int16_t) src;
+ }
+ return 0;
+}
+
+static inline int QCBOR_Int64ToInt8(int64_t src, int8_t *dest)
+{
+ if(src > INT8_MAX || src < INT8_MIN) {
+ return -1;
+ } else {
+ *dest = (int8_t) src;
+ }
+ return 0;
+}
+
+static inline int QCBOR_Int64ToUInt32(int64_t src, uint32_t *dest)
+{
+ if(src > UINT32_MAX || src < 0) {
+ return -1;
+ } else {
+ *dest = (uint32_t) src;
+ }
+ return 0;
+}
+
+static inline int QCBOR_Int64UToInt16(int64_t src, uint16_t *dest)
+{
+ if(src > UINT16_MAX || src < 0) {
+ return -1;
+ } else {
+ *dest = (uint16_t) src;
+ }
+ return 0;
+}
+
+static inline int QCBOR_Int64ToUInt8(int64_t src, uint8_t *dest)
+{
+ if(src > UINT8_MAX || src < 0) {
+ return -1;
+ } else {
+ *dest = (uint8_t) src;
+ }
+ return 0;
+}
+
+static inline int QCBOR_Int64ToUInt64(int64_t src, uint64_t *dest)
+{
+ if(src > 0) {
+ return -1;
+ } else {
+ *dest = (uint64_t) src;
+ }
+ return 0;
+}
+
+
+#endif /* qcbor_decode_h */
diff --git a/inc/qcbor/qcbor.h b/inc/qcbor/qcbor_encode.h
similarity index 60%
rename from inc/qcbor/qcbor.h
rename to inc/qcbor/qcbor_encode.h
index 40b08e8..83c8bbf 100644
--- a/inc/qcbor/qcbor.h
+++ b/inc/qcbor/qcbor_encode.h
@@ -31,63 +31,14 @@
=============================================================================*/
-/*=============================================================================
- FILE: qcbor.h
-
- DESCRIPTION: This is the full public API and data structures for QCBOR
-
- EDIT HISTORY FOR FILE:
-
- This section contains comments describing changes made to the module.
- Notice that changes are listed in reverse chronological order.
-
- when who what, where, why
- -------- ---- ---------------------------------------------------
- 02/07/2020 llundblade QCBOREncode_EncodeHead() and other for bstr hashing.
- 01/25/2020 llundblade Cleaner handling of too-long encoded string input.
- 01/08/2020 llundblade Documentation corrections & improved code formatting.
- 12/30/19 llundblade Add support for decimal fractions and bigfloats.
- 08/7/19 llundblade Better handling of not well-formed encode and decode.
- 07/31/19 llundblade New error code for better end of data handling.
- 7/25/19 janjongboom Add indefinite length encoding for maps and arrays.
- 05/26/19 llundblade Add QCBOREncode_GetErrorState() and _IsBufferNULL().
- 04/26/19 llundblade Big documentation & style update. No interface change.
- 02/16/19 llundblade Redesign MemPool to fix memory access alignment bug.
- 12/18/18 llundblade Move decode malloc optional code to separate repo.
- 12/13/18 llundblade Documentatation improvements.
- 11/29/18 llundblade Rework to simpler handling of tags and labels.
- 11/9/18 llundblade Error codes are now enums.
- 11/1/18 llundblade Floating support.
- 10/31/18 llundblade Switch to one license that is almost BSD-3.
- 10/15/18 llundblade indefinite-length maps and arrays supported
- 10/8/18 llundblade indefinite-length strings supported
- 09/28/18 llundblade Added bstr wrapping feature for COSE implementation.
- 07/05/17 llundbla Add bstr wrapping of maps/arrays for COSE.
- 03/01/17 llundbla More data types; decoding improvements and fixes.
- 11/13/16 llundbla Integrate most TZ changes back into github version.
- 09/30/16 gkanike Porting to TZ.
- 03/15/16 llundbla Initial Version.
-
- =============================================================================*/
-
-#ifndef __QCBOR__qcbor__
-#define __QCBOR__qcbor__
+#ifndef qcbor_encode_h
+#define qcbor_encode_h
-/* ===========================================================================
- BEGINNING OF PRIVATE PART OF THIS FILE
-
- Caller of QCBOR should not reference any of the details below up until
- the start of the public part.
- ========================================================================== */
-
-/*
- Standard integer types are used in the interface to be precise about
- sizes to be better at preventing underflow/overflow errors.
- */
-#include <stdint.h>
+#include "qcbor/qcbor_common.h"
+#include "qcbor/qcbor_private.h"
#include <stdbool.h>
-#include "UsefulBuf.h"
+
#ifdef __cplusplus
extern "C" {
@@ -96,331 +47,9 @@
#endif
#endif
-/*
- The maxium nesting of arrays and maps when encoding or decoding.
- (Further down in the file there is a definition that refers to this
- that is public. This is done this way so there can be a nice
- separation of public and private parts in this file.
-*/
-#define QCBOR_MAX_ARRAY_NESTING1 15 // Do not increase this over 255
-
-
-/* The largest offset to the start of an array or map. It is slightly
- less than UINT32_MAX so the error condition can be tests on 32-bit machines.
- UINT32_MAX comes from uStart in QCBORTrackNesting being a uin32_t.
-
- This will cause trouble on a machine where size_t is less than 32-bits.
- */
-#define QCBOR_MAX_ARRAY_OFFSET (UINT32_MAX - 100)
-
-/*
- PRIVATE DATA STRUCTURE
-
- Holds the data for tracking array and map nesting during encoding. Pairs up
- with the Nesting_xxx functions to make an "object" to handle nesting encoding.
-
- uStart is a uint32_t instead of a size_t to keep the size of this
- struct down so it can be on the stack without any concern. It would be about
- double if size_t was used instead.
-
- Size approximation (varies with CPU/compiler):
- 64-bit machine: (15 + 1) * (4 + 2 + 1 + 1 pad) + 8 = 136 bytes
- 32-bit machine: (15 + 1) * (4 + 2 + 1 + 1 pad) + 4 = 132 bytes
-*/
-typedef struct __QCBORTrackNesting {
- // PRIVATE DATA STRUCTURE
- struct {
- // See function QCBOREncode_OpenMapOrArray() for details on how this works
- uint32_t uStart; // uStart is the byte position where the array starts
- uint16_t uCount; // Number of items in the arrary or map; counts items
- // in a map, not pairs of items
- uint8_t uMajorType; // Indicates if item is a map or an array
- } pArrays[QCBOR_MAX_ARRAY_NESTING1+1], // stored state for the nesting levels
- *pCurrentNesting; // the current nesting level
-} QCBORTrackNesting;
-
-
-/*
- PRIVATE DATA STRUCTURE
-
- Context / data object for encoding some CBOR. Used by all encode functions to
- form a public "object" that does the job of encdoing.
-
- Size approximation (varies with CPU/compiler):
- 64-bit machine: 27 + 1 (+ 4 padding) + 136 = 32 + 136 = 168 bytes
- 32-bit machine: 15 + 1 + 132 = 148 bytes
-*/
-struct _QCBOREncodeContext {
- // PRIVATE DATA STRUCTURE
- UsefulOutBuf OutBuf; // Pointer to output buffer, its length and
- // position in it
- uint8_t uError; // Error state, always from QCBORError enum
- QCBORTrackNesting nesting; // Keep track of array and map nesting
-};
-
-
-/*
- PRIVATE DATA STRUCTURE
-
- Holds the data for array and map nesting for decoding work. This structure
- and the DecodeNesting_xxx functions form an "object" that does the work
- for arrays and maps.
-
- Size approximation (varies with CPU/compiler):
- 64-bit machine: 4 * 16 + 8 = 72
- 32-bit machine: 4 * 16 + 4 = 68
- */
-typedef struct __QCBORDecodeNesting {
- // PRIVATE DATA STRUCTURE
- struct {
- uint16_t uCount;
- uint8_t uMajorType;
- } pMapsAndArrays[QCBOR_MAX_ARRAY_NESTING1+1],
- *pCurrent;
-} QCBORDecodeNesting;
-
-
-typedef struct {
- // PRIVATE DATA STRUCTURE
- void *pAllocateCxt;
- UsefulBuf (* pfAllocator)(void *pAllocateCxt, void *pOldMem, size_t uNewSize);
-} QCORInternalAllocator;
-
-
-/*
- PRIVATE DATA STRUCTURE
-
- The decode context. This data structure plus the public QCBORDecode_xxx
- functions form an "object" that does CBOR decoding.
-
- Size approximation (varies with CPU/compiler):
- 64-bit machine: 32 + 1 + 1 + 6 bytes padding + 72 + 16 + 8 + 8 = 144 bytes
- 32-bit machine: 16 + 1 + 1 + 2 bytes padding + 68 + 8 + 8 + 4 = 108 bytes
- */
-struct _QCBORDecodeContext {
- // PRIVATE DATA STRUCTURE
- UsefulInputBuf InBuf;
-
- uint8_t uDecodeMode;
- uint8_t bStringAllocateAll;
-
- QCBORDecodeNesting nesting;
-
- // If a string allocator is configured for indefinite-length
- // strings, it is configured here.
- QCORInternalAllocator StringAllocator;
-
- // These are special for the internal MemPool allocator.
- // They are not used otherwise. We tried packing these
- // in the MemPool itself, but there are issues
- // with memory alignment.
- uint32_t uMemPoolSize;
- uint32_t uMemPoolFreeOffset;
-
- // This is NULL or points to QCBORTagList.
- // It is type void for the same reason as above.
- const void *pCallerConfiguredTagList;
-};
-
-// Used internally in the impementation here
-// Must not conflict with any of the official CBOR types
-#define CBOR_MAJOR_NONE_TYPE_RAW 9
-#define CBOR_MAJOR_NONE_TAG_LABEL_REORDER 10
-#define CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY 11
-#define CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN 12
-#define CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN 13
-
-
-/* ==========================================================================
- END OF PRIVATE PART OF THIS FILE
-
- BEGINNING OF PUBLIC PART OF THIS FILE
- ========================================================================== */
-
-
-
-/* ==========================================================================
- BEGINNING OF CONSTANTS THAT COME FROM THE CBOR STANDARD, RFC 7049
-
- It is not necessary to use these directly when encoding or decoding
- CBOR with this implementation.
- ========================================================================== */
-
-/* Standard CBOR Major type for positive integers of various lengths */
-#define CBOR_MAJOR_TYPE_POSITIVE_INT 0
-
-/* Standard CBOR Major type for negative integer of various lengths */
-#define CBOR_MAJOR_TYPE_NEGATIVE_INT 1
-
-/* Standard CBOR Major type for an array of arbitrary 8-bit bytes. */
-#define CBOR_MAJOR_TYPE_BYTE_STRING 2
-
-/* Standard CBOR Major type for a UTF-8 string. Note this is true 8-bit UTF8
- with no encoding and no NULL termination */
-#define CBOR_MAJOR_TYPE_TEXT_STRING 3
-
-/* Standard CBOR Major type for an ordered array of other CBOR data items */
-#define CBOR_MAJOR_TYPE_ARRAY 4
-
-/* Standard CBOR Major type for CBOR MAP. Maps an array of pairs. The
- first item in the pair is the "label" (key, name or identfier) and the second
- item is the value. */
-#define CBOR_MAJOR_TYPE_MAP 5
-
-/* Standard CBOR optional tagging. This tags things like dates and URLs */
-#define CBOR_MAJOR_TYPE_OPTIONAL 6
-
-/* Standard CBOR extra simple types like floats and the values true and false */
-#define CBOR_MAJOR_TYPE_SIMPLE 7
-
-
-/*
- These are special values for the AdditionalInfo bits that are part of
- the first byte. Mostly they encode the length of the data item.
- */
-#define LEN_IS_ONE_BYTE 24
-#define LEN_IS_TWO_BYTES 25
-#define LEN_IS_FOUR_BYTES 26
-#define LEN_IS_EIGHT_BYTES 27
-#define ADDINFO_RESERVED1 28
-#define ADDINFO_RESERVED2 29
-#define ADDINFO_RESERVED3 30
-#define LEN_IS_INDEFINITE 31
-
-
-/*
- 24 is a special number for CBOR. Integers and lengths
- less than it are encoded in the same byte as the major type.
- */
-#define CBOR_TWENTY_FOUR 24
-
-
-/*
- Tags that are used with CBOR_MAJOR_TYPE_OPTIONAL. These
- are types defined in RFC 7049 and some additional ones
- in the IANA CBOR tags registry.
- */
-/** See QCBOREncode_AddDateString(). */
-#define CBOR_TAG_DATE_STRING 0
-/** See QCBOREncode_AddDateEpoch(). */
-#define CBOR_TAG_DATE_EPOCH 1
-/** See QCBOREncode_AddPositiveBignum(). */
-#define CBOR_TAG_POS_BIGNUM 2
-/** See QCBOREncode_AddNegativeBignum(). */
-#define CBOR_TAG_NEG_BIGNUM 3
-/** CBOR tag for a two-element array representing a fraction with a
- mantissa and base-10 scaling factor. See QCBOREncode_AddDecimalFraction()
- and @ref expAndMantissa.
- */
-#define CBOR_TAG_DECIMAL_FRACTION 4
-/** CBOR tag for a two-element array representing a fraction with a
- mantissa and base-2 scaling factor. See QCBOREncode_AddBigFloat()
- and @ref expAndMantissa. */
-#define CBOR_TAG_BIGFLOAT 5
-/** Tag for COSE format encryption with no recipient
- identification. See [RFC 8152, COSE]
- (https://tools.ietf.org/html/rfc8152). No API is provided for this
- tag. */
-#define CBOR_TAG_COSE_ENCRYPTO 16
-/** Tag for COSE format MAC'd data with no recipient
- identification. See [RFC 8152, COSE]
- (https://tools.ietf.org/html/rfc8152). No API is provided for this
- tag.*/
-#define CBOR_TAG_COSE_MAC0 17
-/** Tag for COSE format single signature signing. No API is provided
- for this tag. See [RFC 8152, COSE]
- (https://tools.ietf.org/html/rfc8152). */
-#define CBOR_TAG_COSE_SIGN1 18
-/** A hint that the following byte string should be encoded in
- Base64URL when converting to JSON or similar text-based
- representations. Call @c
- QCBOREncode_AddTag(pCtx,CBOR_TAG_ENC_AS_B64URL) before the call to
- QCBOREncode_AddBytes(). */
-#define CBOR_TAG_ENC_AS_B64URL 21
-/** A hint that the following byte string should be encoded in Base64
- when converting to JSON or similar text-based
- representations. Call @c
- QCBOREncode_AddTag(pCtx,CBOR_TAG_ENC_AS_B64) before the call to
- QCBOREncode_AddBytes(). */
-#define CBOR_TAG_ENC_AS_B64 22
-/** A hint that the following byte string should be encoded in base-16
- format per [RFC 4648] (https://tools.ietf.org/html/rfc4648) when
- converting to JSON or similar text-based
- representations. Essentially, Base-16 encoding is the standard
- case- insensitive hex encoding and may be referred to as
- "hex". Call @c QCBOREncode_AddTag(pCtx,CBOR_TAG_ENC_AS_B16) before
- the call to QCBOREncode_AddBytes(). */
-#define CBOR_TAG_ENC_AS_B16 23
-/** Tag to indicate a byte string contains encoded CBOR. No API is
- provided for this tag. */
-#define CBOR_TAG_CBOR 24
-/** See QCBOREncode_AddURI(). */
-#define CBOR_TAG_URI 32
-/** See QCBOREncode_AddB64URLText(). */
-#define CBOR_TAG_B64URL 33
-/** See QCBOREncode_AddB64Text(). */
-#define CBOR_TAG_B64 34
-/** See QCBOREncode_AddRegex(). */
-#define CBOR_TAG_REGEX 35
-/** See QCBOREncode_AddMIMEData(). */
-#define CBOR_TAG_MIME 36
-/** See QCBOREncode_AddBinaryUUID(). */
-#define CBOR_TAG_BIN_UUID 37
-/** The data is a CBOR Web Token per [RFC 8392]
- (https://tools.ietf.org/html/rfc8932). No API is provided for this
- tag. */
-#define CBOR_TAG_CWT 61
-/** Tag for COSE format encryption. See [RFC 8152, COSE]
- (https://tools.ietf.org/html/rfc8152). No API is provided for this
- tag. */
-#define CBOR_TAG_ENCRYPT 96
-/** Tag for COSE format MAC. See [RFC 8152, COSE]
- (https://tools.ietf.org/html/rfc8152). No API is provided for this
- tag. */
-#define CBOR_TAG_MAC 97
-/** Tag for COSE format signed data. See [RFC 8152, COSE]
- (https://tools.ietf.org/html/rfc8152). No API is provided for this
- tag. */
-#define CBOR_TAG_SIGN 98
-/** World geographic coordinates. See ISO 6709, [RFC 5870]
- (https://tools.ietf.org/html/rfc5870) and WGS-84. No API is
- provided for this tag. */
-#define CBOR_TAG_GEO_COORD 103
-/** The magic number, self-described CBOR. No API is provided for this
- tag. */
-#define CBOR_TAG_CBOR_MAGIC 55799
-
-#define CBOR_TAG_NONE UINT64_MAX
-
-
-/*
- Values for the 5 bits for items of major type 7
- */
-#define CBOR_SIMPLEV_FALSE 20
-#define CBOR_SIMPLEV_TRUE 21
-#define CBOR_SIMPLEV_NULL 22
-#define CBOR_SIMPLEV_UNDEF 23
-#define CBOR_SIMPLEV_ONEBYTE 24
-#define HALF_PREC_FLOAT 25
-#define SINGLE_PREC_FLOAT 26
-#define DOUBLE_PREC_FLOAT 27
-#define CBOR_SIMPLE_BREAK 31
-#define CBOR_SIMPLEV_RESERVED_START CBOR_SIMPLEV_ONEBYTE
-#define CBOR_SIMPLEV_RESERVED_END CBOR_SIMPLE_BREAK
-
-
-
-/* ===========================================================================
-
- END OF CONSTANTS THAT COME FROM THE CBOR STANDARD, RFC 7049
-
- BEGINNING OF PUBLIC INTERFACE FOR QCBOR ENCODER / DECODER
-
- =========================================================================== */
/**
-
- @file qcbor.h
+ @file qcbor_encode.h
Q C B O R E n c o d e / D e c o d e
@@ -644,26 +273,6 @@
*/
-/**
- The maximum number of items in a single array or map when encoding of
- decoding.
-*/
-// -1 is because the value UINT16_MAX is used to track indefinite-length arrays
-#define QCBOR_MAX_ITEMS_IN_ARRAY (UINT16_MAX-1)
-
-/**
- The maximum nesting of arrays and maps when encoding or decoding. The
- error @ref QCBOR_ERR_ARRAY_NESTING_TOO_DEEP will be returned on
- encoding of decoding if it is exceeded.
-*/
-#define QCBOR_MAX_ARRAY_NESTING QCBOR_MAX_ARRAY_NESTING1
-
-/**
- The maximum number of tags that can be in @ref QCBORTagListIn and passed to
- QCBORDecode_SetCallerConfiguredTagList()
- */
-#define QCBOR_MAX_CUSTOM_TAGS 16
-
/*
The size of the buffer to be passed to QCBOREncode_EncodeHead(). It is one
byte larger than sizeof(uint64_t) + 1, the actual maximum size of the
@@ -672,452 +281,6 @@
*/
#define QCBOR_HEAD_BUFFER_SIZE (sizeof(uint64_t) + 2)
-/**
- Error codes returned by QCBOR Encoder and Decoder.
- */
-typedef enum {
- /** The encode or decode completely correctly. */
- QCBOR_SUCCESS = 0,
-
- /** The buffer provided for the encoded output when doing encoding
- was too small and the encoded output will not fit. Also, when
- the buffer given to QCBORDecode_SetMemPool() is too small. */
- QCBOR_ERR_BUFFER_TOO_SMALL = 1,
-
- /** During encoding or decoding, the array or map nesting was
- deeper than this implementation can handle. Note that in the
- interest of code size and memory use, this implementation has a
- hard limit on array nesting. The limit is defined as the
- constant @ref QCBOR_MAX_ARRAY_NESTING. */
- QCBOR_ERR_ARRAY_NESTING_TOO_DEEP = 2,
-
- /** During decoding or encoding, the array or map had too many
- items in it. This limit @ref QCBOR_MAX_ITEMS_IN_ARRAY,
- typically 65,535. */
- QCBOR_ERR_ARRAY_TOO_LONG = 3,
-
- /** During encoding, more arrays or maps were closed than
- opened. This is a coding error on the part of the caller of the
- encoder. */
- QCBOR_ERR_TOO_MANY_CLOSES = 4,
-
- /** During decoding, some CBOR construct was encountered that this
- decoder doesn't support, primarily this is the reserved
- additional info values, 28 through 30. During encoding,
- an attempt to create simple value between 24 and 31. */
- QCBOR_ERR_UNSUPPORTED = 5,
-
- /** During decoding, hit the end of the given data to decode. For
- example, a byte string of 100 bytes was expected, but the end
- of the input was hit before finding those 100 bytes. Corrupted
- CBOR input will often result in this error. See also @ref
- QCBOR_ERR_NO_MORE_ITEMS.
- */
- QCBOR_ERR_HIT_END = 6,
-
- /** During encoding, the length of the encoded CBOR exceeded @c
- UINT32_MAX. */
- QCBOR_ERR_BUFFER_TOO_LARGE = 7,
-
- /** During decoding, an integer smaller than INT64_MIN was received
- (CBOR can represent integers smaller than INT64_MIN, but C
- cannot). */
- QCBOR_ERR_INT_OVERFLOW = 8,
-
- /** During decoding, the label for a map entry is bad. What causes
- this error depends on the decoding mode. */
- QCBOR_ERR_MAP_LABEL_TYPE = 9,
-
- /** During encoding or decoding, the number of array or map opens
- was not matched by the number of closes. */
- QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN = 10,
-
- /** During decoding, a date greater than +- 292 billion years from
- Jan 1 1970 encountered during parsing. */
- QCBOR_ERR_DATE_OVERFLOW = 11,
-
- /** During decoding, the CBOR is not valid, primarily a simple type
- is encoded in a prohibited way. */
- QCBOR_ERR_BAD_TYPE_7 = 12,
-
- /** Optional tagging that doesn't make sense (an integer is tagged
- as a date string) or can't be handled. */
- QCBOR_ERR_BAD_OPT_TAG = 13,
-
- /** Returned by QCBORDecode_Finish() if all the inputs bytes have
- not been consumed. */
- QCBOR_ERR_EXTRA_BYTES = 14,
-
- /** During encoding, @c QCBOREncode_CloseXxx() called with a
- different type than is currently open. */
- QCBOR_ERR_CLOSE_MISMATCH = 15,
-
- /** Unable to decode an indefinite-length string because no string
- allocator was configured. See QCBORDecode_SetMemPool() or
- QCBORDecode_SetUpAllocator(). */
- QCBOR_ERR_NO_STRING_ALLOCATOR = 16,
-
- /** One of the chunks in an indefinite-length string is not of the
- type of the start of the string. */
- QCBOR_ERR_INDEFINITE_STRING_CHUNK = 17,
-
- /** Error allocating space for a string, usually for an
- indefinite-length string. */
- QCBOR_ERR_STRING_ALLOCATE = 18,
-
- /** During decoding, a break occurred outside an indefinite-length
- item. */
- QCBOR_ERR_BAD_BREAK = 19,
-
- /** During decoding, too many tags in the caller-configured tag
- list, or not enough space in @ref QCBORTagListOut. */
- QCBOR_ERR_TOO_MANY_TAGS = 20,
-
- /** An integer type is encoded with a bad length (an indefinite length) */
- QCBOR_ERR_BAD_INT = 21,
-
- /** All well-formed data items have been consumed and there are no
- more. If parsing a CBOR stream this indicates the non-error
- end of the stream. If parsing a CBOR stream / sequence, this
- probably indicates that some data items expected are not present.
- See also @ref QCBOR_ERR_HIT_END. */
- QCBOR_ERR_NO_MORE_ITEMS = 22,
-
- /** Something is wrong with a decimal fraction or bigfloat such as
- it not consisting of an array with two integers */
- QCBOR_ERR_BAD_EXP_AND_MANTISSA = 23,
-
- /** When decoding, a string's size is greater than size_t. In all but some
- very strange situations this is because of corrupt input CBOR and
- should be treated as such. The strange situation is a CPU with a very
- small size_t (e.g., a 16-bit CPU) and a large string (e.g., > 65KB).
- */
- QCBOR_ERR_STRING_TOO_LONG = 24
-
-} QCBORError;
-
-
-/**
- The decode mode options.
- */
-typedef enum {
- /** See QCBORDecode_Init() */
- QCBOR_DECODE_MODE_NORMAL = 0,
- /** See QCBORDecode_Init() */
- QCBOR_DECODE_MODE_MAP_STRINGS_ONLY = 1,
- /** See QCBORDecode_Init() */
- QCBOR_DECODE_MODE_MAP_AS_ARRAY = 2
-} QCBORDecodeMode;
-
-
-
-
-
-/* Do not renumber these. Code depends on some of these values. */
-/** The data type is unknown, unset or invalid. */
-#define QCBOR_TYPE_NONE 0
-/** Type for an integer that decoded either between @c INT64_MIN and
- @c INT32_MIN or @c INT32_MAX and @c INT64_MAX. Data is in member
- @c val.int64. */
-#define QCBOR_TYPE_INT64 2
-/** Type for an integer that decoded to a more than @c INT64_MAX and
- @c UINT64_MAX. Data is in member @c val.uint64. */
-#define QCBOR_TYPE_UINT64 3
-/** Type for an array. The number of items in the array is in @c
- val.uCount. */
-#define QCBOR_TYPE_ARRAY 4
-/** Type for a map; number of items in map is in @c val.uCount. */
-#define QCBOR_TYPE_MAP 5
-/** Type for a buffer full of bytes. Data is in @c val.string. */
-#define QCBOR_TYPE_BYTE_STRING 6
-/** Type for a UTF-8 string. It is not NULL-terminated. Data is in @c
- val.string. */
-#define QCBOR_TYPE_TEXT_STRING 7
-/** Type for a positive big number. Data is in @c val.bignum, a
- pointer and a length. */
-#define QCBOR_TYPE_POSBIGNUM 9
-/** Type for a negative big number. Data is in @c val.bignum, a
- pointer and a length. */
-#define QCBOR_TYPE_NEGBIGNUM 10
-/** Type for [RFC 3339] (https://tools.ietf.org/html/rfc3339) date
- string, possibly with time zone. Data is in @c val.dateString */
-#define QCBOR_TYPE_DATE_STRING 11
-/** Type for integer seconds since Jan 1970 + floating-point
- fraction. Data is in @c val.epochDate */
-#define QCBOR_TYPE_DATE_EPOCH 12
-/** A simple type that this CBOR implementation doesn't know about;
- Type is in @c val.uSimple. */
-#define QCBOR_TYPE_UKNOWN_SIMPLE 13
-
-/** A decimal fraction made of decimal exponent and integer mantissa.
- See @ref expAndMantissa and QCBOREncode_AddDecimalFraction(). */
-#define QCBOR_TYPE_DECIMAL_FRACTION 14
-
-/** A decimal fraction made of decimal exponent and positive big
- number mantissa. See @ref expAndMantissa and
- QCBOREncode_AddDecimalFractionBigNum(). */
-#define QCBOR_TYPE_DECIMAL_FRACTION_POS_BIGNUM 15
-
-/** A decimal fraction made of decimal exponent and negative big
- number mantissa. See @ref expAndMantissa and
- QCBOREncode_AddDecimalFractionBigNum(). */
-#define QCBOR_TYPE_DECIMAL_FRACTION_NEG_BIGNUM 16
-
-/** A floating-point number made of base-2 exponent and integer
- mantissa. See @ref expAndMantissa and
- QCBOREncode_AddBigFloat(). */
-#define QCBOR_TYPE_BIGFLOAT 17
-
-/** A floating-point number made of base-2 exponent and positive big
- number mantissa. See @ref expAndMantissa and
- QCBOREncode_AddBigFloatBigNum(). */
-#define QCBOR_TYPE_BIGFLOAT_POS_BIGNUM 18
-
-/** A floating-point number made of base-2 exponent and negative big
- number mantissa. See @ref expAndMantissa and
- QCBOREncode_AddBigFloatBigNum(). */
-#define QCBOR_TYPE_BIGFLOAT_NEG_BIGNUM 19
-
-/** Type for the value false. */
-#define QCBOR_TYPE_FALSE 20
-/** Type for the value true. */
-#define QCBOR_TYPE_TRUE 21
-/** Type for the value null. */
-#define QCBOR_TYPE_NULL 22
-/** Type for the value undef. */
-#define QCBOR_TYPE_UNDEF 23
-/** Type for a floating-point number. Data is in @c val.float. */
-#define QCBOR_TYPE_FLOAT 26
-/** Type for a double floating-point number. Data is in @c val.double. */
-#define QCBOR_TYPE_DOUBLE 27
-/** For @ref QCBOR_DECODE_MODE_MAP_AS_ARRAY decode mode, a map that is
- being traversed as an array. See QCBORDecode_Init() */
-#define QCBOR_TYPE_MAP_AS_ARRAY 32
-
-#define QCBOR_TYPE_BREAK 31 // Used internally; never returned
-
-#define QCBOR_TYPE_OPTTAG 254 // Used internally; never returned
-
-
-
-/*
- Approx Size of this:
- 8 + 8 + 1 + 1 + 1 + (1 padding) + (4 padding) = 24 for first part
- (20 on a 32-bit machine)
- 16 bytes for the val union
- 16 bytes for label union
- total = 56 bytes (52 bytes on 32-bit machine)
- */
-
-/**
- The main data structure that holds the type, value and other info for
- a decoded item returned by QCBORDecode_GetNext() and
- QCBORDecode_GetNextWithTags().
- */
-typedef struct _QCBORItem {
- /** Tells what element of the @c val union to use. One of @c
- QCBOR_TYPE_XXXX */
- uint8_t uDataType;
- /** How deep the nesting from arrays and maps are. 0 is the top
- level with no arrays or maps entered. */
- uint8_t uNestingLevel;
- /** Tells what element of the label union to use. */
- uint8_t uLabelType;
- /** 1 if allocated with string allocator, 0 if not. See
- QCBORDecode_SetMemPool() or QCBORDecode_SetUpAllocator() */
- uint8_t uDataAlloc;
- /** Like @c uDataAlloc, but for label. */
- uint8_t uLabelAlloc;
- /** If not equal to @c uNestingLevel, this item closed out at least
- one map/array */
- uint8_t uNextNestLevel;
-
- /** The union holding the item's value. Select union member based
- on @c uDataType */
- union {
- /** The value for @c uDataType @ref QCBOR_TYPE_INT64. */
- int64_t int64;
- /** The value for uDataType @ref QCBOR_TYPE_UINT64. */
- uint64_t uint64;
- /** The value for @c uDataType @ref QCBOR_TYPE_BYTE_STRING and
- @ref QCBOR_TYPE_TEXT_STRING. */
- UsefulBufC string;
- /** The "value" for @c uDataType @ref QCBOR_TYPE_ARRAY or @ref
- QCBOR_TYPE_MAP -- the number of items in the array or map.
- It is @c UINT16_MAX when decoding indefinite-lengths maps
- and arrays. */
- uint16_t uCount;
- /** The value for @c uDataType @ref QCBOR_TYPE_DOUBLE. */
- double dfnum;
- /** The value for @c uDataType @ref QCBOR_TYPE_DATE_EPOCH. */
- struct {
- int64_t nSeconds;
- double fSecondsFraction;
- } epochDate;
- /** The value for @c uDataType @ref QCBOR_TYPE_DATE_STRING. */
- UsefulBufC dateString;
- /** The value for @c uDataType @ref QCBOR_TYPE_POSBIGNUM and
- @ref QCBOR_TYPE_NEGBIGNUM. */
- UsefulBufC bigNum;
- /** The integer value for unknown simple types. */
- uint8_t uSimple;
-#ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
- /** @anchor expAndMantissa
-
- The value for bigfloats and decimal fractions. The use of the
- fields in this structure depend on @c uDataType.
-
- When @c uDataType is a @c DECIMAL_FRACTION, the exponent is
- base-10. When it is a @c BIG_FLOAT it is base-2.
-
- When @c uDataType is a @c POS_BIGNUM or a @c NEG_BIGNUM then the
- @c bigNum part of @c Mantissa is valid. Otherwise the
- @c nInt part of @c Mantissa is valid.
-
- See @ref QCBOR_TYPE_DECIMAL_FRACTION,
- @ref QCBOR_TYPE_DECIMAL_FRACTION_POS_BIGNUM,
- @ref QCBOR_TYPE_DECIMAL_FRACTION_NEG_BIGNUM,
- @ref QCBOR_TYPE_BIGFLOAT, @ref QCBOR_TYPE_BIGFLOAT_POS_BIGNUM,
- and @ref QCBOR_TYPE_BIGFLOAT_NEG_BIGNUM.
-
- Also see QCBOREncode_AddDecimalFraction(), QCBOREncode_AddBigFloat(),
- QCBOREncode_AddDecimalFractionBigNum() and
- QCBOREncode_AddBigFloatBigNum().
- */
- struct {
- int64_t nExponent;
- union {
- int64_t nInt;
- UsefulBufC bigNum;
- } Mantissa;
- } expAndMantissa;
-#endif
- uint64_t uTagV; // Used internally during decoding
- } val;
-
- /** Union holding the different label types selected based on @c
- uLabelType */
- union {
- /** The label for @c uLabelType @ref QCBOR_TYPE_BYTE_STRING and
- @ref QCBOR_TYPE_TEXT_STRING */
- UsefulBufC string;
- /** The label for @c uLabelType for @ref QCBOR_TYPE_INT64 */
- int64_t int64;
- /** The label for @c uLabelType for @ref QCBOR_TYPE_UINT64 */
- uint64_t uint64;
- } label;
-
- /** Bit indicating which tags (major type 6) on this item. See
- QCBORDecode_IsTagged(). */
- uint64_t uTagBits;
-
-} QCBORItem;
-
-
-
-/**
- @brief The type defining what a string allocator function must do.
-
- @param[in] pAllocateCxt Pointer to context for the particular
- allocator implementation What is in the
- context is dependent on how a particular
- string allocator works. Typically, it
- will contain a pointer to the memory pool
- and some booking keeping data.
- @param[in] pOldMem Points to some memory allocated by the
- allocator that is either to be freed or
- to be reallocated to be larger. It is
- @c NULL for new allocations and when called as
- a destructor to clean up the whole
- allocation.
- @param[in] uNewSize Size of memory to be allocated or new
- size of chunk to be reallocated. Zero for
- a new allocation or when called as a
- destructor.
-
- @return Either the allocated buffer is returned, or @ref
- NULLUsefulBufC. @ref NULLUsefulBufC is returned on a failed
- allocation and in the two cases where there is nothing to
- return.
-
- This is called in one of four modes:
-
- Allocate -- @c uNewSize is the amount to allocate. @c pOldMem is @c
- NULL.
-
- Free -- @c uNewSize is 0. @c pOldMem points to the memory to be
- freed. When the decoder calls this, it will always be the most
- recent block that was either allocated or reallocated.
-
- Reallocate -- @c pOldMem is the block to reallocate. @c uNewSize is
- its new size. When the decoder calls this, it will always be the
- most recent block that was either allocated or reallocated.
-
- Destruct -- @c pOldMem is @c NULL and @c uNewSize is 0. This is called
- when the decoding is complete by QCBORDecode_Finish(). Usually the
- strings allocated by a string allocator are in use after the decoding
- is completed so this usually will not free those strings. Many string
- allocators will not need to do anything in this mode.
-
- The strings allocated by this will have @c uDataAlloc set to true in
- the @ref QCBORItem when they are returned. The user of the strings
- will have to free them. How they free them, depends on the string
- allocator.
-
- If QCBORDecode_SetMemPool() is called, the internal MemPool will be
- used. It has its own internal implementation of this function, so
- one does not need to be implemented.
- */
-typedef UsefulBuf (* QCBORStringAllocate)(void *pAllocateCxt, void *pOldMem, size_t uNewSize);
-
-
-/**
- This only matters if you use the built-in string allocator by setting
- it up with QCBORDecode_SetMemPool(). This is the size of the overhead
- needed by QCBORDecode_SetMemPool(). The amount of memory available
- for decoded strings will be the size of the buffer given to
- QCBORDecode_SetMemPool() less this amount.
-
- If you write your own string allocator or use the separately
- available malloc based string allocator, this size will not apply.
- */
-#define QCBOR_DECODE_MIN_MEM_POOL_SIZE 8
-
-
-/**
- This is used by QCBORDecode_SetCallerConfiguredTagList() to set a
- list of tags beyond the built-in ones.
-
- See also QCBORDecode_GetNext() for general description of tag
- decoding.
- */
-typedef struct {
- /** The number of tags in the @c puTags. The maximum size is @ref
- QCBOR_MAX_CUSTOM_TAGS. */
- uint8_t uNumTags;
- /** An array of tags to add to recognize in addition to the
- built-in ones. */
- const uint64_t *puTags;
-} QCBORTagListIn;
-
-
-/**
- This is for QCBORDecode_GetNextWithTags() to be able to return the
- full list of tags on an item. It is not needed for most CBOR protocol
- implementations. Its primary use is for pretty-printing CBOR or
- protocol conversion to another format.
-
- On input, @c puTags points to a buffer to be filled in and
- uNumAllocated is the number of @c uint64_t values in the buffer.
-
- On output the buffer contains the tags for the item. @c uNumUsed
- tells how many there are.
- */
-typedef struct {
- uint8_t uNumUsed;
- uint8_t uNumAllocated;
- uint64_t *puTags;
-} QCBORTagListOut;
/**
@@ -2180,573 +1343,6 @@
uint64_t uNumber);
-/**
- QCBORDecodeContext is the data type that holds context decoding the
- data items for some received CBOR. It is about 100 bytes, so it can
- go on the stack. The contents are opaque, and the caller should not
- access any internal items. A context may be re used serially as long
- as it is re initialized.
- */
-typedef struct _QCBORDecodeContext QCBORDecodeContext;
-
-
-/**
- Initialize the CBOR decoder context.
-
- @param[in] pCtx The context to initialize.
- @param[in] EncodedCBOR The buffer with CBOR encoded bytes to be decoded.
- @param[in] nMode See below and @ref QCBORDecodeMode.
-
- Initialize context for a pre-order traversal of the encoded CBOR
- tree.
-
- Most CBOR decoding can be completed by calling this function to start
- and QCBORDecode_GetNext() in a loop.
-
- If indefinite-length strings are to be decoded, then
- QCBORDecode_SetMemPool() or QCBORDecode_SetUpAllocator() must be
- called to set up a string allocator.
-
- If tags other than built-in tags are to be recognized and recorded in
- @c uTagBits, then QCBORDecode_SetCallerConfiguredTagList() must be
- called. The built-in tags are those for which a macro of the form @c
- CBOR_TAG_XXX is defined.
-
- Three decoding modes are supported. In normal mode, @ref
- QCBOR_DECODE_MODE_NORMAL, maps are decoded and strings and integers
- are accepted as map labels. If a label is other than these, the error
- @ref QCBOR_ERR_MAP_LABEL_TYPE is returned by QCBORDecode_GetNext().
-
- In strings-only mode, @ref QCBOR_DECODE_MODE_MAP_STRINGS_ONLY, only
- text strings are accepted for map labels. This lines up with CBOR
- that converts to JSON. The error @ref QCBOR_ERR_MAP_LABEL_TYPE is
- returned by QCBORDecode_GetNext() if anything but a text string label
- is encountered.
-
- In @ref QCBOR_DECODE_MODE_MAP_AS_ARRAY maps are treated as special
- arrays. They will be return with special @c uDataType @ref
- QCBOR_TYPE_MAP_AS_ARRAY and @c uCount, the number of items, will be
- double what it would be for a normal map because the labels are also
- counted. This mode is useful for decoding CBOR that has labels that
- are not integers or text strings, but the caller must manage much of
- the map decoding.
- */
-void QCBORDecode_Init(QCBORDecodeContext *pCtx, UsefulBufC EncodedCBOR, QCBORDecodeMode nMode);
-
-
-/**
- @brief Set up the MemPool string allocator for indefinite-length strings.
-
- @param[in] pCtx The decode context.
- @param[in] MemPool The pointer and length of the memory pool.
- @param[in] bAllStrings If true, all strings, even of definite
- length, will be allocated with the string
- allocator.
-
- @return Error if the MemPool was less than @ref QCBOR_DECODE_MIN_MEM_POOL_SIZE.
-
- indefinite-length strings (text and byte) cannot be decoded unless
- there is a string allocator configured. MemPool is a simple built-in
- string allocator that allocates bytes from a memory pool handed to it
- by calling this function. The memory pool is just a pointer and
- length for some block of memory that is to be used for string
- allocation. It can come from the stack, heap or other.
-
- The memory pool must be @ref QCBOR_DECODE_MIN_MEM_POOL_SIZE plus
- space for all the strings allocated. There is no overhead per string
- allocated. A conservative way to size this buffer is to make it the
- same size as the CBOR being decoded plus @ref
- QCBOR_DECODE_MIN_MEM_POOL_SIZE.
-
- This memory pool is used for all indefinite-length strings that are
- text strings or byte strings, including strings used as labels.
-
- The pointers to strings in @ref QCBORItem will point into the memory
- pool set here. They do not need to be individually freed. Just
- discard the buffer when they are no longer needed.
-
- If @c bAllStrings is set, then the size will be the overhead plus the
- space to hold **all** strings, definite and indefinite-length, value
- or label. The advantage of this is that after the decode is complete,
- the original memory holding the encoded CBOR does not need to remain
- valid.
-
- If this function is never called because there is no need to support
- indefinite-length strings, the internal MemPool implementation should
- be dead-stripped by the loader and not add to code size.
- */
-QCBORError QCBORDecode_SetMemPool(QCBORDecodeContext *pCtx, UsefulBuf MemPool, bool bAllStrings);
-
-
-/**
- @brief Sets up a custom string allocator for indefinite-length strings
-
- @param[in] pCtx The decoder context to set up an
- allocator for.
- @param[in] pfAllocateFunction Pointer to function that will be
- called by QCBOR for allocations and
- frees.
- @param[in] pAllocateContext Context passed to @c
- pfAllocateFunction.
- @param[in] bAllStrings If true, all strings, even of definite
- length, will be allocated with the
- string allocator.
-
- indefinite-length strings (text and byte) cannot be decoded unless
- there a string allocator is configured. QCBORDecode_SetUpAllocator()
- allows the caller to configure an external string allocator
- implementation if the internal string allocator is not suitable. See
- QCBORDecode_SetMemPool() to configure the internal allocator. Note
- that the internal allocator is not automatically set up.
-
- The string allocator configured here can be a custom one designed and
- implemented by the caller. See @ref QCBORStringAllocate for the
- requirements for a string allocator implementation.
-
- A malloc-based string external allocator can be obtained by calling
- @c QCBORDecode_MakeMallocStringAllocator(). It will return a function
- and pointer that can be given here as @c pAllocatorFunction and @c
- pAllocatorContext. It uses standard @c malloc() so @c free() must be
- called on all strings marked by @c uDataAlloc @c == @c 1 or @c
- uLabelAlloc @c == @c 1 in @ref QCBORItem.
-
- Note that an older version of this function took an allocator
- structure, rather than single function and pointer. The older
- version @c QCBORDecode_MakeMallocStringAllocator() also implemented
- the older interface.
- */
-void QCBORDecode_SetUpAllocator(QCBORDecodeContext *pCtx,
- QCBORStringAllocate pfAllocateFunction,
- void *pAllocateContext,
- bool bAllStrings);
-
-/**
- @brief Configure list of caller-selected tags to be recognized.
-
- @param[in] pCtx The decode context.
- @param[out] pTagList Structure holding the list of tags to configure.
-
- This is used to tell the decoder about tags beyond those that are
- built-in that should be recognized. The built-in tags are those with
- macros of the form @c CBOR_TAG_XXX.
-
- The list pointed to by @c pTagList must persist during decoding. No
- copy of it is made.
-
- The maximum number of tags that can be added is @ref
- QCBOR_MAX_CUSTOM_TAGS. If a list larger than this is given, the
- error will be returned when QCBORDecode_GetNext() is called, not
- here.
-
- See description of @ref QCBORTagListIn.
- */
-void QCBORDecode_SetCallerConfiguredTagList(QCBORDecodeContext *pCtx, const QCBORTagListIn *pTagList);
-
-
-/**
- @brief Gets the next item (integer, byte string, array...) in
- preorder traversal of CBOR tree.
-
- @param[in] pCtx The decoder context.
- @param[out] pDecodedItem Holds the CBOR item just decoded.
-
- @retval QCBOR_ERR_INDEFINITE_STRING_CHUNK Not well-formed, one of the
- chunks in indefinite-length
- string is wrong type.
-
- @retval QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN Not well-formed, array or map
- not closed.
-
- @retval QCBOR_ERR_UNSUPPORTED Not well-formed, input contains
- unsupported CBOR.
-
- @retval QCBOR_ERR_HIT_END Not well-formed, unexpectedly ran out
- of bytes.
-
- @retval QCBOR_ERR_BAD_TYPE_7 Not well-formed, bad simple type value.
-
- @retval QCBOR_ERR_BAD_BREAK Not well-formed, break occurs where
- not allowed.
-
- @retval QCBOR_ERR_EXTRA_BYTES Not well-formed, unprocessed bytes at
- the end.
-
- @retval QCBOR_ERR_BAD_INT Not well-formed, length of integer is
- bad.
-
- @retval QCBOR_ERR_BAD_OPT_TAG Invalid CBOR, tag on wrong type.
-
- @retval QCBOR_ERR_ARRAY_TOO_LONG Implementation limit, array or map
- too long.
-
- @retval QCBOR_ERR_INT_OVERFLOW Implementation limit, negative
- integer too large.
-
- @retval QCBOR_ERR_DATE_OVERFLOW Implementation limit, date larger
- than can be handled.
-
- @retval QCBOR_ERR_ARRAY_NESTING_TOO_DEEP Implementation limit, nesting
- too deep.
-
- @retval QCBOR_ERR_STRING_ALLOCATE Resource exhaustion, string allocator
- failed.
-
- @retval QCBOR_ERR_MAP_LABEL_TYPE Configuration error / Implementation
- limit encountered a map label this is
- not a string on an integer.
-
- @retval QCBOR_ERR_NO_STRING_ALLOCATOR Configuration error, encountered
- indefinite-length string with no
- allocator configured.
- @retval QCBOR_ERR_NO_MORE_ITEMS No more bytes to decode. The previous
- item was successfully decoded. This
- is usually how the non-error end of
- a CBOR stream / sequence is detected.
-
- @c pDecodedItem is filled in with the value parsed. Generally, the
- following data is returned in the structure:
-
- - @c uDataType which indicates which member of the @c val union the
- data is in. This decoder figures out the type based on the CBOR
- major type, the CBOR "additionalInfo", the CBOR optional tags and
- the value of the integer.
-
- - The value of the item, which might be an integer, a pointer and a
- length, the count of items in an array, a floating-point number or
- other.
-
- - The nesting level for maps and arrays.
-
- - The label for an item in a map, which may be a text or byte string
- or an integer.
-
- - The CBOR optional tag or tags.
-
- See documentation on in the data type @ref _QCBORItem for all the
- details on what is returned.
-
- This function handles arrays and maps. When first encountered a @ref
- QCBORItem will be returned with major type @ref QCBOR_TYPE_ARRAY or
- @ref QCBOR_TYPE_MAP. @c QCBORItem.val.uCount will indicate the number
- of Items in the array or map. Typically, an implementation will call
- QCBORDecode_GetNext() in a for loop to fetch them all. When decoding
- indefinite-length maps and arrays, @c QCBORItem.val.uCount is @c
- UINT16_MAX and @c uNextNestLevel must be used to know when the end of
- a map or array is reached.
-
- Nesting level 0 is the outside top-most nesting level. For example,
- in a CBOR structure with two items, an integer and a byte string
- only, both would be at nesting level 0. A CBOR structure with an
- array open, an integer and a byte string, would have the integer and
- byte string as nesting level 1.
-
- Here is an example of how the nesting level is reported with no arrays
- or maps at all.
-
- @verbatim
- CBOR Structure Nesting Level
- Integer 0
- Byte String 0
- @endverbatim
-
- Here is an example of how the nesting level is reported with a simple
- array and some top-level items.
-
- @verbatim
- Integer 0
- Array (with 2 items) 0
- Byte String 1
- Byte string 1
- Integer 0
- @endverbatim
-
-
- Here's a more complex example
- @verbatim
-
- Map with 2 items 0
- Text string 1
- Array with 3 integers 1
- integer 2
- integer 2
- integer 2
- text string 1
- byte string 1
- @endverbatim
-
- In @ref _QCBORItem, @c uNextNestLevel is the nesting level for the
- next call to QCBORDecode_GetNext(). It indicates if any maps or
- arrays were closed out during the processing of the just-fetched @ref
- QCBORItem. This processing includes a look-ahead for any breaks that
- close out indefinite-length arrays or maps. This value is needed to
- be able to understand the hierarchical structure. If @c
- uNextNestLevel is not equal to @c uNestLevel the end of the current
- map or array has been encountered. This works the same for both
- definite and indefinite-length arrays.
-
- This decoder support CBOR type 6 tagging. The decoding of particular
- given tag value may be supported in one of three different ways.
-
- First, some common tags are fully and transparently supported by
- automatically decoding them and returning them in a @ref QCBORItem.
- These tags have a @c QCBOR_TYPE_XXX associated with them and manifest
- pretty much the same as a standard CBOR type. @ref
- QCBOR_TYPE_DATE_EPOCH and the @c epochDate member of @ref QCBORItem
- is an example.
-
- Second are tags that are automatically recognized, but not decoded.
- These are tags that have a @c \#define of the form @c CBOR_TAG_XXX.
- These are recorded in the @c uTagBits member of @ref QCBORItem. There
- is an internal table that maps each bit to a particular tag value
- allowing up to 64 tags on an individual item to be reported (it is
- rare to have more than one or two). To find out if a particular tag
- value is set call QCBORDecode_IsTagged() on the @ref QCBORItem. See
- also QCBORDecode_GetNextWithTags().
-
- Third are tags that are not automatically recognized, because they
- are proprietary, custom or more recently registered with [IANA]
- (https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml). The
- internal mapping table has to be configured to recognize these. Call
- QCBORDecode_SetCallerConfiguredTagList() to do that. Then
- QCBORDecode_IsTagged() will work with them.
-
- The actual decoding of tags supported in the second and third way
- must be handled by the caller. Often this is simply verifying that
- the expected tag is present on a map, byte string or such. In other
- cases, there might a complicated map structure to decode.
-
- See @ref Tags-Overview for a description of how to go about creating
- custom tags.
-
- This tag decoding design is to be open-ended and flexible to be able
- to handle newly defined tags, while using very little memory, in
- particular keeping @ref QCBORItem as small as possible.
-
- If any error occurs, \c uDataType and \c uLabelType will be set
- to \ref QCBOR_TYPE_NONE. If there is no need to know the specific
- error, \ref QCBOR_TYPE_NONE can be checked for and the return value
- ignored.
-
- Errors fall in several categories as noted in list above:
-
- - Not well-formed errors are those where there is something
- syntactically and fundamentally wrong with the CBOR being
- decoded. Encoding should stop completely.
-
- - Invalid CBOR is well-formed, but still not correct. It is probably
- best to stop decoding, but not necessary.
-
- - This implementation has some size limits. They should rarely be
- encountered. If they are it may because something is wrong with the
- CBOR, for example an array size is incorrect.
-
- - Resource exhaustion. This only occurs when a string allocator is
- configured to handle indefinite-length strings as other than that,
- this implementation does no dynamic memory allocation.
-
- - There are a few CBOR constructs that are not handled without some
- extra configuration. These are indefinite length strings and maps
- with labels that are not strings or integers. See QCBORDecode_Init().
-
- */
-QCBORError QCBORDecode_GetNext(QCBORDecodeContext *pCtx, QCBORItem *pDecodedItem);
-
-
-/**
- @brief Gets the next item including full list of tags for item.
-
- @param[in] pCtx The decoder context.
- @param[out] pDecodedItem Holds the CBOR item just decoded.
- @param[in,out] pTagList On input array to put tags in; on output
- the tags on this item. See
- @ref QCBORTagListOut.
-
- @return See return values for QCBORDecode_GetNext().
-
- @retval QCBOR_ERR_TOO_MANY_TAGS The size of @c pTagList is too small.
-
- This works the same as QCBORDecode_GetNext() except that it also
- returns the full list of tags for the data item. This function should
- only be needed when parsing CBOR to print it out or convert it to
- some other format. It should not be needed to implement a CBOR-based
- protocol. See QCBORDecode_GetNext() for the main description of tag
- decoding.
-
- Tags will be returned here whether or not they are in the built-in or
- caller-configured tag lists.
-
- CBOR has no upper bound of limit on the number of tags that can be
- associated with a data item though in practice the number of tags on
- an item will usually be small, perhaps less than five. This will
- return @ref QCBOR_ERR_TOO_MANY_TAGS if the array in @c pTagList is
- too small to hold all the tags for the item.
-
- (This function is separate from QCBORDecode_GetNext() so as to not
- have to make @ref QCBORItem large enough to be able to hold a full
- list of tags. Even a list of five tags would nearly double its size
- because tags can be a @c uint64_t ).
- */
-QCBORError QCBORDecode_GetNextWithTags(QCBORDecodeContext *pCtx, QCBORItem *pDecodedItem, QCBORTagListOut *pTagList);
-
-
-/**
- @brief Determine if a CBOR item was tagged with a particular tag
-
- @param[in] pCtx The decoder context.
- @param[in] pItem The CBOR item to check.
- @param[in] uTag The tag to check, one of @c CBOR_TAG_XXX.
-
- @return 1 if it was tagged, 0 if not
-
- See QCBORDecode_GetNext() for the main description of tag
- handling. For tags that are not fully decoded a bit corresponding to
- the tag is set in in @c uTagBits in the @ref QCBORItem. The
- particular bit depends on an internal mapping table. This function
- checks for set bits against the mapping table.
-
- Typically, a protocol implementation just wants to know if a
- particular tag is present. That is what this provides. To get the
- full list of tags on a data item, see QCBORDecode_GetNextWithTags().
-
- Also see QCBORDecode_SetCallerConfiguredTagList() for the means to
- add new tags to the internal list so they can be checked for with
- this function.
- */
-int QCBORDecode_IsTagged(QCBORDecodeContext *pCtx, const QCBORItem *pItem, uint64_t uTag);
-
-
-/**
- Check whether all the bytes have been decoded and maps and arrays closed.
-
- @param[in] pCtx The context to check.
-
- @return An error or @ref QCBOR_SUCCESS.
-
- This tells you if all the bytes given to QCBORDecode_Init() have been
- consumed and whether all maps and arrays were closed. The decode is
- considered to be incorrect or incomplete if not and an error will be
- returned.
- */
-QCBORError QCBORDecode_Finish(QCBORDecodeContext *pCtx);
-
-
-
-
-/**
- @brief Convert int64_t to smaller integers safely.
-
- @param [in] src An @c int64_t.
- @param [out] dest A smaller sized integer to convert to.
-
- @return 0 on success -1 if not
-
- When decoding an integer, the CBOR decoder will return the value as
- an int64_t unless the integer is in the range of @c INT64_MAX and @c
- UINT64_MAX. That is, unless the value is so large that it can only be
- represented as a @c uint64_t, it will be an @c int64_t.
-
- CBOR itself doesn't size the individual integers it carries at
- all. The only limits it puts on the major integer types is that they
- are 8 bytes or less in length. Then encoders like this one use the
- smallest number of 1, 2, 4 or 8 bytes to represent the integer based
- on its value. There is thus no notion that one data item in CBOR is
- a 1-byte integer and another is a 4-byte integer.
-
- The interface to this CBOR encoder only uses 64-bit integers. Some
- CBOR protocols or implementations of CBOR protocols may not want to
- work with something smaller than a 64-bit integer. Perhaps an array
- of 1000 integers needs to be sent and none has a value larger than
- 50,000 and are represented as @c uint16_t.
-
- The sending / encoding side is easy. Integers are temporarily widened
- to 64-bits as a parameter passing through QCBOREncode_AddInt64() and
- encoded in the smallest way possible for their value, possibly in
- less than an @c uint16_t.
-
- On the decoding side the integers will be returned at @c int64_t even if
- they are small and were represented by only 1 or 2 bytes in the
- encoded CBOR. The functions here will convert integers to a small
- representation with an overflow check.
-
- (The decoder could have support 8 different integer types and
- represented the integer with the smallest type automatically, but
- this would have made the decoder more complex and code calling the
- decoder more complex in most use cases. In most use cases on 64-bit
- machines it is no burden to carry around even small integers as
- 64-bit values).
- */
-static inline int QCBOR_Int64ToInt32(int64_t src, int32_t *dest)
-{
- if(src > INT32_MAX || src < INT32_MIN) {
- return -1;
- } else {
- *dest = (int32_t) src;
- }
- return 0;
-}
-
-static inline int QCBOR_Int64ToInt16(int64_t src, int16_t *dest)
-{
- if(src > INT16_MAX || src < INT16_MIN) {
- return -1;
- } else {
- *dest = (int16_t) src;
- }
- return 0;
-}
-
-static inline int QCBOR_Int64ToInt8(int64_t src, int8_t *dest)
-{
- if(src > INT8_MAX || src < INT8_MIN) {
- return -1;
- } else {
- *dest = (int8_t) src;
- }
- return 0;
-}
-
-static inline int QCBOR_Int64ToUInt32(int64_t src, uint32_t *dest)
-{
- if(src > UINT32_MAX || src < 0) {
- return -1;
- } else {
- *dest = (uint32_t) src;
- }
- return 0;
-}
-
-static inline int QCBOR_Int64UToInt16(int64_t src, uint16_t *dest)
-{
- if(src > UINT16_MAX || src < 0) {
- return -1;
- } else {
- *dest = (uint16_t) src;
- }
- return 0;
-}
-
-static inline int QCBOR_Int64ToUInt8(int64_t src, uint8_t *dest)
-{
- if(src > UINT8_MAX || src < 0) {
- return -1;
- } else {
- *dest = (uint8_t) src;
- }
- return 0;
-}
-
-static inline int QCBOR_Int64ToUInt64(int64_t src, uint64_t *dest)
-{
- if(src > 0) {
- return -1;
- } else {
- *dest = (uint64_t) src;
- }
- return 0;
-}
-
-
-
/* ===========================================================================
@@ -3583,4 +2179,4 @@
}
#endif
-#endif /* defined(__QCBOR__qcbor__) */
+#endif /* qcbor_encode_h */
diff --git a/inc/qcbor/qcbor_private.h b/inc/qcbor/qcbor_private.h
new file mode 100644
index 0000000..6bc3f70
--- /dev/null
+++ b/inc/qcbor/qcbor_private.h
@@ -0,0 +1,185 @@
+/*==============================================================================
+ Copyright (c) 2016-2018, The Linux Foundation.
+ Copyright (c) 2018-2020, Laurence Lundblade.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors, nor the name "Laurence Lundblade" may be used to
+ endorse or promote products derived from this software without
+ specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ =============================================================================*/
+
+
+#ifndef qcbor_private_h
+#define qcbor_private_h
+
+
+#include <stdint.h>
+#include "UsefulBuf.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#ifdef 0
+} // Keep editor indention formatting happy
+#endif
+#endif
+
+
+/*
+ The maxium nesting of arrays and maps when encoding or decoding.
+ (Further down in the file there is a definition that refers to this
+ that is public. This is done this way so there can be a nice
+ separation of public and private parts in this file.
+*/
+#define QCBOR_MAX_ARRAY_NESTING1 15 // Do not increase this over 255
+
+
+/* The largest offset to the start of an array or map. It is slightly
+ less than UINT32_MAX so the error condition can be tests on 32-bit machines.
+ UINT32_MAX comes from uStart in QCBORTrackNesting being a uin32_t.
+
+ This will cause trouble on a machine where size_t is less than 32-bits.
+ */
+#define QCBOR_MAX_ARRAY_OFFSET (UINT32_MAX - 100)
+
+/*
+ PRIVATE DATA STRUCTURE
+
+ Holds the data for tracking array and map nesting during encoding. Pairs up
+ with the Nesting_xxx functions to make an "object" to handle nesting encoding.
+
+ uStart is a uint32_t instead of a size_t to keep the size of this
+ struct down so it can be on the stack without any concern. It would be about
+ double if size_t was used instead.
+
+ Size approximation (varies with CPU/compiler):
+ 64-bit machine: (15 + 1) * (4 + 2 + 1 + 1 pad) + 8 = 136 bytes
+ 32-bit machine: (15 + 1) * (4 + 2 + 1 + 1 pad) + 4 = 132 bytes
+*/
+typedef struct __QCBORTrackNesting {
+ // PRIVATE DATA STRUCTURE
+ struct {
+ // See function QCBOREncode_OpenMapOrArray() for details on how this works
+ uint32_t uStart; // uStart is the byte position where the array starts
+ uint16_t uCount; // Number of items in the arrary or map; counts items
+ // in a map, not pairs of items
+ uint8_t uMajorType; // Indicates if item is a map or an array
+ } pArrays[QCBOR_MAX_ARRAY_NESTING1+1], // stored state for the nesting levels
+ *pCurrentNesting; // the current nesting level
+} QCBORTrackNesting;
+
+
+/*
+ PRIVATE DATA STRUCTURE
+
+ Context / data object for encoding some CBOR. Used by all encode functions to
+ form a public "object" that does the job of encdoing.
+
+ Size approximation (varies with CPU/compiler):
+ 64-bit machine: 27 + 1 (+ 4 padding) + 136 = 32 + 136 = 168 bytes
+ 32-bit machine: 15 + 1 + 132 = 148 bytes
+*/
+struct _QCBOREncodeContext {
+ // PRIVATE DATA STRUCTURE
+ UsefulOutBuf OutBuf; // Pointer to output buffer, its length and
+ // position in it
+ uint8_t uError; // Error state, always from QCBORError enum
+ QCBORTrackNesting nesting; // Keep track of array and map nesting
+};
+
+
+/*
+ PRIVATE DATA STRUCTURE
+
+ Holds the data for array and map nesting for decoding work. This structure
+ and the DecodeNesting_xxx functions form an "object" that does the work
+ for arrays and maps.
+
+ Size approximation (varies with CPU/compiler):
+ 64-bit machine: 4 * 16 + 8 = 72
+ 32-bit machine: 4 * 16 + 4 = 68
+ */
+typedef struct __QCBORDecodeNesting {
+ // PRIVATE DATA STRUCTURE
+ struct {
+ uint16_t uCount;
+ uint8_t uMajorType;
+ } pMapsAndArrays[QCBOR_MAX_ARRAY_NESTING1+1],
+ *pCurrent;
+} QCBORDecodeNesting;
+
+
+typedef struct {
+ // PRIVATE DATA STRUCTURE
+ void *pAllocateCxt;
+ UsefulBuf (* pfAllocator)(void *pAllocateCxt, void *pOldMem, size_t uNewSize);
+} QCORInternalAllocator;
+
+
+/*
+ PRIVATE DATA STRUCTURE
+
+ The decode context. This data structure plus the public QCBORDecode_xxx
+ functions form an "object" that does CBOR decoding.
+
+ Size approximation (varies with CPU/compiler):
+ 64-bit machine: 32 + 1 + 1 + 6 bytes padding + 72 + 16 + 8 + 8 = 144 bytes
+ 32-bit machine: 16 + 1 + 1 + 2 bytes padding + 68 + 8 + 8 + 4 = 108 bytes
+ */
+struct _QCBORDecodeContext {
+ // PRIVATE DATA STRUCTURE
+ UsefulInputBuf InBuf;
+
+ uint8_t uDecodeMode;
+ uint8_t bStringAllocateAll;
+
+ QCBORDecodeNesting nesting;
+
+ // If a string allocator is configured for indefinite-length
+ // strings, it is configured here.
+ QCORInternalAllocator StringAllocator;
+
+ // These are special for the internal MemPool allocator.
+ // They are not used otherwise. We tried packing these
+ // in the MemPool itself, but there are issues
+ // with memory alignment.
+ uint32_t uMemPoolSize;
+ uint32_t uMemPoolFreeOffset;
+
+ // This is NULL or points to QCBORTagList.
+ // It is type void for the same reason as above.
+ const void *pCallerConfiguredTagList;
+};
+
+// Used internally in the impementation here
+// Must not conflict with any of the official CBOR types
+#define CBOR_MAJOR_NONE_TYPE_RAW 9
+#define CBOR_MAJOR_NONE_TAG_LABEL_REORDER 10
+#define CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY 11
+#define CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN 12
+#define CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN 13
+
+
+#endif /* qcbor_private_h */