Merge branch 'CDE' of github.com:laurencelundblade/QCBOR into CDE
diff --git a/inc/qcbor/qcbor_common.h b/inc/qcbor/qcbor_common.h
index 8019d4c..819abf1 100644
--- a/inc/qcbor/qcbor_common.h
+++ b/inc/qcbor/qcbor_common.h
@@ -530,8 +530,9 @@
     */
    QCBOR_ERR_NOT_PREFERRED = 79,
 
-   /* Trying to encode something that is discouraged without
-    * allowing it by calling QCBOREncode_Allow() */
+   /* Trying to encode something that is discouraged (e.g., 65-bit
+    * negative integer) without allowing it by calling
+    * QCBOREncode_Allow() */
    QCBOR_ERR_NOT_ALLOWED = 80
 
 
diff --git a/inc/qcbor/qcbor_encode.h b/inc/qcbor/qcbor_encode.h
index a13e138..b141437 100644
--- a/inc/qcbor/qcbor_encode.h
+++ b/inc/qcbor/qcbor_encode.h
@@ -489,7 +489,12 @@
  * This mode is just a user guard to prevent accidentally calling
  * something that produces non-preferred serialization. It doesn't do
  * anything but causes errors to occur on attempts to call the above
- * listed functions. This does nothing if the library is compiled QCBOR_DISABLE_ENCODE_USAGE_GUARDS
+ * listed functions. This does nothing if the library is compiled
+ * QCBOR_DISABLE_ENCODE_USAGE_GUARDS.
+ *
+ * See @ref Serialization. It is usually not necessary to set this
+ * mode, but there is usually no issue in setting it.  Preferred
+ * Serialization is defined in RFC 8949, section 4.1.
  */
 static void
 QCBOREncode_SerializationPreferred(QCBOREncodeContext *pCtx);
@@ -500,14 +505,14 @@
  *
  * @param[in] pCtx   The encoding context for mode set.
 
- * This causes QCBOR to produce CBOR Deterministic Encoding.  With
- * CDE, two distant unrelated CBOR encoders will produce exactly the
- * same encoded CBOR for a given input. See also
- * @ref Serialization.
+ * This causes QCBOR to produce CBOR Deterministic Encoding (CDE).
+ * With CDE, two distant unrelated CBOR encoders will produce exactly
+ * the same encoded CBOR for a given input.
  *
- * In addition to doing everything QCBOREncode_SerializationPreferred()
- * does (including excluding xxx), this causes maps to be sorted. The map is sorted
- * automatically when QCBOREncode_CloseMap() is called.
+ * In addition to doing everything
+ * QCBOREncode_SerializationPreferred() does (including exclusion of
+ * indefinite lengths), this causes maps to be sorted. The map is
+ * sorted automatically when QCBOREncode_CloseMap() is called.
  * QCBOREncode_CloseMap() becomes equivalent to
  * QCBOREncode_CloseAndSortMap().
  *
@@ -515,6 +520,11 @@
  * the QCBOR library to be linked. Also, QCBOREncode_CloseMap() runs
  * slower, but this is probably only of consequence in very
  * constrained environments.
+ *
+ * See @ref Serialization. It is usually not necessary to set this
+ * mode as determinism is very rarely needed. However it will
+ * usually work with most protocols. CDE is defined in
+ * draft-ietf-cbor-cde.
  */
 static void
 QCBOREncode_SerializationCDE(QCBOREncodeContext *pCtx);
@@ -525,42 +535,71 @@
  *
  * @param[in] pCtx   The encoding context for mode set.
  *
- * This cases QCBOR to produce "dCBOR" as defined
- * in  draft-mcnally-deterministic-cbor.
+ * This is a superset of CDE. This function does everything
+ * QCBOREncode_SerializationCDE() does. Also it is a super set of
+ * preferred serialization and does everything
+ * QCBOREncode_SerializationPreferred() does.
  *
- * This is a superset of CDE and this function does everything
- * QCBOREncode_SerializationCDE() does, plus the following.
- *
- * The main feature of dCBOR that there is only one way to serialize a
+ * The main feature of dCBOR is that there is only one way to serialize a
  * particular numeric value. This changes the behavior of functions
- * that add floating point numbers.  If the floating-point number is
- * whole, it will be added as an integer, not a floating-point number.
+ * that add floating-point numbers.  If the floating-point number is
+ * whole, it will be encoded as an integer, not a floating-point number.
+ * 0.000 will be encoded as 0x00. Precision is never lost in this
+ * conversion.
  *
  * dCBOR also disallows NaN payloads. QCBOR will allow NaN payloads if
  * you pass a NaN to one of the floating-point encoding functions.
- * This mode forces all NaNs to the half-precision queit NaN. TODO:
- * should this error if an attempt is made to send a NaN payload?
-
- * dCBOR also disallows 65-bit negative integers. QCBOR doesn't
- * produce these by default.
+ * This mode forces all NaNs to the half-precision queit NaN. Also see
+ * QCBOREncode_Allow().
  *
- * dCBOR disallows use of the simple type "undef" produced by
+ * dCBOR also disallows 65-bit negative integers.
+ *
+ * dCBOR disallows use of any simple type other than true, false and
+ * NULL. In particular it disallows use of "undef" produced by
  * QCBOREncode_AddUndef().
+ *
+ * See @ref Serialization. Set this mode only if the protocol you are
+ * implementing requires dCBOR. This mode is usually not compatible
+ * with protocols that don't use dCBOR. dCBOR is defined in
+ * draft-mcnally-deterministic-cbor.
  */
 static void
 QCBOREncode_SerializationdCBOR(QCBOREncodeContext *pCtx);
 
 
-/* By default QCBOR will not encode some item values because they are
- * not very interoperable. They are allowed by the CBOR standard, but
- * almost never used. See QCBOREncode_Allow() and @ref Serialization.
- */
+
+
+/** Bit flag to be passed to QCBOREncode_Allow() to allow NaN payloads
+ *  to be output by QCBOREncode_AddDouble() and
+ *  QCBORENcode_AddFloat(). */
 #define QCBOR_ENCODE_ALLOW_NAN_PAYLOAD 0x01
+
+/** Bit flag to be passed to QCBOREncode_Allow() to allow use of
+ *  QCBOREncode_AddNegativeUInt64(). */
 #define QCBOR_ENCODE_ALLOW_65_BIG_NEG  0x02
+
+/** Bit flag to be passed to QCBOREncode_Allow() output of less
+ *  interoperable values. See @ref QCBOR_ENCODE_ALLOW_NAN_PAYLOAD, and
+ *  @ref QCBOR_ENCODE_ALLOW_65_BIG_NEG. */
 #define QCBOR_ENCODE_ALLOW_ALL         0xFF
 
 
-/* This does nothing if the library is compiled QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+/*
+ * @brief Allow encoding output of less-interoperable values.
+ *
+ * @param[in] pCtx    The encoding context.
+ * @param[in] uAllow  Bit flags indicating what to allow.
+ *
+ * There are a few things in the CBOR standard that are often not
+ * supported and are thus not very interoperable.  By default QCBOR
+ * will error if you attempt to output them.  This disables that
+ * error.
+ *
+ * See @ref QCBOR_ENCODE_ALLOW_NAN_PAYLOAD and @ref
+ * QCBOR_ENCODE_ALLOW_65_BIG_NEG.
+ *
+ * This does nothing if the library is compiled
+ * QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
 static void
 QCBOREncode_Allow(QCBOREncodeContext *pCtx, uint8_t uAllow);
 
@@ -3792,6 +3831,16 @@
 static inline void
 QCBOREncode_Private_AddSimple(QCBOREncodeContext *pMe, const uint64_t uNum)
 {
+#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
+   if(pMe->uMode >= QCBOR_ENCODE_MODE_DCBOR) {
+      if(uNum < CBOR_SIMPLEV_FALSE ||
+         uNum > CBOR_SIMPLEV_NULL) {
+         pMe->uError = QCBOR_ERR_NOT_PREFERRED;
+         return;
+      }
+   }
+#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+
    QCBOREncode_Private_AddType7(pMe, 0, uNum);
 }
 
@@ -3863,13 +3912,6 @@
 static inline void
 QCBOREncode_AddUndef(QCBOREncodeContext *pMe)
 {
-#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
-   if(pMe->uMode >= QCBOR_ENCODE_MODE_DCBOR) {
-      pMe->uError = QCBOR_ERR_NOT_PREFERRED;
-      return;
-   }
-#endif /* ! QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
-
    QCBOREncode_Private_AddSimple(pMe, CBOR_SIMPLEV_UNDEF);
 }
 
diff --git a/src/ieee754.c b/src/ieee754.c
index 4419f72..d4f1b1c 100644
--- a/src/ieee754.c
+++ b/src/ieee754.c
@@ -823,6 +823,7 @@
 }
 
 
+/* Public function; see ieee754.h */
 int
 IEEE754_IsNotStandardDoubleNaN(double d)
 {
@@ -842,7 +843,7 @@
 }
 
 
-
+/* Public function; see ieee754.h */
 int
 IEEE754_IsNotStandardSingleNaN(float f)
 {
diff --git a/src/ieee754.h b/src/ieee754.h
index 02b8a39..7d9abaf 100644
--- a/src/ieee754.h
+++ b/src/ieee754.h
@@ -184,12 +184,38 @@
 IEEE754_SingleToInt(float f);
 
 
+
+/**
+ * @brief Tests whether NaN is "quiet" vs having a payload.
+ *
+ * @param[in] dNum   Double number to test.
+ *
+ * @returns 0 if a quiet NaN, 1 if it has a payload.
+ *
+ * A quiet NaN is usually represented as 0x7ff8000000000000. That is
+ * the significand bits are 0x8000000000000. If the significand bits
+ * are other than 0x8000000000000 it is considered to have a NaN
+ * payload.
+ *
+ * Note that 0x7ff8000000000000 is not specified in a standard, but it
+ * is commonly implemented and chosen by CBOR as the best way to
+ * represent a NaN.
+ */
 int
 IEEE754_IsNotStandardDoubleNaN(double dNum);
 
 
 
-
+/**
+ * @brief Tests whether NaN is "quiet" vs having a payload.
+ *
+ * @param[in] fNum   Float number to test.
+ *
+ * @returns 0 if a quiet NaN, 1 if it has a payload.
+ *
+ * See IEEE754_IsNotStandardDoubleNaN(). A single precision quiet NaN
+ * is 0x7fc00000.
+ */
 int
 IEEE754_IsNotStandardSingleNaN(float fNum);