Clean up some tag decoding
diff --git a/inc/qcbor/qcbor_common.h b/inc/qcbor/qcbor_common.h
index 6180240..521ef6e 100644
--- a/inc/qcbor/qcbor_common.h
+++ b/inc/qcbor/qcbor_common.h
@@ -174,15 +174,17 @@
(https://tools.ietf.org/html/rfc5870) and WGS-84. No API is
provided for this tag. */
#define CBOR_TAG_GEO_COORD 103
-
-/** Binary MIME */
+/** Binary MIME.*/
#define CBOR_TAG_BINARY_MIME 257
-
/** 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
+/** Three different values for invalid tag from the CBOR tags registry */
+#define CBOR_TAG_INVALID16 0xffff
+#define CBOR_TAG_INVALID32 0xffffffff
+#define CBOR_TAG_INVALID64 0xffffffffffffffff
+
/*
@@ -300,7 +302,9 @@
item. */
QCBOR_ERR_BAD_BREAK = 19,
- /** During decoding, too many tags in the caller-configured tag
+ /** More than @ref QCBOR_MAX_TAGS_PER_ITEM tags encounterd for a CBOR ITEM.
+ @ref QCBOR_MAX_TAGS_PER_ITEM is a limit of this implementation.
+ During decoding, too many tags in the caller-configured tag
list, or not enough space in @ref QCBORTagListOut. */
QCBOR_ERR_TOO_MANY_TAGS = 20,
@@ -352,9 +356,9 @@
QCBOR_ERR_NOT_ENTERED = 31,
/** A callback indicates processing should not continue for some non-CBOR reason */
- QCBOR_ERR_CALLBACK_FAIL = 32,
-
- /* This is stored in uint8_t in places; never add values > 255 */
+ QCBOR_ERR_CALLBACK_FAIL = 32
+
+ /* This is stored in uint8_t; never add values > 255 */
} QCBORError;
diff --git a/inc/qcbor/qcbor_decode.h b/inc/qcbor/qcbor_decode.h
index 282ffde..5da7ba3 100644
--- a/inc/qcbor/qcbor_decode.h
+++ b/inc/qcbor/qcbor_decode.h
@@ -936,6 +936,34 @@
/**
+ @brief Returns the tag values for an item.
+
+ @param[in] pCtx The decoder context.
+ @param[in] pItem The CBOR item to get the tag for.
+ @param[in] uIndex The index of the tag to get.
+
+ @returns The actual nth tag value.
+
+ Up to \ref QCBOR_MAX_TAGS_PER_ITEM are recorded for a decoded CBOR item. If there
+ are more than this, the \ref QCBOR_ERR_TOO_MANY_TAGS error is returned
+ by QCBORDecode_GetNext() and other. This is a limit of this implementation,
+ not of CBOR.
+
+ The 0th tag (@c uIndex 0) is the one that occurs closest to the data item.
+ Tags nest, so the nth tag applies to what ever type
+ is a result of applying the (n-1) tag.
+
+ To reduce memory used by a QCBORItem, this implementation maps
+ all tags larger than UINT16_MAX. This function does the unmapping.
+
+ This returns \ref CBOR_TAG_INVALID16 on all errors or if the nth tag is requested and
+ there is no nth tag. If there are no tags on the item, then
+ requesting the 0th tag will return \ref CBOR_TAG_INVALID16.
+ */
+uint64_t QCBORDecode_GetNthTag(QCBORDecodeContext *pCtx, const QCBORItem *pItem, unsigned int uIndex);
+
+
+/**
@brief Check whether all the bytes have been decoded and maps and arrays closed.
@param[in] pCtx The context to check.
@@ -1885,32 +1913,8 @@
return 0;
}
-#define FOFOO (0xffff - 1024)
-/*
- Returns the tag values for an item.
- The 0th tag is the one that occurs closest to the data item.
- Tags nest, so the nth tag applies to what ever type
- is a result of applying the (n-1) tag.
-
- This returns 0xffff on all errors or if the nth tag is requested and
- there is no nth tag. If there are no tags on the item, then
- requesting the 0th tag will return 0xffff.
-
- */
-static inline uint64_t QCBORDecode_GetNthTag(QCBORDecodeContext *pMe, const QCBORItem *pItem, unsigned int uIndex)
-{
- if(uIndex > QCBOR_MAX_TAGS_PER_ITEM) {
- return 0xffff; // TODO constant for standard bad tag value
- }
-
- if(pItem->uTags[uIndex] > FOFOO) {
- return pItem->uTags[uIndex];
- } else {
- return pMe->auMappedTags[pItem->uTags[uIndex] - FOFOO];
- }
-}
static inline QCBORError QCBORDecode_GetError(QCBORDecodeContext *pMe)
{
diff --git a/inc/qcbor/qcbor_private.h b/inc/qcbor/qcbor_private.h
index 02cbf86..c96740f 100644
--- a/inc/qcbor/qcbor_private.h
+++ b/inc/qcbor/qcbor_private.h
@@ -70,6 +70,10 @@
*/
#define QCBOR_NUM_MAPPED_TAGS 4
+#define QCBOR_MAX_NUM_MAPPED_TAGS 1024
+
+#define QCBOR_LAST_UNMAPPED_TAG (CBOR_TAG_INVALID16 - QCBOR_MAX_NUM_MAPPED_TAGS)
+
/*
PRIVATE DATA STRUCTURE
diff --git a/src/qcbor_decode.c b/src/qcbor_decode.c
index 3913e7e..f58c6c3 100644
--- a/src/qcbor_decode.c
+++ b/src/qcbor_decode.c
@@ -397,7 +397,7 @@
me->uDecodeMode = (uint8_t)nDecodeMode;
DecodeNesting_Init(&(me->nesting));
for(int i = 0; i < QCBOR_NUM_MAPPED_TAGS; i++) {
- me->auMappedTags[i] = 0xffff;
+ me->auMappedTags[i] = CBOR_TAG_INVALID16;
}
}
@@ -942,7 +942,10 @@
// Stack usage: int/ptr: 3 -- 24
QCBORError nReturn;
- uint16_t auTags[QCBOR_MAX_TAGS_PER_ITEM] = {0xffff, 0xffff, 0xffff, 0xffff};
+ uint16_t auTags[QCBOR_MAX_TAGS_PER_ITEM] = {CBOR_TAG_INVALID16,
+ CBOR_TAG_INVALID16,
+ CBOR_TAG_INVALID16,
+ CBOR_TAG_INVALID16};
// Loop fetching items until the item fetched is not a tag
for(;;) {
@@ -960,20 +963,20 @@
// Is there room for the tag in the tags list?
size_t uTagIndex;
for(uTagIndex = 0; uTagIndex < QCBOR_MAX_TAGS_PER_ITEM; uTagIndex++) {
- if(auTags[uTagIndex] == 0xffff) {
+ if(auTags[uTagIndex] == CBOR_TAG_INVALID16) {
break;
}
}
if(uTagIndex >= QCBOR_MAX_TAGS_PER_ITEM) {
- return 99; // TODO error code
+ return QCBOR_ERR_TOO_MANY_TAGS;
}
// Is the tag > 16 bits?
- if(pDecodedItem->val.uTagV > 0xffff) {
+ if(pDecodedItem->val.uTagV > CBOR_TAG_INVALID16) {
size_t uTagMapIndex;
// Is there room in the tag map?
for(uTagMapIndex = 0; uTagMapIndex < QCBOR_NUM_MAPPED_TAGS; uTagMapIndex++) {
- if(me->auMappedTags[uTagMapIndex] == 0xffff) {
+ if(me->auMappedTags[uTagMapIndex] == CBOR_TAG_INVALID16) {
break;
}
if(me->auMappedTags[uTagMapIndex] == pDecodedItem->val.uTagV) {
@@ -1678,7 +1681,7 @@
nReturn = DecodeUUID(pDecodedItem);
break;
- case 0xffff:
+ case CBOR_TAG_INVALID16:
// The end of the tag list or no tags
// Successful exit from the loop.
goto Done;
@@ -1733,7 +1736,7 @@
if(pTags != NULL) {
pTags->uNumUsed = 0;
for(int i = 0; i < QCBOR_MAX_TAGS_PER_ITEM; i++) {
- if(pDecodedItem->uTags[i] == 0xffff) {
+ if(pDecodedItem->uTags[i] == CBOR_TAG_INVALID16) {
break;
}
if(pTags->uNumUsed >= pTags->uNumAllocated) {
@@ -1799,7 +1802,7 @@
uint64_t uTag)
{
for(int i = 0; i < QCBOR_MAX_TAGS_PER_ITEM; i++ ) {
- if(pItem->uTags[i] == 0xffff) {
+ if(pItem->uTags[i] == CBOR_TAG_INVALID16) {
break;
}
if(ConvertTag(me, pItem->uTags[i]) == uTag) {
@@ -1838,6 +1841,22 @@
}
+/*
+Public function, see header qcbor/qcbor_decode.h file
+*/
+uint64_t QCBORDecode_GetNthTag(QCBORDecodeContext *pMe, const QCBORItem *pItem, unsigned int uIndex)
+{
+ if(uIndex > QCBOR_MAX_TAGS_PER_ITEM) {
+ return CBOR_TAG_INVALID16;
+ } else if(pItem->uTags[uIndex] <= QCBOR_LAST_UNMAPPED_TAG) {
+ return pItem->uTags[uIndex];
+ } else if(pItem->uTags[uIndex] < QCBOR_NUM_MAPPED_TAGS + QCBOR_LAST_UNMAPPED_TAG) {
+ return pMe->auMappedTags[pItem->uTags[uIndex] - QCBOR_LAST_UNMAPPED_TAG];
+ } else {
+ return CBOR_TAG_INVALID16;
+ }
+}
+
/*