big clean up of example code
diff --git a/example.c b/example.c
index 1e25efa..b0ea925 100644
--- a/example.c
+++ b/example.c
@@ -1,15 +1,14 @@
-/*==============================================================================
- example.c -- Example code for QCBOR
+/* =========================================================================
+   example.c -- Example code for QCBOR
 
- Copyright (c) 2020, Laurence Lundblade. All rights reserved.
+   Copyright (c) 2020, Laurence Lundblade. All rights reserved.
 
- SPDX-License-Identifier: BSD-3-Clause
+   SPDX-License-Identifier: BSD-3-Clause
 
- See BSD-3-Clause license in README.md
+   See BSD-3-Clause license in README.md
 
- Created on 6/30/2020
-=============================================================================*/
-
+   Created on 6/30/2020
+  ========================================================================== */
 
 #include <stdio.h>
 #include "example.h"
@@ -17,48 +16,58 @@
 #include "qcbor/qcbor_decode.h"
 #include "qcbor/qcbor_spiffy_decode.h"
 
+
 #define MAX_CYLINDERS 16
 
-
 /**
- The data structure representing a car engine that is encoded and decoded in this examples.
+ The data structure representing a car engine that is encoded and
+ decoded in this example.
  */
 typedef struct
 {
-    UsefulBufC Manufacturer;
-    int64_t    uDisplacement;
-    int64_t    uHorsePower;
-    double     dDesignedCompresion;
-    int64_t    uNumCylinders;
-    struct {
-        double uMeasuredCompression;
-    }          cylinders[MAX_CYLINDERS];
-    bool       bTurboCharged;
+   UsefulBufC Manufacturer;
+   int64_t    uDisplacement;
+   int64_t    uHorsePower;
+   double     dDesignedCompresion;
+   int64_t    uNumCylinders;
+   bool       bTurboCharged;
+   struct {
+      double uMeasuredCompression;
+   } cylinders[MAX_CYLINDERS];
 } CarEngine;
 
 
 /**
- Initialize the Engine data structure with some values to encode/decode.
+ @brief Initialize the Engine data structure with values to encode/decode.
+
+ @param[out] pE   The Engine structure to fill in
  */
 void EngineInit(CarEngine *pE)
 {
-    pE->Manufacturer = UsefulBuf_FROM_SZ_LITERAL("Porsche");
-    pE->uDisplacement = 3296;
-    pE->uHorsePower = 210;
-    pE->dDesignedCompresion = 9.1;
-    pE->uNumCylinders = 6;
-    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;
-    pE->bTurboCharged = false;
+   pE->Manufacturer        = UsefulBuf_FROM_SZ_LITERAL("Porsche");
+   pE->uDisplacement       = 3296;
+   pE->uHorsePower         = 210;
+   pE->dDesignedCompresion = 9.1;
+   pE->uNumCylinders       = 6;
+   pE->bTurboCharged       = false;
+
+   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;
 }
 
 
 /**
- Return @c true if the two Engined data structures are exactly the same.
+ @brief Compare two Engine structure for equality.
+
+ @param[in] pE1  First Engine to compare.
+ @param[in] pE2  Second Engine to compare.
+
+ @retval Return @c true if the two Engine data structures are exactly the
+ same.
  */
 bool EngineCompare(CarEngine *pE1, CarEngine *pE2)
 {
@@ -92,28 +101,37 @@
 }
 
 
+#ifndef EXAMPLE_DISABLE_DEFINITE_LENGTH_ENCODE
 /**
  @brief Encode an initialized Engine data structure in CBOR.
 
  @param[in] pEngine  The data structure to encode.
- @param[in] Buffer    Pointer and length of buffer to output to.
+ @param[in] Buffer   Pointer and length of buffer to output to.
 
- @return The pointer and length of the encoded CBOR or @ref NULLUsefulBufC on error.
+ @return  The pointer and length of the encoded CBOR or
+          @ref NULLUsefulBufC on error.
 
- @c Buffer must be big enough to hold the output. If it is not @ref NULLUsefulBufC
- will be returned. @ref @ref NULLUsefulBufC will be returned for any other encoding
- errors.
+ This is a simple CBOR encoding example. It outputs the Engine data
+ structure as a map of label-value pairs as well as an array of
+ floating point values.
 
- This encoding will use definite CBOR lengths.
+ @c Buffer must be big enough to hold the output. If it is not @ref
+ NULLUsefulBufC will be returned. @ref @ref NULLUsefulBufC will be
+ returned for any other encoding errors.
+
+ This encoding will use definite CBOR lengths. Definite lengths are
+ preferred in CBOR. See EncodeEngineIndefinteLen() that encodes using
+ indefinite lengths.
  */
-UsefulBufC EncodeEngine(const CarEngine *pEngine, UsefulBuf Buffer)
+UsefulBufC EncodeEngineDefiniteLength(const CarEngine *pEngine, UsefulBuf Buffer)
 {
-    /* Initialize th encoder with the buffer big enough to hold the expected output.
-     If it is too small, QCBOREncode_Finish() will return an error. */
+    /* Initialize the encoder with the buffer big enough to hold the
+       expected output.  If it is too small, QCBOREncode_Finish() will
+       return an error. */
     QCBOREncodeContext EncodeCtx;
     QCBOREncode_Init(&EncodeCtx, Buffer);
 
-    /* Proceed output all the items, letting the internal error
+    /* Proceed to output all the items, letting the internal error
      tracking do its work. */
     QCBOREncode_OpenMap(&EncodeCtx);
     QCBOREncode_AddTextToMap(&EncodeCtx, "Manufacturer", pEngine->Manufacturer);
@@ -130,32 +148,48 @@
     QCBOREncode_CloseMap(&EncodeCtx);
 
     /* Get the pointer and length of the encoded output. If there was
-     anny error it will be returned here. */
+       any error it will be returned here. */
     UsefulBufC EncodedCBOR;
     QCBORError uErr;
     uErr = QCBOREncode_Finish(&EncodeCtx, &EncodedCBOR);
     if(uErr != QCBOR_SUCCESS) {
-        return NULLUsefulBufC;
+       return NULLUsefulBufC;
     } else {
        return EncodedCBOR;
     }
 }
+#endif /* EXAMPLE_DISABLE_DEFINITE_LENGTH_ENCODE */
 
 
+
+
+#ifndef EXAMPLE_DISABLE_INDEFINITE_LENGTH_ENCODE_ENCODE
 /**
- @brief Encode an initialized Engine data structure in CBOR using indefinite lengths..
+ @brief Encode an initialized Engine data structure using indefinite lengths.
 
  @param[in] pEngine  The data structure to encode.
- @param[in] Buffer    Pointer and length of buffer to output to.
+ @param[in] Buffer   Pointer and length of buffer to output to.
 
- @return The pointer and length of the encoded CBOR or @ref NULLUsefulBufC on error.
+ @return The pointer and length of the encoded CBOR or
+         @ref NULLUsefulBufC on error.
 
- This is virtually the same as EncodeEngine(). The encoded CBOR is slightly different as the
-  map and array use indefinite lengths, rather than definite lengths.
+ This is virtually the same as EncodeEngineDefiniteLength(). The
+ encoded CBOR is slightly different as the map and array use
+ indefinite lengths, rather than definite lengths.
 
- There is little practical use for this function as definite lengths are generally preferred for
- CBOR and QCBOR always easily encodes definite lengths. (The advantage of indefinite
- lengths are that they are simpler to encode, but that doesn't come into effect here).
+ A definite length array is encoded as an integer indicating the
+ number of items in it. An indefinite length array is encoded as an
+ opening byte, the items in it and a "break" byte to end
+ it. Indefinite length arrays and maps are easier to encode, but
+ harder to decode.
+
+ The advantage of this implementation is that the encoding side will
+ be a little less object code. (Eventually QCBOR will an ifdef to
+ disable definite length encoding and the object code will be even
+ smaller).  However, note that the encoding implementation for a
+ protocol is just about always much smaller than the decoding
+ implementation and that code savings for use of indefinite lengths is
+ relatively small.
  */
 UsefulBufC EncodeEngineIndefinteLen(const CarEngine *pEngine, UsefulBuf Buffer)
 {
@@ -185,6 +219,7 @@
        return EncodedCBOR;
     }
 }
+#endif /* EXAMPLE_DISABLE_INDEFINITE_LENGTH_ENCODE */
 
 
 /**
@@ -200,7 +235,7 @@
 
 
 /**
- Convert \ref QCBORError to \ref EngineDecodeErrors.
+ Convert @ref QCBORError to @ref EngineDecodeErrors.
  */
 EngineDecodeErrors ConvertError(QCBORError uErr)
 {
@@ -225,29 +260,33 @@
 }
 
 
+#ifndef EXAMPLE_DISABLE_SPIFFY_DECODE
 /**
- @brief Simplest engine decode using advanced decoe features.
+ @brief Simplest engine decode using spiffy decode features.
 
  @param[in] EncodedEngine  Pointer and length of CBOR-encoded engine.
- @param[out] pE  The structure filled in from the decoding.
+ @param[out] pE            The structure filled in from the decoding.
 
  @return The decode error or success.
 
- This verssion of the decoder has the simplest implementation, but
- pulls in more code from the QCBOR library.  This version uses
- the most CPU because it scanns the all the CBOR each time
- a data item is decoded. The CPU used for a data structure as small
- as this is probably insignificant. CPU use for this style of decode is
+ This decodes the CBOR into the engine structure.
+
+ As QCBOR automatically supports both definite and indefinite maps and
+ arrays, this will decode either.
+
+ This uses QCBOR's spiffy decode, so the implementation is simplest
+ and closely parallels the encode implementation in
+ EncodeEngineDefiniteLength().
+
+ See two other ways to implement decoding in
+ DecodeEngineSpiffyFaster() and DecodeEngineBasic().
+
+ This version of the decoder has the simplest implementation, but
+ pulls in more code from the QCBOR library.  This version uses the
+ most CPU cycles because it scans the all the CBOR each time a data
+ item is decoded. The CPU cycles used for a data structure as small as
+ this is probably insignificant. CPU use for this style of decode is
  probably only a factor on slow CPUs with big CBOR inputs.
-
- Code size is yet to be measured, but this is probably the smallest total
- code size if multiple protocols are being decoded in one application because
- the complex parsing of a map and array is done be shared code from the
- CBOR library rather than by individual protocol-specific chunks of code.
- Similarly, this may be the smallest for  complex CBOR with multiple
- maps that need to be processed..
-
- See also DecodeEngineAdvancedFaster() and DecodeEngineBasic().
  */
 EngineDecodeErrors DecodeEngineSpiffy(UsefulBufC EncodedEngine, CarEngine *pE)
 {
@@ -264,8 +303,9 @@
 
     QCBORDecode_GetInt64InMapSZ(&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. */
+    /* Must check error before referencing pE->uNumCylinders to be
+       sure it is valid. If any of the above errored, it won't be
+       valid. */
     uErr = QCBORDecode_GetError(&DecodeCtx);
     if(uErr != QCBOR_SUCCESS) {
         goto Done;
@@ -289,20 +329,27 @@
     return ConvertError(uErr);
 }
 
+#endif /* EXAMPLE_DISABLE_SPIFFY_DECODE */
 
+
+
+#ifndef EXAMPLE_DISABLE_SPIFFY_DECODE_FAST
 /**
- @brief Simplest engine decode using advanced decoe features.
+ @brief Decode an Engine structure with the faster spiffy decode features.
 
  @param[in] EncodedEngine  Pointer and length of CBOR-encoded engine.
- @param[out] pE  The structure filled in from the decoding.
+ @param[out] pE            The structure filled in from the decoding.
 
  @return The decode error or success.
 
- This verssion of the decoder is still fairly simple and uses the
- advanced decode features like DecodeEngine(), but is faster
- and pulls in less library code. It is faster because all the items
- except the array are pulled out of the map in one pass, rather
- than multiple passes.
+ This decodes the same as DecodeEngineSpiffy(), but uses different
+ spiffy decode features.
+
+ This version uses QCBORDecode_GetItemsInMap() which uses less CPU
+ cycles because all the items except the array are pulled out of the
+ map in one pass, rather than having to decode the whole map for each
+ decoded item. This also pulls in less object code from the QCBOR
+ library.
 
  See also DecodeEngineAdvanced() and DecodeEngineBasic().
 */
@@ -362,8 +409,9 @@
     }
 
 
-    /* Must check error before referencing pE->uNumCylinders to be sure it
-     is valid. If any of the above errored, it won't be valid. */
+    /* Must check error before referencing pE->uNumCylinders to be
+       sure it is valid. If any of the above errored, it won't be
+       valid. */
     uErr = QCBORDecode_GetError(&DecodeCtx);
     if(uErr != QCBOR_SUCCESS) {
         goto Done;
@@ -387,20 +435,21 @@
     return ConvertError(uErr);
 }
 
+#endif /* EXAMPLE_DISABLE_SPIFFY_DECODE_FAST */
 
 
-
-
+#ifndef EXAMPLE_DISABLE_BASIC_DECODE
 /**
  @brief Check the type and lable of an item.
 
- @param[in] szLabel  The expected string label.
- @param[in] uQCBORType The expected type or @c QCBOR_TYPE_ANY
- @param[in] pItem  The item to check.
+ @param[in] szLabel     The expected string label.
+ @param[in] uQCBORType  The expected type or @c QCBOR_TYPE_ANY.
+ @param[in] pItem       The item to check.
 
  @retval QCBOR_ERR_LABEL_NOT_FOUND  The label doesn't match.
- @retval QCBOR_ERR_UNEXPECTED_TYPE The label matches, but the type is not as expected.
- @retval QCBOR_SUCCESS Both label and type match.
+ @retval QCBOR_ERR_UNEXPECTED_TYPE  The label matches, but the type is
+                                    not as expected.
+ @retval QCBOR_SUCCESS              Both label and type match.
  */
 QCBORError CheckLabelAndType(const char *szLabel, uint8_t uQCBORType, const QCBORItem *pItem)
 {
@@ -426,8 +475,8 @@
  @brief Decode the array of engine cylinders.
 
  @param[in] pDecodeCtx  The decode context from which to get items.
- @param[out] pE  The structure filled in from the decoding.
- @param[in] pItem The data item that is the start of the array.
+ @param[out] pE         The structure filled in from the decoding.
+ @param[in] pItem       The data item that is the start of the array.
 
  @return Either @ref EngineSuccess or an error.
 
@@ -435,15 +484,15 @@
  items in it, an error is returned.
  */
 EngineDecodeErrors DecodeCylinders(QCBORDecodeContext *pDecodeCtx,
-                                   CarEngine *pE,
-                                   const QCBORItem *pItem)
+                                   CarEngine          *pE,
+                                   const QCBORItem    *pItem)
 {
     int i = 0;
     QCBORItem Item;
 
-    /* Loop getting all the items in the array. This uses
-     nesting level to detect the end so it works for both
-     definite and indefinite length arrays. */
+    /* Loop getting all the items in the array. This uses nesting
+       level to detect the end so it works for both definite and
+       indefinite length arrays. */
     do {
         QCBORError uErr;
 
@@ -471,23 +520,21 @@
 
 
 /**
- @brief Engine decode without advanced decode features.
+ @brief Engine decode without spiffy decode.
 
  @param[in] EncodedEngine  Pointer and length of CBOR-encoded engine.
- @param[out] pE  The structure filled in from the decoding.
+ @param[out] pE            The structure filled in from the decoding.
 
  @return The decode error or success.
 
+ This is the third implementation of engine decoding, again
+ implementing the same functionality as DecodeEngineSpiffy() and
+ DecodeEngineSpiffyFaster().
+
  This version of the deocde is the most complex, but uses
- significantly less code from the QCBOR library.  It is also
- the most CPU-efficient since it does only one pass
- through the CBOR.
-
- Code size is yet to be measured, but this is probably the smallest total
- code size of all three, if just one CBOR protocol is being decoded. If
- multiple protocols are being decoded the other options.
-
- See also DecodeEngineAdvanced() and DecodeEngineAdvancedFaster().
+ significantly less code (2-3KB less on 64-bit Intel) from the QCBOR
+ library.  It is also the most CPU-efficient since it does only one
+ pass through the CBOR.
 */
 EngineDecodeErrors DecodeEngineBasic(UsefulBufC EncodedEngine, CarEngine *pE)
 {
@@ -589,74 +636,80 @@
             return EngineProtocolerror;
         }
 
-        /* Some label data item that is not known
-         (could just ignore extras data items) */
+        /* Some label data item that is not known (could just ignore
+           extras data items) */
         return EngineProtocolerror;
     }
     uReturn = EngineSuccess;
 
+    /* Catch the remainder of errors here */
+    uErr = QCBORDecode_Finish(&DecodeCtx);
+    if(uErr) {
+        uReturn = ConvertError(uErr);
+    }
+
+
+
 Done:
     return uReturn;
 }
 
-
-
+#endif /* EXAMPLE_DISABLE_BASIC_DECODE */
 
 
 int32_t RunQCborExample()
 {
-    CarEngine                  E, DecodedEngine;
-    MakeUsefulBufOnStack(   EngineBuffer, 300);
-    UsefulBufC              EncodedEngine;
+   CarEngine               E, DecodedEngine;
+   MakeUsefulBufOnStack(   EngineBuffer, 300);
+   UsefulBufC              EncodedEngine;
 
-    MakeUsefulBufOnStack(   InDefEngineBuffer, 300);
-    UsefulBufC              InDefEncodedEngine;
+   MakeUsefulBufOnStack(   InDefEngineBuffer, 300);
+   UsefulBufC              InDefEncodedEngine;
 
-    // TODO: error codes and other clean up
+   EngineDecodeErrors      uErr;
 
-    EngineInit(&E);
+   EngineInit(&E);
 
-    EncodedEngine = EncodeEngine(&E, EngineBuffer);
-
-    printf("Engine Encoded in %zu bytes\n", EncodedEngine.len);
-
-    int x = (int)DecodeEngineSpiffy(EncodedEngine, &DecodedEngine);
-    printf("Engine Decode Result: %d\n", x);
+#ifndef EXAMPLE_DISABLE_DEFINITE_LENGTH_ENCODE
+   EncodedEngine = EncodeEngineDefiniteLength(&E, EngineBuffer);
+   printf("Definite Length Engine Encoded in %zu bytes\n", EncodedEngine.len);
+#endif /* EXAMPLE_DISABLE_DEFINITE_LENGTH_ENCODE */
 
 
-    InDefEncodedEngine = EncodeEngineIndefinteLen(&E, InDefEngineBuffer);
-
-    printf("Indef Engine Encoded in %zu bytes\n", InDefEncodedEngine.len);
-
-    x = (int)DecodeEngineSpiffy(InDefEncodedEngine, &DecodedEngine);
-    printf("Indef Engine Decode Result: %d\n", x);
-
-    if(!EngineCompare(&E, &DecodedEngine)) {
-        printf("decode comparison fail\n");
-    }
+#ifndef EXAMPLE_DISABLE_INDEFINITE_LENGTH_ENCODE_ENCODE
+   InDefEncodedEngine = EncodeEngineIndefinteLen(&E, InDefEngineBuffer);
+   printf("Indef Engine Encoded in %zu bytes\n", InDefEncodedEngine.len);
+#endif /* EXAMPLE_DISABLE_INDEFINITE_LENGTH_ENCODE_ENCODE */
 
 
-    x = (int)DecodeEngineBasic(EncodedEngine, &DecodedEngine);
-    printf("Engine Basic Decode Result: %d\n", x);
+#ifndef EXAMPLE_DISABLE_SPIFFY_DECODE
+   uErr = DecodeEngineSpiffy(EncodedEngine, &DecodedEngine);
+   printf("Spiffy Engine Decode Result: %d\n", uErr);
 
-    if(!EngineCompare(&E, &DecodedEngine)) {
-        printf("decode comparison fail\n");
-    }
+   if(!EngineCompare(&E, &DecodedEngine)) {
+      printf("Spiffy Engine Decode comparison fail\n");
+   }
+#endif /* EXAMPLE_DISABLE_SPIFFY_DECODE */
 
+#ifndef EXAMPLE_DISABLE_SPIFFY_DECODE_FAST
+   uErr = DecodeEngineSpiffyFaster(EncodedEngine, &DecodedEngine);
+   printf("Faster Spiffy Engine Decode Result: %d\n", uErr);
 
-    x = (int)DecodeEngineBasic(InDefEncodedEngine, &DecodedEngine);
-    printf("Indef Engine Basic Decode Result: %d\n", x);
+   if(!EngineCompare(&E, &DecodedEngine)) {
+      printf("Faster Spiffy Engine Decode comparison fail\n");
+   }
+#endif /* EXAMPLE_DISABLE_SPIFFY_DECODE_FAST */
 
-    if(!EngineCompare(&E, &DecodedEngine)) {
-        printf("indef decode comparison fail\n");
-    }
+#ifndef EXAMPLE_DISABLE_BASIC_DECODE
+   uErr = DecodeEngineBasic(EncodedEngine, &DecodedEngine);
+   printf("Engine Basic Decode Result: %d\n", uErr);
 
-    x = (int)DecodeEngineSpiffyFaster(EncodedEngine, &DecodedEngine);
-    printf("Efficient Engine Basic Decode Result: %d\n", x);
+   if(!EngineCompare(&E, &DecodedEngine)) {
+      printf("Engine Basic Decode comparison fail\n");
+   }
+#endif /* EXAMPLE_DISABLE_BASIC_DECODE */
 
-    if(!EngineCompare(&E, &DecodedEngine)) {
-        printf("effcieit decode comparison fail\n");
-    }
-   
-    return 0;
+   printf("\n");
+
+   return 0;
 }