Getting started on indefinite lengths
diff --git a/cmd_line_main.c b/cmd_line_main.c
index 309b98b..cf6f1af 100644
--- a/cmd_line_main.c
+++ b/cmd_line_main.c
@@ -31,6 +31,10 @@
 #include "basic_test.h"
 
 int main(int argc, const char * argv[]) {
+     indefinite_length_decode_test();
+
+    
+    
     printf("Test Result %d\n", basic_test_one());
     
     
diff --git a/inc/qcbor.h b/inc/qcbor.h
index b555873..48275af 100644
--- a/inc/qcbor.h
+++ b/inc/qcbor.h
@@ -183,6 +183,12 @@
    uint8_t        uDecodeMode;
    
    QCBORDecodeNesting nesting;
+   
+   // This is NULL or points to a QCBORStringAllocator. It is void
+   // here because _QCBORDecodeContext is defined early n the
+   // private part of this file and QCBORStringAllocat is defined
+   // later in the public part of this file.
+   void *pStringAllocator;
 };
 
 
@@ -627,9 +633,10 @@
 /** Type for the simple value undef; nothing more; nothing in val union. */
 #define QCBOR_TYPE_UNDEF         23
 
+#define QCBOR_TYPE_BREAK         31 // Used internally; never returned
 
 #define QCBOR_TYPE_OPTTAG     254 // Used internally; never returned
-#define QCBOR_TYPE_BREAK      255 // Used internally; never returned
+//#define QCBOR_TYPE_BREAK      255 // Used internally; never returned
 
 
 
@@ -679,6 +686,18 @@
 } QCBORItem;
 
 
+/*
+ Optional to set up an allocator for bstr and tstr types.
+ Required to process indefinite length bstr and tstr types.
+ (indefinite length maps can be processed without this).
+ */
+typedef struct {
+    void *pAllocaterContext;
+    void * (*AllocatorFunction)(void *pMem, size_t uNewSize);
+    bool bAlwaysAlloc;
+} QCBORStringAllocator;
+
+
 /** See the descriptions for CBOR_SIMPLEV_FALSE, CBOR_TAG_DATE_EPOCH... for
     the meaning of the individual tags.  The values here are bit flags
     associated with each tag.  These flags are set in uTagsBits in QCBORItem */
@@ -1436,6 +1455,13 @@
 void QCBORDecode_Init(QCBORDecodeContext *pCtx, UsefulBufC EncodedCBOR, int8_t nMode);
 
 
+/*
+ 
+ */
+void QCBOR_Decode_SetUpAllocator(QCBORDecodeContext *pCtx, const QCBORStringAllocator *pAllocator);
+
+
+
 /**
  Gets the next item (integer, byte string, array...) in pre order traversal of CBOR tree
  
diff --git a/src/qcbor_decode.c b/src/qcbor_decode.c
index 1d6fd58..68fe20a 100644
--- a/src/qcbor_decode.c
+++ b/src/qcbor_decode.c
@@ -92,26 +92,44 @@
    return pNesting->pCurrent != &(pNesting->pMapsAndArrays[0]);
 }
 
+inline static int IsIndefiniteLength(const QCBORDecodeNesting *pNesting)
+{
+   if(!DecodeNesting_IsNested(pNesting)) {
+      return 0;
+   }
+   
+   return pNesting->pCurrent->uCount == UINT16_MAX;
+}
+
 inline static int DecodeNesting_TypeIsMap(const QCBORDecodeNesting *pNesting)
 {
-   if(!DecodeNesting_IsNested(pNesting))
+   if(!DecodeNesting_IsNested(pNesting)) {
       return 0;
+   }
    
    return CBOR_MAJOR_TYPE_MAP == pNesting->pCurrent->uMajorType;
 }
 
-inline static void DecodeNesting_Decrement(QCBORDecodeNesting *pNesting, uint8_t uDataType)
+inline static void DecodeNesting_Decrement(QCBORDecodeNesting *pNesting)
 {
    if(!DecodeNesting_IsNested(pNesting)) {
       return;  // at top level where there is no tracking
    }
    
-   // Decrement
-   pNesting->pCurrent->uCount--;
-   
-   // Pop up nesting levels if the counts at the levels is zero
-   while(0 == pNesting->pCurrent->uCount && DecodeNesting_IsNested(pNesting)) {
+   if(IsIndefiniteLength(pNesting)) {
+      // Decrement only gets called once. Only at the end of the array/map
+      // when the break is encountered. There is no tracking of the number
+      // of items in the array/map.
       pNesting->pCurrent--;
+
+   } else {
+      // Decrement
+      pNesting->pCurrent->uCount--;
+   
+      // Pop up nesting levels if the counts at the levels is zero
+      while(0 == pNesting->pCurrent->uCount && DecodeNesting_IsNested(pNesting)) {
+         pNesting->pCurrent--;
+      }
    }
 }
 
@@ -166,6 +184,15 @@
 
 
 /*
+ Public function, see header file
+ */
+void QCBOR_Decode_SetUpAllocator(QCBORDecodeContext *pCtx, const QCBORStringAllocator *pAllocator)
+{
+    pCtx->pStringAllocator = (void *)pAllocator;
+}
+
+
+/*
  This decodes the fundamental part of a CBOR data item, the type and number
  
  This is the Counterpart to InsertEncodedTypeAndNumber().
@@ -211,10 +238,11 @@
       case ADDINFO_RESERVED1: // reserved by CBOR spec
       case ADDINFO_RESERVED2: // reserved by CBOR spec
       case ADDINFO_RESERVED3: // reserved by CBOR spec
-      case LEN_IS_INDEFINITE: // indefinite types not supported (yet)
          nReturn = QCBOR_ERR_UNSUPPORTED;
          goto Done;
-         
+
+       case LEN_IS_INDEFINITE:
+           // Fall through OK to see what happens: TODO: check this.
       default:
          uTmpValue = uAdditionalInfo;
          break;
@@ -299,6 +327,10 @@
 #error QCBOR_TYPE_UNDEF macro value wrong
 #endif
 
+#if QCBOR_TYPE_BREAK != CBOR_SIMPLE_BREAK
+#error QCBOR_TYPE_BREAK macro value wrong
+#endif
+
 #if QCBOR_TYPE_DOUBLE != DOUBLE_PREC_FLOAT
 #error QCBOR_TYPE_DOUBLE macro value wrong
 #endif
@@ -323,7 +355,6 @@
       case ADDINFO_RESERVED1:  // 28
       case ADDINFO_RESERVED2:  // 29
       case ADDINFO_RESERVED3:  // 30
-      case CBOR_SIMPLE_BREAK:  // 31
          nReturn = QCBOR_ERR_UNSUPPORTED;
          break;
          
@@ -331,6 +362,7 @@
       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
@@ -591,7 +623,11 @@
             nReturn = QCBOR_ERR_ARRAY_TOO_LONG;
             goto Done;
          }
-         pDecodedItem->val.uCount = uNumber; // type conversion OK because of check above
+         if(uAdditionalInfo == LEN_IS_INDEFINITE) {
+            pDecodedItem->val.uCount = UINT16_MAX;
+         } else {
+            pDecodedItem->val.uCount = (uint16_t)uNumber; // type conversion OK because of check above
+         }
          pDecodedItem->uDataType  = uMajorType; // C preproc #if above makes sure constants align
          break;
          
@@ -678,9 +714,19 @@
    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 a integer or string in effect here
-      DecodeNesting_Decrement(&(me->nesting), pDecodedItem->uDataType);
+      if(!IsIndefiniteLength(&(me->nesting))) {
+         // Is a definite length array or map
+         // Track number of items in maps and arrays and ascend nesting if all are consumed
+         // Note that an empty array or map is like a integer or string in effect here
+         DecodeNesting_Decrement(&(me->nesting));
+      } else {
+         // Is an indefinite length array or map
+         if(pDecodedItem->uDataType == QCBOR_TYPE_BREAK) {
+            // Only decrement when the end is encountered.
+            DecodeNesting_Decrement(&(me->nesting));
+            // TODO: get another item here....
+         }
+      }
    }
    
 Done:
diff --git a/test/basic_test.c b/test/basic_test.c
index 1f179ed..ac55a67 100644
--- a/test/basic_test.c
+++ b/test/basic_test.c
@@ -137,3 +137,60 @@
     
     return 0;
 }
+
+
+static const uint8_t pIndefiniteLenString[] = {0x7f, 0x65, 0x73, 0x74, 0x72, 0x65, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x67, 0xff};
+
+static const uint8_t pIndefiniteArray[] = {0x9f, 0x01, 0x82, 0x02, 0x03, 0xff};
+
+//0x9f018202039f0405ffff
+
+int indefinite_length_decode_test() {
+    UsefulBufC IndefLen = UsefulBuf_FromByteArrayLiteral(pIndefiniteArray);
+    
+    
+    // Decode it and see if it is OK
+    QCBORDecodeContext DC;
+    QCBORItem Item;
+    QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
+    
+    QCBORDecode_GetNext(&DC, &Item);
+    if(Item.uDataType != QCBOR_TYPE_ARRAY) {
+        return -1;
+    }
+
+    QCBORDecode_GetNext(&DC, &Item);
+    if(Item.uDataType != QCBOR_TYPE_INT64) {
+        return -1;
+    }
+  
+    QCBORDecode_GetNext(&DC, &Item);
+    if(Item.uDataType != QCBOR_TYPE_ARRAY) {
+        return -1;
+    }
+    
+    QCBORDecode_GetNext(&DC, &Item);
+    if(Item.uDataType != QCBOR_TYPE_INT64) {
+        return -1;
+    }
+    
+    QCBORDecode_GetNext(&DC, &Item);
+    if(Item.uDataType != QCBOR_TYPE_INT64) {
+        return -1;
+    }
+
+    QCBORDecode_GetNext(&DC, &Item);
+    if(Item.uDataType != QCBOR_TYPE_INT64) {
+        return -1;
+    }
+    
+    
+    return 0;
+}
+
+
+
+
+
+
+
diff --git a/test/basic_test.h b/test/basic_test.h
index da5849f..2a91c14 100644
--- a/test/basic_test.h
+++ b/test/basic_test.h
@@ -31,4 +31,6 @@
 
 int basic_test_one(void);
 
+int indefinite_length_decode_test(void);
+
 #endif /* basic_test_h */