Merge branch 'SpiffyDecode' of https://github.com/laurencelundblade/QCBOR into SpiffyDecode
diff --git a/QCBOR.xcodeproj/project.pbxproj b/QCBOR.xcodeproj/project.pbxproj
index 590ffce..1155fdb 100644
--- a/QCBOR.xcodeproj/project.pbxproj
+++ b/QCBOR.xcodeproj/project.pbxproj
@@ -117,8 +117,9 @@
 		E743D10824CEDE2D0017899F /* qcbor_spiffy_decode.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 3; lastKnownFileType = sourcecode.c.h; name = qcbor_spiffy_decode.h; path = inc/qcbor/qcbor_spiffy_decode.h; sourceTree = "<group>"; tabWidth = 3; };
 		E743D11B24DD4EF50017899F /* QCBOR_Disable_HW_Float */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = QCBOR_Disable_HW_Float; sourceTree = BUILT_PRODUCTS_DIR; };
 		E743D13124DE05CC0017899F /* QCBOR_Disable_Preferred_Float */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = QCBOR_Disable_Preferred_Float; sourceTree = BUILT_PRODUCTS_DIR; };
+		E743D132251014E60017899F /* Tagging.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; name = Tagging.md; path = doc/Tagging.md; sourceTree = "<group>"; };
+		E743D13325115A270017899F /* TRY SPIFFY DECODE.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "TRY SPIFFY DECODE.md"; sourceTree = "<group>"; };
 		E74BF411245D6713002CE8E8 /* UsefulBuf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UsefulBuf.h; path = inc/qcbor/UsefulBuf.h; sourceTree = "<group>"; };
-		E74FA9FE247D2F2C003F8ECE /* Tagging.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = Tagging.md; sourceTree = "<group>"; };
 		E772022723B52C02006E966E /* QCBOR_Disable_Exp_Mantissa */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = QCBOR_Disable_Exp_Mantissa; sourceTree = BUILT_PRODUCTS_DIR; };
 		E776E07C214ADF7F00E67947 /* QCBOR */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = QCBOR; sourceTree = BUILT_PRODUCTS_DIR; };
 		E776E08C214AE07400E67947 /* qcbor_encode.c */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 3; lastKnownFileType = sourcecode.c.c; name = qcbor_encode.c; path = src/qcbor_encode.c; sourceTree = "<group>"; tabWidth = 3; };
@@ -128,7 +129,7 @@
 		E776E096214AE0C700E67947 /* cmd_line_main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmd_line_main.c; sourceTree = "<group>"; };
 		E776E161214EE19C00E67947 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
 		E78C91DE240C90C100F4CECE /* qcbor_decode.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 3; lastKnownFileType = sourcecode.c.h; name = qcbor_decode.h; path = inc/qcbor/qcbor_decode.h; sourceTree = "<group>"; tabWidth = 3; };
-		E78C91DF240C90C100F4CECE /* qcbor_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = qcbor_common.h; path = inc/qcbor/qcbor_common.h; sourceTree = "<group>"; };
+		E78C91DF240C90C100F4CECE /* qcbor_common.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 3; lastKnownFileType = sourcecode.c.h; name = qcbor_common.h; path = inc/qcbor/qcbor_common.h; sourceTree = "<group>"; tabWidth = 3; };
 		E78C91E0240C90C100F4CECE /* qcbor_private.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 3; lastKnownFileType = sourcecode.c.h; name = qcbor_private.h; path = inc/qcbor/qcbor_private.h; sourceTree = "<group>"; tabWidth = 3; };
 		E78C91E1240C90C100F4CECE /* qcbor_encode.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 3; lastKnownFileType = sourcecode.c.h; name = qcbor_encode.h; path = inc/qcbor/qcbor_encode.h; sourceTree = "<group>"; tabWidth = 3; };
 /* End PBXFileReference section */
@@ -178,7 +179,8 @@
 			isa = PBXGroup;
 			children = (
 				E776E161214EE19C00E67947 /* README.md */,
-				E74FA9FE247D2F2C003F8ECE /* Tagging.md */,
+				E743D13325115A270017899F /* TRY SPIFFY DECODE.md */,
+				E743D132251014E60017899F /* Tagging.md */,
 				E776E096214AE0C700E67947 /* cmd_line_main.c */,
 				E776E092214AE07C00E67947 /* inc */,
 				E776E08B214AE06600E67947 /* src */,
diff --git a/README.md b/README.md
index 0ee7fef..523d220 100644
--- a/README.md
+++ b/README.md
@@ -25,18 +25,18 @@
 
 **Implemented in C with minimal dependency** – The only dependencies
   are C99, <stdint.h>, <stddef.h>, <stdbool.h> and <string.h> making
-  it highly portable. <math.h> and <fenv.h> are used too, but their use can
-  disabled. No #ifdefs or compiler options need to be set for QCBOR to
-  run correctly.
+  it highly portable. <math.h> and <fenv.h> are used too, but their
+  use can disabled. No #ifdefs or compiler options need to be set for
+  QCBOR to run correctly.
 
-**Focused on C / native data representation** – Careful conversion
-  of CBOR data types in to C data types, carefully handling
-  over and underflow, strict typing and such so the caller
-  doesn't have to worry so much about this and so code
-  using QCBOR passes static analyzers easier.  Simpler code because
-  there is no support for encoding/decoding to/from JSON, pretty
-  printing, diagnostic notation... Only encoding from native C
-  representations and decoding to native C representations is supported.
+**Focused on C / native data representation** – Careful conversion of
+  CBOR data types in to C data types, carefully handling over and
+  underflow, strict typing and such so the caller doesn't have to
+  worry so much about this and so code using QCBOR passes static
+  analyzers easier.  Simpler code because there is no support for
+  encoding/decoding to/from JSON, pretty printing, diagnostic
+  notation... Only encoding from native C representations and decoding
+  to native C representations is supported.
 
 **Small simple memory model** – Malloc is not needed. The encode
   context is 174 bytes, decode context is 312 bytes and the
@@ -46,10 +46,11 @@
   of memory usage making it good for embedded implementations that
   have to run in small fixed memory.
 
-**Supports all of RFC 7049 except strict mode and map sorting** – With some size
-  limits, all data types and formats specified are supported. The same
-  decoding API supports both definite and indefinite-length map and
-  array decoding. Decoding indefinite length strings is supported but requires a string allocator (see
+**Supports all of RFC 7049 except strict mode and map sorting** – With
+  some size limits, all data types and formats specified are
+  supported. The same decoding API supports both definite and
+  indefinite-length map and array decoding. Decoding indefinite length
+  strings is supported but requires a string allocator (see
   documentation).
 
 **Extensible and general** – Provides a way to handle data types that
@@ -71,9 +72,10 @@
 
 ## Code Status
 
-This version with spiffy decode in fall of 2020 is stable, but not quite 
-to the commercial quality level of the previous code. A little more
-testing is necessary for it to be at the previous commercial quality level.
+This version with spiffy decode in fall of 2020 is stable, but not
+quite to the commercial quality level of the previous code. A little
+more testing is necessary for it to be at the previous commercial
+quality level.
 
 Encoding features are generally mature, well tested and commercial quality.
 
@@ -132,16 +134,16 @@
 
 ## Spiffy Decode
 
-In mid-2020 a large addition makes the decoder more powerful and easy
+In Fall 2020 a large addition makes the decoder more powerful and easy
 to use. Backwards compatibility with the previous API is retained as
 the new decoding features layer on top of it.
 
 The first noticable addition are functions to get particular data
-types.  These are an alternative to and built on top of QCBORDecode_GetNext() that
-does the type checking and in some cases sophisticated type
-conversion. They track an error state internally so the caller doesn't
-need.  They also handle the CBOR tagged data types thoroughly and
-properly.
+types.  These are an alternative to and built on top of
+QCBORDecode_GetNext() that does the type checking and in some cases
+sophisticated type conversion. They track an error state internally so
+the caller doesn't need.  They also handle the CBOR tagged data types
+thoroughly and properly.
 
 In line with all the new get functions for non-aggregate types there
 are new functions for aggregate types. When a map is expected,
@@ -180,6 +182,17 @@
 maps and arrays without the caller having to do anything. This includes 
 mixed definite and indefinte maps and arrays.
 
+### Uncompatible Changes
+
+Encoding of MIME tags now uses tag 257 instead of 36. Tag 257 accommodates
+binary and text-based MIME messages where tag 36 does not. Decoding
+supports either.
+
+The number of nested tags on a data item is limited to four. Previously it was
+unlimited.
+
+Some of the error codes have changed.
+
 ## Floating Point Support
 
 By default, all QCBOR floating-point features are enabled. This includes
@@ -235,8 +248,8 @@
  Using any of the functions that search maps by a label will bring in
  about 1KB of code. This is usually wothwhile though because it
  handles does a complex job which includes duplicate label detection,
- item type checking and decoding both definite and indefinite length maps. This
- code is also shared for each map that is searched.
+ item type checking and decoding both definite and indefinite length
+ maps. This code is also shared for each map that is searched.
  
  If QCBOR is set up as a shared library across apps on the system
  there may be a substantial overall code size reduction from using
diff --git a/SpiffyDiffs.md b/SpiffyDiffs.md
new file mode 100644
index 0000000..64e53d4
--- /dev/null
+++ b/SpiffyDiffs.md
@@ -0,0 +1,2 @@
+#  <#Title#>
+
diff --git a/doc/Tagging.md b/doc/Tagging.md
index 85fa3a8..4ba5ea2 100644
--- a/doc/Tagging.md
+++ b/doc/Tagging.md
@@ -1,5 +1,7 @@
 #  Types and Tagging in CBOR
 
+@anchor CBORTags
+
 ## New Types
 
 CBOR provides a means for defining new data types beyond the primitive
@@ -223,7 +225,9 @@
 is a registry of data types.
 
 
+## See Also
 
+See @ref Tags-Overview and @ref Tag-Usage.
 
 
 
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;
 }
diff --git a/inc/qcbor/UsefulBuf.h b/inc/qcbor/UsefulBuf.h
index 41a7b56..6fe33a1 100644
--- a/inc/qcbor/UsefulBuf.h
+++ b/inc/qcbor/UsefulBuf.h
@@ -1493,6 +1493,19 @@
 
 
 /**
+ @brief Gets the input buffer length.
+
+ @param[in] pUInBuf  Pointer to the @ref UsefulInputBuf.
+
+ @return The length of the input buffer.
+
+ This returns the length of th input buffer from UsefulInputBuf_Init()
+ of from UsefulInputBuf_SetBufferLength().
+ */
+static inline size_t UsefulInputBuf_GetBufferLength(UsefulInputBuf *pUInBuf);
+
+
+/**
  @brief Sets the input buffer length (use with caution)
 
  @param[in] pUInBuf  Pointer to the @ref UsefulInputBuf.
@@ -1502,14 +1515,14 @@
  to handle CBOR that is wrapped and embedded in CBOR.
 
  Since this allows setting the length beyond the length of the
- original input buffer it allows the overall safety to
- be undermined.
+ original input buffer it allows the overall safety of UsefulInputBug to
+ be undermined. Use it carefully.
 
  The new length given here should always be equal to or less than
  the length given when UsefulInputBuf_Init() was called.
 
  */
-static void UsefulInputBuf_SetBufferLen(UsefulInputBuf *pUInBuf, size_t uNewLen);
+static void UsefulInputBuf_SetBufferLength(UsefulInputBuf *pUInBuf, size_t uNewLen);
 
 
 /*----------------------------------------------------------
@@ -1934,7 +1947,7 @@
 }
 
 
-static inline size_t UsefulInputBuf_GetLength(UsefulInputBuf *pMe)
+static inline size_t UsefulInputBuf_GetBufferLength(UsefulInputBuf *pMe)
 {
     return pMe->UB.len;
 }
@@ -1969,7 +1982,7 @@
       return 0;
    }
 
-   // subtraction can't go neative because of check above
+   // subtraction can't go negative because of check above
    return pMe->UB.len - pMe->cursor;
 }
 
@@ -2153,7 +2166,7 @@
 }
 
 
-static inline void UsefulInputBuf_SetBufferLen(UsefulInputBuf *pMe, size_t uNewLen)
+static inline void UsefulInputBuf_SetBufferLength(UsefulInputBuf *pMe, size_t uNewLen)
 {
     pMe->UB.len = uNewLen;
 }
diff --git a/inc/qcbor/qcbor_common.h b/inc/qcbor/qcbor_common.h
index 400f023..62858de 100644
--- a/inc/qcbor/qcbor_common.h
+++ b/inc/qcbor/qcbor_common.h
@@ -243,42 +243,41 @@
    /** The encode or decode completely correctly. */
    QCBOR_SUCCESS = 0,
 
-    /** The buffer provided for the encoded output when doing encoding
-        was too small and the encoded output will not fit. */
-    QCBOR_ERR_BUFFER_TOO_SMALL = 1,
-   
-    /** During encoding, an attempt to create simple value between 24
-        and 31. */
-    QCBOR_ERR_ENCODE_UNSUPPORTED = 2,
+   /** The buffer provided for the encoded output when doing encoding
+       was too small and the encoded output will not fit. */
+   QCBOR_ERR_BUFFER_TOO_SMALL = 1,
 
-    /** During encoding, the length of the encoded CBOR exceeded @c
-        UINT32_MAX.
-     */
-    QCBOR_ERR_BUFFER_TOO_LARGE = 3,
+   /** During encoding, an attempt to create simple value between 24
+       and 31. */
+   QCBOR_ERR_ENCODE_UNSUPPORTED = 2,
 
-    /** During encoding, the array or map nesting was deeper than this
-        implementation can handle. Note that in the interest of code
-        size and memory use, this implementation has a hard limit on
-        array nesting. The limit is defined as the constant @ref
-        QCBOR_MAX_ARRAY_NESTING. */
-    QCBOR_ERR_ARRAY_NESTING_TOO_DEEP = 4,
+   /** During encoding, the length of the encoded CBOR exceeded @c
+       UINT32_MAX. */
+   QCBOR_ERR_BUFFER_TOO_LARGE = 3,
 
-    /** During encoding, @c QCBOREncode_CloseXxx() called with a
-        different type than is currently open.  */
-    QCBOR_ERR_CLOSE_MISMATCH = 5,
+   /** During encoding, the array or map nesting was deeper than this
+       implementation can handle. Note that in the interest of code
+       size and memory use, this implementation has a hard limit on
+       array nesting. The limit is defined as the constant @ref
+       QCBOR_MAX_ARRAY_NESTING. */
+   QCBOR_ERR_ARRAY_NESTING_TOO_DEEP = 4,
 
-    /** During encoding, the array or map had too many items in it.
-        This limit @ref QCBOR_MAX_ITEMS_IN_ARRAY, typically 65,535. */
-    QCBOR_ERR_ARRAY_TOO_LONG = 6,
+   /** During encoding, @c QCBOREncode_CloseXxx() called with a
+       different type than is currently open.  */
+   QCBOR_ERR_CLOSE_MISMATCH = 5,
 
-    /** During encoding, more arrays or maps were closed than
-        opened. This is a coding error on the part of the caller of
-        the encoder. */
-    QCBOR_ERR_TOO_MANY_CLOSES = 7,
+   /** During encoding, the array or map had too many items in it.
+       This limit @ref QCBOR_MAX_ITEMS_IN_ARRAY, typically 65,535. */
+   QCBOR_ERR_ARRAY_TOO_LONG = 6,
 
-    /** During encoding the number of array or map opens was not
-        matched by the number of closes. */
-    QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN = 8,
+   /** During encoding, more arrays or maps were closed than
+       opened. This is a coding error on the part of the caller of the
+       encoder. */
+   QCBOR_ERR_TOO_MANY_CLOSES = 7,
+
+   /** During encoding the number of array or map opens was not
+       matched by the number of closes. */
+   QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN = 8,
 
 #define QCBOR_START_OF_NOT_WELL_FORMED_ERRORS 9
 
@@ -298,140 +297,138 @@
        well-formed.*/
    QCBOR_ERR_UNSUPPORTED = 11,
 
-    /** During decoding, the an array or map was not fully consumed.
-        Returned by QCBORDecode_Finish(). The CBOR is not
-        well-formed. */
-    QCBOR_ERR_ARRAY_OR_MAP_UNCONSUMED = 12,
+   /** During decoding, the an array or map was not fully consumed.
+       Returned by QCBORDecode_Finish(). The CBOR is not
+       well-formed. */
+   QCBOR_ERR_ARRAY_OR_MAP_UNCONSUMED = 12,
 
-   /** During decoding, an integer type is encoded with a bad length (
-       that of an indefinite length string). The CBOR is not-well
+   /** During decoding, an integer type is encoded with a bad length
+       (that of an indefinite length string). The CBOR is not-well
        formed. */
    QCBOR_ERR_BAD_INT = 13,
 
-    /** During decoding, one of the chunks in an indefinite-length
-        string is not of the type of the start of the string.  The
-        CBOR is not well-formed.  This error makes no further decoding
-        possible. */
-    QCBOR_ERR_INDEFINITE_STRING_CHUNK = 14,
+#define QCBOR_START_OF_UNRECOVERABLE_DECODE_ERRORS 14
 
-#define QCBOR_START_OF_UNRECOVERABLE_DECODE_ERRORS 15
-    /** During decoding, hit the end of the given data to decode. For
-        example, a byte string of 100 bytes was expected, but the end
-        of the input was hit before finding those 100 bytes.
-        Corrupted CBOR input will often result in this error. See also
-        @ref QCBOR_ERR_NO_MORE_ITEMS. The CBOR is not well-formed.
-        This error makes no further decoding possible.
-      */
-    QCBOR_ERR_HIT_END = 15,
+   /** During decoding, one of the chunks in an indefinite-length
+       string is not of the type of the start of the string.  The CBOR
+       is not well-formed.  This error makes no further decoding
+       possible. */
+   QCBOR_ERR_INDEFINITE_STRING_CHUNK = 14,
 
-    /** During decoding, a break occurred outside an indefinite-length
-        item. The CBOR is not well-formed. This error makes no further
-        decoding possible. */
-    QCBOR_ERR_BAD_BREAK = 16,
+   /** During decoding, hit the end of the given data to decode. For
+       example, a byte string of 100 bytes was expected, but the end
+       of the input was hit before finding those 100 bytes.  Corrupted
+       CBOR input will often result in this error. See also @ref
+       QCBOR_ERR_NO_MORE_ITEMS. The CBOR is not well-formed.  This
+       error makes no further decoding possible. */
+   QCBOR_ERR_HIT_END = 15,
+
+   /** During decoding, a break occurred outside an indefinite-length
+       item. The CBOR is not well-formed. This error makes no further
+       decoding possible. */
+   QCBOR_ERR_BAD_BREAK = 16,
 
 #define QCBOR_END_OF_NOT_WELL_FORMED_ERRORS 16
 
-    /**
-        During decoding, the input is too large. It is greater than
-     UINT32_MAX - 1. This is an implementation limit. This error makes no further decoding possible.
-     */
-    QCBOR_ERR_INPUT_TOO_LARGE = 17,
+   /** During decoding, the input is too large. It is greater than
+       QCBOR_MAX_DECODE_INPUT_SIZE. This is an implementation limit.
+       This error makes no further decoding possible. */
+   QCBOR_ERR_INPUT_TOO_LARGE = 17,
 
-    /** During decoding, the array or map nesting was deeper than this
-        implementation can handle. Note that in the interest of code
-        size and memory use, this implementation has a hard limit on
-        array nesting. The limit is defined as the constant @ref
-        QCBOR_MAX_ARRAY_NESTING. This error makes no further decoding
-        possible. */
-    QCBOR_ERR_ARRAY_DECODE_NESTING_TOO_DEEP = 18,
+   /** During decoding, the array or map nesting was deeper than this
+       implementation can handle. Note that in the interest of code
+       size and memory use, this implementation has a hard limit on
+       array nesting. The limit is defined as the constant @ref
+       QCBOR_MAX_ARRAY_NESTING. This error makes no further decoding
+       possible. */
+   QCBOR_ERR_ARRAY_DECODE_NESTING_TOO_DEEP = 18,
 
-    /** During decoding, the array or map had too many items in it.
-        This limit @ref QCBOR_MAX_ITEMS_IN_ARRAY, typically 65,534,
-        UINT16_MAX - 1. This error makes no further decoding
-        possible. */
-    QCBOR_ERR_ARRAY_DECODE_TOO_LONG = 19,
+   /** During decoding, the array or map had too many items in it.
+       This limit @ref QCBOR_MAX_ITEMS_IN_ARRAY, typically 65,534,
+       UINT16_MAX - 1. This error makes no further decoding
+       possible. */
+   QCBOR_ERR_ARRAY_DECODE_TOO_LONG = 19,
 
-    /** More than @ref QCBOR_MAX_TAGS_PER_ITEM tags encounterd for a
-        CBOR ITEM.  @ref QCBOR_MAX_TAGS_PER_ITEM is a limit of this
-        implementation.  During decoding, too many tags in the
-        caller-configured tag list, or not enough space in @ref
-        QCBORTagListOut. This error makes no further decoding
-        possible.  */
-    QCBOR_ERR_TOO_MANY_TAGS = 20,
+   /** When decoding, a string's size is greater than what a size_t
+       can hold less 4. In all but some very strange situations this
+       is because of corrupt input CBOR and should be treated as
+       such. The strange situation is a CPU with a very small size_t
+       (e.g., a 16-bit CPU) and a large string (e.g., > 65KB). This
+       error makes no further decoding possible. */
+   QCBOR_ERR_STRING_TOO_LONG = 20,
 
-    /** When decoding, a string's size is greater than what a size_t
-        can hold less 4. In all but some very strange situations this
-        is because of corrupt input CBOR and should be treated as
-        such. The strange situation is a CPU with a very small size_t
-        (e.g., a 16-bit CPU) and a large string (e.g., > 65KB). This
-        error makes no further decoding possible.
-     */
-    QCBOR_ERR_STRING_TOO_LONG = 21,
+   /** Something is wrong with a decimal fraction or bigfloat such as
+       it not consisting of an array with two integers. This error
+       makes no further decoding possible. */
+   QCBOR_ERR_BAD_EXP_AND_MANTISSA = 21,
 
-    /** Something is wrong with a decimal fraction or bigfloat such as
-        it not consisting of an array with two integers. This error
-        makes no further decoding possible. */
-    QCBOR_ERR_BAD_EXP_AND_MANTISSA = 22,
+   /** Unable to decode an indefinite-length string because no string
+       allocator was configured. See QCBORDecode_SetMemPool() or
+       QCBORDecode_SetUpAllocator().  This error makes no further
+       decoding possible.*/
+   QCBOR_ERR_NO_STRING_ALLOCATOR = 22,
 
-    /** Unable to decode an indefinite-length string because no string
-        allocator was configured. See QCBORDecode_SetMemPool() or
-        QCBORDecode_SetUpAllocator().  This error makes no further
-        decoding possible.*/
-    QCBOR_ERR_NO_STRING_ALLOCATOR = 23,
+   /** Error allocating space for a string, usually for an
+       indefinite-length string. This error makes no further decoding
+       possible. */
+   QCBOR_ERR_STRING_ALLOCATE = 23,
 
-    /** Error allocating space for a string, usually for an
-        indefinite-length string. This error makes no further decoding
-        possible. */
-    QCBOR_ERR_STRING_ALLOCATE = 24,
+#define QCBOR_END_OF_UNRECOVERABLE_DECODE_ERRORS 23
 
-#define QCBOR_END_OF_UNRECOVERABLE_DECODE_ERRORS 24
+   /** More than @ref QCBOR_MAX_TAGS_PER_ITEM tags encounterd for a
+       CBOR ITEM.  @ref QCBOR_MAX_TAGS_PER_ITEM is a limit of this
+       implementation.  During decoding, too many tags in the
+       caller-configured tag list, or not enough space in @ref
+       QCBORTagListOut. This error makes no further decoding
+       possible.  */
+   QCBOR_ERR_TOO_MANY_TAGS = 24,
 
-    /** During decoding, the type of the label for a map entry is not
-        one that can be handled in the current decoding
-        mode. Typically this is because a label is not an intger or a
-        string. This is an implemation limit. */
-    QCBOR_ERR_MAP_LABEL_TYPE = 25,
+   /** During decoding, the type of the label for a map entry is not
+       one that can be handled in the current decoding mode. Typically
+       this is because a label is not an intger or a string. This is
+       an implemation limit. */
+   QCBOR_ERR_MAP_LABEL_TYPE = 25,
 
-    /** When decodeing for a specific type, the type was not was
-        expected.  */
-    QCBOR_ERR_UNEXPECTED_TYPE = 26,
+   /** When decodeing for a specific type, the type was not was
+       expected.  */
+   QCBOR_ERR_UNEXPECTED_TYPE = 26,
 
-    /** This occurs when decoding one of the tags that QCBOR
-        processed internally.  The content of a tag was of the wrong
-        type. (They were known as "Optional Tags" in RFC 7049. */
-     QCBOR_ERR_BAD_OPT_TAG = 27,
+   /** This occurs when decoding one of the tags that QCBOR processed
+       internally.  The content of a tag was of the wrong type. (They
+       were known as "Optional Tags" in RFC 7049. */
+   QCBOR_ERR_BAD_OPT_TAG = 27,
 
-    /** Duplicate label in map detected */
-    QCBOR_ERR_DUPLICATE_LABEL = 28,
+   /** Duplicate label in map detected */
+   QCBOR_ERR_DUPLICATE_LABEL = 28,
 
-    /** During decoding, the buffer given to QCBORDecode_SetMemPool()
-        is either too small, smaller than
-        QCBOR_DECODE_MIN_MEM_POOL_SIZE or too large, larger than
-        UINT32_MAX.
-        */
-    QCBOR_ERR_MEM_POOL_SIZE = 29,
+   /** During decoding, the buffer given to QCBORDecode_SetMemPool()
+       is either too small, smaller than
+       QCBOR_DECODE_MIN_MEM_POOL_SIZE or too large, larger than
+       UINT32_MAX. */
+   QCBOR_ERR_MEM_POOL_SIZE = 29,
 
-    /** During decoding, an integer smaller than INT64_MIN was
-        received (CBOR can represent integers smaller than INT64_MIN,
-        but C cannot). */
-    QCBOR_ERR_INT_OVERFLOW = 30,
+   /** During decoding, an integer smaller than INT64_MIN was received
+       (CBOR can represent integers smaller than INT64_MIN, but C
+       cannot). */
+   QCBOR_ERR_INT_OVERFLOW = 30,
 
-    /** During decoding, a date greater than +- 292 billion years from
-        Jan 1 1970 encountered during parsing. This is an implementation limit. */
-    QCBOR_ERR_DATE_OVERFLOW = 31,
+   /** During decoding, a date greater than +- 292 billion years from
+       Jan 1 1970 encountered during parsing. This is an
+       implementation limit. */
+   QCBOR_ERR_DATE_OVERFLOW = 31,
 
-    /** During decoding, @c QCBORDecode_ExitXxx() was called for a
-        different type than @c QCBORDecode_EnterXxx(). */
-    QCBOR_ERR_EXIT_MISMATCH = 32,
+   /** During decoding, @c QCBORDecode_ExitXxx() was called for a
+       different type than @c QCBORDecode_EnterXxx(). */
+   QCBOR_ERR_EXIT_MISMATCH = 32,
 
-    /** All well-formed data items have been consumed and there are no
-        more. If parsing a CBOR stream this indicates the non-error end
-        of the stream. If parsing a CBOR stream / sequence, this
-        probably indicates that some data items expected are not
-        present.  See also @ref QCBOR_ERR_HIT_END. */
+   /** All well-formed data items have been consumed and there are no
+       more. If parsing a CBOR stream this indicates the non-error end
+       of the stream. If parsing a CBOR stream / sequence, this
+       probably indicates that some data items expected are not
+       present.  See also @ref QCBOR_ERR_HIT_END. */
    QCBOR_ERR_NO_MORE_ITEMS = 33,
 
-   /** When finding an item by lable, an item with the requested label
+   /** When finding an item by lablel, an item with the requested label
        was not found. */
    QCBOR_ERR_LABEL_NOT_FOUND = 34,
 
@@ -443,34 +440,31 @@
        small for the conversion target */
    QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW = 36,
 
-   /** Trying to get an item by label when a map has not been entered. */
+   /** Trying to get an item by label when a map has not been
+       entered. */
    QCBOR_ERR_MAP_NOT_ENTERED = 37,
 
    /** A callback indicates processing should not continue for some
        non-CBOR reason */
    QCBOR_ERR_CALLBACK_FAIL = 38,
 
-   /** Trying to get something by label when not entered into a
-       map.  */
-   QCBOR_ERR_NOT_A_MAP = 39,
-
    /** Decoding of floating-point epoch dates is unsupported and a
        floating-point date was encountered by the decoder. */
-   QCBOR_ERR_FLOAT_DATE_DISABLED = 40,
+   QCBOR_ERR_FLOAT_DATE_DISABLED = 39,
 
    /** Support for half-precision float decoding is disabled. */
-   QCBOR_ERR_HALF_PRECISION_DISABLED = 41,
+   QCBOR_ERR_HALF_PRECISION_DISABLED = 40,
 
    /** Use of floating-point HW is disabled. This affects all type
        conversions to and from double and float types. */
-   QCBOR_ERR_HW_FLOAT_DISABLED = 42,
+   QCBOR_ERR_HW_FLOAT_DISABLED = 41,
 
    /** Unable to complete operation because a floating-point value
        that is a NaN (not a number), that is too large, too small,
        infinity or -infinity was encountered in encoded CBOR. Usually
        this because conversion of the float-point value was being
        attempted. */
-    QCBOR_ERR_FLOAT_EXCEPTION = 43,
+    QCBOR_ERR_FLOAT_EXCEPTION = 42,
 
    /* This is stored in uint8_t; never add values > 255 */
 } QCBORError;
diff --git a/inc/qcbor/qcbor_decode.h b/inc/qcbor/qcbor_decode.h
index 5c72fac..ca294f1 100644
--- a/inc/qcbor/qcbor_decode.h
+++ b/inc/qcbor/qcbor_decode.h
@@ -145,8 +145,13 @@
    /* This is stored in uint8_t in places; never add values > 255 */
 } QCBORDecodeMode;
 
+/**
+ The maximum size of input to the decoder. Slightly less than UINT32_MAX
+ to make room for some special indicator values.
+ */
+#define QCBOR_MAX_DECODE_INPUT_SIZE (UINT32_MAX - 2)
 
-/*
+/**
  The maximum number of tags that may occur on an individual nested
  item. Typically 4.
  */
@@ -173,8 +178,9 @@
 #define QCBOR_TYPE_MAP            5
 /** Type for a buffer full of bytes. Data is in @c val.string. */
 #define QCBOR_TYPE_BYTE_STRING    6
-/** Type for a UTF-8 string. It is not NULL-terminated. Data is in @c
-    val.string.  */
+/** Type for a UTF-8 string. It is not NULL-terminated. See
+    QCBOREncode_AddText() for a discussion of line endings in CBOR. Data
+    is in @c val.string.  */
 #define QCBOR_TYPE_TEXT_STRING    7
 /** Type for a positive big number. Data is in @c val.bignum, a
     pointer and a length. */
@@ -294,7 +300,7 @@
 /**
  The main data structure that holds the type, value and other info for
  a decoded item returned by QCBORDecode_GetNext() and
- QCBORDecode_GetNextWithTags().
+ and methods.
 
  This size of this may vary by compiler but is roughly 56 bytes on
  a 64-bit CPU and 52 bytes on a 32-bit CPU.
@@ -1109,6 +1115,8 @@
  incorrect lengths or array counts are unrecoverable. Unrecoverable
  errors also occur when certain implementation limits such as the
  limit on array and map nesting occur.
+
+ The specific errors are a range of the errors in @ref QCBORError.
  */
 static bool QCBORDecode_IsUnrecoverableError(QCBORError uErr);
 
@@ -1263,6 +1271,15 @@
    }
 }
 
+// A few sanity checks on size constants and special value lenghts
+#if  QCBOR_MAP_OFFSET_CACHE_INVALID < QCBOR_MAX_DECODE_INPUT_SIZE
+#error QCBOR_MAP_OFFSET_CACHE_INVALID is too large
+#endif
+
+#if QCBOR_NON_BOUNDED_OFFSET < QCBOR_MAX_DECODE_INPUT_SIZE
+#error QCBOR_NON_BOUNDED_OFFSET is too large
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/inc/qcbor/qcbor_encode.h b/inc/qcbor/qcbor_encode.h
index b5492be..3b92943 100644
--- a/inc/qcbor/qcbor_encode.h
+++ b/inc/qcbor/qcbor_encode.h
@@ -101,10 +101,9 @@
 
  - "Key": See "Label" above.
 
- - "Tag": Optional integer that can be added before each data item
- usually to indicate it is new or more specific data type. For
- example, a tag can indicate an integer is a date, or that a map is to
- be considered a type (analogous to a typedef in C).
+ - "Tag": A data item that is an explicitly labeled new data
+ type made up of the tagging integer and the tag content.
+ See @Tags-Overview and @Tag-Usage.
 
  - "Initial Byte": The first byte of an encoded item. Encoding and
  decoding of this byte is taken care of by the implementation.
@@ -220,11 +219,7 @@
 
  @anchor Tags-Overview
 
-
-
-
-
- Any CBOR data item can be tagged to add semantics, define a new data
+ Any CBOR data item can be made into a tag to add semantics, define a new data
  type or such. Some tags are fully standardized and some are just
  registered. Others are not registered and used in a proprietary way.
 
@@ -250,6 +245,8 @@
  that the new value doesn't collide with one that is registered. The
  value of these tags must be 256 or larger.
 
+ See also @ref CBORTags and @ref Tag-Usage
+
  The encoding side of tags not built-in is handled by
  QCBOREncode_AddTag() and is relatively simple. Tag decoding is more
  complex and mainly handled by QCBORDecode_GetNext(). Decoding of the
@@ -352,12 +349,13 @@
 
 
 /**
- Output the full CBOR tag. See @Tags-Overview.
+ Output the full CBOR tag. See @ref CBORTags, @ref Tag-Usage and @ref Tags-Overview.
  */
 #define QCBOR_ENCODE_AS_TAG      0
 
 /**
-  Output only the 'borrowed' content format for the relevant tag. See @Tags-Overview.
+  Output only the 'borrowed' content format for the relevant tag.
+  See @ref CBORTags, @ref Tag-Usage and @ref Tags-Overview.
  */
 #define QCBOR_ENCODE_AS_BORROWED 1
 
@@ -490,6 +488,23 @@
  lengths greater. This limit to 4GB for a text string should not be a
  problem.
 
+ Text lines in Internet protocols (on the wire) are delimited by
+ either a CRLF or just an LF. Officially many protocols specify CRLF,
+ but implementations often work with either. CBOR type 3 text can be
+ either line ending, even a mixture of both.
+
+ Operating systems usually have a line end convention. Windows uses
+ CRLF. Linux and MacOS use LF. Some applications on a given OS may
+ work with either and some may not.
+
+ The majority of use cases and CBOR protocols using type 3 text will
+ work with either line ending. However, some use cases or protocols
+ may not work with either in which case translation to and/or from the
+ local line end convention, typically that of the OS, is necessary.
+
+ QCBOR does no line ending translation for type 3 text when encoding
+ and decoding.
+
  Error handling is the same as QCBOREncode_AddInt64().
  */
 static void QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text);
@@ -642,15 +657,15 @@
  tags. See QCBORDecode_GetNext() for discussion of decoding custom
  tags.
 */
-void QCBOREncode_AddTag(QCBOREncodeContext *pCtx,uint64_t uTag);
+void QCBOREncode_AddTag(QCBOREncodeContext *pCtx, uint64_t uTag);
 
 
 /**
  @brief  Add an epoch-based date.
 
  @param[in] pCtx  The encoding context to add the date to.
- @param[in] uTag  Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
- @param[in] date  Number of seconds since 1970-01-01T00:00Z in UTC time.
+ @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
+ @param[in] nDate  Number of seconds since 1970-01-01T00:00Z in UTC time.
 
  As per RFC 7049 this is similar to UNIX/Linux/POSIX dates. This is
  the most compact way to specify a date and time in CBOR. Note that
@@ -675,18 +690,31 @@
 
  Error handling is the same as QCBOREncode_AddInt64().
  */
-static void QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pCtx, uint8_t uTag, int64_t date);
+static void QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pCtx,
+                                      uint8_t             uTagRequirement,
+                                      int64_t             nDate);
 
-static void QCBOREncode_AddTDateEpochToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint8_t uTag, int64_t date);
+static void QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pCtx,
+                                             const char         *szLabel,
+                                             uint8_t             uTagRequirement,
+                                             int64_t             nDate);
 
-static  void QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint8_t uTag, int64_t date);
+static void QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pCtx,
+                                            int64_t             nLabel,
+                                            uint8_t             uTagRequirement,
+                                            int64_t             nDate);
 
 
-static void QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx, int64_t date);
+static void QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx,
+                                     int64_t             nDate);
 
-static void QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t date);
+static void QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx,
+                                          const char         *szLabel,
+                                          int64_t             nDate);
 
-static  void QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t date);
+static void QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx,
+                                           int64_t             nLabel,
+                                           int64_t             nDate);
 
 
 /**
@@ -714,6 +742,7 @@
  @brief Add a binary UUID to the encoded output.
 
  @param[in] pCtx   The encoding context to add the UUID to.
+ @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
  @param[in] Bytes  Pointer and length of the binary UUID.
 
  A binary UUID as defined in [RFC 4122]
@@ -722,6 +751,21 @@
  It is output as CBOR major type 2, a binary string, with tag @ref
  CBOR_TAG_BIN_UUID indicating the binary string is a UUID.
  */
+static void QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pCtx,
+                                       uint8_t             uTagRequirement,
+                                       UsefulBufC          Bytes);
+
+static void QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pCtx,
+                                              const char         *szLabel,
+                                              uint8_t             uTagRequirement,
+                                              UsefulBufC          Bytes);
+
+static void QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pCtx,
+                                             int64_t             nLabel,
+                                             uint8_t             uTagRequirement,
+                                             UsefulBufC          Bytes);
+
+
 static void QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
 
 static void QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
@@ -733,6 +777,7 @@
  @brief Add a positive big number to the encoded output.
 
  @param[in] pCtx   The encoding context to add the big number to.
+ @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
  @param[in] Bytes  Pointer and length of the big number.
 
  Big numbers are integers larger than 64-bits. Their format is
@@ -746,17 +791,38 @@
  COSE which defines representations for keys chose not to use this
  particular type.
  */
-static void QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
+static void QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pCtx,
+                                           uint8_t             uTagRequirement,
+                                           UsefulBufC          Bytes);
 
-static void QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
+static void QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pCtx,
+                                                  const char         *szLabel,
+                                                  uint8_t             uTagRequirement,
+                                                  UsefulBufC          Bytes);
 
-static void QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
+static void QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pCtx,
+                                                 int64_t             nLabel,
+                                                 uint8_t             uTagRequirement,
+                                                 UsefulBufC          Bytes);
+
+
+static void QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx,
+                                          UsefulBufC          Bytes);
+
+static void QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx,
+                                               const char         *szLabel,
+                                               UsefulBufC          Bytes);
+
+static void QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx,
+                                                int64_t             nLabel,
+                                                UsefulBufC          Bytes);
 
 
 /**
  @brief Add a negative big number to the encoded output.
 
  @param[in] pCtx   The encoding context to add the big number to.
+ @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
  @param[in] Bytes  Pointer and length of the big number.
 
  Big numbers are integers larger than 64-bits. Their format is
@@ -770,11 +836,31 @@
  COSE which defines representations for keys chose not to use this
  particular type.
  */
-static void QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
+static void QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pCtx,
+                                           uint8_t             uTagRequirement,
+                                           UsefulBufC          Bytes);
 
-static void QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
+static void QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pCtx,
+                                                  const char         *szLabel,
+                                                  uint8_t             uTagRequirement,
+                                                  UsefulBufC          Bytes);
 
-static void QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
+static void QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pCtx,
+                                                 int64_t             nLabel,
+                                                 uint8_t             uTagRequirement,
+                                                 UsefulBufC          Bytes);
+
+
+static void QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx,
+                                          UsefulBufC          Bytes);
+
+static void QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx,
+                                               const char         *szLabel,
+                                               UsefulBufC          Bytes);
+
+static void QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx,
+                                                int64_t             nLabel,
+                                                UsefulBufC          Bytes);
 
 
 #ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
@@ -782,6 +868,7 @@
  @brief Add a decimal fraction to the encoded output.
 
  @param[in] pCtx            The encoding context to add the decimal fraction to.
+ @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
  @param[in] nMantissa       The mantissa.
  @param[in] nBase10Exponent The exponent.
 
@@ -814,6 +901,24 @@
 
  See @ref expAndMantissa for decoded representation.
  */
+static void QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pCtx,
+                                            uint8_t             uTagRequirement,
+                                            int64_t             nMantissa,
+                                            int64_t             nBase10Exponent);
+
+static void QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pCtx,
+                                                   const char         *szLabel,
+                                                   uint8_t             uTagRequirement,
+                                                   int64_t             nMantissa,
+                                                   int64_t             nBase10Exponent);
+
+static void QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pCtx,
+                                                  int64_t             nLabel,
+                                                  uint8_t             uTagRequirement,
+                                                  int64_t             nMantissa,
+                                                  int64_t             nBase10Exponent);
+
+
 static void QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pCtx,
                                            int64_t             nMantissa,
                                            int64_t             nBase10Exponent);
@@ -827,11 +932,11 @@
                                                  int64_t             nLabel,
                                                  int64_t             nMantissa,
                                                  int64_t             nBase10Exponent);
-
 /**
  @brief Add a decimal fraction with a big number mantissa to the encoded output.
 
  @param[in] pCtx            The encoding context to add the decimal fraction to.
+ @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
  @param[in] Mantissa        The mantissa.
  @param[in] bIsNegative     false if mantissa is positive, true if negative.
  @param[in] nBase10Exponent The exponent.
@@ -842,16 +947,37 @@
 
  See @ref expAndMantissa for decoded representation.
  */
+static void QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pCtx,
+                                                  uint8_t             uTagRequirement,
+                                                  UsefulBufC          Mantissa,
+                                                  bool                bIsNegative,
+                                                  int64_t             nBase10Exponent);
+
+static void QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
+                                                         const char         *szLabel,
+                                                         uint8_t             uTagRequirement,
+                                                         UsefulBufC          Mantissa,
+                                                         bool                bIsNegative,
+                                                         int64_t             nBase10Exponent);
+
+static void QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
+                                                        int64_t             nLabel,
+                                                        uint8_t             uTagRequirement,
+                                                        UsefulBufC          Mantissa,
+                                                        bool                bIsNegative,
+                                                        int64_t             nBase10Exponent);
+
+
 static void QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pCtx,
                                                  UsefulBufC          Mantissa,
                                                  bool                bIsNegative,
                                                  int64_t             nBase10Exponent);
 
-static void QCBOREncode_AddDecimalFractionBigNumToMap(QCBOREncodeContext *pCtx,
-                                                      const char         *szLabel,
-                                                      UsefulBufC          Mantissa,
-                                                      bool                bIsNegative,
-                                                      int64_t             nBase10Exponent);
+static void QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pCtx,
+                                                        const char         *szLabel,
+                                                        UsefulBufC          Mantissa,
+                                                        bool                bIsNegative,
+                                                        int64_t             nBase10Exponent);
 
 static void QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
                                                        int64_t             nLabel,
@@ -863,6 +989,7 @@
  @brief Add a big floating-point number to the encoded output.
 
  @param[in] pCtx            The encoding context to add the bigfloat to.
+ @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
  @param[in] nMantissa       The mantissa.
  @param[in] nBase2Exponent  The exponent.
 
@@ -893,6 +1020,24 @@
 
  See @ref expAndMantissa for decoded representation.
  */
+static void QCBOREncode_AddTBigFloat(QCBOREncodeContext *pCtx,
+                                     uint8_t             uTagRequirement,
+                                     int64_t             nMantissa,
+                                     int64_t             nBase2Exponent);
+
+static void QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pCtx,
+                                            const char         *szLabel,
+                                            uint8_t             uTagRequirement,
+                                            int64_t             nMantissa,
+                                            int64_t             nBase2Exponent);
+
+static void QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pCtx,
+                                           int64_t             nLabel,
+                                           uint8_t             uTagRequirement,
+                                           int64_t             nMantissa,
+                                           int64_t             nBase2Exponent);
+
+
 static void QCBOREncode_AddBigFloat(QCBOREncodeContext *pCtx,
                                     int64_t             nMantissa,
                                     int64_t             nBase2Exponent);
@@ -907,12 +1052,12 @@
                                           int64_t             nMantissa,
                                           int64_t             nBase2Exponent);
 
-
 /**
  @brief Add a big floating-point number with a big number mantissa to
         the encoded output.
 
  @param[in] pCtx            The encoding context to add the bigfloat to.
+ @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
  @param[in] Mantissa        The mantissa.
  @param[in] bIsNegative     false if mantissa is positive, true if negative.
  @param[in] nBase2Exponent  The exponent.
@@ -923,6 +1068,27 @@
 
  See @ref expAndMantissa for decoded representation.
  */
+static void QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pCtx,
+                                           uint8_t             uTagRequirement,
+                                           UsefulBufC          Mantissa,
+                                           bool                bIsNegative,
+                                           int64_t             nBase2Exponent);
+
+static void QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pCtx,
+                                                  const char         *szLabel,
+                                                  uint8_t             uTagRequirement,
+                                                  UsefulBufC          Mantissa,
+                                                  bool                bIsNegative,
+                                                  int64_t             nBase2Exponent);
+
+static void QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
+                                                 int64_t             nLabel,
+                                                 uint8_t             uTagRequirement,
+                                                 UsefulBufC          Mantissa,
+                                                 bool                bIsNegative,
+                                                 int64_t             nBase2Exponent);
+
+
 static void QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pCtx,
                                           UsefulBufC          Mantissa,
                                           bool                bIsNegative,
@@ -946,6 +1112,7 @@
  @brief Add a text URI to the encoded output.
 
  @param[in] pCtx  The encoding context to add the URI to.
+ @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
  @param[in] URI   Pointer and length of the URI.
 
  The format of URI must be per [RFC 3986]
@@ -959,17 +1126,38 @@
 
       QCBOREncode_AddURI(pCtx, UsefulBuf_FromSZ(szURI));
  */
-static void QCBOREncode_AddURI(QCBOREncodeContext *pCtx, UsefulBufC URI);
+static void QCBOREncode_AddTURI(QCBOREncodeContext *pCtx,
+                                uint8_t             uTagRequirement,
+                                UsefulBufC          URI);
 
-static void QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC URI);
+static void QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pCtx,
+                                       const char         *szLabel,
+                                       uint8_t             uTagRequirement,
+                                       UsefulBufC          URI);
 
-static void QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC URI);
+static void QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pCtx,
+                                      int64_t             nLabel,
+                                      uint8_t             uTagRequirement,
+                                      UsefulBufC          URI);
+
+
+static void QCBOREncode_AddURI(QCBOREncodeContext *pCtx,
+                               UsefulBufC          URI);
+
+static void QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx,
+                                    const char         *szLabel,
+                                    UsefulBufC          URI);
+
+static void QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx,
+                                     int64_t             nLabel,
+                                     UsefulBufC          URI);
 
 
 /**
  @brief Add Base64-encoded text to encoded output.
 
  @param[in] pCtx     The encoding context to add the base-64 text to.
+ @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
  @param[in] B64Text  Pointer and length of the base-64 encoded text.
 
  The text content is Base64 encoded data per [RFC 4648]
@@ -978,17 +1166,39 @@
  It is output as CBOR major type 3, a text string, with tag @ref
  CBOR_TAG_B64 indicating the text string is Base64 encoded.
  */
-static void QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx, UsefulBufC B64Text);
+static void QCBOREncode_AddTB64Text(QCBOREncodeContext *pCtx,
+                                    uint8_t             uTagRequirement,
+                                    UsefulBufC          B64Text);
 
-static void QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text);
+static void QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pCtx,
+                                           const char         *szLabel,
+                                           uint8_t             uTagRequirement,
+                                           UsefulBufC          B64Text);
 
-static void QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text);
+static void QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pCtx,
+                                          int64_t nLabel,
+                                          uint8_t uTagRequirement,
+                                          UsefulBufC B64Text);
+
+
+static void QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx,
+                                   UsefulBufC          B64Text);
+
+static void QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx,
+                                        const char         *szLabel,
+                                        UsefulBufC          B64Text);
+
+static void QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx,
+                                         int64_t             nLabel,
+                                         UsefulBufC          B64Text);
+
 
 
 /**
  @brief Add base64url encoded data to encoded output.
 
  @param[in] pCtx     The encoding context to add the base64url to.
+ @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
  @param[in] B64Text  Pointer and length of the base64url encoded text.
 
  The text content is base64URL encoded text as per [RFC 4648]
@@ -997,17 +1207,38 @@
  It is output as CBOR major type 3, a text string, with tag @ref
  CBOR_TAG_B64URL indicating the text string is a Base64url encoded.
  */
-static void QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx, UsefulBufC B64Text);
+static void QCBOREncode_AddTB64URLText(QCBOREncodeContext *pCtx,
+                                       uint8_t             uTagRequirement,
+                                       UsefulBufC          B64Text);
 
-static void QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text);
+static void QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pCtx,
+                                              const char         *szLabel,
+                                              uint8_t             uTagRequirement,
+                                              UsefulBufC          B64Text);
 
-static void QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text);
+static void QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pCtx,
+                                             int64_t             nLabel,
+                                             uint8_t             uTagRequirement,
+                                             UsefulBufC          B64Text);
+
+
+static void QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx,
+                                      UsefulBufC          B64Text);
+
+static void QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx,
+                                           const char         *szLabel,
+                                           UsefulBufC          B64Text);
+
+static void QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx,
+                                            int64_t             nLabel,
+                                            UsefulBufC          B64Text);
 
 
 /**
  @brief Add Perl Compatible Regular Expression.
 
  @param[in] pCtx    The encoding context to add the regular expression to.
+ @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
  @param[in] Regex   Pointer and length of the regular expression.
 
  The text content is Perl Compatible Regular
@@ -1016,38 +1247,92 @@
  It is output as CBOR major type 3, a text string, with tag @ref
  CBOR_TAG_REGEX indicating the text string is a regular expression.
  */
-static void QCBOREncode_AddRegex(QCBOREncodeContext *pCtx, UsefulBufC Regex);
+static void QCBOREncode_AddTRegex(QCBOREncodeContext *pCtx,
+                                  uint8_t            uTagRequirement,
+                                  UsefulBufC         Regex);
 
-static void QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Regex);
+static void QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pCtx,
+                                         const char         *szLabel,
+                                         uint8_t             uTagRequirement,
+                                         UsefulBufC          Regex);
 
-static void QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Regex);
+static void QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pCtx,
+                                        int64_t             nLabel,
+                                        uint8_t             uTagRequirement,
+                                        UsefulBufC          Regex);
+
+
+static void QCBOREncode_AddRegex(QCBOREncodeContext *pCtx,
+                                 UsefulBufC          Regex);
+
+static void QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx,
+                                      const char         *szLabel,
+                                      UsefulBufC          Regex);
+
+static void QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx,
+                                       int64_t             nLabel,
+                                       UsefulBufC          Regex);
 
 
 /**
- @brief MIME encoded text to the encoded output.
+ @brief MIME encoded data to the encoded output.
 
- @param[in] pCtx      The encoding context to add the MIME data to.
- @param[in] MIMEData  Pointer and length of the regular expression.
+ @param[in] pCtx             The encoding context to add the MIME data to.
+ @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or
+                             @ref QCBOR_ENCODE_AS_BORROWED.
+ @param[in] MIMEData         Pointer and length of the MIME data.
 
  The text content is in MIME format per [RFC 2045]
- (https://tools.ietf.org/html/rfc2045) including the headers. Note
- that this only supports text-format MIME. Binary MIME is not
- supported.
+ (https://tools.ietf.org/html/rfc2045) including the headers.
 
- It is output as CBOR major type 3, a text string, with tag
- @ref CBOR_TAG_MIME indicating the text string is MIME data.
+ It is output as CBOR major type 2, a binary string, with tag @ref
+ CBOR_TAG_BINARY_MIME indicating the string is MIME data.  This
+ outputs tag 257, not tag 36, as it can carry any type of MIME binary,
+ 7-bit, 8-bit, quoted-printable and base64 where tag 36 cannot.
+
+ Previous versions of QCBOR, those before spiffy decode, output tag
+ 36. Decoding supports both tag 36 and 257.  (if the old behavior with
+ tag 36 is needed, copy the inline functions below and change the tag
+ number).
+
+ See also QCBORDecode_GetMIMEMessage() and
+ @ref QCBOR_TYPE_BINARY_MIME.
+
+ This does no translation of line endings. See QCBOREncode_AddText()
+ for a discussion of line endings in CBOR.
  */
-static void QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx, UsefulBufC MIMEData);
+static void QCBOREncode_AddTMIMEData(QCBOREncodeContext *pCtx,
+                                     uint8_t             uTagRequirement,
+                                     UsefulBufC          MIMEData);
 
-static void QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC MIMEData);
+static void QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pCtx,
+                                            const char         *szLabel,
+                                            uint8_t             uTagRequirement,
+                                            UsefulBufC          MIMEData);
 
-static void QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC MIMEData);
+static void QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pCtx,
+                                           int64_t             nLabel,
+                                           uint8_t             uTagRequirement,
+                                           UsefulBufC          MIMEData);
+
+
+static void QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx,
+                                    UsefulBufC          MIMEData);
+
+static void QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx,
+                                         const char         *szLabel,
+                                         UsefulBufC          MIMEData);
+
+static void QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx,
+                                          int64_t             nLabel,
+                                          UsefulBufC          MIMEData);
 
 
 /**
  @brief  Add an RFC 3339 date string
 
  @param[in] pCtx    The encoding context to add the date to.
+ @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or @ref QCBOR_ENCODE_AS_BORROWED.
  @param[in] szDate  Null-terminated string with date to add.
 
  The string szDate should be in the form of [RFC 3339]
@@ -1062,13 +1347,32 @@
 
  Error handling is the same as QCBOREncode_AddInt64().
  */
-static void QCBOREncode_AddDateString(QCBOREncodeContext *pCtx, const char *szDate);
+static void QCBOREncode_AddTDateString(QCBOREncodeContext *pCtx,
+                                       uint8_t             uTagRequirement,
+                                       const char         *szDate);
 
-static void QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szDate);
+static void QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pCtx,
+                                              const char         *szLabel,
+                                              uint8_t             uTagRequirement,
+                                              const char         *szDate);
 
-static void QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szDate);
+static void QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pCtx,
+                                             int64_t             nLabel,
+                                             uint8_t             uTagRequirement,
+                                             const char         *szDate);
 
 
+static void QCBOREncode_AddDateString(QCBOREncodeContext *pCtx,
+                                      const char         *szDate);
+
+static void QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx,
+                                           const char         *szLabel,
+                                           const char         *szDate);
+
+static void QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx,
+                                            int64_t             nLabel,
+                                            const char         *szDate);
+
 /**
  @brief  Add a standard Boolean.
 
@@ -1469,14 +1773,14 @@
  @param uMinLen      The minimum number of bytes to encode uNumber. Almost always
                      this is 0 to use preferred minimal encoding. If this is 4,
                      then even the values 0xffff and smaller will be encoded
-                     as in 4 bytes. This is used primarily when encoding a
+                     in 4 bytes. This is used primarily when encoding a
                      float or double put into uNumber as the leading zero bytes
                      for them must be encoded.
  @param uNumber      The numeric argument part of the CBOR head.
  @return             Pointer and length of the encoded head or
                      @NULLUsefulBufC if the output buffer is too small.
 
- Callers to need to call this for normal CBOR encoding. Note that it doesn't even
+ Callers do not to need to call this for normal CBOR encoding. Note that it doesn't even
  take a @ref QCBOREncodeContext argument.
 
  This encodes the major type and argument part of a data item. The
@@ -1503,10 +1807,9 @@
 
 
 
-/* ===========================================================================
- BEGINNING OF PRIVATE INLINE IMPLEMENTATION
-
- =========================================================================== */
+/* =========================================================================
+     BEGINNING OF PRIVATE INLINE IMPLEMENTATION
+   ========================================================================= */
 
 /**
  @brief Semi-private method to add a buffer full of bytes to encoded output
@@ -1602,15 +1905,26 @@
  @brief  Semi-private method to add bigfloats and decimal fractions.
 
  @param[in] pCtx             The encoding context to add the value to.
- @param[in] uTag             The type 6 tag indicating what this is to be
+ @param[in] uTag             The type 6 tag indicating what this is to be.
  @param[in] BigNumMantissa   Is @ref NULLUsefulBufC if mantissa is an
                              @c int64_t or the actual big number mantissa
                              if not.
  @param[in] nMantissa        The @c int64_t mantissa if it is not a big number.
  @param[in] nExponent        The exponent.
 
- This adds a tagged array with two members, the mantissa and exponent. The
- mantissa can be either a big number or an @c int64_t.
+ This outputs either the @ref CBOR_TAG_DECIMAL_FRACTION or @ref
+ CBOR_TAG_BIGFLOAT tag. if @c uTag is @ref CBOR_TAG_INVALID64, then
+ this outputs the "borrowed" content format.
+
+ The tag content output by this is an array with two members, the
+ exponent and then the mantissa. The mantissa can be either a big
+ number or an @c int64_t.
+
+ This implementation cannot output an exponent further from 0 than
+ INT64_MAX.
+
+ To output a mantissa that is bewteen INT64_MAX and UINT64_MAX from 0,
+ it must be as a big number.
 
  Typically, QCBOREncode_AddDecimalFraction(), QCBOREncode_AddBigFloat(),
  QCBOREncode_AddDecimalFractionBigNum() or QCBOREncode_AddBigFloatBigNum()
@@ -1655,738 +1969,1195 @@
 
 
 
-static inline void QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum)
+static inline void
+QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pMe, const char *szLabel, int64_t uNum)
 {
    // Use _AddBuffer() because _AddSZString() is defined below, not above
-   QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
-   QCBOREncode_AddInt64(pCtx, uNum);
+   QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
+   QCBOREncode_AddInt64(pMe, uNum);
 }
 
-static inline void QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum)
+static inline void
+QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pMe, int64_t nLabel, int64_t uNum)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddInt64(pCtx, uNum);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddInt64(pMe, uNum);
 }
 
 
-static inline void QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum)
+static inline void
+QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pMe, const char *szLabel, uint64_t uNum)
 {
    // Use _AddBuffer() because _AddSZString() is defined below, not above
-   QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
-   QCBOREncode_AddUInt64(pCtx, uNum);
+   QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel));
+   QCBOREncode_AddUInt64(pMe, uNum);
 }
 
-static inline void QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum)
+static inline void
+QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint64_t uNum)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddUInt64(pCtx, uNum);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddUInt64(pMe, uNum);
 }
 
 
-static inline void QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text)
+static inline void
+QCBOREncode_AddText(QCBOREncodeContext *pMe, UsefulBufC Text)
 {
-   QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, Text);
+   QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_TEXT_STRING, Text);
 }
 
-static inline void QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text)
+static inline void
+QCBOREncode_AddTextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Text)
 {
-   // Use _AddBuffer() because _AddSZString() is defined below, not above
-   QCBOREncode_AddText(pCtx, UsefulBuf_FromSZ(szLabel));
-   QCBOREncode_AddText(pCtx, Text);
+   QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szLabel));
+   QCBOREncode_AddText(pMe, Text);
 }
 
-static inline void QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text)
+static inline void
+QCBOREncode_AddTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Text)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddText(pCtx, Text);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddText(pMe, Text);
 }
 
 
-inline static void QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString)
+inline static void
+QCBOREncode_AddSZString(QCBOREncodeContext *pMe, const char *szString)
 {
-   QCBOREncode_AddText(pCtx, UsefulBuf_FromSZ(szString));
+   QCBOREncode_AddText(pMe, UsefulBuf_FromSZ(szString));
 }
 
-static inline void QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString)
+static inline void
+QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pMe, const char *szLabel, const char *szString)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_AddSZString(pCtx, szString);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_AddSZString(pMe, szString);
 }
 
-static inline void QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString)
+static inline void
+QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, const char *szString)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddSZString(pCtx, szString);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddSZString(pMe, szString);
 }
 
 
-static inline void QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum)
+static inline void
+QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pMe, const char *szLabel, double dNum)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_AddDouble(pCtx, dNum);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_AddDouble(pMe, dNum);
 }
 
-static inline void QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum)
+static inline void
+QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pMe, int64_t nLabel, double dNum)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddDouble(pCtx, dNum);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddDouble(pMe, dNum);
 }
 
-static inline void QCBOREncode_AddFloatToMap(QCBOREncodeContext *pCtx, const char *szLabel, float dNum)
+static inline void
+QCBOREncode_AddFloatToMap(QCBOREncodeContext *pMe, const char *szLabel, float dNum)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_AddFloat(pCtx, dNum);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_AddFloat(pMe, dNum);
 }
 
-static inline void QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float fNum)
+static inline void
+QCBOREncode_AddFloatToMapN(QCBOREncodeContext *pMe, int64_t nLabel, float fNum)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddFloat(pCtx, fNum);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddFloat(pMe, fNum);
 }
 
-static inline void QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum)
+static inline void
+QCBOREncode_AddDoubleNoPreferredToMap(QCBOREncodeContext *pMe, const char *szLabel, double dNum)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_AddDoubleNoPreferred(pCtx, dNum);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
 }
 
-static inline void QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum)
+static inline void
+QCBOREncode_AddDoubleNoPreferredToMapN(QCBOREncodeContext *pMe, int64_t nLabel, double dNum)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddDoubleNoPreferred(pCtx, dNum);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
 }
 
-static inline void QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pCtx, const char *szLabel, float dNum)
+static inline void
+QCBOREncode_AddFloatNoPreferredToMap(QCBOREncodeContext *pMe, const char *szLabel, float dNum)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_AddFloatNoPreferred(pCtx, dNum);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_AddFloatNoPreferred(pMe, dNum);
 }
 
-static inline void QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float dNum)
+static inline void
+QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pMe, int64_t nLabel, float dNum)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddFloatNoPreferred(pCtx, dNum);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddFloatNoPreferred(pMe, dNum);
 }
 
 
 
-static inline void QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pCtx, uint8_t uTag, int64_t date)
+static inline void
+QCBOREncode_AddTDateEpoch(QCBOREncodeContext *pMe, uint8_t uTag, int64_t nDate)
 {
    if(uTag == QCBOR_ENCODE_AS_TAG) {
-      QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_EPOCH);
+      QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_EPOCH);
    }
-   QCBOREncode_AddInt64(pCtx, date);
+   QCBOREncode_AddInt64(pMe, nDate);
 }
 
-static inline void QCBOREncode_AddTDateEpochToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint8_t uTag, int64_t date)
+static inline void
+QCBOREncode_AddTDateEpochToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTag, int64_t nDate)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_AddTDateEpoch(pCtx, uTag, date);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
 }
 
-static inline void QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint8_t uTag, int64_t date)
+static inline void
+QCBOREncode_AddTDateEpochToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTag, int64_t nDate)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddTDateEpoch(pCtx, uTag, date);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddTDateEpoch(pMe, uTag, nDate);
 }
 
-static inline void QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx, int64_t date)
+static inline void
+QCBOREncode_AddDateEpoch(QCBOREncodeContext *pMe, int64_t nDate)
 {
-   QCBOREncode_AddTDateEpoch(pCtx, QCBOR_ENCODE_AS_TAG, date);
+   QCBOREncode_AddTDateEpoch(pMe, QCBOR_ENCODE_AS_TAG, nDate);
 }
 
-static inline void QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t date)
+static inline void
+QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pMe, const char *szLabel, int64_t nDate)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_AddDateEpoch(pCtx, date);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_AddDateEpoch(pMe, nDate);
 }
 
-static inline void QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t date)
+static inline void
+QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pMe, int64_t nLabel, int64_t nDate)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddDateEpoch(pCtx, date);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddDateEpoch(pMe, nDate);
 }
 
 
 
-static inline void QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
+static inline void
+QCBOREncode_AddBytes(QCBOREncodeContext *pMe, UsefulBufC Bytes)
 {
-   QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes);
+   QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes);
 }
 
-static inline void QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
+static inline void
+QCBOREncode_AddBytesToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_AddBytes(pCtx, Bytes);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_AddBytes(pMe, Bytes);
 }
 
-static inline void QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
+static inline void
+QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddBytes(pCtx, Bytes);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddBytes(pMe, Bytes);
 }
 
-static inline void QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
+static inline void
+QCBOREncode_AddBytesLenOnly(QCBOREncodeContext *pMe, UsefulBufC Bytes)
 {
-    QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY, Bytes);
+    QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY, Bytes);
 }
 
-static inline void QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
+static inline void
+QCBOREncode_AddBytesLenOnlyToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
 {
-    QCBOREncode_AddSZString(pCtx, szLabel);
-    QCBOREncode_AddBytesLenOnly(pCtx, Bytes);
+    QCBOREncode_AddSZString(pMe, szLabel);
+    QCBOREncode_AddBytesLenOnly(pMe, Bytes);
 }
 
-static inline void QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
+static inline void
+QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
 {
-    QCBOREncode_AddInt64(pCtx, nLabel);
-    QCBOREncode_AddBytesLenOnly(pCtx, Bytes);
+    QCBOREncode_AddInt64(pMe, nLabel);
+    QCBOREncode_AddBytesLenOnly(pMe, Bytes);
 }
 
-static inline void QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
+
+static inline void
+QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
 {
-   QCBOREncode_AddTag(pCtx, CBOR_TAG_BIN_UUID);
-   QCBOREncode_AddBytes(pCtx, Bytes);
+   if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
+      QCBOREncode_AddTag(pMe, CBOR_TAG_BIN_UUID);
+   }
+   QCBOREncode_AddBytes(pMe, Bytes);
 }
 
-static inline void QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
+static inline void
+QCBOREncode_AddTBinaryUUIDToMapSZ(QCBOREncodeContext *pMe,
+                                  const char         *szLabel,
+                                  uint8_t             uTagRequirement,
+                                  UsefulBufC          Bytes)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_AddTag(pCtx, CBOR_TAG_BIN_UUID);
-   QCBOREncode_AddBytes(pCtx, Bytes);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
 }
 
-static inline void QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
+static inline void
+QCBOREncode_AddTBinaryUUIDToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddTag(pCtx, CBOR_TAG_BIN_UUID);
-   QCBOREncode_AddBytes(pCtx, Bytes);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddTBinaryUUID(pMe, uTagRequirement, Bytes);
 }
 
-
-static inline void QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
+static inline void
+QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pMe, UsefulBufC Bytes)
 {
-   QCBOREncode_AddTag(pCtx, CBOR_TAG_POS_BIGNUM);
-   QCBOREncode_AddBytes(pCtx, Bytes);
+   QCBOREncode_AddTBinaryUUID(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
 }
 
-static inline void QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
+static inline void
+QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_AddTag(pCtx, CBOR_TAG_POS_BIGNUM);
-   QCBOREncode_AddBytes(pCtx, Bytes);
+   QCBOREncode_AddTBinaryUUIDToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
 }
 
-static inline void QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
+static inline void
+QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddTag(pCtx, CBOR_TAG_POS_BIGNUM);
-   QCBOREncode_AddBytes(pCtx, Bytes);
+   QCBOREncode_AddTBinaryUUIDToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
 }
 
 
-static inline void QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
+static inline void
+QCBOREncode_AddTPositiveBignum(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
 {
-   QCBOREncode_AddTag(pCtx, CBOR_TAG_NEG_BIGNUM);
-   QCBOREncode_AddBytes(pCtx, Bytes);
+   if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
+      QCBOREncode_AddTag(pMe, CBOR_TAG_POS_BIGNUM);
+   }
+   QCBOREncode_AddBytes(pMe, Bytes);
 }
 
-static inline void QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
+static inline void
+QCBOREncode_AddTPositiveBignumToMapSZ(QCBOREncodeContext *pMe,
+                                      const char         *szLabel,
+                                      uint8_t             uTagRequirement,
+                                      UsefulBufC          Bytes)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_AddTag(pCtx, CBOR_TAG_NEG_BIGNUM);
-   QCBOREncode_AddBytes(pCtx, Bytes);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
 }
 
-static inline void QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
+static inline void
+QCBOREncode_AddTPositiveBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddTag(pCtx, CBOR_TAG_NEG_BIGNUM);
-   QCBOREncode_AddBytes(pCtx, Bytes);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddTPositiveBignum(pMe, uTagRequirement, Bytes);
 }
 
+static inline void
+QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pMe, UsefulBufC Bytes)
+{
+   QCBOREncode_AddTPositiveBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
+}
+
+static inline void
+QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddTPositiveBignumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
+}
+
+static inline void
+QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddTPositiveBignumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
+}
+
+
+static inline void
+QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
+{
+   if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
+      QCBOREncode_AddTag(pMe, CBOR_TAG_NEG_BIGNUM);
+   }
+   QCBOREncode_AddBytes(pMe, Bytes);
+}
+
+static inline void
+QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pMe,
+                                      const char         *szLabel,
+                                      uint8_t             uTagRequirement,
+                                      UsefulBufC          Bytes)
+{
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
+}
+
+static inline void
+QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
+{
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddTNegativeBignum(pMe, uTagRequirement, Bytes);
+}
+
+static inline void
+QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pMe, UsefulBufC Bytes)
+{
+   QCBOREncode_AddTNegativeBignum(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
+}
+
+static inline void
+QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddTNegativeBignumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
+}
+
+static inline void
+QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddTNegativeBignumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
+}
+
+
 
 #ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
 
-static inline void QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pCtx,
-                                                  int64_t             nMantissa,
-                                                  int64_t             nBase10Exponent)
+static inline void
+QCBOREncode_AddTDecimalFraction(QCBOREncodeContext *pMe,
+                                uint8_t             uTagRequirement,
+                                int64_t             nMantissa,
+                                int64_t             nBase10Exponent)
 {
-   QCBOREncode_AddExponentAndMantissa(pCtx,
-                                      CBOR_TAG_DECIMAL_FRACTION,
+   uint64_t uTag;
+   if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
+      uTag = CBOR_TAG_DECIMAL_FRACTION;
+   } else {
+      uTag = CBOR_TAG_INVALID64;
+   }
+   QCBOREncode_AddExponentAndMantissa(pMe,
+                                      uTag,
                                       NULLUsefulBufC,
                                       false,
                                       nMantissa,
                                       nBase10Exponent);
 }
 
-static inline void QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pCtx,
-                                                       const char         *szLabel,
-                                                       int64_t             nMantissa,
-                                                       int64_t             nBase10Exponent)
+static inline void
+QCBOREncode_AddTDecimalFractionToMapSZ(QCBOREncodeContext *pMe,
+                                       const char         *szLabel,
+                                       uint8_t             uTagRequirement,
+                                       int64_t             nMantissa,
+                                       int64_t             nBase10Exponent)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_AddDecimalFraction(pCtx, nMantissa, nBase10Exponent);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_AddTDecimalFraction(pMe, uTagRequirement, nMantissa, nBase10Exponent);
 }
 
-static inline void QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pCtx,
-                                                        int64_t             nLabel,
-                                                        int64_t             nMantissa,
-                                                        int64_t             nBase10Exponent)
+static inline void
+QCBOREncode_AddTDecimalFractionToMapN(QCBOREncodeContext *pMe,
+                                      int64_t             nLabel,
+                                      uint8_t             uTagRequirement,
+                                      int64_t             nMantissa,
+                                      int64_t             nBase10Exponent)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddDecimalFraction(pCtx, nMantissa, nBase10Exponent);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddTDecimalFraction(pMe, uTagRequirement, nMantissa, nBase10Exponent);
 }
 
-static inline void QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pCtx,
-                                                        UsefulBufC          Mantissa,
-                                                        bool                bIsNegative,
-                                                        int64_t             nBase10Exponent)
+static inline void
+QCBOREncode_AddDecimalFraction(QCBOREncodeContext *pMe,
+                               int64_t             nMantissa,
+                               int64_t             nBase10Exponent)
 {
-   QCBOREncode_AddExponentAndMantissa(pCtx,
-                                      CBOR_TAG_DECIMAL_FRACTION,
+   QCBOREncode_AddTDecimalFraction(pMe, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
+}
+
+static inline void
+QCBOREncode_AddDecimalFractionToMap(QCBOREncodeContext *pMe,
+                                    const char         *szLabel,
+                                    int64_t             nMantissa,
+                                    int64_t             nBase10Exponent)
+{
+   QCBOREncode_AddTDecimalFractionToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
+}
+
+static inline void
+QCBOREncode_AddDecimalFractionToMapN(QCBOREncodeContext *pMe,
+                                     int64_t             nLabel,
+                                     int64_t             nMantissa,
+                                     int64_t             nBase10Exponent)
+{
+   QCBOREncode_AddTDecimalFractionToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase10Exponent);
+}
+
+
+
+static inline void
+QCBOREncode_AddTDecimalFractionBigNum(QCBOREncodeContext *pMe,
+                                      uint8_t             uTagRequirement,
+                                      UsefulBufC          Mantissa,
+                                      bool                bIsNegative,
+                                      int64_t             nBase10Exponent)
+{
+   uint64_t uTag;
+   if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
+      uTag = CBOR_TAG_DECIMAL_FRACTION;
+   } else {
+      uTag = CBOR_TAG_INVALID64;
+   }
+   QCBOREncode_AddExponentAndMantissa(pMe,
+                                      uTag,
                                       Mantissa, bIsNegative,
                                       0,
                                       nBase10Exponent);
 }
 
-static inline void QCBOREncode_AddDecimalFractionBigNumToMap(QCBOREncodeContext *pCtx,
-                                                             const char         *szLabel,
-                                                             UsefulBufC          Mantissa,
-                                                             bool                bIsNegative,
-                                                             int64_t             nBase10Exponent)
+static inline void
+QCBOREncode_AddTDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
+                                             const char         *szLabel,
+                                             uint8_t             uTagRequirement,
+                                             UsefulBufC          Mantissa,
+                                             bool                bIsNegative,
+                                             int64_t             nBase10Exponent)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_AddDecimalFractionBigNum(pCtx, Mantissa, bIsNegative, nBase10Exponent);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_AddTDecimalFractionBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase10Exponent);
 }
 
-static inline void QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pCtx,
-                                                              int64_t             nLabel,
-                                                              UsefulBufC          Mantissa,
-                                                              bool                bIsNegative,
-                                                              int64_t             nBase2Exponent)
+static inline void
+QCBOREncode_AddTDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
+                                            int64_t             nLabel,
+                                            uint8_t             uTagRequirement,
+                                            UsefulBufC          Mantissa,
+                                            bool                bIsNegative,
+                                            int64_t             nBase10Exponent)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddDecimalFractionBigNum(pCtx, Mantissa, bIsNegative, nBase2Exponent);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddTDecimalFractionBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase10Exponent);
 }
 
-static inline void QCBOREncode_AddBigFloat(QCBOREncodeContext *pCtx,
-                                           int64_t             nMantissa,
+static inline void
+QCBOREncode_AddDecimalFractionBigNum(QCBOREncodeContext *pMe,
+                                     UsefulBufC          Mantissa,
+                                     bool                bIsNegative,
+                                     int64_t             nBase10Exponent)
+{
+   QCBOREncode_AddTDecimalFractionBigNum(pMe, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase10Exponent);
+}
+
+static inline void
+QCBOREncode_AddDecimalFractionBigNumToMapSZ(QCBOREncodeContext *pMe,
+                                            const char         *szLabel,
+                                            UsefulBufC          Mantissa,
+                                            bool                bIsNegative,
+                                            int64_t             nBase10Exponent)
+{
+   QCBOREncode_AddTDecimalFractionBigNumToMapSZ(pMe,
+                                                szLabel,
+                                                QCBOR_ENCODE_AS_TAG,
+                                                Mantissa,
+                                                bIsNegative,
+                                                nBase10Exponent);
+}
+
+static inline void
+QCBOREncode_AddDecimalFractionBigNumToMapN(QCBOREncodeContext *pMe,
+                                           int64_t             nLabel,
+                                           UsefulBufC          Mantissa,
+                                           bool                bIsNegative,
                                            int64_t             nBase2Exponent)
 {
-   QCBOREncode_AddExponentAndMantissa(pCtx, CBOR_TAG_BIGFLOAT, NULLUsefulBufC, false, nMantissa, nBase2Exponent);
+   QCBOREncode_AddTDecimalFractionBigNumToMapN(pMe,
+                                               nLabel,
+                                               QCBOR_ENCODE_AS_TAG,
+                                               Mantissa,
+                                               bIsNegative,
+                                               nBase2Exponent);
 }
 
-static inline void QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pCtx,
-                                                const char         *szLabel,
-                                                int64_t             nMantissa,
-                                                int64_t             nBase2Exponent)
+
+
+
+
+static inline void
+QCBOREncode_AddTBigFloat(QCBOREncodeContext *pMe,
+                         uint8_t             uTagRequirement,
+                         int64_t             nMantissa,
+                         int64_t             nBase2Exponent)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_AddBigFloat(pCtx, nMantissa, nBase2Exponent);
+   uint64_t uTag;
+   if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
+      uTag = CBOR_TAG_BIGFLOAT;
+   } else {
+      uTag = CBOR_TAG_INVALID64;
+   }
+   QCBOREncode_AddExponentAndMantissa(pMe, uTag, NULLUsefulBufC, false, nMantissa, nBase2Exponent);
 }
 
-static inline void QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pCtx,
-                                                 int64_t             nLabel,
-                                                 int64_t             nMantissa,
-                                                 int64_t             nBase2Exponent)
+static inline void
+QCBOREncode_AddTBigFloatToMapSZ(QCBOREncodeContext *pMe,
+                                const char         *szLabel,
+                                uint8_t             uTagRequirement,
+                                int64_t             nMantissa,
+                                int64_t             nBase2Exponent)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddBigFloat(pCtx, nMantissa, nBase2Exponent);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
 }
 
-static inline void QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pCtx,
-                                                 UsefulBufC          Mantissa,
-                                                 bool                bIsNegative,
-                                                 int64_t             nBase2Exponent)
+static inline void
+QCBOREncode_AddTBigFloatToMapN(QCBOREncodeContext *pMe,
+                               int64_t             nLabel,
+                               uint8_t             uTagRequirement,
+                               int64_t             nMantissa,
+                               int64_t             nBase2Exponent)
 {
-   QCBOREncode_AddExponentAndMantissa(pCtx, CBOR_TAG_BIGFLOAT, Mantissa, bIsNegative, 0, nBase2Exponent);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddTBigFloat(pMe, uTagRequirement, nMantissa, nBase2Exponent);
 }
 
-static inline void QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pCtx,
-                                                      const char         *szLabel,
-                                                      UsefulBufC          Mantissa,
-                                                      bool                bIsNegative,
-                                                      int64_t             nBase2Exponent)
+static inline void
+QCBOREncode_AddBigFloat(QCBOREncodeContext *pMe,
+                        int64_t             nMantissa,
+                        int64_t             nBase2Exponent)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_AddBigFloatBigNum(pCtx, Mantissa, bIsNegative, nBase2Exponent);
+   QCBOREncode_AddTBigFloat(pMe, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
 }
 
-static inline void QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pCtx,
-                                                       int64_t             nLabel,
-                                                       UsefulBufC          Mantissa,
-                                                       bool                bIsNegative,
-                                                       int64_t             nBase2Exponent)
+static inline void
+QCBOREncode_AddBigFloatToMap(QCBOREncodeContext *pMe,
+                             const char         *szLabel,
+                             int64_t             nMantissa,
+                             int64_t             nBase2Exponent)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddBigFloatBigNum(pCtx, Mantissa, bIsNegative, nBase2Exponent);
+   QCBOREncode_AddTBigFloatToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
+}
+
+static inline void
+QCBOREncode_AddBigFloatToMapN(QCBOREncodeContext *pMe,
+                              int64_t             nLabel,
+                              int64_t             nMantissa,
+                              int64_t             nBase2Exponent)
+{
+   QCBOREncode_AddTBigFloatToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, nMantissa, nBase2Exponent);
+}
+
+
+
+static inline void
+QCBOREncode_AddTBigFloatBigNum(QCBOREncodeContext *pMe,
+                               uint8_t             uTagRequirement,
+                               UsefulBufC          Mantissa,
+                               bool                bIsNegative,
+                               int64_t             nBase2Exponent)
+{
+   uint64_t uTag;
+   if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
+      uTag = CBOR_TAG_BIGFLOAT;
+   } else {
+      uTag = CBOR_TAG_INVALID64;
+   }
+   QCBOREncode_AddExponentAndMantissa(pMe, uTag, Mantissa, bIsNegative, 0, nBase2Exponent);
+}
+
+static inline void
+QCBOREncode_AddTBigFloatBigNumToMapSZ(QCBOREncodeContext *pMe,
+                                      const char         *szLabel,
+                                      uint8_t             uTagRequirement,
+                                      UsefulBufC          Mantissa,
+                                      bool                bIsNegative,
+                                      int64_t             nBase2Exponent)
+{
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_AddTBigFloatBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase2Exponent);
+}
+
+static inline void
+QCBOREncode_AddTBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
+                                     int64_t             nLabel,
+                                     uint8_t             uTagRequirement,
+                                     UsefulBufC          Mantissa,
+                                     bool                bIsNegative,
+                                     int64_t             nBase2Exponent)
+{
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddTBigFloatBigNum(pMe, uTagRequirement, Mantissa, bIsNegative, nBase2Exponent);
+}
+
+
+static inline void
+QCBOREncode_AddBigFloatBigNum(QCBOREncodeContext *pMe,
+                              UsefulBufC          Mantissa,
+                              bool                bIsNegative,
+                              int64_t             nBase2Exponent)
+{
+   QCBOREncode_AddTBigFloatBigNum(pMe, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
+}
+
+static inline void
+QCBOREncode_AddBigFloatBigNumToMap(QCBOREncodeContext *pMe,
+                                   const char         *szLabel,
+                                   UsefulBufC          Mantissa,
+                                   bool                bIsNegative,
+                                   int64_t             nBase2Exponent)
+{
+   QCBOREncode_AddTBigFloatBigNumToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
+}
+
+static inline void
+QCBOREncode_AddBigFloatBigNumToMapN(QCBOREncodeContext *pMe,
+                                    int64_t             nLabel,
+                                    UsefulBufC          Mantissa,
+                                    bool                bIsNegative,
+                                    int64_t             nBase2Exponent)
+{
+   QCBOREncode_AddTBigFloatBigNumToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Mantissa, bIsNegative, nBase2Exponent);
 }
 #endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
 
 
-static inline void QCBOREncode_AddURI(QCBOREncodeContext *pCtx, UsefulBufC URI)
+static inline void
+QCBOREncode_AddTURI(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC URI)
 {
-   QCBOREncode_AddTag(pCtx, CBOR_TAG_URI);
-   QCBOREncode_AddText(pCtx, URI);
+   if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
+      QCBOREncode_AddTag(pMe, CBOR_TAG_URI);
+   }
+   QCBOREncode_AddText(pMe, URI);
 }
 
-static inline void QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC URI)
+static inline void
+QCBOREncode_AddTURIToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTagRequirement, UsefulBufC URI)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_AddTag(pCtx, CBOR_TAG_URI);
-   QCBOREncode_AddText(pCtx, URI);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
 }
 
-static inline void QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC URI)
+static inline void
+QCBOREncode_AddTURIToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC URI)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddTag(pCtx, CBOR_TAG_URI);
-   QCBOREncode_AddText(pCtx, URI);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddTURI(pMe, uTagRequirement, URI);
+}
+
+static inline void
+QCBOREncode_AddURI(QCBOREncodeContext *pMe, UsefulBufC URI)
+{
+   QCBOREncode_AddTURI(pMe, QCBOR_ENCODE_AS_TAG, URI);
+}
+
+static inline void
+QCBOREncode_AddURIToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC URI)
+{
+   QCBOREncode_AddTURIToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, URI);
+}
+
+static inline void
+QCBOREncode_AddURIToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC URI)
+{
+   QCBOREncode_AddTURIToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, URI);
 }
 
 
 
-static inline void QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx, UsefulBufC B64Text)
+static inline void
+QCBOREncode_AddTB64Text(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC B64Text)
 {
-   QCBOREncode_AddTag(pCtx, CBOR_TAG_B64);
-   QCBOREncode_AddText(pCtx, B64Text);
+   if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
+      QCBOREncode_AddTag(pMe, CBOR_TAG_B64);
+   }
+   QCBOREncode_AddText(pMe, B64Text);
 }
 
-static inline void QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text)
+static inline void
+QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pMe,
+                               const char         *szLabel,
+                               uint8_t             uTagRequirement,
+                               UsefulBufC          B64Text)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_AddTag(pCtx, CBOR_TAG_B64);
-   QCBOREncode_AddText(pCtx, B64Text);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
 }
 
-static inline void QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text)
+static inline void
+QCBOREncode_AddTB64TextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC B64Text)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddTag(pCtx, CBOR_TAG_B64);
-   QCBOREncode_AddText(pCtx, B64Text);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddTB64Text(pMe, uTagRequirement, B64Text);
+}
+
+static inline void
+QCBOREncode_AddB64Text(QCBOREncodeContext *pMe, UsefulBufC B64Text)
+{
+   QCBOREncode_AddTB64Text(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
+}
+
+static inline void
+QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC B64Text)
+{
+   QCBOREncode_AddTB64TextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
+}
+
+static inline void
+QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC B64Text)
+{
+   QCBOREncode_AddTB64TextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
 }
 
 
-static inline void QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx, UsefulBufC B64Text)
+
+static inline void
+QCBOREncode_AddTB64URLText(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC B64Text)
 {
-   QCBOREncode_AddTag(pCtx, CBOR_TAG_B64URL);
-   QCBOREncode_AddText(pCtx, B64Text);
+   if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
+      QCBOREncode_AddTag(pMe, CBOR_TAG_B64URL);
+   }
+   QCBOREncode_AddText(pMe, B64Text);
 }
 
-static inline void QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text)
+static inline void
+QCBOREncode_AddTB64URLTextToMapSZ(QCBOREncodeContext *pMe,
+                                  const char         *szLabel,
+                                  uint8_t             uTagRequirement,
+                                  UsefulBufC          B64Text)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_AddTag(pCtx, CBOR_TAG_B64URL);
-   QCBOREncode_AddText(pCtx, B64Text);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
 }
 
-static inline void QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text)
+static inline void
+QCBOREncode_AddTB64URLTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC B64Text)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddTag(pCtx, CBOR_TAG_B64URL);
-   QCBOREncode_AddText(pCtx, B64Text);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddTB64URLText(pMe, uTagRequirement, B64Text);
+}
+
+static inline void
+QCBOREncode_AddB64URLText(QCBOREncodeContext *pMe, UsefulBufC B64Text)
+{
+   QCBOREncode_AddTB64URLText(pMe, QCBOR_ENCODE_AS_TAG, B64Text);
+}
+
+static inline void
+QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC B64Text)
+{
+   QCBOREncode_AddTB64URLTextToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, B64Text);
+}
+
+static inline void
+QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC B64Text)
+{
+   QCBOREncode_AddTB64URLTextToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, B64Text);
 }
 
 
-static inline void QCBOREncode_AddRegex(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
+
+static inline void
+QCBOREncode_AddTRegex(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC Bytes)
 {
-   QCBOREncode_AddTag(pCtx, CBOR_TAG_REGEX);
-   QCBOREncode_AddText(pCtx, Bytes);
+   if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
+      QCBOREncode_AddTag(pMe, CBOR_TAG_REGEX);
+   }
+   QCBOREncode_AddText(pMe, Bytes);
 }
 
-static inline void QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
+static inline void
+QCBOREncode_AddTRegexToMapSZ(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_AddTag(pCtx, CBOR_TAG_REGEX);
-   QCBOREncode_AddText(pCtx, Bytes);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
 }
 
-static inline void QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
+static inline void
+QCBOREncode_AddTRegexToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC Bytes)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddTag(pCtx, CBOR_TAG_REGEX);
-   QCBOREncode_AddText(pCtx, Bytes);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddTRegex(pMe, uTagRequirement, Bytes);
+}
+
+static inline void
+QCBOREncode_AddRegex(QCBOREncodeContext *pMe, UsefulBufC Bytes)
+{
+   QCBOREncode_AddTRegex(pMe, QCBOR_ENCODE_AS_TAG, Bytes);
+}
+
+static inline void
+QCBOREncode_AddRegexToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddTRegexToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, Bytes);
+}
+
+static inline void
+QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddTRegexToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, Bytes);
+
 }
 
 
-static inline void QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx, UsefulBufC MIMEData)
+static inline void
+QCBOREncode_AddTMIMEData(QCBOREncodeContext *pMe, uint8_t uTagRequirement, UsefulBufC MIMEData)
 {
-   QCBOREncode_AddTag(pCtx, CBOR_TAG_MIME);
-   QCBOREncode_AddText(pCtx, MIMEData);
+   if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
+      QCBOREncode_AddTag(pMe, CBOR_TAG_BINARY_MIME);
+   }
+   QCBOREncode_AddBytes(pMe, MIMEData);
 }
 
-static inline void QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC MIMEData)
+static inline void
+QCBOREncode_AddTMIMEDataToMapSZ(QCBOREncodeContext *pMe,
+                                const char         *szLabel,
+                                uint8_t             uTagRequirement,
+                                UsefulBufC          MIMEData)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_AddTag(pCtx, CBOR_TAG_MIME);
-   QCBOREncode_AddText(pCtx, MIMEData);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
 }
 
-static inline void QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC MIMEData)
+static inline void
+QCBOREncode_AddTMIMEDataToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC MIMEData)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddTag(pCtx, CBOR_TAG_MIME);
-   QCBOREncode_AddText(pCtx, MIMEData);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddTMIMEData(pMe, uTagRequirement, MIMEData);
+}
+
+static inline void
+QCBOREncode_AddMIMEData(QCBOREncodeContext *pMe, UsefulBufC MIMEData)
+{
+   QCBOREncode_AddTMIMEData(pMe, QCBOR_ENCODE_AS_TAG, MIMEData);
+}
+
+static inline void
+QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC MIMEData)
+{
+   QCBOREncode_AddTMIMEDataToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
+}
+
+static inline void
+QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC MIMEData)
+{
+   QCBOREncode_AddTMIMEDataToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, MIMEData);
 }
 
 
-static inline void QCBOREncode_AddDateString(QCBOREncodeContext *pCtx, const char *szDate)
+static inline void
+QCBOREncode_AddTDateString(QCBOREncodeContext *pMe, uint8_t uTagRequirement, const char *szDate)
 {
-   QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_STRING);
-   QCBOREncode_AddSZString(pCtx, szDate);
+   if(uTagRequirement == QCBOR_ENCODE_AS_TAG) {
+      QCBOREncode_AddTag(pMe, CBOR_TAG_DATE_STRING);
+   }
+   QCBOREncode_AddSZString(pMe, szDate);
 }
 
-static inline void QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szDate)
+static inline void
+QCBOREncode_AddTDateStringToMapSZ(QCBOREncodeContext *pMe,
+                                  const char         *szLabel,
+                                  uint8_t             uTagRequirement,
+                                  const char         *szDate)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_STRING);
-   QCBOREncode_AddSZString(pCtx, szDate);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
 }
 
-static inline void QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szDate)
+static inline void
+QCBOREncode_AddTDateStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, const char *szDate)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_STRING);
-   QCBOREncode_AddSZString(pCtx, szDate);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddTDateString(pMe, uTagRequirement, szDate);
+}
+
+static inline void
+QCBOREncode_AddDateString(QCBOREncodeContext *pMe, const char *szDate)
+{
+   QCBOREncode_AddTDateString(pMe, QCBOR_ENCODE_AS_TAG, szDate);
+}
+
+static inline void
+QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pMe, const char *szLabel, const char *szDate)
+{
+   QCBOREncode_AddTDateStringToMapSZ(pMe, szLabel, QCBOR_ENCODE_AS_TAG, szDate);
+}
+
+static inline void
+QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pMe, int64_t nLabel, const char *szDate)
+{
+   QCBOREncode_AddTDateStringToMapN(pMe, nLabel, QCBOR_ENCODE_AS_TAG, szDate);
 }
 
 
-static inline void QCBOREncode_AddSimple(QCBOREncodeContext *pCtx, uint64_t uNum)
+static inline void
+QCBOREncode_AddSimple(QCBOREncodeContext *pMe, uint64_t uNum)
 {
-   QCBOREncode_AddType7(pCtx, 0, uNum);
+   QCBOREncode_AddType7(pMe, 0, uNum);
 }
 
-static inline void QCBOREncode_AddSimpleToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint8_t uSimple)
+static inline void
+QCBOREncode_AddSimpleToMap(QCBOREncodeContext *pMe, const char *szLabel, uint8_t uSimple)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_AddSimple(pCtx, uSimple);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_AddSimple(pMe, uSimple);
 }
 
-static inline void QCBOREncode_AddSimpleToMapN(QCBOREncodeContext *pCtx, int nLabel, uint8_t uSimple)
+static inline void
+QCBOREncode_AddSimpleToMapN(QCBOREncodeContext *pMe, int nLabel, uint8_t uSimple)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddSimple(pCtx, uSimple);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddSimple(pMe, uSimple);
 }
 
 
-static inline void QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b)
+static inline void
+QCBOREncode_AddBool(QCBOREncodeContext *pMe, bool b)
 {
    uint8_t uSimple = CBOR_SIMPLEV_FALSE;
    if(b) {
       uSimple = CBOR_SIMPLEV_TRUE;
    }
-   QCBOREncode_AddSimple(pCtx, uSimple);
+   QCBOREncode_AddSimple(pMe, uSimple);
 }
 
-static inline void QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b)
+static inline void
+QCBOREncode_AddBoolToMap(QCBOREncodeContext *pMe, const char *szLabel, bool b)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_AddBool(pCtx, b);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_AddBool(pMe, b);
 }
 
-static inline void QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b)
+static inline void
+QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pMe, int64_t nLabel, bool b)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddBool(pCtx, b);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddBool(pMe, b);
 }
 
 
-static inline void QCBOREncode_AddNULL(QCBOREncodeContext *pCtx)
+static inline void
+QCBOREncode_AddNULL(QCBOREncodeContext *pMe)
 {
-   QCBOREncode_AddSimple(pCtx, CBOR_SIMPLEV_NULL);
+   QCBOREncode_AddSimple(pMe, CBOR_SIMPLEV_NULL);
 }
 
-static inline void QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel)
+static inline void
+QCBOREncode_AddNULLToMap(QCBOREncodeContext *pMe, const char *szLabel)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_AddNULL(pCtx);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_AddNULL(pMe);
 }
 
-static inline void QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
+static inline void
+QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pMe, int64_t nLabel)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddNULL(pCtx);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddNULL(pMe);
 }
 
 
-static inline void QCBOREncode_AddUndef(QCBOREncodeContext *pCtx)
+static inline void
+QCBOREncode_AddUndef(QCBOREncodeContext *pMe)
 {
-   QCBOREncode_AddSimple(pCtx, CBOR_SIMPLEV_UNDEF);
+   QCBOREncode_AddSimple(pMe, CBOR_SIMPLEV_UNDEF);
 }
 
-static inline void QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel)
+static inline void
+QCBOREncode_AddUndefToMap(QCBOREncodeContext *pMe, const char *szLabel)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_AddUndef(pCtx);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_AddUndef(pMe);
 }
 
-static inline void QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
+static inline void
+QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pMe, int64_t nLabel)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddUndef(pCtx);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddUndef(pMe);
 }
 
 
-static inline void QCBOREncode_OpenArray(QCBOREncodeContext *pCtx)
+static inline void
+QCBOREncode_OpenArray(QCBOREncodeContext *pMe)
 {
-   QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_ARRAY);
+   QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
 }
 
-static inline void QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel)
+static inline void
+QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pMe, const char *szLabel)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_OpenArray(pCtx);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_OpenArray(pMe);
 }
 
-static inline void QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx,  int64_t nLabel)
+static inline void
+QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pMe,  int64_t nLabel)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_OpenArray(pCtx);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_OpenArray(pMe);
 }
 
-static inline void QCBOREncode_CloseArray(QCBOREncodeContext *pCtx)
+static inline void
+QCBOREncode_CloseArray(QCBOREncodeContext *pMe)
 {
-   QCBOREncode_CloseMapOrArray(pCtx, CBOR_MAJOR_TYPE_ARRAY);
+   QCBOREncode_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_ARRAY);
 }
 
 
-static inline void QCBOREncode_OpenMap(QCBOREncodeContext *pCtx)
+static inline void
+QCBOREncode_OpenMap(QCBOREncodeContext *pMe)
 {
-   QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_MAP);
+   QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
 }
 
-static inline void QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel)
+static inline void
+QCBOREncode_OpenMapInMap(QCBOREncodeContext *pMe, const char *szLabel)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_OpenMap(pCtx);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_OpenMap(pMe);
 }
 
-static inline void QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
+static inline void
+QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_OpenMap(pCtx);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_OpenMap(pMe);
 }
 
-static inline void QCBOREncode_CloseMap(QCBOREncodeContext *pCtx)
+static inline void
+QCBOREncode_CloseMap(QCBOREncodeContext *pMe)
 {
-   QCBOREncode_CloseMapOrArray(pCtx, CBOR_MAJOR_TYPE_MAP);
+   QCBOREncode_CloseMapOrArray(pMe, CBOR_MAJOR_TYPE_MAP);
 }
 
-static inline void QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pCtx)
+static inline void
+QCBOREncode_OpenArrayIndefiniteLength(QCBOREncodeContext *pMe)
 {
-   QCBOREncode_OpenMapOrArrayIndefiniteLength(pCtx, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
+   QCBOREncode_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
 }
 
-static inline void QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pCtx, const char *szLabel)
+static inline void
+QCBOREncode_OpenArrayIndefiniteLengthInMap(QCBOREncodeContext *pMe, const char *szLabel)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_OpenArrayIndefiniteLength(pCtx);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_OpenArrayIndefiniteLength(pMe);
 }
 
-static inline void QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pCtx,  int64_t nLabel)
+static inline void
+QCBOREncode_OpenArrayIndefiniteLengthInMapN(QCBOREncodeContext *pMe,  int64_t nLabel)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_OpenArrayIndefiniteLength(pCtx);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_OpenArrayIndefiniteLength(pMe);
 }
 
-static inline void QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pCtx)
+static inline void
+QCBOREncode_CloseArrayIndefiniteLength(QCBOREncodeContext *pMe)
 {
-   QCBOREncode_CloseMapOrArrayIndefiniteLength(pCtx, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
+   QCBOREncode_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_ARRAY_INDEFINITE_LEN);
 }
 
 
-static inline void QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pCtx)
+static inline void
+QCBOREncode_OpenMapIndefiniteLength(QCBOREncodeContext *pMe)
 {
-   QCBOREncode_OpenMapOrArrayIndefiniteLength(pCtx, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
+   QCBOREncode_OpenMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
 }
 
-static inline void QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pCtx, const char *szLabel)
+static inline void
+QCBOREncode_OpenMapIndefiniteLengthInMap(QCBOREncodeContext *pMe, const char *szLabel)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_OpenMapIndefiniteLength(pCtx);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_OpenMapIndefiniteLength(pMe);
 }
 
-static inline void QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
+static inline void
+QCBOREncode_OpenMapIndefiniteLengthInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_OpenMapIndefiniteLength(pCtx);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_OpenMapIndefiniteLength(pMe);
 }
 
-static inline void QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pCtx)
+static inline void
+QCBOREncode_CloseMapIndefiniteLength(QCBOREncodeContext *pMe)
 {
-   QCBOREncode_CloseMapOrArrayIndefiniteLength(pCtx, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
+   QCBOREncode_CloseMapOrArrayIndefiniteLength(pMe, CBOR_MAJOR_NONE_TYPE_MAP_INDEFINITE_LEN);
 }
 
 
-static inline void QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx)
+static inline void
+QCBOREncode_BstrWrap(QCBOREncodeContext *pMe)
 {
-   QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_BYTE_STRING);
+   QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_TYPE_BYTE_STRING);
 }
 
-static inline void QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel)
+static inline void
+QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pMe, const char *szLabel)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_BstrWrap(pCtx);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_BstrWrap(pMe);
 }
 
-static inline void QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
+static inline void
+QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pMe, int64_t nLabel)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_BstrWrap(pCtx);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_BstrWrap(pMe);
 }
 
-static inline void QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR)
+static inline void
+QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pMe, UsefulBufC *pWrappedCBOR)
 {
-   QCBOREncode_CloseBstrWrap2(pCtx, true, pWrappedCBOR);
+   QCBOREncode_CloseBstrWrap2(pMe, true, pWrappedCBOR);
 }
 
 
-static inline void QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded)
+static inline void
+QCBOREncode_AddEncoded(QCBOREncodeContext *pMe, UsefulBufC Encoded)
 {
-   QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_NONE_TYPE_RAW, Encoded);
+   QCBOREncode_AddBuffer(pMe, CBOR_MAJOR_NONE_TYPE_RAW, Encoded);
 }
 
-static inline void QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded)
+static inline void
+QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pMe, const char *szLabel, UsefulBufC Encoded)
 {
-   QCBOREncode_AddSZString(pCtx, szLabel);
-   QCBOREncode_AddEncoded(pCtx, Encoded);
+   QCBOREncode_AddSZString(pMe, szLabel);
+   QCBOREncode_AddEncoded(pMe, Encoded);
 }
 
-static inline void QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded)
+static inline void
+QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pMe, int64_t nLabel, UsefulBufC Encoded)
 {
-   QCBOREncode_AddInt64(pCtx, nLabel);
-   QCBOREncode_AddEncoded(pCtx, Encoded);
+   QCBOREncode_AddInt64(pMe, nLabel);
+   QCBOREncode_AddEncoded(pMe, Encoded);
 }
 
 
-static inline int QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx)
+static inline int
+QCBOREncode_IsBufferNULL(QCBOREncodeContext *pMe)
 {
-   return UsefulOutBuf_IsBufferNULL(&(pCtx->OutBuf));
+   return UsefulOutBuf_IsBufferNULL(&(pMe->OutBuf));
 }
 
-static inline QCBORError QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx)
+static inline QCBORError
+QCBOREncode_GetErrorState(QCBOREncodeContext *pMe)
 {
-   if(UsefulOutBuf_GetError(&(pCtx->OutBuf))) {
+   if(UsefulOutBuf_GetError(&(pMe->OutBuf))) {
       // Items didn't fit in the buffer.
       // This check catches this condition for all the appends and inserts
       // so checks aren't needed when the appends and inserts are performed.
       // And of course UsefulBuf will never overrun the input buffer given
       // to it. No complex analysis of the error handling in this file is
       // needed to know that is true. Just read the UsefulBuf code.
-      pCtx->uError = QCBOR_ERR_BUFFER_TOO_SMALL;
+      pMe->uError = QCBOR_ERR_BUFFER_TOO_SMALL;
       // QCBOR_ERR_BUFFER_TOO_SMALL masks other errors, but that is
       // OK. Once the caller fixes this, they'll be unmasked.
    }
 
-   return (QCBORError)pCtx->uError;
+   return (QCBORError)pMe->uError;
 }
 
 
-/* ===========================================================================
- END OF PRIVATE INLINE IMPLEMENTATION
-
- =========================================================================== */
+/* ========================================================================
+     END OF PRIVATE INLINE IMPLEMENTATION
+   ======================================================================== */
 
 #ifdef __cplusplus
 }
diff --git a/inc/qcbor/qcbor_private.h b/inc/qcbor/qcbor_private.h
index a00f54f..a72cfdd 100644
--- a/inc/qcbor/qcbor_private.h
+++ b/inc/qcbor/qcbor_private.h
@@ -248,7 +248,7 @@
 
    // A cached offset to the end of the current map
    // 0 if no value is cached.
-#define MAP_OFFSET_CACHE_INVALID UINT32_MAX // TODO: exclude this value from input length
+#define QCBOR_MAP_OFFSET_CACHE_INVALID UINT32_MAX
    uint32_t uMapEndOffsetCache;
 
    uint8_t  uDecodeMode;
diff --git a/inc/qcbor/qcbor_spiffy_decode.h b/inc/qcbor/qcbor_spiffy_decode.h
index 9673bcd..2e60860 100644
--- a/inc/qcbor/qcbor_spiffy_decode.h
+++ b/inc/qcbor/qcbor_spiffy_decode.h
@@ -112,11 +112,16 @@
  type. Then for use one of the type-specific methods to get the item
  again to take advantage of the type conversion provided.
 
- Error reporting when get items by label in a map is not accurate for
- some errors. They are reported as not found rather than overflow and
- such. The error may be for other than the labeled item being searched
- for. Non-well formed maps cannot be searched at all. (This may be
- improved).
+ When getting an item by label from a map the whole map is
+ traversed including traversal of nested arrays and maps. If
+ there is any unrecoverable error anywhere in the that traversal
+ the retrieval by label will fail and the unrecoverable error
+ will be returned even if it is not due to the labeled item
+ being sought. Recoverable errors will be ignored unless
+ they are on the item being sought, in which case the
+ unrecoverable error will be returned. Unrecoverable
+ errors are those indicated by QCBORDecode_IsUnrecoverableError().
+ 
 
  @anchor Tag-Usage
 
@@ -210,6 +215,7 @@
 
 
 
+
 /**
  @brief Decode next item into a signed 64-bit integer.
 
@@ -412,8 +418,8 @@
  QCBORDecode_GetUInt64Convert().
 */
 void QCBORDecode_GetUInt64ConvertAll(QCBORDecodeContext *pCtx,
-                                     uint32_t           uConvertTypes,
-                                     uint64_t          *puValue);
+                                     uint32_t            uConvertTypes,
+                                     uint64_t           *puValue);
 
 void QCBORDecode_GetUInt64ConvertAllInMapN(QCBORDecodeContext *pCtx,
                                            int64_t             nLabel,
@@ -426,6 +432,62 @@
                                             uint64_t           *puValue);
 
 
+
+
+/**
+ @brief Decode the next item as a byte string
+
+ @param[in] pCtx   The decode context
+ @param[out] pBytes  The decoded byte string
+
+ The CBOR item to decode must be a byte string, CBOR type 2.
+
+ See @ref Decode-Errors for discussion on how error handling works.
+
+ If the CBOR tem to decode is not a byte string, the @ref
+ QCBOR_ERR_UNEXPECTED_TYPE error is set.
+ */
+static void QCBORDecode_GetByteString(QCBORDecodeContext *pCtx,
+                                      UsefulBufC         *pBytes);
+
+static void QCBORDecode_GetByteStringInMapN(QCBORDecodeContext *pCtx,
+                                            int64_t             nLabel,
+                                            UsefulBufC         *pBytes);
+
+static void QCBORDecode_GetByteStringInMapSZ(QCBORDecodeContext *pCtx,
+                                             const char         *szLabel,
+                                             UsefulBufC         *pBytes);
+
+
+/**
+ @brief Decode the next item as a text string.
+
+ @param[in] pCtx   The decode context.
+ @param[out] pText  The decoded byte string.
+
+ The CBOR item to decode must be a text string, CBOR type 3.
+
+ See @ref Decode-Errors for discussion on how error handling works.  It the CBOR item
+ to decode is not a text string, the @ref QCBOR_ERR_UNEXPECTED_TYPE
+ error is set.
+
+ This does no translation of line endings. See QCBOREncode_AddText()
+ for a discussion of line endings in CBOR.
+*/
+static void QCBORDecode_GetTextString(QCBORDecodeContext *pCtx,
+                                      UsefulBufC         *pText);
+
+static void QCBORDecode_GetTextStringInMapN(QCBORDecodeContext *pCtx,
+                                            int64_t             nLabel,
+                                            UsefulBufC         *pText);
+
+static void QCBORDecode_GetTextStringInMapSZ(QCBORDecodeContext *pCtx,
+                                             const char         *szLabel,
+                                             UsefulBufC         *pText);
+
+
+
+
 /**
  @brief Decode next item into a double floating-point value.
 
@@ -459,6 +521,309 @@
                                          double             *pdValue);
 
 
+
+
+/**
+ @brief Enter an array for decoding in bounded mode.
+
+ @param[in] pCtx   The decode context.
+
+ This enters an array for decoding in bounded mode. The items in array
+ are decoded in order the same as when not in bounded mode, but the
+ decoding will not proceed past the end or the array. The error @ref
+ QCBOR_ERR_NO_MORE_ITEMS will be set when the end of the array is
+ encountered. To decode past the end of the array,
+ QCBORDecode_ExitArray() must be called. Also, QCBORDecode_Finish()
+ will return an error if all arrays that were enetered are not exited.
+
+ This works the same for definite and indefinite length arrays.
+
+ See @ref Decode-Errors for discussion on how error handling works.
+
+ If attempting to enter a data item that is not an array @ref
+ QCBOR_ERR_UNEXPECTED_TYPE wil be set.
+
+ Nested arrays and maps may be entered to a depth of @ref
+ QCBOR_MAX_ARRAY_NESTING.
+
+ See also QCBORDecode_ExitArray(), QCBORDecode_EnterMap() and
+ QCBORDecode_EnterBstrWrapped().
+*/
+static void QCBORDecode_EnterArray(QCBORDecodeContext *pCtx);
+
+void QCBORDecode_EnterArrayFromMapN(QCBORDecodeContext *pMe, int64_t uLabel);
+
+void QCBORDecode_EnterArrayFromMapSZ(QCBORDecodeContext *pMe, const char *szLabel);
+
+
+/**
+ @brief Exit an array that has been enetered.
+
+ @param[in] pCtx   The decode context.
+
+ An array must have been entered for this to succeed.
+
+ The items in the array that was entered do not have to have been
+ consumed for this to succeed.
+
+ This sets the pre-order traversal cursor to the item after the array
+ that was exited.
+*/
+static void QCBORDecode_ExitArray(QCBORDecodeContext *pCtx);
+
+
+
+
+/**
+ @brief Enter a map for decoding and searching.
+
+ @param[in] pCtx   The decode context.
+
+ The next item in the CBOR input must be map or this sets an error.
+
+ This puts the decoder in bounded mode which narrows decoding to the
+ map entered and enables getting items by label.
+
+ All items in the map must be well-formed to be able to search it by
+ label because a full traversal is done for each search. If not, the
+ search will retun an error for the item that is not well-formed.
+ This will be the first non-well-formed item which may not be the item
+ with the label that is the target of the search.
+
+ Nested maps can be decoded like this by entering each map in turn.
+
+ Call QCBORDecode_ExitMap() to exit the current map decoding
+ level. When all map decoding layers are exited then bounded mode is
+ fully exited.
+
+ While in bounded mode, QCBORDecode_GetNext() works as usual on the
+ map and the in-order traversal cursor is maintained. It starts out at
+ the first item in the map just entered. Attempts to get items off the
+ end of the map will give error @ref QCBOR_ERR_NO_MORE_ITEMS rather
+ going to the next item after the map as it would when not in bounded
+ mode.
+
+ Exiting leaves the pre-order cursor at the data item following the
+ last entry in the map or at the end of the input CBOR if there
+ nothing after the map.
+
+ Entering and Exiting a map is a way to skip over an entire map and
+ its contents. After QCBORDecode_ExitMap(), the pre-order traversal
+ cursor will be at the first item after the map.
+
+ See @ref Decode-Errors for discussion on how error handling works.
+
+ See also QCBORDecode_EnterArray() and QCBORDecode_EnterBstrWrapped().
+ Entering and exiting any nested combination of maps, arrays and
+ bstr-wrapped CBOR is supported up to the maximum of @ref
+ QCBOR_MAX_ARRAY_NESTING.
+ */
+static void QCBORDecode_EnterMap(QCBORDecodeContext *pCtx);
+
+void QCBORDecode_EnterMapFromMapN(QCBORDecodeContext *pCtx, int64_t nLabel);
+
+void QCBORDecode_EnterMapFromMapSZ(QCBORDecodeContext *pCtx, const char *szLabel);
+
+
+/**
+ @brief Exit a map that has been enetered.
+
+ @param[in] pCtx   The decode context.
+
+ A map must have been entered for this to succeed.
+
+ The items in the map that was entered do not have to have been
+ consumed for this to succeed.
+
+ This sets thepre-order traversal cursor to the item after
+ the map that was exited.
+*/
+static void QCBORDecode_ExitMap(QCBORDecodeContext *pCtx);
+
+
+/**
+ @brief Indicate if decoder is in bound mode.
+ @param[in] pCtx   The decode context.
+
+ @return true is returned if a map, array or bstr wrapped CBOR has
+ been entered. This only returns false if all maps, arrays and bstr
+ wrapped CBOR levels have been exited.
+ */
+bool QCBORDecode_InBoundedMode(QCBORDecodeContext *pCtx);
+
+
+/**
+ @brief Get an item in map by label and type.
+
+ @param[in] pCtx   The decode context.
+ @param[in] nLabel The integer label.
+ @param[in] uQcborType  The QCBOR type. One of @c QCBOR_TYPE_XXX.
+ @param[out] pItem  The returned item.
+
+ A map must have been entered to use this. If not @ref QCBOR_ERR_MAP_NOT_ENTERED is
+ set.
+
+ The map is searched for an item of the requested label and type.
+ @ref QCBOR_TYPE_ANY can be given to search for the label without
+ matching the type.
+
+ This will always search the entire map. This will always perform
+ duplicate label detection, setting @ref QCBOR_ERR_DUPLICATE_LABEL if
+ there is more than one occurance of the label being searched for.
+
+ Duplicate label detection is performed for the item being sought, but
+ only for the item being sought.
+
+ This performs a full decode of every item in the map being searched,
+ which involves a full traversal of every item. For maps with little
+ nesting, this is of little consequence, but may be of consequence for
+ large deeply nested CBOR structures on slow CPUs.
+
+ See @ref Decode-Errors for discussion on how error handling works.
+
+ See also QCBORDecode_GetItemsInMap() for error discussion.
+*/
+void QCBORDecode_GetItemInMapN(QCBORDecodeContext *pCtx,
+                               int64_t             nLabel,
+                               uint8_t             uQcborType,
+                               QCBORItem          *pItem);
+
+void QCBORDecode_GetItemInMapSZ(QCBORDecodeContext *pCtx,
+                                const char         *szLabel,
+                                uint8_t             uQcborType,
+                                QCBORItem          *pItem);
+
+
+/**
+ @brief Get a group of labeled items all at once from a map
+
+ @param[in] pCtx   The decode context.
+ @param[in,out] pItemList  On input the items to search for. On output the returned items.
+
+ This gets several labeled items out of a map.
+
+ @c pItemList is an array of items terminated by an item with @c
+ uLabelType @ref QCBOR_TYPE_NONE.
+
+ On input the labels to search for are in the @c uLabelType and label
+ fields in the items in @c pItemList.
+
+ Also on input are the requested QCBOR types in the field @c
+ uDataType.  To match any type, searching just by label, @c uDataType
+ can be @ref QCBOR_TYPE_ANY.
+
+ This is a CPU-efficient way to decode a bunch of items in a map. It
+ is more efficient than scanning each individually because the map
+ only needs to be traversed once.
+
+ This will return maps and arrays that are in the map, but provides no
+ way to descend into and decode them. Use
+ QCBORDecode_EnterMapinMapN(), QCBORDecode_EnterArrayInMapN() and such
+ to descend into and process maps and arrays.
+
+ See @ref Decode-Errors for discussion on how error handling works.
+
+ The following errors are set:
+
+ @ref QCBOR_ERR_MAP_NOT_ENTERED when calling this without previousl
+ calling QCBORDecode_EnterMap() or other methods to enter a map.
+
+ @ref QCBOR_ERR_DUPLICATE_LABEL when one of the labels being searched
+ for is duplicate.
+
+ @ref QCBOR_ERR_HIT_END or other errors classifed as not-well-formed
+ by QCBORDecode_IsNotWellFormed() as it is not possible to traverse
+ maps that have any non-well formed items.
+
+ @ref QCBOR_ERR_UNEXPECTED_TYPE when the type of an item found by
+ matching a label is not the type requested.
+
+ @ref QCBOR_ERR_ARRAY_NESTING_TOO_DEEP and other implementation limit
+  errors as it is not possible to travere a map beyond the limits of
+  the implementation.
+
+ The error may occur on items that are not being searched for.  For
+ example, it is impossible to traverse over a map that has an array in
+ it that is not closed or over array and map nesting deeper than this
+ implementation can track.
+
+ See also QCBORDecode_GetItemInMapN().
+ */
+void QCBORDecode_GetItemsInMap(QCBORDecodeContext *pCtx, QCBORItem *pItemList);
+
+
+/**
+ @brief Per-item callback for map searching.
+
+ @param[in] pCallbackCtx  Pointer to the caller-defined context for the callback
+ @param[in] pItem  The item from the map.
+
+ The error set is intended for QCBOR errors, not general protocol
+ decoding errors. If this sets other than @ref QCBOR_SUCCESS, the
+ search will stop and the value it returns will be set in
+ QCBORDecode_GetItemsInMapWithCallback(). The special error, @ref
+ QCBOR_ERR_CALLBACK_FAIL, can be returned to indicate some protocol
+ processing error that is not a CBOR error. The specific details of
+ the protocol processing error can be returned the call back context.
+ */
+typedef QCBORError (*QCBORItemCallback)(void            *pCallbackCtx,
+                                        const QCBORItem *pItem);
+
+
+/**
+ @brief Get a group of labeled items all at once from a map with a callback
+
+ @param[in] pCtx   The decode context.
+ @param[in,out] pItemList  On input the items to search for. On output the returned items.
+ @param[in,out] pCallbackCtx Pointer to a context structure for @ref QCBORItemCallback
+ @param[in] pfCB pointer to function of type @ref QCBORItemCallback that is called on unmatched items.
+
+ This searchs a map like QCBORDecode_GetItemsInMap(), but calls a
+ callback on items not matched rather than ignoring them. If @c
+ pItemList is empty, the call back will be called on every item in the
+ map.
+
+ Like QCBORDecode_GetItemsInMap(), this only matches and calls back on
+ the items at the top level of the map entered. Items in nested
+ maps and arrays are skipped over and not candidate for matching or the
+ callback.
+
+ See QCBORItemCallback() for error handling.
+ */
+void QCBORDecode_GetItemsInMapWithCallback(QCBORDecodeContext *pCtx,
+                                           QCBORItem          *pItemList,
+                                           void               *pCallbackCtx,
+                                           QCBORItemCallback   pfCB);
+
+
+
+
+/**
+ @brief Decode the next item as a Boolean.
+
+ @param[in] pCtx   The decode context.
+ @param[out] pbBool  The decoded byte string.
+
+ The CBOR item to decode must be either the CBOR simple value (CBOR
+ type 7) @c true or @c false.
+
+ See @ref Decode-Errors for discussion on how error handling works.  It
+ the CBOR item to decode is not true or false the @ref
+ QCBOR_ERR_UNEXPECTED_TYPE error is set.
+*/
+void QCBORDecode_GetBool(QCBORDecodeContext *pCtx, bool *pbBool);
+
+void QCBORDecode_GetBoolInMapN(QCBORDecodeContext *pCtx,
+                               int64_t             nLabel,
+                               bool               *pbBool);
+
+void QCBORDecode_GetBoolInMapSZ(QCBORDecodeContext *pCtx,
+                                const char         *szLabel,
+                                bool               *pbBool);
+
+
+
+
 /**
  @brief Decode next item into a double floating-point value with basic conversion.
 
@@ -495,9 +860,9 @@
                                          double             *pdValue);
 
 static void QCBORDecode_GetDoubleConvertInMapN(QCBORDecodeContext *pCtx,
-                                               int64_t            nLabel,
-                                               uint32_t           uConvertTypes,
-                                               double            *pdValue);
+                                               int64_t             nLabel,
+                                               uint32_t            uConvertTypes,
+                                               double             *pdValue);
 
 static void QCBORDecode_GetDoubleConvertInMapSZ(QCBORDecodeContext *pCtx,
                                                 const char         *szLabel,
@@ -546,83 +911,6 @@
 
 
 /**
- @brief Decode the next item as a byte string
-
- @param[in] pCtx   The decode context
- @param[out] pBytes  The decoded byte string
-
- The CBOR item to decode must be a byte string, CBOR type 2.
-
- See @ref Decode-Errors for discussion on how error handling works.
-
- If the CBOR tem to decode is not a byte string, the @ref
- QCBOR_ERR_UNEXPECTED_TYPE error is set.
- */
-static void QCBORDecode_GetByteString(QCBORDecodeContext *pCtx,
-                                      UsefulBufC *pBytes);
-
-static void QCBORDecode_GetByteStringInMapN(QCBORDecodeContext *pCtx,
-                                            int64_t             nLabel,
-                                            UsefulBufC         *pBytes);
-
-static void QCBORDecode_GetByteStringInMapSZ(QCBORDecodeContext *pCtx,
-                                             const char         *szLabel,
-                                             UsefulBufC         *pBytes);
-
-
-/**
- @brief Decode the next item as a text string.
-
- @param[in] pCtx   The decode context.
- @param[out] pText  The decoded byte string.
-
- The CBOR item to decode must be a text string, CBOR type 3.
-
- See @ref Decode-Errors for discussion on how error handling works.  It the CBOR item
- to decode is not a text string, the @ref QCBOR_ERR_UNEXPECTED_TYPE
- error is set.
-*/
-static void QCBORDecode_GetTextString(QCBORDecodeContext *pCtx,
-                                      UsefulBufC *pText);
-
-static void QCBORDecode_GetTextStringInMapN(QCBORDecodeContext *pCtx,
-                                            int64_t             nLabel,
-                                            UsefulBufC         *pText);
-
-static void QCBORDecode_GetTextStringInMapSZ(QCBORDecodeContext *pCtx,
-                                             const char         *szLabel,
-                                             UsefulBufC         *pText);
-
-
-
-
-/**
- @brief Decode the next item as a Boolean.
-
- @param[in] pCtx   The decode context.
- @param[out] pbBool  The decoded byte string.
-
- The CBOR item to decode must be either the CBOR simple value (CBOR
- type 7) @c true or @c false.
-
- See @ref Decode-Errors for discussion on how error handling works.  It
- the CBOR item to decode is not true or false the @ref
- QCBOR_ERR_UNEXPECTED_TYPE error is set.
-*/
-void QCBORDecode_GetBool(QCBORDecodeContext *pCtx, bool *pbBool);
-
-void QCBORDecode_GetBoolInMapN(QCBORDecodeContext *pCtx,
-                               int64_t             nLabel,
-                               bool               *pbBool);
-
-void QCBORDecode_GetBoolInMapSZ(QCBORDecodeContext *pCtx,
-                                const char         *szLabel,
-                                bool               *pbBool);
-
-
-
-
-/**
  @brief Decode the next item as a date string.
 
  @param[in] pCtx             The decode context.
@@ -655,7 +943,6 @@
                                              UsefulBufC         *pDateString);
 
 
-
 /**
  @brief Decode the next item as an epoch date.
 
@@ -686,8 +973,8 @@
  @ref QCBOR_TYPE_DATE_EPOCH.
 */
 void QCBORDecode_GetEpochDate(QCBORDecodeContext *pCtx,
-                              uint8_t              uTagRequirement,
-                              int64_t             *pnTime);
+                              uint8_t             uTagRequirement,
+                              int64_t            *pnTime);
 
 void QCBORDecode_GetEpochDateInMapN(QCBORDecodeContext *pCtx,
                                     int64_t             nLabel,
@@ -700,6 +987,8 @@
                                      int64_t            *pnTime);
 
 
+
+
 /**
  @brief Decode the next item as a big number.
 
@@ -761,6 +1050,8 @@
                                   bool               *pbIsNegative);
 
 
+
+
 #ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
 /**
  @brief Decode the next item as a decimal fraction.
@@ -962,6 +1253,8 @@
 #endif /* #ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
 
 
+
+
 /**
  @brief Decode the next item as a URI.
 
@@ -1101,8 +1394,7 @@
  @param[in] pCtx             The decode context.
  @param[in] uTagRequirement  One of @c QCBOR_TAG_REQUIREMENT_XXX.
  @param[out] pMessage        The decoded regular expression.
- @param[out] pbIsNot7Bit     @c true if MIME is binary or 8-bit.
-
+ @param[out] pbIsTag257     @c true if tag was 257. May be @c NULL.
 
  This decodes the standard CBOR MIME and binary MIME tags, integer tag
  numbers of 36 or 257, or encoded CBOR that is not a tag, that is a
@@ -1114,34 +1406,37 @@
 
  The MIME message itself is not parsed.
 
- This decodes both tag 36 and 257. If it is tag 257, pbIsNot7Bit
- is @c true. While it is clear that tag 36 can't contain,
- binary or 8-bit MIME, it is probably legal for tag 257
- to contain 7-bit MIME. Hopefully in most uses the
- Content-Transfer-Encoding header is present and the
- contents of pbIsNot7Bit can be ignored. It may be NULL.
+ This decodes both tag 36 and 257. If it is tag 257, pbIsTag257
+ is @c true. The difference between the two is that
+ tag 36 is utf8 and tag 257 is a byte string that can
+ carry binary MIME. QCBOR processes them exactly
+ the same. Possibly the difference can be ignored.
+ NULL can be passed to have no value returned.
 
  See also @ref CBOR_TAG_MIME, @ref CBOR_TAG_BINARY_MIME,
- QCBOREncode_AddMIMEData(), @ref QCBOR_TYPE_MIME and
+ QCBOREncode_AddTMIMEData(), @ref QCBOR_TYPE_MIME and
  @ref QCBOR_TYPE_BINARY_MIME.
+
+ This does no translation of line endings. See QCBOREncode_AddText()
+ for a discussion of line endings in CBOR.
 */
 static void QCBORDecode_GetMIMEMessage(QCBORDecodeContext *pCtx,
                                        uint8_t             uTagRequirement,
                                        UsefulBufC         *pMessage,
-                                       bool               *pbIsNot7Bit);
+                                       bool               *pbIsTag257);
 
 static void QCBORDecode_GetMIMEMessageInMapN(QCBORDecodeContext *pCtx,
                                             int64_t              nLabel,
                                             uint8_t              uTagRequirement,
                                             UsefulBufC          *pMessage,
-                                            bool                *pbIsNot7Bit);
+                                            bool                *pbIsTag257);
 
 
 static void QCBORDecode_GetMIMEMessageInMapSZ(QCBORDecodeContext *pCtx,
                                               const char         *szLabel,
                                               uint8_t             uTagRequirement,
                                               UsefulBufC         *pMessage,
-                                              bool               *pbIsNot7Bit);
+                                              bool               *pbIsTag257);
 
 /**
  @brief Decode the next item as a UUID
@@ -1178,124 +1473,6 @@
 
 
 /**
- @brief Enter a map for decoding and searching.
-
- @param[in] pCtx   The decode context.
-
- The next item in the CBOR input must be map or this sets an error.
-
- This puts the decoder in bounded mode which narrows decoding to the
- map entered and enables getting items by label.
-
- All items in the map must be well-formed to be able to search it by
- label because a full traversal is done for each search. If not, the
- search will retun an error for the item that is not well-formed.
- This will be the first non-well-formed item which may not be the item
- with the label that is the target of the search.
-
- Nested maps can be decoded like this by entering each map in turn.
-
- Call QCBORDecode_ExitMap() to exit the current map decoding
- level. When all map decoding layers are exited then bounded mode is
- fully exited.
-
- While in bounded mode, QCBORDecode_GetNext() works as usual on the
- map and the in-order traversal cursor is maintained. It starts out at
- the first item in the map just entered. Attempts to get items off the
- end of the map will give error @ref QCBOR_ERR_NO_MORE_ITEMS rather
- going to the next item after the map as it would when not in bounded
- mode.
-
- Exiting leaves the pre-order cursor at the data item following the
- last entry in the map or at the end of the input CBOR if there
- nothing after the map.
-
- Entering and Exiting a map is a way to skip over an entire map and
- its contents. After QCBORDecode_ExitMap(), the pre-order traversal
- cursor will be at the first item after the map.
-
- See @ref Decode-Errors for discussion on how error handling works.
-
- See also QCBORDecode_EnterArray() and QCBORDecode_EnterBstrWrapped().
- Entering and exiting any nested combination of maps, arrays and
- bstr-wrapped CBOR is supported up to the maximum of @ref
- QCBOR_MAX_ARRAY_NESTING.
- */
-static void QCBORDecode_EnterMap(QCBORDecodeContext *pCtx);
-
-void QCBORDecode_EnterMapFromMapN(QCBORDecodeContext *pCtx, int64_t nLabel);
-
-void QCBORDecode_EnterMapFromMapSZ(QCBORDecodeContext *pCtx, const char *szLabel);
-
-
-/**
- @brief Exit a map that has been enetered.
-
- @param[in] pCtx   The decode context.
-
- A map must have been entered for this to succeed.
-
- The items in the map that was entered do not have to have been
- consumed for this to succeed.
-
- This sets thepre-order traversal cursor to the item after
- the map that was exited.
-*/
-static void QCBORDecode_ExitMap(QCBORDecodeContext *pCtx);
-
-
-/**
- @brief Enter an array for decoding in bounded mode.
-
- @param[in] pCtx   The decode context.
-
- This enters an array for decoding in bounded mode. The items in array
- are decoded in order the same as when not in bounded mode, but the
- decoding will not proceed past the end or the array. The error @ref
- QCBOR_ERR_NO_MORE_ITEMS will be set when the end of the array is
- encountered. To decode past the end of the array,
- QCBORDecode_ExitArray() must be called. Also, QCBORDecode_Finish()
- will return an error if all arrays that were enetered are not exited.
-
- This works the same for definite and indefinite length arrays.
-
- See @ref Decode-Errors for discussion on how error handling works.
-
- If attempting to enter a data item that is not an array @ref
- QCBOR_ERR_UNEXPECTED_TYPE wil be set.
-
- Nested arrays and maps may be entered to a depth of @ref
- QCBOR_MAX_ARRAY_NESTING.
-
- See also QCBORDecode_ExitArray(), QCBORDecode_EnterMap() and
- QCBORDecode_EnterBstrWrapped().
-*/
-static void QCBORDecode_EnterArray(QCBORDecodeContext *pCtx);
-
-void QCBORDecode_EnterArrayFromMapN(QCBORDecodeContext *pMe, int64_t uLabel);
-
-void QCBORDecode_EnterArrayFromMapSZ(QCBORDecodeContext *pMe, const char *szLabel);
-
-
-/**
- @brief Exit an array that has been enetered.
-
- @param[in] pCtx   The decode context.
-
- An array must have been entered for this to succeed.
-
- The items in the array that was entered do not have to have been
- consumed for this to succeed.
-
- This sets the pre-order traversal cursor to the item after the array
- that was exited.
-*/
-static void QCBORDecode_ExitArray(QCBORDecodeContext *pCtx);
-
-
-
-
-/**
  @brief Decode some byte-string wrapped CBOR.
 
  @param[in] pCtx   The decode context.
@@ -1375,162 +1552,6 @@
 void QCBORDecode_ExitBstrWrapped(QCBORDecodeContext *pCtx);
 
 
-/**
- @brief Indicate if decoder is in bound mode.
- @param[in] pCtx   The decode context.
-
- @return true is returned if a map, array or bstr wrapped CBOR has
- been entered. This only returns false if all maps, arrays and bstr
- wrapped CBOR levels have been exited.
- */
-bool QCBORDecode_InBoundedMode(QCBORDecodeContext *pCtx);
-
-
-/**
- @brief Get an item in map by label and type.
-
- @param[in] pCtx   The decode context.
- @param[in] nLabel The integer label.
- @param[in] uQcborType  The QCBOR type. One of @c QCBOR_TYPE_XXX.
- @param[out] pItem  The returned item.
-
- A map must have been entered to use this. If not @ref QCBOR_ERR_MAP_NOT_ENTERED is
- set.
-
- The map is searched for an item of the requested label and type.
- @ref QCBOR_TYPE_ANY can be given to search for the label without
- matching the type.
-
- This will always search the entire map. This will always perform
- duplicate label detection, setting @ref QCBOR_ERR_DUPLICATE_LABEL if
- there is more than one occurance of the label being searched for.
-
- Duplicate label detection is performed for the item being sought, but
- only for the item being sought.
-
- This performs a full decode of every item in the map being searched,
- which involves a full traversal of every item. For maps with little
- nesting, this is of little consequence, but may be of consequence for
- large deeply nested CBOR structures on slow CPUs.
-
- See @ref Decode-Errors for discussion on how error handling works.
-
- See also QCBORDecode_GetItemsInMap() for error discussion.
-*/
-void QCBORDecode_GetItemInMapN(QCBORDecodeContext *pCtx,
-                               int64_t             nLabel,
-                               uint8_t             uQcborType,
-                               QCBORItem          *pItem);
-
-void QCBORDecode_GetItemInMapSZ(QCBORDecodeContext *pCtx,
-                                const char         *szLabel,
-                                uint8_t             uQcborType,
-                                QCBORItem          *pItem);
-
-
-/**
- @brief Get a group of labeled items all at once from a map
-
- @param[in] pCtx   The decode context.
- @param[in,out] pItemList  On input the items to search for. On output the returned items.
-
- This gets several labeled items out of a map.
-
- @c pItemList is an array of items terminated by an item with @c
- uLabelType @ref QCBOR_TYPE_NONE.
-
- On input the labels to search for are in the @c uLabelType and label
- fields in the items in @c pItemList.
-
- Also on input are the requested QCBOR types in the field @c
- uDataType.  To match any type, searching just by label, @c uDataType
- can be @ref QCBOR_TYPE_ANY.
-
- This is a CPU-efficient way to decode a bunch of items in a map. It
- is more efficient than scanning each individually because the map
- only needs to be traversed once.
-
- This will return maps and arrays that are in the map, but provides no
- way to descend into and decode them. Use
- QCBORDecode_EnterMapinMapN(), QCBORDecode_EnterArrayInMapN() and such
- to descend into and process maps and arrays.
-
- See @ref Decode-Errors for discussion on how error handling works.
-
- The following errors are set:
-
- @ref QCBOR_ERR_MAP_NOT_ENTERED when calling this without previousl
- calling QCBORDecode_EnterMap() or other methods to enter a map.
-
- @ref QCBOR_ERR_DUPLICATE_LABEL when one of the labels being searched
- for is duplicate.
-
- @ref QCBOR_ERR_HIT_END or other errors classifed as not-well-formed
- by QCBORDecode_IsNotWellFormed() as it is not possible to traverse
- maps that have any non-well formed items.
-
- @ref QCBOR_ERR_UNEXPECTED_TYPE when the type of an item found by
- matching a label is not the type requested.
-
- @ref QCBOR_ERR_ARRAY_NESTING_TOO_DEEP and other implementation limit
-  errors as it is not possible to travere a map beyond the limits of
-  the implementation.
-
- The error may occur on items that are not being searched for.  For
- example, it is impossible to traverse over a map that has an array in
- it that is not closed or over array and map nesting deeper than this
- implementation can track.
-
- See also QCBORDecode_GetItemInMapN().
- */
-void QCBORDecode_GetItemsInMap(QCBORDecodeContext *pCtx, QCBORItem *pItemList);
-
-
-/**
- @brief Per-item callback for map searching.
-
- @param[in] pCallbackCtx  Pointer to the caller-defined context for the callback
- @param[in] pItem  The item from the map.
-
- The error set is intended for QCBOR errors, not general protocol
- decoding errors. If this sets other than @ref QCBOR_SUCCESS, the
- search will stop and the value it returns will be set in
- QCBORDecode_GetItemsInMapWithCallback(). The special error, @ref
- QCBOR_ERR_CALLBACK_FAIL, can be returned to indicate some protocol
- processing error that is not a CBOR error. The specific details of
- the protocol processing error can be returned the call back context.
- */
-typedef QCBORError (*QCBORItemCallback)(void *pCallbackCtx,
-                                        const QCBORItem *pItem);
-
-
-/**
- @brief Get a group of labeled items all at once from a map with a callback
-
- @param[in] pCtx   The decode context.
- @param[in,out] pItemList  On input the items to search for. On output the returned items.
- @param[in,out] pCallbackCtx Pointer to a context structure for @ref QCBORItemCallback
- @param[in] pfCB pointer to function of type @ref QCBORItemCallback that is called on unmatched items.
-
- This searchs a map like QCBORDecode_GetItemsInMap(), but calls a
- callback on items not matched rather than ignoring them. If @c
- pItemList is empty, the call back will be called on every item in the
- map.
-
- Like QCBORDecode_GetItemsInMap(), this only matches and calls back on
- the items at the top level of the map entered. Items in nested
- maps and arrays are skipped over and not candidate for matching or the
- callback.
-
- See QCBORItemCallback() for error handling.
- */
-void QCBORDecode_GetItemsInMapWithCallback(QCBORDecodeContext *pCtx,
-                                           QCBORItem          *pItemList,
-                                           void               *pCallbackCtx,
-                                           QCBORItemCallback   pfCB);
-
-
-
 
 
 /* ===========================================================================
@@ -1539,6 +1560,95 @@
 
 
 // Semi-private
+void
+QCBORDecode_GetUInt64ConvertInternal(QCBORDecodeContext *pMe,
+                                     uint32_t            uConvertTypes,
+                                     uint64_t           *puValue,
+                                     QCBORItem          *pItem);
+
+// Semi-private
+void
+QCBORDecode_GetUInt64ConvertInternalInMapN(QCBORDecodeContext *pMe,
+                                           int64_t             nLabel,
+                                           uint32_t            uConvertTypes,
+                                           uint64_t           *puValue,
+                                           QCBORItem          *pItem);
+
+// Semi-private
+void
+QCBORDecode_GetUInt64ConvertInternalInMapSZ(QCBORDecodeContext *pMe,
+                                            const char         *szLabel,
+                                            uint32_t            uConvertTypes,
+                                            uint64_t           *puValue,
+                                            QCBORItem          *pItem);
+
+
+void QCBORDecode_GetUInt64Convert(QCBORDecodeContext *pMe,
+                                  uint32_t            uConvertTypes,
+                                  uint64_t           *puValue)
+{
+    QCBORItem Item;
+    QCBORDecode_GetUInt64ConvertInternal(pMe, uConvertTypes, puValue, &Item);
+}
+
+inline static void
+QCBORDecode_GetUInt64ConvertInMapN(QCBORDecodeContext *pMe,
+                                   int64_t             nLabel,
+                                   uint32_t            uConvertTypes,
+                                   uint64_t           *puValue)
+{
+   QCBORItem Item;
+   QCBORDecode_GetUInt64ConvertInternalInMapN(pMe,
+                                              nLabel,
+                                              uConvertTypes,
+                                              puValue,
+                                              &Item);
+}
+
+inline static void
+QCBORDecode_GetUInt64ConvertInMapSZ(QCBORDecodeContext *pMe,
+                                    const char         *szLabel,
+                                    uint32_t            uConvertTypes,
+                                    uint64_t           *puValue)
+{
+   QCBORItem Item;
+   QCBORDecode_GetUInt64ConvertInternalInMapSZ(pMe,
+                                               szLabel,
+                                               uConvertTypes,
+                                               puValue,
+                                               &Item);
+}
+
+static inline void
+QCBORDecode_GetUInt64(QCBORDecodeContext *pMe, uint64_t *puValue)
+{
+    QCBORDecode_GetUInt64Convert(pMe, QCBOR_CONVERT_TYPE_XINT64, puValue);
+}
+
+inline static void
+QCBORDecode_GetUInt64InMapN(QCBORDecodeContext *pMe,
+                            int64_t             nLabel,
+                            uint64_t           *puValue)
+{
+   QCBORDecode_GetUInt64ConvertInMapN(pMe,
+                                      nLabel,
+                                      QCBOR_CONVERT_TYPE_XINT64,
+                                      puValue);
+}
+
+inline static void
+QCBORDecode_GetUInt64InMapSZ(QCBORDecodeContext *pMe,
+                             const char         *szLabel,
+                             uint64_t           *puValue)
+{
+   QCBORDecode_GetUInt64ConvertInMapSZ(pMe,
+                                       szLabel,
+                                       QCBOR_CONVERT_TYPE_XINT64,
+                                       puValue);
+}
+
+
+// Semi-private
 void QCBORDecode_EnterBoundedMapOrArray(QCBORDecodeContext *pMe, uint8_t uType);
 
 // Semi-private
@@ -1600,15 +1710,16 @@
 
 inline static void
 QCBORDecode_GetInt64ConvertInMapN(QCBORDecodeContext *pMe,
-                                  int64_t            nLabel,
-                                  uint32_t           uConvertTypes,
-                                  int64_t           *pnValue)
+                                  int64_t             nLabel,
+                                  uint32_t            uConvertTypes,
+                                  int64_t            *pnValue)
 {
    QCBORItem Item;
    QCBORDecode_GetInt64ConvertInternalInMapN(pMe,
                                              nLabel,
                                              uConvertTypes,
-                                             pnValue, &Item);
+                                             pnValue,
+                                             &Item);
 }
 
 inline static void
@@ -1621,7 +1732,8 @@
    QCBORDecode_GetInt64ConvertInternalInMapSZ(pMe,
                                               szLabel,
                                               uConvertTypes,
-                                              pnValue, &Item);
+                                              pnValue,
+                                              &Item);
 }
 
 inline static void
@@ -1632,8 +1744,8 @@
 
 inline static void
 QCBORDecode_GetInt64InMapN(QCBORDecodeContext *pMe,
-                           int64_t nLabel,
-                           int64_t *pnValue)
+                           int64_t             nLabel,
+                           int64_t            *pnValue)
 {
    QCBORDecode_GetInt64ConvertInMapN(pMe,
                                      nLabel,
@@ -1643,8 +1755,8 @@
 
 inline static void
 QCBORDecode_GetInt64InMapSZ(QCBORDecodeContext *pMe,
-                            const char *szLabel,
-                            int64_t *pnValue)
+                            const char         *szLabel,
+                            int64_t            *pnValue)
 {
    QCBORDecode_GetInt64ConvertInMapSZ(pMe,
                                       szLabel,
@@ -1655,95 +1767,6 @@
 
 
 
-// Semi-private
-void
-QCBORDecode_GetUInt64ConvertInternal(QCBORDecodeContext *pMe,
-                                     uint32_t            uConvertTypes,
-                                     uint64_t           *puValue,
-                                     QCBORItem          *pItem);
-
-// Semi-private
-void
-QCBORDecode_GetUInt64ConvertInternalInMapN(QCBORDecodeContext *pMe,
-                                           int64_t             nLabel,
-                                           uint32_t            uConvertTypes,
-                                           uint64_t           *puValue,
-                                           QCBORItem          *pItem);
-
-// Semi-private
-void
-QCBORDecode_GetUInt64ConvertInternalInMapSZ(QCBORDecodeContext *pMe,
-                                            const char         *szLabel,
-                                            uint32_t            uConvertTypes,
-                                            uint64_t           *puValue,
-                                            QCBORItem          *pItem);
-
-
-void QCBORDecode_GetUInt64Convert(QCBORDecodeContext *pMe,
-                                  uint32_t uConvertTypes,
-                                  uint64_t *puValue)
-{
-    QCBORItem Item;
-    QCBORDecode_GetUInt64ConvertInternal(pMe, uConvertTypes, puValue, &Item);
-}
-
-inline static void
-QCBORDecode_GetUInt64ConvertInMapN(QCBORDecodeContext *pMe,
-                                   int64_t            nLabel,
-                                   uint32_t           uConvertTypes,
-                                   uint64_t          *puValue)
-{
-   QCBORItem Item;
-   QCBORDecode_GetUInt64ConvertInternalInMapN(pMe,
-                                              nLabel,
-                                              uConvertTypes,
-                                              puValue,
-                                              &Item);
-}
-
-inline static void
-QCBORDecode_GetUInt64ConvertInMapSZ(QCBORDecodeContext *pMe,
-                                    const char         *szLabel,
-                                    uint32_t            uConvertTypes,
-                                    uint64_t           *puValue)
-{
-   QCBORItem Item;
-   QCBORDecode_GetUInt64ConvertInternalInMapSZ(pMe,
-                                               szLabel,
-                                               uConvertTypes,
-                                               puValue,
-                                               &Item);
-}
-
-static inline void
-QCBORDecode_GetUInt64(QCBORDecodeContext *pMe, uint64_t *puValue)
-{
-    QCBORDecode_GetUInt64Convert(pMe, QCBOR_CONVERT_TYPE_XINT64, puValue);
-}
-
-inline static void
-QCBORDecode_GetUInt64InMapN(QCBORDecodeContext *pMe,
-                            int64_t             nLabel,
-                            uint64_t           *puValue)
-{
-   QCBORDecode_GetUInt64ConvertInMapN(pMe,
-                                      nLabel,
-                                      QCBOR_CONVERT_TYPE_XINT64,
-                                      puValue);
-}
-
-inline static void
-QCBORDecode_GetUInt64InMapSZ(QCBORDecodeContext *pMe,
-                             const char         *szLabel,
-                             uint64_t           *puValue)
-{
-   QCBORDecode_GetUInt64ConvertInMapSZ(pMe,
-                                       szLabel,
-                                       QCBOR_CONVERT_TYPE_XINT64,
-                                       puValue);
-}
-
-
 
 // Semi-private
 void
@@ -1755,10 +1778,10 @@
 // Semi-private
 void
 QCBORDecode_GetDoubleConvertInternalInMapN(QCBORDecodeContext *pMe,
-                                           int64_t            nLabel,
-                                           uint32_t           uConvertTypes,
-                                           double            *pdValue,
-                                           QCBORItem         *pItem);
+                                           int64_t             nLabel,
+                                           uint32_t            uConvertTypes,
+                                           double             *pdValue,
+                                           QCBORItem          *pItem);
 
 // Semi-private
 void
@@ -1871,10 +1894,10 @@
 
 
 // Semi private
-QCBORError QCBORDecode_GetMIMEInternal(uint8_t     uTagRequirement,
-                                       const       QCBORItem *pItem,
-                                       UsefulBufC *pMessage,
-                                       bool       *pbIsNot7Bit);
+QCBORError QCBORDecode_GetMIMEInternal(uint8_t           uTagRequirement,
+                                       const  QCBORItem *pItem,
+                                       UsefulBufC       *pMessage,
+                                       bool             *pbIsTag257);
 
 
 
@@ -1894,8 +1917,8 @@
 
 inline static void
 QCBORDecode_GetByteStringInMapN(QCBORDecodeContext *pMe,
-                           int64_t             nLabel,
-                           UsefulBufC         *pBstr)
+                                int64_t             nLabel,
+                                UsefulBufC         *pBstr)
 {
    const TagSpecification TagSpec =
       {
@@ -1908,8 +1931,8 @@
 
 inline static void
 QCBORDecode_GetByteStringInMapSZ(QCBORDecodeContext *pMe,
-                            const char         *szLabel,
-                            UsefulBufC         *pBstr)
+                                 const char         *szLabel,
+                                 UsefulBufC         *pBstr)
 {
    const TagSpecification TagSpec =
       {
@@ -1938,8 +1961,8 @@
 
 inline static void
 QCBORDecode_GetTextStringInMapN(QCBORDecodeContext *pMe,
-                          int64_t             nLabel,
-                          UsefulBufC         *pText)
+                                int64_t             nLabel,
+                                UsefulBufC         *pText)
 {
    // This TagSpec only matches text strings; it also should optimize down
    // to passing a 64-bit integer
@@ -1955,8 +1978,8 @@
 
 inline static void
 QCBORDecode_GetTextStringInMapSZ(QCBORDecodeContext *pMe,
-                           const               char *szLabel,
-                           UsefulBufC         *pText)
+                                 const               char *szLabel,
+                                 UsefulBufC         *pText)
 {
    const TagSpecification TagSpec =
       {
@@ -2208,7 +2231,7 @@
 QCBORDecode_GetMIMEMessage(QCBORDecodeContext *pMe,
                            uint8_t             uTagRequirement,
                            UsefulBufC         *pMessage,
-                           bool               *pbIsNot7Bit)
+                           bool               *pbIsTag257)
 {
    if(pMe->uLastError != QCBOR_SUCCESS) {
       // Already in error state, do nothing
@@ -2225,7 +2248,7 @@
    pMe->uLastError = (uint8_t)QCBORDecode_GetMIMEInternal(uTagRequirement,
                                                           &Item,
                                                           pMessage,
-                                                          pbIsNot7Bit);
+                                                          pbIsTag257);
 }
 
 static inline void
@@ -2233,7 +2256,7 @@
                                  int64_t             nLabel,
                                  uint8_t             uTagRequirement,
                                  UsefulBufC         *pMessage,
-                                 bool               *pbIsNot7Bit)
+                                 bool               *pbIsTag257)
 {
    QCBORItem Item;
    QCBORDecode_GetItemInMapN(pMe, nLabel, QCBOR_TYPE_ANY, &Item);
@@ -2242,7 +2265,7 @@
       pMe->uLastError = (uint8_t)QCBORDecode_GetMIMEInternal(uTagRequirement,
                                                              &Item,
                                                              pMessage,
-                                                             pbIsNot7Bit);
+                                                             pbIsTag257);
    }
 }
 
@@ -2251,7 +2274,7 @@
                                   const char         *szLabel,
                                   uint8_t             uTagRequirement,
                                   UsefulBufC         *pMessage,
-                                  bool               *pbIsNot7Bit)
+                                  bool               *pbIsTag257)
 {
    QCBORItem Item;
    QCBORDecode_GetItemInMapSZ(pMe, szLabel, QCBOR_TYPE_ANY, &Item);
@@ -2260,7 +2283,7 @@
       pMe->uLastError = (uint8_t)QCBORDecode_GetMIMEInternal(uTagRequirement,
                                                              &Item,
                                                              pMessage,
-                                                             pbIsNot7Bit);
+                                                             pbIsTag257);
    }
 }
 
diff --git a/src/qcbor_decode.c b/src/qcbor_decode.c
index d697f03..e6a4c0e 100644
--- a/src/qcbor_decode.c
+++ b/src/qcbor_decode.c
@@ -93,11 +93,8 @@
   ===========================================================================*/
 
 /*
- See commecnts about and typedef of QCBORDecodeNesting in qcbor_private.h, the data structure
- all these functions work on.
-
-
-
+ See commecnts about and typedef of QCBORDecodeNesting in qcbor_private.h,
+ the data structure all these functions work on.
  */
 
 
@@ -219,15 +216,15 @@
 DecodeNesting_IsAtEndOfBoundedLevel(const QCBORDecodeNesting *pNesting)
 {
    if(pNesting->pCurrentBounded == NULL) {
-      // No bounded map or array or... 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)) { // TODO: pCurrent vs pCurrentBounded
-      // Not at a bounded level
+   if(!DecodeNesting_IsCurrentBounded(pNesting)) {
+      // In a traveral at a level deeper than the bounded level
       return false;
    }
    // Works for both definite and indefinite length maps/arrays
@@ -235,7 +232,7 @@
       // Count is not zero, still unconsumed item
       return false;
    }
-   // All checks passed, got to the end of a map/array
+   // All checks passed, got to the end of an array or map
    return true;
 }
 
@@ -326,8 +323,11 @@
 
     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
     */
-   if(uOffset >= QCBOR_NON_BOUNDED_OFFSET) {
+   if(uOffset >= QCBOR_MAX_DECODE_INPUT_SIZE) {
       return QCBOR_ERR_INPUT_TOO_LARGE;
    }
 
@@ -471,70 +471,6 @@
 }
 
 
-#include <stdio.h>
-
-const char *TypeStr(uint8_t type)
-{
-   switch(type) {
-      case QCBOR_TYPE_MAP: return "  map";
-      case QCBOR_TYPE_ARRAY: return "array";
-      case QCBOR_TYPE_BYTE_STRING: return " bstr";
-      default: return " --- ";
-   }
-}
-
-static char buf[20]; // Not thread safe, but that is OK
-const char *CountString(uint16_t uCount, uint16_t uTotal)
-{
-   if(uTotal == QCBOR_COUNT_INDICATES_INDEFINITE_LENGTH) {
-      strcpy(buf, "indefinite");
-   } else {
-      sprintf(buf, "%d/%d", uCount, uTotal);
-   }
-   return buf;
-}
-
-
-void DecodeNesting_Print(QCBORDecodeNesting *pNesting, UsefulInputBuf *pBuf, const char *szName)
-{
-#if 0
-   printf("---%s--%d/%d--\narrow is current bounded level\n",
-          szName,
-          (uint32_t)pBuf->cursor,
-          (uint32_t)pBuf->UB.len);
-
-   printf("Level   Type       Count  Offsets \n");
-   for(int i = 0; i < QCBOR_MAX_ARRAY_NESTING; i++) {
-      if(&(pNesting->pLevels[i]) > pNesting->pCurrent) {
-         break;
-      }
-
-      printf("%2s %2d  %s  ",
-             pNesting->pCurrentBounded == &(pNesting->pLevels[i]) ? "->": "  ",
-             i,
-             TypeStr(pNesting->pLevels[i].uLevelType));
-
-      if(pNesting->pLevels[i].uLevelType == QCBOR_TYPE_BYTE_STRING) {
-         printf("               %5d   %5d",
-                pNesting->pLevels[i].u.bs.uEndOfBstr,
-                pNesting->pLevels[i].u.bs.uPreviousEndOffset);
-
-      } else {
-         printf("%10.10s  ",
-                CountString(pNesting->pLevels[i].u.ma.uCountCursor,
-                            pNesting->pLevels[i].u.ma.uCountTotal));
-         if(pNesting->pLevels[i].u.ma.uStartOffset != UINT32_MAX) {
-            printf("Bounded start: %u",pNesting->pLevels[i].u.ma.uStartOffset);
-         }
-      }
-
-      printf("\n");
-   }
-   printf("\n");
-#endif
-}
-
-
 
 /*===========================================================================
    QCBORStringAllocate -- STRING ALLOCATOR INVOCATION
@@ -805,7 +741,8 @@
 
    // 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
+   // DecodeTypeAndNumber() never returns an AdditionalInfo > 0x1f so cast
+   // is safe
    pDecodedItem->uDataType = (uint8_t)nAdditionalInfo;
 
    switch(nAdditionalInfo) {
@@ -1267,7 +1204,7 @@
          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 an problem with being well-formed CBOR.
+         // error, not a problem with being well-formed CBOR.
          continue;
       }
       // Slide tags over one in the array to make room at index 0
@@ -1292,7 +1229,7 @@
             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 an problem with being well-formed CBOR.
+            // error, not a problem with being well-formed CBOR.
             continue;
          }
 
@@ -1361,8 +1298,9 @@
          // be the real data
          QCBORItem LabelItem = *pDecodedItem;
          nReturn = GetNext_TaggedItem(me, pDecodedItem);
-         if(nReturn)
+         if(QCBORDecode_IsUnrecoverableError(nReturn)) {
             goto Done;
+         }
 
          pDecodedItem->uLabelAlloc = LabelItem.uDataAlloc;
 
@@ -1457,7 +1395,8 @@
              /* Didn't close out map or array, so all work here is done */
              break;
           }
-          /* All of a definite length array was consumed; fall through to ascend */
+          /* All of a definite length array was consumed; fall through to
+             ascend */
 
       } else {
          /* If not definite length, have to check for a CBOR break */
@@ -1488,9 +1427,11 @@
 
       /* All items in the map/array level have been consumed. */
 
-      /* But ascent in bounded mode is only by explicit call to QCBORDecode_ExitBoundedMode() */
+      /* But ascent in bounded mode is only by explicit call to
+         QCBORDecode_ExitBoundedMode() */
       if(DecodeNesting_IsCurrentBounded(&(pMe->nesting))) {
-         /* Set the count to zero for definite length arrays to indicate cursor is at end of bounded map / array */
+         /* Set the count to zero for definite length arrays to indicate
+            cursor is at end of bounded map / array */
          if(bMarkEnd) {
             // Used for definite and indefinite to signal end
             DecodeNesting_ZeroMapOrArrayCount(&(pMe->nesting));
@@ -1604,8 +1545,8 @@
       /*
        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.
+       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
@@ -1664,12 +1605,6 @@
    }
 
 Done:
-   if(uReturn != QCBOR_SUCCESS) {
-      /* This sets uDataType and uLabelType to QCBOR_TYPE_NONE */
-      pDecodedItem->uDataType = QCBOR_TYPE_NONE;
-      pDecodedItem->uLabelType = QCBOR_TYPE_NONE;
-      // memset(pDecodedItem, 0, sizeof(QCBORItem));
-   }
    return uReturn;
 }
 
@@ -1874,7 +1809,8 @@
       // 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) {
+   }  else if(mantissaItem.uDataType == QCBOR_TYPE_POSBIGNUM ||
+              mantissaItem.uDataType == QCBOR_TYPE_NEGBIGNUM) {
       // Got a good big num mantissa
       pDecodedItem->val.expAndMantissa.Mantissa.bigNum = mantissaItem.val.bigNum;
       // Depends on numbering of QCBOR_TYPE_XXX
@@ -1995,8 +1931,8 @@
 /*
  Public function, see header qcbor/qcbor_decode.h file
  */
-QCBORError
-QCBORDecode_GetNext(QCBORDecodeContext *me, QCBORItem *pDecodedItem)
+static QCBORError
+QCBORDecode_GetNextTag(QCBORDecodeContext *me, QCBORItem *pDecodedItem)
 {
    QCBORError nReturn;
 
@@ -2026,7 +1962,7 @@
          nReturn = DecodeBigNum(pDecodedItem);
          break;
 
-   #ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
+#ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
          case CBOR_TAG_DECIMAL_FRACTION:
          case CBOR_TAG_BIGFLOAT:
          // For aggregate tagged types, what goes into pTags is only collected
@@ -2035,7 +1971,7 @@
 
          nReturn = QCBORDecode_MantissaAndExponent(me, pDecodedItem);
          break;
-   #endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
+#endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
 
          case CBOR_TAG_CBOR:
          nReturn = DecodeWrappedCBOR(pDecodedItem);
@@ -2090,11 +2026,20 @@
    }
 
 Done:
-   if(nReturn != QCBOR_SUCCESS) {
+   return nReturn;
+}
+
+
+QCBORError
+QCBORDecode_GetNext(QCBORDecodeContext *pMe, QCBORItem *pDecodedItem)
+{
+   QCBORError uErr;
+   uErr = QCBORDecode_GetNextTag(pMe, pDecodedItem);
+   if(uErr != QCBOR_SUCCESS) {
       pDecodedItem->uDataType  = QCBOR_TYPE_NONE;
       pDecodedItem->uLabelType = QCBOR_TYPE_NONE;
    }
-   return nReturn;
+   return uErr;
 }
 
 
@@ -2137,7 +2082,7 @@
          if(pTags->uNumUsed >= pTags->uNumAllocated) {
             return QCBOR_ERR_TOO_MANY_TAGS;
          }
-         pTags->puTags[pTags->uNumUsed] = ConvertTag(me, pDecodedItem->uTags[i]);
+         pTags->puTags[pTags->uNumUsed] = ConvertTag(me,pDecodedItem->uTags[i]);
          pTags->uNumUsed++;
       }
    }
@@ -2337,7 +2282,7 @@
 
    // Just assume the size here. It was checked during SetUp so
    // the assumption is safe.
-   UsefulInputBuf_Init(&UIB, (UsefulBufC){pMem, QCBOR_DECODE_MIN_MEM_POOL_SIZE});
+   UsefulInputBuf_Init(&UIB, (UsefulBufC){pMem,QCBOR_DECODE_MIN_MEM_POOL_SIZE});
    *puPoolSize     = UsefulInputBuf_GetUint32(&UIB);
    *puFreeOffset   = UsefulInputBuf_GetUint32(&UIB);
    return UsefulInputBuf_GetError(&UIB);
@@ -2502,8 +2447,6 @@
    QCBORError uReturn;
    QCBORItem  Item;
 
-   DecodeNesting_Print(&(pMe->nesting), &(pMe->InBuf), "ConsumeItem");
-
    // If it is a map or array, this will tell if it is empty.
    const bool bIsEmpty = (pItemToConsume->uNextNestLevel <= pItemToConsume->uNestingLevel);
 
@@ -2597,11 +2540,14 @@
 
  @retval QCBOR_ERR_NOT_ENTERED Trying to search without having entered a map
 
- @retval QCBOR_ERR_DUPLICATE_LABEL Duplicate items (items with the same label) were found
- for one of the labels being search for. This duplicate detection is only performed for items in pItemArray,
- not every item in the map.
+ @retval QCBOR_ERR_DUPLICATE_LABEL Duplicate items (items with the same label)
+                                   were found for one of the labels being
+                                   search for. This duplicate detection is
+                                   only performed for items in pItemArray,
+                                   not every item in the map.
 
- @retval QCBOR_ERR_UNEXPECTED_TYPE The label was matched, but not the type.
+ @retval QCBOR_ERR_UNEXPECTED_TYPE A label was matched, but the type was
+                                   wrong for the matchd label.
 
  @retval Also errors returned by QCBORDecode_GetNext().
 
@@ -2660,10 +2606,21 @@
                        DecodeNesting_GetMapOrArrayStart(&(pMe->nesting)));
 
    /*
-    Loop over all the items in the map. They could be
-    deeply nested and this should handle both definite
-    and indefinite length maps and arrays, so this
-    adds some complexity.
+    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
+    length maps and arrays. The only reason this is ever
+    called on arrays is to find their end position.
+
+    This will always run over all items in order to do
+    duplicate detection.
+
+    This will exit with failure if it encounters an
+    unrecoverable error, but continue on for recoverable
+    errors.
+
+    If a recoverable error occurs on a matched item, then
+    that error code is returned.
     */
    const uint8_t uMapNestLevel = DecodeNesting_GetBoundedModeLevel(&(pMe->nesting));
    uint_fast8_t  uNextNestLevel;
@@ -2673,21 +2630,21 @@
 
       /* Get the item */
       QCBORItem Item;
-      uReturn = QCBORDecode_GetNext(pMe, &Item);
-      if(QCBORDecode_IsUnrecoverableError(uReturn)) {
+      QCBORError uResult = QCBORDecode_GetNextTag(pMe, &Item);
+      if(QCBORDecode_IsUnrecoverableError(uResult)) {
          /* Got non-well-formed CBOR so map can't even be decoded. */
+         uReturn = uResult;
          goto Done;
       }
-      if(uReturn == QCBOR_ERR_NO_MORE_ITEMS) {
+      if(uResult == QCBOR_ERR_NO_MORE_ITEMS) {
          // Unexpected end of map or array.
+         uReturn = uResult;
          goto Done;
       }
 
       /* See if item has one of the labels that are of interest */
       bool bMatched = false;
       for(int nIndex = 0; pItemArray[nIndex].uLabelType != QCBOR_TYPE_NONE; nIndex++) {
-         // TODO: have label filled in on invalid CBOR so error reporting
-         // can work a lot better.
          if(MatchLabel(Item, pItemArray[nIndex])) {
             /* A label match has been found */
             if(uFoundItemBitMap & (0x01ULL << nIndex)) {
@@ -2700,6 +2657,11 @@
                goto Done;
             }
 
+            if(uResult != QCBOR_SUCCESS) {
+               uReturn = uResult;
+               goto Done;
+            }
+
             /* Successful match. Return the item. */
             pItemArray[nIndex] = Item;
             uFoundItemBitMap |= 0x01ULL << nIndex;
@@ -2741,6 +2703,14 @@
    uReturn = QCBOR_SUCCESS;
 
    const size_t uEndOffset = UsefulInputBuf_Tell(&(pMe->InBuf));
+
+   // Check here makes sure that this won't accidentally be
+   // QCBOR_MAP_OFFSET_CACHE_INVALID which is larger than
+   // QCBOR_MAX_DECODE_INPUT_SIZE.
+   if(uEndOffset >= QCBOR_MAX_DECODE_INPUT_SIZE) {
+      uReturn = QCBOR_ERR_INPUT_TOO_LARGE;
+      goto Done;
+   }
    /* Cast OK because encoded CBOR is limited to UINT32_MAX */
    pMe->uMapEndOffsetCache = (uint32_t)uEndOffset;
 
@@ -2748,10 +2718,11 @@
    DecodeNesting_RestoreFromMapSearch(&(pMe->nesting), &SaveNesting);
 
  Done2:
-   /* For all items not found, set the data type to QCBOR_TYPE_NONE */
+   /* For all items not found, set the data and label type to QCBOR_TYPE_NONE */
    for(int i = 0; pItemArray[i].uLabelType != 0; i++) {
       if(!(uFoundItemBitMap & (0x01ULL << i))) {
-         pItemArray[i].uDataType = QCBOR_TYPE_NONE;
+         pItemArray[i].uDataType  = QCBOR_TYPE_NONE;
+         pItemArray[i].uLabelType = QCBOR_TYPE_NONE;
       }
    }
 
@@ -2778,16 +2749,16 @@
    OneItemSeach[1].uLabelType  = QCBOR_TYPE_NONE; // Indicates end of array
 
    QCBORError uReturn = MapSearch(pMe, OneItemSeach, NULL, NULL, NULL);
+
+   *pItem = OneItemSeach[0];
+
    if(uReturn != QCBOR_SUCCESS) {
       goto Done;
    }
    if(OneItemSeach[0].uDataType == QCBOR_TYPE_NONE) {
       uReturn = QCBOR_ERR_LABEL_NOT_FOUND;
-      goto Done;
    }
 
-   *pItem = OneItemSeach[0];
-
  Done:
    pMe->uLastError = (uint8_t)uReturn;
 }
@@ -2828,7 +2799,8 @@
 
 
 
-static QCBORError CheckTypeList(int uDataType, const uint8_t puTypeList[QCBOR_TAGSPEC_NUM_TYPES])
+static QCBORError
+CheckTypeList(int uDataType, const uint8_t puTypeList[QCBOR_TAGSPEC_NUM_TYPES])
 {
    for(size_t i = 0; i < QCBOR_TAGSPEC_NUM_TYPES; i++) {
       if(uDataType == puTypeList[i]) {
@@ -2848,7 +2820,8 @@
 
  The data type must be one of the QCBOR_TYPEs, not the IETF CBOR Registered tag value.
  */
-static QCBORError CheckTagRequirement(const TagSpecification TagSpec, const QCBORItem *pItem)
+static QCBORError
+CheckTagRequirement(const TagSpecification TagSpec, const QCBORItem *pItem)
 {
    if(!(TagSpec.uTagRequirement & QCBOR_TAG_REQUIREMENT_ALLOW_ADDITIONAL_TAGS) &&
       pItem->uTags[0] != CBOR_TAG_INVALID16) {
@@ -3090,7 +3063,7 @@
       goto Done;
    }
 
-    CopyTags(pMe, &Item);
+   CopyTags(pMe, &Item);
 
 
    const bool bIsEmpty = (Item.uNextNestLevel <= Item.uNestingLevel);
@@ -3100,11 +3073,12 @@
          // the decrement when exiting the map/array works correctly
          pMe->nesting.pCurrent->u.ma.uCountCursor++;
       }
-      // Special case to increment nesting level for zero-length maps and arrays entered in bounded mode.
+      // Special case to increment nesting level for zero-length maps
+      // and arrays entered in bounded mode.
       DecodeNesting_Descend(&(pMe->nesting), uType);
    }
 
-   pMe->uMapEndOffsetCache = MAP_OFFSET_CACHE_INVALID;
+   pMe->uMapEndOffsetCache = QCBOR_MAP_OFFSET_CACHE_INVALID;
 
    uErr = DecodeNesting_EnterBoundedMapOrArray(&(pMe->nesting), bIsEmpty,
                                                UsefulInputBuf_Tell(&(pMe->InBuf)));
@@ -3115,8 +3089,8 @@
 
 
 /*
- This is the common work for exiting a level that is a bounded map, array or bstr
- wrapped CBOR.
+ This is the common work for exiting a level that is a bounded map,
+ array or bstr wrapped CBOR.
 
  One chunk of work is to set up the pre-order traversal so it is at
  the item just after the bounded map, array or bstr that is being
@@ -3163,10 +3137,9 @@
     */
    DecodeNesting_LevelUpBounded(&(pMe->nesting));
 
-   pMe->uMapEndOffsetCache = MAP_OFFSET_CACHE_INVALID;
+   pMe->uMapEndOffsetCache = QCBOR_MAP_OFFSET_CACHE_INVALID;
 
 Done:
-   DecodeNesting_Print(&(pMe->nesting), &(pMe->InBuf),  "ExitBoundedLevel");
    return uErr;
 }
 
@@ -3191,7 +3164,7 @@
     that is being exited. If there is no cached value,
     from previous map search, then do a dummy search.
     */
-   if(pMe->uMapEndOffsetCache == MAP_OFFSET_CACHE_INVALID) {
+   if(pMe->uMapEndOffsetCache == QCBOR_MAP_OFFSET_CACHE_INVALID) {
       QCBORItem Dummy;
       Dummy.uLabelType = QCBOR_TYPE_NONE;
       uErr = MapSearch(pMe, &Dummy, NULL, NULL, NULL);
@@ -3242,9 +3215,9 @@
    }
 
    if(DecodeNesting_IsCurrentDefiniteLength(&(pMe->nesting))) {
-      /* Reverse the decrement done by GetNext() for the bstr as
-       so the increment in NestLevelAscender called by ExitBoundedLevel()
-       will work right. */
+      // Reverse the decrement done by GetNext() for the bstr so the
+      // increment in NestLevelAscender() called by ExitBoundedLevel()
+      // will work right.
       DecodeNesting_ReverseDecrement(&(pMe->nesting));
    }
 
@@ -3252,27 +3225,34 @@
       *pBstr = pItem->val.string;
    }
 
-   const size_t uPreviousLength = UsefulInputBuf_GetLength(&(pMe->InBuf));
-
-   // Need to move UIB input cursor to the right place
+   // This saves the current length of the UsefulInputBuf and then
+   // narrows the UsefulInputBuf to start and length of the wrapped
+   // CBOR that is being entered.
+   //
+   // This makes sure the length is less than
+   // QCBOR_MAX_DECODE_INPUT_SIZE which is slighly less than
+   // UINT32_MAX. The value UINT32_MAX is used as a special indicator
+   // value. The checks against QCBOR_MAX_DECODE_INPUT_SIZE also make
+   // the casts safe.  uEndOfBstr will always be less than
+   // uPreviousLength because of the way UsefulInputBuf works so there
+   // is no need to check it.  There is also a range check in the
+   // seek.
+   //
    // Most of these calls are simple inline accessors so this doesn't
-   // amount to much code. There is a range check in the seek.
-   const size_t uEndOfBstr = UsefulInputBuf_Tell(&(pMe->InBuf));
-   if(uEndOfBstr >= UINT32_MAX || uPreviousLength >= UINT32_MAX) {
-      // TODO: test this error condition
+   // amount to much code.
+   const size_t uPreviousLength = UsefulInputBuf_GetBufferLength(&(pMe->InBuf));
+   if(uPreviousLength >= QCBOR_MAX_DECODE_INPUT_SIZE) {
       uError = QCBOR_ERR_INPUT_TOO_LARGE;
       goto Done;
    }
+   const size_t uEndOfBstr = UsefulInputBuf_Tell(&(pMe->InBuf));
    UsefulInputBuf_Seek(&(pMe->InBuf), uEndOfBstr - pItem->val.string.len);
-   UsefulInputBuf_SetBufferLen(&(pMe->InBuf), uEndOfBstr);
+   UsefulInputBuf_SetBufferLength(&(pMe->InBuf), uEndOfBstr);
 
-   // Casts are OK because of the checks above.
    uError = DecodeNesting_DescendIntoBstrWrapped(&(pMe->nesting),
-                                                   (uint32_t)uPreviousLength,
-                                                   (uint32_t)uEndOfBstr);
+                                                 (uint32_t)uPreviousLength,
+                                                 (uint32_t)uEndOfBstr);
 Done:
-   DecodeNesting_Print(&(pMe->nesting), &(pMe->InBuf),  "Entered Bstr");
-
    return uError;
 }
 
@@ -3314,7 +3294,10 @@
    QCBORItem Item;
    QCBORDecode_GetItemInMapN(pMe, nLabel, QCBOR_TYPE_ANY, &Item);
 
-   pMe->uLastError = (uint8_t)InternalEnterBstrWrapped(pMe, &Item, uTagRequirement, pBstr);
+   pMe->uLastError = (uint8_t)InternalEnterBstrWrapped(pMe,
+                                                       &Item,
+                                                       uTagRequirement,
+                                                       pBstr);
 }
 
 
@@ -3329,7 +3312,10 @@
    QCBORItem Item;
    QCBORDecode_GetItemInMapSZ(pMe, szLabel, QCBOR_TYPE_ANY, &Item);
 
-   pMe->uLastError = (uint8_t)InternalEnterBstrWrapped(pMe, &Item, uTagRequirement, pBstr);
+   pMe->uLastError = (uint8_t)InternalEnterBstrWrapped(pMe,
+                                                       &Item,
+                                                       uTagRequirement,
+                                                       pBstr);
 }
 
 
@@ -3352,7 +3338,7 @@
     Reset the length of the UsefulInputBuf to what it was before
     the bstr wrapped CBOR was entered.
     */
-   UsefulInputBuf_SetBufferLen(&(pMe->InBuf),
+   UsefulInputBuf_SetBufferLength(&(pMe->InBuf),
                                DecodeNesting_GetPreviousBoundedEnd(&(pMe->nesting)));
 
 
@@ -3367,7 +3353,8 @@
 
 
 
-static QCBORError InterpretBool(QCBORDecodeContext *pMe, const QCBORItem *pItem, bool *pBool)
+static QCBORError
+InterpretBool(QCBORDecodeContext *pMe, const QCBORItem *pItem, bool *pBool)
 {
    switch(pItem->uDataType) {
       case QCBOR_TYPE_TRUE:
@@ -3436,76 +3423,6 @@
 
 
 
-/*
- A number of methods decode CBOR that is associated with a
- specific tag or tags.
-
- The API of the method returns the
- data in a way specific to the
-
- No tags at all.
-
-
- Require tag for the particular type for the method and no other.
-
-
- Either no tags at all or the particular type for the method and no other.
-
- No tag for particular type; pass other tags along.
-
- Require the tag for the particular type; pass other tags along
-
- Any tagging is OK; consume the tag for the particular type if present,
- pass other tags along.
-
-
- 1) REQUIRED
-- 1 XXXX -- works
-- T 1 XXX -- works, T is returned
-
- if(tag is of interest) {
-   process content
-   return T if present
- }
-
-
- 2) FORBIDDEN
- - XXX -- works
- - T XXX -- ???
-
- if(tag is of interest) {
-    error out since tag is forbidden
- } else {
-    process contents
-    return T
- }
-
- 3) OPTIONAL
- - XXX works
- - 1 XXX works
- - T XXX
- - T 1 XXX  works, T is returned
-
-if (inner tag is of interest) {
-   process content
-   return tag T if present
- } else if (there is no tag) {
-   process content
- } else {
-   process content if possible
-   return T
- }
-
-A field is type X
- - tag for type X is REQUIRED
- - tag for type X is FORBIDDEN
- - tag for type X is optional
- - Other tags are FORBIDDEN
- - Other tags are ALLOWED
-
-
-
- */
 
 static void ProcessEpochDate(QCBORDecodeContext *pMe,
                              QCBORItem           *pItem,
@@ -3721,7 +3638,7 @@
 QCBORError QCBORDecode_GetMIMEInternal(uint8_t     uTagRequirement,
                                        const       QCBORItem *pItem,
                                        UsefulBufC *pMessage,
-                                       bool       *pbIsNot7Bit)
+                                       bool       *pbIsTag257)
 {
    const TagSpecification TagSpecText =
       {
@@ -3740,14 +3657,14 @@
 
    if(CheckTagRequirement(TagSpecText, pItem) == QCBOR_SUCCESS) {
       *pMessage = pItem->val.string;
-      if(pbIsNot7Bit != NULL) {
-         *pbIsNot7Bit = false;
+      if(pbIsTag257 != NULL) {
+         *pbIsTag257 = false;
       }
       uReturn = QCBOR_SUCCESS;
    } else if(CheckTagRequirement(TagSpecBinary, pItem) == QCBOR_SUCCESS) {
       *pMessage = pItem->val.string;
-      if(pbIsNot7Bit != NULL) {
-         *pbIsNot7Bit = true;
+      if(pbIsTag257 != NULL) {
+         *pbIsTag257 = true;
       }
       uReturn = QCBOR_SUCCESS;
 
@@ -3758,7 +3675,8 @@
    return uReturn;
 }
 
-// Improvement: add methods for wrapped CBOR, a simple alternate to EnterBstrWrapped
+// Improvement: add methods for wrapped CBOR, a simple alternate
+// to EnterBstrWrapped
 
 
 
@@ -3769,7 +3687,8 @@
 
 
 // The exponentiator that works on only positive numbers
-static QCBORError Exponentitate10(uint64_t uMantissa, int64_t nExponent, uint64_t *puResult)
+static QCBORError
+Exponentitate10(uint64_t uMantissa, int64_t nExponent, uint64_t *puResult)
 {
    uint64_t uResult = uMantissa;
 
@@ -3801,7 +3720,8 @@
 
 
 // The exponentiator that works on only positive numbers
-static QCBORError Exponentitate2(uint64_t uMantissa, int64_t nExponent, uint64_t *puResult)
+static QCBORError
+Exponentitate2(uint64_t uMantissa, int64_t nExponent, uint64_t *puResult)
 {
    uint64_t uResult;
 
@@ -3834,7 +3754,8 @@
 
 
 /*
- Compute value with signed mantissa and signed result. Works with exponent of 2 or 10 based on exponentiator.
+ Compute value with signed mantissa and signed result. Works with
+ exponent of 2 or 10 based on exponentiator.
  */
 static inline QCBORError ExponentiateNN(int64_t       nMantissa,
                                         int64_t       nExponent,
@@ -3876,7 +3797,8 @@
 
 
 /*
- Compute value with signed mantissa and unsigned result. Works with exponent of 2 or 10 based on exponentiator.
+ Compute value with signed mantissa and unsigned result. Works with
+ exponent of 2 or 10 based on exponentiator.
  */
 static inline QCBORError ExponentitateNU(int64_t       nMantissa,
                                          int64_t       nExponent,
@@ -3895,7 +3817,8 @@
 
 
 /*
- Compute value with signed mantissa and unsigned result. Works with exponent of 2 or 10 based on exponentiator.
+ Compute value with signed mantissa and unsigned result. Works with
+ exponent of 2 or 10 based on exponentiator.
  */
 static inline QCBORError ExponentitateUU(uint64_t       uMantissa,
                                          int64_t        nExponent,
@@ -3987,14 +3910,16 @@
 
 \param[in] uConvertTypes  Bit mask list of conversion options.
 
-\retval QCBOR_ERR_UNEXPECTED_TYPE  Conversion, possible, but not requested in uConvertTypes.
+\retval QCBOR_ERR_UNEXPECTED_TYPE  Conversion, possible, but not requested
+                                   in uConvertTypes.
 
 \retval QCBOR_ERR_UNEXPECTED_TYPE  Of a type that can't be converted
 
-\retval QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW Conversion result is too large or too small.
-
+\retval QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW  Conversion result is too large
+                                              or too small.
 */
-static QCBORError ConvertInt64(const QCBORItem *pItem, uint32_t uConvertTypes, int64_t *pnValue)
+static QCBORError
+ConvertInt64(const QCBORItem *pItem, uint32_t uConvertTypes, int64_t *pnValue)
 {
    switch(pItem->uDataType) {
       case QCBOR_TYPE_FLOAT:
@@ -4112,14 +4037,16 @@
 
  \param[in] uConvertTypes  Bit mask list of conversion options.
 
- \retval QCBOR_ERR_UNEXPECTED_TYPE  Conversion, possible, but not requested in uConvertTypes.
+ \retval QCBOR_ERR_UNEXPECTED_TYPE  Conversion, possible, but not requested
+                                    in uConvertTypes.
 
  \retval QCBOR_ERR_UNEXPECTED_TYPE  Of a type that can't be converted
 
- \retval QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW Conversion result is too large or too small.
-
+ \retval QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW  Conversion result is too large
+                                               or too small.
  */
-static QCBORError Int64ConvertAll(const QCBORItem *pItem, uint32_t uConvertTypes, int64_t *pnValue)
+static QCBORError
+Int64ConvertAll(const QCBORItem *pItem, uint32_t uConvertTypes, int64_t *pnValue)
 {
    switch(pItem->uDataType) {
 
@@ -4270,7 +4197,11 @@
 {
    QCBORItem Item;
 
-   QCBORDecode_GetInt64ConvertInternalInMapN(pMe, nLabel, uConvertTypes, pnValue, &Item);
+   QCBORDecode_GetInt64ConvertInternalInMapN(pMe,
+                                             nLabel,
+                                             uConvertTypes,
+                                             pnValue,
+                                             &Item);
 
    if(pMe->uLastError == QCBOR_SUCCESS) {
       // The above conversion succeeded
@@ -4295,7 +4226,11 @@
                                            int64_t            *pnValue)
 {
    QCBORItem Item;
-   QCBORDecode_GetInt64ConvertInternalInMapSZ(pMe, szLabel, uConvertTypes, pnValue, &Item);
+   QCBORDecode_GetInt64ConvertInternalInMapSZ(pMe,
+                                              szLabel,
+                                              uConvertTypes,
+                                              pnValue,
+                                              &Item);
 
    if(pMe->uLastError == QCBOR_SUCCESS) {
       // The above conversion succeeded
@@ -4311,7 +4246,7 @@
 }
 
 
-static QCBORError ConvertUint64(const QCBORItem *pItem, uint32_t uConvertTypes, uint64_t *puValue)
+static QCBORError ConvertUInt64(const QCBORItem *pItem, uint32_t uConvertTypes, uint64_t *puValue)
 {
    switch(pItem->uDataType) {
       case QCBOR_TYPE_DOUBLE:
@@ -4416,7 +4351,7 @@
       *pItem = Item;
    }
 
-   pMe->uLastError = (uint8_t)ConvertUint64(&Item, uConvertTypes, puValue);
+   pMe->uLastError = (uint8_t)ConvertUInt64(&Item, uConvertTypes, puValue);
 }
 
 
@@ -4431,7 +4366,7 @@
       return;
    }
 
-   pMe->uLastError = (uint8_t)ConvertUint64(pItem, uConvertTypes, puValue);
+   pMe->uLastError = (uint8_t)ConvertUInt64(pItem, uConvertTypes, puValue);
 }
 
 
@@ -4450,14 +4385,15 @@
       return;
    }
 
-   pMe->uLastError = (uint8_t)ConvertUint64(pItem, uConvertTypes, puValue);
+   pMe->uLastError = (uint8_t)ConvertUInt64(pItem, uConvertTypes, puValue);
 }
 
 
 /*
  Public function, see header qcbor/qcbor_decode.h file
 */
-static QCBORError Uint64ConvertAll(const QCBORItem *pItem, uint32_t uConvertTypes, uint64_t *puValue)
+static QCBORError
+UInt64ConvertAll(const QCBORItem *pItem, uint32_t uConvertTypes, uint64_t *puValue)
 {
    switch(pItem->uDataType) {
 
@@ -4576,7 +4512,7 @@
       return;
    }
 
-   pMe->uLastError = (uint8_t)Uint64ConvertAll(&Item, uConvertTypes, puValue);
+   pMe->uLastError = (uint8_t)UInt64ConvertAll(&Item, uConvertTypes, puValue);
 }
 
 
@@ -4590,7 +4526,11 @@
 {
    QCBORItem Item;
 
-   QCBORDecode_GetUInt64ConvertInternalInMapN(pMe, nLabel, uConvertTypes, puValue, &Item);
+   QCBORDecode_GetUInt64ConvertInternalInMapN(pMe,
+                                              nLabel,
+                                              uConvertTypes,
+                                              puValue,
+                                              &Item);
 
    if(pMe->uLastError == QCBOR_SUCCESS) {
       // The above conversion succeeded
@@ -4602,7 +4542,7 @@
       return;
    }
 
-   pMe->uLastError = (uint8_t)Uint64ConvertAll(&Item, uConvertTypes, puValue);
+   pMe->uLastError = (uint8_t)UInt64ConvertAll(&Item, uConvertTypes, puValue);
 }
 
 
@@ -4615,7 +4555,11 @@
                                             uint64_t           *puValue)
 {
    QCBORItem Item;
-   QCBORDecode_GetUInt64ConvertInternalInMapSZ(pMe, szLabel, uConvertTypes, puValue, &Item);
+   QCBORDecode_GetUInt64ConvertInternalInMapSZ(pMe,
+                                               szLabel,
+                                               uConvertTypes,
+                                               puValue,
+                                               &Item);
 
    if(pMe->uLastError == QCBOR_SUCCESS) {
       // The above conversion succeeded
@@ -4627,7 +4571,7 @@
       return;
    }
 
-   pMe->uLastError = (uint8_t)Uint64ConvertAll(&Item, uConvertTypes, puValue);
+   pMe->uLastError = (uint8_t)UInt64ConvertAll(&Item, uConvertTypes, puValue);
 }
 
 
@@ -4776,7 +4720,8 @@
 #endif /* QCBOR_DISABLE_FLOAT_HW_USE */
 
 
-static QCBORError DoubleConvertAll(const QCBORItem *pItem, uint32_t uConvertTypes, double *pdValue)
+static QCBORError
+DoubleConvertAll(const QCBORItem *pItem, uint32_t uConvertTypes, double *pdValue)
 {
 #ifndef QCBOR_DISABLE_FLOAT_HW_USE
    /*
@@ -5219,7 +5164,13 @@
       {QCBOR_TYPE_ARRAY, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
    };
 
-   ProcessMantissaAndExponentBig(pMe, TagSpec, &Item, MantissaBuffer, pMantissa, pbMantissaIsNegative, pnExponent);
+   ProcessMantissaAndExponentBig(pMe,
+                                 TagSpec,
+                                 &Item,
+                                 MantissaBuffer,
+                                 pMantissa,
+                                 pbMantissaIsNegative,
+                                 pnExponent);
 }
 
 
@@ -5251,7 +5202,13 @@
       {QCBOR_TYPE_ARRAY, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
    };
 
-   ProcessMantissaAndExponentBig(pMe, TagSpec, &Item, BufferForMantissa, pMantissa, pbIsNegative, pnExponent);
+   ProcessMantissaAndExponentBig(pMe,
+                                 TagSpec,
+                                 &Item,
+                                 BufferForMantissa,
+                                 pMantissa,
+                                 pbIsNegative,
+                                 pnExponent);
 }
 
 
@@ -5436,7 +5393,13 @@
       {QCBOR_TYPE_ARRAY, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
    };
 
-   ProcessMantissaAndExponentBig(pMe, TagSpec, &Item, BufferForMantissa, pMantissa, pbIsNegative, pnExponent);
+   ProcessMantissaAndExponentBig(pMe,
+                                 TagSpec,
+                                 &Item,
+                                 BufferForMantissa,
+                                 pMantissa,
+                                 pbIsNegative,
+                                 pnExponent);
 }
 
 
@@ -5468,7 +5431,13 @@
       {QCBOR_TYPE_ARRAY, QCBOR_TYPE_NONE, QCBOR_TYPE_NONE}
    };
 
-   ProcessMantissaAndExponentBig(pMe, TagSpec, &Item, BufferForMantissa, pMantissa, pbIsNegative, pnExponent);
+   ProcessMantissaAndExponentBig(pMe,
+                                 TagSpec,
+                                 &Item,
+                                 BufferForMantissa,
+                                 pMantissa,
+                                 pbIsNegative,
+                                 pnExponent);
 }
 
 #endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
diff --git a/src/qcbor_encode.c b/src/qcbor_encode.c
index a53f775..2416662 100644
--- a/src/qcbor_encode.c
+++ b/src/qcbor_encode.c
@@ -633,6 +633,10 @@
  one of the inline wrappers will usually be called rather than this.
 
  See qcbor/qcbor_encode.h
+
+ Improvement: create another version of this that only
+ takes a big number mantissa and converts the output to
+ a type 0 or 1 integer when mantissa is small enough.
  */
 void QCBOREncode_AddExponentAndMantissa(QCBOREncodeContext *pMe,
                                         uint64_t            uTag,
@@ -648,7 +652,9 @@
     base-2 for big floats and base-10 for decimal fractions, but that
     has no effect on the code here.
     */
-   QCBOREncode_AddTag(pMe, uTag);
+   if(uTag != CBOR_TAG_INVALID64) {
+      QCBOREncode_AddTag(pMe, uTag);
+   }
    QCBOREncode_OpenArray(pMe);
    QCBOREncode_AddInt64(pMe, nExponent);
    if(!UsefulBuf_IsNULLC(BigNumMantissa)) {
diff --git a/test/qcbor_decode_tests.c b/test/qcbor_decode_tests.c
index 26ed048..17b9c0f 100644
--- a/test/qcbor_decode_tests.c
+++ b/test/qcbor_decode_tests.c
@@ -63,8 +63,6 @@
 #endif
 
 
-// TODO: error handling for well-formed CBOR that is invalid or hits an implementation limit
-
 static const uint8_t spExpectedEncodedInts[] = {
    0x98, 0x2f, 0x3b, 0x7f, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x3b, 0x00, 0x00, 0x00, 0x01,
@@ -1774,7 +1772,7 @@
    // Definite length array containing an unclosed indefinite length array
    { {(uint8_t[]){0x81, 0x9f}, 2}, QCBOR_ERR_NO_MORE_ITEMS },
    // Deeply nested definite length arrays with deepest one unclosed
-   { {(uint8_t[]){0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81}, 9}, QCBOR_ERR_NO_MORE_ITEMS }, // TODO: 23
+   { {(uint8_t[]){0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81}, 9}, QCBOR_ERR_NO_MORE_ITEMS },
    // Deeply nested indefinite length arrays with deepest one unclosed
    { {(uint8_t[]){0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0xff, 0xff, 0xff, 0xff}, 9}, QCBOR_ERR_NO_MORE_ITEMS },
    // Mixed nesting with indefinite unclosed
@@ -2023,29 +2021,30 @@
       return -2;
    }
 
-/*
- TODO: fix this
-   This test is disabled until QCBOREncode_EncodeHead() is brought in so
- the size encoded can be tied to SIZE_MAX and work for all size CPUs.
 
- This relies on the largest string allowed being SIZE_MAX -4 rather than
- SIZE_MAX. That way the test can be performed.
-   {
-      QCBORDecodeContext DCtx;
-      QCBORItem          Item;
+   /*
+    The max size of a string for QCBOR is SIZE_MAX - 4 so this
+    tests here can be performed to see that the max length
+    error check works correctly. See DecodeBytes(). If the max
+    size was SIZE_MAX, it wouldn't be possible to test this.
 
-      static uint8_t foo[] = {0x5b, 0xff, 0xff, 0xff, 0xff,
-                                    0xff, 0xff, 0xff, 0xff};
+    This test will automatocally adapt the all CPU sizes
+    through the use of SIZE_MAX.
+   */
 
-      QCBORDecode_Init(&DCtx,
-                       UsefulBuf_FROM_BYTE_ARRAY_LITERAL(foo),
-                       QCBOR_DECODE_MODE_NORMAL);
+   MakeUsefulBufOnStack(  HeadBuf, QCBOR_HEAD_BUFFER_SIZE);
+   UsefulBufC             EncodedHead;
 
-      if(QCBOR_ERR_STRING_TOO_LONG != QCBORDecode_GetNext(&DCtx, &Item)) {
-         return -4;
-      }
+   // This makes a CBOR head with a text string that is very long
+   // but doesn't fill in the bytes of the text string as that is
+   // not needed to test this part of QCBOR.
+   EncodedHead = QCBOREncode_EncodeHead(HeadBuf, CBOR_MAJOR_TYPE_TEXT_STRING, 0, SIZE_MAX);
+
+   QCBORDecode_Init(&DCtx, EncodedHead, QCBOR_DECODE_MODE_NORMAL);
+
+   if(QCBOR_ERR_STRING_TOO_LONG != QCBORDecode_GetNext(&DCtx, &Item)) {
+      return -4;
    }
-*/
 
    return 0;
 }
@@ -2481,7 +2480,7 @@
    }
 #else /* QCBOR_DISABLE_FLOAT_HW_USE */
    uError = QCBORDecode_GetAndResetError(&DC);
-   if(uError != QCBOR_ERR_LABEL_NOT_FOUND) {
+   if(uError != QCBOR_ERR_FLOAT_DATE_DISABLED) {
       return 102;
    }
 #endif /* QCBOR_DISABLE_FLOAT_HW_USE */
@@ -2495,7 +2494,7 @@
    }
 #else /* QCBOR_DISABLE_FLOAT_HW_USE */
    uError = QCBORDecode_GetAndResetError(&DC);
-   if(uError != QCBOR_ERR_LABEL_NOT_FOUND) {
+   if(uError != QCBOR_ERR_FLOAT_DATE_DISABLED) {
       return 112;
    }
 #endif /* QCBOR_DISABLE_FLOAT_HW_USE */
@@ -4605,43 +4604,6 @@
   }
  */
 
-#include <stdio.h>
-
-static char strbuf[10];
-const char *PrintType(uint8_t type) {
-   switch(type) {
-   case QCBOR_TYPE_INT64: return "INT64";
-      case QCBOR_TYPE_UINT64: return "UINT64";
-      case QCBOR_TYPE_ARRAY: return "ARRAY";
-      case QCBOR_TYPE_MAP: return "MAP";
-      case QCBOR_TYPE_BYTE_STRING: return "BYTE_STRING";
-      case QCBOR_TYPE_TEXT_STRING: return "TEXT_STRING";
-      default:
-      sprintf(strbuf, "%d", type);
-      return strbuf;
-   }
-}
-
-
-void PrintItem(QCBORItem Item)
-{
-   printf("\nData: %s nest: %d,%d %s\n",
-          PrintType(Item.uDataType),
-          Item.uNestingLevel,
-          Item.uNextNestLevel,
-          Item.uDataAlloc ? "Allocated":"");
-   if(Item.uLabelType) {
-      printf("Label: %s ", PrintType(Item.uLabelType));
-      if(Item.uLabelType == QCBOR_TYPE_INT64) {
-         printf("%lld\n", Item.label.int64);
-      } else if(Item.uLabelType == QCBOR_TYPE_TEXT_STRING) {
-         // TODO: proper conversion to null-terminated string
-         printf("\"%4.4s\"\n", (const char *)Item.label.string.ptr);
-      }
-   }
-}
-
-
 int32_t EMap(UsefulBufC input)
 {
      QCBORItem Item1, Item2, Item3;
@@ -4778,12 +4740,62 @@
  }
  */
 
-
 static const uint8_t spMapOfEmpty[] = {
    0xa6, 0x00, 0x80, 0x09, 0x82, 0x80, 0x80, 0x08, 0xa3, 0x01,
    0x80, 0x02, 0xa0, 0x03, 0x80, 0x04, 0xa0, 0x05, 0x9f, 0xff,
    0x06, 0x9f, 0x80, 0x9f, 0xff, 0xff};
 
+/*
+ Too many tags
+ Invalid tag content
+ Duplicate label
+ Integer overflow
+ Date overflow
+
+ {1: 224(225(226(227(4(0))))),
+  2: 1(h''),
+  3: -18446744073709551616,
+  4: 1(1.0e+300),
+  5: 0, 8: 8}
+ */
+static const uint8_t spRecoverableMapErrors[] = {
+   0xbf,
+   0x01, 0xd8, 0xe0, 0xd8, 0xe1, 0xd8, 0xe2, 0xd8, 0xe3, 0xd8, 0x04, 0x00,
+   0x02, 0xc1, 0x40,
+   0x03, 0x3b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0x04, 0xc1, 0xfb, 0x7e, 0x37, 0xe4, 0x3c, 0x88, 0x00, 0x75, 0x9c,
+   0x05, 0x00,
+   0x05, 0x00,
+   0x08, 0x08,
+   0xff
+};
+
+// Bad break
+static const uint8_t spUnRecoverableMapError1[] = {
+   0xa2, 0xff, 0x01, 0x00, 0x02, 0x00
+};
+
+// No more items
+static const uint8_t spUnRecoverableMapError2[] = {
+   0xbf, 0x02, 0xbf, 0xff, 0x01, 0x00, 0x02, 0x00
+};
+
+// Hit end because string is too long
+static const uint8_t spUnRecoverableMapError3[] = {
+   0xbf, 0x02, 0x69, 0x64, 0x64, 0xff
+};
+
+// Hit end because string is too long
+static const uint8_t spUnRecoverableMapError4[] = {
+   0xbf,
+      0x02, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
+            0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff
+};
+
+
 int32_t EnterMapTest()
 {
    QCBORItem          Item1;
@@ -4964,12 +4976,88 @@
    QCBORDecode_GetInt64(&DCtx, &nDecodedInt2);
    QCBORDecode_ExitArray(&DCtx);
    uErr = QCBORDecode_Finish(&DCtx);
-   if(uErr != QCBOR_SUCCESS){
+   if(uErr != QCBOR_SUCCESS) {
       return 2014;
    }
 
-   // TODO: more testing of entered mapps and arrays with problems
-   // TODO: document error handling better (maybe improve error handling)
+   int64_t nInt;
+   QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spRecoverableMapErrors), 0);
+   QCBORDecode_EnterMap(&DCtx);
+   QCBORDecode_GetInt64InMapN(&DCtx, 0x01, &nInt);
+   uErr = QCBORDecode_GetAndResetError(&DCtx);
+   if(uErr != QCBOR_ERR_TOO_MANY_TAGS) {
+      return 2021;
+   }
+
+   QCBORDecode_GetEpochDateInMapN(&DCtx, 0x02, QCBOR_TAG_REQUIREMENT_TAG, &nInt);
+   uErr = QCBORDecode_GetAndResetError(&DCtx);
+   if(uErr != QCBOR_ERR_BAD_OPT_TAG) {
+      return 2022;
+   }
+
+   QCBORDecode_GetInt64InMapN(&DCtx, 0x03, &nInt);
+   uErr = QCBORDecode_GetAndResetError(&DCtx);
+   if(uErr != QCBOR_ERR_INT_OVERFLOW) {
+      return 2023;
+   }
+
+   QCBORDecode_GetEpochDateInMapN(&DCtx, 0x04, QCBOR_TAG_REQUIREMENT_TAG, &nInt);
+   uErr = QCBORDecode_GetAndResetError(&DCtx);
+#ifndef QCBOR_DISABLE_FLOAT_HW_USE
+   if(uErr != QCBOR_ERR_DATE_OVERFLOW) {
+      return 2024;
+   }
+#else
+   if(uErr != QCBOR_ERR_FLOAT_DATE_DISABLED) {
+      return 2027;
+   }
+#endif
+
+   QCBORDecode_GetInt64InMapN(&DCtx, 0x05, &nInt);
+   uErr = QCBORDecode_GetAndResetError(&DCtx);
+   if(uErr != QCBOR_ERR_DUPLICATE_LABEL) {
+      return 2025;
+   }
+
+   QCBORDecode_GetInt64InMapN(&DCtx, 0x08, &nInt);
+
+   QCBORDecode_ExitMap(&DCtx);
+   uErr = QCBORDecode_Finish(&DCtx);
+   if(uErr != QCBOR_SUCCESS) {
+      return 2026;
+   }
+
+   QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spUnRecoverableMapError1), 0);
+   QCBORDecode_EnterMap(&DCtx);
+   QCBORDecode_GetInt64InMapN(&DCtx, 0x01, &nInt);
+   uErr = QCBORDecode_GetAndResetError(&DCtx);
+   if(uErr != QCBOR_ERR_BAD_BREAK) {
+      return 2030;
+   }
+
+   QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spUnRecoverableMapError2), 0);
+   QCBORDecode_EnterMap(&DCtx);
+   QCBORDecode_GetInt64InMapN(&DCtx, 0x01, &nInt);
+   uErr = QCBORDecode_GetAndResetError(&DCtx);
+   if(uErr != QCBOR_ERR_NO_MORE_ITEMS) {
+      return 2031;
+   }
+
+   QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spUnRecoverableMapError3), 0);
+   QCBORDecode_EnterMap(&DCtx);
+   QCBORDecode_GetInt64InMapN(&DCtx, 0x01, &nInt);
+   uErr = QCBORDecode_GetAndResetError(&DCtx);
+   if(uErr != QCBOR_ERR_HIT_END) {
+      return 2032;
+   }
+
+   QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spUnRecoverableMapError4), 0);
+   QCBORDecode_EnterMap(&DCtx);
+   QCBORDecode_GetInt64InMapN(&DCtx, 0x01, &nInt);
+   uErr = QCBORDecode_GetAndResetError(&DCtx);
+   if(uErr != QCBOR_ERR_ARRAY_DECODE_NESTING_TOO_DEEP) {
+      return 2033;
+   }
 
    return 0;
 }
@@ -5906,16 +5994,15 @@
   array
      7
      8
-
  */
 
-static UsefulBufC foo(UsefulBuf ffo)
+static UsefulBufC EncodeBstrWrapTestData(UsefulBuf OutputBuffer)
 {
-   UsefulBufC Encoded;
+   UsefulBufC         Encoded;
    QCBOREncodeContext EC;
-   QCBORError uErr;
+   QCBORError         uErr;
 
-   QCBOREncode_Init(&EC, ffo);
+   QCBOREncode_Init(&EC, OutputBuffer);
 
    QCBOREncode_BstrWrap(&EC);
      QCBOREncode_OpenMap(&EC);
@@ -5949,34 +6036,34 @@
 
 int32_t EnterBstrTest()
 {
-   MakeUsefulBufOnStack(ffo, 100);
+   MakeUsefulBufOnStack(OutputBuffer, 100);
 
    QCBORDecodeContext DC;
 
-   QCBORDecode_Init(&DC, foo(ffo), 0);
+   QCBORDecode_Init(&DC, EncodeBstrWrapTestData(OutputBuffer), 0);
 
-   int64_t i1, i2, i3, i4, i5, i6, i7, i8;
+   int64_t n1, n2, n3, n4, n5, n6, n7, n8;
 
 
    QCBORDecode_EnterBstrWrapped(&DC, QCBOR_TAG_REQUIREMENT_NOT_A_TAG, NULL);
      QCBORDecode_EnterMap(&DC);
-       QCBORDecode_GetInt64InMapN(&DC, 100, &i1);
-       QCBORDecode_GetInt64InMapN(&DC, 200, &i2);
+       QCBORDecode_GetInt64InMapN(&DC, 100, &n1);
+       QCBORDecode_GetInt64InMapN(&DC, 200, &n2);
      QCBORDecode_ExitMap(&DC);
      QCBORDecode_EnterBstrWrapped(&DC, QCBOR_TAG_REQUIREMENT_NOT_A_TAG, NULL);
        QCBORDecode_EnterArray(&DC);
-         QCBORDecode_GetInt64(&DC, &i3);
+         QCBORDecode_GetInt64(&DC, &n3);
          QCBORDecode_EnterBstrWrapped(&DC, QCBOR_TAG_REQUIREMENT_NOT_A_TAG, NULL);
-           QCBORDecode_GetInt64(&DC, &i4);
+           QCBORDecode_GetInt64(&DC, &n4);
          QCBORDecode_ExitBstrWrapped(&DC);
-         QCBORDecode_GetInt64(&DC, &i5);
+         QCBORDecode_GetInt64(&DC, &n5);
        QCBORDecode_ExitArray(&DC);
      QCBORDecode_ExitBstrWrapped(&DC);
-     QCBORDecode_GetInt64(&DC, &i6);
+     QCBORDecode_GetInt64(&DC, &n6);
    QCBORDecode_ExitBstrWrapped(&DC);
    QCBORDecode_EnterArray(&DC);
-     QCBORDecode_GetInt64(&DC, &i7);
-     QCBORDecode_GetInt64(&DC, &i8);
+     QCBORDecode_GetInt64(&DC, &n7);
+     QCBORDecode_GetInt64(&DC, &n8);
    QCBORDecode_ExitArray(&DC);
 
    QCBORError uErr = QCBORDecode_Finish(&DC);
@@ -6258,3 +6345,105 @@
 
    return 0;
 }
+
+
+
+
+/*
+ [
+    "aaaaaaaaaa",
+    {}
+ ]
+ */
+static const uint8_t spTooLarge1[] = {
+   0x9f,
+   0x6a, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+   0xa0,
+   0xff
+};
+
+/*
+ [
+   {
+      0: "aaaaaaaaaa"
+    }
+ ]
+ */
+static const uint8_t spTooLarge2[] = {
+   0x9f,
+   0xa1,
+   0x00,
+   0x6a, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+   0xff
+};
+
+/*
+ h'A1006A61616161616161616161'
+
+ {
+    0: "aaaaaaaaaa"
+ }
+ */
+static const uint8_t spTooLarge3[] = {
+   0x4d,
+   0xa1,
+   0x00,
+   0x6a, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+};
+
+int32_t TooLargeInputTest(void)
+{
+   QCBORDecodeContext DC;
+   QCBORError         uErr;
+   UsefulBufC         String;
+
+   // These tests require a build with QCBOR_MAX_DECODE_INPUT_SIZE set
+   // to 10 There's not really any way to test this error
+   // condition. The error condition is not complex, so setting
+   // QCBOR_MAX_DECODE_INPUT_SIZE gives an OK test.
+
+   // The input CBOR is only too large because the
+   // QCBOR_MAX_DECODE_INPUT_SIZE is 10.
+   //
+   // This test is disabled for the normal test runs because of the
+   // special build requirement.
+
+
+   // Tests the start of a map being too large
+   QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spTooLarge1), QCBOR_DECODE_MODE_NORMAL);
+   QCBORDecode_EnterArray(&DC);
+   QCBORDecode_GetTextString(&DC, &String);
+   uErr = QCBORDecode_GetError(&DC);
+   if(uErr != QCBOR_SUCCESS) {
+      return 1;
+   }
+   QCBORDecode_EnterMap(&DC);
+   uErr = QCBORDecode_GetError(&DC);
+   if(uErr != QCBOR_ERR_INPUT_TOO_LARGE) {
+      return 2;
+   }
+
+   // Tests the end of a map being too large
+   QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spTooLarge2), QCBOR_DECODE_MODE_NORMAL);
+   QCBORDecode_EnterArray(&DC);
+   QCBORDecode_EnterMap(&DC);
+   uErr = QCBORDecode_GetError(&DC);
+   if(uErr != QCBOR_SUCCESS) {
+      return 3;
+   }
+   QCBORDecode_ExitMap(&DC);
+   uErr = QCBORDecode_GetError(&DC);
+   if(uErr != QCBOR_ERR_INPUT_TOO_LARGE) {
+      return 4;
+   }
+
+   // Tests the entire input CBOR being too large when processing bstr wrapping
+   QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spTooLarge3), QCBOR_DECODE_MODE_NORMAL);
+   QCBORDecode_EnterBstrWrapped(&DC, QCBOR_TAG_REQUIREMENT_NOT_A_TAG, NULL);
+   uErr = QCBORDecode_GetError(&DC);
+   if(uErr != QCBOR_ERR_INPUT_TOO_LARGE) {
+      return 5;
+   }
+
+   return 0;
+}
diff --git a/test/qcbor_decode_tests.h b/test/qcbor_decode_tests.h
index 4bf6b39..1c01ee4 100644
--- a/test/qcbor_decode_tests.h
+++ b/test/qcbor_decode_tests.h
@@ -284,4 +284,11 @@
  */
 int32_t DecodeTaggedTypeTests(void);
 
+
+/*
+ Test the detection of input that is too large. Requires
+ a special build that makes QCBOR_MAX_DECODE_INPUT_SIZE small.
+ */
+int32_t TooLargeInputTest(void);
+
 #endif /* defined(__QCBOR__qcbort_decode_tests__) */
diff --git a/test/qcbor_encode_tests.c b/test/qcbor_encode_tests.c
index c8c35c6..c573a4b 100644
--- a/test/qcbor_encode_tests.c
+++ b/test/qcbor_encode_tests.c
@@ -316,8 +316,8 @@
  0x1c, 0x59, 0x57, 0x35, 0x35, 0x49, 0x47, 0x4e, 0x68, 0x63,
  0x6d, 0x35, 0x68, 0x62, 0x43, 0x42, 0x77, 0x62, 0x47, 0x56,
  0x68, 0x63, 0x33, 0x56, 0x79, 0x5a, 0x51, 0x3d, 0x3d, 0xd8,
- 0x23, 0x67, 0x5b, 0x5e, 0x61, 0x62, 0x63, 0x5d, 0x2b, 0xd8,
- 0x24, 0x79, 0x01, 0x57, 0x4d, 0x49, 0x4d, 0x45, 0x2d, 0x56,
+ 0x23, 0x67, 0x5b, 0x5e, 0x61, 0x62, 0x63, 0x5d, 0x2b, 0xd9,
+ 0x01, 0x01, 0x59, 0x01, 0x57, 0x4d, 0x49, 0x4d, 0x45, 0x2d, 0x56,
  0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x31, 0x2e,
  0x30, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d,
  0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x6d, 0x75, 0x6c, 0x74,
@@ -376,7 +376,7 @@
  0x79, 0x5a, 0x53, 0x34, 0x3d, 0x64, 0x70, 0x6f, 0x70, 0x6f,
  0xd8, 0x23, 0x68, 0x31, 0x30, 0x30, 0x5c, 0x73, 0x2a, 0x6d,
  0x6b, 0x38, 0x32, 0xd8, 0x23, 0x66, 0x70, 0x65, 0x72, 0x6c,
- 0x5c, 0x42, 0x63, 0x4e, 0x65, 0x64, 0xd8, 0x24, 0x79, 0x01,
+ 0x5c, 0x42, 0x63, 0x4e, 0x65, 0x64, 0xd9, 0x01, 0x01, 0x59, 0x01,
  0x57, 0x4d, 0x49, 0x4d, 0x45, 0x2d, 0x56, 0x65, 0x72, 0x73,
  0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x31, 0x2e, 0x30, 0x0a, 0x43,
  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70,
@@ -411,7 +411,7 @@
  0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x65, 0x78,
  0x74, 0x0a, 0x0a, 0x2d, 0x2d, 0x58, 0x58, 0x58, 0x58, 0x62,
  0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x20, 0x74, 0x65,
- 0x78, 0x74, 0x2d, 0x2d, 0x0a, 0xd8, 0x24, 0x79, 0x01, 0x57,
+ 0x78, 0x74, 0x2d, 0x2d, 0x0a, 0xd9, 0x01, 0x01, 0x59, 0x01, 0x57,
  0x4d, 0x49, 0x4d, 0x45, 0x2d, 0x56, 0x65, 0x72, 0x73, 0x69,
  0x6f, 0x6e, 0x3a, 0x20, 0x31, 0x2e, 0x30, 0x0a, 0x43, 0x6f,
  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65,
@@ -2628,7 +2628,7 @@
 
    QCBOREncode_AddDecimalFractionToMapN(&EC, 300, 3, -1);
 
-   QCBOREncode_AddDecimalFractionBigNumToMap(&EC,
+   QCBOREncode_AddDecimalFractionBigNumToMapSZ(&EC,
                                              "decimal fraction bignum postive",
                                              BigNum,
                                              false,
@@ -2640,7 +2640,7 @@
                                               false,
                                               INT32_MAX);
 
-   QCBOREncode_AddDecimalFractionBigNumToMap(&EC,
+   QCBOREncode_AddDecimalFractionBigNumToMapSZ(&EC,
                                              "decimal fraction bignum negative",
                                              BigNum,
                                              true,
diff --git a/test/run_tests.c b/test/run_tests.c
index be180a7..a6b402e 100644
--- a/test/run_tests.c
+++ b/test/run_tests.c
@@ -108,6 +108,7 @@
     TEST_ENTRY(CoseSign1TBSTest),
     TEST_ENTRY(StringDecoderModeFailTest),
     TEST_ENTRY_DISABLED(BigComprehensiveInputTest),
+    TEST_ENTRY_DISABLED(TooLargeInputTest),
     TEST_ENTRY(EncodeErrorTests),
     TEST_ENTRY(SetUpAllocatorTest),
     TEST_ENTRY(SimpleValuesIndefiniteLengthTest1),