Merge master (what will be 1.4.2) into dev
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
  * ========================================================================== */