new example starting to work
diff --git a/example.c b/example.c
new file mode 100644
index 0000000..b07a76c
--- /dev/null
+++ b/example.c
@@ -0,0 +1,269 @@
+/*==============================================================================
+ example.c -- Example code for QCBOR
+
+ Copyright (c) 2020, Laurence Lundblade. All rights reserved.
+
+ SPDX-License-Identifier: BSD-3-Clause
+
+ See BSD-3-Clause license in README.md
+
+ Created on 6/30/2020
+=============================================================================*/
+
+
+#include <stdio.h>
+#include "example.h"
+#include "qcbor/qcbor_encode.h"
+#include "qcbor/qcbor_decode.h"
+
+#define MAX_CYLINDERS 16
+
+typedef struct
+{
+    UsefulBufC Manufacturer;
+    uint64_t uNumCylinders;
+    uint64_t uDisplacement;
+    uint64_t uHorsePower;
+    double uDesignedCompresion;
+    struct {
+        double uMeasuredCompression;
+    } cylinders[MAX_CYLINDERS];
+    bool bTurboCharged;
+} Engine;
+
+
+void EngineInit(Engine *pE)
+{
+    pE->uNumCylinders = 6;
+    pE->bTurboCharged = false;
+    pE->Manufacturer = UsefulBuf_FROM_SZ_LITERAL("Porsche");
+    pE->uDisplacement = 3296;
+    pE->uHorsePower = 210;
+    pE->uDesignedCompresion = 9.1;
+    pE->cylinders[0].uMeasuredCompression = 9.0;
+    pE->cylinders[1].uMeasuredCompression = 9.2;
+    pE->cylinders[2].uMeasuredCompression = 8.9;
+    pE->cylinders[3].uMeasuredCompression = 8.9;
+    pE->cylinders[4].uMeasuredCompression = 9.1;
+    pE->cylinders[5].uMeasuredCompression = 9.0;
+}
+
+
+UsefulBufC EncodeEngine(const Engine *pEngine, UsefulBuf Buffer)
+{
+    QCBOREncodeContext EncodeCtx;
+
+    QCBOREncode_Init(&EncodeCtx, Buffer);
+    QCBOREncode_OpenMap(&EncodeCtx);
+    QCBOREncode_AddTextToMap(&EncodeCtx, "Manufacturer", pEngine->Manufacturer);
+    QCBOREncode_AddUInt64ToMap(&EncodeCtx, "NumCylinders", pEngine->uNumCylinders);
+    QCBOREncode_AddUInt64ToMap(&EncodeCtx, "Displacement", pEngine->uDisplacement);
+    QCBOREncode_AddUInt64ToMap(&EncodeCtx, "HorsePower", pEngine->uHorsePower);
+    QCBOREncode_AddDoubleToMap(&EncodeCtx, "DesignedCompression", pEngine->uDesignedCompresion);
+    QCBOREncode_OpenArrayInMap(&EncodeCtx, "Cylinders");
+    for(uint64_t i = 0 ; i < pEngine->uNumCylinders; i++) {
+        QCBOREncode_AddDouble(&EncodeCtx, pEngine->cylinders[i].uMeasuredCompression);
+    }
+    QCBOREncode_CloseArray(&EncodeCtx);
+    QCBOREncode_AddBoolToMap(&EncodeCtx, "turbo", pEngine->bTurboCharged);
+    QCBOREncode_CloseMap(&EncodeCtx);
+
+    UsefulBufC EncodedCBOR;
+    QCBORError uErr;
+    uErr = QCBOREncode_Finish(&EncodeCtx, &EncodedCBOR);
+    if(uErr != QCBOR_SUCCESS) {
+        return NULLUsefulBufC;
+    } else {
+       return EncodedCBOR;
+    }
+}
+
+
+UsefulBufC EncodeEngineIndefinteLen(const Engine *pEngine, UsefulBuf Buffer)
+{
+    QCBOREncodeContext EncodeCtx;
+
+    QCBOREncode_Init(&EncodeCtx, Buffer);
+    QCBOREncode_OpenMapIndefiniteLength(&EncodeCtx);
+    QCBOREncode_AddTextToMap(&EncodeCtx, "Manufacturer", pEngine->Manufacturer);
+    QCBOREncode_AddUInt64ToMap(&EncodeCtx, "Displacement", pEngine->uDisplacement);
+    QCBOREncode_AddUInt64ToMap(&EncodeCtx, "HorsePower", pEngine->uHorsePower);
+    QCBOREncode_AddDoubleToMap(&EncodeCtx, "DesignedCompression", pEngine->uDesignedCompresion);
+    QCBOREncode_AddUInt64ToMap(&EncodeCtx, "NumCylinders", pEngine->uNumCylinders);
+    QCBOREncode_OpenArrayIndefiniteLengthInMap(&EncodeCtx, "Cylinders");
+    for(uint64_t i = 0 ; i < pEngine->uNumCylinders; i++) {
+        QCBOREncode_AddDouble(&EncodeCtx, pEngine->cylinders[i].uMeasuredCompression);
+    }
+    QCBOREncode_CloseArrayIndefiniteLength(&EncodeCtx);
+    QCBOREncode_AddBoolToMap(&EncodeCtx, "turbo", pEngine->bTurboCharged);
+    QCBOREncode_CloseMapIndefiniteLength(&EncodeCtx);
+
+    UsefulBufC EncodedCBOR;
+    QCBORError uErr;
+    uErr = QCBOREncode_Finish(&EncodeCtx, &EncodedCBOR);
+    if(uErr != QCBOR_SUCCESS) {
+        return NULLUsefulBufC;
+    } else {
+       return EncodedCBOR;
+    }
+}
+
+
+/*
+A -- require all fields ; easiest code
+B -- all are optional; messiest code; should this be accommodate better?
+C -- some are optional; not too hard
+
+It is a protocol error to have the wrong type for a label.
+
+ */
+
+QCBORError DecodeEngine(UsefulBufC EncodedEngine, Engine *pE)
+{
+    QCBORDecodeContext DecodeCtx;
+
+    QCBORDecode_Init(&DecodeCtx, EncodedEngine, QCBOR_DECODE_MODE_NORMAL);
+    QCBORDecode_EnterMap(&DecodeCtx);
+    QCBORDecode_GetTextInMapSZ(&DecodeCtx, "Manufacturer", &(pE->Manufacturer));
+    QCBORDecode_GetUInt64InMapSZ(&DecodeCtx, "Displacement", &(pE->uDisplacement));
+    QCBORDecode_GetUInt64InMapSZ(&DecodeCtx, "HorsePower", &(pE->uHorsePower));
+    QCBORDecode_GetDoubleInMapSZ(&DecodeCtx, "DesignedCompression", &(pE->uDesignedCompresion));
+    QCBORDecode_GetBoolInMapSZ(&DecodeCtx, "turbo", &(pE->bTurboCharged));
+
+    QCBORDecode_GetUInt64InMapSZ(&DecodeCtx, "NumCylinders", &(pE->uNumCylinders));
+
+    /* Must check error before referencing pE->uNumCylinders to be sure it
+     is valid. If any of the above errored, it won't be valid. */
+    if(QCBORDecode_GetError(&DecodeCtx)) {
+        return 100; // TODO: more error processing
+    }
+
+    if(pE->uNumCylinders > MAX_CYLINDERS) {
+        return 900;
+    }
+
+    QCBORDecode_EnterArrayFromMapSZ(&DecodeCtx, "Cylinders");
+    uint64_t i = 0;
+    while(1) {
+        QCBORDecode_GetDouble(&DecodeCtx, &(pE->cylinders[i].uMeasuredCompression));
+        i++;
+        if(i >= pE->uNumCylinders ) {
+            break;
+        }
+    }
+    QCBORDecode_ExitArray(&DecodeCtx);
+    QCBORDecode_ExitMap(&DecodeCtx);
+
+    QCBORError uErr = QCBORDecode_Finish(&DecodeCtx);
+
+    return uErr;
+}
+
+#if 0
+QCBORError CheckLabelAndType(const char *szLabel, uint8_t uQCBORType, QCBORItem *pItem)
+{
+    if(pItem->uLabelType != QCBOR_TYPE_TEXT_STRING) {
+        return QCBOR_ERR_NOT_FOUND;
+    }
+
+    UsefulBufC Label = UsefulBuf_FromSZ(szLabel);
+
+    if(UsefulBuf_Compare(Label, pItem->val.string)) {
+        return QCBOR_ERR_NOT_FOUND;
+    }
+
+    if(pItem->uDataType != uQCBORType) {
+        return QCBOR_ERR_UNEXPECTED_TYPE;
+    }
+
+    return QCBOR_SUCCESS;
+}
+
+void DecodeCylinders(QCBORDecodeContext *pDctx, Engine *pE, const QCBORItem *pItem)
+{
+
+}
+
+QCBORError DecodeEngineBasic(UsefulBufC EncodedEngine, Engine *pE)
+{
+    QCBORDecodeContext DecodeCtx;
+
+    QCBORDecode_Init(&DecodeCtx, EncodedEngine, 0);// TODO: fill in mode;
+
+    QCBORItem Item;
+    QCBORError uErr;
+
+    uErr = QCBORDecode_GetNext(&DecodeCtx, &Item);
+    if(uErr != QCBOR_SUCCESS) {
+        goto Done;
+    }
+    if(Item.uDataType != QCBOR_TYPE_MAP) {
+        uErr = 100;
+        goto Done;
+    }
+
+    while(1) {
+        uErr = QCBORDecode_GetNext(&DecodeCtx, &Item);
+        if(uErr != QCBOR_SUCCESS) {
+            goto Done;
+        }
+        if(Item.uDataType != QCBOR_TYPE_MAP) {
+            uErr = 100;
+            goto Done;
+        }
+
+        if(CheckLabelAndType("Manufacturer", QCBOR_TYPE_TEXT_STRING, &Item )) {
+            if(Item.uDataType != QCBOR_TYPE_TEXT_STRING) {
+                return 99; // TODO: what to do on wrong type?
+            } else {
+                // TODO: copy string or change data type
+            }
+
+        } else if(CheckLabel("NumCylinders", &Item)) {
+          if(Item.uDataType != QCBOR_TYPE_INT64) {
+              return 99; // TODO: what to do on wrong type?
+          } else {
+              // TODO: what about overflow
+              pE->uNumCylinders = (uint8_t)Item.val.int64;
+              // TODO: copy string or change data type
+          }
+        } else if(CheckLabel("Cylinders", &Item)) {
+            DecodeCylinders(&DecodeCtx, pE, &Item);
+         }
+
+    }
+
+
+Done:
+    return uErr;
+}
+
+#endif
+
+
+
+
+
+void RunQCborExample()
+{
+    Engine                  E, DecodedEngine;
+    MakeUsefulBufOnStack(   EngineBuffer, 300);
+    UsefulBufC              EncodedEngine;
+
+    MakeUsefulBufOnStack(   InDefEngineBuffer, 300);
+    UsefulBufC              InDefEncodedEngine;
+
+    EngineInit(&E);
+
+    EncodedEngine = EncodeEngine(&E, EngineBuffer);
+
+    printf("Engine Encoded in %zu bytes\n", EncodedEngine.len);
+
+    DecodeEngine(EncodedEngine, &DecodedEngine);
+
+
+    InDefEncodedEngine = EncodeEngineIndefinteLen(&E, InDefEngineBuffer);
+
+    printf("Indef Engine Encoded in %zu bytes\n", InDefEncodedEngine.len);
+
+}