Merge master (what will be 1.4.2) into dev
diff --git a/LICENSE b/LICENSE
index bf7753f..6dc0157 100644
--- a/LICENSE
+++ b/LICENSE
@@ -33,4 +33,5 @@
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
index 9adfefe..fa511d2 100644
--- a/README.md
+++ b/README.md
@@ -183,7 +183,7 @@
 
 ## Code Status
 
-The official current release is version 1.3. Changes over the last few
+The official current release is version 1.4.1 Changes over the last few
 years have been only minor bug fixes, minor feature additions and
 documentation improvements. QCBOR 1.x is highly stable.
 
@@ -553,44 +553,8 @@
 * Máté Tóth-Pál for float-point disabling and other
 * Dave Thaler for portability to Windows
 
-## Copyright and License
-
-QCBOR is available under what is essentially the 3-Clause BSD License.
-
-Files created inside Qualcomm and open-sourced through CAF (The Code
-Aurora Forum) have a slightly modified 3-Clause BSD License. The
-modification additionally disclaims NON-INFRINGEMENT.
-
-Files created after release to CAF use the standard 3-Clause BSD
-License with no modification. These files have the SPDX license
-identifier, "SPDX-License-Identifier: BSD-3-Clause" in them.
-
-### BSD-3-Clause license
-
-* Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-
-* Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-
-* Neither the name of the copyright holder nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 ### Copyright for this README
 
-Copyright (c) 2018-2021, Laurence Lundblade. All rights reserved.
+Copyright (c) 2018-2024, Laurence Lundblade. All rights reserved.
 Copyright (c) 2021-2023, Arm Limited. All rights reserved.
diff --git a/cmd_line_main.c b/cmd_line_main.c
index 4df6e98..da5d071 100644
--- a/cmd_line_main.c
+++ b/cmd_line_main.c
@@ -5,7 +5,7 @@
 
  SPDX-License-Identifier: BSD-3-Clause
 
- See BSD-3-Clause license in README.md
+ See BSD-3-Clause license in file named "LICENSE"
 
  Created on 9/13/18
  =============================================================================*/
diff --git a/example.c b/example.c
index d580c78..ed5d597 100644
--- a/example.c
+++ b/example.c
@@ -6,7 +6,7 @@
 
    SPDX-License-Identifier: BSD-3-Clause
 
-   See BSD-3-Clause license in README.md
+   See BSD-3-Clause license in file named "LICENSE"
 
    Created on 6/30/2020
   ========================================================================== */
diff --git a/example.h b/example.h
index b5bcf4b..903b3f5 100644
--- a/example.h
+++ b/example.h
@@ -5,7 +5,7 @@
 
  SPDX-License-Identifier: BSD-3-Clause
 
- See BSD-3-Clause license in README.md
+ See BSD-3-Clause license in file named "LICENSE"
 
  Created on 6/30/20
  =============================================================================*/
diff --git a/inc/qcbor/UsefulBuf.h b/inc/qcbor/UsefulBuf.h
index d67dd85..819a0d5 100644
--- a/inc/qcbor/UsefulBuf.h
+++ b/inc/qcbor/UsefulBuf.h
@@ -43,9 +43,12 @@
 
  when         who             what, where, why
  --------     ----            --------------------------------------------------
- 1/7/2024     llundblade      Add UsefulInputBuf_Compare().
+ 08/14/2024   llundblade      Add UsefulOutBuf_RetrieveOutputStorage().
+ 08/13/2024   llundblade      Add UsefulInputBuf_RetrieveUndecodedInput().
+ 08/08/2024   llundblade      Add UsefulOutBuf_SubString().
  10/05/2024   llundblade      Add Xxx_OffsetToPointer.
  28/02/2024   llundblade      Rearrange UsefulOutBuf_Compare().
+ 1/7/2024     llundblade      Add UsefulInputBuf_Compare().
  19/11/2023   llundblade      Add UsefulOutBuf_GetOutput().
  19/11/2023   llundblade      Add UsefulOutBuf_Swap().
  19/11/2023   llundblade      Add UsefulOutBuf_Compare().
@@ -1410,6 +1413,36 @@
 UsefulOutBuf_OutUBufOffset(UsefulOutBuf *pUOutBuf, size_t uOffset);
 
 
+/*
+ * @brief Return a substring of the output data.
+ *
+ * @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
+ * @param[in] uStart    Offset of start of substring.
+ * @param[in] uLen      Length of substring.
+ *
+ * This is the same as UsefulOutBuf_OutUBuf(), but returns a
+ * substring. @c NULLUsefulBufC is returned if the requested substring
+ * is off the end of the output bytes or if in error state.
+ */
+UsefulBufC UsefulOutBuf_SubString(UsefulOutBuf *pUOutBuf,
+                                  const size_t  uStart,
+                                  const size_t  uLen);
+
+
+/**
+ * @brief Retrieve the storage buffer passed in to UsefulOutBuf_Init().
+ *
+ * @param[in] pUOutBuf  The encoding context.
+ *
+ * @return The output storage buffer passed to UsefulOutBuf_Init().
+ *
+ * This doesn't give any information about how much has been encoded
+ * or the error state. It just returns the exact @ref UsefulOutBuf given
+ * to UsefulOutBuf_Init().
+ */
+static UsefulBuf UsefulOutBuf_RetrieveOutputStorage(UsefulOutBuf *pUOutBuf);
+
+
 /**
  * @brief Compare bytes at offsets.
  *
@@ -1823,6 +1856,17 @@
 static void UsefulInputBuf_SetBufferLength(UsefulInputBuf *pUInBuf, size_t uNewLen);
 
 
+/** @brief  Retrieve the undecoded input buffer.
+ *
+ * @param[in] pUInBuf  Pointer to the @ref UsefulInputBuf.
+ *
+ * @return The input that was given to UsefulInputBuf_Init().
+ *
+ * A simple convenience method, should it be useful to get the original input back.
+ */
+static UsefulBufC UsefulInputBuf_RetrieveUndecodedInput(UsefulInputBuf *pUInBuf);
+
+
 /**
  * @brief Compare two ranges of bytes somewhere in the input buffer.
  *
@@ -1851,6 +1895,8 @@
                        const size_t    uLen2);
 
 
+
+
 /*----------------------------------------------------------
  Inline implementations.
  */
@@ -2353,6 +2399,12 @@
 }
 
 
+static inline UsefulBuf UsefulOutBuf_RetrieveOutputStorage(UsefulOutBuf *pMe)
+{
+   return pMe->UB;
+}
+
+
 
 
 static inline void UsefulInputBuf_Init(UsefulInputBuf *pMe, UsefulBufC UB)
@@ -2621,6 +2673,11 @@
     pMe->UB.len = uNewLen;
 }
 
+static inline UsefulBufC UsefulInputBuf_RetrieveUndecodedInput(UsefulInputBuf *pMe)
+{
+   return pMe->UB;
+}
+
 
 #ifdef __cplusplus
 }
diff --git a/inc/qcbor/qcbor_common.h b/inc/qcbor/qcbor_common.h
index e51ebc6..74e20ee 100644
--- a/inc/qcbor/qcbor_common.h
+++ b/inc/qcbor/qcbor_common.h
@@ -63,6 +63,7 @@
 #define QCBOR_VERSION_PATCH 0
 
 
+
 /**
  * This define indicates a version of QCBOR that supports spiffy
  * decode, the decode functions found in qcbor_spiffy_decode.h.
@@ -118,36 +119,36 @@
  * are types defined in RFC 8949 and some additional ones
  * in the IANA CBOR tags registry.
  */
-/** See QCBOREncode_AddDateString(). */
+/** See QCBOREncode_AddTDateString(). */
 #define CBOR_TAG_DATE_STRING    0
-/** See QCBOREncode_AddDateEpoch(). */
+/** See QCBOREncode_AddTDateEpoch(). */
 #define CBOR_TAG_DATE_EPOCH     1
-/** See QCBOREncode_AddPositiveBignum(). */
+/** See QCBOREncode_AddTPositiveBignum(). */
 #define CBOR_TAG_POS_BIGNUM     2
-/** See QCBOREncode_AddNegativeBignum(). */
+/** See QCBOREncode_AddTNegativeBignum(). */
 #define CBOR_TAG_NEG_BIGNUM     3
 /** CBOR tag for a two-element array representing a fraction with a
  *  mantissa and base-10 scaling factor. See
- *  QCBOREncode_AddDecimalFraction() and @ref expAndMantissa. */
+ *  QCBOREncode_AddTDecimalFraction() and @ref expAndMantissa. */
 #define CBOR_TAG_DECIMAL_FRACTION  4
 /** CBOR tag for a two-element array representing a fraction with a
- *  mantissa and base-2 scaling factor. See QCBOREncode_AddBigFloat()
+ *  mantissa and base-2 scaling factor. See QCBOREncode_AddTBigFloat()
  *  and @ref expAndMantissa. */
 #define CBOR_TAG_BIGFLOAT       5
 /** Not Decoded by QCBOR. Tag for COSE format encryption with no
- *  recipient identification. See [RFC 8152, COSE]
- *  (https://tools.ietf.org/html/rfc8152). No API is provided for this
- *  tag. */
+ *  recipient identification. See [RFC 9052, COSE]
+ *  (https://www.rfc-editor.org/rfc/rfc9052.html). No API is provided
+ *  for this tag. */
 #define CBOR_TAG_COSE_ENCRYPT0 16
 #define CBOR_TAG_COSE_ENCRYPTO 16
 /** Not Decoded by QCBOR. Tag for COSE format MAC'd data with no
- *  recipient identification. See [RFC 8152, COSE]
- *  (https://tools.ietf.org/html/rfc8152). No API is provided for this
+ *  recipient identification. See [RFC 9052, COSE]
+ *  (https://www.rfc-editor.org/rfc/rfc9052.html). No API is provided for this
  *  tag. */
 #define CBOR_TAG_COSE_MAC0     17
 /** Tag for COSE format single signature signing. No API is provided
- *  for this tag. See [RFC 8152, COSE]
- *  (https://tools.ietf.org/html/rfc8152). */
+ *  for this tag. See [RFC 9052, COSE]
+ *  (https://www.rfc-editor.org/rfc/rfc9052.html). */
 #define CBOR_TAG_COSE_SIGN1    18
 /** A hint that the following byte string should be encoded in
  *  Base64URL when converting to JSON or similar text-based
@@ -162,12 +163,12 @@
  *  QCBOREncode_AddBytes(). */
 #define CBOR_TAG_ENC_AS_B64    22
 /** A hint that the following byte string should be encoded in base-16
- *  format per [RFC 4648] (https://tools.ietf.org/html/rfc4648) when
- *  converting to JSON or similar text-based
- *  representations. Essentially, Base-16 encoding is the standard
- *  case- insensitive hex encoding and may be referred to as
- *  "hex". Call @c QCBOREncode_AddTag(pCtx,CBOR_TAG_ENC_AS_B16) before
- *  the call to QCBOREncode_AddBytes(). */
+ *  format per [RFC 4648]
+ *  (https://www.rfc-editor.org/rfc/rfc4648.html) when converting to
+ *  JSON or similar text-based representations. Essentially, Base-16
+ *  encoding is the standard case- insensitive hex encoding and may be
+ *  referred to as "hex". Call @c QCBOREncode_AddTag(pCtx,CBOR_TAG_ENC_AS_B16)
+ *  before the call to QCBOREncode_AddBytes(). */
 #define CBOR_TAG_ENC_AS_B16    23
 /** See QCBORDecode_EnterBstrWrapped()). */
 #define CBOR_TAG_CBOR          24
@@ -184,40 +185,40 @@
 /** See QCBOREncode_AddBinaryUUID(). */
 #define CBOR_TAG_BIN_UUID      37
 /** The data is a CBOR Web Token per [RFC 8392]
- *  (https://tools.ietf.org/html/rfc8932). No API is provided for this
+ *  (https://www.rfc-editor.org/rfc/rfc8392.html). No API is provided for this
  *  tag. */
 #define CBOR_TAG_CWT           61
-/** Tag for COSE format encryption. See [RFC 8152, COSE]
- *  (https://tools.ietf.org/html/rfc8152). No API is provided for this
+/** Tag for COSE format encryption. See [RFC 9052, COSE]
+ * (https://www.rfc-editor.org/rfc/rfc9052.html). No API is provided for this
  *  tag. */
 #define CBOR_TAG_CBOR_SEQUENCE 63
-/** Not Decoded by QCBOR. Tag for COSE format encrypt. See [RFC 8152, COSE]
- *  (https://tools.ietf.org/html/rfc8152). No API is provided for this
+/** Not Decoded by QCBOR. Tag for COSE format encrypt. See [RFC 9052, COSE]
+ * (https://www.rfc-editor.org/rfc/rfc9052.html). No API is provided for this
  *  tag. */
 #define CBOR_TAG_COSE_ENCRYPT  96
 #define CBOR_TAG_ENCRYPT       96
-/** Not Decoded by QCBOR. Tag for COSE format MAC. See [RFC 8152, COSE]
-    (https://tools.ietf.org/html/rfc8152). No API is provided for this
+/** Not Decoded by QCBOR. Tag for COSE format MAC. See [RFC 9052, COSE]
+ * (https://www.rfc-editor.org/rfc/rfc9052.html). No API is provided for this
     tag. */
 #define CBOR_TAG_COSE_MAC      97
 #define CBOR_TAG_MAC           97
-/** Not Decoded by QCBOR. Tag for COSE format signed data. See [RFC 8152, COSE]
-    (https://tools.ietf.org/html/rfc8152). No API is provided for this
+/** Not Decoded by QCBOR. Tag for COSE format signed data. See [RFC 9052, COSE]
+ * (https://www.rfc-editor.org/rfc/rfc9052.html). No API is provided for this
     tag. */
 #define CBOR_TAG_COSE_SIGN     98
 #define CBOR_TAG_SIGN          98
 /** Tag for date counted by days from Jan 1 1970 per [RFC 8943]
- *  (https://tools.ietf.org/html/rfc8943). See
+ *  (https://www.rfc-editor.org/rfc/rfc8943.html). See
  *  QCBOREncode_AddTDaysEpoch(). */
 #define CBOR_TAG_DAYS_EPOCH    100
 /** Not Decoded by QCBOR. World geographic coordinates. See ISO 6709, [RFC 5870]
- *  (https://tools.ietf.org/html/rfc5870) and WGS-84. No API is
+ *  (https://www.rfc-editor.org/rfc/rfc5870.html) and WGS-84. No API is
  *  provided for this tag. */
 #define CBOR_TAG_GEO_COORD     103
 /** Binary MIME.*/
 #define CBOR_TAG_BINARY_MIME   257
 /** Tag for date string without time or time zone per [RFC 8943]
- *  (https://tools.ietf.org/html/rfc8943). See
+ *  (https://www.rfc-editor.org/rfc/rfc8943.html). See
  *  QCBOREncode_AddTDaysString(). */
 #define CBOR_TAG_DAYS_STRING   1004
 /** The magic number, self-described CBOR. No API is provided for this
@@ -278,8 +279,9 @@
     *  different type than is currently open.  */
    QCBOR_ERR_CLOSE_MISMATCH = 5,
 
-   /** During encoding, the array or map had too many items in it.
-    *  This limit @ref QCBOR_MAX_ITEMS_IN_ARRAY, typically 65,535. */
+   /** During encoding, the array or map had too many items in it. The
+    * limits are @ref QCBOR_MAX_ITEMS_IN_ARRAY and
+    * @ref QCBOR_MAX_ITEMS_IN_MAP. */
    QCBOR_ERR_ARRAY_TOO_LONG = 6,
 
    /** During encoding, more arrays or maps were closed than
@@ -366,9 +368,9 @@
    QCBOR_ERR_ARRAY_DECODE_NESTING_TOO_DEEP = 41,
 
    /** 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. */
+    *  This limit is @ref QCBOR_MAX_ITEMS_IN_ARRAY (65,534) for
+    *  arrays and @ref QCBOR_MAX_ITEMS_IN_MAP (32,767) for maps. This
+    *  error makes no further decoding possible. */
    QCBOR_ERR_ARRAY_DECODE_TOO_LONG = 42,
 
    /** When decoding, a string's size is greater than what a size_t
@@ -598,14 +600,19 @@
 
 
 /**
- * The maximum number of items in a single array or map when encoding or
- * decoding.
+ * The maximum number of items in a single array when encoding or
+ * decoding. See also @ref QCBOR_MAX_ITEMS_IN_MAP.
  */
 #define QCBOR_MAX_ITEMS_IN_ARRAY (UINT16_MAX-1) /* -1 is because the
                                                  * value UINT16_MAX is
                                                  * used to indicate
                                                  * indefinite-length.
                                                  */
+/**
+ * The maximum number of items in a single map when encoding or
+ * decoding. See also @ref QCBOR_MAX_ITEMS_IN_ARRAY.
+ */
+#define QCBOR_MAX_ITEMS_IN_MAP  (QCBOR_MAX_ITEMS_IN_ARRAY/2)
 
 
 #ifdef __cplusplus
diff --git a/inc/qcbor/qcbor_decode.h b/inc/qcbor/qcbor_decode.h
index f2f4a4b..8b56b5d 100644
--- a/inc/qcbor/qcbor_decode.h
+++ b/inc/qcbor/qcbor_decode.h
@@ -1282,6 +1282,19 @@
 
 
 /**
+ * @brief  Retrieve the undecoded input buffer.
+ *
+ * @param[in]  pCtx  The decode context.
+ *
+ * @return The input that was given to QCBORDecode_Init().
+ *
+ * A simple convenience method, should it be useful to get the original input back.
+ */
+static UsefulBufC
+QCBORDecode_RetrieveUndecodedInput(QCBORDecodeContext *pCtx);
+
+
+/**
  * @brief Get the decoding error.
  *
  * @param[in] pCtx    The decoder context.
@@ -1713,6 +1726,12 @@
    return (uint32_t)UsefulInputBuf_Tell(&(pMe->InBuf));
 }
 
+static inline UsefulBufC
+QCBORDecode_RetrieveUndecodedInput(QCBORDecodeContext *pMe)
+{
+   return UsefulInputBuf_RetrieveUndecodedInput(&(pMe->InBuf));
+}
+
 static inline QCBORError
 QCBORDecode_GetError(QCBORDecodeContext *pMe)
 {
diff --git a/inc/qcbor/qcbor_encode.h b/inc/qcbor/qcbor_encode.h
index 96a91e1..a1a1aae 100644
--- a/inc/qcbor/qcbor_encode.h
+++ b/inc/qcbor/qcbor_encode.h
@@ -57,10 +57,11 @@
  * # QCBOR Overview
  *
  * This implements CBOR -- Concise Binary Object Representation as
- * defined in [RFC 8949] (https://tools.ietf.org/html/rfc8949). More
- * information is at http://cbor.io.  This is a near-complete implementation of
- * the specification. [RFC 8742] (https://tools.ietf.org/html/rfc8742) CBOR
- * Sequences is also supported. Limitations are listed further down.
+ * defined in [RFC 8949] (https://www.rfc-editor.org/rfc/rfc8949.html).
+ * More information is at http://cbor.io.  This is a near-complete
+ * implementation of the specification. [RFC 8742]
+ * (https://www.rfc-editor.org/rfc/rfc8742.html) CBOR Sequences is
+ * also supported. Limitations are listed further down.
  *
  * See @ref Encoding for general discussion on encoding,
  * @ref BasicDecode for general discussion on the basic decode features
@@ -222,12 +223,13 @@
  * Note that when you nest arrays or maps in a map, the nested array or
  * map has a label.
  *
- * Many CBOR-based protocols start with an array or map. This makes them
- * self-delimiting. No external length or end marker is needed to know
- * the end. It is also possible not start this way, in which case this
- * it is usually called a CBOR sequence which is described in
- * [RFC 8742] (https://tools.ietf.org/html/rfc8742). This encoder supports
- * either just by whether the first item added is an array, map or other.
+ * Many CBOR-based protocols start with an array or map. This makes
+ * them self-delimiting. No external length or end marker is needed to
+ * know the end. It is also possible not start this way, in which case
+ * this it is usually called a CBOR sequence which is described in
+ * [RFC 8742] (https://www.rfc-editor.org/rfc/rfc8742.html). This
+ * encoder supports either just by whether the first item added is an
+ * array, map or other.
  *
  * If QCBOR is compiled with QCBOR_DISABLE_ENCODE_USAGE_GUARDS defined,
  * the errors QCBOR_ERR_CLOSE_MISMATCH, QCBOR_ERR_ARRAY_TOO_LONG,
@@ -413,7 +415,7 @@
 
 
 /**
- * Initialize the encoder to prepare to encode some CBOR.
+ * Initialize the encoder.
  *
  * @param[in,out]  pCtx     The encoder context to initialize.
  * @param[in]      Storage  The buffer into which the encoded result
@@ -656,21 +658,20 @@
  * protocols. If integers can be kept between -23 and 23
  * they will be encoded in one byte including the major type.
  *
- * If you pass a smaller int, say an @c int16_t or a small value, say
- * 100, the encoding will still be CBOR's most compact that can
+ * If you pass a smaller integer, like @c int16_t or a small value,
+ * like 100, the encoding will still be CBOR's most compact that can
  * represent the value.  For example, CBOR always encodes the value 0
  * as one byte, 0x00. The representation as 0x00 includes
  * identification of the type as an integer too as the major type for
- * an integer is 0. See [RFC 8949]
- * (https://tools.ietf.org/html/rfc8949) Appendix A for more examples
- * of CBOR encoding. This compact encoding is also preferred
- * serialization CBOR as per section 34.1 in RFC 8949.
+ * an integer is 0. See [RFC 8949 Appendix A]
+ * (https://www.rfc-editor.org/rfc/rfc8949.html#section-appendix.a)
+ * for more examples of CBOR encoding. This compact encoding is
+ * preferred serialization CBOR as per [RFC 8949 section 4.1]
+ * (https://www.rfc-editor.org/rfc/rfc8949.html#section-4.1)
  *
  * There are no functions to add @c int16_t or @c int32_t because they
  * are not necessary because this always encodes to the smallest
- * number of bytes based on the value (If this code is running on a
- * 32-bit machine having a way to add 32-bit integers would reduce
- * code size some).
+ * number of bytes based on the value.
  *
  * If the encoding context is in an error state, this will do
  * nothing. If an error occurs when adding this integer, the internal
@@ -683,10 +684,10 @@
 QCBOREncode_AddInt64(QCBOREncodeContext *pCtx, int64_t nNum);
 
 static void
-QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum);
+QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t nNum);
 
 static void
-QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum);
+QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t nNum);
 
 
 /**
@@ -765,9 +766,9 @@
  * @param[in] pCtx   The encoding context to add the text to.
  * @param[in] Text   Pointer and length of text to add.
  *
- * The text passed in must be unencoded UTF-8 according to [RFC 3629]
- * (https://tools.ietf.org/html/rfc3629). There is no NULL
- * termination. The text is added as CBOR major type 3.
+ * The text passed in must be unencoded UTF-8 according to
+ * [RFC 3629] (https://www.rfc-editor.org/rfc/rfc3629.html). There is
+ * no NULL termination. The text is added as CBOR major type 3.
  *
  * If called with @c nBytesLen equal to 0, an empty string will be
  * added. When @c nBytesLen is 0, @c pBytes may be @c NULL.
@@ -832,6 +833,7 @@
  * @param[in] pCtx  The encoding context to add the double to.
  * @param[in] dNum  The double-precision number to add.
  *
+<<<<<<< HEAD
  * This encodes using preferred serialization, selectively encoding
  * the input floating-point number as either double-precision,
  * single-precision or half-precision. Infinity, NaN and 0 are always
@@ -855,6 +857,32 @@
  * can't be directly decoded into an int64_t or uint64_t. See
  * QCBORDecode_GetNumberConvertPrecisely(), a good method to use to
  * decode dCBOR.
+=======
+ * This encodes and outputs a double-precision floating-point
+ * number. CBOR major type 7 is used.
+ *
+ * This implements preferred serialization, selectively encoding the
+ * double-precision floating-point number as either double-precision,
+ * single-precision or half-precision. Infinity, NaN and zero are
+ * always encoded as half-precision. If no precision will be lost in
+ * the conversion to half-precision, then it will be converted and
+ * encoded. If not and no precision will be lost in conversion to
+ * single-precision, then it will be converted and encoded. If not,
+ * then no conversion is performed, and it encoded as a
+ * double-precision.
+ *
+ * Half-precision floating-point numbers take up two bytes, half that
+ * of single-precision, one quarter of double-precision. Preferred
+ * serialization can therefore reduce message size down to one quarter
+ * of the original if most of the values are zero, infinity or NaN.
+ *
+ * When decoded, QCBOR returns these values as double-precision even
+ * if they were encoded as single or half-precision.
+ *
+ * It is possible to disable preferred serialization when compiling
+ * QCBOR. In that case, this operates the same as
+ * QCBOREncode_AddDoubleNoPreferred().
+>>>>>>> master
  *
  * Error handling is the same as QCBOREncode_AddInt64().
  *
@@ -884,11 +912,16 @@
 /**
  * @brief Add a single-precision floating-point number to the encoded output.
  *
- * @param[in] pCtx  The encoding context to add the double to.
+ * @param[in] pCtx  The encoding context to add the single to.
  * @param[in] fNum  The single-precision number to add.
  *
  * This is identical to QCBOREncode_AddDouble() except the input is
+<<<<<<< HEAD
  * single-precision. It also supports dCBOR.
+=======
+ * single-precision. The preferred serialization output will be either
+ * single-precision or half-precision.
+>>>>>>> master
  *
  * See also QCBOREncode_AddDouble(), QCBOREncode_AddDoubleNoPreferred(),
  * and QCBOREncode_AddFloatNoPreferred() and @ref Floating-Point.
@@ -949,7 +982,7 @@
 
 static void
 QCBOREncode_AddFloatNoPreferredToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, float fNum);
-#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
+#endif /* ! USEFULBUF_DISABLE_ALL_FLOAT */
 
 
 /**
@@ -1056,7 +1089,7 @@
  *  @param[in] nDays            Number of days before or after 1970-01-0.
  *
  * This date format is described in
- * [RFC 8943] (https://tools.ietf.org/html/rfc8943).
+ * [RFC 8943] (https://www.rfc-editor.org/rfc/rfc8943.html).
  *
  * The preferred integer serialization rules apply here so the date
  * will be encoded in a minimal number of bytes. Until about the year
@@ -1180,7 +1213,8 @@
  * @param[in] Bytes            Pointer and length of the binary UUID.
  *
  * A binary UUID as defined in [RFC 4122]
- * (https://tools.ietf.org/html/rfc4122) is added to the output.
+ * (https://www.rfc-editor.org/rfc/rfc4122.html) is added to the
+ * output.
  *
  * 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.
@@ -1216,10 +1250,10 @@
 /**
  * @brief Add a positive big number using preferred serialization.
  *
- * @param[in] pCtx             The encoding context to add the big number to.
+ * @param[in] pCtx             The encoding context.
  * @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or
  *                             @ref QCBOR_ENCODE_AS_BORROWED.
- * @param[in] BigNumber            Pointer and length of the big number.
+ * @param[in] BigNumber        Pointer and length of the big number.
  *
  * @c BigNumber makes up an aribtrary precision integer in
  * network/big-endian byte order.  The first byte is the most
@@ -1228,7 +1262,8 @@
  * If the value in @c BigNumber is greater than @c UINT64_MAX, this
  * will be encoded as the CBOR tag @ref CBOR_TAG_POS_BIGNUM. If less
  * then, it will be output as a type 0 integer. This is as required
- * for preferred serialization described in RFC 8949 section 3.4.3.
+ * for preferred serialization described in [RFC 8949 section 3.4.3]
+ * (https://www.rfc-editor.org/rfc/rfc8949.html#section-3.4.3).
  *
  * See also QCBOREncode_AddTPositiveBignumNoPreferred().
  *
@@ -1291,7 +1326,7 @@
 /**
  * @brief Add a positive big number without preferred serialization.
  *
- * @param[in] pCtx             The encoding context to add the big number to.
+ * @param[in] pCtx             The encoding context.
  * @param[in] uTagRequirement  Either @ref QCBOR_ENCODE_AS_TAG or
  *                             @ref QCBOR_ENCODE_AS_BORROWED.
  * @param[in] BigNumber            Pointer and length of the big number.
@@ -1325,7 +1360,7 @@
  * @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] BigNum            Pointer and length of the big number.
+ * @param[in] BigNumber        Pointer and length of the big number.
  *
  * This outputs @c BigNum as a type 1 if the value is greater than or
  * equal to -(2^64), and as tag 3 if less than. This is as required
@@ -1348,19 +1383,19 @@
 void
 QCBOREncode_AddTNegativeBignum(QCBOREncodeContext *pCtx,
                                uint8_t             uTagRequirement,
-                               UsefulBufC          BigNum);
+                               UsefulBufC          BigNumber);
 
 static void
 QCBOREncode_AddTNegativeBignumToMapSZ(QCBOREncodeContext *pCtx,
                                       const char         *szLabel,
                                       uint8_t             uTagRequirement,
-                                      UsefulBufC          Bytes);
+                                      UsefulBufC          BigNumber);
 
 static void
 QCBOREncode_AddTNegativeBignumToMapN(QCBOREncodeContext *pCtx,
                                      int64_t             nLabel,
                                      uint8_t             uTagRequirement,
-                                     UsefulBufC          Bytes);
+                                     UsefulBufC          BigNumber);
 
 
 /**
@@ -1427,6 +1462,7 @@
                                                 UsefulBufC          BigNumber);
 
 
+
 #ifndef QCBOR_DISABLE_EXP_AND_MANTISSA
 /**
  * @brief Add a decimal fraction to the encoded output.
@@ -1702,7 +1738,7 @@
                                     UsefulBufC          Mantissa,
                                     bool                bIsNegative,
                                     int64_t             nBase2Exponent);
-#endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
+#endif /* ! QCBOR_DISABLE_EXP_AND_MANTISSA */
 
 
 /**
@@ -1714,7 +1750,7 @@
  * @param[in] URI              Pointer and length of the URI.
  *
  * The format of URI must be per [RFC 3986]
- * (https://tools.ietf.org/html/rfc3986).
+ * (https://www.rfc-editor.org/rfc/rfc3986.html).
  *
  * It is output as CBOR major type 3, a text string, with tag @ref
  * CBOR_TAG_URI indicating the text string is a URI.
@@ -1766,7 +1802,7 @@
  * @param[in] B64Text          Pointer and length of the base-64 encoded text.
  *
  * The text content is Base64 encoded data per [RFC 4648]
- * (https://tools.ietf.org/html/rfc4648).
+ * (https://www.rfc-editor.org/rfc/rfc4648.html).
  *
  * It is output as CBOR major type 3, a text string, with tag @ref
  * CBOR_TAG_B64 indicating the text string is Base64 encoded.
@@ -1774,7 +1810,7 @@
 static void
 QCBOREncode_AddTB64Text(QCBOREncodeContext *pCtx,
                         uint8_t             uTagRequirement,
-                                    UsefulBufC          B64Text);
+                        UsefulBufC          B64Text);
 
 static void
 QCBOREncode_AddTB64TextToMapSZ(QCBOREncodeContext *pCtx,
@@ -1813,8 +1849,8 @@
  *                             @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]
- * (https://tools.ietf.org/html/rfc4648).
+ * The text content is base64URL encoded text as per
+ * [RFC 4648] (https://www.rfc-editor.org/rfc/rfc4648.html).
  *
  * It is output as CBOR major type 3, a text string, with tag
  * @ref CBOR_TAG_B64URL indicating the text string is a Base64url
@@ -1909,7 +1945,7 @@
  * @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.
+ * (https://www.rfc-editor.org/rfc/rfc2045.html) including the headers.
  *
  * 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
@@ -1969,11 +2005,11 @@
  *                             @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]
- * (https://tools.ietf.org/html/rfc3339) as defined by section 3.3 in
- * [RFC 4287] (https://tools.ietf.org/html/rfc4287). This is as
- * described in section 3.4.1 in [RFC 8949]
- * (https://tools.ietf.org/html/rfc8949).
+ * The string szDate should be in the form of
+ * [RFC 3339] (https://www.rfc-editor.org/rfc/rfc3339.html) as defined
+ * by section 3.3 in [RFC 4287] (https://www.rfc-editor.org/rfc/rfc4287.html).
+ * This is as described in section 3.4.1 in [RFC 8949]
+ * (https://www.rfc-editor.org/rfc/rfc8949.html#section3.1.4).
  *
  * Note that this function doesn't validate the format of the date
  * string at all. If you add an incorrect format date string, the
@@ -2026,10 +2062,10 @@
  * @param[in] szDate           Null-terminated string with date to add.
  *
  * This date format is described in
- * [RFC 8943] (https://tools.ietf.org/html/rfc8943), but that mainly
+ * [RFC 8943] (https://www.rfc-editor.org/rfc/rfc8943.html), but that mainly
  * references RFC 3339.  The string szDate must be in the forrm
  * specified the ABNF for a full-date in
- * [RFC 3339] (https://tools.ietf.org/html/rfc3339). Examples of this
+ * [RFC 3339] (https://www.rfc-editor.org/rfc/rfc3339.html). Examples of this
  * are "1985-04-12" and "1937-01-01".  The time and the time zone are
  * never included.
  *
@@ -2111,7 +2147,7 @@
  *
  * Note that this value will not translate to JSON.
  *
- * This Undef doesn't have any special meaning in CBOR such as a
+ * "undef" doesn't have any special meaning in CBOR such as a
  * terminating value for a string or an empty value.
  *
  * Error handling is the same as QCBOREncode_AddInt64().
@@ -2256,8 +2292,8 @@
  * text strings, then just call the QCBOREncode_AddXxx() function
  * explicitly to add the label. Then call it again to add the value.
  *
- * See the [RFC 8949] (https://tools.ietf.org/html/rfc8949) for a lot
- * more information on creating maps.
+ * See the [RFC 8949] (https://www.rfc-editor.org/rfc/rfc8949.html)
+ * for a lot more information on creating maps.
  */
 static void
 QCBOREncode_OpenMap(QCBOREncodeContext *pCtx);
@@ -2399,11 +2435,11 @@
  * contain encoded CBOR. This increases nesting level by one.
  *
  * The typical use case is for encoded CBOR that is to be
- * cryptographically hashed, as part of a [RFC 8152, COSE]
- * (https://tools.ietf.org/html/rfc8152) implementation. The wrapping
- * byte string is taken as input by the hash function (which is why it
- * is returned by QCBOREncode_CloseBstrWrap2()).  It is also easy to
- * recover on decoding with standard CBOR decoders.
+ * cryptographically hashed, as part of a [RFC 9052, COSE]
+ * (https://www.rfc-editor.org/rfc/rfc9052.html) implementation. The
+ * wrapping byte string is taken as input by the hash function (which
+ * is why it is returned by QCBOREncode_CloseBstrWrap2()).  It is also
+ * easy to recover on decoding with standard CBOR decoders.
  *
  * Using QCBOREncode_BstrWrap() and QCBOREncode_CloseBstrWrap2()
  * avoids having to encode the items first in one buffer (e.g., the
@@ -2442,8 +2478,8 @@
  *
  * A pointer and length of the enclosed encoded CBOR is returned in @c
  * *pWrappedCBOR if it is not @c NULL. The main purpose of this is so
- * this data can be hashed (e.g., with SHA-256) as part of a [RFC
- * 8152, COSE] (https://tools.ietf.org/html/rfc8152)
+ * this data can be hashed (e.g., with SHA-256) as part of a
+ * [RFC 9052, COSE] (https://www.rfc-editor.org/rfc/rfc9052.html)
  * implementation. **WARNING**, this pointer and length should be used
  * right away before any other calls to @c QCBOREncode_CloseXxx() as
  * they will move data around and the pointer and length will no
@@ -2476,7 +2512,7 @@
  *
  * @param[in] pCtx       The encoding context.
  *
- * This cancels QCBOREncode_BstrWrap() making tghe encoding as if it
+ * This cancels QCBOREncode_BstrWrap() making the encoding as if it
  * were never called.
  *
  * WARNING: This does not work on QCBOREncode_BstrWrapInMap()
@@ -2498,8 +2534,7 @@
  * @param[in] Encoded  The already-encoded CBOR to add to the context.
  *
  * The encoded CBOR being added must be fully conforming CBOR. It must
- * be complete with no arrays or maps that are incomplete. While this
- * encoder doesn't ever produce indefinite lengths, it is OK for the
+ * be complete with no arrays or maps that are incomplete. it is OK for the
  * raw CBOR added here to have indefinite lengths.
  *
  * The raw CBOR added here is not checked in anyway. If it is not
@@ -2583,7 +2618,8 @@
  *
  * This may be called multiple times. It will always return the
  * same. It can also be interleaved with calls to
- * QCBOREncode_FinishGetSize().
+ * QCBOREncode_FinishGetSize(). See QCBOREncode_SubString() for a
+ * means to get the thus-far-encoded CBOR.
  *
  * QCBOREncode_GetErrorState() can be called to get the current
  * error state in order to abort encoding early as an optimization, but
@@ -2610,22 +2646,35 @@
 
 
 /**
- * @brief Indicate whether output buffer is NULL or not.
+ * @brief Indicate whether the output storage buffer is NULL.
  *
  * @param[in] pCtx  The encoding context.
  *
  * @return 1 if the output buffer is @c NULL.
  *
- * Sometimes a @c NULL input buffer is given to QCBOREncode_Init() so
- * that the size of the generated CBOR can be calculated without
- * allocating a buffer for it. This returns 1 when the output buffer
- * is @c NULL and 0 when it is not.
+ * As described in QCBOREncode_Init(), @c Storage.ptr may be give as @c NULL
+ * for output size calculation. This returns 1 when that is the true, and 0 if not.
  */
 static int
 QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx);
 
 
 /**
+ * @brief Retrieve the storage buffer passed in to QCBOREncode_Init().
+ *
+ * @param[in] pCtx  The encoding context.
+ *
+ * @return The output storage buffer passed to QCBOREncode_Init().
+ *
+ * This doesn't give any information about how much has been encoded
+ * or the error state. It just returns the exact @ref UsefulOutBuf given
+ * to QCBOREncode_Init().
+ */
+static UsefulBuf
+QCBOREncode_RetrieveOutputStorage(QCBOREncodeContext *pCtx);
+
+
+/**
  * @brief Get the encoding error state.
  *
  * @param[in] pCtx  The encoding context.
@@ -2643,7 +2692,73 @@
 
 
 /**
- * Encode the "head" of a CBOR data item.
+ * @brief Returns current end of encoded data.
+ *
+ * @param[in] pCtx  The encoding context.
+ *
+ * @return Byte offset of end of encoded data.
+ *
+ * The purpose of this is to enable cryptographic hashing over a
+ * subpart of thus far CBOR-encoded data. Then perhaps a signature
+ * over the hashed CBOR is added to the encoded output. There is
+ * nothing specific to hashing or signing in this, so this can be used
+ * for other too.
+ *
+ * Call this to get the offset of the start of the encoded
+ * to-be-hashed CBOR items, then call QCBOREncode_SubString().
+ * QCBOREncode_Tell() can also be called twice, first to get the
+ * offset of the start and second for the offset of the end. Those
+ * offsets can be applied to the output storage buffer.
+ *
+ * This will return successfully even if the encoder is in the error
+ * state.
+ *
+ * WARNING: All definite-length arrays and maps opened before the
+ * first call to QCBOREncode_Tell() must not be closed until the
+ * substring is obtained and processed. Similarly, every
+ * definite-length array or map opened after the first call to
+ * QCBOREncode_Tell() must be closed before the substring is obtained
+ * and processed.  The same applies for opened byte strings. There is
+ * no detection of these errors. This occurs because QCBOR goes back
+ * and inserts the lengths of definite-length arrays and maps when
+ * they are closed. This insertion will make the offsets incorrect.
+ */
+static size_t
+QCBOREncode_Tell(QCBOREncodeContext *pCtx);
+
+
+/**
+ * @brief Get a substring of encoded CBOR for cryptographic hash
+ *
+ * @param[in] pCtx  The encoding context.
+ * @param[in] uStart  The start offset of substring.
+ *
+ * @return Pointer and length of of substring.
+ *
+ * @c uStart is obtained by calling QCBOREncode_Tell() before encoding
+ * the first item in the substring. Then encode some data items. Then
+ * call this. The substring returned contains the encoded data items.
+ *
+ * The substring may have deeply nested arrays and maps as long as any
+ * opened after the call to QCBOREncode_Tell() are closed before this
+ * is called.
+ *
+ * This will return @c NULLUsefulBufC if the encoder is in the error
+ * state or if @c uStart is beyond the end of the thus-far encoded
+ * data items.
+ *
+ * If @c uStart is 0, all the thus-far-encoded CBOR will be returned.
+ * Unlike QCBOREncode_Finish(), this will succeed even if some arrays
+ * and maps are not closed.
+ *
+ * See important usage WARNING in QCBOREncode_Tell()
+ */
+UsefulBufC
+QCBOREncode_SubString(QCBOREncodeContext *pCtx, const size_t uStart);
+
+
+/**
+ * @brief Encode the head of a CBOR data item.
  *
  * @param Buffer       Buffer to output the encoded head to; must be
  *                     @ref QCBOR_HEAD_BUFFER_SIZE bytes in size.
@@ -2671,7 +2786,7 @@
  * doesn't have to be encoded in a contiguous buffer.
  *
  * For example, if you have a 100,000 byte binary blob in a buffer that
- * needs to be a bstr encoded and then hashed. You could allocate a
+ * needs to be bstr encoded and then hashed. You could allocate a
  * 100,010 byte buffer and encode it normally. Alternatively, you can
  * encode the head in a 10 byte buffer with this function, hash that and
  * then hash the 100,000 bytes using the same hash context.
@@ -2832,19 +2947,19 @@
 static inline void
 QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pMe,
                           const char        *szLabel,
-                          const int64_t      uNum)
+                          const int64_t      nNum)
 {
    QCBOREncode_AddSZString(pMe, szLabel);
-   QCBOREncode_AddInt64(pMe, uNum);
+   QCBOREncode_AddInt64(pMe, nNum);
 }
 
 static inline void
 QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pMe,
                            const int64_t       nLabel,
-                           const int64_t       uNum)
+                           const int64_t       nNum)
 {
    QCBOREncode_AddInt64(pMe, nLabel);
-   QCBOREncode_AddInt64(pMe, uNum);
+   QCBOREncode_AddInt64(pMe, nNum);
 }
 
 
@@ -2945,10 +3060,6 @@
 }
 
 
-
-/*
- * Public functions for adding a tag. See qcbor/qcbor_encode.h
- */
 static inline void
 QCBOREncode_AddTag(QCBOREncodeContext *pMe, const uint64_t uTag)
 {
@@ -2957,6 +3068,7 @@
 
 
 
+
 #ifndef USEFULBUF_DISABLE_ALL_FLOAT
 
 static inline void
@@ -2983,7 +3095,7 @@
    QCBOREncode_Private_AddPreferredDouble(pMe, dNum);
 #else /* QCBOR_DISABLE_PREFERRED_FLOAT */
    QCBOREncode_AddDoubleNoPreferred(pMe, dNum);
-#endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
+#endif /* ! QCBOR_DISABLE_PREFERRED_FLOAT */
 }
 
 static inline void
@@ -3012,7 +3124,7 @@
    QCBOREncode_Private_AddPreferredFloat(pMe, fNum);
 #else /* QCBOR_DISABLE_PREFERRED_FLOAT */
    QCBOREncode_AddFloatNoPreferred(pMe, fNum);
-#endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
+#endif /* ! QCBOR_DISABLE_PREFERRED_FLOAT */
 }
 
 static inline void
@@ -3068,7 +3180,7 @@
    QCBOREncode_AddInt64(pMe, nLabel);
    QCBOREncode_AddFloatNoPreferred(pMe, dNum);
 }
-#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
+#endif /* ! USEFULBUF_DISABLE_ALL_FLOAT */
 
 
 
@@ -3207,6 +3319,7 @@
 }
 
 
+
 static inline void
 QCBOREncode_AddTBinaryUUID(QCBOREncodeContext *pMe,
                            const uint8_t       uTagRequirement,
@@ -3731,7 +3844,7 @@
                                         bIsNegative,
                                         nBase2Exponent);
 }
-#endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
+#endif /* ! QCBOR_DISABLE_EXP_AND_MANTISSA */
 
 
 static inline void
@@ -4112,7 +4225,7 @@
       pMe->uError = QCBOR_ERR_ENCODE_UNSUPPORTED;
       return;
    }
-#endif /* !QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
 
    QCBOREncode_Private_AddType7(pMe, 0, uNum);
 }
@@ -4368,6 +4481,14 @@
    return UsefulOutBuf_IsBufferNULL(&(pMe->OutBuf));
 }
 
+
+static inline UsefulBuf
+QCBOREncode_RetrieveOutputStorage(QCBOREncodeContext *pMe)
+{
+   return UsefulOutBuf_RetrieveOutputStorage(&(pMe->OutBuf));
+}
+
+
 static inline QCBORError
 QCBOREncode_GetErrorState(QCBOREncodeContext *pMe)
 {
@@ -4389,6 +4510,12 @@
 }
 
 
+static inline size_t
+QCBOREncode_Tell(QCBOREncodeContext *pMe)
+{
+   return UsefulOutBuf_GetEndPosition(&(pMe->OutBuf));
+}
+
 /* ========================================================================
      END OF PRIVATE INLINE IMPLEMENTATION
    ======================================================================== */
diff --git a/inc/qcbor/qcbor_spiffy_decode.h b/inc/qcbor/qcbor_spiffy_decode.h
index 26325d8..855e840 100644
--- a/inc/qcbor/qcbor_spiffy_decode.h
+++ b/inc/qcbor/qcbor_spiffy_decode.h
@@ -6,7 +6,7 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
- * See BSD-3-Clause license in README.md
+ * See BSD-3-Clause license in file named "LICENSE"
  *
  * Forked from qcbor_decode.h on 7/23/2020
  * ========================================================================== */
diff --git a/src/UsefulBuf.c b/src/UsefulBuf.c
index 4177010..25a92f4 100644
--- a/src/UsefulBuf.c
+++ b/src/UsefulBuf.c
@@ -44,8 +44,9 @@
 
  when        who          what, where, why
  --------    ----         ---------------------------------------------------
- 1/7/2024    llundblade   Add UsefulInputBuf_Compare().
+ 08/08/2024  llundblade   Add UsefulOutBuf_SubString().
  21/05/2024  llundblade   Comment formatting and some code tidiness.
+ 1/7/2024    llundblade   Add UsefulInputBuf_Compare().
  28/02/2022  llundblade   Rearrange UsefulOutBuf_Compare().
  19/11/2023  llundblade   Add UsefulOutBuf_GetOutput().
  19/11/2023  llundblade   Add UsefulOutBuf_Swap().
@@ -418,6 +419,35 @@
 }
 
 
+/*
+ * Public function -- see UsefulBuf.h
+ *
+ * Code Reviewers: THIS FUNCTION DOES POINTER MATH
+ */
+UsefulBufC UsefulOutBuf_SubString(UsefulOutBuf *pMe,
+                                  const size_t  uStart,
+                                  const size_t  uLen)
+{
+   const UsefulBufC Tmp = UsefulOutBuf_OutUBuf(pMe);
+
+   if(UsefulBuf_IsNULLC(Tmp)) {
+      return NULLUsefulBufC;
+   }
+
+   if(uStart > Tmp.len) {
+      return NULLUsefulBufC;
+   }
+
+   if(Tmp.len - uStart < uLen) {
+      return NULLUsefulBufC;
+   }
+
+   UsefulBufC SubString;
+   SubString.ptr = (const uint8_t *)Tmp.ptr + uStart;
+   SubString.len = uLen;
+
+   return SubString;
+}
 
 
 /*
diff --git a/src/ieee754.c b/src/ieee754.c
index 40421ad..506d5e8 100644
--- a/src/ieee754.c
+++ b/src/ieee754.c
@@ -6,7 +6,7 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
- * See BSD-3-Clause license in README.md
+ * See BSD-3-Clause license in file named "LICENSE"
  *
  * Created on 7/23/18
  * ========================================================================== */
diff --git a/src/ieee754.h b/src/ieee754.h
index fed28f1..9d3a8f3 100644
--- a/src/ieee754.h
+++ b/src/ieee754.h
@@ -5,7 +5,7 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
- * See BSD-3-Clause license in README.md
+ * See BSD-3-Clause license in file named "LICENSE"
  *
  * Created on 7/23/18
  * ========================================================================== */
diff --git a/src/qcbor_decode.c b/src/qcbor_decode.c
index 41e6b21..21845f4 100644
--- a/src/qcbor_decode.c
+++ b/src/qcbor_decode.c
@@ -461,8 +461,8 @@
 
 static QCBORError
 DecodeNesting_DescendMapOrArray(QCBORDecodeNesting *pNesting,
-                                uint8_t             uQCBORType,
-                                uint64_t            uCount)
+                                const uint8_t       uQCBORType,
+                                const uint16_t      uCount)
 {
    QCBORError uError = QCBOR_SUCCESS;
 
@@ -474,21 +474,16 @@
       /* Empty indefinite-length maps and arrays are handled elsewhere */
    }
 
-   /* Error out if arrays is too long to handle */
-   if(uCount != QCBOR_COUNT_INDICATES_INDEFINITE_LENGTH &&
-      uCount > QCBOR_MAX_ITEMS_IN_ARRAY) {
-      uError = QCBOR_ERR_ARRAY_DECODE_TOO_LONG;
-      goto Done;
-   }
+   /* Rely on check in QCBOR_Private_DecodeArrayOrMap() for definite-length
+    * arrays and maps that are too long */
 
    uError = DecodeNesting_Descend(pNesting, uQCBORType);
    if(uError != QCBOR_SUCCESS) {
       goto Done;
    }
 
-   /* Fill in the new map/array level. Check above makes casts OK. */
-   pNesting->pCurrent->u.ma.uCountCursor  = (uint16_t)uCount;
-   pNesting->pCurrent->u.ma.uCountTotal   = (uint16_t)uCount;
+   pNesting->pCurrent->u.ma.uCountCursor = uCount;
+   pNesting->pCurrent->u.ma.uCountTotal  = uCount;
 
    DecodeNesting_ClearBoundedMode(pNesting);
 
@@ -1075,7 +1070,7 @@
 static QCBORError
 QCBOR_Private_DecodeArrayOrMap(const uint8_t  uMode,
                                const int      nMajorType,
-                               const uint64_t uItemCount,
+                               uint64_t       uItemCount,
                                const int      nAdditionalInfo,
                                QCBORItem     *pDecodedItem)
 {
@@ -1108,28 +1103,20 @@
       uReturn = QCBOR_ERR_INDEF_LEN_ARRAYS_DISABLED;
 #endif /* ! QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
    } else {
+      /* ----- Definite-length array/map ----- */
+      if(uItemCount > (nMajorType == QCBOR_TYPE_MAP ? QCBOR_MAX_ITEMS_IN_MAP : QCBOR_MAX_ITEMS_IN_ARRAY)) {
+         uReturn = QCBOR_ERR_ARRAY_DECODE_TOO_LONG;
 
+      } else {
 #ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
-      if(uMode == QCBOR_DECODE_MODE_MAP_AS_ARRAY && nMajorType == QCBOR_TYPE_MAP) {
-         /* ------ Definite-length map as array ------ */
-
-         if(uItemCount > QCBOR_MAX_ITEMS_IN_ARRAY/2) {
-            uReturn = QCBOR_ERR_ARRAY_DECODE_TOO_LONG;
-         } else {
-            /* cast OK because of check above */
-            pDecodedItem->val.uCount = (uint16_t)uItemCount*2;
+         if(uMode == QCBOR_DECODE_MODE_MAP_AS_ARRAY && nMajorType == QCBOR_TYPE_MAP) {
+            /* ------ Map as array ------ */
+            uItemCount *= 2;
          }
-
-      } else
 #endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
-      {
-         /* ------ Definite-length array/map ------ */
-         if(uItemCount > QCBOR_MAX_ITEMS_IN_ARRAY) {
-            uReturn = QCBOR_ERR_ARRAY_DECODE_TOO_LONG;
-         } else {
-            /* cast OK because of check above */
-            pDecodedItem->val.uCount = (uint16_t)uItemCount;
-         }
+
+         /* cast OK because of check above */
+         pDecodedItem->val.uCount = (uint16_t)uItemCount;
       }
    }
 
@@ -1528,9 +1515,9 @@
                                    QCBORItem           *pDecodedItem)
 {
    QCBORError uReturn;
-   int      nMajorType = 0;
-   uint64_t uArgument = 0;
-   int      nAdditionalInfo = 0;
+   int       nMajorType = 0;
+   uint64_t  uArgument = 0;
+   int       nAdditionalInfo = 0;
 
    memset(pDecodedItem, 0, sizeof(QCBORItem));
 
@@ -2311,8 +2298,8 @@
        */
       QCBORError uDescendErr;
       uDescendErr = DecodeNesting_DescendMapOrArray(&(pMe->nesting),
-                                                pDecodedItem->uDataType,
-                                                pDecodedItem->val.uCount);
+                                                    pDecodedItem->uDataType,
+                                                    pDecodedItem->val.uCount);
       if(uDescendErr != QCBOR_SUCCESS) {
          /* This error is probably a traversal error and it overrides
           * the non-traversal error.
diff --git a/src/qcbor_encode.c b/src/qcbor_encode.c
index fa7f485..50ed8a3 100644
--- a/src/qcbor_encode.c
+++ b/src/qcbor_encode.c
@@ -1,35 +1,35 @@
-/*==============================================================================
- Copyright (c) 2016-2018, The Linux Foundation.
- Copyright (c) 2018-2024, Laurence Lundblade.
- Copyright (c) 2021, Arm Limited.
- All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-    * Neither the name of The Linux Foundation nor the names of its
-      contributors, nor the name "Laurence Lundblade" may be used to
-      endorse or promote products derived from this software without
-      specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- =============================================================================*/
+/* ===========================================================================
+ * Copyright (c) 2016-2018, The Linux Foundation.
+ * Copyright (c) 2018-2024, Laurence Lundblade.
+ * Copyright (c) 2021, Arm Limited.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors, nor the name "Laurence Lundblade" may be used to
+ *       endorse or promote products derived from this software without
+ *       specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ========================================================================= */
 
 
 #include "qcbor/qcbor_encode.h"
@@ -115,10 +115,10 @@
 Nesting_Increment(QCBORTrackNesting *pNesting)
 {
 #ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
-   if(1 >= QCBOR_MAX_ITEMS_IN_ARRAY - pNesting->pCurrentNesting->uCount) {
+   if(pNesting->pCurrentNesting->uCount >= QCBOR_MAX_ITEMS_IN_ARRAY) {
       return QCBOR_ERR_ARRAY_TOO_LONG;
    }
-#endif /* !QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
 
    pNesting->pCurrentNesting->uCount++;
 
@@ -170,7 +170,7 @@
 {
    return pNesting->pCurrentNesting == &pNesting->pArrays[0] ? false : true;
 }
-#endif /* QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
 
 
 
@@ -227,7 +227,7 @@
  *
  * QCBOR_DISABLE_ENCODE_USAGE_GUARDS also disables the check for more
  * than QCBOR_MAX_ITEMS_IN_ARRAY in an array. Since
- * QCBOR_MAX_ITEMS_IN_ARRAY is very large (65,535) it is very unlikely
+ * QCBOR_MAX_ITEMS_IN_ARRAY is very large (65,534) it is very unlikely
  * to be reached. If it is reached, the count will wrap around to zero
  * and CBOR that is not well formed will be produced, but there will
  * be no buffers overrun and new security issues in the code.
@@ -450,7 +450,7 @@
       nAdditionalInfo = CBOR_SIMPLE_BREAK;
 
    } else
-#endif /* !QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
+#endif /* ! QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
       if (uArgument < CBOR_TWENTY_FOUR && uMinLen == 0) {
       /* Simple case where argument is < 24 */
       nAdditionalInfo = (int)uArgument;
@@ -529,7 +529,7 @@
    }
 #else
    (void)Nesting_Increment(&(pMe->nesting));
-#endif /* !QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
 }
 
 
@@ -580,7 +580,7 @@
 
 
 /*
- * Public functions for adding signed integers. See qcbor/qcbor_encode.h
+ * Public function for adding signed integers. See qcbor/qcbor_encode.h
  */
 void
 QCBOREncode_AddInt64(QCBOREncodeContext *pMe, const int64_t nNum)
@@ -630,7 +630,7 @@
 
 
 /*
- * Public functions for adding raw encoded CBOR. See qcbor/qcbor_encode.h
+ * Public function for adding raw encoded CBOR. See qcbor/qcbor_encode.h
  */
 void
 QCBOREncode_AddEncoded(QCBOREncodeContext *pMe, const UsefulBufC Encoded)
@@ -759,7 +759,7 @@
 
    QCBOREncode_Private_AddType7(pMe, (uint8_t)FloatResult.uSize, FloatResult.uValue);
 }
-#endif /* !QCBOR_DISABLE_PREFERRED_FLOAT */
+#endif /* ! QCBOR_DISABLE_PREFERRED_FLOAT */
 
 
 
@@ -1120,7 +1120,7 @@
    }
    QCBOREncode_CloseArray(pMe);
 }
-#endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
+#endif /* ! QCBOR_DISABLE_EXP_AND_MANTISSA */
 
 
 /**
@@ -1196,7 +1196,7 @@
     */
    QCBOREncode_Private_OpenMapOrArray(pMe, uMajorType);
 }
-#endif
+#endif /* ! QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
 
 
 /**
@@ -1231,7 +1231,7 @@
       return true;
    }
 
-#else /* !QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+#else /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
    /* None of these checks are performed if the encode guards are
     * turned off as they all relate to correct calling.
     *
@@ -1241,14 +1241,14 @@
 
    (void)uMajorType;
    (void)pMe;
-#endif /* !QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
 
    return false;
 }
 
 
 /**
- * @brief Insert the CBOR head for a map, array or wrapped bstr
+ * @brief Insert the CBOR head for a map, array or wrapped bstr.
  *
  * @param pMe         QCBOR encoding context.
  * @param uMajorType  One of CBOR_MAJOR_TYPE_XXXX.
@@ -1643,7 +1643,7 @@
 
 
 /*
- * Public functions for closing bstr wrapping. See qcbor/qcbor_encode.h
+ * Public function for closing bstr wrapping. See qcbor/qcbor_encode.h
  */
 void
 QCBOREncode_CloseBstrWrap2(QCBOREncodeContext *pMe,
@@ -1707,7 +1707,7 @@
     * security hole, so no extra code or state is added to handle this
     * condition.
     */
-#endif /* QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
 
    Nesting_Decrease(&(pMe->nesting));
    Nesting_Decrement(&(pMe->nesting));
@@ -1729,7 +1729,7 @@
       pMe->uError = QCBOR_ERR_OPEN_BYTE_STRING;
       return;
    }
-#endif /* QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
 
    QCBOREncode_Private_OpenMapOrArray(pMe, CBOR_MAJOR_NONE_TYPE_OPEN_BSTR);
 }
@@ -1752,7 +1752,6 @@
 
 
 #ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS
-
 /**
  * @brief Semi-private method to close a map, array with indefinite length
  *
@@ -1774,7 +1773,7 @@
    QCBOREncode_Private_AppendCBORHead(pMe, CBOR_MAJOR_NONE_TYPE_SIMPLE_BREAK, CBOR_SIMPLE_BREAK, 0);
    Nesting_Decrease(&(pMe->nesting));
 }
-#endif
+#endif /* ! QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
 
 
 /*
@@ -1792,7 +1791,7 @@
       pMe->uError = QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN;
       goto Done;
    }
-#endif /* QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
 
    *pEncodedCBOR = UsefulOutBuf_OutUBuf(&(pMe->OutBuf));
 
@@ -1802,7 +1801,7 @@
 
 
 /*
- * Public functions to get size of the encoded result. See qcbor/qcbor_encode.h
+ * Public function to get size of the encoded result. See qcbor/qcbor_encode.h
  */
 QCBORError
 QCBOREncode_FinishGetSize(QCBOREncodeContext *pMe, size_t *puEncodedLen)
@@ -1817,3 +1816,28 @@
 
    return nReturn;
 }
+
+
+/*
+ * Public function to get substring of encoded-so-far. See qcbor/qcbor_encode.h
+ */
+UsefulBufC
+QCBOREncode_SubString(QCBOREncodeContext *pMe, const size_t uStart)
+{
+   if(pMe->uError) {
+      return NULLUsefulBufC;
+   }
+
+   /* An attempt was made to detect usage errors by comparing uStart
+    * to offsets of open arrays and maps in pMe->nesting, but it is
+    * not possible because there's not enough information in just
+    * the offset. It's not possible to known if Tell() was called before
+    * or after an Open(). To detect this error, the nesting level
+    * would also need to be known. This is not frequently used, so
+    * it is not worth adding this complexity.
+    */
+
+   const size_t uEnd = QCBOREncode_Tell(pMe);
+
+   return UsefulOutBuf_SubString(&(pMe->OutBuf), uStart, uEnd - uStart);
+}
diff --git a/src/qcbor_err_to_str.c b/src/qcbor_err_to_str.c
index 87c2b28..f9588e5 100644
--- a/src/qcbor_err_to_str.c
+++ b/src/qcbor_err_to_str.c
@@ -7,7 +7,7 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
- * See BSD-3-Clause license in README.md
+ * See BSD-3-Clause license in file named "LICENSE"
  *
  * Created on 3/21/20
  * ========================================================================== */
diff --git a/test/UsefulBuf_Tests.c b/test/UsefulBuf_Tests.c
index 6e47f3c..338e6db 100644
--- a/test/UsefulBuf_Tests.c
+++ b/test/UsefulBuf_Tests.c
@@ -127,6 +127,30 @@
       goto Done;
    }
 
+   Out = UsefulOutBuf_SubString(&UOB, 10, 8);
+   if(UsefulBuf_IsNULLC(Out) ||
+      UsefulBuf_Compare(UsefulBuf_FROM_SZ_LITERAL("unbounce"), Out) ||
+      UsefulOutBuf_GetError(&UOB)) {
+      szReturn = "SubString substring";
+      goto Done;
+   }
+
+   Out = UsefulOutBuf_SubString(&UOB, 0, Expected.len);
+   if(UsefulBuf_IsNULLC(Out) ||
+      UsefulBuf_Compare(Expected, Out) ||
+      UsefulOutBuf_GetError(&UOB)) {
+      szReturn = "SubString all";
+      goto Done;
+   }
+
+   Out = UsefulOutBuf_SubString(&UOB, Expected.len, 0);
+   if(UsefulBuf_IsNULLC(Out) ||
+      UsefulBuf_Compare(UsefulBuf_FROM_SZ_LITERAL(""), Out) ||
+      UsefulOutBuf_GetError(&UOB)) {
+      szReturn = "SubString empty";
+      goto Done;
+   }
+
    /* Now test the size calculation mode */
    UsefulOutBuf_Init(&UOB, SizeCalculateUsefulBuf);
 
@@ -246,7 +270,7 @@
       return "Bad insertion point not caught";
 
 
-   UsefulBuf_MAKE_STACK_UB(outBuf2,10);
+   UsefulBuf_MAKE_STACK_UB(outBuf2, 10);
 
    UsefulOutBuf_Init(&UOB, outBuf2);
 
@@ -260,6 +284,29 @@
       return "insert with data should have failed";
    }
 
+   UsefulOutBuf_Init(&UOB, outBuf2);
+   UsefulOutBuf_AppendString(&UOB, "abc123");
+
+   UsefulBufC Out = UsefulOutBuf_SubString(&UOB, 7, 1);
+   if(!UsefulBuf_IsNULLC(Out)) {
+      return "SubString start should fail off end 1";
+   }
+   Out = UsefulOutBuf_SubString(&UOB, 5, 3);
+   if(!UsefulBuf_IsNULLC(Out)) {
+      return "SubString len should fail off end 2";
+   }
+   Out = UsefulOutBuf_SubString(&UOB, 0, 7);
+   if(!UsefulBuf_IsNULLC(Out)) {
+      return "SubString len should fail off end 3";
+   }
+   Out = UsefulOutBuf_SubString(&UOB, 7, 0);
+   if(!UsefulBuf_IsNULLC(Out)) {
+      return "SubString len should fail off end 4";
+   }
+   Out = UsefulOutBuf_SubString(&UOB, 6, 1);
+   if(!UsefulBuf_IsNULLC(Out)) {
+      return "SubString len should fail off end 5";
+   }
 
    UsefulOutBuf_Init(&UOB, (UsefulBuf){NULL, SIZE_MAX - 5});
    UsefulOutBuf_AppendData(&UOB, "123456789", SIZE_MAX -6);
diff --git a/test/float_tests.c b/test/float_tests.c
index d59241f..892942d 100644
--- a/test/float_tests.c
+++ b/test/float_tests.c
@@ -6,7 +6,7 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
- * See BSD-3-Clause license in README.md
+ * See BSD-3-Clause license in file named "LICENSE"
  *
  * Created on 9/19/18
  * ========================================================================= */
diff --git a/test/float_tests.h b/test/float_tests.h
index 427aa76..cfc2e6e 100644
--- a/test/float_tests.h
+++ b/test/float_tests.h
@@ -5,7 +5,7 @@
 
  SPDX-License-Identifier: BSD-3-Clause
 
- See BSD-3-Clause license in README.md
+ See BSD-3-Clause license in file named "LICENSE"
 
  Created on 9/19/18
  =============================================================================*/
diff --git a/test/half_to_double_from_rfc7049.h b/test/half_to_double_from_rfc7049.h
index 8e07dc2..aa3b4c3 100644
--- a/test/half_to_double_from_rfc7049.h
+++ b/test/half_to_double_from_rfc7049.h
@@ -6,7 +6,7 @@
 
  SPDX-License-Identifier: BSD-3-Clause
 
- See BSD-3-Clause license in README.md
+ See BSD-3-Clause license in file named "LICENSE"
 
  Created on 9/23/18
   ============================================================================*/
diff --git a/test/not_well_formed_cbor.h b/test/not_well_formed_cbor.h
index 5a213ef..c325768 100644
--- a/test/not_well_formed_cbor.h
+++ b/test/not_well_formed_cbor.h
@@ -7,7 +7,7 @@
 
  SPDX-License-Identifier: BSD-3-Clause
 
- See BSD-3-Clause license in README.md
+ See BSD-3-Clause license in file named "LICENSE"
 
  Created on 7/27/19
  ==============================================================================*/
diff --git a/test/qcbor_decode_tests.c b/test/qcbor_decode_tests.c
index 202be19..8217053 100644
--- a/test/qcbor_decode_tests.c
+++ b/test/qcbor_decode_tests.c
@@ -2296,9 +2296,61 @@
 }
 
 
+/* These are just the item that open large maps and arrays, not
+ * the items in the array. This is sufficient to test the
+ * boundary condition. */
+static const uint8_t spLargeArrayFake[] = {
+   0x99, 0xff, 0xfe};
+
+static const uint8_t spTooLargeArrayFake[] = {
+   0x99, 0xff, 0xff};
+
+static const uint8_t spLargeMapFake[] = {
+   0xb9, 0x7f, 0xff};
+
+static const uint8_t spTooLargeMapFake[] = {
+   0xba, 0x00, 0x00, 0x80, 0x00};
+
 
 int32_t ParseMapTest(void)
 {
+   QCBORDecodeContext DCtx;
+   QCBORItem          Item;
+   QCBORError         uErr;
+
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spLargeArrayFake),
+                    QCBOR_DECODE_MODE_NORMAL);
+   uErr = QCBORDecode_GetNext(&DCtx, &Item);
+   if(uErr != QCBOR_SUCCESS || Item.val.uCount != QCBOR_MAX_ITEMS_IN_ARRAY) {
+      return -100;
+   }
+
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spTooLargeArrayFake),
+                    QCBOR_DECODE_MODE_NORMAL);
+   uErr = QCBORDecode_GetNext(&DCtx, &Item);
+   if(uErr != QCBOR_ERR_ARRAY_DECODE_TOO_LONG) {
+      return -101;
+   }
+
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spLargeMapFake),
+                    QCBOR_DECODE_MODE_NORMAL);
+   uErr = QCBORDecode_GetNext(&DCtx, &Item);
+   if(uErr != QCBOR_SUCCESS || Item.val.uCount != QCBOR_MAX_ITEMS_IN_MAP) {
+      return -110;
+   }
+
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spTooLargeMapFake),
+                    QCBOR_DECODE_MODE_NORMAL);
+   uErr = QCBORDecode_GetNext(&DCtx, &Item);
+   if(uErr != QCBOR_ERR_ARRAY_DECODE_TOO_LONG) {
+      return -111;
+   }
+
+
    // Parse a moderatly complex map structure very thoroughly
    int32_t nResult = ParseMapTest1(QCBOR_DECODE_MODE_NORMAL);
    if(nResult) {
@@ -11038,6 +11090,18 @@
       return -107;
    }
 
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pValidMapEncoded),
+                    QCBOR_DECODE_MODE_NORMAL);
+
+   UsefulBufC Xx = QCBORDecode_RetrieveUndecodedInput(&DCtx);
+   if(Xx.ptr != pValidMapEncoded) {
+      return -200;
+   }
+   if(Xx.len != sizeof(pValidMapEncoded)) {
+      return -201;
+   }
+
    return 0;
 }
 
diff --git a/test/qcbor_encode_tests.c b/test/qcbor_encode_tests.c
index 88251ac..e2b8341 100644
--- a/test/qcbor_encode_tests.c
+++ b/test/qcbor_encode_tests.c
@@ -187,6 +187,11 @@
    }
 
 
+   UsefulBuf Tmp = QCBOREncode_RetrieveOutputStorage(&EC);
+   if(Tmp.ptr != spBigBuf && Tmp.len != sizeof(spBigBuf)) {
+      return -111;
+   }
+
    // Make another encoded message with the CBOR from the previous
    // put into this one
    UsefulBuf_MAKE_STACK_UB(MemoryForEncoded2, 20);
@@ -203,6 +208,8 @@
    if(QCBOREncode_Finish(&EC, &Encoded2)) {
       return -5;
    }
+
+
     /*
      [                // 0    1:3
         451,          // 1    1:2
@@ -1136,10 +1143,9 @@
 static const uint8_t spExpectedEncodedSimpleIndefiniteLength[] = {
    0x9f, 0xf5, 0xf4, 0xf6, 0xf7, 0xbf, 0x65, 0x55, 0x4e, 0x44, 0x65, 0x66, 0xf7, 0xff, 0xff};
 
-int32_t SimpleValuesIndefiniteLengthTest1(void)
+int32_t IndefiniteLengthTest(void)
 {
    QCBOREncodeContext ECtx;
-   int nReturn = 0;
 
    QCBOREncode_Init(&ECtx, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
    QCBOREncode_OpenArrayIndefiniteLength(&ECtx);
@@ -1158,13 +1164,38 @@
 
    UsefulBufC ECBOR;
    if(QCBOREncode_Finish(&ECtx, &ECBOR)) {
-      nReturn = -1;
+      return -1;
    }
 
-   if(CheckResults(ECBOR, spExpectedEncodedSimpleIndefiniteLength))
+   if(CheckResults(ECBOR, spExpectedEncodedSimpleIndefiniteLength)) {
       return -2;
+   }
 
-   return(nReturn);
+
+#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
+   QCBOREncode_Init(&ECtx, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
+   QCBOREncode_OpenArrayIndefiniteLength(&ECtx);
+   QCBOREncode_CloseArray(&ECtx);
+   if(QCBOREncode_GetErrorState(&ECtx) != QCBOR_ERR_CLOSE_MISMATCH) {
+      return -3;
+   }
+
+   QCBOREncode_Init(&ECtx, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
+   QCBOREncode_OpenArray(&ECtx);
+   QCBOREncode_CloseArrayIndefiniteLength(&ECtx);
+   if(QCBOREncode_GetErrorState(&ECtx) != QCBOR_ERR_CLOSE_MISMATCH) {
+      return -3;
+   }
+
+   QCBOREncode_Init(&ECtx, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
+   QCBOREncode_OpenArrayIndefiniteLength(&ECtx);
+   QCBOREncode_CloseMapIndefiniteLength(&ECtx);
+   if(QCBOREncode_GetErrorState(&ECtx) != QCBOR_ERR_CLOSE_MISMATCH) {
+      return -3;
+   }
+#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+
+   return 0;
 }
 #endif
 
@@ -2063,6 +2094,24 @@
       return -11;
    }
 
+#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
+   // Seventh test, erroneous cancel
+   QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
+   QCBOREncode_CancelBstrWrap(&EC);
+   uErr = QCBOREncode_GetErrorState(&EC);
+   if(uErr != QCBOR_ERR_TOO_MANY_CLOSES) {
+      return -12;
+   }
+
+   QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
+   QCBOREncode_OpenArray(&EC);
+   QCBOREncode_CancelBstrWrap(&EC);
+   uErr = QCBOREncode_GetErrorState(&EC);
+   if(uErr != QCBOR_ERR_CLOSE_MISMATCH) {
+      return -13;
+   }
+#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+
    return 0;
 }
 
@@ -2817,6 +2866,12 @@
       return -11;
    }
 
+   UsefulBuf Tmp;
+   Tmp = QCBOREncode_RetrieveOutputStorage(&EC);
+   if(Tmp.ptr != NULL && Tmp.len != UINT32_MAX) {
+      return -111;
+   }
+
    /* ------ QCBOR_ERR_UNSUPPORTED -------- */
    QCBOREncode_Init(&EC, Large);
    QCBOREncode_OpenArray(&EC);
@@ -2873,6 +2928,37 @@
       return -130;
    }
 
+
+#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
+   /* ------ QCBOR_ERR_ARRAY_TOO_LONG -------- */
+   QCBOREncode_Init(&EC, Large);
+   QCBOREncode_OpenArray(&EC);
+   int i;
+   for(i = 0; i < QCBOR_MAX_ITEMS_IN_ARRAY; i++) {
+      QCBOREncode_AddInt64(&EC, 0);
+   }
+   if(QCBOREncode_GetErrorState(&EC)) {
+      return 250;
+   }
+   QCBOREncode_AddInt64(&EC, 0);
+   if(QCBOREncode_GetErrorState(&EC) != QCBOR_ERR_ARRAY_TOO_LONG) {
+      return 251;
+   }
+
+   QCBOREncode_Init(&EC, Large);
+   QCBOREncode_OpenMap(&EC);
+   for(i = 0; i < QCBOR_MAX_ITEMS_IN_MAP; i++) {
+      QCBOREncode_AddInt64ToMapN(&EC, 0,0);
+   }
+   if(QCBOREncode_GetErrorState(&EC)) {
+      return 250;
+   }
+   QCBOREncode_AddInt64ToMapN(&EC, 0,0);
+   if(QCBOREncode_GetErrorState(&EC) != QCBOR_ERR_ARRAY_TOO_LONG) {
+      return 251;
+   }
+#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+
    return 0;
 }
 
@@ -2881,26 +2967,34 @@
 /*
    [
       4([-1, 3]),
+      [-1, 4],
       4([-20, 4759477275222530853136]),
+      [2, 4759477275222530853136],
       4([9223372036854775807, -4759477275222530853137]),
       5([300, 100]),
+      [600, 200],
       5([-20, 4759477275222530853136]),
-      5([-9223372036854775808, -4759477275222530853137])
- ]
+      [4, 4759477275222530853136],
+      5([-9223372036854775808, -4759477275222530853137])]
+   ]
  */
 static const uint8_t spExpectedExponentAndMantissaArray[] = {
-   0x86, 0xC4, 0x82, 0x20, 0x03, 0xC4, 0x82, 0x33,
-   0xC2, 0x4A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
-   0x07, 0x08, 0x09, 0x10, 0xC4, 0x82, 0x1B, 0x7F,
-   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3,
-   0x4A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-   0x08, 0x09, 0x0F, 0xC5, 0x82, 0x19, 0x01, 0x2C,
-   0x18, 0x64, 0xC5, 0x82, 0x33, 0xC2, 0x4A, 0x01,
-   0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
-   0x10, 0xC5, 0x82, 0x3B, 0x7F, 0xFF, 0xFF, 0xFF,
-   0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0x4A, 0x01, 0x02,
-   0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0F};
-
+   0x8A, 0xC4, 0x82, 0x20, 0x03, 0x82, 0x20, 0x04,
+   0xC4, 0x82, 0x33, 0xC2, 0x4A, 0x01, 0x02, 0x03,
+   0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x82,
+   0x02, 0xC2, 0x4A, 0x01, 0x02, 0x03, 0x04, 0x05,
+   0x06, 0x07, 0x08, 0x09, 0x10, 0xC4, 0x82, 0x1B,
+   0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+   0xC3, 0x4A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+   0x07, 0x08, 0x09, 0x0F, 0xC5, 0x82, 0x19, 0x01, // TODO: adjust this back to value from master when better big num is ...
+   0x2C, 0x18, 0x64, 0x82, 0x19, 0x02, 0x58, 0x18,
+   0xC8, 0xC5, 0x82, 0x33, 0xC2, 0x4A, 0x01, 0x02,
+   0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10,
+   0x82, 0x04, 0xC2, 0x4A, 0x01, 0x02, 0x03, 0x04,
+   0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0xC5, 0x82,
+   0x3B, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+   0xFF, 0xC3, 0x4A, 0x01, 0x02, 0x03, 0x04, 0x05,
+   0x06, 0x07, 0x08, 0x09, 0x0F}; // TODO: adjust this back to value from master when better big num is ...
 
 /*
   {
@@ -3114,10 +3208,14 @@
    QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
    QCBOREncode_OpenArray(&EC);
    QCBOREncode_AddDecimalFraction(&EC, 3, -1); // 3 * (10 ^ -1)
+   QCBOREncode_AddTDecimalFraction(&EC, QCBOR_ENCODE_AS_BORROWED, 4, -1); // 3 * (10 ^ -1)
    QCBOREncode_AddDecimalFractionBigNum(&EC, BigNum , false, -20);
+   QCBOREncode_AddTDecimalFractionBigNum(&EC, QCBOR_ENCODE_AS_BORROWED, BigNum , false, 2);
    QCBOREncode_AddDecimalFractionBigNum(&EC, BigNum, true, INT64_MAX);
    QCBOREncode_AddBigFloat(&EC, 100, 300);
+   QCBOREncode_AddTBigFloat(&EC, QCBOR_ENCODE_AS_BORROWED, 200, 600);
    QCBOREncode_AddBigFloatBigNum(&EC, BigNum, false, -20);
+   QCBOREncode_AddTBigFloatBigNum(&EC, QCBOR_ENCODE_AS_BORROWED, BigNum, false, 4);
    QCBOREncode_AddBigFloatBigNum(&EC, BigNum, true, INT64_MIN);
    QCBOREncode_CloseArray(&EC);
 
@@ -3977,3 +4075,84 @@
 
 }
 #endif /* ! USEFULBUF_DISABLE_ALL_FLOAT && ! QCBOR_DISABLE_PREFERRED_FLOAT */
+
+int32_t SubStringTest(void)
+{
+   QCBOREncodeContext EC;
+   size_t             uStart;
+   size_t             uCurrent;
+   UsefulBufC         SS;
+   UsefulBufC         Encoded;
+   QCBORError         uErr;
+
+   QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
+   QCBOREncode_OpenArray(&EC);
+   uStart = QCBOREncode_Tell(&EC);
+   QCBOREncode_AddInt64(&EC, 0);
+   SS = QCBOREncode_SubString(&EC, uStart);
+   if(UsefulBuf_Compare(SS, (UsefulBufC){"\x00", 1})) {
+      return 1;
+   }
+
+   QCBOREncode_OpenArray(&EC);
+
+   QCBOREncode_CloseArray(&EC);
+   SS = QCBOREncode_SubString(&EC, uStart);
+   if(UsefulBuf_Compare(SS, (UsefulBufC){"\x00\x80", 2})) {
+      return 3;
+   }
+
+
+   /* Try it on a sequence */
+   QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
+   uStart = QCBOREncode_Tell(&EC);
+   QCBOREncode_AddInt64(&EC, 1);
+   QCBOREncode_AddInt64(&EC, 1);
+   QCBOREncode_AddInt64(&EC, 1);
+   QCBOREncode_AddInt64(&EC, 1);
+   SS = QCBOREncode_SubString(&EC, uStart);
+   if(UsefulBuf_Compare(SS, (UsefulBufC){"\x01\x01\x01\x01", 4})) {
+      return 10;
+   }
+
+   uCurrent = QCBOREncode_Tell(&EC);
+   if(!UsefulBuf_IsNULLC(QCBOREncode_SubString(&EC, uCurrent+1))) {
+      return 11;
+   }
+
+#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
+   /* Now cause an error */
+   QCBOREncode_OpenMap(&EC);
+   QCBOREncode_CloseArray(&EC);
+   if(!UsefulBuf_IsNULLC(QCBOREncode_SubString(&EC, uStart))) {
+      return 15;
+   }
+#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+
+
+   QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
+   QCBOREncode_AddInt64(&EC, 1);
+   QCBOREncode_AddInt64(&EC, 1);
+   uStart = QCBOREncode_Tell(&EC);
+   QCBOREncode_OpenMap(&EC);
+   QCBOREncode_OpenMapInMapN(&EC, 3);
+   QCBOREncode_OpenArrayInMapN(&EC, 4);
+   QCBOREncode_AddInt64(&EC, 0);
+   QCBOREncode_CloseArray(&EC);
+   QCBOREncode_CloseMap(&EC);
+   QCBOREncode_CloseMap(&EC);
+   SS = QCBOREncode_SubString(&EC, uStart);
+   if(UsefulBuf_Compare(SS, (UsefulBufC){"\xA1\x03\xA1\x04\x81\x00", 6})) {
+      return 20;
+   }
+
+   uErr = QCBOREncode_Finish(&EC, &Encoded);
+   if(uErr) {
+      return 21;
+   }
+   if(UsefulBuf_Compare(Encoded, (UsefulBufC){"\x01\x01\xA1\x03\xA1\x04\x81\x00", 8})) {
+      return 22;
+   }
+
+   return 0;
+}
diff --git a/test/qcbor_encode_tests.h b/test/qcbor_encode_tests.h
index 1be5635..cb9f00f 100644
--- a/test/qcbor_encode_tests.h
+++ b/test/qcbor_encode_tests.h
@@ -108,7 +108,7 @@
 /*
  Encodes basic maps and arrays with indefinite length
  */
-int32_t SimpleValuesIndefiniteLengthTest1(void);
+int32_t IndefiniteLengthTest(void);
 
 
 /*
@@ -204,4 +204,7 @@
 
 #endif /* ! USEFULBUF_DISABLE_ALL_FLOAT && ! QCBOR_DISABLE_PREFERRED_FLOAT */
 
+int32_t SubStringTest(void);
+
+
 #endif /* defined(__QCBOR__qcbor_encode_tests__) */
diff --git a/test/run_tests.c b/test/run_tests.c
index 682d5e1..386da72 100644
--- a/test/run_tests.c
+++ b/test/run_tests.c
@@ -6,7 +6,7 @@
 
  SPDX-License-Identifier: BSD-3-Clause
 
- See BSD-3-Clause license in README.md
+ See BSD-3-Clause license in file named "LICENSE"
 
  Created on 9/30/18
  =============================================================================*/
@@ -158,7 +158,7 @@
    TEST_ENTRY_DISABLED(TooLargeInputTest),
    TEST_ENTRY(EncodeErrorTests),
 #ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS
-   TEST_ENTRY(SimpleValuesIndefiniteLengthTest1),
+    TEST_ENTRY(IndefiniteLengthTest),
 #endif
    TEST_ENTRY(EncodeLengthThirtyoneTest),
    TEST_ENTRY(CBORSequenceDecodeTests),
@@ -174,14 +174,14 @@
 #endif /* QCBOR_DISABLE_TAGS */
    TEST_ENTRY(ExponentAndMantissaEncodeTests),
 #endif /* QCBOR_DISABLE_EXP_AND_MANTISSA */
-   TEST_ENTRY(BoolTest),
    TEST_ENTRY(SortMapTest),
 #if !defined(USEFULBUF_DISABLE_ALL_FLOAT) && !defined(QCBOR_DISABLE_PREFERRED_FLOAT)
    TEST_ENTRY(CDETest),
    TEST_ENTRY(DCBORTest),
 #endif /* ! USEFULBUF_DISABLE_ALL_FLOAT && ! QCBOR_DISABLE_PREFERRED_FLOAT */
-   TEST_ENTRY(ParseEmptyMapInMapTest),
-
+    TEST_ENTRY(ParseEmptyMapInMapTest),
+    TEST_ENTRY(SubStringTest),
+    TEST_ENTRY(BoolTest)
 };
 
 
diff --git a/test/run_tests.h b/test/run_tests.h
index 6790710..370558a 100644
--- a/test/run_tests.h
+++ b/test/run_tests.h
@@ -5,7 +5,7 @@
 
  SPDX-License-Identifier: BSD-3-Clause
 
- See BSD-3-Clause license in README.md
+ See BSD-3-Clause license in file named "LICENSE"
 
  Created 9/30/18
  =============================================================================*/
diff --git a/ub-example.c b/ub-example.c
index 996cf3a..ec776dc 100644
--- a/ub-example.c
+++ b/ub-example.c
@@ -5,7 +5,7 @@
 
    SPDX-License-Identifier: BSD-3-Clause
 
-   See BSD-3-Clause license in README.md
+   See BSD-3-Clause license in file named "LICENSE"
 
    Created on 4/8/22
   ========================================================================== */
diff --git a/ub-example.h b/ub-example.h
index 131c807..93449f4 100644
--- a/ub-example.h
+++ b/ub-example.h
@@ -5,7 +5,7 @@
 
    SPDX-License-Identifier: BSD-3-Clause
 
-   See BSD-3-Clause license in README.md
+   See BSD-3-Clause license in file named "LICENSE"
 
    Created on 4/8/22
   ========================================================================== */