diff --git a/src/decode_nesting.h b/src/decode_nesting.h
new file mode 100644
index 0000000..0e1c3a1
--- /dev/null
+++ b/src/decode_nesting.h
@@ -0,0 +1,419 @@
+/* ==========================================================================
+ * decode_nesting.c -- All inline implementation of QCBORDecodeNesting
+ *
+ * Copyright (c) 2016-2018, The Linux Foundation.
+ * Copyright (c) 2018-2024, Laurence Lundblade.
+ * Copyright (c) 2021, Arm Limited.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Forked from qcbor_decode.c on 11/28/24
+ * ========================================================================== */
+
+#ifndef decode_nesting_h
+#define decode_nesting_h
+
+#include "qcbor/qcbor_private.h"
+
+
+/* When this was not all explicitly inline, the compiler decided to
+ * inline everything on its own, so we know there's no loss by
+ * making it all inline.
+ */
+
+static inline void
+DecodeNesting_Init(QCBORDecodeNesting *pNesting)
+{
+   /* Assumes that *pNesting has been zero'd before this call. */
+   pNesting->pLevels[0].uLevelType = QCBOR_TYPE_BYTE_STRING;
+   pNesting->pCurrent = &(pNesting->pLevels[0]);
+}
+
+
+static inline bool
+DecodeNesting_IsCurrentDefiniteLength(const QCBORDecodeNesting *pNesting)
+{
+   if(pNesting->pCurrent->uLevelType == QCBOR_TYPE_BYTE_STRING) {
+      /* Not a map or array */
+      return false;
+   }
+
+#ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS
+   if(pNesting->pCurrent->u.ma.uCountTotal == QCBOR_COUNT_INDICATES_INDEFINITE_LENGTH) {
+      /* Is indefinite */
+      return false;
+   }
+
+#endif /* ! QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
+
+   /* All checks passed; is a definte length map or array */
+   return true;
+}
+
+
+static inline bool
+DecodeNesting_IsBoundedType(const QCBORDecodeNesting *pNesting, uint8_t uType)
+{
+   if(pNesting->pCurrentBounded == NULL) {
+      return false;
+   }
+
+   uint8_t uItemDataType = pNesting->pCurrentBounded->uLevelType;
+#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
+   if(uItemDataType == QCBOR_TYPE_MAP_AS_ARRAY) {
+      uItemDataType = QCBOR_TYPE_ARRAY;
+   }
+#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
+
+   if(uItemDataType != uType) {
+      return false;
+   }
+
+   return true;
+}
+
+
+static inline bool
+DecodeNesting_IsCurrentBounded(const QCBORDecodeNesting *pNesting)
+{
+   if(pNesting->pCurrent->uLevelType == QCBOR_TYPE_BYTE_STRING) {
+      return true;
+   }
+   if(pNesting->pCurrent->u.ma.uStartOffset != QCBOR_NON_BOUNDED_OFFSET) {
+      return true;
+   }
+   return false;
+}
+
+
+static inline bool
+DecodeNesting_IsBoundedEmpty(const QCBORDecodeNesting *pNesting)
+{
+   if(pNesting->pCurrentBounded->u.ma.uCountCursor == QCBOR_COUNT_INDICATES_ZERO_LENGTH) {
+      return true;
+   } else {
+      return false;
+   }
+}
+
+
+static inline bool
+DecodeNesting_IsAtEndOfBoundedLevel(const QCBORDecodeNesting *pNesting)
+{
+   if(pNesting->pCurrentBounded == NULL) {
+      /* No bounded map or array set up */
+      return false;
+   }
+   if(pNesting->pCurrent->uLevelType == QCBOR_TYPE_BYTE_STRING) {
+      /* Not a map or array; end of those is by byte count */
+      return false;
+   }
+   if(!DecodeNesting_IsCurrentBounded(pNesting)) {
+      /* In a traveral at a level deeper than the bounded level */
+      return false;
+   }
+   /* Works for both definite- and indefinitelength maps/arrays */
+   if(pNesting->pCurrentBounded->u.ma.uCountCursor != 0 &&
+      pNesting->pCurrentBounded->u.ma.uCountCursor != QCBOR_COUNT_INDICATES_ZERO_LENGTH) {
+      /* Count is not zero, still unconsumed item */
+      return false;
+   }
+   /* All checks passed, got to the end of an array or map*/
+   return true;
+}
+
+
+static inline bool
+DecodeNesting_IsEndOfDefiniteLengthMapOrArray(const QCBORDecodeNesting *pNesting)
+{
+   /* Must only be called on map / array */
+   if(pNesting->pCurrent->u.ma.uCountCursor == 0) {
+      return true;
+   } else {
+      return false;
+   }
+}
+
+
+static inline bool
+DecodeNesting_IsCurrentTypeMap(const QCBORDecodeNesting *pNesting)
+{
+   if(pNesting->pCurrent->uLevelType == CBOR_MAJOR_TYPE_MAP) {
+      return true;
+   } else {
+      return false;
+   }
+}
+
+
+static inline bool
+DecodeNesting_IsCurrentAtTop(const QCBORDecodeNesting *pNesting)
+{
+   if(pNesting->pCurrent == &(pNesting->pLevels[0])) {
+      return true;
+   } else {
+      return false;
+   }
+}
+
+
+static inline bool
+DecodeNesting_IsCurrentBstrWrapped(const QCBORDecodeNesting *pNesting)
+{
+   if(pNesting->pCurrent->uLevelType == QCBOR_TYPE_BYTE_STRING) {
+      /* is a byte string */
+      return true;
+   }
+   return false;
+}
+
+
+static inline uint8_t
+DecodeNesting_GetCurrentLevel(const QCBORDecodeNesting *pNesting)
+{
+   const ptrdiff_t nLevel = pNesting->pCurrent - &(pNesting->pLevels[0]);
+   /* Limit in DecodeNesting_Descend against more than
+    * QCBOR_MAX_ARRAY_NESTING gaurantees cast is safe
+    */
+   return (uint8_t)nLevel;
+}
+
+
+
+
+static inline void
+DecodeNesting_DecrementDefiniteLengthMapOrArrayCount(QCBORDecodeNesting *pNesting)
+{
+   /* Only call on a definite-length array / map */
+   pNesting->pCurrent->u.ma.uCountCursor--;
+}
+
+
+static inline void
+DecodeNesting_ZeroMapOrArrayCount(QCBORDecodeNesting *pNesting)
+{
+   pNesting->pCurrent->u.ma.uCountCursor = 0;
+}
+
+static inline void
+DecodeNesting_ResetMapOrArrayCount(QCBORDecodeNesting *pNesting)
+{
+   if(pNesting->pCurrent->u.ma.uCountCursor != QCBOR_COUNT_INDICATES_ZERO_LENGTH) {
+      pNesting->pCurrentBounded->u.ma.uCountCursor = pNesting->pCurrentBounded->u.ma.uCountTotal;
+   }
+}
+
+static inline void
+DecodeNesting_ReverseDecrement(QCBORDecodeNesting *pNesting)
+{
+   /* Only call on a definite-length array / map */
+   pNesting->pCurrent->u.ma.uCountCursor++;
+}
+
+
+
+
+static inline void
+DecodeNesting_ClearBoundedMode(QCBORDecodeNesting *pNesting)
+{
+   pNesting->pCurrent->u.ma.uStartOffset = QCBOR_NON_BOUNDED_OFFSET;
+}
+
+
+static inline QCBORError
+DecodeNesting_Descend(QCBORDecodeNesting *pNesting, uint8_t uType)
+{
+   /* Error out if nesting is too deep */
+   if(pNesting->pCurrent >= &(pNesting->pLevels[QCBOR_MAX_ARRAY_NESTING])) {
+      return QCBOR_ERR_ARRAY_DECODE_NESTING_TOO_DEEP;
+   }
+
+   /* The actual descend */
+   pNesting->pCurrent++;
+
+   pNesting->pCurrent->uLevelType = uType;
+
+   return QCBOR_SUCCESS;
+}
+
+static inline QCBORError
+DecodeNesting_DescendMapOrArray(QCBORDecodeNesting *pNesting,
+                                const uint8_t       uQCBORType,
+                                const uint16_t      uCount)
+{
+   QCBORError uError = QCBOR_SUCCESS;
+
+   if(uCount == 0) {
+      /* Nothing to do for empty definite-length arrays. They are just are
+       * effectively the same as an item that is not a map or array.
+       */
+      goto Done;
+      /* Empty indefinite-length maps and arrays are handled elsewhere */
+   }
+
+   /* Rely on check in QCBOR_Private_DecodeArrayOrMap() for definite-length
+    * arrays and maps that are too long */
+
+   uError = DecodeNesting_Descend(pNesting, uQCBORType);
+   if(uError != QCBOR_SUCCESS) {
+      goto Done;
+   }
+
+   pNesting->pCurrent->u.ma.uCountCursor = uCount;
+   pNesting->pCurrent->u.ma.uCountTotal  = uCount;
+
+   DecodeNesting_ClearBoundedMode(pNesting);
+
+Done:
+   return uError;;
+}
+
+
+static inline QCBORError
+DecodeNesting_DescendIntoBstrWrapped(QCBORDecodeNesting *pNesting,
+                                     uint32_t            uEndOffset,
+                                     uint32_t            uStartOffset)
+{
+   QCBORError uError;
+
+   uError = DecodeNesting_Descend(pNesting, QCBOR_TYPE_BYTE_STRING);
+   if(uError != QCBOR_SUCCESS) {
+      goto Done;
+   }
+
+   /* Fill in the new byte string level */
+   pNesting->pCurrent->u.bs.uSavedEndOffset  = uEndOffset;
+   pNesting->pCurrent->u.bs.uBstrStartOffset = uStartOffset;
+
+   /* Bstr wrapped levels are always bounded */
+   pNesting->pCurrentBounded = pNesting->pCurrent;
+
+Done:
+   return uError;;
+}
+
+
+static inline void
+DecodeNesting_Ascend(QCBORDecodeNesting *pNesting)
+{
+   pNesting->pCurrent--;
+}
+
+
+
+
+static inline void
+DecodeNesting_SetCurrentToBoundedLevel(QCBORDecodeNesting *pNesting)
+{
+   pNesting->pCurrent = pNesting->pCurrentBounded;
+}
+
+static inline void
+DecodeNesting_SetMapOrArrayBoundedMode(QCBORDecodeNesting *pNesting, bool bIsEmpty, size_t uStart)
+{
+   /* Should be only called on maps and arrays */
+   /*
+    * DecodeNesting_EnterBoundedMode() checks to be sure uStart is not
+    * larger than DecodeNesting_EnterBoundedMode which keeps it less than
+    * uin32_t so the cast is safe.
+    */
+   pNesting->pCurrent->u.ma.uStartOffset = (uint32_t)uStart;
+
+   if(bIsEmpty) {
+      pNesting->pCurrent->u.ma.uCountCursor = QCBOR_COUNT_INDICATES_ZERO_LENGTH;
+   }
+}
+
+static inline QCBORError
+DecodeNesting_EnterBoundedMapOrArray(QCBORDecodeNesting *pNesting,
+                                     bool                bIsEmpty,
+                                     size_t              uOffset)
+{
+   /*
+    * Should only be called on map/array.
+    *
+    * Have descended into this before this is called. The job here is
+    * just to mark it in bounded mode.
+    *
+    * Check against QCBOR_MAX_DECODE_INPUT_SIZE make sure that
+    * uOffset doesn't collide with QCBOR_NON_BOUNDED_OFFSET.
+    *
+    * Cast of uOffset to uint32_t for cases where SIZE_MAX < UINT32_MAX.
+    */
+   if((uint32_t)uOffset >= QCBOR_MAX_DECODE_INPUT_SIZE) {
+      return QCBOR_ERR_INPUT_TOO_LARGE;
+   }
+
+   pNesting->pCurrentBounded = pNesting->pCurrent;
+
+   DecodeNesting_SetMapOrArrayBoundedMode(pNesting, bIsEmpty, uOffset);
+
+   return QCBOR_SUCCESS;
+}
+
+
+static inline uint32_t
+DecodeNesting_GetPreviousBoundedEnd(const QCBORDecodeNesting *pMe)
+{
+   return pMe->pCurrentBounded->u.bs.uSavedEndOffset;
+}
+
+
+static inline uint8_t
+DecodeNesting_GetBoundedModeLevel(const QCBORDecodeNesting *pNesting)
+{
+   const ptrdiff_t nLevel = pNesting->pCurrentBounded - &(pNesting->pLevels[0]);
+   /* Limit in DecodeNesting_Descend against more than
+    * QCBOR_MAX_ARRAY_NESTING gaurantees cast is safe
+    */
+   return (uint8_t)nLevel;
+}
+
+
+
+
+static inline uint32_t
+DecodeNesting_GetMapOrArrayStart(const QCBORDecodeNesting *pNesting)
+{
+   return pNesting->pCurrentBounded->u.ma.uStartOffset;
+}
+
+
+static inline void
+DecodeNesting_LevelUpCurrent(QCBORDecodeNesting *pNesting)
+{
+   pNesting->pCurrent = pNesting->pCurrentBounded - 1;
+}
+
+
+static inline void
+DecodeNesting_LevelUpBounded(QCBORDecodeNesting *pNesting)
+{
+   while(pNesting->pCurrentBounded != &(pNesting->pLevels[0])) {
+      pNesting->pCurrentBounded--;
+      if(DecodeNesting_IsCurrentBounded(pNesting)) {
+         break;
+      }
+   }
+}
+
+
+
+
+static inline void
+DecodeNesting_PrepareForMapSearch(QCBORDecodeNesting *pNesting,
+                                  QCBORDecodeNesting *pSave)
+{
+   *pSave = *pNesting;
+}
+
+
+static inline void
+DecodeNesting_RestoreFromMapSearch(QCBORDecodeNesting *pNesting,
+                                   const QCBORDecodeNesting *pSave)
+{
+   *pNesting = *pSave;
+}
+
+#endif /* decode_nesting_h */
diff --git a/src/decode_private.h b/src/decode_private.h
index 506c668..c1d6f9f 100644
--- a/src/decode_private.h
+++ b/src/decode_private.h
@@ -1,79 +1,113 @@
-/*==============================================================================
- Copyright (c) 2016-2018, The Linux Foundation.
- Copyright (c) 2018-2024, Laurence Lundblade.
- Copyright (c) 2021, Arm Limited.
- All rights reserved.
+/* ==========================================================================
+ * decode_private.c -- semi-private & inline functions for qcbor_decode.c
+ *
+ * Copyright (c) 2016-2018, The Linux Foundation.
+ * Copyright (c) 2018-2024, Laurence Lundblade.
+ * Copyright (c) 2021, Arm Limited.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Forked from qcbor_decode.c on 11/14/24
+ * ========================================================================== */
 
- Created on 11/14/24 from qcbor_decode.c
-
-
-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 decode_private_h
 #define decode_private_h
 
+#include "qcbor/qcbor_decode.h"
+#include "qcbor/qcbor_spiffy_decode.h" /* For QCBORItemCallback */
 
+/* These are decode functions used by the spiffy decode and number decode
+ * implementation. They are internal linkage and nothing to do with
+ * the public decode interface.
+ */
+
+/* Semi-private function. See qcbor_decode.c */
 QCBORError
 QCBORDecode_Private_GetNextTagContent(QCBORDecodeContext *pMe,
                                       QCBORItem          *pDecodedItem);
 
-void
-QCBORDecode_Private_ProcessTagItemMulti(QCBORDecodeContext      *pMe,
-                                        QCBORItem               *pItem,
-                                        const uint8_t            uTagRequirement,
-                                        const uint8_t            uQCBORTypes[],
-                                        const uint64_t           uTagNumbers[],
-                                        QCBORTagContentCallBack *pfCB,
-                                        size_t                   uOffset);
 
-
-void
-QCBORDecode_Private_ProcessTagItem(QCBORDecodeContext      *pMe,
-                                   QCBORItem               *pItem,
-                                   const uint8_t            uTagRequirement,
-                                   const uint8_t            uQCBORTypes[],
-                                   const uint64_t           uTagNumber,
-                                   QCBORTagContentCallBack *pfCB,
-                                   size_t                   uOffset);
-
+/* Semi-private function. See qcbor_decode.c */
 void
 QCBORDecode_Private_GetItemInMapNoCheckSZ(QCBORDecodeContext *pMe,
-                                  const char         *szLabel,
-                                  const uint8_t       uQcborType,
-                                  QCBORItem          *pItem,
-                                  size_t             *puOffset);
+                                          const char         *szLabel,
+                                          const uint8_t       uQcborType,
+                                          QCBORItem          *pItem,
+                                          size_t             *puOffset);
 
+/* Semi-private function. See qcbor_decode.c */
 void
 QCBORDecode_Private_GetItemInMapNoCheckN(QCBORDecodeContext *pMe,
-                                 const int64_t       nLabel,
-                                 const uint8_t       uQcborType,
-                                 QCBORItem          *pItem,
-                                 size_t             *puOffset);
+                                         const int64_t       nLabel,
+                                         const uint8_t       uQcborType,
+                                         QCBORItem          *pItem,
+                                         size_t             *puOffset);
+
+
+/* Semi-private function. See qcbor_decode.c */
+uint64_t
+QCBORDecode_Private_UnMapTagNumber(const QCBORDecodeContext *pMe,
+                                   const uint16_t            uMappedTagNumber);
+
+/* Semi-private function. See qcbor_decode.c */
+QCBORError
+QCBORDecode_Private_ConsumeItem(QCBORDecodeContext *pMe,
+                                const QCBORItem    *pItemToConsume,
+                                bool               *pbBreak,
+                                uint8_t            *puNextNestLevel);
+
+/* Semi-private function. See qcbor_decode.c */
+QCBORError
+QCBORDecode_Private_GetItemChecks(QCBORDecodeContext *pMe,
+                                  QCBORError          uErr,
+                                  const size_t        uOffset,
+                                  QCBORItem          *pDecodedItem);
+
+/* Semi-private function. See qcbor_decode.c */
+QCBORError
+QCBORDecode_Private_NestLevelAscender(QCBORDecodeContext *pMe,
+                                      bool                bMarkEnd,
+                                      bool               *pbBreak);
+
+
+typedef struct {
+   void               *pCBContext;
+   QCBORItemCallback   pfCallback;
+} MapSearchCallBack;
+
+typedef struct {
+   size_t   uStartOffset;
+   uint16_t uItemCount;
+} MapSearchInfo;
+
+/* Semi-private function. See qcbor_decode.c */
+QCBORError
+QCBORDecode_Private_MapSearch(QCBORDecodeContext *pMe,
+                              QCBORItem          *pItemArray,
+                              MapSearchInfo      *pInfo,
+                              MapSearchCallBack  *pCallBack);
+
+
+/* Semi-private function. See qcbor_decode.c */
+QCBORError
+QCBORDecode_Private_ExitBoundedLevel(QCBORDecodeContext *pMe,
+                                     const uint32_t      uEndOffset);
+
+
+static inline void
+QCBORDecode_Private_SaveTagNumbers(QCBORDecodeContext *pMe, const QCBORItem *pItem)
+{
+#ifndef QCBOR_DISABLE_TAGS
+   memcpy(pMe->auLastTags, pItem->auTagNumbers, sizeof(pItem->auTagNumbers));
+#else /* ! QCBOR_DISABLE_TAGS */
+   (void)pMe;
+   (void)pItem;
+#endif /* ! QCBOR_DISABLE_TAGS */
+}
+
+
 
 static inline void
 QCBORDecode_Private_GetAndTell(QCBORDecodeContext *pMe, QCBORItem *Item, size_t *uOffset)
@@ -84,7 +118,7 @@
    }
 
    *uOffset = QCBORDecode_Tell(pMe);
-#else
+#else /* ! QCBOR_DISABLE_TAGS */
    *uOffset = SIZE_MAX;
 
 #endif /* ! QCBOR_DISABLE_TAGS */
@@ -92,4 +126,25 @@
 }
 
 
+
+
+/* Semi-private function. See qcbor_tag_decode.c */
+void
+QCBORDecode_Private_ProcessTagItemMulti(QCBORDecodeContext      *pMe,
+                                        QCBORItem               *pItem,
+                                        const uint8_t            uTagRequirement,
+                                        const uint8_t            uQCBORTypes[],
+                                        const uint64_t           uTagNumbers[],
+                                        QCBORTagContentCallBack *pfCB,
+                                        size_t                   uOffset);
+
+/* Semi-private function. See qcbor_tag_decode.c */
+void
+QCBORDecode_Private_ProcessTagItem(QCBORDecodeContext      *pMe,
+                                   QCBORItem               *pItem,
+                                   const uint8_t            uTagRequirement,
+                                   const uint8_t            uQCBORTypes[],
+                                   const uint64_t           uTagNumber,
+                                   QCBORTagContentCallBack *pfCB,
+                                   size_t                   uOffset);
 #endif /* decode_private_h */
diff --git a/src/qcbor_decode.c b/src/qcbor_decode.c
index 7e2abad..257f8e7 100644
--- a/src/qcbor_decode.c
+++ b/src/qcbor_decode.c
@@ -36,6 +36,9 @@
 #include "qcbor/qcbor_spiffy_decode.h"
 #include "qcbor/qcbor_tag_decode.h"
 #include "ieee754.h" /* Does not use math.h */
+#include "decode_private.h"
+#include "decode_nesting.h"
+
 
 
 #if (defined(__GNUC__) && !defined(__clang__))
@@ -127,453 +130,6 @@
 #endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
 }
 
-/* Return true if the labels in Item1 and Item2 are the same.
-   Works only for integer and string labels. Returns false
-   for any other type. */
-static bool
-QCBORItem_MatchLabel(const QCBORItem Item1, const QCBORItem Item2)
-{
-   if(Item1.uLabelType == QCBOR_TYPE_INT64) {
-      if(Item2.uLabelType == QCBOR_TYPE_INT64 && Item1.label.int64 == Item2.label.int64) {
-         return true;
-      }
-#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
-   } else if(Item1.uLabelType == QCBOR_TYPE_TEXT_STRING) {
-      if(Item2.uLabelType == QCBOR_TYPE_TEXT_STRING && !UsefulBuf_Compare(Item1.label.string, Item2.label.string)) {
-         return true;
-      }
-   } else if(Item1.uLabelType == QCBOR_TYPE_BYTE_STRING) {
-      if(Item2.uLabelType == QCBOR_TYPE_BYTE_STRING && !UsefulBuf_Compare(Item1.label.string, Item2.label.string)) {
-         return true;
-      }
-   } else if(Item1.uLabelType == QCBOR_TYPE_UINT64) {
-      if(Item2.uLabelType == QCBOR_TYPE_UINT64 && Item1.label.uint64 == Item2.label.uint64) {
-         return true;
-      }
-#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
-   }
-
-   /* Other label types are never matched */
-   return false;
-}
-
-
-/*
- Returns true if Item1 and Item2 are the same type
- or if either are of QCBOR_TYPE_ANY.
- */
-static bool
-QCBORItem_MatchType(const QCBORItem Item1, const QCBORItem Item2)
-{
-   if(Item1.uDataType == Item2.uDataType) {
-      return true;
-   } else if(Item1.uDataType == QCBOR_TYPE_ANY) {
-      return true;
-   } else if(Item2.uDataType == QCBOR_TYPE_ANY) {
-      return true;
-   }
-   return false;
-}
-
-
-/*===========================================================================
-   DecodeNesting -- Tracking array/map/sequence/bstr-wrapped nesting
-  ===========================================================================*/
-
-/*
- * See comments about and typedef of QCBORDecodeNesting in qcbor_private.h,
- * the data structure all these functions work on.
- */
-
-
-static uint8_t
-DecodeNesting_GetCurrentLevel(const QCBORDecodeNesting *pNesting)
-{
-   const ptrdiff_t nLevel = pNesting->pCurrent - &(pNesting->pLevels[0]);
-   /* Limit in DecodeNesting_Descend against more than
-    * QCBOR_MAX_ARRAY_NESTING gaurantees cast is safe
-    */
-   return (uint8_t)nLevel;
-}
-
-
-static uint8_t
-DecodeNesting_GetBoundedModeLevel(const QCBORDecodeNesting *pNesting)
-{
-   const ptrdiff_t nLevel = pNesting->pCurrentBounded - &(pNesting->pLevels[0]);
-   /* Limit in DecodeNesting_Descend against more than
-    * QCBOR_MAX_ARRAY_NESTING gaurantees cast is safe
-    */
-   return (uint8_t)nLevel;
-}
-
-
-static uint32_t
-DecodeNesting_GetMapOrArrayStart(const QCBORDecodeNesting *pNesting)
-{
-   return pNesting->pCurrentBounded->u.ma.uStartOffset;
-}
-
-
-static bool
-DecodeNesting_IsBoundedEmpty(const QCBORDecodeNesting *pNesting)
-{
-   if(pNesting->pCurrentBounded->u.ma.uCountCursor == QCBOR_COUNT_INDICATES_ZERO_LENGTH) {
-      return true;
-   } else {
-      return false;
-   }
-}
-
-
-static bool
-DecodeNesting_IsCurrentAtTop(const QCBORDecodeNesting *pNesting)
-{
-   if(pNesting->pCurrent == &(pNesting->pLevels[0])) {
-      return true;
-   } else {
-      return false;
-   }
-}
-
-
-static bool
-DecodeNesting_IsCurrentDefiniteLength(const QCBORDecodeNesting *pNesting)
-{
-   if(pNesting->pCurrent->uLevelType == QCBOR_TYPE_BYTE_STRING) {
-      /* Not a map or array */
-      return false;
-   }
-
-#ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS
-   if(pNesting->pCurrent->u.ma.uCountTotal == QCBOR_COUNT_INDICATES_INDEFINITE_LENGTH) {
-      /* Is indefinite */
-      return false;
-   }
-
-#endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
-
-   /* All checks passed; is a definte length map or array */
-   return true;
-}
-
-static bool
-DecodeNesting_IsCurrentBstrWrapped(const QCBORDecodeNesting *pNesting)
-{
-   if(pNesting->pCurrent->uLevelType == QCBOR_TYPE_BYTE_STRING) {
-      /* is a byte string */
-      return true;
-   }
-   return false;
-}
-
-
-static bool
-DecodeNesting_IsCurrentBounded(const QCBORDecodeNesting *pNesting)
-{
-   if(pNesting->pCurrent->uLevelType == QCBOR_TYPE_BYTE_STRING) {
-      return true;
-   }
-   if(pNesting->pCurrent->u.ma.uStartOffset != QCBOR_NON_BOUNDED_OFFSET) {
-      return true;
-   }
-   return false;
-}
-
-
-static void
-DecodeNesting_SetMapOrArrayBoundedMode(QCBORDecodeNesting *pNesting, bool bIsEmpty, size_t uStart)
-{
-   /* Should be only called on maps and arrays */
-   /*
-    * DecodeNesting_EnterBoundedMode() checks to be sure uStart is not
-    * larger than DecodeNesting_EnterBoundedMode which keeps it less than
-    * uin32_t so the cast is safe.
-    */
-   pNesting->pCurrent->u.ma.uStartOffset = (uint32_t)uStart;
-
-   if(bIsEmpty) {
-      pNesting->pCurrent->u.ma.uCountCursor = QCBOR_COUNT_INDICATES_ZERO_LENGTH;
-   }
-}
-
-
-static void
-DecodeNesting_ClearBoundedMode(QCBORDecodeNesting *pNesting)
-{
-   pNesting->pCurrent->u.ma.uStartOffset = QCBOR_NON_BOUNDED_OFFSET;
-}
-
-
-static bool
-DecodeNesting_IsAtEndOfBoundedLevel(const QCBORDecodeNesting *pNesting)
-{
-   if(pNesting->pCurrentBounded == NULL) {
-      /* No bounded map or array set up */
-      return false;
-   }
-   if(pNesting->pCurrent->uLevelType == QCBOR_TYPE_BYTE_STRING) {
-      /* Not a map or array; end of those is by byte count */
-      return false;
-   }
-   if(!DecodeNesting_IsCurrentBounded(pNesting)) {
-      /* In a traveral at a level deeper than the bounded level */
-      return false;
-   }
-   /* Works for both definite- and indefinitelength maps/arrays */
-   if(pNesting->pCurrentBounded->u.ma.uCountCursor != 0 &&
-      pNesting->pCurrentBounded->u.ma.uCountCursor != QCBOR_COUNT_INDICATES_ZERO_LENGTH) {
-      /* Count is not zero, still unconsumed item */
-      return false;
-   }
-   /* All checks passed, got to the end of an array or map*/
-   return true;
-}
-
-
-static bool
-DecodeNesting_IsEndOfDefiniteLengthMapOrArray(const QCBORDecodeNesting *pNesting)
-{
-   /* Must only be called on map / array */
-   if(pNesting->pCurrent->u.ma.uCountCursor == 0) {
-      return true;
-   } else {
-      return false;
-   }
-}
-
-
-static bool
-DecodeNesting_IsCurrentTypeMap(const QCBORDecodeNesting *pNesting)
-{
-   if(pNesting->pCurrent->uLevelType == CBOR_MAJOR_TYPE_MAP) {
-      return true;
-   } else {
-      return false;
-   }
-}
-
-
-static bool
-DecodeNesting_IsBoundedType(const QCBORDecodeNesting *pNesting, uint8_t uType)
-{
-   if(pNesting->pCurrentBounded == NULL) {
-      return false;
-   }
-
-   uint8_t uItemDataType = pNesting->pCurrentBounded->uLevelType;
-#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
-   if(uItemDataType == QCBOR_TYPE_MAP_AS_ARRAY) {
-      uItemDataType = QCBOR_TYPE_ARRAY;
-   }
-#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
-
-   if(uItemDataType != uType) {
-      return false;
-   }
-
-   return true;
-}
-
-
-static void
-DecodeNesting_DecrementDefiniteLengthMapOrArrayCount(QCBORDecodeNesting *pNesting)
-{
-   /* Only call on a definite-length array / map */
-   pNesting->pCurrent->u.ma.uCountCursor--;
-}
-
-
-static void
-DecodeNesting_ReverseDecrement(QCBORDecodeNesting *pNesting)
-{
-   /* Only call on a definite-length array / map */
-   pNesting->pCurrent->u.ma.uCountCursor++;
-}
-
-
-static void
-DecodeNesting_Ascend(QCBORDecodeNesting *pNesting)
-{
-   pNesting->pCurrent--;
-}
-
-
-static QCBORError
-DecodeNesting_Descend(QCBORDecodeNesting *pNesting, uint8_t uType)
-{
-   /* Error out if nesting is too deep */
-   if(pNesting->pCurrent >= &(pNesting->pLevels[QCBOR_MAX_ARRAY_NESTING])) {
-      return QCBOR_ERR_ARRAY_DECODE_NESTING_TOO_DEEP;
-   }
-
-   /* The actual descend */
-   pNesting->pCurrent++;
-
-   pNesting->pCurrent->uLevelType = uType;
-
-   return QCBOR_SUCCESS;
-}
-
-
-static QCBORError
-DecodeNesting_EnterBoundedMapOrArray(QCBORDecodeNesting *pNesting,
-                                     bool                bIsEmpty,
-                                     size_t              uOffset)
-{
-   /*
-    * Should only be called on map/array.
-    *
-    * Have descended into this before this is called. The job here is
-    * just to mark it in bounded mode.
-    *
-    * Check against QCBOR_MAX_DECODE_INPUT_SIZE make sure that
-    * uOffset doesn't collide with QCBOR_NON_BOUNDED_OFFSET.
-    *
-    * Cast of uOffset to uint32_t for cases where SIZE_MAX < UINT32_MAX.
-    */
-   if((uint32_t)uOffset >= QCBOR_MAX_DECODE_INPUT_SIZE) {
-      return QCBOR_ERR_INPUT_TOO_LARGE;
-   }
-
-   pNesting->pCurrentBounded = pNesting->pCurrent;
-
-   DecodeNesting_SetMapOrArrayBoundedMode(pNesting, bIsEmpty, uOffset);
-
-   return QCBOR_SUCCESS;
-}
-
-
-static QCBORError
-DecodeNesting_DescendMapOrArray(QCBORDecodeNesting *pNesting,
-                                const uint8_t       uQCBORType,
-                                const uint16_t      uCount)
-{
-   QCBORError uError = QCBOR_SUCCESS;
-
-   if(uCount == 0) {
-      /* Nothing to do for empty definite-length arrays. They are just are
-       * effectively the same as an item that is not a map or array.
-       */
-      goto Done;
-      /* Empty indefinite-length maps and arrays are handled elsewhere */
-   }
-
-   /* Rely on check in QCBOR_Private_DecodeArrayOrMap() for definite-length
-    * arrays and maps that are too long */
-
-   uError = DecodeNesting_Descend(pNesting, uQCBORType);
-   if(uError != QCBOR_SUCCESS) {
-      goto Done;
-   }
-
-   pNesting->pCurrent->u.ma.uCountCursor = uCount;
-   pNesting->pCurrent->u.ma.uCountTotal  = uCount;
-
-   DecodeNesting_ClearBoundedMode(pNesting);
-
-Done:
-   return uError;;
-}
-
-
-static void
-DecodeNesting_LevelUpCurrent(QCBORDecodeNesting *pNesting)
-{
-   pNesting->pCurrent = pNesting->pCurrentBounded - 1;
-}
-
-
-static void
-DecodeNesting_LevelUpBounded(QCBORDecodeNesting *pNesting)
-{
-   while(pNesting->pCurrentBounded != &(pNesting->pLevels[0])) {
-      pNesting->pCurrentBounded--;
-      if(DecodeNesting_IsCurrentBounded(pNesting)) {
-         break;
-      }
-   }
-}
-
-
-static void
-DecodeNesting_SetCurrentToBoundedLevel(QCBORDecodeNesting *pNesting)
-{
-   pNesting->pCurrent = pNesting->pCurrentBounded;
-}
-
-
-static QCBORError
-DecodeNesting_DescendIntoBstrWrapped(QCBORDecodeNesting *pNesting,
-                                     uint32_t            uEndOffset,
-                                     uint32_t            uStartOffset)
-{
-   QCBORError uError;
-
-   uError = DecodeNesting_Descend(pNesting, QCBOR_TYPE_BYTE_STRING);
-   if(uError != QCBOR_SUCCESS) {
-      goto Done;
-   }
-
-   /* Fill in the new byte string level */
-   pNesting->pCurrent->u.bs.uSavedEndOffset  = uEndOffset;
-   pNesting->pCurrent->u.bs.uBstrStartOffset = uStartOffset;
-
-   /* Bstr wrapped levels are always bounded */
-   pNesting->pCurrentBounded = pNesting->pCurrent;
-
-Done:
-   return uError;;
-}
-
-
-static void
-DecodeNesting_ZeroMapOrArrayCount(QCBORDecodeNesting *pNesting)
-{
-   pNesting->pCurrent->u.ma.uCountCursor = 0;
-}
-
-
-static void
-DecodeNesting_ResetMapOrArrayCount(QCBORDecodeNesting *pNesting)
-{
-   if(pNesting->pCurrent->u.ma.uCountCursor != QCBOR_COUNT_INDICATES_ZERO_LENGTH) {
-      pNesting->pCurrentBounded->u.ma.uCountCursor = pNesting->pCurrentBounded->u.ma.uCountTotal;
-   }
-}
-
-
-static void
-DecodeNesting_Init(QCBORDecodeNesting *pNesting)
-{
-   /* Assumes that *pNesting has been zero'd before this call. */
-   pNesting->pLevels[0].uLevelType = QCBOR_TYPE_BYTE_STRING;
-   pNesting->pCurrent = &(pNesting->pLevels[0]);
-}
-
-
-static void
-DecodeNesting_PrepareForMapSearch(QCBORDecodeNesting *pNesting,
-                                  QCBORDecodeNesting *pSave)
-{
-   *pSave = *pNesting;
-}
-
-
-static void
-DecodeNesting_RestoreFromMapSearch(QCBORDecodeNesting *pNesting,
-                                   const QCBORDecodeNesting *pSave)
-{
-   *pNesting = *pSave;
-}
-
-
-static uint32_t
-DecodeNesting_GetPreviousBoundedEnd(const QCBORDecodeNesting *pMe)
-{
-   return pMe->pCurrentBounded->u.bs.uSavedEndOffset;
-}
-
 
 
 
@@ -1791,7 +1347,7 @@
  *
  * This is the reverse of MapTagNumber()
  */
-static uint64_t
+uint64_t
 QCBORDecode_Private_UnMapTagNumber(const QCBORDecodeContext *pMe,
                                    const uint16_t            uMappedTagNumber)
 {
@@ -2121,7 +1677,7 @@
  *
  * Improvement: this could reduced further if indef is disabled
  */
-static QCBORError
+QCBORError
 QCBORDecode_Private_NestLevelAscender(QCBORDecodeContext *pMe, bool bMarkEnd, bool *pbBreak)
 {
    QCBORError uReturn;
@@ -2253,7 +1809,7 @@
  * item count or finding CBOR breaks.  It detects the ends of the
  * top-level sequence and of bstr-wrapped CBOR by byte count.
  */
-static QCBORError
+QCBORError
 QCBORDecode_Private_GetNextMapOrArray(QCBORDecodeContext *pMe,
                                       bool               *pbBreak,
                                       QCBORItem          *pDecodedItem,
@@ -2440,7 +1996,7 @@
  * map. In that case, this is just a pass through for @c puNextNestLevel
  * since there is nothing to do.
  */
-static QCBORError
+QCBORError
 QCBORDecode_Private_ConsumeItem(QCBORDecodeContext *pMe,
                                 const QCBORItem    *pItemToConsume,
                                 bool               *pbBreak,
@@ -2644,7 +2200,7 @@
 }
 #endif /* ! QCBOR_DISABLE_DECODE_CONFORMANCE */
 
-static QCBORError
+QCBORError
 QCBORDecode_Private_GetItemChecks(QCBORDecodeContext *pMe,
                                   QCBORError          uErr,
                                   const size_t        uOffset,
@@ -2732,17 +2288,6 @@
 }
 
 
-static void
-QCBORDecode_Private_SaveTagNumbers(QCBORDecodeContext *pMe, const QCBORItem *pItem)
-{
-#ifndef QCBOR_DISABLE_TAGS
-   memcpy(pMe->auLastTags, pItem->auTagNumbers, sizeof(pItem->auTagNumbers));
-#else
-   (void)pMe;
-   (void)pItem;
-#endif
-}
-
 /*
  * Public function, see header qcbor/qcbor_decode.h file
  */
@@ -2809,99 +2354,18 @@
 }
 
 
-#ifndef QCBOR_DISABLE_TAGS
 /*
  * Public function, see header qcbor/qcbor_decode.h file
  */
-uint64_t
-QCBORDecode_GetNthTagNumber(const QCBORDecodeContext *pMe,
-                            const QCBORItem          *pItem,
-                            uint8_t                   uIndex)
+void
+QCBORDecode_VGetNextConsume(QCBORDecodeContext *pMe, QCBORItem *pDecodedItem)
 {
-   if(pItem->uDataType == QCBOR_TYPE_NONE) {
-      return CBOR_TAG_INVALID64;
+   QCBORDecode_VGetNext(pMe, pDecodedItem);
+
+   if(pMe->uLastError == QCBOR_SUCCESS) {
+      pMe->uLastError = (uint8_t)QCBORDecode_Private_ConsumeItem(pMe, pDecodedItem, NULL,
+         &pDecodedItem->uNextNestLevel);
    }
-   if(uIndex >= QCBOR_MAX_TAGS_PER_ITEM) {
-      return CBOR_TAG_INVALID64;
-   }
-
-   return QCBORDecode_Private_UnMapTagNumber(pMe, pItem->auTagNumbers[uIndex]);
-}
-
-
-/*
- * Public function, see header qcbor/qcbor_decode.h file
- */
-uint64_t
-QCBORDecode_GetNthTagNumberOfLast(QCBORDecodeContext *pMe,
-                                  uint8_t             uIndex)
-{
-   if(pMe->uLastError != QCBOR_SUCCESS) {
-      return CBOR_TAG_INVALID64;
-   }
-   if(uIndex >= QCBOR_MAX_TAGS_PER_ITEM) {
-      return CBOR_TAG_INVALID64;
-   }
-
-   return QCBORDecode_Private_UnMapTagNumber(pMe, pMe->auLastTags[uIndex]);
-}
-
-
-/*
- * Public function, see header qcbor/qcbor_decode.h file
- */
-static uint64_t
-QCBORDecode_Private_GetNthTagNumberReverse(const QCBORDecodeContext *pMe,
-                                           const uint16_t            puTagNumbers[],
-                                           const uint32_t            uIndex)
-{
-   uint32_t uArrayIndex;
-
-   /* Find number of tag numbers */
-   for(uArrayIndex = QCBOR_MAX_TAGS_PER_ITEM-1; uArrayIndex > 0; uArrayIndex--) {
-      if(puTagNumbers[uArrayIndex] != CBOR_TAG_INVALID16) {
-         break;
-      }
-   }
-   if(uIndex > uArrayIndex) {
-      return CBOR_TAG_INVALID64;
-   }
-
-   return QCBORDecode_Private_UnMapTagNumber(pMe, puTagNumbers[uArrayIndex - uIndex]);
-}
-
-
-/*
- * Public function, see header qcbor/qcbor_decode.h file
- */
-uint64_t
-QCBORDecode_GetNthTag(QCBORDecodeContext *pMe,
-                      const QCBORItem    *pItem,
-                      const uint32_t      uIndex)
-{
-   if(pItem->uDataType == QCBOR_TYPE_NONE) {
-      return CBOR_TAG_INVALID64;
-   }
-
-   return QCBORDecode_Private_GetNthTagNumberReverse(pMe, pItem->auTagNumbers, uIndex);
-}
-
-
-/*
- * Public function, see header qcbor/qcbor_decode.h file
- */
-uint64_t
-QCBORDecode_GetNthTagOfLast(const QCBORDecodeContext *pMe,
-                            uint32_t                  uIndex)
-{
-   if(pMe->uLastError != QCBOR_SUCCESS) {
-      return CBOR_TAG_INVALID64;
-   }
-   if(uIndex >= QCBOR_MAX_TAGS_PER_ITEM) {
-      return CBOR_TAG_INVALID64;
-   }
-
-   return QCBORDecode_Private_GetNthTagNumberReverse(pMe, pMe->auLastTags, uIndex);
 }
 
 
@@ -2909,52 +2373,129 @@
  * Public function, see header qcbor/qcbor_decode.h file
  */
 QCBORError
-QCBORDecode_GetNextTagNumber(QCBORDecodeContext *pMe, uint64_t *puTagNumber)
+QCBORDecode_EndCheck(QCBORDecodeContext *pMe)
 {
-   QCBORItem   Item;
-   size_t      uOffset;
-   QCBORError  uErr;
+   size_t     uCursorOffset;
+   QCBORError uErr;
 
-   const QCBORDecodeNesting SaveNesting = pMe->nesting;
-   const UsefulInputBuf Save = pMe->InBuf;
-
-   uOffset = UsefulInputBuf_Tell(&(pMe->InBuf));
-   if(uOffset == pMe->uTagNumberCheckOffset) {
-      pMe->uTagNumberIndex++;
-   } else {
-      pMe->uTagNumberIndex = 0;
-   }
-
-   *puTagNumber = CBOR_TAG_INVALID64;
-   uErr = QCBORDecode_Private_GetNextTagContent(pMe, &Item);
-   if(uErr) {
+   uErr = QCBORDecode_GetError(pMe);
+   if(uErr != QCBOR_SUCCESS) {
       return uErr;
    }
 
-   *puTagNumber = QCBORDecode_GetNthTagNumber(pMe, &Item, pMe->uTagNumberIndex);
-   if(*puTagNumber == CBOR_TAG_INVALID64 ||
-      QCBORDecode_GetNthTagNumber(pMe, &Item, pMe->uTagNumberIndex+1) == CBOR_TAG_INVALID64 ) {
-      pMe->uTagNumberIndex = QCBOR_ALL_TAGS_PROCESSED;
-   }
-   pMe->uTagNumberCheckOffset = uOffset;
+   uCursorOffset = UsefulInputBuf_Tell(&(pMe->InBuf));
 
-   pMe->nesting = SaveNesting;
-   pMe->InBuf = Save;
+   if(uCursorOffset == UsefulInputBuf_GetBufferLength(&(pMe->InBuf))) {
+      return QCBOR_ERR_NO_MORE_ITEMS;
+   }
 
    return QCBOR_SUCCESS;
 }
 
 
-/*
- * Public function, see header qcbor/qcbor_decode.h file
+/**
+ * @brief Semi-private. Get pointer, length and item for an array or map.
+ *
+ * @param[in] pMe            The decode context.
+ * @param[in] uType          CBOR major type, either array/map.
+ * @param[out] pItem         The item for the array/map.
+ * @param[out] pEncodedCBOR  Pointer and length of the encoded map or array.
+ *
+ * The next item to be decoded must be a map or array as specified by @c uType.
+ *
+ * @c pItem will be filled in with the label and tags of the array or map
+ * in addition to @c pEncodedCBOR giving the pointer and length of the
+ * encoded CBOR.
+ *
+ * When this is complete, the traversal cursor is at the end of the array or
+ * map that was retrieved.
  */
 void
-QCBORDecode_VGetNextTagNumber(QCBORDecodeContext *pMe, uint64_t *puTagNumber)
+QCBORDecode_Private_GetArrayOrMap(QCBORDecodeContext *pMe,
+                                  const uint8_t       uType,
+                                  QCBORItem          *pItem,
+                                  UsefulBufC         *pEncodedCBOR)
 {
-   pMe->uLastError = (uint8_t)QCBORDecode_GetNextTagNumber(pMe, puTagNumber);
+   QCBORError uErr;
+   uint8_t    uNestLevel;
+   size_t     uStartingCursor;
+   size_t     uStartOfReturned;
+   size_t     uEndOfReturned;
+   size_t     uTempSaveCursor;
+   bool       bInMap;
+   QCBORItem  LabelItem;
+   bool       EndedByBreak;
+
+   uStartingCursor = UsefulInputBuf_Tell(&(pMe->InBuf));
+   bInMap = DecodeNesting_IsCurrentTypeMap(&(pMe->nesting));
+
+   /* Could call GetNext here, but don't need to because this
+    * is only interested in arrays and maps. TODO: switch to GetNext()? */
+   uErr = QCBORDecode_Private_GetNextMapOrArray(pMe, NULL, pItem, NULL);
+   if(uErr != QCBOR_SUCCESS) {
+      pMe->uLastError = (uint8_t)uErr;
+      return;
+   }
+
+   uint8_t uItemDataType = pItem->uDataType;
+#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
+   if(uItemDataType == QCBOR_TYPE_MAP_AS_ARRAY) {
+      uItemDataType = QCBOR_TYPE_ARRAY;
+   }
+#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
+
+   if(uItemDataType != uType) {
+      pMe->uLastError = QCBOR_ERR_UNEXPECTED_TYPE;
+      return;
+   }
+
+   if(bInMap) {
+      /* If the item is in a map, the start of the array/map
+       * itself, not the label, must be found. Do this by
+       * rewinding to the starting position and fetching
+       * just the label data item. QCBORDecode_Private_GetNextTagNumber()
+       * doesn't do any of the array/map item counting or nesting
+       * level tracking. Used here it will just fetech the label
+       * data item.
+       *
+       * Have to save the cursor and put it back to the position
+       * after the full item once the label as been fetched by
+       * itself.
+       */
+      uTempSaveCursor = UsefulInputBuf_Tell(&(pMe->InBuf));
+      UsefulInputBuf_Seek(&(pMe->InBuf), uStartingCursor);
+
+      /* Item has been fetched once so safe to ignore error */
+      (void)QCBORDecode_Private_GetNextTagNumber(pMe, &LabelItem);
+
+      uStartOfReturned = UsefulInputBuf_Tell(&(pMe->InBuf));
+      UsefulInputBuf_Seek(&(pMe->InBuf), uTempSaveCursor);
+   } else {
+      uStartOfReturned = uStartingCursor;
+   }
+
+   /* Consume the entire array/map to find the end */
+   uErr = QCBORDecode_Private_ConsumeItem(pMe, pItem, &EndedByBreak, &uNestLevel);
+   if(uErr != QCBOR_SUCCESS) {
+      pMe->uLastError = (uint8_t)uErr;
+      goto Done;
+   }
+
+   /* Fill in returned values */
+   uEndOfReturned = UsefulInputBuf_Tell(&(pMe->InBuf));
+   if(EndedByBreak) {
+      /* When ascending nesting levels, a break for the level above
+       * was consumed. That break is not a part of what is consumed here. */
+      uEndOfReturned--;
+   }
+   pEncodedCBOR->ptr = UsefulInputBuf_OffsetToPointer(&(pMe->InBuf), uStartOfReturned);
+   pEncodedCBOR->len = uEndOfReturned - uStartOfReturned;
+
+Done:
+   return;
 }
 
-#endif /* ! QCBOR_DISABLE_TAGS */
+
 
 #ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS
 
@@ -3147,2108 +2688,6 @@
 
 
 
-/*
- * Public function, see header qcbor/qcbor_decode.h file
- */
-void
-QCBORDecode_VGetNextConsume(QCBORDecodeContext *pMe, QCBORItem *pDecodedItem)
-{
-   QCBORDecode_VGetNext(pMe, pDecodedItem);
-
-   if(pMe->uLastError == QCBOR_SUCCESS) {
-      pMe->uLastError = (uint8_t)QCBORDecode_Private_ConsumeItem(pMe, pDecodedItem, NULL,
-         &pDecodedItem->uNextNestLevel);
-   }
-}
-
-
-/*
- * Public function, see header qcbor/qcbor_decode.h file
- */
-QCBORError
-QCBORDecode_EndCheck(QCBORDecodeContext *pMe)
-{
-   size_t     uCursorOffset;
-   QCBORError uErr;
-
-   uErr = QCBORDecode_GetError(pMe);
-   if(uErr != QCBOR_SUCCESS) {
-      return uErr;
-   }
-
-   uCursorOffset = UsefulInputBuf_Tell(&(pMe->InBuf));
-
-   if(uCursorOffset == UsefulInputBuf_GetBufferLength(&(pMe->InBuf))) {
-      return QCBOR_ERR_NO_MORE_ITEMS;
-   }
-
-   return QCBOR_SUCCESS;
-}
-
-
-/**
- * @brief Rewind cursor to start as if map or array were just entered.
- *
- * @param[in]  pMe   The decoding context
- *
- * This affects the nesting tracking and the UsefulInputBuf.
- */
-static void
-QCBORDecode_Private_RewindMapOrArray(QCBORDecodeContext *pMe)
-{
-   /* Reset nesting tracking to the deepest bounded level */
-   DecodeNesting_SetCurrentToBoundedLevel(&(pMe->nesting));
-
-   DecodeNesting_ResetMapOrArrayCount(&(pMe->nesting));
-
-   /* Reposition traversal cursor to the start of the map/array */
-   UsefulInputBuf_Seek(&(pMe->InBuf),
-                       DecodeNesting_GetMapOrArrayStart(&(pMe->nesting)));
-}
-
-
-/*
- * Public function, see header qcbor/qcbor_decode.h file
- */
-void
-QCBORDecode_Rewind(QCBORDecodeContext *pMe)
-{
-   if(pMe->nesting.pCurrentBounded != NULL) {
-      /* In a bounded map, array or bstr-wrapped CBOR */
-
-      if(DecodeNesting_IsBoundedType(&(pMe->nesting), QCBOR_TYPE_BYTE_STRING)) {
-         /* In bstr-wrapped CBOR. */
-
-         /* Reposition traversal cursor to start of wrapping byte string */
-         UsefulInputBuf_Seek(&(pMe->InBuf),
-                             pMe->nesting.pCurrentBounded->u.bs.uBstrStartOffset);
-         DecodeNesting_SetCurrentToBoundedLevel(&(pMe->nesting));
-
-      } else {
-         /* In a map or array */
-         QCBORDecode_Private_RewindMapOrArray(pMe);
-      }
-
-   } else {
-      /* Not in anything bounded */
-
-      /* Reposition traversal cursor to the start of input CBOR */
-      UsefulInputBuf_Seek(&(pMe->InBuf), 0ULL);
-
-      /* Reset nesting tracking to beginning of input. */
-      DecodeNesting_Init(&(pMe->nesting));
-   }
-
-   pMe->uLastError = QCBOR_SUCCESS;
-}
-
-
-
-
-
-typedef struct {
-   void               *pCBContext;
-   QCBORItemCallback   pfCallback;
-} MapSearchCallBack;
-
-typedef struct {
-   size_t   uStartOffset;
-   uint16_t uItemCount;
-} MapSearchInfo;
-
-
-/**
- * @brief Search a map for a set of items.
- *
- * @param[in]  pMe           The decode context to search.
- * @param[in,out] pItemArray The items to search for and the items found.
- * @param[out] pInfo         Several bits of meta-info returned by search.
- * @param[in] pCallBack      Callback object or @c NULL.
- *
- * @retval QCBOR_ERR_NOT_ENTERED     Trying to search without entering a map.
- *
- * @retval QCBOR_ERR_DUPLICATE_LABEL Duplicate items (items with the same label)
- *                                   were found for one of the labels being
- *                                   search for. This duplicate detection is
- *                                   only performed for items in pItemArray,
- *                                   not every item in the map.
- *
- * @retval QCBOR_ERR_UNEXPECTED_TYPE A label was matched, but the type was
- *                                   wrong for the matchd label.
- *
- * @retval Also errors returned by QCBORDecode_GetNext().
- *
- * On input, @c pItemArray contains a list of labels and data types of
- * items to be found.
- *
- * On output, the fully retrieved items are filled in with values and
- * such. The label was matched, so it never changes.
- *
- * If an item was not found, its data type is set to @ref QCBOR_TYPE_NONE.
- *
- * This also finds the ends of maps and arrays when they are exited.
- */
-static QCBORError
-QCBORDecode_Private_MapSearch(QCBORDecodeContext *pMe,
-                              QCBORItem          *pItemArray,
-                              MapSearchInfo      *pInfo,
-                              MapSearchCallBack  *pCallBack)
-{
-   QCBORError uReturn;
-   uint64_t   uFoundItemBitMap = 0;
-
-   if(pMe->uLastError != QCBOR_SUCCESS) {
-      uReturn = pMe->uLastError;
-      goto Done2;
-   }
-
-   if(!DecodeNesting_IsBoundedType(&(pMe->nesting), QCBOR_TYPE_MAP) &&
-      pItemArray->uLabelType != QCBOR_TYPE_NONE) {
-      /* QCBOR_TYPE_NONE as first item indicates just looking
-         for the end of an array, so don't give error. */
-      uReturn = QCBOR_ERR_MAP_NOT_ENTERED;
-      goto Done2;
-   }
-
-   if(DecodeNesting_IsBoundedEmpty(&(pMe->nesting))) {
-      // It is an empty bounded array or map
-      if(pItemArray->uLabelType == QCBOR_TYPE_NONE) {
-         // Just trying to find the end of the map or array
-         pMe->uMapEndOffsetCache = DecodeNesting_GetMapOrArrayStart(&(pMe->nesting));
-         uReturn = QCBOR_SUCCESS;
-      } else {
-         // Nothing is ever found in an empty array or map. All items
-         // are marked as not found below.
-         uReturn = QCBOR_SUCCESS;
-      }
-      goto Done2;
-   }
-
-   QCBORDecodeNesting SaveNesting;
-   size_t uSavePos = UsefulInputBuf_Tell(&(pMe->InBuf));
-   DecodeNesting_PrepareForMapSearch(&(pMe->nesting), &SaveNesting);
-
-   /* Reposition to search from the start of the map / array */
-   QCBORDecode_Private_RewindMapOrArray(pMe);
-
-   /*
-    Loop over all the items in the map or array. Each item
-    could be a map or array, but label matching is only at
-    the main level. This handles definite- and indefinite-
-    length maps and arrays. The only reason this is ever
-    called on arrays is to find their end position.
-
-    This will always run over all items in order to do
-    duplicate detection.
-
-    This will exit with failure if it encounters an
-    unrecoverable error, but continue on for recoverable
-    errors.
-
-    If a recoverable error occurs on a matched item, then
-    that error code is returned.
-    */
-   const uint8_t uMapNestLevel = DecodeNesting_GetBoundedModeLevel(&(pMe->nesting));
-   if(pInfo) {
-      pInfo->uItemCount = 0;
-   }
-   uint8_t       uNextNestLevel;
-   do {
-      /* Remember offset of the item because sometimes it has to be returned */
-      const size_t uOffset = UsefulInputBuf_Tell(&(pMe->InBuf));
-
-      /* Get the item */
-      QCBORItem Item;
-      /* QCBORDecode_Private_GetNextTagContent() rather than GetNext()
-       * because a label match is performed on recoverable errors to
-       * be able to return the the error code for the found item. */
-      QCBORError uResult = QCBORDecode_Private_GetNextTagContent(pMe, &Item);
-      if(QCBORDecode_IsUnrecoverableError(uResult)) {
-         /* The map/array can't be decoded when unrecoverable errors occur */
-         uReturn = uResult;
-         goto Done;
-      }
-      if(uResult == QCBOR_ERR_NO_MORE_ITEMS) {
-         /* Unexpected end of map or array. */
-         uReturn = uResult;
-         goto Done;
-      }
-
-      /* See if item has one of the labels that are of interest */
-      bool bMatched = false;
-      for(int nIndex = 0; pItemArray[nIndex].uLabelType != QCBOR_TYPE_NONE; nIndex++) {
-         if(QCBORItem_MatchLabel(Item, pItemArray[nIndex])) {
-            /* A label match has been found */
-            if(uFoundItemBitMap & (0x01ULL << nIndex)) {
-               uReturn = QCBOR_ERR_DUPLICATE_LABEL;
-               goto Done;
-            }
-            if(uResult != QCBOR_SUCCESS) {
-               /* The label matches, but the data item is in error.
-                * It is OK to have recoverable errors on items that
-                * are not matched. */
-               uReturn = uResult;
-               goto Done;
-            }
-            if(!QCBORItem_MatchType(Item, pItemArray[nIndex])) {
-               /* The data item is not of the type(s) requested */
-               uReturn = QCBOR_ERR_UNEXPECTED_TYPE;
-               goto Done;
-            }
-
-            /* Successful match. Return the item. */
-            pItemArray[nIndex] = Item;
-            uFoundItemBitMap |= 0x01ULL << nIndex;
-            if(pInfo) {
-               pInfo->uStartOffset = uOffset;
-            }
-            bMatched = true;
-         }
-      }
-
-
-      if(!bMatched && pCallBack != NULL) {
-         /*
-          Call the callback on unmatched labels.
-          (It is tempting to do duplicate detection here, but that would
-          require dynamic memory allocation because the number of labels
-          that might be encountered is unbounded.)
-         */
-         uReturn = (*(pCallBack->pfCallback))(pCallBack->pCBContext, &Item);
-         if(uReturn != QCBOR_SUCCESS) {
-            goto Done;
-         }
-      }
-
-      /*
-       Consume the item whether matched or not. This
-       does the work of traversing maps and array and
-       everything in them. In this loop only the
-       items at the current nesting level are examined
-       to match the labels.
-       */
-      uReturn = QCBORDecode_Private_ConsumeItem(pMe, &Item, NULL, &uNextNestLevel);
-      if(uReturn != QCBOR_SUCCESS) {
-         goto Done;
-      }
-
-      if(pInfo) {
-         pInfo->uItemCount++;
-      }
-
-   } while (uNextNestLevel >= uMapNestLevel);
-
-   uReturn = QCBOR_SUCCESS;
-
-   const size_t uEndOffset = UsefulInputBuf_Tell(&(pMe->InBuf));
-
-   // Check here makes sure that this won't accidentally be
-   // QCBOR_MAP_OFFSET_CACHE_INVALID which is larger than
-   // QCBOR_MAX_DECODE_INPUT_SIZE.
-   // Cast to uint32_t to possibly address cases where SIZE_MAX < UINT32_MAX
-   if((uint32_t)uEndOffset >= QCBOR_MAX_DECODE_INPUT_SIZE) {
-      uReturn = QCBOR_ERR_INPUT_TOO_LARGE;
-      goto Done;
-   }
-   /* Cast OK because encoded CBOR is limited to UINT32_MAX */
-   pMe->uMapEndOffsetCache = (uint32_t)uEndOffset;
-
- Done:
-   DecodeNesting_RestoreFromMapSearch(&(pMe->nesting), &SaveNesting);
-   UsefulInputBuf_Seek(&(pMe->InBuf), uSavePos);
-
- Done2:
-   /* For all items not found, set the data and label type to QCBOR_TYPE_NONE */
-   for(int i = 0; pItemArray[i].uLabelType != 0; i++) {
-      if(!(uFoundItemBitMap & (0x01ULL << i))) {
-         pItemArray[i].uDataType  = QCBOR_TYPE_NONE;
-         pItemArray[i].uLabelType = QCBOR_TYPE_NONE;
-      }
-   }
-
-   return uReturn;
-}
-
-
-/*
- * Public function, see header qcbor/qcbor_decode.h file
- */
-void
-QCBORDecode_SeekToLabelN(QCBORDecodeContext *pMe, int64_t nLabel)
-{
-   MapSearchInfo Info;
-   QCBORItem     OneItemSeach[2];
-
-   if(pMe->uLastError != QCBOR_SUCCESS) {
-      return;
-   }
-
-   OneItemSeach[0].uLabelType  = QCBOR_TYPE_INT64;
-   OneItemSeach[0].label.int64 = nLabel;
-   OneItemSeach[0].uDataType   = QCBOR_TYPE_ANY;
-   OneItemSeach[1].uLabelType  = QCBOR_TYPE_NONE; // Indicates end of array
-
-   pMe->uLastError = (uint8_t)QCBORDecode_Private_MapSearch(pMe, OneItemSeach, &Info, NULL);
-   if(pMe->uLastError == QCBOR_SUCCESS) {
-      UsefulInputBuf_Seek(&(pMe->InBuf), Info.uStartOffset);
-   }
-}
-
-
-void
-QCBORDecode_SeekToLabelSZ(QCBORDecodeContext *pMe, const char *szLabel)
-{
-#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
-   MapSearchInfo  Info;
-   QCBORItem      OneItemSeach[2];
-
-   if(pMe->uLastError != QCBOR_SUCCESS) {
-      return;
-   }
-
-   OneItemSeach[0].uLabelType   = QCBOR_TYPE_TEXT_STRING;
-   OneItemSeach[0].label.string = UsefulBuf_FromSZ(szLabel);
-   OneItemSeach[0].uDataType    = QCBOR_TYPE_ANY;
-   OneItemSeach[1].uLabelType   = QCBOR_TYPE_NONE; // Indicates end of array
-
-   pMe->uLastError = (uint8_t)QCBORDecode_Private_MapSearch(pMe, OneItemSeach, &Info, NULL);
-   if(pMe->uLastError == QCBOR_SUCCESS) {
-      UsefulInputBuf_Seek(&(pMe->InBuf), Info.uStartOffset);
-   }
-#else
-   (void)pMe;
-   (void)szLabel;
-   pMe->uLastError = QCBOR_ERR_LABEL_NOT_FOUND;
-#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
-}
-
-
-void
-QCBORDecode_Private_GetItemInMapNoCheck(QCBORDecodeContext *pMe,
-                                        QCBORItem          *OneItemSeach,
-                                        QCBORItem          *pItem,
-                                        size_t             *puOffset)
-{
-   QCBORError    uErr;
-   MapSearchInfo SearchInfo;
-
-   if(pMe->uLastError != QCBOR_SUCCESS) {
-      return;
-   }
-
-   uErr = QCBORDecode_Private_MapSearch(pMe, OneItemSeach, &SearchInfo, NULL);
-
-   if(uErr == QCBOR_SUCCESS && OneItemSeach[0].uDataType == QCBOR_TYPE_NONE) {
-      uErr = QCBOR_ERR_LABEL_NOT_FOUND;
-   }
-   *pItem = OneItemSeach[0];
-   *puOffset = SearchInfo.uStartOffset;
-
-   if(uErr == QCBOR_SUCCESS) {
-      QCBORDecode_Private_SaveTagNumbers(pMe, pItem);
-   }
-
-   pMe->uLastError = (uint8_t)uErr;
-}
-
-
-static void
-QCBORDecode_Private_GetItemInMap(QCBORDecodeContext *pMe, QCBORItem *OneItemSeach, QCBORItem *pItem)
-{
-   QCBORError  uErr;
-   size_t      uOffset;
-
-   QCBORDecode_Private_GetItemInMapNoCheck(pMe, OneItemSeach, pItem, &uOffset);
-
-   uErr = QCBORDecode_Private_GetItemChecks(pMe, pMe->uLastError, uOffset, pItem);
-   if(uErr != QCBOR_SUCCESS) {
-      goto Done;
-   }
-
-   QCBORDecode_Private_SaveTagNumbers(pMe, pItem);
-
-Done:
-   pMe->uLastError = (uint8_t)uErr;
-}
-
-
-/*
- * Public function, see header qcbor/qcbor_decode.h file
- */
-void
-QCBORDecode_GetItemInMapN(QCBORDecodeContext *pMe,
-                          const int64_t       nLabel,
-                          const uint8_t       uQcborType,
-                          QCBORItem          *pItem)
-{
-   QCBORItem OneItemSeach[2];
-
-   OneItemSeach[0].uLabelType  = QCBOR_TYPE_INT64;
-   OneItemSeach[0].label.int64 = nLabel;
-   OneItemSeach[0].uDataType   = uQcborType;
-   OneItemSeach[1].uLabelType  = QCBOR_TYPE_NONE; // Indicates end of array
-
-   QCBORDecode_Private_GetItemInMap(pMe, OneItemSeach, pItem);
-}
-
-
-/**
- * @brief Get an item by label by type.
- *
- * @param[in] pMe         The decode context.
- * @param[in] nLabel      The label to search map for.
- * @param[in] uQcborType  The QCBOR type to look for.
- * @param[out] pItem      The item found.
- * @param[out] puOffset   The offset of item for tag consumption check.
- *
- * This finds the item with the given label in currently open
- * map. This does not call QCBORDecode_Private_GetItemChecks()
- * to check tag number consumption or decode conformance.
- */
-void
-QCBORDecode_Private_GetItemInMapNoCheckN(QCBORDecodeContext *pMe,
-                                 const int64_t       nLabel,
-                                 const uint8_t       uQcborType,
-                                 QCBORItem          *pItem,
-                                 size_t             *puOffset)
-{
-   QCBORItem OneItemSeach[2];
-
-   OneItemSeach[0].uLabelType  = QCBOR_TYPE_INT64;
-   OneItemSeach[0].label.int64 = nLabel;
-   OneItemSeach[0].uDataType   = uQcborType;
-   OneItemSeach[1].uLabelType  = QCBOR_TYPE_NONE; // Indicates end of array
-
-   QCBORDecode_Private_GetItemInMapNoCheck(pMe, OneItemSeach,  pItem, puOffset);
-}
-
-
-/*
- * Public function, see header qcbor/qcbor_decode.h file
- */
-void
-QCBORDecode_GetItemInMapSZ(QCBORDecodeContext *pMe,
-                           const char         *szLabel,
-                           const uint8_t       uQcborType,
-                           QCBORItem          *pItem)
-{
-#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
-   QCBORItem OneItemSeach[2];
-
-   OneItemSeach[0].uLabelType   = QCBOR_TYPE_TEXT_STRING;
-   OneItemSeach[0].label.string = UsefulBuf_FromSZ(szLabel);
-   OneItemSeach[0].uDataType    = uQcborType;
-   OneItemSeach[1].uLabelType   = QCBOR_TYPE_NONE; // Indicates end of array
-
-   QCBORDecode_Private_GetItemInMap(pMe, OneItemSeach, pItem);
-
-#else
-   (void)pMe;
-   (void)szLabel;
-   (void)uQcborType;
-   (void)pItem;
-   pMe->uLastError = QCBOR_ERR_LABEL_NOT_FOUND;
-#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
-}
-
-/**
- * @brief Get an item by string label of a particular type
- *
- * @param[in] pMe         The decode context.
- * @param[in] szLabel     The label to search map for.
- * @param[in] uQcborType  The QCBOR type to look for.
- * @param[out] pItem      The item found.
- * @param[out] puOffset   The offset of item for tag consumption check.
- *
- * This finds the item with the given label in currently open
- * map. This does not call QCBORDecode_Private_GetItemChecks()
- * to check tag number consumption or decode conformance.
- */
-void
-QCBORDecode_Private_GetItemInMapNoCheckSZ(QCBORDecodeContext *pMe,
-                                  const char         *szLabel,
-                                  const uint8_t       uQcborType,
-                                  QCBORItem          *pItem,
-                                  size_t             *puOffset)
-{
-#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
-   QCBORItem OneItemSeach[2];
-
-   OneItemSeach[0].uLabelType   = QCBOR_TYPE_TEXT_STRING;
-   OneItemSeach[0].label.string = UsefulBuf_FromSZ(szLabel);
-   OneItemSeach[0].uDataType    = uQcborType;
-   OneItemSeach[1].uLabelType   = QCBOR_TYPE_NONE; // Indicates end of array
-
-   QCBORDecode_Private_GetItemInMapNoCheck(pMe, OneItemSeach, pItem, puOffset);
-
-#else
-   (void)pMe;
-   (void)szLabel;
-   (void)uQcborType;
-   (void)pItem;
-   (void)puOffset;
-   pMe->uLastError = QCBOR_ERR_LABEL_NOT_FOUND;
-#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
-}
-
-
-
-
-/**
- * @brief Semi-private. Get pointer, length and item for an array or map.
- *
- * @param[in] pMe            The decode context.
- * @param[in] uType          CBOR major type, either array/map.
- * @param[out] pItem         The item for the array/map.
- * @param[out] pEncodedCBOR  Pointer and length of the encoded map or array.
- *
- * The next item to be decoded must be a map or array as specified by @c uType.
- *
- * @c pItem will be filled in with the label and tags of the array or map
- * in addition to @c pEncodedCBOR giving the pointer and length of the
- * encoded CBOR.
- *
- * When this is complete, the traversal cursor is at the end of the array or
- * map that was retrieved.
- */
-void
-QCBORDecode_Private_GetArrayOrMap(QCBORDecodeContext *pMe,
-                                  const uint8_t       uType,
-                                  QCBORItem          *pItem,
-                                  UsefulBufC         *pEncodedCBOR)
-{
-   QCBORError uErr;
-   uint8_t    uNestLevel;
-   size_t     uStartingCursor;
-   size_t     uStartOfReturned;
-   size_t     uEndOfReturned;
-   size_t     uTempSaveCursor;
-   bool       bInMap;
-   QCBORItem  LabelItem;
-   bool       EndedByBreak;
-
-   uStartingCursor = UsefulInputBuf_Tell(&(pMe->InBuf));
-   bInMap = DecodeNesting_IsCurrentTypeMap(&(pMe->nesting));
-
-   /* Could call GetNext here, but don't need to because this
-    * is only interested in arrays and maps. TODO: switch to GetNext()? */
-   uErr = QCBORDecode_Private_GetNextMapOrArray(pMe, NULL, pItem, NULL);
-   if(uErr != QCBOR_SUCCESS) {
-      pMe->uLastError = (uint8_t)uErr;
-      return;
-   }
-
-   uint8_t uItemDataType = pItem->uDataType;
-#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
-   if(uItemDataType == QCBOR_TYPE_MAP_AS_ARRAY) {
-      uItemDataType = QCBOR_TYPE_ARRAY;
-   }
-#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
-
-   if(uItemDataType != uType) {
-      pMe->uLastError = QCBOR_ERR_UNEXPECTED_TYPE;
-      return;
-   }
-
-   if(bInMap) {
-      /* If the item is in a map, the start of the array/map
-       * itself, not the label, must be found. Do this by
-       * rewinding to the starting position and fetching
-       * just the label data item. QCBORDecode_Private_GetNextTagNumber()
-       * doesn't do any of the array/map item counting or nesting
-       * level tracking. Used here it will just fetech the label
-       * data item.
-       *
-       * Have to save the cursor and put it back to the position
-       * after the full item once the label as been fetched by
-       * itself.
-       */
-      uTempSaveCursor = UsefulInputBuf_Tell(&(pMe->InBuf));
-      UsefulInputBuf_Seek(&(pMe->InBuf), uStartingCursor);
-
-      /* Item has been fetched once so safe to ignore error */
-      (void)QCBORDecode_Private_GetNextTagNumber(pMe, &LabelItem);
-
-      uStartOfReturned = UsefulInputBuf_Tell(&(pMe->InBuf));
-      UsefulInputBuf_Seek(&(pMe->InBuf), uTempSaveCursor);
-   } else {
-      uStartOfReturned = uStartingCursor;
-   }
-
-   /* Consume the entire array/map to find the end */
-   uErr = QCBORDecode_Private_ConsumeItem(pMe, pItem, &EndedByBreak, &uNestLevel);
-   if(uErr != QCBOR_SUCCESS) {
-      pMe->uLastError = (uint8_t)uErr;
-      goto Done;
-   }
-
-   /* Fill in returned values */
-   uEndOfReturned = UsefulInputBuf_Tell(&(pMe->InBuf));
-   if(EndedByBreak) {
-      /* When ascending nesting levels, a break for the level above
-       * was consumed. That break is not a part of what is consumed here. */
-      uEndOfReturned--;
-   }
-   pEncodedCBOR->ptr = UsefulInputBuf_OffsetToPointer(&(pMe->InBuf), uStartOfReturned);
-   pEncodedCBOR->len = uEndOfReturned - uStartOfReturned;
-
-Done:
-   return;
-}
-
-
-/**
- * @brief Semi-private. Get pointer, length and item count of an array or map.
- *
- * @param[in] pMe            The decode context.
- * @param[in] pTarget        The label and type of the array or map to retrieve.
- * @param[out] pItem         The item for the array/map.
- * @param[out] pEncodedCBOR  Pointer and length of the encoded map or array.
- *
- * The next item to be decoded must be a map or array as specified by @c uType.
- *
- * When this is complete, the traversal cursor is unchanged.
- */void
-QCBORDecode_Private_SearchAndGetArrayOrMap(QCBORDecodeContext *pMe,
-                                           QCBORItem          *pTarget,
-                                           QCBORItem          *pItem,
-                                           UsefulBufC         *pEncodedCBOR)
-{
-   MapSearchInfo      Info;
-   QCBORDecodeNesting SaveNesting;
-   size_t             uSaveCursor;
-
-   pMe->uLastError = (uint8_t)QCBORDecode_Private_MapSearch(pMe, pTarget, &Info, NULL);
-   if(pMe->uLastError != QCBOR_SUCCESS) {
-      return;
-   }
-   pMe->uLastError = (uint8_t)QCBORDecode_Private_GetItemChecks(pMe, pMe->uLastError, Info.uStartOffset, pItem);
-   if(pMe->uLastError != QCBOR_SUCCESS) {
-      return;
-   }
-
-   /* Save the whole position of things so they can be restored.
-    * so the cursor position is unchanged by this operation, like
-    * all the other GetXxxxInMap() operations. */
-   DecodeNesting_PrepareForMapSearch(&(pMe->nesting), &SaveNesting);
-   uSaveCursor = UsefulInputBuf_Tell(&(pMe->InBuf));
-
-   DecodeNesting_ResetMapOrArrayCount(&(pMe->nesting));
-   UsefulInputBuf_Seek(&(pMe->InBuf), Info.uStartOffset);
-   QCBORDecode_Private_GetArrayOrMap(pMe, pTarget[0].uDataType, pItem, pEncodedCBOR);
-
-   UsefulInputBuf_Seek(&(pMe->InBuf), uSaveCursor);
-   DecodeNesting_RestoreFromMapSearch(&(pMe->nesting), &SaveNesting);
-}
-
-
-
-
-static void
-QCBORDecode_Private_ProcessTagOne(QCBORDecodeContext      *pMe,
-                                  QCBORItem               *pItem,
-                                  const uint8_t            uTagRequirement,
-                                  const uint8_t            uQCBORType,
-                                  const uint64_t           uTagNumber,
-                                  QCBORTagContentCallBack *pfCB,
-                                  size_t                   uOffset);
-
-/**
- * @brief Semi-private to get an string by label to match a tag specification.
- *
- * @param[in] pMe              The decode context.
- * @param[in] nLabel           Label to search map for.
- * @param[in] uTagRequirement  Whether or not tag number is required.
- *                             See @ref QCBOR_TAG_REQUIREMENT_TAG.
- * @param[in] uQCBOR_Type      QCBOR type to search for.
- * @param[in] uTagNumber       Tag number to match.
- * @param[out] pString         The string found.
- *
- * This finds the string  with the given label in currently open
- * map. Then checks that its tag number and types matches the tag
- * specification. If not, an error is set in the decode context.
- */
-void
-QCBORDecode_Private_GetTaggedStringInMapN(QCBORDecodeContext  *pMe,
-                                          const int64_t        nLabel,
-                                          const uint8_t        uTagRequirement,
-                                          const uint8_t        uQCBOR_Type,
-                                          const uint64_t       uTagNumber,
-                                          UsefulBufC          *pString)
-{
-   QCBORItem  Item;
-   size_t     uOffset;
-
-   QCBORDecode_Private_GetItemInMapNoCheckN(pMe, nLabel, QCBOR_TYPE_ANY, &Item, &uOffset);
-   QCBORDecode_Private_ProcessTagOne(pMe,
-                                    &Item,
-                                     uTagRequirement,
-                                     uQCBOR_Type,
-                                     uTagNumber,
-                                     QCBORDecode_StringsTagCB,
-                                     uOffset);
-
-   if(pMe->uLastError == QCBOR_SUCCESS) {
-      *pString = Item.val.string;
-   }
-}
-
-
-/**
- * @brief Semi-private to get an string by label to match a tag specification.
- *
- * @param[in] pMe              The decode context.
- * @param[in] szLabel           Label to search map for.
- * @param[in] uTagRequirement  Whether or not tag number is required.
- *                             See @ref QCBOR_TAG_REQUIREMENT_TAG.
- * @param[in] uQCBOR_Type      QCBOR type to search for.
- * @param[in] uTagNumber       Tag number to match.
- * @param[out] pString         The string found.
- *
- * This finds the string  with the given label in currently open
- * map. Then checks that its tag number and types matches the tag
- * specification. If not, an error is set in the decode context.
-  */
-void
-QCBORDecode_Private_GetTaggedStringInMapSZ(QCBORDecodeContext  *pMe,
-                                           const char          *szLabel,
-                                           uint8_t              uTagRequirement,
-                                           uint8_t              uQCBOR_Type,
-                                           uint64_t             uTagNumber,
-                                           UsefulBufC          *pString)
-{
-   QCBORItem Item;
-   size_t    uOffset;
-
-   QCBORDecode_Private_GetItemInMapNoCheckSZ(pMe, szLabel, QCBOR_TYPE_ANY, &Item, &uOffset);
-   QCBORDecode_Private_ProcessTagOne(pMe,
-                                   &Item,
-                                   uTagRequirement,
-                                   uQCBOR_Type,
-                                   uTagNumber,
-                                   QCBORDecode_StringsTagCB,
-                                   uOffset);
-
-
-   if(pMe->uLastError == QCBOR_SUCCESS) {
-      *pString = Item.val.string;
-   }
-}
-
-
-/*
- * Public function, see header qcbor/qcbor_decode.h file
- */
-void
-QCBORDecode_GetItemsInMap(QCBORDecodeContext *pMe, QCBORItem *pItemList)
-{
-   pMe->uLastError = (uint8_t)QCBORDecode_Private_MapSearch(pMe, pItemList, NULL, NULL);
-}
-
-/*
- * Public function, see header qcbor/qcbor_decode.h file
- */
-void
-QCBORDecode_GetItemsInMapWithCallback(QCBORDecodeContext *pMe,
-                                      QCBORItem          *pItemList,
-                                      void               *pCallbackCtx,
-                                      QCBORItemCallback   pfCB)
-{
-   MapSearchCallBack CallBack;
-
-   CallBack.pCBContext = pCallbackCtx;
-   CallBack.pfCallback = pfCB;
-
-   pMe->uLastError = (uint8_t)QCBORDecode_Private_MapSearch(pMe, pItemList, NULL, &CallBack);
-}
-
-
-#ifndef QCBOR_DISABLE_TAGS
-/*
- * Public function, see header qcbor/qcbor_decode.h file
- */
-QCBORError
-QCBORDecode_GetNextTagNumberInMapN(QCBORDecodeContext *pMe, const int64_t nLabel, uint64_t *puTagNumber)
-{
-   size_t         uOffset;
-   MapSearchInfo  Info;
-   QCBORItem      OneItemSeach[2];
-
-   if(pMe->uLastError != QCBOR_SUCCESS) {
-      return pMe->uLastError;
-   }
-
-   OneItemSeach[0].uLabelType  = QCBOR_TYPE_INT64;
-   OneItemSeach[0].label.int64 = nLabel;
-   OneItemSeach[0].uDataType   = QCBOR_TYPE_ANY;
-   OneItemSeach[1].uLabelType  = QCBOR_TYPE_NONE; // Indicates end of array
-
-   QCBORError uReturn = QCBORDecode_Private_MapSearch(pMe, OneItemSeach, &Info, NULL);
-
-   uOffset = Info.uStartOffset;
-   if(uOffset == pMe->uTagNumberCheckOffset) {
-      pMe->uTagNumberIndex++;
-   } else {
-      pMe->uTagNumberIndex = 0;
-   }
-
-   *puTagNumber = CBOR_TAG_INVALID64;
-
-   *puTagNumber = QCBORDecode_GetNthTagNumber(pMe, &OneItemSeach[0], pMe->uTagNumberIndex);
-   if(*puTagNumber == CBOR_TAG_INVALID64 ||
-      QCBORDecode_GetNthTagNumber(pMe, &OneItemSeach[0], pMe->uTagNumberIndex+1) == CBOR_TAG_INVALID64 ) {
-      pMe->uTagNumberIndex = QCBOR_ALL_TAGS_PROCESSED;
-   }
-   pMe->uTagNumberCheckOffset = uOffset;
-
-   return uReturn;
-}
-
-
-/*
- * Public function, see header qcbor/qcbor_decode.h file
- */
-QCBORError
-QCBORDecode_GetNextTagNumberInMapSZ(QCBORDecodeContext *pMe, const char *szLabel, uint64_t *puTagNumber)
-{
-#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
-   size_t         uOffset;
-   MapSearchInfo  Info;
-   QCBORItem      OneItemSeach[2];
-
-   if(pMe->uLastError != QCBOR_SUCCESS) {
-      return pMe->uLastError;
-   }
-
-   OneItemSeach[0].uLabelType   = QCBOR_TYPE_TEXT_STRING;
-   OneItemSeach[0].label.string = UsefulBuf_FromSZ(szLabel);
-   OneItemSeach[0].uDataType    = QCBOR_TYPE_ANY;
-   OneItemSeach[1].uLabelType   = QCBOR_TYPE_NONE; // Indicates end of array
-
-   QCBORError uReturn = QCBORDecode_Private_MapSearch(pMe, OneItemSeach, &Info, NULL);
-
-
-   uOffset = Info.uStartOffset;
-   if(uOffset == pMe->uTagNumberCheckOffset) {
-      pMe->uTagNumberIndex++;
-   } else {
-      pMe->uTagNumberIndex = 0;
-   }
-
-   *puTagNumber = CBOR_TAG_INVALID64;
-
-   *puTagNumber = QCBORDecode_GetNthTagNumber(pMe, &OneItemSeach[0], pMe->uTagNumberIndex);
-   if(*puTagNumber == CBOR_TAG_INVALID64 ||
-      QCBORDecode_GetNthTagNumber(pMe, &OneItemSeach[0], pMe->uTagNumberIndex+1) == CBOR_TAG_INVALID64 ) {
-      pMe->uTagNumberIndex = 255; /* All tags clear for this item */
-   }
-   pMe->uTagNumberCheckOffset = uOffset;
-
-   return uReturn;
-#else
-   (void)pMe;
-   (void)szLabel;
-   (void)puTagNumber;
-   return QCBOR_ERR_LABEL_NOT_FOUND;
-#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
-}
-#endif /* ! QCBOR_DISABLE_TAGS */
-
-
-/**
- * @brief Search for a map/array by label and enter it
- *
- * @param[in] pMe  The decode context.
- * @param[in] pSearch The map/array to search for.
- *
- * @c pSearch is expected to contain one item of type map or array
- * with the label specified. The current bounded map will be searched for
- * this and if found  will be entered.
- *
- * If the label is not found, or the item found is not a map or array,
- * the error state is set.
- */
-static void
-QCBORDecode_Private_SearchAndEnter(QCBORDecodeContext *pMe, QCBORItem pSearch[])
-{
-   QCBORError     uErr;
-   MapSearchInfo  SearchInfo;
-
-   // The first item in pSearch is the one that is to be
-   // entered. It should be the only one filled in. Any other
-   // will be ignored unless it causes an error.
-   if(pMe->uLastError != QCBOR_SUCCESS) {
-      return;
-   }
-
-   uErr = QCBORDecode_Private_MapSearch(pMe, pSearch, &SearchInfo, NULL);
-
-   pMe->uLastError = (uint8_t)QCBORDecode_Private_GetItemChecks(pMe, uErr, SearchInfo.uStartOffset, pSearch);
-
-   if(pMe->uLastError != QCBOR_SUCCESS) {
-      return;
-   }
-
-   if(pSearch->uDataType == QCBOR_TYPE_NONE) {
-      pMe->uLastError = QCBOR_ERR_LABEL_NOT_FOUND;
-      return;
-   }
-
-
-   /* The map or array was found. Now enter it.
-    *
-    * QCBORDecode_EnterBoundedMapOrArray() used here, requires the
-    * next item for the pre-order traversal cursor to be the map/array
-    * found by MapSearch(). The next few lines of code force the
-    * cursor to that.
-    *
-    * There is no need to retain the old cursor because
-    * QCBORDecode_EnterBoundedMapOrArray() will set it to the
-    * beginning of the map/array being entered.
-    *
-    * The cursor is forced by: 1) setting the input buffer position to
-    * the item offset found by MapSearch(), 2) setting the map/array
-    * counter to the total in the map/array, 3) setting the nesting
-    * level. Setting the map/array counter to the total is not
-    * strictly correct, but this is OK because this cursor only needs
-    * to be used to get one item and MapSearch() has already found it
-    * confirming it exists.
-    */
-   UsefulInputBuf_Seek(&(pMe->InBuf), SearchInfo.uStartOffset);
-
-   DecodeNesting_ResetMapOrArrayCount(&(pMe->nesting));
-
-   DecodeNesting_SetCurrentToBoundedLevel(&(pMe->nesting));
-
-   QCBORDecode_Private_EnterBoundedMapOrArray(pMe, pSearch->uDataType, NULL);
-}
-
-
-/*
- * Public function, see header qcbor/qcbor_decode.h file
- */
-void
-QCBORDecode_EnterMapFromMapN(QCBORDecodeContext *pMe, int64_t nLabel)
-{
-   QCBORItem OneItemSeach[2];
-   OneItemSeach[0].uLabelType  = QCBOR_TYPE_INT64;
-   OneItemSeach[0].label.int64 = nLabel;
-   OneItemSeach[0].uDataType   = QCBOR_TYPE_MAP;
-   OneItemSeach[1].uLabelType  = QCBOR_TYPE_NONE;
-
-   /* The map to enter was found, now finish off entering it. */
-   QCBORDecode_Private_SearchAndEnter(pMe, OneItemSeach);
-}
-
-
-/*
- * Public function, see header qcbor/qcbor_decode.h file
- */
-void
-QCBORDecode_EnterMapFromMapSZ(QCBORDecodeContext *pMe, const char  *szLabel)
-{
-#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
-   QCBORItem OneItemSeach[2];
-   OneItemSeach[0].uLabelType   = QCBOR_TYPE_TEXT_STRING;
-   OneItemSeach[0].label.string = UsefulBuf_FromSZ(szLabel);
-   OneItemSeach[0].uDataType    = QCBOR_TYPE_MAP;
-   OneItemSeach[1].uLabelType   = QCBOR_TYPE_NONE;
-
-   QCBORDecode_Private_SearchAndEnter(pMe, OneItemSeach);
-#else
-   (void)szLabel;
-   pMe->uLastError = QCBOR_ERR_LABEL_NOT_FOUND;
-#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
-}
-
-/*
- * Public function, see header qcbor/qcbor_decode.h file
- */
-void
-QCBORDecode_EnterArrayFromMapN(QCBORDecodeContext *pMe, int64_t nLabel)
-{
-   QCBORItem OneItemSeach[2];
-   OneItemSeach[0].uLabelType  = QCBOR_TYPE_INT64;
-   OneItemSeach[0].label.int64 = nLabel;
-   OneItemSeach[0].uDataType   = QCBOR_TYPE_ARRAY;
-   OneItemSeach[1].uLabelType  = QCBOR_TYPE_NONE;
-
-   QCBORDecode_Private_SearchAndEnter(pMe, OneItemSeach);
-}
-
-/*
- * Public function, see header qcbor/qcbor_decode.h file
- */
-void
-QCBORDecode_EnterArrayFromMapSZ(QCBORDecodeContext *pMe, const char  *szLabel)
-{
-#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
-   QCBORItem OneItemSeach[2];
-   OneItemSeach[0].uLabelType   = QCBOR_TYPE_TEXT_STRING;
-   OneItemSeach[0].label.string = UsefulBuf_FromSZ(szLabel);
-   OneItemSeach[0].uDataType    = QCBOR_TYPE_ARRAY;
-   OneItemSeach[1].uLabelType   = QCBOR_TYPE_NONE;
-
-   QCBORDecode_Private_SearchAndEnter(pMe, OneItemSeach);
-#else
-   (void)szLabel;
-   pMe->uLastError = QCBOR_ERR_LABEL_NOT_FOUND;
-#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
-}
-
-
-/**
- * @brief Semi-private to do the the work for EnterMap() and EnterArray().
- *
- * @param[in] pMe     The decode context
- * @param[in] uType   QCBOR_TYPE_MAP or QCBOR_TYPE_ARRAY.
- * @param[out] pItem  The data item for the map or array entered.
- *
- * The next item in the traversal must be a map or array.  This
- * consumes that item and does the book keeping to enter the map or
- * array.
- */
-void
-QCBORDecode_Private_EnterBoundedMapOrArray(QCBORDecodeContext *pMe,
-                                           const uint8_t       uType,
-                                           QCBORItem          *pItem)
-{
-    QCBORError uErr;
-
-   /* Must only be called on maps and arrays. */
-   if(pMe->uLastError != QCBOR_SUCCESS) {
-      // Already in error state; do nothing.
-      return;
-   }
-
-   /* Get the data item that is the map or array being entered. */
-   QCBORItem Item;
-   uErr = QCBORDecode_GetNext(pMe, &Item);
-   if(uErr != QCBOR_SUCCESS) {
-      goto Done;
-   }
-
-   uint8_t uItemDataType = Item.uDataType;
-
-#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
-   if(uItemDataType == QCBOR_TYPE_MAP_AS_ARRAY ) {
-      uItemDataType = QCBOR_TYPE_ARRAY;
-   }
-#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
-
-   if(uItemDataType != uType) {
-      uErr = QCBOR_ERR_UNEXPECTED_TYPE;
-      goto Done;
-   }
-
-   QCBORDecode_Private_SaveTagNumbers(pMe, &Item);
-
-
-   const bool bIsEmpty = (Item.uNextNestLevel <= Item.uNestingLevel);
-   if(bIsEmpty) {
-      if(DecodeNesting_IsCurrentDefiniteLength(&(pMe->nesting))) {
-         // Undo decrement done by QCBORDecode_GetNext() so the the
-         // the decrement when exiting the map/array works correctly
-         pMe->nesting.pCurrent->u.ma.uCountCursor++;
-      }
-      // Special case to increment nesting level for zero-length maps
-      // and arrays entered in bounded mode.
-      DecodeNesting_Descend(&(pMe->nesting), uType);
-   }
-
-   pMe->uMapEndOffsetCache = QCBOR_MAP_OFFSET_CACHE_INVALID;
-
-   uErr = DecodeNesting_EnterBoundedMapOrArray(&(pMe->nesting), bIsEmpty,
-                                               UsefulInputBuf_Tell(&(pMe->InBuf)));
-
-   if(pItem != NULL) {
-      *pItem = Item;
-   }
-
-Done:
-   pMe->uLastError = (uint8_t)uErr;
-}
-
-
-/**
- * @brief Exit a bounded map, array or bstr (semi-private).
- *
- * @param[in] pMe         Decode context.
- * @param[in] uEndOffset  The input buffer offset of the end of item exited.
- *
- * @returns  QCBOR_SUCCESS or an error code.
- *
- * This is the common work for exiting a level that is a bounded map,
- * array or bstr wrapped CBOR.
- *
- * One chunk of work is to set up the pre-order traversal so it is at
- * the item just after the bounded map, array or bstr that is being
- * exited. This is somewhat complex.
- *
- * The other work is to level-up the bounded mode to next higest
- * bounded mode or the top level if there isn't one.
- */
-static QCBORError
-QCBORDecode_Private_ExitBoundedLevel(QCBORDecodeContext *pMe,
-                                     const uint32_t      uEndOffset)
-{
-   QCBORError uErr;
-
-   /*
-    * First the pre-order-traversal byte offset is positioned to the
-    * item just after the bounded mode item that was just consumed.
-    */
-   UsefulInputBuf_Seek(&(pMe->InBuf), uEndOffset);
-
-   /*
-    * Next, set the current nesting level to one above the bounded
-    * level that was just exited.
-    *
-    * DecodeNesting_CheckBoundedType() is always called before this
-    * and makes sure pCurrentBounded is valid.
-    */
-   DecodeNesting_LevelUpCurrent(&(pMe->nesting));
-
-   /*
-    * This does the complex work of leveling up the pre-order
-    * traversal when the end of a map or array or another bounded
-    * level is reached.  It may do nothing, or ascend all the way to
-    * the top level.
-    */
-   uErr = QCBORDecode_Private_NestLevelAscender(pMe, NULL, false);
-   if(uErr != QCBOR_SUCCESS) {
-      goto Done;
-   }
-
-   /*
-    * This makes the next highest bounded level the current bounded
-    * level. If there is no next highest level, then no bounded mode
-    * is in effect.
-    */
-   DecodeNesting_LevelUpBounded(&(pMe->nesting));
-
-   pMe->uMapEndOffsetCache = QCBOR_MAP_OFFSET_CACHE_INVALID;
-
-Done:
-   return uErr;
-}
-
-
-/**
- * @brief Get started exiting a map or array (semi-private)
- *
- * @param[in] pMe  The decode context
- * @param[in] uType  QCBOR_TYPE_ARRAY or QCBOR_TYPE_MAP
- *
- * This does some work for map and array exiting (but not
- * bstr exiting). Then QCBORDecode_Private_ExitBoundedLevel()
- * is called to do the rest.
- */
-void
-QCBORDecode_Private_ExitBoundedMapOrArray(QCBORDecodeContext *pMe,
-                                          const uint8_t       uType)
-{
-   if(pMe->uLastError != QCBOR_SUCCESS) {
-      /* Already in error state; do nothing. */
-      return;
-   }
-
-   QCBORError uErr;
-
-   if(!DecodeNesting_IsBoundedType(&(pMe->nesting), uType)) {
-      uErr = QCBOR_ERR_EXIT_MISMATCH;
-      goto Done;
-   }
-
-   /*
-    Have to set the offset to the end of the map/array
-    that is being exited. If there is no cached value,
-    from previous map search, then do a dummy search.
-    */
-   if(pMe->uMapEndOffsetCache == QCBOR_MAP_OFFSET_CACHE_INVALID) {
-      QCBORItem Dummy;
-      Dummy.uLabelType = QCBOR_TYPE_NONE;
-      uErr = QCBORDecode_Private_MapSearch(pMe, &Dummy, NULL, NULL);
-      if(uErr != QCBOR_SUCCESS) {
-         goto Done;
-      }
-   }
-
-   uErr = QCBORDecode_Private_ExitBoundedLevel(pMe, pMe->uMapEndOffsetCache);
-
-Done:
-   pMe->uLastError = (uint8_t)uErr;
-}
-
-
-// TODO: re order this file with tags stuff last. bstr is a tag thing
-static QCBORError
-QCBORDecode_Private_CheckTagNType(QCBORDecodeContext *pMe,
-                                  const QCBORItem *pItem,
-                                  const size_t uOffset,
-                                  const uint8_t *uQCBORTypes,
-                                  const uint64_t *uTagNumbers,
-                                  const uint8_t uTagRequirement,
-                                  bool *bTypeMatched);
-
-/**
- * @brief The main work of entering some byte-string wrapped CBOR.
- *
- * @param[in] pMe             The decode context.
- * @param[in] pItem           The byte string item.
- * @param[in] uTagRequirement One of @c QCBOR_TAG_REQUIREMENT_XXX
- * @param[out] pBstr          Pointer and length of byte string entered.
- *
- * This is called once the byte string item has been decoded to do all
- * the book keeping work for descending a nesting level into the
- * nested CBOR.
- *
- * See QCBORDecode_EnterBstrWrapped() for details on uTagRequirement.
- */
-static QCBORError
-QCBORDecode_Private_EnterBstrWrapped(QCBORDecodeContext *pMe,
-                                     const QCBORItem    *pItem,
-                                     const uint8_t       uTagRequirement,
-                                     const size_t        uOffset,
-                                     UsefulBufC         *pBstr)
-{
-   bool       bTypeMatched;
-   QCBORError uError;
-
-   const uint8_t uTypes[] = {QBCOR_TYPE_WRAPPED_CBOR, QBCOR_TYPE_WRAPPED_CBOR_SEQUENCE, QCBOR_TYPE_NONE};
-   const uint64_t uTagNumbers[] = {CBOR_TAG_CBOR, CBOR_TAG_CBOR_SEQUENCE, CBOR_TAG_INVALID64};
-
-
-   if(pBstr) {
-      *pBstr = NULLUsefulBufC;
-   }
-
-   if(pMe->uLastError != QCBOR_SUCCESS) {
-      return pMe->uLastError;
-   }
-
-   if(pItem->uDataAlloc) {
-      return QCBOR_ERR_CANNOT_ENTER_ALLOCATED_STRING;
-   }
-
-   uError = QCBORDecode_Private_CheckTagNType(pMe,
-                                              pItem,
-                                              uOffset,
-                                              uTypes, // TODO: maybe this should be empty
-                                              uTagNumbers,
-                                              uTagRequirement,
-                                             &bTypeMatched);
-
-   if(pItem->uDataType != QCBOR_TYPE_BYTE_STRING) {
-      uError = QCBOR_ERR_BAD_TAG_CONTENT; // TODO: error
-   }
-
-
-   if(DecodeNesting_IsCurrentDefiniteLength(&(pMe->nesting))) {
-      /* Reverse the decrement done by GetNext() for the bstr so the
-       * increment in QCBORDecode_NestLevelAscender() called by
-       * ExitBoundedLevel() will work right.
-       */
-      DecodeNesting_ReverseDecrement(&(pMe->nesting));
-   }
-
-   if(pBstr) {
-      *pBstr = pItem->val.string;
-   }
-
-   /* This saves the current length of the UsefulInputBuf and then
-    * narrows the UsefulInputBuf to start and length of the wrapped
-    * CBOR that is being entered.
-    *
-    * Most of these calls are simple inline accessors so this doesn't
-    * amount to much code.
-    */
-
-   const size_t uPreviousLength = UsefulInputBuf_GetBufferLength(&(pMe->InBuf));
-   /* This check makes the cast of uPreviousLength to uint32_t below safe. */
-   if(uPreviousLength >= QCBOR_MAX_DECODE_INPUT_SIZE) {
-      uError = QCBOR_ERR_INPUT_TOO_LARGE;
-      goto Done;
-   }
-
-   const size_t uStartOfBstr = UsefulInputBuf_PointerToOffset(&(pMe->InBuf),
-                                                              pItem->val.string.ptr);
-   /* This check makes the cast of uStartOfBstr to uint32_t below safe. */
-   if(uStartOfBstr == SIZE_MAX || uStartOfBstr > QCBOR_MAX_DECODE_INPUT_SIZE) {
-      /* This should never happen because pItem->val.string.ptr should
-       * always be valid since it was just returned.
-       */
-      uError = QCBOR_ERR_INPUT_TOO_LARGE;
-      goto Done;
-   }
-
-   const size_t uEndOfBstr = uStartOfBstr + pItem->val.string.len;
-
-   UsefulInputBuf_Seek(&(pMe->InBuf), uStartOfBstr);
-   UsefulInputBuf_SetBufferLength(&(pMe->InBuf), uEndOfBstr);
-
-   uError = DecodeNesting_DescendIntoBstrWrapped(&(pMe->nesting),
-                                                 (uint32_t)uPreviousLength,
-                                                 (uint32_t)uStartOfBstr);
-Done:
-   return uError;
-}
-
-
-static void
-QCBORDecode_Private_GetAndTell(QCBORDecodeContext *pMe, QCBORItem *Item, size_t *uOffset)
-{
-#ifndef QCBOR_DISABLE_TAGS
-   if(pMe->uLastError != QCBOR_SUCCESS) {
-      return;
-   }
-
-   *uOffset = QCBORDecode_Tell(pMe);
-#else
-   *uOffset = SIZE_MAX;
-
-#endif /* ! QCBOR_DISABLE_TAGS */
-   pMe->uLastError = (uint8_t)QCBORDecode_Private_GetNextTagContent(pMe, Item);
-}
-
-
-/*
- * Public function, see header qcbor/qcbor_decode.h file
- */
-void
-QCBORDecode_EnterBstrWrapped(QCBORDecodeContext *pMe,
-                             const uint8_t       uTagRequirement,
-                             UsefulBufC         *pBstr)
-{
-   QCBORItem Item;
-   size_t    uOffset;
-
-   QCBORDecode_Private_GetAndTell(pMe, &Item, &uOffset);
-   pMe->uLastError = (uint8_t)QCBORDecode_Private_EnterBstrWrapped(pMe,
-                                                                  &Item,
-                                                                   uTagRequirement,
-                                                                   uOffset,
-                                                                   pBstr);
-}
-
-
-/*
- * Public function, see header qcbor/qcbor_decode.h file
- */
-void
-QCBORDecode_EnterBstrWrappedFromMapN(QCBORDecodeContext *pMe,
-                                     const int64_t       nLabel,
-                                     const uint8_t       uTagRequirement,
-                                     UsefulBufC         *pBstr)
-{
-   QCBORItem Item;
-   size_t    uOffset;
-
-   QCBORDecode_Private_GetItemInMapNoCheckN(pMe, nLabel, QCBOR_TYPE_BYTE_STRING, &Item, &uOffset);
-   pMe->uLastError = (uint8_t)QCBORDecode_Private_EnterBstrWrapped(pMe,
-                                                                  &Item,
-                                                                   uTagRequirement,
-                                                                   uOffset,
-                                                                   pBstr);
-}
-
-
-/*
- * Public function, see header qcbor/qcbor_decode.h file
- */
-void
-QCBORDecode_EnterBstrWrappedFromMapSZ(QCBORDecodeContext *pMe,
-                                      const char         *szLabel,
-                                      const uint8_t       uTagRequirement,
-                                      UsefulBufC         *pBstr)
-{
-   QCBORItem Item;
-   size_t    uOffset;
-
-   QCBORDecode_Private_GetItemInMapNoCheckSZ(pMe, szLabel, QCBOR_TYPE_BYTE_STRING, &Item, &uOffset);
-   pMe->uLastError = (uint8_t)QCBORDecode_Private_EnterBstrWrapped(pMe,
-                                                                  &Item,
-                                                                   uTagRequirement,
-                                                                   uOffset,
-                                                                   pBstr);
-}
-
-
-/*
- * Public function, see header qcbor/qcbor_decode.h file
- */
-void
-QCBORDecode_ExitBstrWrapped(QCBORDecodeContext *pMe)
-{
-   if(pMe->uLastError != QCBOR_SUCCESS) {
-      // Already in error state; do nothing.
-      return;
-   }
-
-   if(!DecodeNesting_IsBoundedType(&(pMe->nesting), QCBOR_TYPE_BYTE_STRING)) {
-      pMe->uLastError = QCBOR_ERR_EXIT_MISMATCH;
-      return;
-   }
-
-   const uint32_t uEndOfBstr = (uint32_t)UsefulInputBuf_GetBufferLength(&(pMe->InBuf));
-
-   /*
-    Reset the length of the UsefulInputBuf to what it was before
-    the bstr wrapped CBOR was entered.
-    */
-   UsefulInputBuf_SetBufferLength(&(pMe->InBuf),
-                               DecodeNesting_GetPreviousBoundedEnd(&(pMe->nesting)));
-
-
-   QCBORError uErr = QCBORDecode_Private_ExitBoundedLevel(pMe, uEndOfBstr);
-   pMe->uLastError = (uint8_t)uErr;
-}
-
-
-
-/**
- * @brief Process simple type true and false, a boolean
- *
- * @param[in] pMe     The decode context.
- * @param[in] pItem   The item with either true or false.
- * @param[out] pBool  The boolean value output.
- *
- * Sets the internal error if the item isn't a true or a false. Also
- * records any tag numbers as the tag numbers of the last item.
- */
-static void
-QCBORDecode_Private_ProcessBool(QCBORDecodeContext *pMe,
-                                const QCBORItem    *pItem,
-                                bool               *pBool)
-{
-   if(pMe->uLastError != QCBOR_SUCCESS) {
-      /* Already in error state, do nothing */
-      return;
-   }
-
-   switch(pItem->uDataType) {
-      case QCBOR_TYPE_TRUE:
-         *pBool = true;
-         break;
-
-      case QCBOR_TYPE_FALSE:
-         *pBool = false;
-         break;
-
-      default:
-         pMe->uLastError = QCBOR_ERR_UNEXPECTED_TYPE;
-         break;
-   }
-}
-
-
-/*
- * Public function, see header qcbor/qcbor_decode.h file
- */
-void
-QCBORDecode_GetBool(QCBORDecodeContext *pMe, bool *pValue)
-{
-   QCBORItem  Item;
-   QCBORDecode_VGetNext(pMe, &Item);
-   QCBORDecode_Private_ProcessBool(pMe, &Item, pValue);
-}
-
-
-/*
- * Public function, see header qcbor/qcbor_decode.h file
- */
-void
-QCBORDecode_GetBoolInMapN(QCBORDecodeContext *pMe,
-                          const int64_t       nLabel,
-                          bool               *pValue)
-{
-   QCBORItem Item;
-   QCBORDecode_GetItemInMapN(pMe, nLabel, QCBOR_TYPE_ANY, &Item);
-   QCBORDecode_Private_ProcessBool(pMe, &Item, pValue);
-}
-
-
-/*
- * Public function, see header qcbor/qcbor_decode.h file
- */
-void
-QCBORDecode_GetBoolInMapSZ(QCBORDecodeContext *pMe,
-                           const char         *szLabel,
-                           bool               *pValue)
-{
-   QCBORItem Item;
-   QCBORDecode_GetItemInMapSZ(pMe, szLabel, QCBOR_TYPE_ANY, &Item);
-   QCBORDecode_Private_ProcessBool(pMe, &Item, pValue);
-}
-
-
-/**
- * @brief Process simple values.
- *
- * @param[in] pMe     The decode context.
- * @param[in] pItem   The item with the simple value.
- * @param[out] puSimple  The simple value output.
- *
- * Sets the internal error if the item isn't a true or a false. Also
- * records any tag numbers as the tag numbers of the last item.
- */
-static void
-QCBORDecode_Private_ProcessSimple(QCBORDecodeContext *pMe,
-                                  const QCBORItem    *pItem,
-                                  uint8_t            *puSimple)
-{
-   if(pMe->uLastError != QCBOR_SUCCESS) {
-      return;
-   }
-
-   /* It's kind of lame to remap true...undef back to simple values, but
-    * this function isn't used much and to not do it would require
-    * changing GetNext() behavior in an incompatible way.
-    */
-   switch(pItem->uDataType) {
-      case QCBOR_TYPE_UKNOWN_SIMPLE:
-         *puSimple = pItem->val.uSimple;
-         break;
-
-      case QCBOR_TYPE_TRUE:
-         *puSimple = CBOR_SIMPLEV_TRUE;
-         break;
-
-      case QCBOR_TYPE_FALSE:
-         *puSimple = CBOR_SIMPLEV_FALSE;
-         break;
-
-      case QCBOR_TYPE_NULL:
-         *puSimple = CBOR_SIMPLEV_NULL;
-         break;
-
-      case QCBOR_TYPE_UNDEF:
-         *puSimple = CBOR_SIMPLEV_UNDEF;
-         break;
-
-      default:
-         pMe->uLastError = QCBOR_ERR_UNEXPECTED_TYPE;
-         return;
-   }
-}
-
-/*
- * Public function, see header qcbor/qcbor_decode.h file
- */
-void
-QCBORDecode_GetSimple(QCBORDecodeContext *pMe, uint8_t *puSimple)
-{
-   QCBORItem Item;
-   QCBORDecode_VGetNext(pMe, &Item);
-   QCBORDecode_Private_ProcessSimple(pMe, &Item, puSimple);
-}
-
-/*
- * Public function, see header qcbor/qcbor_decode.h file
- */
-void
-QCBORDecode_GetSimpleInMapN(QCBORDecodeContext *pMe,
-                            int64_t             nLabel,
-                            uint8_t            *puSimpleValue)
-{
-   QCBORItem Item;
-   QCBORDecode_GetItemInMapN(pMe, nLabel, QCBOR_TYPE_ANY, &Item);
-   QCBORDecode_Private_ProcessSimple(pMe, &Item, puSimpleValue);
-}
-
-/*
- * Public function, see header qcbor/qcbor_decode.h file
- */
-void
-QCBORDecode_GetSimpleInMapSZ(QCBORDecodeContext *pMe,
-                             const char         *szLabel,
-                             uint8_t            *puSimpleValue)
-{
-   QCBORItem Item;
-   QCBORDecode_GetItemInMapSZ(pMe, szLabel, QCBOR_TYPE_ANY, &Item);
-   QCBORDecode_Private_ProcessSimple(pMe, &Item, puSimpleValue);
-}
-
-
-
-
-#ifndef QCBOR_DISABLE_TAGS
-// TODO:  uTagNumber might be better a list than calling this multiple times
-static QCBORError
-QCBORDecode_Private_Check1TagNumber(const QCBORDecodeContext *pMe,
-                                    const QCBORItem          *pItem,
-                                    const uint64_t            uTagNumber,
-                                    const size_t              uOffset)
-{
-   if(pItem->auTagNumbers[0] == CBOR_TAG_INVALID16) {
-      /* There are no tag numbers at all, so no unprocessed */
-      return QCBOR_SUCCESS;
-   }
-
-   /* There are some tag numbers, so keep checking. This check passes
-    * if there is one and only one tag number that matches uTagNumber
-    */
-
-   // TODO: behave different in v1 and v2?
-
-   const uint64_t uInnerTag = QCBORDecode_GetNthTagNumber(pMe, pItem, 0);
-
-   if(uInnerTag == uTagNumber && pItem->auTagNumbers[1] == CBOR_TAG_INVALID16 ) {
-      /* The only tag number is the one we are processing so no unprocessed */
-      return QCBOR_SUCCESS;
-   }
-
-   if(uOffset != pMe->uTagNumberCheckOffset) {
-      /* processed tag numbers are for some other item, not us */
-      return QCBOR_ERR_UNPROCESSED_TAG_NUMBER;
-   }
-
-   if(pMe->uTagNumberIndex != 1) {
-      return QCBOR_ERR_UNPROCESSED_TAG_NUMBER;
-   }
-
-   return QCBOR_SUCCESS;
-}
-#endif
-
-
-static QCBORError
-QCBORDecode_Private_CheckTagNType(QCBORDecodeContext *pMe,
-                                  const QCBORItem    *pItem,
-                                  const size_t        uOffset,
-                                  const uint8_t      *uQCBORTypes,
-                                  const uint64_t     *uTagNumbers,
-                                  const uint8_t       uTagRequirement,
-                                  bool               *bTypeMatched)
-{
-   const int      nTagReq   = uTagRequirement & ~QCBOR_TAG_REQUIREMENT_ALLOW_ADDITIONAL_TAGS;
-
-   *bTypeMatched = false;
-   for(const uint8_t *pTNum = uQCBORTypes; *pTNum != QCBOR_TYPE_NONE; pTNum++) {
-      if(pItem->uDataType == *pTNum) {
-         *bTypeMatched = true;
-         break;
-      }
-   }
-
-#ifndef QCBOR_DISABLE_TAGS
-   bool        bTagNumberMatched;
-   QCBORError  uErr;
-   const uint64_t uInnerTag = QCBORDecode_GetNthTagNumber(pMe, pItem, 0);
-
-   bTagNumberMatched = false;
-   for(const uint64_t *pQType = uTagNumbers; *pQType != CBOR_TAG_INVALID64; pQType++) {
-      if(uInnerTag == *pQType) {
-         bTagNumberMatched = true;
-         break;
-      }
-   }
-
-
-   if(nTagReq == QCBOR_TAG_REQUIREMENT_TAG) {
-      /* There must be a tag number */
-      if(!bTagNumberMatched && !*bTypeMatched) {
-         return QCBOR_ERR_UNEXPECTED_TYPE; // TODO: error code
-      }
-
-   } else if(nTagReq == QCBOR_TAG_REQUIREMENT_NOT_A_TAG) {
-      if(bTagNumberMatched || *bTypeMatched) {
-         return QCBOR_ERR_UNEXPECTED_TYPE; // TODO: error code
-      }
-
-   } else if(nTagReq == QCBOR_TAG_REQUIREMENT_OPTIONAL_TAG) {
-      /* No check necessary */
-   }
-
-   /* Now check if there are extra tags and if there's an error in them */
-   if(!(uTagRequirement & QCBOR_TAG_REQUIREMENT_ALLOW_ADDITIONAL_TAGS)) {
-      /* The flag to ignore extra is not set, so keep checking */
-      for(const uint64_t *pTNum = uTagNumbers; *pTNum != CBOR_TAG_INVALID64; pTNum++) {
-         uErr = QCBORDecode_Private_Check1TagNumber(pMe, pItem, *pTNum, uOffset);
-         if(uErr != QCBOR_SUCCESS) {
-            return uErr;
-         }
-      }
-   }
-
-   return QCBOR_SUCCESS;
-#else
-   (void)pMe;
-   (void)uOffset;
-   (void)uTagNumbers;
-
-   if(nTagReq != QCBOR_TAG_REQUIREMENT_TAG && bTypeMatched) {
-      return QCBOR_SUCCESS;
-   } else {
-      return QCBOR_ERR_UNEXPECTED_TYPE;
-   }
-
-#endif
-
-}
-
-
-void
-QCBORDecode_Private_ProcessTagItemMulti(QCBORDecodeContext      *pMe,
-                                        QCBORItem               *pItem,
-                                        const uint8_t            uTagRequirement,
-                                        const uint8_t            uQCBORTypes[],
-                                        const uint64_t           uTagNumbers[],
-                                        QCBORTagContentCallBack *pfCB,
-                                        size_t                   uOffset)
-{
-   QCBORError uErr;
-   bool       bTypeMatched;
-
-   if(pMe->uLastError != QCBOR_SUCCESS) {
-      return;
-   }
-
-   uErr = QCBORDecode_Private_CheckTagNType(pMe,
-                                            pItem,
-                                            uOffset,
-                                            uQCBORTypes,
-                                            uTagNumbers,
-                                            uTagRequirement,
-                                            &bTypeMatched);
-   if(uErr != QCBOR_SUCCESS) {
-      goto Done;
-   }
-
-   if(!bTypeMatched) {
-      /* Tag content wasn't previously processed, do it now */
-      uErr = (*pfCB)(pMe, NULL, uTagNumbers[0], pItem);
-      if(uErr != QCBOR_SUCCESS) {
-         goto Done;
-      }
-   }
-
-Done:
-   pMe->uLastError = (uint8_t)uErr;
-}
-
-
-/*
- **/
-void
-QCBORDecode_Private_ProcessTagItem(QCBORDecodeContext      *pMe,
-                                   QCBORItem               *pItem,
-                                   const uint8_t            uTagRequirement,
-                                   const uint8_t            uQCBORTypes[],
-                                   const uint64_t           uTagNumber,
-                                   QCBORTagContentCallBack *pfCB,
-                                   size_t                   uOffset)
-{
-   uint64_t auTagNumbers[2];
-
-   auTagNumbers[0] = uTagNumber;
-   auTagNumbers[1] = CBOR_TAG_INVALID64;
-
-   QCBORDecode_Private_ProcessTagItemMulti(pMe,
-                                           pItem,
-                                           uTagRequirement,
-                                           uQCBORTypes,
-                                           auTagNumbers,
-                                           pfCB,
-                                           uOffset);
-}
-
-
-static void
-QCBORDecode_Private_ProcessTagOne(QCBORDecodeContext     *pMe,
-                                  QCBORItem               *pItem,
-                                  const uint8_t            uTagRequirement,
-                                  const uint8_t            uQCBORType,
-                                  const uint64_t           uTagNumber,
-                                  QCBORTagContentCallBack *pfCB,
-                                  const size_t             uOffset)
-{
-   uint8_t auQCBORType[2];
-
-   auQCBORType[0] = uQCBORType;
-   auQCBORType[1] = QCBOR_TYPE_NONE;
-
-   QCBORDecode_Private_ProcessTagItem(pMe,
-                                      pItem,
-                                      uTagRequirement,
-                                      auQCBORType,
-                                      uTagNumber,
-                                      pfCB,
-                                      uOffset);
-}
-
-
-
-
-/*
- * Public function, see header qcbor/qcbor_spiffy_decode.h file
- */
-void
-QCBORDecode_GetEpochDate(QCBORDecodeContext *pMe,
-                         uint8_t             uTagRequirement,
-                         int64_t            *pnTime)
-{
-   QCBORItem  Item;
-   size_t     uOffset;
-
-   QCBORDecode_Private_GetAndTell(pMe, &Item, &uOffset);
-   QCBORDecode_Private_ProcessTagOne(pMe,
-                                     &Item,
-                                     uTagRequirement,
-                                     QCBOR_TYPE_DATE_EPOCH,
-                                     CBOR_TAG_DATE_EPOCH,
-                                     QCBORDecode_DateEpochTagCB,
-                                     uOffset);
-   *pnTime = Item.val.epochDate.nSeconds;
-}
-
-
-/*
- * Public function, see header qcbor/qcbor_spiffy_decode.h file
- */
-void
-QCBORDecode_GetEpochDateInMapN(QCBORDecodeContext *pMe,
-                               int64_t             nLabel,
-                               uint8_t             uTagRequirement,
-                               int64_t            *pnTime)
-{
-   QCBORItem Item;
-   size_t uOffset;
-
-   QCBORDecode_Private_GetItemInMapNoCheckN(pMe, nLabel, QCBOR_TYPE_ANY, &Item, &uOffset);
-   QCBORDecode_Private_ProcessTagOne(pMe,
-                                     &Item,
-                                     uTagRequirement,
-                                     QCBOR_TYPE_DATE_EPOCH,
-                                     CBOR_TAG_DATE_EPOCH,
-                                     QCBORDecode_DateEpochTagCB,
-                                     uOffset);
-   *pnTime = Item.val.epochDate.nSeconds;
-}
-
-
-/*
- * Public function, see header qcbor/qcbor_spiffy_decode.h file
- */
-void
-QCBORDecode_GetEpochDateInMapSZ(QCBORDecodeContext *pMe,
-                                const char         *szLabel,
-                                uint8_t             uTagRequirement,
-                                int64_t            *pnTime)
-{
-   QCBORItem Item;
-   size_t uOffset;
-
-   QCBORDecode_Private_GetItemInMapNoCheckSZ(pMe, szLabel, QCBOR_TYPE_ANY, &Item, &uOffset);
-   QCBORDecode_Private_ProcessTagOne(pMe,
-                                     &Item,
-                                     uTagRequirement,
-                                     QCBOR_TYPE_DATE_EPOCH,
-                                     CBOR_TAG_DATE_EPOCH,
-                                     QCBORDecode_DateEpochTagCB,
-                                     uOffset);
-   *pnTime = Item.val.epochDate.nSeconds;
-}
-
-
-/*
- * Public function, see header qcbor/qcbor_decode.h
- */
-void
-QCBORDecode_GetEpochDays(QCBORDecodeContext *pMe,
-                         uint8_t             uTagRequirement,
-                         int64_t            *pnDays)
-{
-   QCBORItem  Item;
-   size_t     uOffset;
-
-   QCBORDecode_Private_GetAndTell(pMe, &Item, &uOffset);
-   QCBORDecode_Private_ProcessTagOne(pMe,
-                                     &Item,
-                                     uTagRequirement,
-                                     QCBOR_TYPE_DAYS_EPOCH,
-                                     CBOR_TAG_DAYS_EPOCH,
-                                     QCBORDecode_DaysEpochTagCB,
-                                     uOffset);
-   *pnDays = Item.val.epochDays;
-}
-
-
-/*
- * Public function, see header qcbor/qcbor_decode.h
- */
-void
-QCBORDecode_GetEpochDaysInMapN(QCBORDecodeContext *pMe,
-                               int64_t             nLabel,
-                               uint8_t             uTagRequirement,
-                               int64_t            *pnDays)
-{
-   QCBORItem Item;
-   size_t uOffset;
-
-   QCBORDecode_Private_GetItemInMapNoCheckN(pMe, nLabel, QCBOR_TYPE_ANY, &Item, &uOffset);
-   QCBORDecode_Private_ProcessTagOne(pMe,
-                                     &Item,
-                                     uTagRequirement,
-                                     QCBOR_TYPE_DAYS_EPOCH,
-                                     CBOR_TAG_DAYS_EPOCH,
-                                     QCBORDecode_DaysEpochTagCB,
-                                     uOffset);
-   *pnDays = Item.val.epochDays;
-}
-
-
-/*
- * Public function, see header qcbor/qcbor_decode.h
- */
-void
-QCBORDecode_GetEpochDaysInMapSZ(QCBORDecodeContext *pMe,
-                                const char         *szLabel,
-                                uint8_t             uTagRequirement,
-                                int64_t            *pnDays)
-{
-   QCBORItem Item;
-   size_t    uOffset;
-
-   QCBORDecode_Private_GetItemInMapNoCheckSZ(pMe, szLabel, QCBOR_TYPE_ANY, &Item, &uOffset);
-   QCBORDecode_Private_ProcessTagOne(pMe,
-                                      &Item,
-                                      uTagRequirement,
-                                      QCBOR_TYPE_DAYS_EPOCH,
-                                      CBOR_TAG_DAYS_EPOCH,
-                                      QCBORDecode_DaysEpochTagCB,
-                                      uOffset);
-   *pnDays = Item.val.epochDays;
-}
-
-
-
-
-void
-QCBORDecode_Private_GetTaggedString(QCBORDecodeContext  *pMe,
-                                    const uint8_t        uTagRequirement,
-                                    const uint8_t        uQCBOR_Type,
-                                    const uint64_t       uTagNumber,
-                                    UsefulBufC          *pStr)
-{
-   QCBORItem  Item;
-   size_t uOffset;
-
-   QCBORDecode_Private_GetAndTell(pMe, &Item, &uOffset);
-   QCBORDecode_Private_ProcessTagOne(pMe,
-                                     &Item,
-                                      uTagRequirement,
-                                      uQCBOR_Type,
-                                      uTagNumber,
-                                      QCBORDecode_StringsTagCB,
-                                      uOffset);
-
-   if(pMe->uLastError == QCBOR_SUCCESS) {
-      *pStr = Item.val.string;
-   } else {
-      *pStr = NULLUsefulBufC;
-   }
-}
-
-
-
-static void
-QCBORDecode_Private_GetMIME(QCBORDecodeContext *pMe,
-                            const uint8_t       uTagRequirement,
-                            QCBORItem          *pItem,
-                            UsefulBufC         *pValue,
-                            bool               *pbIsTag257,
-                            size_t              uOffset)
-{
-   QCBORError uErr;
-
-   const uint8_t puTypes[] = {QCBOR_TYPE_MIME, QCBOR_TYPE_BINARY_MIME, QCBOR_TYPE_NONE};
-
-   const uint64_t puTNs[] = {CBOR_TAG_MIME, CBOR_TAG_BINARY_MIME, CBOR_TAG_INVALID64};
-
-   QCBORDecode_Private_ProcessTagItemMulti(pMe,
-                                           pItem,
-                                           uTagRequirement,
-                                           puTypes,
-                                           puTNs,
-                                           QCBORDecode_MIMETagCB,
-                                           uOffset);
-   if(pMe->uLastError) {
-      return;
-   }
-
-   if(pItem->uDataType == QCBOR_TYPE_MIME) {
-      *pbIsTag257 = false;
-   } else if(pItem->uDataType == QCBOR_TYPE_BINARY_MIME) {
-      *pbIsTag257 = true;
-   }
-   *pValue = pItem->val.string;
-
-
-   uErr = QCBOR_SUCCESS;
-
-   pMe->uLastError = (uint8_t)uErr;
-}
-
-
-void
-QCBORDecode_GetMIMEMessage(QCBORDecodeContext *pMe,
-                           const uint8_t       uTagRequirement,
-                           UsefulBufC         *pMessage,
-                           bool               *pbIsTag257)
-{
-   QCBORItem  Item;
-   size_t     uOffset;
-
-   QCBORDecode_Private_GetAndTell(pMe, &Item, &uOffset);
-   QCBORDecode_Private_GetMIME(pMe,
-                               uTagRequirement,
-                              &Item,
-                               pMessage,
-                               pbIsTag257,
-                               uOffset);
-}
-
-void
-QCBORDecode_GetMIMEMessageInMapN(QCBORDecodeContext *pMe,
-                                 const int64_t       nLabel,
-                                 const uint8_t       uTagRequirement,
-                                 UsefulBufC         *pMessage,
-                                 bool               *pbIsTag257)
-{
-   QCBORItem  Item;
-   size_t     uOffset;
-
-   QCBORDecode_Private_GetItemInMapNoCheckN(pMe, nLabel, QCBOR_TYPE_ANY, &Item, &uOffset);
-   QCBORDecode_Private_GetMIME(pMe,
-                                uTagRequirement,
-                               &Item,
-                                pMessage,
-                                pbIsTag257,
-                                uOffset);
-}
-
-void
-QCBORDecode_GetMIMEMessageInMapSZ(QCBORDecodeContext *pMe,
-                                  const char         *szLabel,
-                                  const uint8_t       uTagRequirement,
-                                  UsefulBufC         *pMessage,
-                                  bool               *pbIsTag257)
-{
-   QCBORItem  Item;
-   size_t     uOffset;
-
-   QCBORDecode_Private_GetItemInMapNoCheckSZ(pMe, szLabel, QCBOR_TYPE_ANY, &Item, &uOffset);
-   QCBORDecode_Private_GetMIME(pMe,
-                                uTagRequirement,
-                               &Item,
-                                pMessage,
-                                pbIsTag257,
-                                uOffset);
-}
-
-
-
 // Improvement: add methods for wrapped CBOR, a simple alternate
 // to EnterBstrWrapped
 
diff --git a/src/qcbor_number_decode.c b/src/qcbor_number_decode.c
index 6873b94..5c6f3e3 100644
--- a/src/qcbor_number_decode.c
+++ b/src/qcbor_number_decode.c
@@ -1,5 +1,5 @@
 /* ==========================================================================
- * number_decode.c -- Number decoding beyond the basic ints and floats
+ * qcbor_number_decode.c -- Number decoding beyond the basic ints and floats
  *
  * Copyright (c) 2016-2018, The Linux Foundation.
  * Copyright (c) 2018-2024, Laurence Lundblade.
@@ -10,7 +10,7 @@
  *
  * See BSD-3-Clause license in README.md
  *
- *  Created on 11/14/24 from qcbor_decode.c
+ * Created on 11/14/24 from qcbor_decode.c
  * ========================================================================== */
 
 
diff --git a/src/qcbor_spiffy_decode.c b/src/qcbor_spiffy_decode.c
new file mode 100644
index 0000000..5c25f54
--- /dev/null
+++ b/src/qcbor_spiffy_decode.c
@@ -0,0 +1,1197 @@
+
+
+/* ==========================================================================
+ * qcbor_spiffy_decode.c -- "Spiffy" QCBOR decoding
+ *
+ * Copyright (c) 2016-2018, The Linux Foundation.
+ * Copyright (c) 2018-2024, Laurence Lundblade.
+ * Copyright (c) 2021, Arm Limited.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * See BSD-3-Clause license in README.md
+ *
+ * Created on 11/28/24 from qcbor_decode.c
+ * ========================================================================== */
+
+
+#include "qcbor/qcbor_decode.h"
+#include "qcbor/qcbor_spiffy_decode.h"
+// TODO: see about removing these two includes
+#include "qcbor/qcbor_tag_decode.h"
+#include "ieee754.h" /* Does not use math.h */
+#include "decode_private.h"
+#include "decode_nesting.h"
+
+
+
+#if (defined(__GNUC__) && !defined(__clang__))
+/*
+ * This is how the -Wmaybe-uninitialized compiler warning is
+ * handled. It can’t be ignored because some version of gcc enable it
+ * with -Wall which is a common and useful gcc warning option. It also
+ * can’t be ignored because it is the goal of QCBOR to compile clean
+ * out of the box in all environments.
+ *
+ * The big problem with -Wmaybe-uninitialized is that it generates
+ * false positives. It complains things are uninitialized when they
+ * are not. This is because it is not a thorough static analyzer. This
+ * is why “maybe” is in its name. The problem is it is just not
+ * thorough enough to understand all the code (and someone saw fit to
+ * put it in gcc and worse to enable it with -Wall).
+ *
+ * One solution would be to change the code so -Wmaybe-uninitialized
+ * doesn’t get confused, for example adding an unnecessary extra
+ * initialization to zero. (If variables were truly uninitialized, the
+ * correct path is to understand the code thoroughly and set them to
+ * the correct value at the correct time; in essence this is already
+ * done; -Wmaybe-uninitialized just can’t tell). This path is not
+ * taken because it makes the code bigger and is kind of the tail
+ * wagging the dog.
+ *
+ * The solution here is to just use a pragma to disable it for the
+ * whole file. Disabling it for each line makes the code fairly ugly
+ * requiring #pragma to push, pop and ignore. Another reason is the
+ * warnings issues vary by version of gcc and which optimization
+ * optimizations are selected. Another reason is that compilers other
+ * than gcc don’t have -Wmaybe-uninitialized.
+ *
+ * One may ask how to be sure these warnings are false positives and
+ * not real issues. 1) The code has been read carefully to check. 2)
+ * Testing is pretty thorough. 3) This code has been run through
+ * thorough high-quality static analyzers.
+ *
+ * In particularly, most of the warnings are about
+ * Item.Item->uDataType being uninitialized. QCBORDecode_GetNext()
+ * *always* sets this value and test case confirm
+ * this. -Wmaybe-uninitialized just can't tell.
+ *
+ * https://stackoverflow.com/questions/5080848/disable-gcc-may-be-used-uninitialized-on-a-particular-variable
+ */
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+
+
+/* Return true if the labels in Item1 and Item2 are the same.
+   Works only for integer and string labels. Returns false
+   for any other type. */
+static bool
+QCBORItem_MatchLabel(const QCBORItem Item1, const QCBORItem Item2)
+{
+   if(Item1.uLabelType == QCBOR_TYPE_INT64) {
+      if(Item2.uLabelType == QCBOR_TYPE_INT64 && Item1.label.int64 == Item2.label.int64) {
+         return true;
+      }
+#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
+   } else if(Item1.uLabelType == QCBOR_TYPE_TEXT_STRING) {
+      if(Item2.uLabelType == QCBOR_TYPE_TEXT_STRING && !UsefulBuf_Compare(Item1.label.string, Item2.label.string)) {
+         return true;
+      }
+   } else if(Item1.uLabelType == QCBOR_TYPE_BYTE_STRING) {
+      if(Item2.uLabelType == QCBOR_TYPE_BYTE_STRING && !UsefulBuf_Compare(Item1.label.string, Item2.label.string)) {
+         return true;
+      }
+   } else if(Item1.uLabelType == QCBOR_TYPE_UINT64) {
+      if(Item2.uLabelType == QCBOR_TYPE_UINT64 && Item1.label.uint64 == Item2.label.uint64) {
+         return true;
+      }
+#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
+   }
+
+   /* Other label types are never matched */
+   return false;
+}
+
+
+
+/*
+ Returns true if Item1 and Item2 are the same type
+ or if either are of QCBOR_TYPE_ANY.
+ */
+static bool
+QCBORItem_MatchType(const QCBORItem Item1, const QCBORItem Item2)
+{
+   if(Item1.uDataType == Item2.uDataType) {
+      return true;
+   } else if(Item1.uDataType == QCBOR_TYPE_ANY) {
+      return true;
+   } else if(Item2.uDataType == QCBOR_TYPE_ANY) {
+      return true;
+   }
+   return false;
+}
+
+/**
+ * @brief Rewind cursor to start as if map or array were just entered.
+ *
+ * @param[in]  pMe   The decoding context
+ *
+ * This affects the nesting tracking and the UsefulInputBuf.
+ */
+static void
+QCBORDecode_Private_RewindMapOrArray(QCBORDecodeContext *pMe)
+{
+   /* Reset nesting tracking to the deepest bounded level */
+   DecodeNesting_SetCurrentToBoundedLevel(&(pMe->nesting));
+
+   DecodeNesting_ResetMapOrArrayCount(&(pMe->nesting));
+
+   /* Reposition traversal cursor to the start of the map/array */
+   UsefulInputBuf_Seek(&(pMe->InBuf),
+                       DecodeNesting_GetMapOrArrayStart(&(pMe->nesting)));
+}
+
+
+/*
+ * Public function, see header qcbor/qcbor_decode.h file
+ */
+void
+QCBORDecode_Rewind(QCBORDecodeContext *pMe)
+{
+   if(pMe->nesting.pCurrentBounded != NULL) {
+      /* In a bounded map, array or bstr-wrapped CBOR */
+
+      if(DecodeNesting_IsBoundedType(&(pMe->nesting), QCBOR_TYPE_BYTE_STRING)) {
+         /* In bstr-wrapped CBOR. */
+
+         /* Reposition traversal cursor to start of wrapping byte string */
+         UsefulInputBuf_Seek(&(pMe->InBuf),
+                             pMe->nesting.pCurrentBounded->u.bs.uBstrStartOffset);
+         DecodeNesting_SetCurrentToBoundedLevel(&(pMe->nesting));
+
+      } else {
+         /* In a map or array */
+         QCBORDecode_Private_RewindMapOrArray(pMe);
+      }
+
+   } else {
+      /* Not in anything bounded */
+
+      /* Reposition traversal cursor to the start of input CBOR */
+      UsefulInputBuf_Seek(&(pMe->InBuf), 0ULL);
+
+      /* Reset nesting tracking to beginning of input. */
+      DecodeNesting_Init(&(pMe->nesting));
+   }
+
+   pMe->uLastError = QCBOR_SUCCESS;
+}
+
+
+
+
+/**
+ * @brief Search a map for a set of items.
+ *
+ * @param[in]  pMe           The decode context to search.
+ * @param[in,out] pItemArray The items to search for and the items found.
+ * @param[out] pInfo         Several bits of meta-info returned by search.
+ * @param[in] pCallBack      Callback object or @c NULL.
+ *
+ * @retval QCBOR_ERR_NOT_ENTERED     Trying to search without entering a map.
+ *
+ * @retval QCBOR_ERR_DUPLICATE_LABEL Duplicate items (items with the same label)
+ *                                   were found for one of the labels being
+ *                                   search for. This duplicate detection is
+ *                                   only performed for items in pItemArray,
+ *                                   not every item in the map.
+ *
+ * @retval QCBOR_ERR_UNEXPECTED_TYPE A label was matched, but the type was
+ *                                   wrong for the matchd label.
+ *
+ * @retval Also errors returned by QCBORDecode_GetNext().
+ *
+ * On input, @c pItemArray contains a list of labels and data types of
+ * items to be found.
+ *
+ * On output, the fully retrieved items are filled in with values and
+ * such. The label was matched, so it never changes.
+ *
+ * If an item was not found, its data type is set to @ref QCBOR_TYPE_NONE.
+ *
+ * This also finds the ends of maps and arrays when they are exited.
+ */
+QCBORError
+QCBORDecode_Private_MapSearch(QCBORDecodeContext *pMe,
+                              QCBORItem          *pItemArray,
+                              MapSearchInfo      *pInfo,
+                              MapSearchCallBack  *pCallBack)
+{
+   QCBORError uReturn;
+   uint64_t   uFoundItemBitMap = 0;
+
+   if(pMe->uLastError != QCBOR_SUCCESS) {
+      uReturn = pMe->uLastError;
+      goto Done2;
+   }
+
+   if(!DecodeNesting_IsBoundedType(&(pMe->nesting), QCBOR_TYPE_MAP) &&
+      pItemArray->uLabelType != QCBOR_TYPE_NONE) {
+      /* QCBOR_TYPE_NONE as first item indicates just looking
+         for the end of an array, so don't give error. */
+      uReturn = QCBOR_ERR_MAP_NOT_ENTERED;
+      goto Done2;
+   }
+
+   if(DecodeNesting_IsBoundedEmpty(&(pMe->nesting))) {
+      // It is an empty bounded array or map
+      if(pItemArray->uLabelType == QCBOR_TYPE_NONE) {
+         // Just trying to find the end of the map or array
+         pMe->uMapEndOffsetCache = DecodeNesting_GetMapOrArrayStart(&(pMe->nesting));
+         uReturn = QCBOR_SUCCESS;
+      } else {
+         // Nothing is ever found in an empty array or map. All items
+         // are marked as not found below.
+         uReturn = QCBOR_SUCCESS;
+      }
+      goto Done2;
+   }
+
+   QCBORDecodeNesting SaveNesting;
+   size_t uSavePos = UsefulInputBuf_Tell(&(pMe->InBuf));
+   DecodeNesting_PrepareForMapSearch(&(pMe->nesting), &SaveNesting);
+
+   /* Reposition to search from the start of the map / array */
+   QCBORDecode_Private_RewindMapOrArray(pMe);
+
+   /*
+    Loop over all the items in the map or array. Each item
+    could be a map or array, but label matching is only at
+    the main level. This handles definite- and indefinite-
+    length maps and arrays. The only reason this is ever
+    called on arrays is to find their end position.
+
+    This will always run over all items in order to do
+    duplicate detection.
+
+    This will exit with failure if it encounters an
+    unrecoverable error, but continue on for recoverable
+    errors.
+
+    If a recoverable error occurs on a matched item, then
+    that error code is returned.
+    */
+   const uint8_t uMapNestLevel = DecodeNesting_GetBoundedModeLevel(&(pMe->nesting));
+   if(pInfo) {
+      pInfo->uItemCount = 0;
+   }
+   uint8_t       uNextNestLevel;
+   do {
+      /* Remember offset of the item because sometimes it has to be returned */
+      const size_t uOffset = UsefulInputBuf_Tell(&(pMe->InBuf));
+
+      /* Get the item */
+      QCBORItem Item;
+      /* QCBORDecode_Private_GetNextTagContent() rather than GetNext()
+       * because a label match is performed on recoverable errors to
+       * be able to return the the error code for the found item. */
+      QCBORError uResult = QCBORDecode_Private_GetNextTagContent(pMe, &Item);
+      if(QCBORDecode_IsUnrecoverableError(uResult)) {
+         /* The map/array can't be decoded when unrecoverable errors occur */
+         uReturn = uResult;
+         goto Done;
+      }
+      if(uResult == QCBOR_ERR_NO_MORE_ITEMS) {
+         /* Unexpected end of map or array. */
+         uReturn = uResult;
+         goto Done;
+      }
+
+      /* See if item has one of the labels that are of interest */
+      bool bMatched = false;
+      for(int nIndex = 0; pItemArray[nIndex].uLabelType != QCBOR_TYPE_NONE; nIndex++) {
+         if(QCBORItem_MatchLabel(Item, pItemArray[nIndex])) {
+            /* A label match has been found */
+            if(uFoundItemBitMap & (0x01ULL << nIndex)) {
+               uReturn = QCBOR_ERR_DUPLICATE_LABEL;
+               goto Done;
+            }
+            if(uResult != QCBOR_SUCCESS) {
+               /* The label matches, but the data item is in error.
+                * It is OK to have recoverable errors on items that
+                * are not matched. */
+               uReturn = uResult;
+               goto Done;
+            }
+            if(!QCBORItem_MatchType(Item, pItemArray[nIndex])) {
+               /* The data item is not of the type(s) requested */
+               uReturn = QCBOR_ERR_UNEXPECTED_TYPE;
+               goto Done;
+            }
+
+            /* Successful match. Return the item. */
+            pItemArray[nIndex] = Item;
+            uFoundItemBitMap |= 0x01ULL << nIndex;
+            if(pInfo) {
+               pInfo->uStartOffset = uOffset;
+            }
+            bMatched = true;
+         }
+      }
+
+
+      if(!bMatched && pCallBack != NULL) {
+         /*
+          Call the callback on unmatched labels.
+          (It is tempting to do duplicate detection here, but that would
+          require dynamic memory allocation because the number of labels
+          that might be encountered is unbounded.)
+         */
+         uReturn = (*(pCallBack->pfCallback))(pCallBack->pCBContext, &Item);
+         if(uReturn != QCBOR_SUCCESS) {
+            goto Done;
+         }
+      }
+
+      /*
+       Consume the item whether matched or not. This
+       does the work of traversing maps and array and
+       everything in them. In this loop only the
+       items at the current nesting level are examined
+       to match the labels.
+       */
+      uReturn = QCBORDecode_Private_ConsumeItem(pMe, &Item, NULL, &uNextNestLevel);
+      if(uReturn != QCBOR_SUCCESS) {
+         goto Done;
+      }
+
+      if(pInfo) {
+         pInfo->uItemCount++;
+      }
+
+   } while (uNextNestLevel >= uMapNestLevel);
+
+   uReturn = QCBOR_SUCCESS;
+
+   const size_t uEndOffset = UsefulInputBuf_Tell(&(pMe->InBuf));
+
+   // Check here makes sure that this won't accidentally be
+   // QCBOR_MAP_OFFSET_CACHE_INVALID which is larger than
+   // QCBOR_MAX_DECODE_INPUT_SIZE.
+   // Cast to uint32_t to possibly address cases where SIZE_MAX < UINT32_MAX
+   if((uint32_t)uEndOffset >= QCBOR_MAX_DECODE_INPUT_SIZE) {
+      uReturn = QCBOR_ERR_INPUT_TOO_LARGE;
+      goto Done;
+   }
+   /* Cast OK because encoded CBOR is limited to UINT32_MAX */
+   pMe->uMapEndOffsetCache = (uint32_t)uEndOffset;
+
+ Done:
+   DecodeNesting_RestoreFromMapSearch(&(pMe->nesting), &SaveNesting);
+   UsefulInputBuf_Seek(&(pMe->InBuf), uSavePos);
+
+ Done2:
+   /* For all items not found, set the data and label type to QCBOR_TYPE_NONE */
+   for(int i = 0; pItemArray[i].uLabelType != 0; i++) {
+      if(!(uFoundItemBitMap & (0x01ULL << i))) {
+         pItemArray[i].uDataType  = QCBOR_TYPE_NONE;
+         pItemArray[i].uLabelType = QCBOR_TYPE_NONE;
+      }
+   }
+
+   return uReturn;
+}
+
+
+/*
+ * Public function, see header qcbor/qcbor_decode.h file
+ */
+void
+QCBORDecode_SeekToLabelN(QCBORDecodeContext *pMe, int64_t nLabel)
+{
+   MapSearchInfo Info;
+   QCBORItem     OneItemSeach[2];
+
+   if(pMe->uLastError != QCBOR_SUCCESS) {
+      return;
+   }
+
+   OneItemSeach[0].uLabelType  = QCBOR_TYPE_INT64;
+   OneItemSeach[0].label.int64 = nLabel;
+   OneItemSeach[0].uDataType   = QCBOR_TYPE_ANY;
+   OneItemSeach[1].uLabelType  = QCBOR_TYPE_NONE; // Indicates end of array
+
+   pMe->uLastError = (uint8_t)QCBORDecode_Private_MapSearch(pMe, OneItemSeach, &Info, NULL);
+   if(pMe->uLastError == QCBOR_SUCCESS) {
+      UsefulInputBuf_Seek(&(pMe->InBuf), Info.uStartOffset);
+   }
+}
+
+
+void
+QCBORDecode_SeekToLabelSZ(QCBORDecodeContext *pMe, const char *szLabel)
+{
+#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
+   MapSearchInfo  Info;
+   QCBORItem      OneItemSeach[2];
+
+   if(pMe->uLastError != QCBOR_SUCCESS) {
+      return;
+   }
+
+   OneItemSeach[0].uLabelType   = QCBOR_TYPE_TEXT_STRING;
+   OneItemSeach[0].label.string = UsefulBuf_FromSZ(szLabel);
+   OneItemSeach[0].uDataType    = QCBOR_TYPE_ANY;
+   OneItemSeach[1].uLabelType   = QCBOR_TYPE_NONE; // Indicates end of array
+
+   pMe->uLastError = (uint8_t)QCBORDecode_Private_MapSearch(pMe, OneItemSeach, &Info, NULL);
+   if(pMe->uLastError == QCBOR_SUCCESS) {
+      UsefulInputBuf_Seek(&(pMe->InBuf), Info.uStartOffset);
+   }
+#else
+   (void)pMe;
+   (void)szLabel;
+   pMe->uLastError = QCBOR_ERR_LABEL_NOT_FOUND;
+#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
+}
+
+
+void
+QCBORDecode_Private_GetItemInMapNoCheck(QCBORDecodeContext *pMe,
+                                        QCBORItem          *OneItemSeach,
+                                        QCBORItem          *pItem,
+                                        size_t             *puOffset)
+{
+   QCBORError    uErr;
+   MapSearchInfo SearchInfo;
+
+   if(pMe->uLastError != QCBOR_SUCCESS) {
+      return;
+   }
+
+   uErr = QCBORDecode_Private_MapSearch(pMe, OneItemSeach, &SearchInfo, NULL);
+
+   if(uErr == QCBOR_SUCCESS && OneItemSeach[0].uDataType == QCBOR_TYPE_NONE) {
+      uErr = QCBOR_ERR_LABEL_NOT_FOUND;
+   }
+   *pItem = OneItemSeach[0];
+   *puOffset = SearchInfo.uStartOffset;
+
+   if(uErr == QCBOR_SUCCESS) {
+      QCBORDecode_Private_SaveTagNumbers(pMe, pItem);
+   }
+
+   pMe->uLastError = (uint8_t)uErr;
+}
+
+
+static void
+QCBORDecode_Private_GetItemInMap(QCBORDecodeContext *pMe, QCBORItem *OneItemSeach, QCBORItem *pItem)
+{
+   QCBORError  uErr;
+   size_t      uOffset;
+
+   QCBORDecode_Private_GetItemInMapNoCheck(pMe, OneItemSeach, pItem, &uOffset);
+
+   uErr = QCBORDecode_Private_GetItemChecks(pMe, pMe->uLastError, uOffset, pItem);
+   if(uErr != QCBOR_SUCCESS) {
+      goto Done;
+   }
+
+   QCBORDecode_Private_SaveTagNumbers(pMe, pItem);
+
+Done:
+   pMe->uLastError = (uint8_t)uErr;
+}
+
+
+/*
+ * Public function, see header qcbor/qcbor_decode.h file
+ */
+void
+QCBORDecode_GetItemInMapN(QCBORDecodeContext *pMe,
+                          const int64_t       nLabel,
+                          const uint8_t       uQcborType,
+                          QCBORItem          *pItem)
+{
+   QCBORItem OneItemSeach[2];
+
+   OneItemSeach[0].uLabelType  = QCBOR_TYPE_INT64;
+   OneItemSeach[0].label.int64 = nLabel;
+   OneItemSeach[0].uDataType   = uQcborType;
+   OneItemSeach[1].uLabelType  = QCBOR_TYPE_NONE; // Indicates end of array
+
+   QCBORDecode_Private_GetItemInMap(pMe, OneItemSeach, pItem);
+}
+
+
+/**
+ * @brief Get an item by label by type.
+ *
+ * @param[in] pMe         The decode context.
+ * @param[in] nLabel      The label to search map for.
+ * @param[in] uQcborType  The QCBOR type to look for.
+ * @param[out] pItem      The item found.
+ * @param[out] puOffset   The offset of item for tag consumption check.
+ *
+ * This finds the item with the given label in currently open
+ * map. This does not call QCBORDecode_Private_GetItemChecks()
+ * to check tag number consumption or decode conformance.
+ */
+void
+QCBORDecode_Private_GetItemInMapNoCheckN(QCBORDecodeContext *pMe,
+                                 const int64_t       nLabel,
+                                 const uint8_t       uQcborType,
+                                 QCBORItem          *pItem,
+                                 size_t             *puOffset)
+{
+   QCBORItem OneItemSeach[2];
+
+   OneItemSeach[0].uLabelType  = QCBOR_TYPE_INT64;
+   OneItemSeach[0].label.int64 = nLabel;
+   OneItemSeach[0].uDataType   = uQcborType;
+   OneItemSeach[1].uLabelType  = QCBOR_TYPE_NONE; // Indicates end of array
+
+   QCBORDecode_Private_GetItemInMapNoCheck(pMe, OneItemSeach,  pItem, puOffset);
+}
+
+
+/*
+ * Public function, see header qcbor/qcbor_decode.h file
+ */
+void
+QCBORDecode_GetItemInMapSZ(QCBORDecodeContext *pMe,
+                           const char         *szLabel,
+                           const uint8_t       uQcborType,
+                           QCBORItem          *pItem)
+{
+#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
+   QCBORItem OneItemSeach[2];
+
+   OneItemSeach[0].uLabelType   = QCBOR_TYPE_TEXT_STRING;
+   OneItemSeach[0].label.string = UsefulBuf_FromSZ(szLabel);
+   OneItemSeach[0].uDataType    = uQcborType;
+   OneItemSeach[1].uLabelType   = QCBOR_TYPE_NONE; // Indicates end of array
+
+   QCBORDecode_Private_GetItemInMap(pMe, OneItemSeach, pItem);
+
+#else
+   (void)pMe;
+   (void)szLabel;
+   (void)uQcborType;
+   (void)pItem;
+   pMe->uLastError = QCBOR_ERR_LABEL_NOT_FOUND;
+#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
+}
+
+/**
+ * @brief Get an item by string label of a particular type
+ *
+ * @param[in] pMe         The decode context.
+ * @param[in] szLabel     The label to search map for.
+ * @param[in] uQcborType  The QCBOR type to look for.
+ * @param[out] pItem      The item found.
+ * @param[out] puOffset   The offset of item for tag consumption check.
+ *
+ * This finds the item with the given label in currently open
+ * map. This does not call QCBORDecode_Private_GetItemChecks()
+ * to check tag number consumption or decode conformance.
+ */
+void
+QCBORDecode_Private_GetItemInMapNoCheckSZ(QCBORDecodeContext *pMe,
+                                  const char         *szLabel,
+                                  const uint8_t       uQcborType,
+                                  QCBORItem          *pItem,
+                                  size_t             *puOffset)
+{
+#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
+   QCBORItem OneItemSeach[2];
+
+   OneItemSeach[0].uLabelType   = QCBOR_TYPE_TEXT_STRING;
+   OneItemSeach[0].label.string = UsefulBuf_FromSZ(szLabel);
+   OneItemSeach[0].uDataType    = uQcborType;
+   OneItemSeach[1].uLabelType   = QCBOR_TYPE_NONE; // Indicates end of array
+
+   QCBORDecode_Private_GetItemInMapNoCheck(pMe, OneItemSeach, pItem, puOffset);
+
+#else
+   (void)pMe;
+   (void)szLabel;
+   (void)uQcborType;
+   (void)pItem;
+   (void)puOffset;
+   pMe->uLastError = QCBOR_ERR_LABEL_NOT_FOUND;
+#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
+}
+
+
+
+
+
+
+/**
+ * @brief Semi-private. Get pointer, length and item count of an array or map.
+ *
+ * @param[in] pMe            The decode context.
+ * @param[in] pTarget        The label and type of the array or map to retrieve.
+ * @param[out] pItem         The item for the array/map.
+ * @param[out] pEncodedCBOR  Pointer and length of the encoded map or array.
+ *
+ * The next item to be decoded must be a map or array as specified by @c uType.
+ *
+ * When this is complete, the traversal cursor is unchanged.
+ */void
+QCBORDecode_Private_SearchAndGetArrayOrMap(QCBORDecodeContext *pMe,
+                                           QCBORItem          *pTarget,
+                                           QCBORItem          *pItem,
+                                           UsefulBufC         *pEncodedCBOR)
+{
+   MapSearchInfo      Info;
+   QCBORDecodeNesting SaveNesting;
+   size_t             uSaveCursor;
+
+   pMe->uLastError = (uint8_t)QCBORDecode_Private_MapSearch(pMe, pTarget, &Info, NULL);
+   if(pMe->uLastError != QCBOR_SUCCESS) {
+      return;
+   }
+   pMe->uLastError = (uint8_t)QCBORDecode_Private_GetItemChecks(pMe, pMe->uLastError, Info.uStartOffset, pItem);
+   if(pMe->uLastError != QCBOR_SUCCESS) {
+      return;
+   }
+
+   /* Save the whole position of things so they can be restored.
+    * so the cursor position is unchanged by this operation, like
+    * all the other GetXxxxInMap() operations. */
+   DecodeNesting_PrepareForMapSearch(&(pMe->nesting), &SaveNesting);
+   uSaveCursor = UsefulInputBuf_Tell(&(pMe->InBuf));
+
+   DecodeNesting_ResetMapOrArrayCount(&(pMe->nesting));
+   UsefulInputBuf_Seek(&(pMe->InBuf), Info.uStartOffset);
+   QCBORDecode_Private_GetArrayOrMap(pMe, pTarget[0].uDataType, pItem, pEncodedCBOR);
+
+   UsefulInputBuf_Seek(&(pMe->InBuf), uSaveCursor);
+   DecodeNesting_RestoreFromMapSearch(&(pMe->nesting), &SaveNesting);
+}
+
+
+
+/*
+ * Public function, see header qcbor/qcbor_decode.h file
+ */
+void
+QCBORDecode_GetItemsInMap(QCBORDecodeContext *pMe, QCBORItem *pItemList)
+{
+   pMe->uLastError = (uint8_t)QCBORDecode_Private_MapSearch(pMe, pItemList, NULL, NULL);
+}
+
+/*
+ * Public function, see header qcbor/qcbor_decode.h file
+ */
+void
+QCBORDecode_GetItemsInMapWithCallback(QCBORDecodeContext *pMe,
+                                      QCBORItem          *pItemList,
+                                      void               *pCallbackCtx,
+                                      QCBORItemCallback   pfCB)
+{
+   MapSearchCallBack CallBack;
+
+   CallBack.pCBContext = pCallbackCtx;
+   CallBack.pfCallback = pfCB;
+
+   pMe->uLastError = (uint8_t)QCBORDecode_Private_MapSearch(pMe, pItemList, NULL, &CallBack);
+}
+
+
+
+
+/**
+ * @brief Search for a map/array by label and enter it
+ *
+ * @param[in] pMe  The decode context.
+ * @param[in] pSearch The map/array to search for.
+ *
+ * @c pSearch is expected to contain one item of type map or array
+ * with the label specified. The current bounded map will be searched for
+ * this and if found  will be entered.
+ *
+ * If the label is not found, or the item found is not a map or array,
+ * the error state is set.
+ */
+static void
+QCBORDecode_Private_SearchAndEnter(QCBORDecodeContext *pMe, QCBORItem pSearch[])
+{
+   QCBORError     uErr;
+   MapSearchInfo  SearchInfo;
+
+   // The first item in pSearch is the one that is to be
+   // entered. It should be the only one filled in. Any other
+   // will be ignored unless it causes an error.
+   if(pMe->uLastError != QCBOR_SUCCESS) {
+      return;
+   }
+
+   uErr = QCBORDecode_Private_MapSearch(pMe, pSearch, &SearchInfo, NULL);
+
+   pMe->uLastError = (uint8_t)QCBORDecode_Private_GetItemChecks(pMe, uErr, SearchInfo.uStartOffset, pSearch);
+
+   if(pMe->uLastError != QCBOR_SUCCESS) {
+      return;
+   }
+
+   if(pSearch->uDataType == QCBOR_TYPE_NONE) {
+      pMe->uLastError = QCBOR_ERR_LABEL_NOT_FOUND;
+      return;
+   }
+
+
+   /* The map or array was found. Now enter it.
+    *
+    * QCBORDecode_EnterBoundedMapOrArray() used here, requires the
+    * next item for the pre-order traversal cursor to be the map/array
+    * found by MapSearch(). The next few lines of code force the
+    * cursor to that.
+    *
+    * There is no need to retain the old cursor because
+    * QCBORDecode_EnterBoundedMapOrArray() will set it to the
+    * beginning of the map/array being entered.
+    *
+    * The cursor is forced by: 1) setting the input buffer position to
+    * the item offset found by MapSearch(), 2) setting the map/array
+    * counter to the total in the map/array, 3) setting the nesting
+    * level. Setting the map/array counter to the total is not
+    * strictly correct, but this is OK because this cursor only needs
+    * to be used to get one item and MapSearch() has already found it
+    * confirming it exists.
+    */
+   UsefulInputBuf_Seek(&(pMe->InBuf), SearchInfo.uStartOffset);
+
+   DecodeNesting_ResetMapOrArrayCount(&(pMe->nesting));
+
+   DecodeNesting_SetCurrentToBoundedLevel(&(pMe->nesting));
+
+   QCBORDecode_Private_EnterBoundedMapOrArray(pMe, pSearch->uDataType, NULL);
+}
+
+
+/*
+ * Public function, see header qcbor/qcbor_decode.h file
+ */
+void
+QCBORDecode_EnterMapFromMapN(QCBORDecodeContext *pMe, int64_t nLabel)
+{
+   QCBORItem OneItemSeach[2];
+   OneItemSeach[0].uLabelType  = QCBOR_TYPE_INT64;
+   OneItemSeach[0].label.int64 = nLabel;
+   OneItemSeach[0].uDataType   = QCBOR_TYPE_MAP;
+   OneItemSeach[1].uLabelType  = QCBOR_TYPE_NONE;
+
+   /* The map to enter was found, now finish off entering it. */
+   QCBORDecode_Private_SearchAndEnter(pMe, OneItemSeach);
+}
+
+
+/*
+ * Public function, see header qcbor/qcbor_decode.h file
+ */
+void
+QCBORDecode_EnterMapFromMapSZ(QCBORDecodeContext *pMe, const char  *szLabel)
+{
+#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
+   QCBORItem OneItemSeach[2];
+   OneItemSeach[0].uLabelType   = QCBOR_TYPE_TEXT_STRING;
+   OneItemSeach[0].label.string = UsefulBuf_FromSZ(szLabel);
+   OneItemSeach[0].uDataType    = QCBOR_TYPE_MAP;
+   OneItemSeach[1].uLabelType   = QCBOR_TYPE_NONE;
+
+   QCBORDecode_Private_SearchAndEnter(pMe, OneItemSeach);
+#else
+   (void)szLabel;
+   pMe->uLastError = QCBOR_ERR_LABEL_NOT_FOUND;
+#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
+}
+
+/*
+ * Public function, see header qcbor/qcbor_decode.h file
+ */
+void
+QCBORDecode_EnterArrayFromMapN(QCBORDecodeContext *pMe, int64_t nLabel)
+{
+   QCBORItem OneItemSeach[2];
+   OneItemSeach[0].uLabelType  = QCBOR_TYPE_INT64;
+   OneItemSeach[0].label.int64 = nLabel;
+   OneItemSeach[0].uDataType   = QCBOR_TYPE_ARRAY;
+   OneItemSeach[1].uLabelType  = QCBOR_TYPE_NONE;
+
+   QCBORDecode_Private_SearchAndEnter(pMe, OneItemSeach);
+}
+
+/*
+ * Public function, see header qcbor/qcbor_decode.h file
+ */
+void
+QCBORDecode_EnterArrayFromMapSZ(QCBORDecodeContext *pMe, const char  *szLabel)
+{
+#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
+   QCBORItem OneItemSeach[2];
+   OneItemSeach[0].uLabelType   = QCBOR_TYPE_TEXT_STRING;
+   OneItemSeach[0].label.string = UsefulBuf_FromSZ(szLabel);
+   OneItemSeach[0].uDataType    = QCBOR_TYPE_ARRAY;
+   OneItemSeach[1].uLabelType   = QCBOR_TYPE_NONE;
+
+   QCBORDecode_Private_SearchAndEnter(pMe, OneItemSeach);
+#else
+   (void)szLabel;
+   pMe->uLastError = QCBOR_ERR_LABEL_NOT_FOUND;
+#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
+}
+
+
+/**
+ * @brief Semi-private to do the the work for EnterMap() and EnterArray().
+ *
+ * @param[in] pMe     The decode context
+ * @param[in] uType   QCBOR_TYPE_MAP or QCBOR_TYPE_ARRAY.
+ * @param[out] pItem  The data item for the map or array entered.
+ *
+ * The next item in the traversal must be a map or array.  This
+ * consumes that item and does the book keeping to enter the map or
+ * array.
+ */
+void
+QCBORDecode_Private_EnterBoundedMapOrArray(QCBORDecodeContext *pMe,
+                                           const uint8_t       uType,
+                                           QCBORItem          *pItem)
+{
+    QCBORError uErr;
+
+   /* Must only be called on maps and arrays. */
+   if(pMe->uLastError != QCBOR_SUCCESS) {
+      // Already in error state; do nothing.
+      return;
+   }
+
+   /* Get the data item that is the map or array being entered. */
+   QCBORItem Item;
+   uErr = QCBORDecode_GetNext(pMe, &Item);
+   if(uErr != QCBOR_SUCCESS) {
+      goto Done;
+   }
+
+   uint8_t uItemDataType = Item.uDataType;
+
+#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
+   if(uItemDataType == QCBOR_TYPE_MAP_AS_ARRAY ) {
+      uItemDataType = QCBOR_TYPE_ARRAY;
+   }
+#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
+
+   if(uItemDataType != uType) {
+      uErr = QCBOR_ERR_UNEXPECTED_TYPE;
+      goto Done;
+   }
+
+   QCBORDecode_Private_SaveTagNumbers(pMe, &Item);
+
+
+   const bool bIsEmpty = (Item.uNextNestLevel <= Item.uNestingLevel);
+   if(bIsEmpty) {
+      if(DecodeNesting_IsCurrentDefiniteLength(&(pMe->nesting))) {
+         // Undo decrement done by QCBORDecode_GetNext() so the the
+         // the decrement when exiting the map/array works correctly
+         pMe->nesting.pCurrent->u.ma.uCountCursor++;
+      }
+      // Special case to increment nesting level for zero-length maps
+      // and arrays entered in bounded mode.
+      DecodeNesting_Descend(&(pMe->nesting), uType);
+   }
+
+   pMe->uMapEndOffsetCache = QCBOR_MAP_OFFSET_CACHE_INVALID;
+
+   uErr = DecodeNesting_EnterBoundedMapOrArray(&(pMe->nesting), bIsEmpty,
+                                               UsefulInputBuf_Tell(&(pMe->InBuf)));
+
+   if(pItem != NULL) {
+      *pItem = Item;
+   }
+
+Done:
+   pMe->uLastError = (uint8_t)uErr;
+}
+
+
+/**
+ * @brief Exit a bounded map, array or bstr (semi-private).
+ *
+ * @param[in] pMe         Decode context.
+ * @param[in] uEndOffset  The input buffer offset of the end of item exited.
+ *
+ * @returns  QCBOR_SUCCESS or an error code.
+ *
+ * This is the common work for exiting a level that is a bounded map,
+ * array or bstr wrapped CBOR.
+ *
+ * One chunk of work is to set up the pre-order traversal so it is at
+ * the item just after the bounded map, array or bstr that is being
+ * exited. This is somewhat complex.
+ *
+ * The other work is to level-up the bounded mode to next higest
+ * bounded mode or the top level if there isn't one.
+ */
+QCBORError
+QCBORDecode_Private_ExitBoundedLevel(QCBORDecodeContext *pMe,
+                                     const uint32_t      uEndOffset)
+{
+   QCBORError uErr;
+
+   /*
+    * First the pre-order-traversal byte offset is positioned to the
+    * item just after the bounded mode item that was just consumed.
+    */
+   UsefulInputBuf_Seek(&(pMe->InBuf), uEndOffset);
+
+   /*
+    * Next, set the current nesting level to one above the bounded
+    * level that was just exited.
+    *
+    * DecodeNesting_CheckBoundedType() is always called before this
+    * and makes sure pCurrentBounded is valid.
+    */
+   DecodeNesting_LevelUpCurrent(&(pMe->nesting));
+
+   /*
+    * This does the complex work of leveling up the pre-order
+    * traversal when the end of a map or array or another bounded
+    * level is reached.  It may do nothing, or ascend all the way to
+    * the top level.
+    */
+   uErr = QCBORDecode_Private_NestLevelAscender(pMe, NULL, false);
+   if(uErr != QCBOR_SUCCESS) {
+      goto Done;
+   }
+
+   /*
+    * This makes the next highest bounded level the current bounded
+    * level. If there is no next highest level, then no bounded mode
+    * is in effect.
+    */
+   DecodeNesting_LevelUpBounded(&(pMe->nesting));
+
+   pMe->uMapEndOffsetCache = QCBOR_MAP_OFFSET_CACHE_INVALID;
+
+Done:
+   return uErr;
+}
+
+
+/**
+ * @brief Get started exiting a map or array (semi-private)
+ *
+ * @param[in] pMe  The decode context
+ * @param[in] uType  QCBOR_TYPE_ARRAY or QCBOR_TYPE_MAP
+ *
+ * This does some work for map and array exiting (but not
+ * bstr exiting). Then QCBORDecode_Private_ExitBoundedLevel()
+ * is called to do the rest.
+ */
+void
+QCBORDecode_Private_ExitBoundedMapOrArray(QCBORDecodeContext *pMe,
+                                          const uint8_t       uType)
+{
+   if(pMe->uLastError != QCBOR_SUCCESS) {
+      /* Already in error state; do nothing. */
+      return;
+   }
+
+   QCBORError uErr;
+
+   if(!DecodeNesting_IsBoundedType(&(pMe->nesting), uType)) {
+      uErr = QCBOR_ERR_EXIT_MISMATCH;
+      goto Done;
+   }
+
+   /*
+    Have to set the offset to the end of the map/array
+    that is being exited. If there is no cached value,
+    from previous map search, then do a dummy search.
+    */
+   if(pMe->uMapEndOffsetCache == QCBOR_MAP_OFFSET_CACHE_INVALID) {
+      QCBORItem Dummy;
+      Dummy.uLabelType = QCBOR_TYPE_NONE;
+      uErr = QCBORDecode_Private_MapSearch(pMe, &Dummy, NULL, NULL);
+      if(uErr != QCBOR_SUCCESS) {
+         goto Done;
+      }
+   }
+
+   uErr = QCBORDecode_Private_ExitBoundedLevel(pMe, pMe->uMapEndOffsetCache);
+
+Done:
+   pMe->uLastError = (uint8_t)uErr;
+}
+
+
+
+
+
+/**
+ * @brief Process simple type true and false, a boolean
+ *
+ * @param[in] pMe     The decode context.
+ * @param[in] pItem   The item with either true or false.
+ * @param[out] pBool  The boolean value output.
+ *
+ * Sets the internal error if the item isn't a true or a false. Also
+ * records any tag numbers as the tag numbers of the last item.
+ */
+static void
+QCBORDecode_Private_ProcessBool(QCBORDecodeContext *pMe,
+                                const QCBORItem    *pItem,
+                                bool               *pBool)
+{
+   if(pMe->uLastError != QCBOR_SUCCESS) {
+      /* Already in error state, do nothing */
+      return;
+   }
+
+   switch(pItem->uDataType) {
+      case QCBOR_TYPE_TRUE:
+         *pBool = true;
+         break;
+
+      case QCBOR_TYPE_FALSE:
+         *pBool = false;
+         break;
+
+      default:
+         pMe->uLastError = QCBOR_ERR_UNEXPECTED_TYPE;
+         break;
+   }
+}
+
+
+/*
+ * Public function, see header qcbor/qcbor_decode.h file
+ */
+void
+QCBORDecode_GetBool(QCBORDecodeContext *pMe, bool *pValue)
+{
+   QCBORItem  Item;
+   QCBORDecode_VGetNext(pMe, &Item);
+   QCBORDecode_Private_ProcessBool(pMe, &Item, pValue);
+}
+
+
+/*
+ * Public function, see header qcbor/qcbor_decode.h file
+ */
+void
+QCBORDecode_GetBoolInMapN(QCBORDecodeContext *pMe,
+                          const int64_t       nLabel,
+                          bool               *pValue)
+{
+   QCBORItem Item;
+   QCBORDecode_GetItemInMapN(pMe, nLabel, QCBOR_TYPE_ANY, &Item);
+   QCBORDecode_Private_ProcessBool(pMe, &Item, pValue);
+}
+
+
+/*
+ * Public function, see header qcbor/qcbor_decode.h file
+ */
+void
+QCBORDecode_GetBoolInMapSZ(QCBORDecodeContext *pMe,
+                           const char         *szLabel,
+                           bool               *pValue)
+{
+   QCBORItem Item;
+   QCBORDecode_GetItemInMapSZ(pMe, szLabel, QCBOR_TYPE_ANY, &Item);
+   QCBORDecode_Private_ProcessBool(pMe, &Item, pValue);
+}
+
+
+/**
+ * @brief Process simple values.
+ *
+ * @param[in] pMe     The decode context.
+ * @param[in] pItem   The item with the simple value.
+ * @param[out] puSimple  The simple value output.
+ *
+ * Sets the internal error if the item isn't a true or a false. Also
+ * records any tag numbers as the tag numbers of the last item.
+ */
+static void
+QCBORDecode_Private_ProcessSimple(QCBORDecodeContext *pMe,
+                                  const QCBORItem    *pItem,
+                                  uint8_t            *puSimple)
+{
+   if(pMe->uLastError != QCBOR_SUCCESS) {
+      return;
+   }
+
+   /* It's kind of lame to remap true...undef back to simple values, but
+    * this function isn't used much and to not do it would require
+    * changing GetNext() behavior in an incompatible way.
+    */
+   switch(pItem->uDataType) {
+      case QCBOR_TYPE_UKNOWN_SIMPLE:
+         *puSimple = pItem->val.uSimple;
+         break;
+
+      case QCBOR_TYPE_TRUE:
+         *puSimple = CBOR_SIMPLEV_TRUE;
+         break;
+
+      case QCBOR_TYPE_FALSE:
+         *puSimple = CBOR_SIMPLEV_FALSE;
+         break;
+
+      case QCBOR_TYPE_NULL:
+         *puSimple = CBOR_SIMPLEV_NULL;
+         break;
+
+      case QCBOR_TYPE_UNDEF:
+         *puSimple = CBOR_SIMPLEV_UNDEF;
+         break;
+
+      default:
+         pMe->uLastError = QCBOR_ERR_UNEXPECTED_TYPE;
+         return;
+   }
+}
+
+/*
+ * Public function, see header qcbor/qcbor_decode.h file
+ */
+void
+QCBORDecode_GetSimple(QCBORDecodeContext *pMe, uint8_t *puSimple)
+{
+   QCBORItem Item;
+   QCBORDecode_VGetNext(pMe, &Item);
+   QCBORDecode_Private_ProcessSimple(pMe, &Item, puSimple);
+}
+
+/*
+ * Public function, see header qcbor/qcbor_decode.h file
+ */
+void
+QCBORDecode_GetSimpleInMapN(QCBORDecodeContext *pMe,
+                            int64_t             nLabel,
+                            uint8_t            *puSimpleValue)
+{
+   QCBORItem Item;
+   QCBORDecode_GetItemInMapN(pMe, nLabel, QCBOR_TYPE_ANY, &Item);
+   QCBORDecode_Private_ProcessSimple(pMe, &Item, puSimpleValue);
+}
+
+/*
+ * Public function, see header qcbor/qcbor_decode.h file
+ */
+void
+QCBORDecode_GetSimpleInMapSZ(QCBORDecodeContext *pMe,
+                             const char         *szLabel,
+                             uint8_t            *puSimpleValue)
+{
+   QCBORItem Item;
+   QCBORDecode_GetItemInMapSZ(pMe, szLabel, QCBOR_TYPE_ANY, &Item);
+   QCBORDecode_Private_ProcessSimple(pMe, &Item, puSimpleValue);
+}
+
+
+
+
+
+
+// Improvement: add methods for wrapped CBOR, a simple alternate
+// to EnterBstrWrapped
+
diff --git a/src/qcbor_tag_decode.c b/src/qcbor_tag_decode.c
index 31f9c03..2627962 100644
--- a/src/qcbor_tag_decode.c
+++ b/src/qcbor_tag_decode.c
@@ -10,13 +10,1029 @@
  * Created on 9/5/24 from qcbode_decode.c
  * ========================================================================== */
 
-// TODO: qcbor_tag_decode.c or tag_decode.c
-
 #include "qcbor/qcbor_tag_decode.h"
+#include "decode_private.h"
+#include "decode_nesting.h"
 
 #include <math.h> /* For isnan() */
 
 
+
+#ifndef QCBOR_DISABLE_TAGS
+
+/* Public function; see qcbor_tag_decode.h */
+QCBORError
+QCBORDecode_GetNextTagNumber(QCBORDecodeContext *pMe, uint64_t *puTagNumber)
+{
+   QCBORItem   Item;
+   size_t      uOffset;
+   QCBORError  uErr;
+
+   const QCBORDecodeNesting SaveNesting = pMe->nesting;
+   const UsefulInputBuf Save = pMe->InBuf;
+
+   uOffset = UsefulInputBuf_Tell(&(pMe->InBuf));
+   if(uOffset == pMe->uTagNumberCheckOffset) {
+      pMe->uTagNumberIndex++;
+   } else {
+      pMe->uTagNumberIndex = 0;
+   }
+
+   *puTagNumber = CBOR_TAG_INVALID64;
+   uErr = QCBORDecode_Private_GetNextTagContent(pMe, &Item);
+   if(uErr) {
+      return uErr;
+   }
+
+   *puTagNumber = QCBORDecode_GetNthTagNumber(pMe, &Item, pMe->uTagNumberIndex);
+   if(*puTagNumber == CBOR_TAG_INVALID64 ||
+      QCBORDecode_GetNthTagNumber(pMe, &Item, pMe->uTagNumberIndex+1) == CBOR_TAG_INVALID64 ) {
+      pMe->uTagNumberIndex = QCBOR_ALL_TAGS_PROCESSED;
+   }
+   pMe->uTagNumberCheckOffset = uOffset;
+
+   pMe->nesting = SaveNesting;
+   pMe->InBuf = Save;
+
+   return QCBOR_SUCCESS;
+}
+
+
+/* Public function; see qcbor_tag_decode.h */
+void
+QCBORDecode_VGetNextTagNumber(QCBORDecodeContext *pMe, uint64_t *puTagNumber)
+{
+   pMe->uLastError = (uint8_t)QCBORDecode_GetNextTagNumber(pMe, puTagNumber);
+}
+
+/*
+ * Public function, see header qcbor/qcbor_tag_decode.h file
+ */
+QCBORError
+QCBORDecode_GetNextTagNumberInMapN(QCBORDecodeContext *pMe, const int64_t nLabel, uint64_t *puTagNumber)
+{
+   size_t         uOffset;
+   MapSearchInfo  Info;
+   QCBORItem      OneItemSeach[2];
+   QCBORError     uReturn;
+
+   if(pMe->uLastError != QCBOR_SUCCESS) {
+      return pMe->uLastError;
+   }
+
+   OneItemSeach[0].uLabelType  = QCBOR_TYPE_INT64;
+   OneItemSeach[0].label.int64 = nLabel;
+   OneItemSeach[0].uDataType   = QCBOR_TYPE_ANY;
+   OneItemSeach[1].uLabelType  = QCBOR_TYPE_NONE; // Indicates end of array
+
+   uReturn = QCBORDecode_Private_MapSearch(pMe, OneItemSeach, &Info, NULL);
+
+   uOffset = Info.uStartOffset;
+   if(uOffset == pMe->uTagNumberCheckOffset) {
+      pMe->uTagNumberIndex++;
+   } else {
+      pMe->uTagNumberIndex = 0;
+   }
+
+   *puTagNumber = CBOR_TAG_INVALID64;
+
+   *puTagNumber = QCBORDecode_GetNthTagNumber(pMe,
+                                              &OneItemSeach[0],
+                                              pMe->uTagNumberIndex);
+   if(*puTagNumber == CBOR_TAG_INVALID64 ||
+      QCBORDecode_GetNthTagNumber(pMe, &OneItemSeach[0], pMe->uTagNumberIndex+1) == CBOR_TAG_INVALID64 ) {
+      pMe->uTagNumberIndex = QCBOR_ALL_TAGS_PROCESSED;
+   }
+   pMe->uTagNumberCheckOffset = uOffset;
+
+   return uReturn;
+}
+
+
+/* Public function; see qcbor_tag_decode.h */
+QCBORError
+QCBORDecode_GetNextTagNumberInMapSZ(QCBORDecodeContext *pMe, const char *szLabel, uint64_t *puTagNumber)
+{
+#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
+   size_t         uOffset;
+   MapSearchInfo  Info;
+   QCBORItem      OneItemSeach[2];
+
+   if(pMe->uLastError != QCBOR_SUCCESS) {
+      return pMe->uLastError;
+   }
+
+   OneItemSeach[0].uLabelType   = QCBOR_TYPE_TEXT_STRING;
+   OneItemSeach[0].label.string = UsefulBuf_FromSZ(szLabel);
+   OneItemSeach[0].uDataType    = QCBOR_TYPE_ANY;
+   OneItemSeach[1].uLabelType   = QCBOR_TYPE_NONE; // Indicates end of array
+
+   QCBORError uReturn = QCBORDecode_Private_MapSearch(pMe, OneItemSeach, &Info, NULL);
+
+
+   uOffset = Info.uStartOffset;
+   if(uOffset == pMe->uTagNumberCheckOffset) {
+      pMe->uTagNumberIndex++;
+   } else {
+      pMe->uTagNumberIndex = 0;
+   }
+
+   *puTagNumber = CBOR_TAG_INVALID64;
+
+   *puTagNumber = QCBORDecode_GetNthTagNumber(pMe,
+                                              &OneItemSeach[0],
+                                              pMe->uTagNumberIndex);
+   if(*puTagNumber == CBOR_TAG_INVALID64 ||
+      QCBORDecode_GetNthTagNumber(pMe, &OneItemSeach[0], pMe->uTagNumberIndex+1) == CBOR_TAG_INVALID64 ) {
+      pMe->uTagNumberIndex = 255; /* All tags clear for this item */
+   }
+   pMe->uTagNumberCheckOffset = uOffset;
+
+   return uReturn;
+#else /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
+   (void)pMe;
+   (void)szLabel;
+   (void)puTagNumber;
+   return QCBOR_ERR_LABEL_NOT_FOUND;
+#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
+}
+
+
+/* Public function; see qcbor_tag_decode.h */
+uint64_t
+QCBORDecode_GetNthTagNumber(const QCBORDecodeContext *pMe,
+                            const QCBORItem          *pItem,
+                            uint8_t                   uIndex)
+{
+   if(pItem->uDataType == QCBOR_TYPE_NONE) {
+      return CBOR_TAG_INVALID64;
+   }
+   if(uIndex >= QCBOR_MAX_TAGS_PER_ITEM) {
+      return CBOR_TAG_INVALID64;
+   }
+
+   return QCBORDecode_Private_UnMapTagNumber(pMe, pItem->auTagNumbers[uIndex]);
+}
+
+
+/* Public function; see qcbor_tag_decode.h */
+uint64_t
+QCBORDecode_GetNthTagNumberOfLast(QCBORDecodeContext *pMe, uint8_t uIndex)
+{
+   if(pMe->uLastError != QCBOR_SUCCESS) {
+      return CBOR_TAG_INVALID64;
+   }
+   if(uIndex >= QCBOR_MAX_TAGS_PER_ITEM) {
+      return CBOR_TAG_INVALID64;
+   }
+
+   return QCBORDecode_Private_UnMapTagNumber(pMe, pMe->auLastTags[uIndex]);
+}
+
+
+static uint64_t
+QCBORDecode_Private_GetNthTagNumberReverse(const QCBORDecodeContext *pMe,
+                                           const uint16_t            puTagNumbers[],
+                                           const uint32_t            uIndex)
+{
+   uint32_t uArrayIndex;
+
+   /* Find number of tag numbers */
+   for(uArrayIndex = QCBOR_MAX_TAGS_PER_ITEM-1; uArrayIndex > 0; uArrayIndex--) {
+      if(puTagNumbers[uArrayIndex] != CBOR_TAG_INVALID16) {
+         break;
+      }
+   }
+   if(uIndex > uArrayIndex) {
+      return CBOR_TAG_INVALID64;
+   }
+
+   return QCBORDecode_Private_UnMapTagNumber(pMe, puTagNumbers[uArrayIndex - uIndex]);
+}
+
+
+/* Public function; see qcbor_tag_decode.h */
+uint64_t
+QCBORDecode_GetNthTag(QCBORDecodeContext *pMe,
+                      const QCBORItem    *pItem,
+                      const uint32_t      uIndex)
+{
+   if(pItem->uDataType == QCBOR_TYPE_NONE) {
+      return CBOR_TAG_INVALID64;
+   }
+
+   return QCBORDecode_Private_GetNthTagNumberReverse(pMe,
+                                                     pItem->auTagNumbers,
+                                                     uIndex);
+}
+
+
+/* Public function; see qcbor_tag_decode.h */
+uint64_t
+QCBORDecode_GetNthTagOfLast(const QCBORDecodeContext *pMe, uint32_t uIndex)
+{
+   if(pMe->uLastError != QCBOR_SUCCESS) {
+      return CBOR_TAG_INVALID64;
+   }
+   if(uIndex >= QCBOR_MAX_TAGS_PER_ITEM) {
+      return CBOR_TAG_INVALID64;
+   }
+
+   return QCBORDecode_Private_GetNthTagNumberReverse(pMe,
+                                                     pMe->auLastTags,
+                                                     uIndex);
+}
+
+
+
+// TODO:  uTagNumber might be better a list than calling this multiple times
+static QCBORError
+QCBORDecode_Private_Check1TagNumber(const QCBORDecodeContext *pMe,
+                                    const QCBORItem          *pItem,
+                                    const uint64_t            uTagNumber,
+                                    const size_t              uOffset)
+{
+   if(pItem->auTagNumbers[0] == CBOR_TAG_INVALID16) {
+      /* There are no tag numbers at all, so no unprocessed */
+      return QCBOR_SUCCESS;
+   }
+
+   /* There are some tag numbers, so keep checking. This check passes
+    * if there is one and only one tag number that matches uTagNumber
+    */
+
+   // TODO: behave different in v1 and v2?
+
+   const uint64_t uInnerTag = QCBORDecode_GetNthTagNumber(pMe, pItem, 0);
+
+   if(uInnerTag == uTagNumber && pItem->auTagNumbers[1] == CBOR_TAG_INVALID16) {
+      /* The only tag number is the one we are processing so no unprocessed */
+      return QCBOR_SUCCESS;
+   }
+
+   if(uOffset != pMe->uTagNumberCheckOffset) {
+      /* processed tag numbers are for some other item, not us */
+      return QCBOR_ERR_UNPROCESSED_TAG_NUMBER;
+   }
+
+   if(pMe->uTagNumberIndex != 1) {
+      return QCBOR_ERR_UNPROCESSED_TAG_NUMBER;
+   }
+
+   return QCBOR_SUCCESS;
+}
+#endif /* ! QCBOR_DISABLE_TAGS */
+
+
+static QCBORError
+QCBORDecode_Private_CheckTagNType(QCBORDecodeContext *pMe,
+                                  const QCBORItem    *pItem,
+                                  const size_t        uOffset,
+                                  const uint8_t      *uQCBORTypes,
+                                  const uint64_t     *uTagNumbers,
+                                  const uint8_t       uTagRequirement,
+                                  bool               *bTypeMatched)
+{
+   const uint64_t *pQType;
+   const uint64_t *pTNum;
+   const uint8_t  *pTypeNum;
+
+   const int nTagReq = uTagRequirement & ~QCBOR_TAG_REQUIREMENT_ALLOW_ADDITIONAL_TAGS;
+
+   *bTypeMatched = false;
+   for(pTypeNum = uQCBORTypes; *pTypeNum != QCBOR_TYPE_NONE; pTypeNum++) {
+      if(pItem->uDataType == *pTypeNum) {
+         *bTypeMatched = true;
+         break;
+      }
+   }
+
+#ifndef QCBOR_DISABLE_TAGS
+   bool        bTagNumberMatched;
+   QCBORError  uErr;
+   const uint64_t uInnerTag = QCBORDecode_GetNthTagNumber(pMe, pItem, 0);
+
+   bTagNumberMatched = false;
+   for(pQType = uTagNumbers; *pQType != CBOR_TAG_INVALID64; pQType++) {
+      if(uInnerTag == *pQType) {
+         bTagNumberMatched = true;
+         break;
+      }
+   }
+
+
+   if(nTagReq == QCBOR_TAG_REQUIREMENT_TAG) {
+      /* There must be a tag number */
+      if(!bTagNumberMatched && !*bTypeMatched) {
+         return QCBOR_ERR_UNEXPECTED_TYPE; // TODO: error code
+      }
+
+   } else if(nTagReq == QCBOR_TAG_REQUIREMENT_NOT_A_TAG) {
+      if(bTagNumberMatched || *bTypeMatched) {
+         return QCBOR_ERR_UNEXPECTED_TYPE; // TODO: error code
+      }
+
+   } else if(nTagReq == QCBOR_TAG_REQUIREMENT_OPTIONAL_TAG) {
+      /* No check necessary */
+   }
+
+   /* Now check if there are extra tags and if there's an error in them */
+   if(!(uTagRequirement & QCBOR_TAG_REQUIREMENT_ALLOW_ADDITIONAL_TAGS)) {
+      /* The flag to ignore extra is not set, so keep checking */
+      for(pTNum = uTagNumbers; *pTNum != CBOR_TAG_INVALID64; pTNum++) {
+         uErr = QCBORDecode_Private_Check1TagNumber(pMe, pItem, *pTNum, uOffset);
+         if(uErr != QCBOR_SUCCESS) {
+            return uErr;
+         }
+      }
+   }
+
+   return QCBOR_SUCCESS;
+#else /* ! QCBOR_DISABLE_TAGS */
+   (void)pMe;
+   (void)uOffset;
+   (void)uTagNumbers;
+
+   if(nTagReq != QCBOR_TAG_REQUIREMENT_TAG && bTypeMatched) {
+      return QCBOR_SUCCESS;
+   } else {
+      return QCBOR_ERR_UNEXPECTED_TYPE;
+   }
+
+#endif /* ! QCBOR_DISABLE_TAGS */
+
+}
+
+
+void
+QCBORDecode_Private_ProcessTagItemMulti(QCBORDecodeContext      *pMe,
+                                        QCBORItem               *pItem,
+                                        const uint8_t            uTagRequirement,
+                                        const uint8_t            uQCBORTypes[],
+                                        const uint64_t           uTagNumbers[],
+                                        QCBORTagContentCallBack *pfCB,
+                                        size_t                   uOffset)
+{
+   QCBORError uErr;
+   bool       bTypeMatched;
+
+   if(pMe->uLastError != QCBOR_SUCCESS) {
+      return;
+   }
+
+   uErr = QCBORDecode_Private_CheckTagNType(pMe,
+                                            pItem,
+                                            uOffset,
+                                            uQCBORTypes,
+                                            uTagNumbers,
+                                            uTagRequirement,
+                                            &bTypeMatched);
+   if(uErr != QCBOR_SUCCESS) {
+      goto Done;
+   }
+
+   if(!bTypeMatched) {
+      /* Tag content wasn't previously processed, do it now */
+      uErr = (*pfCB)(pMe, NULL, uTagNumbers[0], pItem);
+      if(uErr != QCBOR_SUCCESS) {
+         goto Done;
+      }
+   }
+
+Done:
+   pMe->uLastError = (uint8_t)uErr;
+}
+
+
+/*
+ **/
+void
+QCBORDecode_Private_ProcessTagItem(QCBORDecodeContext      *pMe,
+                                   QCBORItem               *pItem,
+                                   const uint8_t            uTagRequirement,
+                                   const uint8_t            uQCBORTypes[],
+                                   const uint64_t           uTagNumber,
+                                   QCBORTagContentCallBack *pfCB,
+                                   size_t                   uOffset)
+{
+   uint64_t auTagNumbers[2];
+
+   auTagNumbers[0] = uTagNumber;
+   auTagNumbers[1] = CBOR_TAG_INVALID64;
+
+   QCBORDecode_Private_ProcessTagItemMulti(pMe,
+                                           pItem,
+                                           uTagRequirement,
+                                           uQCBORTypes,
+                                           auTagNumbers,
+                                           pfCB,
+                                           uOffset);
+}
+
+
+static void
+QCBORDecode_Private_ProcessTagOne(QCBORDecodeContext      *pMe,
+                                  QCBORItem               *pItem,
+                                  const uint8_t            uTagRequirement,
+                                  const uint8_t            uQCBORType,
+                                  const uint64_t           uTagNumber,
+                                  QCBORTagContentCallBack *pfCB,
+                                  const size_t             uOffset)
+{
+   uint8_t auQCBORType[2];
+
+   auQCBORType[0] = uQCBORType;
+   auQCBORType[1] = QCBOR_TYPE_NONE;
+
+   QCBORDecode_Private_ProcessTagItem(pMe,
+                                      pItem,
+                                      uTagRequirement,
+                                      auQCBORType,
+                                      uTagNumber,
+                                      pfCB,
+                                      uOffset);
+}
+
+
+void
+QCBORDecode_Private_GetTaggedString(QCBORDecodeContext  *pMe,
+                                    const uint8_t        uTagRequirement,
+                                    const uint8_t        uQCBOR_Type,
+                                    const uint64_t       uTagNumber,
+                                    UsefulBufC          *pStr)
+{
+   QCBORItem  Item;
+   size_t uOffset;
+
+   QCBORDecode_Private_GetAndTell(pMe, &Item, &uOffset);
+   QCBORDecode_Private_ProcessTagOne(pMe,
+                                     &Item,
+                                      uTagRequirement,
+                                      uQCBOR_Type,
+                                      uTagNumber,
+                                      QCBORDecode_StringsTagCB,
+                                      uOffset);
+
+   if(pMe->uLastError == QCBOR_SUCCESS) {
+      *pStr = Item.val.string;
+   } else {
+      *pStr = NULLUsefulBufC;
+   }
+}
+
+
+/**
+ * @brief Semi-private to get an string by label to match a tag specification.
+ *
+ * @param[in] pMe              The decode context.
+ * @param[in] nLabel           Label to search map for.
+ * @param[in] uTagRequirement  Whether or not tag number is required.
+ *                             See @ref QCBOR_TAG_REQUIREMENT_TAG.
+ * @param[in] uQCBOR_Type      QCBOR type to search for.
+ * @param[in] uTagNumber       Tag number to match.
+ * @param[out] pString         The string found.
+ *
+ * This finds the string  with the given label in currently open
+ * map. Then checks that its tag number and types matches the tag
+ * specification. If not, an error is set in the decode context.
+ */
+void
+QCBORDecode_Private_GetTaggedStringInMapN(QCBORDecodeContext  *pMe,
+                                          const int64_t        nLabel,
+                                          const uint8_t        uTagRequirement,
+                                          const uint8_t        uQCBOR_Type,
+                                          const uint64_t       uTagNumber,
+                                          UsefulBufC          *pString)
+{
+   QCBORItem  Item;
+   size_t     uOffset;
+
+   QCBORDecode_Private_GetItemInMapNoCheckN(pMe,
+                                            nLabel,
+                                            QCBOR_TYPE_ANY,
+                                            &Item,
+                                            &uOffset);
+   QCBORDecode_Private_ProcessTagOne(pMe,
+                                    &Item,
+                                     uTagRequirement,
+                                     uQCBOR_Type,
+                                     uTagNumber,
+                                     QCBORDecode_StringsTagCB,
+                                     uOffset);
+
+   if(pMe->uLastError == QCBOR_SUCCESS) {
+      *pString = Item.val.string;
+   }
+}
+
+
+/**
+ * @brief Semi-private to get an string by label to match a tag specification.
+ *
+ * @param[in] pMe              The decode context.
+ * @param[in] szLabel           Label to search map for.
+ * @param[in] uTagRequirement  Whether or not tag number is required.
+ *                             See @ref QCBOR_TAG_REQUIREMENT_TAG.
+ * @param[in] uQCBOR_Type      QCBOR type to search for.
+ * @param[in] uTagNumber       Tag number to match.
+ * @param[out] pString         The string found.
+ *
+ * This finds the string  with the given label in currently open
+ * map. Then checks that its tag number and types matches the tag
+ * specification. If not, an error is set in the decode context.
+  */
+void
+QCBORDecode_Private_GetTaggedStringInMapSZ(QCBORDecodeContext  *pMe,
+                                           const char          *szLabel,
+                                           uint8_t              uTagRequirement,
+                                           uint8_t              uQCBOR_Type,
+                                           uint64_t             uTagNumber,
+                                           UsefulBufC          *pString)
+{
+   QCBORItem Item;
+   size_t    uOffset;
+
+   QCBORDecode_Private_GetItemInMapNoCheckSZ(pMe,
+                                             szLabel,
+                                             QCBOR_TYPE_ANY,
+                                             &Item,
+                                             &uOffset);
+   QCBORDecode_Private_ProcessTagOne(pMe,
+                                   &Item,
+                                   uTagRequirement,
+                                   uQCBOR_Type,
+                                   uTagNumber,
+                                   QCBORDecode_StringsTagCB,
+                                   uOffset);
+
+
+   if(pMe->uLastError == QCBOR_SUCCESS) {
+      *pString = Item.val.string;
+   }
+}
+
+
+
+
+/**
+ * @brief The main work of entering some byte-string wrapped CBOR.
+ *
+ * @param[in] pMe             The decode context.
+ * @param[in] pItem           The byte string item.
+ * @param[in] uTagRequirement One of @c QCBOR_TAG_REQUIREMENT_XXX
+ * @param[out] pBstr          Pointer and length of byte string entered.
+ *
+ * This is called once the byte string item has been decoded to do all
+ * the book keeping work for descending a nesting level into the
+ * nested CBOR.
+ *
+ * See QCBORDecode_EnterBstrWrapped() for details on uTagRequirement.
+ */
+static QCBORError
+QCBORDecode_Private_EnterBstrWrapped(QCBORDecodeContext *pMe,
+                                     const QCBORItem    *pItem,
+                                     const uint8_t       uTagRequirement,
+                                     const size_t        uOffset,
+                                     UsefulBufC         *pBstr)
+{
+   bool       bTypeMatched;
+   QCBORError uError;
+
+   const uint8_t uTypes[] = {QBCOR_TYPE_WRAPPED_CBOR,
+                             QBCOR_TYPE_WRAPPED_CBOR_SEQUENCE,
+                             QCBOR_TYPE_NONE};
+   const uint64_t uTagNumbers[] = {CBOR_TAG_CBOR,
+                                   CBOR_TAG_CBOR_SEQUENCE,
+                                   CBOR_TAG_INVALID64};
+
+
+   if(pBstr) {
+      *pBstr = NULLUsefulBufC;
+   }
+
+   if(pMe->uLastError != QCBOR_SUCCESS) {
+      return pMe->uLastError;
+   }
+
+   if(pItem->uDataAlloc) {
+      return QCBOR_ERR_CANNOT_ENTER_ALLOCATED_STRING;
+   }
+
+   uError = QCBORDecode_Private_CheckTagNType(pMe,
+                                              pItem,
+                                              uOffset,
+                                              uTypes,//TODO: maybe empty?
+                                              uTagNumbers,
+                                              uTagRequirement,
+                                             &bTypeMatched);
+
+   if(pItem->uDataType != QCBOR_TYPE_BYTE_STRING) {
+      uError = QCBOR_ERR_BAD_TAG_CONTENT; // TODO: error
+   }
+
+
+   if(DecodeNesting_IsCurrentDefiniteLength(&(pMe->nesting))) {
+      /* Reverse the decrement done by GetNext() for the bstr so the
+       * increment in QCBORDecode_NestLevelAscender() called by
+       * ExitBoundedLevel() will work right.
+       */
+      DecodeNesting_ReverseDecrement(&(pMe->nesting));
+   }
+
+   if(pBstr) {
+      *pBstr = pItem->val.string;
+   }
+
+   /* This saves the current length of the UsefulInputBuf and then
+    * narrows the UsefulInputBuf to start and length of the wrapped
+    * CBOR that is being entered.
+    *
+    * Most of these calls are simple inline accessors so this doesn't
+    * amount to much code.
+    */
+
+   const size_t uPreviousLength = UsefulInputBuf_GetBufferLength(&(pMe->InBuf));
+   /* This check makes the cast of uPreviousLength to uint32_t below safe. */
+   if(uPreviousLength >= QCBOR_MAX_DECODE_INPUT_SIZE) {
+      uError = QCBOR_ERR_INPUT_TOO_LARGE;
+      goto Done;
+   }
+
+   const size_t uStartOfBstr = UsefulInputBuf_PointerToOffset(&(pMe->InBuf),
+                                                              pItem->val.string.ptr);
+   /* This check makes the cast of uStartOfBstr to uint32_t below safe. */
+   if(uStartOfBstr == SIZE_MAX || uStartOfBstr > QCBOR_MAX_DECODE_INPUT_SIZE) {
+      /* This should never happen because pItem->val.string.ptr should
+       * always be valid since it was just returned.
+       */
+      uError = QCBOR_ERR_INPUT_TOO_LARGE;
+      goto Done;
+   }
+
+   const size_t uEndOfBstr = uStartOfBstr + pItem->val.string.len;
+
+   UsefulInputBuf_Seek(&(pMe->InBuf), uStartOfBstr);
+   UsefulInputBuf_SetBufferLength(&(pMe->InBuf), uEndOfBstr);
+
+   uError = DecodeNesting_DescendIntoBstrWrapped(&(pMe->nesting),
+                                                 (uint32_t)uPreviousLength,
+                                                 (uint32_t)uStartOfBstr);
+Done:
+   return uError;
+}
+
+
+/* Public function; see qcbor_tag_decode.h */
+void
+QCBORDecode_EnterBstrWrapped(QCBORDecodeContext *pMe,
+                             const uint8_t       uTagRequirement,
+                             UsefulBufC         *pBstr)
+{
+   QCBORItem Item;
+   size_t    uOffset;
+
+   QCBORDecode_Private_GetAndTell(pMe, &Item, &uOffset);
+   pMe->uLastError = (uint8_t)QCBORDecode_Private_EnterBstrWrapped(pMe,
+                                                                  &Item,
+                                                                   uTagRequirement,
+                                                                   uOffset,
+                                                                   pBstr);
+}
+
+
+/* Public function; see qcbor_tag_decode.h */
+void
+QCBORDecode_EnterBstrWrappedFromMapN(QCBORDecodeContext *pMe,
+                                     const int64_t       nLabel,
+                                     const uint8_t       uTagRequirement,
+                                     UsefulBufC         *pBstr)
+{
+   QCBORItem Item;
+   size_t    uOffset;
+
+   QCBORDecode_Private_GetItemInMapNoCheckN(pMe,
+                                            nLabel,
+                                            QCBOR_TYPE_BYTE_STRING,
+                                            &Item,
+                                            &uOffset);
+   pMe->uLastError = (uint8_t)QCBORDecode_Private_EnterBstrWrapped(pMe,
+                                                                  &Item,
+                                                                   uTagRequirement,
+                                                                   uOffset,
+                                                                   pBstr);
+}
+
+
+/* Public function; see qcbor_tag_decode.h */
+void
+QCBORDecode_EnterBstrWrappedFromMapSZ(QCBORDecodeContext *pMe,
+                                      const char         *szLabel,
+                                      const uint8_t       uTagRequirement,
+                                      UsefulBufC         *pBstr)
+{
+   QCBORItem Item;
+   size_t    uOffset;
+
+   QCBORDecode_Private_GetItemInMapNoCheckSZ(pMe,
+                                             szLabel,
+                                             QCBOR_TYPE_BYTE_STRING,
+                                             &Item,
+                                             &uOffset);
+   pMe->uLastError = (uint8_t)QCBORDecode_Private_EnterBstrWrapped(pMe,
+                                                                  &Item,
+                                                                   uTagRequirement,
+                                                                   uOffset,
+                                                                   pBstr);
+}
+
+
+/* Public function; see qcbor_tag_decode.h */
+void
+QCBORDecode_ExitBstrWrapped(QCBORDecodeContext *pMe)
+{
+   if(pMe->uLastError != QCBOR_SUCCESS) {
+      // Already in error state; do nothing.
+      return;
+   }
+
+   if(!DecodeNesting_IsBoundedType(&(pMe->nesting), QCBOR_TYPE_BYTE_STRING)) {
+      pMe->uLastError = QCBOR_ERR_EXIT_MISMATCH;
+      return;
+   }
+
+   const uint32_t uEndOfBstr = (uint32_t)UsefulInputBuf_GetBufferLength(&(pMe->InBuf));
+
+   /*
+    Reset the length of the UsefulInputBuf to what it was before
+    the bstr wrapped CBOR was entered.
+    */
+   UsefulInputBuf_SetBufferLength(&(pMe->InBuf),
+                               DecodeNesting_GetPreviousBoundedEnd(&(pMe->nesting)));
+
+
+   QCBORError uErr = QCBORDecode_Private_ExitBoundedLevel(pMe, uEndOfBstr);
+   pMe->uLastError = (uint8_t)uErr;
+}
+
+
+
+
+/* Public function; see qcbor_tag_decode.h */
+void
+QCBORDecode_GetEpochDate(QCBORDecodeContext *pMe,
+                         uint8_t             uTagRequirement,
+                         int64_t            *pnTime)
+{
+   QCBORItem  Item;
+   size_t     uOffset;
+
+   QCBORDecode_Private_GetAndTell(pMe, &Item, &uOffset);
+   QCBORDecode_Private_ProcessTagOne(pMe,
+                                     &Item,
+                                     uTagRequirement,
+                                     QCBOR_TYPE_DATE_EPOCH,
+                                     CBOR_TAG_DATE_EPOCH,
+                                     QCBORDecode_DateEpochTagCB,
+                                     uOffset);
+   *pnTime = Item.val.epochDate.nSeconds;
+}
+
+
+/* Public function; see qcbor_tag_decode.h */
+void
+QCBORDecode_GetEpochDateInMapN(QCBORDecodeContext *pMe,
+                               int64_t             nLabel,
+                               uint8_t             uTagRequirement,
+                               int64_t            *pnTime)
+{
+   QCBORItem Item;
+   size_t uOffset;
+
+   QCBORDecode_Private_GetItemInMapNoCheckN(pMe,
+                                            nLabel,
+                                            QCBOR_TYPE_ANY,
+                                            &Item,
+                                            &uOffset);
+   QCBORDecode_Private_ProcessTagOne(pMe,
+                                     &Item,
+                                     uTagRequirement,
+                                     QCBOR_TYPE_DATE_EPOCH,
+                                     CBOR_TAG_DATE_EPOCH,
+                                     QCBORDecode_DateEpochTagCB,
+                                     uOffset);
+   *pnTime = Item.val.epochDate.nSeconds;
+}
+
+
+/* Public function; see qcbor_tag_decode.h */
+void
+QCBORDecode_GetEpochDateInMapSZ(QCBORDecodeContext *pMe,
+                                const char         *szLabel,
+                                uint8_t             uTagRequirement,
+                                int64_t            *pnTime)
+{
+   QCBORItem Item;
+   size_t uOffset;
+
+   QCBORDecode_Private_GetItemInMapNoCheckSZ(pMe,
+                                             szLabel,
+                                             QCBOR_TYPE_ANY,
+                                             &Item,
+                                             &uOffset);
+   QCBORDecode_Private_ProcessTagOne(pMe,
+                                     &Item,
+                                     uTagRequirement,
+                                     QCBOR_TYPE_DATE_EPOCH,
+                                     CBOR_TAG_DATE_EPOCH,
+                                     QCBORDecode_DateEpochTagCB,
+                                     uOffset);
+   *pnTime = Item.val.epochDate.nSeconds;
+}
+
+
+/* Public function; see qcbor_tag_decode.h */
+void
+QCBORDecode_GetEpochDays(QCBORDecodeContext *pMe,
+                         uint8_t             uTagRequirement,
+                         int64_t            *pnDays)
+{
+   QCBORItem  Item;
+   size_t     uOffset;
+
+   QCBORDecode_Private_GetAndTell(pMe, &Item, &uOffset);
+   QCBORDecode_Private_ProcessTagOne(pMe,
+                                     &Item,
+                                     uTagRequirement,
+                                     QCBOR_TYPE_DAYS_EPOCH,
+                                     CBOR_TAG_DAYS_EPOCH,
+                                     QCBORDecode_DaysEpochTagCB,
+                                     uOffset);
+   *pnDays = Item.val.epochDays;
+}
+
+
+/* Public function; see qcbor_tag_decode.h */
+void
+QCBORDecode_GetEpochDaysInMapN(QCBORDecodeContext *pMe,
+                               int64_t             nLabel,
+                               uint8_t             uTagRequirement,
+                               int64_t            *pnDays)
+{
+   QCBORItem Item;
+   size_t uOffset;
+
+   QCBORDecode_Private_GetItemInMapNoCheckN(pMe,
+                                            nLabel,
+                                            QCBOR_TYPE_ANY,
+                                            &Item,
+                                            &uOffset);
+   QCBORDecode_Private_ProcessTagOne(pMe,
+                                     &Item,
+                                     uTagRequirement,
+                                     QCBOR_TYPE_DAYS_EPOCH,
+                                     CBOR_TAG_DAYS_EPOCH,
+                                     QCBORDecode_DaysEpochTagCB,
+                                     uOffset);
+   *pnDays = Item.val.epochDays;
+}
+
+
+/* Public function; see qcbor_tag_decode.h */
+void
+QCBORDecode_GetEpochDaysInMapSZ(QCBORDecodeContext *pMe,
+                                const char         *szLabel,
+                                uint8_t             uTagRequirement,
+                                int64_t            *pnDays)
+{
+   QCBORItem Item;
+   size_t    uOffset;
+
+   QCBORDecode_Private_GetItemInMapNoCheckSZ(pMe,
+                                             szLabel,
+                                             QCBOR_TYPE_ANY,
+                                             &Item,
+                                             &uOffset);
+   QCBORDecode_Private_ProcessTagOne(pMe,
+                                      &Item,
+                                      uTagRequirement,
+                                      QCBOR_TYPE_DAYS_EPOCH,
+                                      CBOR_TAG_DAYS_EPOCH,
+                                      QCBORDecode_DaysEpochTagCB,
+                                      uOffset);
+   *pnDays = Item.val.epochDays;
+}
+
+
+
+
+static void
+QCBORDecode_Private_GetMIME(QCBORDecodeContext *pMe,
+                            const uint8_t       uTagRequirement,
+                            QCBORItem          *pItem,
+                            UsefulBufC         *pValue,
+                            bool               *pbIsTag257,
+                            size_t              uOffset)
+{
+   QCBORError uErr;
+
+   const uint8_t puTypes[] = {QCBOR_TYPE_MIME, QCBOR_TYPE_BINARY_MIME, QCBOR_TYPE_NONE};
+
+   const uint64_t puTNs[] = {CBOR_TAG_MIME, CBOR_TAG_BINARY_MIME, CBOR_TAG_INVALID64};
+
+   QCBORDecode_Private_ProcessTagItemMulti(pMe,
+                                           pItem,
+                                           uTagRequirement,
+                                           puTypes,
+                                           puTNs,
+                                           QCBORDecode_MIMETagCB,
+                                           uOffset);
+   if(pMe->uLastError) {
+      return;
+   }
+
+   if(pItem->uDataType == QCBOR_TYPE_MIME) {
+      *pbIsTag257 = false;
+   } else if(pItem->uDataType == QCBOR_TYPE_BINARY_MIME) {
+      *pbIsTag257 = true;
+   }
+   *pValue = pItem->val.string;
+
+
+   uErr = QCBOR_SUCCESS;
+
+   pMe->uLastError = (uint8_t)uErr;
+}
+
+/* Public function; see qcbor_tag_decode.h */
+void
+QCBORDecode_GetMIMEMessage(QCBORDecodeContext *pMe,
+                           const uint8_t       uTagRequirement,
+                           UsefulBufC         *pMessage,
+                           bool               *pbIsTag257)
+{
+   QCBORItem  Item;
+   size_t     uOffset;
+
+   QCBORDecode_Private_GetAndTell(pMe, &Item, &uOffset);
+   QCBORDecode_Private_GetMIME(pMe,
+                               uTagRequirement,
+                              &Item,
+                               pMessage,
+                               pbIsTag257,
+                               uOffset);
+}
+
+/* Public function; see qcbor_tag_decode.h */
+void
+QCBORDecode_GetMIMEMessageInMapN(QCBORDecodeContext *pMe,
+                                 const int64_t       nLabel,
+                                 const uint8_t       uTagRequirement,
+                                 UsefulBufC         *pMessage,
+                                 bool               *pbIsTag257)
+{
+   QCBORItem  Item;
+   size_t     uOffset;
+
+   QCBORDecode_Private_GetItemInMapNoCheckN(pMe,
+                                            nLabel,
+                                            QCBOR_TYPE_ANY,
+                                            &Item,
+                                            &uOffset);
+   QCBORDecode_Private_GetMIME(pMe,
+                                uTagRequirement,
+                               &Item,
+                                pMessage,
+                                pbIsTag257,
+                                uOffset);
+}
+
+/* Public function; see qcbor_tag_decode.h */
+void
+QCBORDecode_GetMIMEMessageInMapSZ(QCBORDecodeContext *pMe,
+                                  const char         *szLabel,
+                                  const uint8_t       uTagRequirement,
+                                  UsefulBufC         *pMessage,
+                                  bool               *pbIsTag257)
+{
+   QCBORItem  Item;
+   size_t     uOffset;
+
+   QCBORDecode_Private_GetItemInMapNoCheckSZ(pMe,
+                                             szLabel,
+                                             QCBOR_TYPE_ANY,
+                                             &Item,
+                                             &uOffset);
+   QCBORDecode_Private_GetMIME(pMe,
+                                uTagRequirement,
+                               &Item,
+                                pMessage,
+                                pbIsTag257,
+                                uOffset);
+}
+
+
+
+
 /* Public function; see qcbor_tag_decode.h */
 QCBORError
 QCBORDecode_DateEpochTagCB(QCBORDecodeContext *pDecodeCtx,
@@ -166,7 +1182,8 @@
  *                           @ref CBOR_TAG_BIG_FLOAT.
  * @param[in] pDecodedItem   Item being decoded.
  *
- * @returns One of the ten values related to @ref QCBOR_TYPE_DECIMAL_FRACTION and @ref QCBOR_TYPE_BIGFLOAT
+ * @returns One of the ten values related to @ref QCBOR_TYPE_DECIMAL_FRACTION
+ *          and @ref QCBOR_TYPE_BIGFLOAT
  *
  * Does mapping between a CBOR tag number and a QCBOR type with a
  * little logic and arithmetic.
