Clean up / rearrange of code for tracking nesting; fixed a bug too
diff --git a/QCBOR.xcodeproj/project.pbxproj b/QCBOR.xcodeproj/project.pbxproj
index 17dc1f2..dfcdcf4 100644
--- a/QCBOR.xcodeproj/project.pbxproj
+++ b/QCBOR.xcodeproj/project.pbxproj
@@ -7,7 +7,7 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
-		0F60E27B2164705400483952 /* qcbor_decode_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = 0F60E27A2164705400483952 /* qcbor_decode_malloc.c */; };
+		0F58EB9C216A388E002FD6D1 /* qcbor_decode_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = 0F58EB9B216A388E002FD6D1 /* qcbor_decode_malloc.c */; };
 		E73B5756216071900080D658 /* bstrwrap_tests.c in Sources */ = {isa = PBXBuildFile; fileRef = E73B5755216071900080D658 /* bstrwrap_tests.c */; };
 		E73B57592161CA690080D658 /* ieee754.c in Sources */ = {isa = PBXBuildFile; fileRef = E73B57582161CA690080D658 /* ieee754.c */; };
 		E73B575E2161CA7C0080D658 /* half_precision_test.c in Sources */ = {isa = PBXBuildFile; fileRef = E73B575A2161CA7C0080D658 /* half_precision_test.c */; };
@@ -33,7 +33,7 @@
 /* End PBXCopyFilesBuildPhase section */
 
 /* Begin PBXFileReference section */
-		0F60E27A2164705400483952 /* qcbor_decode_malloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = qcbor_decode_malloc.c; sourceTree = "<group>"; };
+		0F58EB9B216A388E002FD6D1 /* qcbor_decode_malloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = qcbor_decode_malloc.c; path = src/qcbor_decode_malloc.c; sourceTree = "<group>"; };
 		E73B5754216071900080D658 /* bstrwrap_tests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = bstrwrap_tests.h; path = test/bstrwrap_tests.h; sourceTree = "<group>"; };
 		E73B5755216071900080D658 /* bstrwrap_tests.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = bstrwrap_tests.c; path = test/bstrwrap_tests.c; sourceTree = "<group>"; };
 		E73B57572161CA680080D658 /* ieee754.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ieee754.h; path = src/ieee754.h; sourceTree = "<group>"; };
@@ -90,7 +90,7 @@
 		E776E08B214AE06600E67947 /* src */ = {
 			isa = PBXGroup;
 			children = (
-				0F60E27A2164705400483952 /* qcbor_decode_malloc.c */,
+				0F58EB9B216A388E002FD6D1 /* qcbor_decode_malloc.c */,
 				E73B57582161CA690080D658 /* ieee754.c */,
 				E73B57572161CA680080D658 /* ieee754.h */,
 				E776E08E214AE07500E67947 /* qcbor_decode.c */,
@@ -183,7 +183,7 @@
 			buildActionMask = 2147483647;
 			files = (
 				E776E08F214AE07500E67947 /* qcbor_encode.c in Sources */,
-				0F60E27B2164705400483952 /* qcbor_decode_malloc.c in Sources */,
+				0F58EB9C216A388E002FD6D1 /* qcbor_decode_malloc.c in Sources */,
 				E73B57592161CA690080D658 /* ieee754.c in Sources */,
 				E73B575F2161CA7C0080D658 /* half_to_double_from_rfc7049.c in Sources */,
 				E73B57652161F8F80080D658 /* run_tests.c in Sources */,
diff --git a/inc/qcbor.h b/inc/qcbor.h
index 4ea4079..d8bf35f 100644
--- a/inc/qcbor.h
+++ b/inc/qcbor.h
@@ -677,7 +677,7 @@
       uint64_t    uint64;     /** The value for uDataType QCBOR_TYPE_UINT64 */
 
       UsefulBufC  string;     /** The value for uDataType QCBOR_TYPE_BYTE_STRING and QCBOR_TYPE_TEXT_STRING */
-      uint16_t    uCount;     /** The "value" for uDataType QCBOR_TYPE_ARRAY or QCBOR_TYPE_MAP -- the number of items in the array or map */
+      uint16_t    uCount;     /** The "value" for uDataType QCBOR_TYPE_ARRAY or QCBOR_TYPE_MAP -- the number of items in the array or map */ // TODO: indefinite len arrays
       float       fnum;       /** The value for uDataType QCBOR_TYPE_FLOAT */
       double      dfnum;      /** The value for uDataType QCBOR_TYPE_DOUBLE */
       struct {
diff --git a/src/qcbor_decode.c b/src/qcbor_decode.c
index eccd469..4679ec0 100644
--- a/src/qcbor_decode.c
+++ b/src/qcbor_decode.c
@@ -80,7 +80,7 @@
 
 
 /*
- Collection of functions to track the map and array nesting for decoding
+ Collection of functions to track the map/array nesting for decoding
  */
 
 inline static int IsMapOrArray(uint8_t uDataType)
@@ -95,13 +95,14 @@
 
 inline static int DecodeNesting_IsIndefiniteLength(const QCBORDecodeNesting *pNesting)
 {
-   if(!DecodeNesting_IsNested(pNesting)) {
-      return 0;
-   }
-   
    return pNesting->pCurrent->uCount == UINT16_MAX;
 }
 
+inline static uint8_t DecodeNesting_GetLevel(QCBORDecodeNesting *pNesting)
+{
+   return pNesting->pCurrent - &(pNesting->pMapsAndArrays[0]);
+}
+
 inline static int DecodeNesting_TypeIsMap(const QCBORDecodeNesting *pNesting)
 {
    if(!DecodeNesting_IsNested(pNesting)) {
@@ -111,54 +112,82 @@
    return CBOR_MAJOR_TYPE_MAP == pNesting->pCurrent->uMajorType;
 }
 
-inline static void DecodeNesting_Ascend(QCBORDecodeNesting *pNesting)
+// Process a break. This will either ascend the nesting or error out
+inline static int DecodeNesting_BreakAscend(QCBORDecodeNesting *pNesting)
 {
-   pNesting->pCurrent--;
-}
-
-inline static void DecodeNesting_Decrement(QCBORDecodeNesting *pNesting)
-{
+   // breaks must always occur when there is nesting
    if(!DecodeNesting_IsNested(pNesting)) {
-      return;  // at top level where there is no tracking
+      return QCBOR_ERR_BAD_BREAK;
    }
    
-   // Decrement
+   // breaks can only occur when the map/array is indefinite length
+   if(!DecodeNesting_IsIndefiniteLength(pNesting)) {
+      return QCBOR_ERR_BAD_BREAK;
+   }
+   
+   // if all OK, the break reduces the level of nesting
+   pNesting->pCurrent--;
+   
+   return QCBOR_SUCCESS;
+}
+
+// Called on every single item except breaks including the opening of a map/array
+inline static void DecodeNesting_DecrementCount(QCBORDecodeNesting *pNesting)
+{
+   if(!DecodeNesting_IsNested(pNesting)) {
+      // at top level where there is no tracking
+      return;
+   }
+   
+   if(DecodeNesting_IsIndefiniteLength(pNesting)) {
+      // There is no count for indefinite length arrays/maps
+      return;
+   }
+   
+   // Decrement the count of items in this array/map
    pNesting->pCurrent->uCount--;
 
-   // Pop up nesting levels if the counts at the levels is zero
-   while(0 == pNesting->pCurrent->uCount && DecodeNesting_IsNested(pNesting)) {
+   // Pop up nesting levels if the counts at the levels are zero
+   while(DecodeNesting_IsNested(pNesting) && 0 == pNesting->pCurrent->uCount) {
       pNesting->pCurrent--;
    }
 }
 
-inline static int DecodeNesting_Descend(QCBORDecodeNesting *pNesting, uint8_t uMajorType, int uCount)
+// Called on every map/array
+inline static int DecodeNesting_Descend(QCBORDecodeNesting *pNesting, QCBORItem *pItem)
 {
    int nReturn = QCBOR_SUCCESS;
    
-   if(uCount > QCBOR_MAX_ITEMS_IN_ARRAY) {
+   if(pItem->val.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
+      goto Done;
+      // Empty indefinite length maps and arrays are handled elsewhere; TODO: where?
+   }
+   
+   // Error out if arrays is too long to handle
+   if(pItem->val.uCount != UINT16_MAX && pItem->val.uCount > QCBOR_MAX_ITEMS_IN_ARRAY) {
       nReturn = QCBOR_ERR_ARRAY_TOO_LONG;
       goto Done;
    }
    
+   // Error out if nesting is too deep
    if(pNesting->pCurrent >= &(pNesting->pMapsAndArrays[QCBOR_MAX_ARRAY_NESTING])) {
       nReturn = QCBOR_ERR_ARRAY_NESTING_TOO_DEEP;
       goto Done;
    }
    
+   // The actual descend
    pNesting->pCurrent++;
    
-   pNesting->pCurrent->uMajorType = uMajorType;
-   pNesting->pCurrent->uCount     = uCount;
+   // Record a few details for this nesting level
+   pNesting->pCurrent->uMajorType = pItem->uDataType;
+   pNesting->pCurrent->uCount     = pItem->val.uCount;
    
 Done:
    return nReturn;;
 }
 
-inline static uint8_t DecodeNesting_GetLevel(QCBORDecodeNesting *pNesting)
-{
-   return pNesting->pCurrent - &(pNesting->pMapsAndArrays[0]);
-}
-
 inline static void DecodeNesting_Init(QCBORDecodeNesting *pNesting)
 {
    pNesting->pCurrent = &(pNesting->pMapsAndArrays[0]);
@@ -612,8 +641,11 @@
 static int GetNext_FullItem(QCBORDecodeContext *me, QCBORItem *pDecodedItem)
 {
    int nReturn;
+   UsefulBufC FullString = NULLUsefulBufC;
    QCBORStringAllocator *pAlloc =  (QCBORStringAllocator *)me->pStringAllocator;
    
+   // TODO: can this call to GetNext_Item go in the loop below so there is only
+   // one call to it so it can inline?
    nReturn = GetNext_Item(&(me->InBuf), pDecodedItem, me->bStringAllocateAll ? pAlloc: NULL);
    if(nReturn) {
       goto Done;
@@ -645,7 +677,6 @@
    const uint8_t uStringType = pDecodedItem->uDataType;
    
    // Loop getting segments of indefinite string
-   UsefulBufC FullString = NULLUsefulBufC;
    for(;;) {
       // Get item for next segment
       QCBORItem Item;
@@ -698,6 +729,7 @@
 {
    int nReturn;
    
+   // TODO: optimize loop below so there is only one call to GetNext_FullItem
    nReturn = GetNext_FullItem(me, pDecodedItem);
    if(nReturn) {
       goto Done;
@@ -854,47 +886,38 @@
 {
    int nReturn;
    
-   if(!UsefulInputBuf_BytesUnconsumed(&(me->InBuf))) {
-      nReturn = QCBOR_ERR_HIT_END;
-      goto Done;
-   }
-   
-   nReturn = GetNext_MapEntry(me, pDecodedItem);
-   if(nReturn) {
-      goto Done;
-   }
-   
-   // Handle any breaks that are closing out arrays or maps
-   while(pDecodedItem->uDataType == QCBOR_TYPE_BREAK) {
-      if(!DecodeNesting_IsIndefiniteLength(&(me->nesting))) {
-         nReturn = QCBOR_ERR_BAD_BREAK;
+   // Loop getting items until one that is not a break is fetched
+   for(;;) {
+      nReturn = GetNext_MapEntry(me, pDecodedItem);
+      if(nReturn) {
          goto Done;
       }
       
-      // Close out and ascend
-      DecodeNesting_Ascend(&(me->nesting));
-      
-      nReturn = GetNext_MapEntry(me, pDecodedItem);
+      if(pDecodedItem->uDataType != QCBOR_TYPE_BREAK) {
+         break;
+      }
+
+      // Item is a break. That means we have to try to reduce
+      // nesting level.
+      nReturn = DecodeNesting_BreakAscend(&(me->nesting));
       if(nReturn) {
          goto Done;
       }
    }
    
-   // Now have the next item that is not a break. The one that is going to be returned
+   // Now have the next item that is not a break, the one that is going to be returned
 
-   // Record the nesting level for this data item
+   // Record the nesting level for this data item before processing any of
+   // decrementing and decsending
    pDecodedItem->uNestingLevel = DecodeNesting_GetLevel(&(me->nesting));
    
-   // If the new item is a non-empty array or map, the nesting level descends
-   if(IsMapOrArray(pDecodedItem->uDataType) && pDecodedItem->val.uCount) {
-      nReturn = DecodeNesting_Descend(&(me->nesting), pDecodedItem->uDataType, pDecodedItem->val.uCount);
-   } else {
-      // Track number of items in maps and arrays and ascend nesting if all are consumed
-      // Note that an empty array or map is like an integer or string in effect here
-      // No counting is done for indefinite length arrays
-      if(!DecodeNesting_IsIndefiniteLength(&(me->nesting))) {
-         DecodeNesting_Decrement(&(me->nesting));
-      }
+   // Always decrement the count at the current level no matter what type
+   // except for breaks as breaks are always processed above
+   DecodeNesting_DecrementCount(&(me->nesting));
+   
+   // If the new item is array or map, the nesting level descends
+   if(IsMapOrArray(pDecodedItem->uDataType)) {
+      nReturn = DecodeNesting_Descend(&(me->nesting), pDecodedItem);
    }
    
 Done:
@@ -912,14 +935,21 @@
    // Consume any breaks ending indefinite length arrays or maps here
    // Definite length arrays and maps get closed off above when they
    // the last item in them is consumed; they are not handled here.
+   // TODO: put in a function and make common with above similar code
    while(DecodeNesting_GetLevel(&(me->nesting))) {
       QCBORItem Item;
-      GetNext_Item(&(me->InBuf), &Item, false);
+      int nReturn = GetNext_Item(&(me->InBuf), &Item, NULL);
+      if(nReturn) {
+         break;
+      }
       if(Item.uDataType != QCBOR_TYPE_BREAK) {
          nReturn = QCBOR_ERR_EXTRA_BYTES;
          break;
       }
-      DecodeNesting_Ascend(&(me->nesting));
+      nReturn = DecodeNesting_BreakAscend(&(me->nesting));
+      if(nReturn) {
+         break;
+      }
    }
    
    // Call the desctructor for the string allocator if there is one