Decoder optimization and improved code comments; no semantic change

The core decoder object code is 100 bytes smaller.

Some functions are rewritten to be more clear, but no semantic changes.

Lots of improvements in the code comments for the decoder.
diff --git a/src/qcbor_decode.c b/src/qcbor_decode.c
index a600831..fc9cf2b 100644
--- a/src/qcbor_decode.c
+++ b/src/qcbor_decode.c
@@ -1,6 +1,6 @@
 /*==============================================================================
  Copyright (c) 2016-2018, The Linux Foundation.
- Copyright (c) 2018-2020, Laurence Lundblade.
+ Copyright (c) 2018-2021, Laurence Lundblade.
  All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -33,24 +33,30 @@
 
 #include "qcbor/qcbor_decode.h"
 #include "qcbor/qcbor_spiffy_decode.h"
-#include "ieee754.h" // Does not use math.h
+#include "ieee754.h" /* Does not use math.h */
 
 #ifndef QCBOR_DISABLE_FLOAT_HW_USE
-#include <math.h> // For isnan(), llround(), llroudf(), round(), roundf(),
-                  // pow(), exp2()
-#include <fenv.h> // feclearexcept(), fetestexcept()
+
+#include <math.h> /* For isnan(), llround(), llroudf(), round(), roundf(),
+                   * pow(), exp2()
+                   */
+#include <fenv.h> /* feclearexcept(), fetestexcept() */
+
 #endif /* QCBOR_DISABLE_FLOAT_HW_USE */
 
 
+
 /*
- This casts away the const-ness of a pointer, usually so it can be
- freed or realloced.
+ * This casts away the const-ness of a pointer, usually so it can be
+ * freed or realloced.
  */
 #define UNCONST_POINTER(ptr)    ((void *)(ptr))
 
 #define SIZEOF_C_ARRAY(array,type) (sizeof(array)/sizeof(type))
 
 
+
+
 static inline bool
 QCBORItem_IsMapOrArray(const QCBORItem *pMe)
 {
@@ -97,8 +103,8 @@
   ===========================================================================*/
 
 /*
- See comments about and typedef of QCBORDecodeNesting in qcbor_private.h,
- the data structure all these functions work on.
+ * See comments about and typedef of QCBORDecodeNesting in qcbor_private.h,
+ * the data structure all these functions work on.
  */
 
 
@@ -106,9 +112,8 @@
 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
+   /* Limit in DecodeNesting_Descend against more than
+    * QCBOR_MAX_ARRAY_NESTING gaurantees cast is safe
     */
    return (uint8_t)nLevel;
 }
@@ -118,9 +123,8 @@
 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
+   /* Limit in DecodeNesting_Descend against more than
+    * QCBOR_MAX_ARRAY_NESTING gaurantees cast is safe
     */
    return (uint8_t)nLevel;
 }
@@ -159,18 +163,19 @@
 DecodeNesting_IsCurrentDefiniteLength(const QCBORDecodeNesting *pNesting)
 {
    if(pNesting->pCurrent->uLevelType == QCBOR_TYPE_BYTE_STRING) {
-      // Not a map or array
+      /* 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
+      /* Is indefinite */
       return false;
    }
+
 #endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
 
-   // All checks passed; is a definte length map or array
+   /* All checks passed; is a definte length map or array */
    return true;
 }
 
@@ -178,7 +183,7 @@
 DecodeNesting_IsCurrentBstrWrapped(const QCBORDecodeNesting *pNesting)
 {
    if(pNesting->pCurrent->uLevelType == QCBOR_TYPE_BYTE_STRING) {
-      // is a byte string
+      /* is a byte string */
       return true;
    }
    return false;
@@ -199,11 +204,11 @@
 
 static inline void DecodeNesting_SetMapOrArrayBoundedMode(QCBORDecodeNesting *pNesting, bool bIsEmpty, size_t uStart)
 {
-   // Should be only called on maps and arrays
+   /* 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.
+    * 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;
 
@@ -223,24 +228,24 @@
 DecodeNesting_IsAtEndOfBoundedLevel(const QCBORDecodeNesting *pNesting)
 {
    if(pNesting->pCurrentBounded == NULL) {
-      // No bounded map or array set up
+      /* 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
+      /* 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
+      /* In a traveral at a level deeper than the bounded level */
       return false;
    }
-   // Works for both definite and indefinite length maps/arrays
+   /* 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
+      /* Count is not zero, still unconsumed item */
       return false;
    }
-   // All checks passed, got to the end of an array or map
+   /* All checks passed, got to the end of an array or map*/
    return true;
 }
 
@@ -248,7 +253,7 @@
 static inline bool
 DecodeNesting_IsEndOfDefiniteLengthMapOrArray(const QCBORDecodeNesting *pNesting)
 {
-   // Must only be called on map / array
+   /* Must only be called on map / array */
    if(pNesting->pCurrent->u.ma.uCountCursor == 0) {
       return true;
    } else {
@@ -286,7 +291,7 @@
 static inline void
 DecodeNesting_DecrementDefiniteLengthMapOrArrayCount(QCBORDecodeNesting *pNesting)
 {
-   // Only call on a defnite length array / map
+   /* Only call on a definite-length array / map */
    pNesting->pCurrent->u.ma.uCountCursor--;
 }
 
@@ -294,7 +299,7 @@
 static inline void
 DecodeNesting_ReverseDecrement(QCBORDecodeNesting *pNesting)
 {
-   // Only call on a defnite length array / map
+   /* Only call on a definite-length array / map */
    pNesting->pCurrent->u.ma.uCountCursor++;
 }
 
@@ -309,12 +314,12 @@
 static QCBORError
 DecodeNesting_Descend(QCBORDecodeNesting *pNesting, uint8_t uType)
 {
-   // Error out if nesting is too deep
+   /* 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
+   /* The actual descend */
    pNesting->pCurrent++;
 
    pNesting->pCurrent->uLevelType = uType;
@@ -324,18 +329,20 @@
 
 
 static inline QCBORError
-DecodeNesting_EnterBoundedMapOrArray(QCBORDecodeNesting *pNesting, bool bIsEmpty, size_t uOffset)
+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.
+    * 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;
@@ -357,13 +364,14 @@
    QCBORError uError = QCBOR_SUCCESS;
 
    if(uCount == 0) {
-      // Nothing to do for empty definite lenth arrays. They are just are
-      // effectively the same as an item that is not a map or array
+      /* 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
+      /* Empty indefinite-length maps and arrays are handled elsewhere */
    }
 
-   // Error out if arrays is too long to handle
+   /* Error out if arrays is too long to handle */
    if(uCount != QCBOR_COUNT_INDICATES_INDEFINITE_LENGTH &&
       uCount > QCBOR_MAX_ITEMS_IN_ARRAY) {
       uError = QCBOR_ERR_ARRAY_DECODE_TOO_LONG;
@@ -375,7 +383,7 @@
       goto Done;
    }
 
-   // Fill in the new map/array level. Check above makes casts OK.
+   /* Fill in the new map/array level. Check above makes casts OK. */
    pNesting->pCurrent->u.ma.uCountCursor  = (uint16_t)uCount;
    pNesting->pCurrent->u.ma.uCountTotal   = (uint16_t)uCount;
 
@@ -404,6 +412,7 @@
    }
 }
 
+
 static inline void
 DecodeNesting_SetCurrentToBoundedLevel(QCBORDecodeNesting *pNesting)
 {
@@ -423,11 +432,11 @@
       goto Done;
    }
 
-   // Fill in the new byte string level
+   /* Fill in the new byte string level */
    pNesting->pCurrent->u.bs.uPreviousEndOffset = uEndOffset;
    pNesting->pCurrent->u.bs.uEndOfBstr         = uEndOfBstr;
 
-   // Bstr wrapped levels are always bounded
+   /* Bstr wrapped levels are always bounded */
    pNesting->pCurrentBounded = pNesting->pCurrent;
 
 Done:
@@ -459,7 +468,8 @@
 
 
 static inline void
-DecodeNesting_PrepareForMapSearch(QCBORDecodeNesting *pNesting, QCBORDecodeNesting *pSave)
+DecodeNesting_PrepareForMapSearch(QCBORDecodeNesting *pNesting,
+                                  QCBORDecodeNesting *pSave)
 {
    *pSave = *pNesting;
    pNesting->pCurrent = pNesting->pCurrentBounded;
@@ -468,7 +478,8 @@
 
 
 static inline void
-DecodeNesting_RestoreFromMapSearch(QCBORDecodeNesting *pNesting, const QCBORDecodeNesting *pSave)
+DecodeNesting_RestoreFromMapSearch(QCBORDecodeNesting *pNesting,
+                                   const QCBORDecodeNesting *pSave)
 {
    *pNesting = *pSave;
 }
@@ -488,6 +499,8 @@
 }
 
 
+
+
 #ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS
 /*===========================================================================
    QCBORStringAllocate -- STRING ALLOCATOR INVOCATION
@@ -529,6 +542,8 @@
 #endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS */
 
 
+
+
 /*===========================================================================
  QCBORDecode -- The main implementation of CBOR decoding
 
@@ -536,33 +551,35 @@
  used here: QCBORDecodeContext
   ===========================================================================*/
 /*
- Public function, see header file
+ * Public function, see header file
  */
-void QCBORDecode_Init(QCBORDecodeContext *me,
-                      UsefulBufC EncodedCBOR,
-                      QCBORDecodeMode nDecodeMode)
+void QCBORDecode_Init(QCBORDecodeContext *pMe,
+                      UsefulBufC          EncodedCBOR,
+                      QCBORDecodeMode     nDecodeMode)
 {
-   memset(me, 0, sizeof(QCBORDecodeContext));
-   UsefulInputBuf_Init(&(me->InBuf), EncodedCBOR);
-   // Don't bother with error check on decode mode. If a bad value is
-   // passed it will just act as if the default normal mode of 0 was set.
-   me->uDecodeMode = (uint8_t)nDecodeMode;
-   DecodeNesting_Init(&(me->nesting));
-   for(int i = 0; i < QCBOR_NUM_MAPPED_TAGS; i++) {
-      me->auMappedTags[i] = CBOR_TAG_INVALID16;
-   }
+   memset(pMe, 0, sizeof(QCBORDecodeContext));
+   UsefulInputBuf_Init(&(pMe->InBuf), EncodedCBOR);
+   /* Don't bother with error check on decode mode. If a bad value is
+    * passed it will just act as if the default normal mode of 0 was set.
+    */
+   pMe->uDecodeMode = (uint8_t)nDecodeMode;
+   DecodeNesting_Init(&(pMe->nesting));
+
+   /* Inialize me->auMappedTags to CBOR_TAG_INVALID16. See
+    * GetNext_TaggedItem() and MapTagNumber(). */
+   memset(pMe->auMappedTags, 0xff, sizeof(pMe->auMappedTags));
 }
 
 
 #ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS
 
 /*
- Public function, see header file
+ * Public function, see header file
  */
 void QCBORDecode_SetUpAllocator(QCBORDecodeContext *pMe,
                                 QCBORStringAllocate pfAllocateFunction,
-                                void *pAllocateContext,
-                                bool bAllStrings)
+                                void               *pAllocateContext,
+                                bool                bAllStrings)
 {
    pMe->StringAllocator.pfAllocator   = pfAllocateFunction;
    pMe->StringAllocator.pAllocateCxt  = pAllocateContext;
@@ -571,154 +588,218 @@
 #endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS */
 
 
+
+
 /*
- Public function, see header file
+ * Deprecated public function, see header file
  */
-void QCBORDecode_SetCallerConfiguredTagList(QCBORDecodeContext *pMe,
+void QCBORDecode_SetCallerConfiguredTagList(QCBORDecodeContext   *pMe,
                                             const QCBORTagListIn *pTagList)
 {
-   // This does nothing now. It is retained for backwards compatibility
+   /* This does nothing now. It is retained for backwards compatibility */
    (void)pMe;
    (void)pTagList;
 }
 
 
+
+
 /*
- This decodes the fundamental part of a CBOR data item, the type and
- number
-
- This is the counterpart to QCBOREncode_EncodeHead().
-
- This does the network->host byte order conversion. The conversion
- here also results in the conversion for floats in addition to that
- for lengths, tags and integer values.
-
- This returns:
-   pnMajorType -- the major type for the item
-
-   puArgument -- the "number" which is used a the value for integers,
-               tags and floats and length for strings and arrays
-
-   pnAdditionalInfo -- Pass this along to know what kind of float or
-                       if length is indefinite
-
- The int type is preferred to uint8_t for some variables as this
- avoids integer promotions, can reduce code size and makes
- static analyzers happier.
-
- @retval QCBOR_ERR_UNSUPPORTED
-
- @retval QCBOR_ERR_HIT_END
+ * Decoding items is done in six layers, one calling the next one
+ * down. If a layer has no work to do for a particular item, it
+ * returns quickly.
+ *
+ * 1. QCBORDecode_GetNextTagContent - The top layer processes tagged
+ * data items, turning them into the local C representation.  For the
+ * most simple it is just associating a QCBOR_TYPE with the data. For
+ * the complex ones that an aggregate of data items, there is some
+ * further decoding and some limited recursion.
+ *
+ * 2. QCBORDecode_GetNextMapOrArray - This manages the beginnings and
+ * ends of maps and arrays. It tracks descending into and ascending
+ * out of maps/arrays. It processes breaks that terminate
+ * indefinite-length maps and arrays.
+ *
+ * 3. QCBORDecode_GetNextMapEntry - This handles the combining of two
+ * items, the label and the data, that make up a map entry.  It only
+ * does work on maps. It combines the label and data items into one
+ * labeled item.
+ *
+ * 4. QCBORDecode_GetNextTagNumber - This decodes type 6 tag
+ * numbers. It turns the tag numbers into bit flags associated with
+ * the data item. No actual decoding of the contents of the tag is
+ * performed here.
+ *
+ * 5. QCBORDecode_GetNextFullString - This assembles the sub-items
+ * that make up an indefinite-length string into one string item. It
+ * uses the string allocator to create contiguous space for the
+ * item. It processes all breaks that are part of indefinite-length
+ * strings.
+ *
+ * 6. DecodeAtomicDataItem - This decodes the atomic data items in
+ * CBOR. Each atomic data item has a "major type", an integer
+ * "argument" and optionally some content. For text and byte strings,
+ * the content is the bytes that make up the string. These are the
+ * smallest data items that are considered to be well-formed.  The
+ * content may also be other data items in the case of aggregate
+ * types. They are not handled in this layer.
+ *
+ * Roughly this takes 300 bytes of stack for vars. TODO: evaluate this
+ * more carefully and correctly.
  */
-static inline QCBORError DecodeTypeAndNumber(UsefulInputBuf *pUInBuf,
-                                              int *pnMajorType,
-                                              uint64_t *puArgument,
-                                              int *pnAdditionalInfo)
+
+
+/*
+ * Note about use of int and unsigned variables.
+ *
+ * See http://www.unix.org/whitepapers/64bit.html for reasons int is
+ * used carefully here, and in particular why it isn't used in the
+ * public interface.  Also see
+ * https://stackoverflow.com/questions/17489857/why-is-int-typically-32-bit-on-64-bit-compilers
+ *
+ * Int is used for values that need less than 16-bits and would be
+ * subject to integer promotion and result in complaining from static
+ * analyzers.
+ */
+
+
+/**
+ * @brief Decode the CBOR head, the type and argument.
+ *
+ * @param[in] pUInBuf            The input buffer to read from.
+ * @param[out] pnMajorType       The decoded major type.
+ * @param[out] puArgument        The decoded argument.
+ * @param[out] pnAdditionalInfo  The decoded Lower 5 bits of initial byte.
+ *
+ * @retval QCBOR_ERR_UNSUPPORTED
+ * @retval QCBOR_ERR_HIT_END
+ *
+ * This decodes the CBOR "head" that every CBOR data item has. See
+ * longer explaination of the head in documentation for
+ * QCBOREncode_EncodeHead().
+ *
+ * This does the network->host byte order conversion. The conversion
+ * here also results in the conversion for floats in addition to that
+ * for lengths, tags and integer values.
+ *
+ * The int type is preferred to uint8_t for some variables as this
+ * avoids integer promotions, can reduce code size and makes static
+ * analyzers happier.
+ */
+static inline QCBORError
+DecodeHead(UsefulInputBuf *pUInBuf,
+           int            *pnMajorType,
+           uint64_t       *puArgument,
+           int            *pnAdditionalInfo)
 {
-   QCBORError nReturn;
+   QCBORError uReturn;
 
-   // Get the initial byte that every CBOR data item has
-   const int nInitialByte = (int)UsefulInputBuf_GetByte(pUInBuf);
-
-   // Break down the initial byte
+   /* Get the initial byte that every CBOR data item has and break it
+    * down. */
+   const int nInitialByte    = (int)UsefulInputBuf_GetByte(pUInBuf);
    const int nTmpMajorType   = nInitialByte >> 5;
    const int nAdditionalInfo = nInitialByte & 0x1f;
 
-   // Where the number or argument accumulates
+   /* Where the argument accumulates */
    uint64_t uArgument;
 
    if(nAdditionalInfo >= LEN_IS_ONE_BYTE && nAdditionalInfo <= LEN_IS_EIGHT_BYTES) {
-      // Need to get 1,2,4 or 8 additional argument bytes. Map
-      // LEN_IS_ONE_BYTE..LEN_IS_EIGHT_BYTES to actual length
+      /* Need to get 1,2,4 or 8 additional argument bytes. Map
+       * LEN_IS_ONE_BYTE..LEN_IS_EIGHT_BYTES to actual length.
+       */
       static const uint8_t aIterate[] = {1,2,4,8};
 
-      // Loop getting all the bytes in the argument
+      /* Loop getting all the bytes in the argument */
       uArgument = 0;
       for(int i = aIterate[nAdditionalInfo - LEN_IS_ONE_BYTE]; i; i--) {
-         // This shift and add gives the endian conversion
+         /* This shift and add gives the endian conversion. */
          uArgument = (uArgument << 8) + UsefulInputBuf_GetByte(pUInBuf);
       }
    } else if(nAdditionalInfo >= ADDINFO_RESERVED1 && nAdditionalInfo <= ADDINFO_RESERVED3) {
-      // The reserved and thus-far unused additional info values
-      nReturn = QCBOR_ERR_UNSUPPORTED;
+      /* The reserved and thus-far unused additional info values */
+      uReturn = QCBOR_ERR_UNSUPPORTED;
       goto Done;
    } else {
-      // Less than 24, additional info is argument or 31, an indefinite length
-      // No more bytes to get
+      /* Less than 24, additional info is argument or 31, an
+       * indefinite-length.  No more bytes to get.
+       */
       uArgument = (uint64_t)nAdditionalInfo;
    }
 
    if(UsefulInputBuf_GetError(pUInBuf)) {
-      nReturn = QCBOR_ERR_HIT_END;
+      uReturn = QCBOR_ERR_HIT_END;
       goto Done;
    }
 
-   // All successful if we got here.
-   nReturn           = QCBOR_SUCCESS;
+   /* All successful if arrived here. */
+   uReturn           = QCBOR_SUCCESS;
    *pnMajorType      = nTmpMajorType;
    *puArgument       = uArgument;
    *pnAdditionalInfo = nAdditionalInfo;
 
 Done:
-   return nReturn;
+   return uReturn;
 }
 
 
-/*
- CBOR doesn't explicitly specify two's compliment for integers but all
- CPUs use it these days and the test vectors in the RFC are so. All
- integers in the CBOR structure are positive and the major type
- indicates positive or negative.  CBOR can express positive integers
- up to 2^x - 1 where x is the number of bits and negative integers
- down to 2^x.  Note that negative numbers can be one more away from
- zero than positive.  Stdint, as far as I can tell, uses two's
- compliment to represent negative integers.
-
- See http://www.unix.org/whitepapers/64bit.html for reasons int is
- used carefully here, and in particular why it isn't used in the interface.
- Also see
- https://stackoverflow.com/questions/17489857/why-is-int-typically-32-bit-on-64-bit-compilers
-
- Int is used for values that need less than 16-bits and would be subject
- to integer promotion and complaining by static analyzers.
-
- @retval QCBOR_ERR_INT_OVERFLOW
+/**
+ * @brief Decode integer types, major types 0 and 1.
+ *
+ * @param[in] nMajorType     The CBOR major type (0 or 1).
+ * @param[in] uArgument      The argument from the head.
+ * @param[out] pDecodedItem  The filled in decoded item.
+ *
+ * @retval QCBOR_ERR_INT_OVERFLOW
+ *
+ * Must only be called when major type is 0 or 1.
+ *
+ * CBOR doesn't explicitly specify two's compliment for integers but
+ * all CPUs use it these days and the test vectors in the RFC are
+ * so. All integers in the CBOR structure are positive and the major
+ * type indicates positive or negative.  CBOR can express positive
+ * integers up to 2^x - 1 where x is the number of bits and negative
+ * integers down to 2^x.  Note that negative numbers can be one more
+ * away from zero than positive.  Stdint, as far as I can tell, uses
+ * two's compliment to represent negative integers.
  */
 static inline QCBORError
-DecodeInteger(int nMajorType, uint64_t uNumber, QCBORItem *pDecodedItem)
+DecodeInteger(int nMajorType, uint64_t uArgument, QCBORItem *pDecodedItem)
 {
-   QCBORError nReturn = QCBOR_SUCCESS;
+   QCBORError uReturn = QCBOR_SUCCESS;
 
    if(nMajorType == CBOR_MAJOR_TYPE_POSITIVE_INT) {
-      if (uNumber <= INT64_MAX) {
-         pDecodedItem->val.int64 = (int64_t)uNumber;
+      if (uArgument <= INT64_MAX) {
+         pDecodedItem->val.int64 = (int64_t)uArgument;
          pDecodedItem->uDataType = QCBOR_TYPE_INT64;
 
       } else {
-         pDecodedItem->val.uint64 = uNumber;
+         pDecodedItem->val.uint64 = uArgument;
          pDecodedItem->uDataType  = QCBOR_TYPE_UINT64;
-
       }
+
    } else {
-      if(uNumber <= INT64_MAX) {
-         // CBOR's representation of negative numbers lines up with the
-         // two-compliment representation. A negative integer has one
-         // more in range than a positive integer. INT64_MIN is
-         // equal to (-INT64_MAX) - 1.
-         pDecodedItem->val.int64 = (-(int64_t)uNumber) - 1;
+      if(uArgument <= INT64_MAX) {
+         /* CBOR's representation of negative numbers lines up with
+          * the two-compliment representation. A negative integer has
+          * one more in range than a positive integer. INT64_MIN is
+          * equal to (-INT64_MAX) - 1.
+          */
+         pDecodedItem->val.int64 = (-(int64_t)uArgument) - 1;
          pDecodedItem->uDataType = QCBOR_TYPE_INT64;
 
       } else {
-         // C can't represent a negative integer in this range
-         // so it is an error.
-         nReturn = QCBOR_ERR_INT_OVERFLOW;
+         /* C can't represent a negative integer in this range so it
+          * is an error.
+          */
+         uReturn = QCBOR_ERR_INT_OVERFLOW;
       }
    }
 
-   return nReturn;
+   return uReturn;
 }
 
-// Make sure #define value line up as DecodeSimple counts on this.
+
+/* Make sure #define value line up as DecodeSimple counts on this. */
 #if QCBOR_TYPE_FALSE != CBOR_SIMPLEV_FALSE
 #error QCBOR_TYPE_FALSE macro value wrong
 #endif
@@ -747,145 +828,169 @@
 #error QCBOR_TYPE_FLOAT macro value wrong
 #endif
 
-/*
- Decode true, false, floats, break...
 
- @retval QCBOR_ERR_HALF_PRECISION_DISABLED
-
- @retval QCBOR_ERR_BAD_TYPE_7
+/**
+ * @brief Decode major type 7 -- true, false, floating-point, break...
+ *
+ * @param[in] nAdditionalInfo   The lower five bits from the initial byte.
+ * @param[in] uArgument         The argument from the head.
+ * @param[out] pDecodedItem     The filled in decoded item.
+ *
+ * @retval QCBOR_ERR_HALF_PRECISION_DISABLED
+ * @retval QCBOR_ERR_BAD_TYPE_7
  */
-static inline QCBORError
-DecodeSimple(int nAdditionalInfo, uint64_t uNumber, QCBORItem *pDecodedItem)
-{
-   QCBORError nReturn = QCBOR_SUCCESS;
 
-   // uAdditionalInfo is 5 bits from the initial byte. Compile time checks
-   // above make sure uAdditionalInfo values line up with uDataType values.
-   // DecodeTypeAndNumber() never returns an AdditionalInfo > 0x1f so cast
-   // is safe
+static inline QCBORError
+DecodeType7(int nAdditionalInfo, uint64_t uArgument, QCBORItem *pDecodedItem)
+{
+   QCBORError uReturn = QCBOR_SUCCESS;
+
+   /* uAdditionalInfo is 5 bits from the initial byte. Compile time
+    * checks above make sure uAdditionalInfo values line up with
+    * uDataType values.  DecodeHead() never returns an AdditionalInfo
+    * > 0x1f so cast is safe.
+    */
    pDecodedItem->uDataType = (uint8_t)nAdditionalInfo;
 
    switch(nAdditionalInfo) {
-      // No check for ADDINFO_RESERVED1 - ADDINFO_RESERVED3 as they are
-      // caught before this is called.
+      /* No check for ADDINFO_RESERVED1 - ADDINFO_RESERVED3 as they
+       * are caught before this is called.
+       */
 
-      case HALF_PREC_FLOAT: // 25
+      case HALF_PREC_FLOAT: /* 25 */
 #ifndef QCBOR_DISABLE_PREFERRED_FLOAT
-         // Half-precision is returned as a double.
-         // The cast to uint16_t is safe because the encoded value
-         // was 16 bits. It was widened to 64 bits to be passed in here.
-         pDecodedItem->val.dfnum = IEEE754_HalfToDouble((uint16_t)uNumber);
+         /* Half-precision is returned as a double.  The cast to
+          * uint16_t is safe because the encoded value was 16 bits. It
+          * was widened to 64 bits to be passed in here.
+          */
+         pDecodedItem->val.dfnum = IEEE754_HalfToDouble((uint16_t)uArgument);
          pDecodedItem->uDataType = QCBOR_TYPE_DOUBLE;
 #else /* QCBOR_DISABLE_PREFERRED_FLOAT */
-         nReturn = QCBOR_ERR_HALF_PRECISION_DISABLED;
+         uReturn = QCBOR_ERR_HALF_PRECISION_DISABLED;
 #endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
          break;
-      case SINGLE_PREC_FLOAT: // 26
-         // Single precision is normally returned as a double
-         // since double is widely supported, there is no loss of
-         // precision, it makes it easy for the caller in
-         // most cases and it can be converted back to single
-         // with no loss of precision
-         //
-         // The cast to uint32_t is safe because the encoded value
-         // was 32 bits. It was widened to 64 bits to be passed in here.
+      case SINGLE_PREC_FLOAT: /* 26 */
+         /* Single precision is normally returned as a double since
+          * double is widely supported, there is no loss of precision,
+          * it makes it easy for the caller in most cases and it can
+          * be converted back to single with no loss of precision
+          *
+          * The cast to uint32_t is safe because the encoded value was
+          * 32 bits. It was widened to 64 bits to be passed in here.
+          */
          {
-            const float f = UsefulBufUtil_CopyUint32ToFloat((uint32_t)uNumber);
+            const float f = UsefulBufUtil_CopyUint32ToFloat((uint32_t)uArgument);
 #ifndef QCBOR_DISABLE_FLOAT_HW_USE
-            // In the normal case, use HW to convert float to double.
+            /* In the normal case, use HW to convert float to
+             * double. */
             pDecodedItem->val.dfnum = (double)f;
             pDecodedItem->uDataType = QCBOR_TYPE_DOUBLE;
 #else /* QCBOR_DISABLE_FLOAT_HW_USE */
-            // Use of float HW is disabled, return as a float.
+            /* Use of float HW is disabled, return as a float. */
             pDecodedItem->val.fnum = f;
             pDecodedItem->uDataType = QCBOR_TYPE_FLOAT;
 
-            // IEEE754_FloatToDouble() could be used here to return
-            // as a double, but it adds object code and most likely
-            // anyone disabling FLOAT HW use doesn't care about
-            // floats and wants to save object code.
+            /* IEEE754_FloatToDouble() could be used here to return as
+             * a double, but it adds object code and most likely
+             * anyone disabling FLOAT HW use doesn't care about floats
+             * and wants to save object code.
+             */
 #endif /* QCBOR_DISABLE_FLOAT_HW_USE */
          }
          break;
 
-      case DOUBLE_PREC_FLOAT: // 27
-         pDecodedItem->val.dfnum = UsefulBufUtil_CopyUint64ToDouble(uNumber);
+      case DOUBLE_PREC_FLOAT: /* 27 */
+         pDecodedItem->val.dfnum = UsefulBufUtil_CopyUint64ToDouble(uArgument);
          pDecodedItem->uDataType = QCBOR_TYPE_DOUBLE;
          break;
 
-      case CBOR_SIMPLEV_FALSE: // 20
-      case CBOR_SIMPLEV_TRUE:  // 21
-      case CBOR_SIMPLEV_NULL:  // 22
-      case CBOR_SIMPLEV_UNDEF: // 23
-      case CBOR_SIMPLE_BREAK:  // 31
-         break; // nothing to do
+      case CBOR_SIMPLEV_FALSE: /* 20 */
+      case CBOR_SIMPLEV_TRUE:  /* 21 */
+      case CBOR_SIMPLEV_NULL:  /* 22 */
+      case CBOR_SIMPLEV_UNDEF: /* 23 */
+      case CBOR_SIMPLE_BREAK:  /* 31 */
+         break; /* nothing to do */
 
-      case CBOR_SIMPLEV_ONEBYTE: // 24
-         if(uNumber <= CBOR_SIMPLE_BREAK) {
-            // This takes out f8 00 ... f8 1f which should be encoded as e0 … f7
-            nReturn = QCBOR_ERR_BAD_TYPE_7;
+      case CBOR_SIMPLEV_ONEBYTE: /* 24 */
+         if(uArgument <= CBOR_SIMPLE_BREAK) {
+            /* This takes out f8 00 ... f8 1f which should be encoded
+             * as e0 … f7
+             */
+            uReturn = QCBOR_ERR_BAD_TYPE_7;
             goto Done;
          }
          /* FALLTHROUGH */
-         // fall through intentionally
 
-      default: // 0-19
+      default: /* 0-19 */
          pDecodedItem->uDataType   = QCBOR_TYPE_UKNOWN_SIMPLE;
-         /*
-          DecodeTypeAndNumber will make uNumber equal to
-          uAdditionalInfo when uAdditionalInfo is < 24 This cast is
-          safe because the 2, 4 and 8 byte lengths of uNumber are in
-          the double/float cases above
+         /* DecodeHead() will make uArgument equal to
+          * nAdditionalInfo when nAdditionalInfo is < 24. This cast is
+          * safe because the 2, 4 and 8 byte lengths of uNumber are in
+          * the double/float cases above
           */
-         pDecodedItem->val.uSimple = (uint8_t)uNumber;
+         pDecodedItem->val.uSimple = (uint8_t)uArgument;
          break;
    }
 
 Done:
-   return nReturn;
+   return uReturn;
 }
 
 
-/*
- Decode text and byte strings. Call the string allocator if asked to.
-
- @retval QCBOR_ERR_HIT_END
-
- @retval QCBOR_ERR_STRING_ALLOCATE
-
- @retval QCBOR_ERR_STRING_TOO_LONG
+/**
+ * @brief Decode text and byte strings
+ *
+ * @param[in] pAllocator     The string allocator or NULL.
+ * @param[in] uStrLen        The length of the string.
+ * @param[in] pUInBuf        The surce from which to read the string's bytes.
+ * @param[out] pDecodedItem  The filled in decoded item.
+ *
+ * @retval QCBOR_ERR_HIT_END
+ * @retval QCBOR_ERR_STRING_ALLOCATE
+ * @retval QCBOR_ERR_STRING_TOO_LONG
+ *
+ * The reads @c uStrlen bytes from @c pUInBuf and fills in @c
+ * pDecodedItem. If @c pAllocator is not NULL then memory for the
+ * string is allocated.
  */
-static inline QCBORError DecodeBytes(const QCBORInternalAllocator *pAllocator,
-                                     uint64_t uStrLen,
-                                     UsefulInputBuf *pUInBuf,
-                                     QCBORItem *pDecodedItem)
+static inline QCBORError
+DecodeBytes(const QCBORInternalAllocator *pAllocator,
+            uint64_t                      uStrLen,
+            UsefulInputBuf               *pUInBuf,
+            QCBORItem                    *pDecodedItem)
 {
-   QCBORError nReturn = QCBOR_SUCCESS;
+   QCBORError uReturn = QCBOR_SUCCESS;
 
-   // CBOR lengths can be 64 bits, but size_t is not 64 bits on all CPUs.
-   // This check makes the casts to size_t below safe.
-
-   // 4 bytes less than the largest sizeof() so this can be tested by
-   // putting a SIZE_MAX length in the CBOR test input (no one will
-   // care the limit on strings is 4 bytes shorter).
+   /* CBOR lengths can be 64 bits, but size_t is not 64 bits on all
+    * CPUs.  This check makes the casts to size_t below safe.
+    *
+    * The max is 4 bytes less than the largest sizeof() so this can be
+    * tested by putting a SIZE_MAX length in the CBOR test input (no
+    * one will care the limit on strings is 4 bytes shorter).
+    */
    if(uStrLen > SIZE_MAX-4) {
-      nReturn = QCBOR_ERR_STRING_TOO_LONG;
+      uReturn = QCBOR_ERR_STRING_TOO_LONG;
       goto Done;
    }
 
    const UsefulBufC Bytes = UsefulInputBuf_GetUsefulBuf(pUInBuf, (size_t)uStrLen);
    if(UsefulBuf_IsNULLC(Bytes)) {
-      // Failed to get the bytes for this string item
-      nReturn = QCBOR_ERR_HIT_END;
+      /* Failed to get the bytes for this string item */
+      uReturn = QCBOR_ERR_HIT_END;
       goto Done;
    }
 
 #ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS
+   /* Note that this is not where allocation to coalesce
+    * indefinite-length strings is done. This is for when the caller
+    * has requested all strings be allocated. Disabling indefinite
+    * length strings also disables this allocate-all option.
+    */
    if(pAllocator) {
-      // We are asked to use string allocator to make a copy
+      /* request to use the string allocator to make a copy */
       UsefulBuf NewMem = StringAllocator_Allocate(pAllocator, (size_t)uStrLen);
       if(UsefulBuf_IsNULL(NewMem)) {
-         nReturn = QCBOR_ERR_STRING_ALLOCATE;
+         uReturn = QCBOR_ERR_STRING_ALLOCATE;
          goto Done;
       }
       pDecodedItem->val.string = UsefulBuf_Copy(NewMem, Bytes);
@@ -896,16 +1001,23 @@
    (void)pAllocator;
 #endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS */
 
-   // Normal case with no string allocator
+   /* Normal case with no string allocator */
    pDecodedItem->val.string = Bytes;
 
 Done:
-   return nReturn;
+   return uReturn;
 }
 
 
-/* Map the CBOR major types for strings to the QCBOR types for strngs */
-static inline uint8_t MapStringMajorTypes(int nCBORMajorType)
+/**
+ * @brief Map the CBOR major types for strings to the QCBOR types.
+ *
+ * @param[in] nCBORMajorType  The CBOR major type to convert.
+ * @retturns QCBOR type number.
+ *
+ * This only works for the two string types.
+ */
+static inline uint8_t ConvertStringMajorTypes(int nCBORMajorType)
 {
    #if CBOR_MAJOR_TYPE_BYTE_STRING + 4 != QCBOR_TYPE_BYTE_STRING
    #error QCBOR_TYPE_BYTE_STRING no lined up with major type
@@ -919,140 +1031,34 @@
 }
 
 
-// Make sure the constants align as this is assumed by
-// the GetAnItem() implementation
-#if QCBOR_TYPE_ARRAY != CBOR_MAJOR_TYPE_ARRAY
-#error QCBOR_TYPE_ARRAY value not lined up with major type
-#endif
-#if QCBOR_TYPE_MAP != CBOR_MAJOR_TYPE_MAP
-#error QCBOR_TYPE_MAP value not lined up with major type
-#endif
-
-/*
- This gets a single data item and decodes it including preceding
- optional tagging. This does not deal with arrays and maps and nesting
- except to decode the data item introducing them. Arrays and maps are
- handled at the next level up in GetNext().
-
- Errors detected here include: an array that is too long to decode,
- hit end of buffer unexpectedly, a few forms of invalid encoded CBOR
-
- @retval QCBOR_ERR_UNSUPPORTED
-
- @retval QCBOR_ERR_HIT_END
-
- @retval QCBOR_ERR_INT_OVERFLOW
-
- @retval QCBOR_ERR_STRING_ALLOCATE
-
- @retval QCBOR_ERR_STRING_TOO_LONG
-
- @retval QCBOR_ERR_HALF_PRECISION_DISABLED
-
- @retval QCBOR_ERR_BAD_TYPE_7
-
+/**
+ * @brief Map the CBOR major types  for arrays/maps  to the QCBOR types.
+ *
+ * @param[in] nCBORMajorType  The CBOR major type to convert.
+ * @retturns QCBOR type number.
+ *
+ * This only works for the two aggregate types.
  */
-static QCBORError GetNext_Item(UsefulInputBuf *pUInBuf,
-                               QCBORItem *pDecodedItem,
-                               const QCBORInternalAllocator *pAllocator)
+static inline uint8_t ConvertArrayOrMapType(int nCBORMajorType)
 {
-   QCBORError nReturn;
+   #if QCBOR_TYPE_ARRAY != CBOR_MAJOR_TYPE_ARRAY
+   #error QCBOR_TYPE_ARRAY value not lined up with major type
+   #endif
 
-   /*
-    Get the major type and the number. Number could be length of more
-    bytes or the value depending on the major type nAdditionalInfo is
-    an encoding of the length of the uNumber and is needed to decode
-    floats and doubles
-   */
-   int      nMajorType = 0;
-   uint64_t uNumber = 0;
-   int      nAdditionalInfo = 0;
+   #if QCBOR_TYPE_MAP != CBOR_MAJOR_TYPE_MAP
+   #error QCBOR_TYPE_MAP value not lined up with major type
+   #endif
 
-   memset(pDecodedItem, 0, sizeof(QCBORItem));
-
-   nReturn = DecodeTypeAndNumber(pUInBuf, &nMajorType, &uNumber, &nAdditionalInfo);
-
-   // Error out here if we got into trouble on the type and number.  The
-   // code after this will not work if the type and number is not good.
-   if(nReturn) {
-      goto Done;
-   }
-
-   // At this point the major type and the value are valid. We've got
-   // the type and the number that starts every CBOR data item.
-   switch (nMajorType) {
-      case CBOR_MAJOR_TYPE_POSITIVE_INT: // Major type 0
-      case CBOR_MAJOR_TYPE_NEGATIVE_INT: // Major type 1
-         if(nAdditionalInfo == LEN_IS_INDEFINITE) {
-            nReturn = QCBOR_ERR_BAD_INT;
-         } else {
-            nReturn = DecodeInteger(nMajorType, uNumber, pDecodedItem);
-         }
-         break;
-
-      case CBOR_MAJOR_TYPE_BYTE_STRING: // Major type 2
-      case CBOR_MAJOR_TYPE_TEXT_STRING: // Major type 3
-         pDecodedItem->uDataType = MapStringMajorTypes(nMajorType);
-         if(nAdditionalInfo == LEN_IS_INDEFINITE) {
-            pDecodedItem->val.string = (UsefulBufC){NULL, QCBOR_STRING_LENGTH_INDEFINITE};
-         } else {
-            nReturn = DecodeBytes(pAllocator, uNumber, pUInBuf, pDecodedItem);
-         }
-         break;
-
-      case CBOR_MAJOR_TYPE_ARRAY: // Major type 4
-      case CBOR_MAJOR_TYPE_MAP:   // Major type 5
-         // Record the number of items in the array or map
-         if(uNumber > QCBOR_MAX_ITEMS_IN_ARRAY) {
-            nReturn = QCBOR_ERR_ARRAY_DECODE_TOO_LONG;
-            goto Done;
-         }
-         if(nAdditionalInfo == LEN_IS_INDEFINITE) {
-#ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS
-            pDecodedItem->val.uCount = QCBOR_COUNT_INDICATES_INDEFINITE_LENGTH;
-#else /* QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
-            nReturn = QCBOR_ERR_INDEF_LEN_ARRAYS_DISABLED;
-            break;
-#endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
-         } else {
-            // type conversion OK because of check above
-            pDecodedItem->val.uCount = (uint16_t)uNumber;
-         }
-         // C preproc #if above makes sure constants for major types align
-         // DecodeTypeAndNumber never returns a major type > 7 so cast is safe
-         pDecodedItem->uDataType = (uint8_t)nMajorType;
-         break;
-
-      case CBOR_MAJOR_TYPE_OPTIONAL: // Major type 6, optional prepended tags
-         if(nAdditionalInfo == LEN_IS_INDEFINITE) {
-            nReturn = QCBOR_ERR_BAD_INT;
-         } else {
-            pDecodedItem->val.uTagV = uNumber;
-            pDecodedItem->uDataType = QCBOR_TYPE_TAG;
-         }
-         break;
-
-      case CBOR_MAJOR_TYPE_SIMPLE:
-         // Major type 7, float, double, true, false, null...
-         nReturn = DecodeSimple(nAdditionalInfo, uNumber, pDecodedItem);
-         break;
-
-      default:
-         // Never happens because DecodeTypeAndNumber() should never return > 7
-         nReturn = QCBOR_ERR_UNSUPPORTED;
-         break;
-   }
-
-Done:
-   return nReturn;
+   return (uint8_t)(nCBORMajorType);
 }
 
 
 /**
- * @brief Process indefinite length strings
+ * @brief Decode a single primitive data item (decode layer 6).
  *
- * @param[in] pMe   Decoder context
- * @param[in,out] pDecodedItem  The decoded item that work is done on.
+ * @param[in] pUInBuf       Input buffer to read data item from.
+ * @param[out] pDecodedItem  The filled-in decoded item.
+ * @param[in] pAllocator    The allocator to use for strings or NULL.
  *
  * @retval QCBOR_ERR_UNSUPPORTED
  * @retval QCBOR_ERR_HIT_END
@@ -1061,20 +1067,133 @@
  * @retval QCBOR_ERR_STRING_TOO_LONG
  * @retval QCBOR_ERR_HALF_PRECISION_DISABLED
  * @retval QCBOR_ERR_BAD_TYPE_7
+ * @retval QCBOR_ERR_INDEF_LEN_ARRAYS_DISABLED
+ *
+ * This decodes the most primitive / atomic data item. It does
+ * no combing of data items.
+ */
+static QCBORError
+DecodeAtomicDataItem(UsefulInputBuf               *pUInBuf,
+                     QCBORItem                    *pDecodedItem,
+                     const QCBORInternalAllocator *pAllocator)
+{
+   QCBORError uReturn;
+
+   /* Get the major type and the argument. The argument could be
+    * length of more bytes or the value depending on the major
+    * type. nAdditionalInfo is an encoding of the length of the
+    * uNumber and is needed to decode floats and doubles.
+    */
+   int      nMajorType = 0;
+   uint64_t uArgument = 0;
+   int      nAdditionalInfo = 0;
+
+   memset(pDecodedItem, 0, sizeof(QCBORItem));
+
+   uReturn = DecodeHead(pUInBuf, &nMajorType, &uArgument, &nAdditionalInfo);
+   if(uReturn) {
+      goto Done;
+   }
+
+   /* At this point the major type and the argument are valid. We've
+    * got the type and the argument that starts every CBOR data item.
+    */
+   switch (nMajorType) {
+      case CBOR_MAJOR_TYPE_POSITIVE_INT: /* Major type 0 */
+      case CBOR_MAJOR_TYPE_NEGATIVE_INT: /* Major type 1 */
+         if(nAdditionalInfo == LEN_IS_INDEFINITE) {
+            uReturn = QCBOR_ERR_BAD_INT;
+         } else {
+            uReturn = DecodeInteger(nMajorType, uArgument, pDecodedItem);
+         }
+         break;
+
+      case CBOR_MAJOR_TYPE_BYTE_STRING: /* Major type 2 */
+      case CBOR_MAJOR_TYPE_TEXT_STRING: /* Major type 3 */
+         pDecodedItem->uDataType = ConvertStringMajorTypes(nMajorType);
+         if(nAdditionalInfo == LEN_IS_INDEFINITE) {
+            pDecodedItem->val.string = (UsefulBufC){NULL, QCBOR_STRING_LENGTH_INDEFINITE};
+         } else {
+            uReturn = DecodeBytes(pAllocator, uArgument, pUInBuf, pDecodedItem);
+         }
+         break;
+
+      case CBOR_MAJOR_TYPE_ARRAY: /* Major type 4 */
+      case CBOR_MAJOR_TYPE_MAP:   /* Major type 5 */
+         if(nAdditionalInfo == LEN_IS_INDEFINITE) {
+            /* Indefinite-length string. */
+#ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS
+            pDecodedItem->val.uCount = QCBOR_COUNT_INDICATES_INDEFINITE_LENGTH;
+#else /* QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
+            uReturn = QCBOR_ERR_INDEF_LEN_ARRAYS_DISABLED;
+            break;
+#endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
+         } else {
+            /* Definite-length string. */
+            if(uArgument > QCBOR_MAX_ITEMS_IN_ARRAY) {
+                uReturn = QCBOR_ERR_ARRAY_DECODE_TOO_LONG;
+                goto Done;
+             }
+            /* cast OK because of check above */
+            pDecodedItem->val.uCount = (uint16_t)uArgument;
+         }
+         pDecodedItem->uDataType = ConvertArrayOrMapType(nMajorType);
+         break;
+
+      case CBOR_MAJOR_TYPE_TAG: /* Major type 6, tag numbers */
+         if(nAdditionalInfo == LEN_IS_INDEFINITE) {
+            uReturn = QCBOR_ERR_BAD_INT;
+         } else {
+            pDecodedItem->val.uTagV = uArgument;
+            pDecodedItem->uDataType = QCBOR_TYPE_TAG;
+         }
+         break;
+
+      case CBOR_MAJOR_TYPE_SIMPLE:
+         /* Major type 7: float, double, true, false, null... */
+         uReturn = DecodeType7(nAdditionalInfo, uArgument, pDecodedItem);
+         break;
+
+      default:
+         /* Never happens because DecodeHead() should never return > 7 */
+         uReturn = QCBOR_ERR_UNSUPPORTED;
+         break;
+   }
+
+Done:
+   return uReturn;
+}
+
+
+/**
+ * @brief Process indefinite-length strings (decode layer 5).
+ *
+ * @param[in] pMe   Decoder context
+ * @param[out] pDecodedItem  The decoded item that work is done on.
+ *
+ * @retval QCBOR_ERR_UNSUPPORTED
+ * @retval QCBOR_ERR_HIT_END
+ * @retval QCBOR_ERR_INT_OVERFLOW
+ * @retval QCBOR_ERR_STRING_ALLOCATE
+ * @retval QCBOR_ERR_STRING_TOO_LONG
+ * @retval QCBOR_ERR_HALF_PRECISION_DISABLED
+ * @retval QCBOR_ERR_BAD_TYPE_7
+ * @retval QCBOR_ERR_INDEF_LEN_ARRAYS_DISABLED
  * @retval QCBOR_ERR_NO_STRING_ALLOCATOR
  * @retval QCBOR_ERR_INDEFINITE_STRING_CHUNK
+ * @retval QCBOR_ERR_INDEF_LEN_STRINGS_DISABLED
  *
- * If @c pDecodedItem is not an indefinite length string, this does nothing.
+ * If @c pDecodedItem is not an indefinite-length string, this does nothing.
  *
- * If it is, this loops getting the subsequent chunks that make up the
- * string.  The string allocator is used to make a contiguous buffer for
- * the chunks.  When this completes @c pDecodedItem contains the
- * put-together string.
+ * If it is, this loops getting the subsequent chunk data items that
+ * make up the string.  The string allocator is used to make a
+ * contiguous buffer for the chunks.  When this completes @c
+ * pDecodedItem contains the put-together string.
  *
  * Code Reviewers: THIS FUNCTION DOES A LITTLE POINTER MATH
  */
 static inline QCBORError
-GetNext_FullItem(QCBORDecodeContext *pMe, QCBORItem *pDecodedItem)
+QCBORDecode_GetNextFullString(QCBORDecodeContext *pMe, QCBORItem *pDecodedItem)
 {
    /* Aproximate stack usage
     *                                             64-bit      32-bit
@@ -1085,10 +1204,10 @@
     */
 
    /* The string allocator is used here for two purposes: 1)
-    * coalescing the chunks of an indefinite length string, 2)
-    * allocating storage for every string returned.
+    * coalescing the chunks of an indefinite-length string, 2)
+    * allocating storage for every string returned when requested.
     *
-    * The first use is below in this function. Indefinite length
+    * The first use is below in this function. Indefinite-length
     * strings cannot be processed at all without a string allocator.
     *
     * The second used is in DecodeBytes() which is called by
@@ -1115,12 +1234,12 @@
 #endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS */
 
    QCBORError uReturn;
-   uReturn = GetNext_Item(&(pMe->InBuf), pDecodedItem, pAllocatorForGetNext);
+   uReturn = DecodeAtomicDataItem(&(pMe->InBuf), pDecodedItem, pAllocatorForGetNext);
    if(uReturn != QCBOR_SUCCESS) {
       goto Done;
    }
 
-   /* Only do indefinite length processing on strings */
+   /* Only do indefinite-length processing on strings */
    const uint8_t uStringType = pDecodedItem->uDataType;
    if(uStringType!= QCBOR_TYPE_BYTE_STRING && uStringType != QCBOR_TYPE_TEXT_STRING) {
       goto Done;
@@ -1132,29 +1251,29 @@
    }
 
 #ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS
-   /* Can't do indefinite length strings without a string allocator */
+   /* Can't decode indefinite-length strings without a string allocator */
    if(pAllocator == NULL) {
       uReturn = QCBOR_ERR_NO_STRING_ALLOCATOR;
       goto Done;
    }
 
-   /* Loop getting chunks of the indefinite length string */
+   /* Loop getting chunks of the indefinite-length string */
    UsefulBufC FullString = NULLUsefulBufC;
 
    for(;;) {
       /* Get QCBORItem for next chunk */
       QCBORItem StringChunkItem;
       /* Pass a NULL string allocator to GetNext_Item() because the
-       * individual string chunks in an indefinite length should not
+       * individual string chunks in an indefinite-length should not
        * be allocated. They are always copied in the the contiguous
        * buffer allocated here.
        */
-      uReturn = GetNext_Item(&(pMe->InBuf), &StringChunkItem, NULL);
+      uReturn = DecodeAtomicDataItem(&(pMe->InBuf), &StringChunkItem, NULL);
       if(uReturn) {
          break;
       }
 
-      /* Is item is the marker for end of the indefinite length string? */
+      /* Is item is the marker for end of the indefinite-length string? */
       if(StringChunkItem.uDataType == QCBOR_TYPE_BREAK) {
          /* String is complete */
          pDecodedItem->val.string = FullString;
@@ -1163,9 +1282,9 @@
       }
 
       /* All chunks must be of the same type, the type of the item
-       * that introduces the indefinite length string. This also
+       * that introduces the indefinite-length string. This also
        * catches errors where the chunk is not a string at all and an
-       * indefinite length string inside an indefinite length string.
+       * indefinite-length string inside an indefinite-length string.
        */
       if(StringChunkItem.uDataType != uStringType ||
          StringChunkItem.val.string.len == QCBOR_STRING_LENGTH_INDEFINITE) {
@@ -1203,108 +1322,157 @@
 }
 
 
-static uint64_t ConvertTag(const QCBORDecodeContext *me, uint16_t uTagVal) {
-   if(uTagVal <= QCBOR_LAST_UNMAPPED_TAG) {
-      return uTagVal;
-   } else if(uTagVal == CBOR_TAG_INVALID16) {
+/**
+ * @brief This converts a tag number to a shorter mapped value for storage.
+ *
+ * @param[in] pMe                The decode context.
+ * @param[in] uUnMappedTag       The tag number to map
+ * @param[out] puMappedTagNumer  The stored tag number.
+ *
+ * @return error code.
+ *
+ * The main point of mapping tag numbers is make QCBORItem
+ * smaller. With this mapping storage of 4 tags takes up 8
+ * bytes. Without, it would take up 32 bytes.
+ *
+ * This maps tag numbers greater than QCBOR_LAST_UNMAPPED_TAG.
+ * QCBOR_LAST_UNMAPPED_TAG is a little smaller than MAX_UINT16.
+ *
+ * See also UnMapTagNumber() and @ref QCBORItem.
+ */
+static inline QCBORError
+MapTagNumber(QCBORDecodeContext *pMe, uint64_t uUnMappedTag, uint16_t *puMappedTagNumer)
+{
+   if(uUnMappedTag > QCBOR_LAST_UNMAPPED_TAG) {
+      unsigned uTagMapIndex;
+      /* Is there room in the tag map, or is it in it already? */
+      for(uTagMapIndex = 0; uTagMapIndex < QCBOR_NUM_MAPPED_TAGS; uTagMapIndex++) {
+         if(pMe->auMappedTags[uTagMapIndex] == CBOR_TAG_INVALID64) {
+            break;
+         }
+         if(pMe->auMappedTags[uTagMapIndex] == uUnMappedTag) {
+            break;
+         }
+      }
+      if(uTagMapIndex >= QCBOR_NUM_MAPPED_TAGS) {
+         return QCBOR_ERR_TOO_MANY_TAGS;
+      }
+
+      /* Covers the cases where tag is new and were it is already in the map */
+      pMe->auMappedTags[uTagMapIndex] = uUnMappedTag;
+      *puMappedTagNumer = (uint16_t)(uTagMapIndex + QCBOR_LAST_UNMAPPED_TAG + 1);
+
+   } else {
+      *puMappedTagNumer = (uint16_t)uUnMappedTag;
+   }
+
+   return QCBOR_SUCCESS;
+}
+
+
+/**
+ * @brief This converts a mapped tag number to the actual tag number.
+ *
+ * @param[in] pMe               The decode context.
+ * @param[in] uMappedTagNumber  The stored tag number.
+ *
+ * @return The actual tag number is returned or
+ *         @ref CBOR_TAG_INVALID64 on error.
+ *
+ * This is the reverse of MapTagNumber()
+ */
+static uint64_t
+UnMapTagNumber(const QCBORDecodeContext *pMe, uint16_t uMappedTagNumber)
+{
+   if(uMappedTagNumber <= QCBOR_LAST_UNMAPPED_TAG) {
+      return uMappedTagNumber;
+   } else if(uMappedTagNumber == CBOR_TAG_INVALID16) {
       return CBOR_TAG_INVALID64;
    } else {
-      // This won't be negative because of code below in GetNext_TaggedItem()
-      const unsigned uIndex = uTagVal - (QCBOR_LAST_UNMAPPED_TAG + 1);
-      return me->auMappedTags[uIndex];
+      /* This won't be negative because of code below in
+       * MapTagNumber()
+       */
+      const unsigned uIndex = uMappedTagNumber - (QCBOR_LAST_UNMAPPED_TAG + 1);
+      return pMe->auMappedTags[uIndex];
    }
 }
 
 
-/*
- Gets all optional tag data items preceding a data item that is not an
- optional tag and records them as bits in the tag map.
+/**
+ * @brief Aggregate all tags wrapping a data item (decode layer 4).
+ *
+ * @param[in] pMe            Decoder context
+ * @param[out] pDecodedItem  The decoded item that work is done on.
 
- @retval QCBOR_ERR_UNSUPPORTED
-
- @retval QCBOR_ERR_HIT_END
-
- @retval QCBOR_ERR_INT_OVERFLOW
-
- @retval QCBOR_ERR_STRING_ALLOCATE
-
- @retval QCBOR_ERR_STRING_TOO_LONG
-
- @retval QCBOR_ERR_HALF_PRECISION_DISABLED
-
- @retval QCBOR_ERR_BAD_TYPE_7
-
- @retval QCBOR_ERR_NO_STRING_ALLOCATOR
-
- @retval QCBOR_ERR_INDEFINITE_STRING_CHUNK
-
- @retval QCBOR_ERR_TOO_MANY_TAGS
+ * @retval QCBOR_ERR_UNSUPPORTED
+ * @retval QCBOR_ERR_HIT_END
+ * @retval QCBOR_ERR_INT_OVERFLOW
+ * @retval QCBOR_ERR_STRING_ALLOCATE
+ * @retval QCBOR_ERR_STRING_TOO_LONG
+ * @retval QCBOR_ERR_HALF_PRECISION_DISABLED
+ * @retval QCBOR_ERR_BAD_TYPE_7
+ * @retval QCBOR_ERR_INDEF_LEN_ARRAYS_DISABLED
+ * @retval QCBOR_ERR_NO_STRING_ALLOCATOR
+ * @retval QCBOR_ERR_INDEFINITE_STRING_CHUNK
+ * @retval QCBOR_ERR_INDEF_LEN_STRINGS_DISABLED
+ * @retval QCBOR_ERR_TOO_MANY_TAGS
+ *
+ * This loops getting atomic data items until one is not a tag
+ * number.  Usually this is largely pass-through because most
+ * item are not tag numbers.
  */
 static QCBORError
-GetNext_TaggedItem(QCBORDecodeContext *me, QCBORItem *pDecodedItem)
+QCBORDecode_GetNextTagNumber(QCBORDecodeContext *pMe, QCBORItem *pDecodedItem)
 {
-   uint16_t auTags[QCBOR_MAX_TAGS_PER_ITEM] = {CBOR_TAG_INVALID16,
-                                               CBOR_TAG_INVALID16,
-                                               CBOR_TAG_INVALID16,
-                                               CBOR_TAG_INVALID16};
+   uint16_t auItemsTags[QCBOR_MAX_TAGS_PER_ITEM];
+
+   /* Initialize to CBOR_TAG_INVALID16 */
+   #if CBOR_TAG_INVALID16 != 0xffff
+   /* Be sure the memset does the right thing. */
+   #err CBOR_TAG_INVALID16 tag not defined as expected
+   #endif
+   memset(auItemsTags, 0xff, sizeof(auItemsTags));
 
    QCBORError uReturn = QCBOR_SUCCESS;
 
-   // Loop fetching items until the item fetched is not a tag
+   /* Loop fetching data items until the item fetched is not a tag */
    for(;;) {
-      QCBORError uErr = GetNext_FullItem(me, pDecodedItem);
+      QCBORError uErr = QCBORDecode_GetNextFullString(pMe, pDecodedItem);
       if(uErr != QCBOR_SUCCESS) {
          uReturn = uErr;
-         goto Done; // Error out of the loop
+         goto Done;
       }
 
       if(pDecodedItem->uDataType != QCBOR_TYPE_TAG) {
-         // Successful exit from loop; maybe got some tags, maybe not
-         memcpy(pDecodedItem->uTags, auTags, sizeof(auTags));
+         /* Successful exit from loop; maybe got some tags, maybe not */
+         memcpy(pDecodedItem->uTags, auItemsTags, sizeof(auItemsTags));
          break;
       }
 
-      if(auTags[QCBOR_MAX_TAGS_PER_ITEM - 1] != CBOR_TAG_INVALID16) {
-         // No room in the tag list
+      if(auItemsTags[QCBOR_MAX_TAGS_PER_ITEM - 1] != CBOR_TAG_INVALID16) {
+         /* No room in the tag list */
          uReturn = QCBOR_ERR_TOO_MANY_TAGS;
-         // Continue on to get all tags on this item even though
-         // it is erroring out in the end. This is a resource limit
-         // error, not a problem with being well-formed CBOR.
+         /* Continue on to get all tags wrapping this item even though
+          * it is erroring out in the end. This allows decoding to
+          * continue. This is a resource limit error, not a problem
+          * with being well-formed CBOR.
+          */
          continue;
       }
-      // Slide tags over one in the array to make room at index 0
-      for(size_t uTagIndex = QCBOR_MAX_TAGS_PER_ITEM - 1; uTagIndex > 0; uTagIndex--) {
-         auTags[uTagIndex] = auTags[uTagIndex-1];
-      }
+      /* Slide tags over one in the array to make room at index 0.
+       * Must use memmove because the move source and destination
+       * overlap.
+       */
+      memmove(&auItemsTags[1], auItemsTags, sizeof(auItemsTags) - sizeof(auItemsTags[0]));
 
-      // Is the tag > 16 bits?
-      if(pDecodedItem->val.uTagV > QCBOR_LAST_UNMAPPED_TAG) {
-         size_t uTagMapIndex;
-         // Is there room in the tag map, or is it in it already?
-         for(uTagMapIndex = 0; uTagMapIndex < QCBOR_NUM_MAPPED_TAGS; uTagMapIndex++) {
-            if(me->auMappedTags[uTagMapIndex] == CBOR_TAG_INVALID16) {
-               break;
-            }
-            if(me->auMappedTags[uTagMapIndex] == pDecodedItem->val.uTagV) {
-               break;
-            }
-         }
-         if(uTagMapIndex >= QCBOR_NUM_MAPPED_TAGS) {
-            // No room for the tag
-            uReturn = QCBOR_ERR_TOO_MANY_TAGS;
-            // Continue on to get all tags on this item even though
-            // it is erroring out in the end. This is a resource limit
-            // error, not a problem with being well-formed CBOR.
-            continue;
-         }
-
-         // Covers the cases where tag is new and were it is already in the map
-         me->auMappedTags[uTagMapIndex] = pDecodedItem->val.uTagV;
-         auTags[0] = (uint16_t)(uTagMapIndex + QCBOR_LAST_UNMAPPED_TAG + 1);
-
-      } else {
-         auTags[0] = (uint16_t)pDecodedItem->val.uTagV;
-      }
+      /* Map the tag */
+      uint16_t uMappedTagNumer;
+      uReturn = MapTagNumber(pMe, pDecodedItem->val.uTagV, &uMappedTagNumer);
+      /* Continue even on error so as to consume all tags wrapping
+       * this data item so decoding can go on. If MapTagNumber()
+       * errors once it will continue to error.
+       */
+      auItemsTags[0] = uMappedTagNumer;
    }
 
 Done:
@@ -1312,70 +1480,73 @@
 }
 
 
-/*
- This layer takes care of map entries. It combines the label and data
- items into one QCBORItem.
-
- @retval QCBOR_ERR_UNSUPPORTED
-
- @retval QCBOR_ERR_HIT_END
-
- @retval QCBOR_ERR_INT_OVERFLOW
-
- @retval QCBOR_ERR_STRING_ALLOCATE
-
- @retval QCBOR_ERR_STRING_TOO_LONG
-
- @retval QCBOR_ERR_HALF_PRECISION_DISABLED
-
- @retval QCBOR_ERR_BAD_TYPE_7
-
- @retval QCBOR_ERR_NO_STRING_ALLOCATOR
-
- @retval QCBOR_ERR_INDEFINITE_STRING_CHUNK
-
- @retval QCBOR_ERR_TOO_MANY_TAGS
-
- @retval QCBOR_ERR_MAP_LABEL_TYPE
-
- @retval QCBOR_ERR_ARRAY_DECODE_TOO_LONG
+/**
+ * @brief Combine a map entry label and value into one item (decode layer 3).
+ *
+ * @param[in] pMe            Decoder context
+ * @param[out] pDecodedItem  The decoded item that work is done on.
+ *
+ * @retval QCBOR_ERR_UNSUPPORTED
+ * @retval QCBOR_ERR_HIT_END
+ * @retval QCBOR_ERR_INT_OVERFLOW
+ * @retval QCBOR_ERR_STRING_ALLOCATE
+ * @retval QCBOR_ERR_STRING_TOO_LONG
+ * @retval QCBOR_ERR_HALF_PRECISION_DISABLED
+ * @retval QCBOR_ERR_BAD_TYPE_7
+ * @retval QCBOR_ERR_INDEF_LEN_ARRAYS_DISABLED
+ * @retval QCBOR_ERR_NO_STRING_ALLOCATOR
+ * @retval QCBOR_ERR_INDEFINITE_STRING_CHUNK
+ * @retval QCBOR_ERR_INDEF_LEN_STRINGS_DISABLED
+ * @retval QCBOR_ERR_TOO_MANY_TAGS
+ * @retval QCBOR_ERR_ARRAY_DECODE_TOO_LONG
+ * @retval QCBOR_ERR_MAP_LABEL_TYPE
+ *
+ * If a the current nesting level is a map, then this
+ * combines pairs of items into one data item with a label
+ * and value.
+ *
+ * This is pass-through if the current nesting leve is
+ * not a map.
+ *
+ * This also implements maps-as-array mode where a map
+ * is treated like an array to allow caller to do their
+ * own label processing.
  */
 static inline QCBORError
-GetNext_MapEntry(QCBORDecodeContext *me, QCBORItem *pDecodedItem)
+QCBORDecode_GetNextMapEntry(QCBORDecodeContext *pMe, QCBORItem *pDecodedItem)
 {
-   // Stack use: int/ptr 1, QCBORItem  -- 56
-   QCBORError nReturn = GetNext_TaggedItem(me, pDecodedItem);
-   if(nReturn)
-      goto Done;
-
-   if(pDecodedItem->uDataType == QCBOR_TYPE_BREAK) {
-      // Break can't be a map entry
+   QCBORError uReturn = QCBORDecode_GetNextTagNumber(pMe, pDecodedItem);
+   if(uReturn != QCBOR_SUCCESS) {
       goto Done;
    }
 
-   if(me->uDecodeMode != QCBOR_DECODE_MODE_MAP_AS_ARRAY) {
-      // In a map and caller wants maps decoded, not treated as arrays
+   if(pDecodedItem->uDataType == QCBOR_TYPE_BREAK) {
+      /* Break can't be a map entry */
+      goto Done;
+   }
 
-      if(DecodeNesting_IsCurrentTypeMap(&(me->nesting))) {
-         // If in a map and the right decoding mode, get the label
+   if(pMe->uDecodeMode != QCBOR_DECODE_MODE_MAP_AS_ARRAY) {
+      /* Normal decoding of maps -- combine label and value into one item. */
 
-         // Save label in pDecodedItem and get the next which will
-         // be the real data
+      if(DecodeNesting_IsCurrentTypeMap(&(pMe->nesting))) {
+         /* Save label in pDecodedItem and get the next which will
+          * be the real data item.
+          */
          QCBORItem LabelItem = *pDecodedItem;
-         nReturn = GetNext_TaggedItem(me, pDecodedItem);
-         if(QCBORDecode_IsUnrecoverableError(nReturn)) {
+         uReturn = QCBORDecode_GetNextTagNumber(pMe, pDecodedItem);
+         if(QCBORDecode_IsUnrecoverableError(uReturn)) {
             goto Done;
          }
 
          pDecodedItem->uLabelAlloc = LabelItem.uDataAlloc;
 
          if(LabelItem.uDataType == QCBOR_TYPE_TEXT_STRING) {
-            // strings are always good labels
+            /* strings are always good labels */
             pDecodedItem->label.string = LabelItem.val.string;
             pDecodedItem->uLabelType = QCBOR_TYPE_TEXT_STRING;
-         } else if (QCBOR_DECODE_MODE_MAP_STRINGS_ONLY == me->uDecodeMode) {
-            // It's not a string and we only want strings
-            nReturn = QCBOR_ERR_MAP_LABEL_TYPE;
+         } else if (QCBOR_DECODE_MODE_MAP_STRINGS_ONLY == pMe->uDecodeMode) {
+            /* It's not a string and we only want strings */
+            uReturn = QCBOR_ERR_MAP_LABEL_TYPE;
             goto Done;
          } else if(LabelItem.uDataType == QCBOR_TYPE_INT64) {
             pDecodedItem->label.int64 = LabelItem.val.int64;
@@ -1388,36 +1559,48 @@
             pDecodedItem->uLabelAlloc = LabelItem.uDataAlloc;
             pDecodedItem->uLabelType = QCBOR_TYPE_BYTE_STRING;
          } else {
-            // label is not an int or a string. It is an arrray
-            // or a float or such and this implementation doesn't handle that.
-            // Also, tags on labels are ignored.
-            nReturn = QCBOR_ERR_MAP_LABEL_TYPE;
+            /* label is not an int or a string. It is an arrray
+             * or a float or such and this implementation doesn't handle that.
+             * Also, tags on labels are ignored.
+             */
+            uReturn = QCBOR_ERR_MAP_LABEL_TYPE;
             goto Done;
          }
       }
    } else {
+      /* Decoding of maps as arrays to let the caller decide what to do
+       * about labels, particularly lables that are not integers or
+       * strings.
+       */
       if(pDecodedItem->uDataType == QCBOR_TYPE_MAP) {
          if(pDecodedItem->val.uCount > QCBOR_MAX_ITEMS_IN_ARRAY/2) {
-            nReturn = QCBOR_ERR_ARRAY_DECODE_TOO_LONG;
+            uReturn = QCBOR_ERR_ARRAY_DECODE_TOO_LONG;
             goto Done;
          }
-         // Decoding a map as an array
          pDecodedItem->uDataType = QCBOR_TYPE_MAP_AS_ARRAY;
-         // Cast is safe because of check against QCBOR_MAX_ITEMS_IN_ARRAY/2
-         // Cast is needed because of integer promotion
+         /* Cast is safe because of check against QCBOR_MAX_ITEMS_IN_ARRAY/2.
+          * Cast is needed because of integer promotion.
+          */
          pDecodedItem->val.uCount = (uint16_t)(pDecodedItem->val.uCount * 2);
       }
    }
 
 Done:
-   return nReturn;
+   return uReturn;
 }
 
 
 #ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS
-/*
- See if next item is a CBOR break. If it is, it is consumed,
- if not it is not consumed.
+/**
+ * @brief Peek and see if next data item is a break;
+ *
+ * @param[in]  pUIB            UsefulInputBuf to read from.
+ * @param[out] pbNextIsBreak   Indicate if next was a break or not.
+ *
+ * @return  Any decoding error.
+ *
+ * See if next item is a CBOR break. If it is, it is consumed,
+ * if not it is not consumed.
 */
 static inline QCBORError
 NextIsBreak(UsefulInputBuf *pUIB, bool *pbNextIsBreak)
@@ -1426,12 +1609,12 @@
    if(UsefulInputBuf_BytesUnconsumed(pUIB) != 0) {
       QCBORItem Peek;
       size_t uPeek = UsefulInputBuf_Tell(pUIB);
-      QCBORError uReturn = GetNext_Item(pUIB, &Peek, NULL);
+      QCBORError uReturn = DecodeAtomicDataItem(pUIB, &Peek, NULL);
       if(uReturn != QCBOR_SUCCESS) {
          return uReturn;
       }
       if(Peek.uDataType != QCBOR_TYPE_BREAK) {
-         // It is not a break, rewind so it can be processed normally.
+         /* It is not a break, rewind so it can be processed normally. */
          UsefulInputBuf_Seek(pUIB, uPeek);
       } else {
          *pbNextIsBreak = true;
@@ -1443,12 +1626,18 @@
 #endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
 
 
-/*
+/**
+ * @brief Ascend up nesting levels if all items in them have been consumed.
+ *
+ * @param[in] pMe       The decode context.
+ * @param[in] bMarkEnd  If true mark end of maps/arrays with count of zero.
+ *
  * An item was just consumed, now figure out if it was the
  * end of an array/map map that can be closed out. That
  * may in turn close out the above array/map...
 */
-static QCBORError NestLevelAscender(QCBORDecodeContext *pMe, bool bMarkEnd)
+static QCBORError
+QCBORDecode_NestLevelAscender(QCBORDecodeContext *pMe, bool bMarkEnd)
 {
    QCBORError uReturn;
 
@@ -1472,7 +1661,7 @@
              /* Didn't close out array/map, so all work here is done */
              break;
           }
-          /* All items in a definite length array were consumed so it
+          /* All items in a definite-length array were consumed so it
            * is time to ascend one level. This happens below.
            */
 
@@ -1492,7 +1681,7 @@
             break;
          }
 
-         /* It was a break in an indefinite length map / array so
+         /* It was a break in an indefinitelength map / array so
           * it is time to ascend one level.
           */
 
@@ -1506,7 +1695,7 @@
        * QCBORDecode_ExitBoundedMode().
        */
       if(DecodeNesting_IsCurrentBounded(&(pMe->nesting))) {
-         /* Set the count to zero for definite length arrays to indicate
+         /* Set the count to zero for definite-length arrays to indicate
          * cursor is at end of bounded array/map */
          if(bMarkEnd) {
             /* Used for definite and indefinite to signal end */
@@ -1530,116 +1719,106 @@
 }
 
 
-/*
- This handles the traversal descending into and asecnding out of maps,
- arrays and bstr-wrapped CBOR. It figures out the ends of definite and
- indefinte length maps and arrays by looking at the item count or
- finding CBOR breaks.  It detects the ends of the top-level sequence
- and of bstr-wrapped CBOR by byte count.
-
- @retval QCBOR_ERR_UNSUPPORTED X
-
- @retval QCBOR_ERR_HIT_END
-
- @retval QCBOR_ERR_INT_OVERFLOW X
-
- @retval QCBOR_ERR_STRING_ALLOCATE
-
- @retval QCBOR_ERR_STRING_TOO_LONG
-
- @retval QCBOR_ERR_HALF_PRECISION_DISABLED X
-
- @retval QCBOR_ERR_BAD_TYPE_7 X
-
- @retval QCBOR_ERR_NO_STRING_ALLOCATOR
-
- @retval QCBOR_ERR_INDEFINITE_STRING_CHUNK
-
- @retval QCBOR_ERR_TOO_MANY_TAGS
-
- @retval QCBOR_ERR_MAP_LABEL_TYPE X
-
- @retval QCBOR_ERR_ARRAY_DECODE_TOO_LONG
-
- @retval QCBOR_ERR_NO_MORE_ITEMS
-
- @retval QCBOR_ERR_BAD_BREAK
-
+/**
+ * @brief Ascending & Descending out of nesting levels (decode layer 2).
+ *
+ * @param[in] pMe            Decoder context
+ * @param[out] pDecodedItem  The decoded item that work is done on.
+ *
+ * @retval QCBOR_ERR_UNSUPPORTED
+ * @retval QCBOR_ERR_HIT_END
+ * @retval QCBOR_ERR_INT_OVERFLOW
+ * @retval QCBOR_ERR_STRING_ALLOCATE
+ * @retval QCBOR_ERR_STRING_TOO_LONG
+ * @retval QCBOR_ERR_HALF_PRECISION_DISABLED
+ * @retval QCBOR_ERR_BAD_TYPE_7
+ * @retval QCBOR_ERR_INDEF_LEN_ARRAYS_DISABLED
+ * @retval QCBOR_ERR_NO_STRING_ALLOCATOR
+ * @retval QCBOR_ERR_INDEFINITE_STRING_CHUNK
+ * @retval QCBOR_ERR_INDEF_LEN_STRINGS_DISABLED
+ * @retval QCBOR_ERR_TOO_MANY_TAGS
+ * @retval QCBOR_ERR_ARRAY_DECODE_TOO_LONG
+ * @retval QCBOR_ERR_MAP_LABEL_TYPE
+ * @retval QCBOR_ERR_NO_MORE_ITEMS
+ * @retval QCBOR_ERR_BAD_BREAK
+ * @retval QCBOR_ERR_ARRAY_DECODE_NESTING_TOO_DEEP
+ *
+ * This handles the traversal descending into and asecnding out of
+ * maps, arrays and bstr-wrapped CBOR. It figures out the ends of
+ * definite- and indefinte-length maps and arrays by looking at the
+ * 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
-QCBORDecode_GetNextMapOrArray(QCBORDecodeContext *me, QCBORItem *pDecodedItem)
+QCBORDecode_GetNextMapOrArray(QCBORDecodeContext *pMe, QCBORItem *pDecodedItem)
 {
    QCBORError uReturn;
    /* ==== First: figure out if at the end of a traversal ==== */
 
-   /*
-    If out of bytes to consume, it is either the end of the top-level
-    sequence of some bstr-wrapped CBOR that was entered.
-
-    In the case of bstr-wrapped CBOR, the length of the UsefulInputBuf
-    was set to that of the bstr-wrapped CBOR. When the bstr-wrapped
-    CBOR is exited, the length is set back to the top-level's length
-    or to the next highest bstr-wrapped CBOR.
+   /* If out of bytes to consume, it is either the end of the
+    * top-level sequence of some bstr-wrapped CBOR that was entered.
+    *
+    * In the case of bstr-wrapped CBOR, the length of the
+    * UsefulInputBuf was set to that of the bstr-wrapped CBOR. When
+    * the bstr-wrapped CBOR is exited, the length is set back to the
+    * top-level's length or to the next highest bstr-wrapped CBOR.
    */
-   if(UsefulInputBuf_BytesUnconsumed(&(me->InBuf)) == 0) {
+   if(UsefulInputBuf_BytesUnconsumed(&(pMe->InBuf)) == 0) {
       uReturn = QCBOR_ERR_NO_MORE_ITEMS;
       goto Done;
    }
 
-   /*
-    Check to see if at the end of a bounded definite length map or
-    array. The check for a break ending indefinite length array is
-    later in NestLevelAscender().
+   /* Check to see if at the end of a bounded definite-length map or
+    * array. The check for a break ending indefinite-length array is
+    * later in QCBORDecode_NestLevelAscender().
     */
-   if(DecodeNesting_IsAtEndOfBoundedLevel(&(me->nesting))) {
+   if(DecodeNesting_IsAtEndOfBoundedLevel(&(pMe->nesting))) {
       uReturn = QCBOR_ERR_NO_MORE_ITEMS;
       goto Done;
    }
 
    /* ==== Next: not at the end, so get another item ==== */
-   uReturn = GetNext_MapEntry(me, pDecodedItem);
+   uReturn = QCBORDecode_GetNextMapEntry(pMe, pDecodedItem);
    if(QCBORDecode_IsUnrecoverableError(uReturn)) {
       /* Error is so bad that traversal is not possible. */
       goto Done;
    }
 
-   /*
-    Breaks ending arrays/maps are processed later in the call to
-    NestLevelAscender(). They should never show up here.
+   /* Breaks ending arrays/maps are processed later in the call to
+    * QCBORDecode_NestLevelAscender(). They should never show up here.
     */
    if(pDecodedItem->uDataType == QCBOR_TYPE_BREAK) {
       uReturn = QCBOR_ERR_BAD_BREAK;
       goto Done;
    }
 
-   /*
-     Record the nesting level for this data item before processing any
-     of decrementing and descending.
+   /* Record the nesting level for this data item before processing
+    * any of decrementing and descending.
     */
-   pDecodedItem->uNestingLevel = DecodeNesting_GetCurrentLevel(&(me->nesting));
+   pDecodedItem->uNestingLevel = DecodeNesting_GetCurrentLevel(&(pMe->nesting));
 
 
    /* ==== Next: Process the item for descent, ascent, decrement... ==== */
    if(QCBORItem_IsMapOrArray(pDecodedItem)) {
-      /*
-       If the new item is a map or array, descend.
-
-       Empty indefinite length maps and arrays are descended into, but
-       then ascended out of in the next chunk of code.
-
-       Maps and arrays do count as items in the map/array that
-       encloses them so a decrement needs to be done for them too, but
-       that is done only when all the items in them have been
-       processed, not when they are opened with the exception of an
-       empty map or array.
+      /* If the new item is a map or array, descend.
+       *
+       * Empty indefinite-length maps and arrays are descended into,
+       * but then ascended out of in the next chunk of code.
+       *
+       * Maps and arrays do count as items in the map/array that
+       * encloses them so a decrement needs to be done for them too,
+       * but that is done only when all the items in them have been
+       * processed, not when they are opened with the exception of an
+       * empty map or array.
        */
       QCBORError uDescendErr;
-      uDescendErr = DecodeNesting_DescendMapOrArray(&(me->nesting),
+      uDescendErr = DecodeNesting_DescendMapOrArray(&(pMe->nesting),
                                                 pDecodedItem->uDataType,
                                                 pDecodedItem->val.uCount);
       if(uDescendErr != QCBOR_SUCCESS) {
-         /* This error is probably a traversal error and it
-          overrides the non-traversal error. */
+         /* This error is probably a traversal error and it overrides
+          * the non-traversal error.
+          */
          uReturn = uDescendErr;
          goto Done;
       }
@@ -1648,58 +1827,79 @@
    if(!QCBORItem_IsMapOrArray(pDecodedItem) ||
        QCBORItem_IsEmptyDefiniteLengthMapOrArray(pDecodedItem) ||
        QCBORItem_IsIndefiniteLengthMapOrArray(pDecodedItem)) {
-      /*
-       The following cases are handled here:
-         - A non-aggregate item like an integer or string
-         - An empty definite length map or array
-         - An indefinite length map or array that might be empty or might not.
-
-       NestLevelAscender() does the work of decrementing the count for an
-       definite length map/array and break detection for an indefinite
-       length map/array. If the end of the map/array was reached, then
-       it ascends nesting levels, possibly all the way to the top level.
+      /* The following cases are handled here:
+       *  - A non-aggregate item like an integer or string
+       *  - An empty definite-length map or array
+       *  - An indefinite-length map or array that might be empty or might not.
+       *
+       * QCBORDecode_NestLevelAscender() does the work of decrementing the count
+       * for an definite-length map/array and break detection for an
+       * indefinite-0length map/array. If the end of the map/array was
+       * reached, then it ascends nesting levels, possibly all the way
+       * to the top level.
        */
       QCBORError uAscendErr;
-      uAscendErr = NestLevelAscender(me, true);
+      uAscendErr = QCBORDecode_NestLevelAscender(pMe, true);
       if(uAscendErr != QCBOR_SUCCESS) {
-         /* This error is probably a traversal error and it
-          overrides the non-traversal error. */
+         /* This error is probably a traversal error and it overrides
+          * the non-traversal error.
+          */
          uReturn = uAscendErr;
          goto Done;
       }
    }
 
    /* ==== Last: tell the caller the nest level of the next item ==== */
-   /*
-    Tell the caller what level is next. This tells them what
-    maps/arrays were closed out and makes it possible for them to
-    reconstruct the tree with just the information returned in
-    a QCBORItem.
+   /* Tell the caller what level is next. This tells them what
+    * maps/arrays were closed out and makes it possible for them to
+    * reconstruct the tree with just the information returned in a
+    * QCBORItem.
    */
-   if(DecodeNesting_IsAtEndOfBoundedLevel(&(me->nesting))) {
+   if(DecodeNesting_IsAtEndOfBoundedLevel(&(pMe->nesting))) {
       /* At end of a bounded map/array; uNextNestLevel 0 to indicate this */
       pDecodedItem->uNextNestLevel = 0;
    } else {
-      pDecodedItem->uNextNestLevel = DecodeNesting_GetCurrentLevel(&(me->nesting));
+      pDecodedItem->uNextNestLevel = DecodeNesting_GetCurrentLevel(&(pMe->nesting));
    }
 
 Done:
    return uReturn;
 }
 
-static void ShiftTags(QCBORItem *pDecodedItem)
+
+/**
+ * @brief Shift 0th tag out of the tag list.
+ *
+ * pDecodedItem[in,out]  The data item to convert.
+ *
+ * The 0th tag is discarded. \ref CBOR_TAG_INVALID16 is
+ * shifted into empty slot at the end of the tag list.
+ */
+static inline void ShiftTags(QCBORItem *pDecodedItem)
 {
-   pDecodedItem->uTags[0] = pDecodedItem->uTags[1];
-   pDecodedItem->uTags[1] = pDecodedItem->uTags[2];
-   pDecodedItem->uTags[2] = pDecodedItem->uTags[3];
-   pDecodedItem->uTags[2] = CBOR_TAG_INVALID16;
+   for(int i = 0; i < QCBOR_MAX_TAGS_PER_ITEM-1; i++) {
+      pDecodedItem->uTags[i] = pDecodedItem->uTags[i+1];
+   }
+   pDecodedItem->uTags[QCBOR_MAX_TAGS_PER_ITEM-1] = CBOR_TAG_INVALID16;
 }
 
 
-
-/*
- The epoch formatted date. Turns lots of different forms of encoding
- date into uniform one
+/**
+ * @brief Convert different epoch date formats in to the QCBOR epoch date format
+ *
+ * pDecodedItem[in,out]  The data item to convert.
+ *
+ * @retval QCBOR_ERR_DATE_OVERFLOW
+ * @retval QCBOR_ERR_FLOAT_DATE_DISABLED
+ * @retval QCBOR_ERR_BAD_TAG_CONTENT
+ *
+ * The epoch date tag defined in QCBOR allows for floating-point
+ * dates. It even allows a protocol to flop between date formats when
+ * ever it wants.  Floating-point dates aren't that useful as they are
+ * only needed for dates beyond the age of the earth.
+ *
+ * This converts all the date formats into one format of an unsigned
+ * integer plus a floating-point fraction.
  */
 static QCBORError DecodeDateEpoch(QCBORItem *pDecodedItem)
 {
@@ -1714,8 +1914,9 @@
          break;
 
       case QCBOR_TYPE_UINT64:
-         // This only happens for CBOR type 0 > INT64_MAX so it is
-         // always an overflow.
+         /* This only happens for CBOR type 0 > INT64_MAX so it is
+          * always an overflow.
+          */
          uReturn = QCBOR_ERR_DATE_OVERFLOW;
          goto Done;
          break;
@@ -1724,42 +1925,47 @@
       case QCBOR_TYPE_FLOAT:
 #ifndef QCBOR_DISABLE_FLOAT_HW_USE
       {
-         // This comparison needs to be done as a float before
-         // conversion to an int64_t to be able to detect doubles that
-         // are too large to fit into an int64_t.  A double has 52
-         // bits of preceision. An int64_t has 63. Casting INT64_MAX
-         // to a double actually causes a round up which is bad and
-         // wrong for the comparison because it will allow conversion
-         // of doubles that can't fit into a uint64_t.  To remedy this
-         // INT64_MAX - 0x7ff is used as the cutoff point because if
-         // that value rounds up in conversion to double it will still
-         // be less than INT64_MAX. 0x7ff is picked because it has 11
-         // bits set.
-         //
-         // INT64_MAX seconds is on the order of 10 billion years, and
-         // the earth is less than 5 billion years old, so for most
-         // uses this conversion error won't occur even though doubles
-         // can go much larger.
-         //
-         // Without the 0x7ff there is a ~30 minute range of time
-         // values 10 billion years in the past and in the future
-         // where this code would go wrong. Some compilers
-         // will generate warnings or errors without the 0x7ff
-         // because of the precision issue.
+         /* Convert working value to double if input was a float */
          const double d = pDecodedItem->uDataType == QCBOR_TYPE_DOUBLE ?
-                            pDecodedItem->val.dfnum :
-                            (double)pDecodedItem->val.fnum;
-         if(isnan(d) ||
-            d > (double)(INT64_MAX - 0x7ff) ||
-            d < (double)(INT64_MIN + 0x7ff)) {
+                   pDecodedItem->val.dfnum :
+                   (double)pDecodedItem->val.fnum;
+
+         /* The conversion from float to integer requires overflow
+          * detection since floats can be much larger than integers.
+          * This implementation errors out on these large float values
+          * since they are beyond the age of the earth.
+          *
+          * These constants for the overflow check are computed by the
+          * compiler. They are not computed at run time.
+          *
+          * The factor of 0x7ff is added/subtracted to avoid a
+          * rounding error in the wrong direction when the compiler
+          * computes these constants. There is rounding because an
+          * 64-bit integer has 63 bits of precision where a double
+          * only has 53 bits. Without the 0x7ff factor, the compiler
+          * may round up and produce a double for the bounds check
+          * that is larger than can be stored in a 64-bit integer. The
+          * amount of 0x7ff is picked because it has 11 bits set.
+          *
+          * Without the 0x7ff there is a ~30 minute range of time
+          * values 10 billion years in the past and in the future
+          * where this code could go wrong. Some compilers correctly
+          * generate a warning or error without the 0x7ff.
+          */
+         const double dDateMax = (double)(INT64_MAX - 0x7ff);
+         const double dDateMin = (double)(INT64_MIN + 0x7ff);
+
+         if(isnan(d) || d > dDateMax || d < dDateMin) {
             uReturn = QCBOR_ERR_DATE_OVERFLOW;
             goto Done;
          }
+
+         /* The actual conversion */
          pDecodedItem->val.epochDate.nSeconds = (int64_t)d;
          pDecodedItem->val.epochDate.fSecondsFraction =
                            d - (double)pDecodedItem->val.epochDate.nSeconds;
       }
-#else
+#else /* QCBOR_DISABLE_FLOAT_HW_USE */
 
          uReturn = QCBOR_ERR_FLOAT_DATE_DISABLED;
          goto Done;
@@ -1768,7 +1974,7 @@
          break;
 
       default:
-         uReturn = QCBOR_ERR_BAD_OPT_TAG;
+         uReturn = QCBOR_ERR_BAD_TAG_CONTENT;
          goto Done;
    }
 
@@ -1780,107 +1986,128 @@
 
 
 #ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
-/*
- Decode decimal fractions and big floats.
-
- When called pDecodedItem must be the array that is tagged as a big
- float or decimal fraction, the array that has the two members, the
- exponent and mantissa.
-
- This will fetch and decode the exponent and mantissa and put the
- result back into pDecodedItem.
+/**
+ * @brief Decode decimal fractions and big floats.
+ *
+ * @param[in] pMe               The decode context.
+ * @param[in,out] pDecodedItem  On input the array data item that
+ *                              holds the mantissa and exponent.  On
+ *                              output the decoded mantissa and
+ *                              exponent.
+ *
+ * @returns  Decoding errors from getting primitive data items or
+ *           \ref QCBOR_ERR_BAD_EXP_AND_MANTISSA.
+ *
+ * When called pDecodedItem must be the array that is tagged as a big
+ * float or decimal fraction, the array that has the two members, the
+ * exponent and mantissa.
+ *
+ * This will fetch and decode the exponent and mantissa and put the
+ * result back into pDecodedItem.
  */
 static inline QCBORError
-QCBORDecode_MantissaAndExponent(QCBORDecodeContext *me, QCBORItem *pDecodedItem)
+QCBORDecode_MantissaAndExponent(QCBORDecodeContext *pMe, QCBORItem *pDecodedItem)
 {
-   QCBORError nReturn;
+   QCBORError uReturn;
 
-   // --- Make sure it is an array; track nesting level of members ---
+   /* --- Make sure it is an array; track nesting level of members --- */
    if(pDecodedItem->uDataType != QCBOR_TYPE_ARRAY) {
-      nReturn = QCBOR_ERR_BAD_EXP_AND_MANTISSA;
+      uReturn = QCBOR_ERR_BAD_EXP_AND_MANTISSA;
       goto Done;
    }
 
-   // A check for pDecodedItem->val.uCount == 2 would work for
-   // definite length arrays, but not for indefnite.  Instead remember
-   // the nesting level the two integers must be at, which is one
-   // deeper than that of the array.
+   /* A check for pDecodedItem->val.uCount == 2 would work for
+    * definite-length arrays, but not for indefnite.  Instead remember
+    * the nesting level the two integers must be at, which is one
+    * deeper than that of the array.
+    */
    const int nNestLevel = pDecodedItem->uNestingLevel + 1;
 
-   // --- Is it a decimal fraction or a bigfloat? ---
-   const bool bIsTaggedDecimalFraction = QCBORDecode_IsTagged(me, pDecodedItem, CBOR_TAG_DECIMAL_FRACTION);
+   /* --- Which is it, decimal fraction or a bigfloat? --- */
+   const bool bIsTaggedDecimalFraction = QCBORDecode_IsTagged(pMe, pDecodedItem, CBOR_TAG_DECIMAL_FRACTION);
    pDecodedItem->uDataType = bIsTaggedDecimalFraction ? QCBOR_TYPE_DECIMAL_FRACTION : QCBOR_TYPE_BIGFLOAT;
 
-   // --- Get the exponent ---
+   /* --- Get the exponent --- */
    QCBORItem exponentItem;
-   nReturn = QCBORDecode_GetNextMapOrArray(me, &exponentItem);
-   if(nReturn != QCBOR_SUCCESS) {
+   uReturn = QCBORDecode_GetNextMapOrArray(pMe, &exponentItem);
+   if(uReturn != QCBOR_SUCCESS) {
       goto Done;
    }
    if(exponentItem.uNestingLevel != nNestLevel) {
-      // Array is empty or a map/array encountered when expecting an int
-      nReturn = QCBOR_ERR_BAD_EXP_AND_MANTISSA;
+      /* Array is empty or a map/array encountered when expecting an int */
+      uReturn = QCBOR_ERR_BAD_EXP_AND_MANTISSA;
       goto Done;
    }
    if(exponentItem.uDataType == QCBOR_TYPE_INT64) {
-     // Data arriving as an unsigned int < INT64_MAX has been converted
-     // to QCBOR_TYPE_INT64 and thus handled here. This is also means
-     // that the only data arriving here of type QCBOR_TYPE_UINT64 data
-     // will be too large for this to handle and thus an error that will
-     // get handled in the next else.
+     /* Data arriving as an unsigned int < INT64_MAX has been
+      * converted to QCBOR_TYPE_INT64 and thus handled here. This is
+      * also means that the only data arriving here of type
+      * QCBOR_TYPE_UINT64 data will be too large for this to handle
+      * and thus an error that will get handled in the next else.
+      */
      pDecodedItem->val.expAndMantissa.nExponent = exponentItem.val.int64;
    } else {
-      // Wrong type of exponent or a QCBOR_TYPE_UINT64 > INT64_MAX
-      nReturn = QCBOR_ERR_BAD_EXP_AND_MANTISSA;
+      /* Wrong type of exponent or a QCBOR_TYPE_UINT64 > INT64_MAX */
+      uReturn = QCBOR_ERR_BAD_EXP_AND_MANTISSA;
       goto Done;
    }
 
-   // --- Get the mantissa ---
+   /* --- Get the mantissa --- */
    QCBORItem mantissaItem;
-   nReturn = QCBORDecode_GetNextWithTags(me, &mantissaItem, NULL);
-   if(nReturn != QCBOR_SUCCESS) {
+   uReturn = QCBORDecode_GetNextWithTags(pMe, &mantissaItem, NULL);
+   if(uReturn != QCBOR_SUCCESS) {
       goto Done;
    }
    if(mantissaItem.uNestingLevel != nNestLevel) {
-      // Mantissa missing or map/array encountered when expecting number
-      nReturn = QCBOR_ERR_BAD_EXP_AND_MANTISSA;
+      /* Mantissa missing or map/array encountered when expecting number */
+      uReturn = QCBOR_ERR_BAD_EXP_AND_MANTISSA;
       goto Done;
    }
    if(mantissaItem.uDataType == QCBOR_TYPE_INT64) {
-      // Data arriving as an unsigned int < INT64_MAX has been converted
-      // to QCBOR_TYPE_INT64 and thus handled here. This is also means
-      // that the only data arriving here of type QCBOR_TYPE_UINT64 data
-      // will be too large for this to handle and thus an error that
-      // will get handled in an else below.
+      /* Data arriving as an unsigned int < INT64_MAX has been
+       * converted to QCBOR_TYPE_INT64 and thus handled here. This is
+       * also means that the only data arriving here of type
+       * QCBOR_TYPE_UINT64 data will be too large for this to handle
+       * and thus an error that will get handled in an else below.
+       */
       pDecodedItem->val.expAndMantissa.Mantissa.nInt = mantissaItem.val.int64;
    }  else if(mantissaItem.uDataType == QCBOR_TYPE_POSBIGNUM ||
               mantissaItem.uDataType == QCBOR_TYPE_NEGBIGNUM) {
-      // Got a good big num mantissa
+      /* Got a good big num mantissa */
       pDecodedItem->val.expAndMantissa.Mantissa.bigNum = mantissaItem.val.bigNum;
-      // Depends on numbering of QCBOR_TYPE_XXX
+      /* Depends on numbering of QCBOR_TYPE_XXX */
       pDecodedItem->uDataType = (uint8_t)(pDecodedItem->uDataType +
                                           mantissaItem.uDataType - QCBOR_TYPE_POSBIGNUM +
                                           1);
    } else {
-      // Wrong type of mantissa or a QCBOR_TYPE_UINT64 > INT64_MAX
-      nReturn = QCBOR_ERR_BAD_EXP_AND_MANTISSA;
+      /* Wrong type of mantissa or a QCBOR_TYPE_UINT64 > INT64_MAX */
+      uReturn = QCBOR_ERR_BAD_EXP_AND_MANTISSA;
       goto Done;
    }
 
-   // --- Check that array only has the two numbers ---
+   /* --- Check that array only has the two numbers --- */
    if(mantissaItem.uNextNestLevel == nNestLevel) {
-      // Extra items in the decimal fraction / big float
-      nReturn = QCBOR_ERR_BAD_EXP_AND_MANTISSA;
+      /* Extra items in the decimal fraction / big float */
+      uReturn = QCBOR_ERR_BAD_EXP_AND_MANTISSA;
       goto Done;
    }
    pDecodedItem->uNextNestLevel = mantissaItem.uNextNestLevel;
 
 Done:
-  return nReturn;
+  return uReturn;
 }
 #endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
 
 
+/**
+ * @brief Decode the MIME type tag
+ *
+ * @param[in,out] pDecodedItem   The item to decode.
+ *
+ *  Handle the text and binary MIME type tags. Slightly too complicated
+ *  f or ProcessTaggedString() because the RFC 7049 MIME type was
+ *  incorreclty text-only.
+ */
 static inline QCBORError DecodeMIME(QCBORItem *pDecodedItem)
 {
    if(pDecodedItem->uDataType == QCBOR_TYPE_TEXT_STRING) {
@@ -1889,14 +2116,13 @@
       pDecodedItem->uDataType = QCBOR_TYPE_BINARY_MIME;
    } else {
       return QCBOR_ERR_BAD_OPT_TAG;
-
    }
 
    return QCBOR_SUCCESS;
 }
 
 
-/*
+/**
  * Table of CBOR tags whose content is either a text string or a byte
  * string. The table maps the CBOR tag to the QCBOR type. The high-bit
  * of uQCBORtype indicates the content should be a byte string rather
@@ -1925,7 +2151,16 @@
 };
 
 
-/*
+/**
+ * @brief Process standard CBOR tags whose content is a string
+ *
+ * @param[in] uTag              The tag.
+ * @param[in,out] pDecodedItem  The data item.
+ *
+ * @returns  This returns QCBOR_SUCCESS if the tag was procssed,
+ *           \ref QCBOR_ERR_UNSUPPORTED if the tag was not processed and
+ *           \ref QCBOR_ERR_BAD_OPT_TAG if the content type was wrong for the tag.
+ *
  * Process the CBOR tags that whose content is a byte string or a text
  * string and for which the string is just passed on to the caller.
  *
@@ -1933,13 +2168,9 @@
  * type.  Nothing more. It may not be the most important
  * functionality, but it part of implementing as much of RFC 8949 as
  * possible.
- *
- * This returns QCBOR_SUCCESS if the tag was procssed,
- * QCBOR_ERR_UNSUPPORTED if the tag was not processed and
- * QCBOR_ERR_BAD_OPT_TAG if the content type was wrong for the tag.
  */
-static inline
-QCBORError ProcessTaggedString(uint16_t uTag, QCBORItem *pDecodedItem)
+static inline QCBORError
+ProcessTaggedString(uint16_t uTag, QCBORItem *pDecodedItem)
 {
    /* This only works on tags that were not mapped; no need for other yet */
    if(uTag > QCBOR_LAST_UNMAPPED_TAG) {
@@ -1973,18 +2204,25 @@
 }
 
 
-/*
+/**
+ * @brief Decode tag content for select tags (decoding layer 1).
+ *
+ * @param[in] pMe            The decode context.
+ * @param[out] pDecodedItem  The decoded item.
+ *
+ * @return Decoding error code.
+ *
  * CBOR tag numbers for the item were decoded in GetNext_TaggedItem(),
  * but the whole tag was not decoded. Here, the whole tags (tag number
  * and tag content) that are supported by QCBOR are decoded. This is a
  * quick pass through for items that are not tags.
  */
 static QCBORError
-QCBORDecode_GetNextTag(QCBORDecodeContext *me, QCBORItem *pDecodedItem)
+QCBORDecode_GetNextTagContent(QCBORDecodeContext *pMe, QCBORItem *pDecodedItem)
 {
    QCBORError uReturn;
 
-   uReturn = QCBORDecode_GetNextMapOrArray(me, pDecodedItem);
+   uReturn = QCBORDecode_GetNextMapOrArray(pMe, pDecodedItem);
    if(uReturn != QCBOR_SUCCESS) {
       goto Done;
    }
@@ -2014,7 +2252,7 @@
 #ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
       } else if(uTagToProcess == CBOR_TAG_DECIMAL_FRACTION ||
                 uTagToProcess == CBOR_TAG_BIGFLOAT) {
-         uReturn = QCBORDecode_MantissaAndExponent(me, pDecodedItem);
+         uReturn = QCBORDecode_MantissaAndExponent(pMe, pDecodedItem);
 #endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
 
       } else if(uTagToProcess == CBOR_TAG_MIME ||
@@ -2052,13 +2290,13 @@
 
 
 /*
- Public function, see header qcbor/qcbor_decode.h file
+ * Public function, see header qcbor/qcbor_decode.h file
  */
 QCBORError
 QCBORDecode_GetNext(QCBORDecodeContext *pMe, QCBORItem *pDecodedItem)
 {
    QCBORError uErr;
-   uErr = QCBORDecode_GetNextTag(pMe, pDecodedItem);
+   uErr = QCBORDecode_GetNextTagContent(pMe, pDecodedItem);
    if(uErr != QCBOR_SUCCESS) {
       pDecodedItem->uDataType  = QCBOR_TYPE_NONE;
       pDecodedItem->uLabelType = QCBOR_TYPE_NONE;
@@ -2068,7 +2306,7 @@
 
 
 /*
- Public function, see header qcbor/qcbor_decode.h file
+ * Public function, see header qcbor/qcbor_decode.h file
  */
 QCBORError
 QCBORDecode_PeekNext(QCBORDecodeContext *pMe, QCBORItem *pDecodedItem)
@@ -2086,7 +2324,7 @@
 
 
 /*
- Public function, see header qcbor/qcbor_decode.h file
+ * Public function, see header qcbor/qcbor_decode.h file
  */
 void QCBORDecode_VGetNext(QCBORDecodeContext *pMe, QCBORItem *pDecodedItem)
 {
@@ -2099,24 +2337,23 @@
 
 
 /*
- Public function, see header qcbor/qcbor_decode.h file
+ * Public function, see header qcbor/qcbor_decode.h file
  */
 QCBORError
-QCBORDecode_GetNextWithTags(QCBORDecodeContext *me,
-                            QCBORItem *pDecodedItem,
-                            QCBORTagListOut *pTags)
+QCBORDecode_GetNextWithTags(QCBORDecodeContext *pMe,
+                            QCBORItem          *pDecodedItem,
+                            QCBORTagListOut    *pTags)
 {
-   QCBORError nReturn;
+   QCBORError uReturn;
 
-   nReturn = QCBORDecode_GetNext(me, pDecodedItem);
-   if(nReturn != QCBOR_SUCCESS) {
-      return nReturn;
+   uReturn = QCBORDecode_GetNext(pMe, pDecodedItem);
+   if(uReturn != QCBOR_SUCCESS) {
+      return uReturn;
    }
 
    if(pTags != NULL) {
       pTags->uNumUsed = 0;
-      // Reverse the order because pTags is reverse of
-      // QCBORItem.uTags.
+      /* Reverse the order because pTags is reverse of QCBORItem.uTags. */
       for(int nTagIndex = QCBOR_MAX_TAGS_PER_ITEM-1; nTagIndex >=0; nTagIndex--) {
          if(pDecodedItem->uTags[nTagIndex] == CBOR_TAG_INVALID16) {
             continue;
@@ -2124,7 +2361,7 @@
          if(pTags->uNumUsed >= pTags->uNumAllocated) {
             return QCBOR_ERR_TOO_MANY_TAGS;
          }
-         pTags->puTags[pTags->uNumUsed] = ConvertTag(me,pDecodedItem->uTags[nTagIndex]);
+         pTags->puTags[pTags->uNumUsed] = UnMapTagNumber(pMe,pDecodedItem->uTags[nTagIndex]);
          pTags->uNumUsed++;
       }
    }
@@ -2134,52 +2371,9 @@
 
 
 /*
- Decoding items is done in 5 layered functions, one calling the
- next one down. If a layer has no work to do for a particular item
- it returns quickly.
-
- - QCBORDecode_GetNext, GetNextWithTags -- The top layer processes
- tagged data items, turning them into the local C representation.
- For the most simple it is just associating a QCBOR_TYPE with the data. For
- the complex ones that an aggregate of data items, there is some further
- decoding and a little bit of recursion.
-
- - QCBORDecode_GetNextMapOrArray - This manages the beginnings and
- ends of maps and arrays. It tracks descending into and ascending
- out of maps/arrays. It processes all breaks that terminate
- indefinite length maps and arrays.
-
- - GetNext_MapEntry -- This handles the combining of two
- items, the label and the data, that make up a map entry.
- It only does work on maps. It combines the label and data
- items into one labeled item.
-
- - GetNext_TaggedItem -- This decodes type 6 tagging. It turns the
- tags into bit flags associated with the data item. No actual decoding
- of the contents of the tagged item is performed here.
-
- - GetNext_FullItem -- This assembles the sub-items that make up
- an indefinte length string into one string item. It uses the
- string allocater to create contiguous space for the item. It
- processes all breaks that are part of indefinite length strings.
-
- - GetNext_Item -- This decodes the atomic data items in CBOR. Each
- atomic data item has a "major type", an integer "argument" and optionally
- some content. For text and byte strings, the content is the bytes
- that make up the string. These are the smallest data items that are
- considered to be well-formed.  The content may also be other data items in
- the case of aggregate types. They are not handled in this layer.
-
- Roughly this takes 300 bytes of stack for vars. Need to
- evaluate this more carefully and correctly.
-
+ * Public function, see header qcbor/qcbor_decode.h file
  */
-
-
-/*
- Public function, see header qcbor/qcbor_decode.h file
- */
-bool QCBORDecode_IsTagged(QCBORDecodeContext *me,
+bool QCBORDecode_IsTagged(QCBORDecodeContext *pMe,
                           const QCBORItem   *pItem,
                           uint64_t           uTag)
 {
@@ -2187,7 +2381,7 @@
       if(pItem->uTags[uTagIndex] == CBOR_TAG_INVALID16) {
          break;
       }
-      if(ConvertTag(me, pItem->uTags[uTagIndex]) == uTag) {
+      if(UnMapTagNumber(pMe, pItem->uTags[uTagIndex]) == uTag) {
          return true;
       }
    }
@@ -2197,32 +2391,33 @@
 
 
 /*
- Public function, see header qcbor/qcbor_decode.h file
+ * Public function, see header qcbor/qcbor_decode.h file
  */
-QCBORError QCBORDecode_Finish(QCBORDecodeContext *me)
+QCBORError QCBORDecode_Finish(QCBORDecodeContext *pMe)
 {
-   QCBORError uReturn = me->uLastError;
+   QCBORError uReturn = pMe->uLastError;
 
    if(uReturn != QCBOR_SUCCESS) {
       goto Done;
    }
 
-   // Error out if all the maps/arrays are not closed out
-   if(!DecodeNesting_IsCurrentAtTop(&(me->nesting))) {
+   /* Error out if all the maps/arrays are not closed out */
+   if(!DecodeNesting_IsCurrentAtTop(&(pMe->nesting))) {
       uReturn = QCBOR_ERR_ARRAY_OR_MAP_UNCONSUMED;
       goto Done;
    }
 
-   // Error out if not all the bytes are consumed
-   if(UsefulInputBuf_BytesUnconsumed(&(me->InBuf))) {
+   /* Error out if not all the bytes are consumed */
+   if(UsefulInputBuf_BytesUnconsumed(&(pMe->InBuf))) {
       uReturn = QCBOR_ERR_EXTRA_BYTES;
    }
 
 Done:
 #ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS
-   // Call the destructor for the string allocator if there is one.
-   // Always called, even if there are errors; always have to clean up
-   StringAllocator_Destruct(&(me->StringAllocator));
+   /* Call the destructor for the string allocator if there is one.
+    * Always called, even if there are errors; always have to clean up.
+    */
+   StringAllocator_Destruct(&(pMe->StringAllocator));
 #endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS */
 
    return uReturn;
@@ -2230,8 +2425,8 @@
 
 
 /*
- Public function, see header qcbor/qcbor_decode.h file
-*/
+ * Public function, see header qcbor/qcbor_decode.h file
+ */
 // Improvement: make these inline?
 uint64_t QCBORDecode_GetNthTag(QCBORDecodeContext *pMe,
                                const QCBORItem    *pItem,
@@ -2243,13 +2438,14 @@
    if(uIndex >= QCBOR_MAX_TAGS_PER_ITEM) {
       return CBOR_TAG_INVALID64;
    } else {
-      return ConvertTag(pMe, pItem->uTags[uIndex]);
+      return UnMapTagNumber(pMe, pItem->uTags[uIndex]);
    }
 }
 
+
 /*
- Public function, see header qcbor/qcbor_decode.h file
-*/
+ * Public function, see header qcbor/qcbor_decode.h file
+ */
 uint64_t QCBORDecode_GetNthTagOfLast(const QCBORDecodeContext *pMe,
                                      uint32_t                  uIndex)
 {
@@ -2259,40 +2455,10 @@
    if(uIndex >= QCBOR_MAX_TAGS_PER_ITEM) {
       return CBOR_TAG_INVALID64;
    } else {
-      return ConvertTag(pMe, pMe->uLastTags[uIndex]);
+      return UnMapTagNumber(pMe, pMe->uLastTags[uIndex]);
    }
 }
 
-/*
-
-Decoder errors handled in this file
-
- - Hit end of input before it was expected while decoding type and
-   number QCBOR_ERR_HIT_END
-
- - negative integer that is too large for C QCBOR_ERR_INT_OVERFLOW
-
- - Hit end of input while decoding a text or byte string
-   QCBOR_ERR_HIT_END
-
- - Encountered conflicting tags -- e.g., an item is tagged both a date
-   string and an epoch date QCBOR_ERR_UNSUPPORTED
-
- - Encontered an array or mapp that has too many items
-   QCBOR_ERR_ARRAY_DECODE_TOO_LONG
-
- - Encountered array/map nesting that is too deep
-   QCBOR_ERR_ARRAY_DECODE_NESTING_TOO_DEEP
-
- - An epoch date > INT64_MAX or < INT64_MIN was encountered
-   QCBOR_ERR_DATE_OVERFLOW
-
- - The type of a map label is not a string or int
-   QCBOR_ERR_MAP_LABEL_TYPE
-
- - Hit end with arrays or maps still open -- QCBOR_ERR_EXTRA_BYTES
-
- */
 
 
 
@@ -2301,7 +2467,7 @@
 /* ===========================================================================
    MemPool -- BUILT-IN SIMPLE STRING ALLOCATOR
 
-   This implements a simple sting allocator for indefinite length
+   This implements a simple sting allocator for indefinite-length
    strings that can be enabled by calling QCBORDecode_SetMemPool(). It
    implements the function type QCBORStringAllocate and allows easy
    use of it.
@@ -2505,7 +2671,7 @@
    if(QCBORItem_IsMapOrArray(pItemToConsume) && !bIsEmpty) {
       /* There is only real work to do for non-empty maps and arrays */
 
-      /* This works for definite and indefinite length
+      /* This works for definite- and indefinite- length
        * maps and arrays by using the nesting level
        */
       do {
@@ -2658,7 +2824,7 @@
    /*
     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
+    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.
 
@@ -2680,7 +2846,7 @@
 
       /* Get the item */
       QCBORItem Item;
-      QCBORError uResult = QCBORDecode_GetNextTag(pMe, &Item);
+      QCBORError uResult = QCBORDecode_GetNextTagContent(pMe, &Item);
       if(QCBORDecode_IsUnrecoverableError(uResult)) {
          /* Unrecoverable error so map can't even be decoded. */
          uReturn = uResult;
@@ -3198,7 +3364,7 @@
     reached.  It may do nothing, or ascend all the way to the top
     level.
     */
-   uErr = NestLevelAscender(pMe, false);
+   uErr = QCBORDecode_NestLevelAscender(pMe, false);
    if(uErr != QCBOR_SUCCESS) {
       goto Done;
    }
@@ -3289,7 +3455,7 @@
 
    if(DecodeNesting_IsCurrentDefiniteLength(&(pMe->nesting))) {
       // Reverse the decrement done by GetNext() for the bstr so the
-      // increment in NestLevelAscender() called by ExitBoundedLevel()
+      // increment in QCBORDecode_NestLevelAscender() called by ExitBoundedLevel()
       // will work right.
       DecodeNesting_ReverseDecrement(&(pMe->nesting));
    }