Big improvements in source code comments for encoding (#58)

Except for a few lines, all changes are to comments, not code. The code change are simple clarifications.

This is primarily change to the implementation comments, not to documentation of the public interface.

Co-authored-by: Laurence Lundblade <lgl@securitytheory.com>
diff --git a/src/qcbor_encode.c b/src/qcbor_encode.c
index 623b8d5..e04e21b 100644
--- a/src/qcbor_encode.c
+++ b/src/qcbor_encode.c
@@ -35,40 +35,49 @@
 #include "ieee754.h"
 
 
+/**
+ * @file qcbor_encode.c
+ * 
+ * The entire implementation of the QCBOR encoder.
+ */
+
 
 /*
- Nesting -- This tracks the nesting of maps and arrays.
-
- The following functions and data type QCBORTrackNesting implement the
- nesting management for encoding.
-
- CBOR's two nesting types, arrays and maps, are tracked here. There is
- a limit of QCBOR_MAX_ARRAY_NESTING to the number of arrays and maps
- that can be nested in one encoding so the encoding context stays
- small enough to fit on the stack.
-
- When an array / map is opened, pCurrentNesting points to the element
- in pArrays that records the type, start position and accumulates a
- count of the number of items added. When closed the start position is
- used to go back and fill in the type and number of items in the array
- / map.
-
- Encoded output can be just items like ints and strings that are not
- part of any array / map. That is, the first thing encoded does not
- have to be an array or a map.
-
- QCBOR has a special feature to allow constructing bstr-wrapped CBOR
- directly into the output buffer, so an extra buffer for it is not
- needed.  This is implemented as nesting with type
- CBOR_MAJOR_TYPE_BYTE_STRING and uses this code. Bstr-wrapped CBOR is
- used by COSE for data that is to be hashed.
+ * == Nesting Tracking ==
+ *
+ * The following functions and data type QCBORTrackNesting implement
+ * the nesting management for encoding.
+ *
+ * CBOR's two nesting types, arrays and maps, are tracked here. There
+ * is a limit of QCBOR_MAX_ARRAY_NESTING to the number of arrays and
+ * maps that can be nested in one encoding so the encoding context
+ * stays small enough to fit on the stack.
+ *
+ * When an array/map is opened, pCurrentNesting points to the element
+ * in pArrays that records the type, start position and accumulates a
+ * count of the number of items added. When closed the start position
+ * is used to go back and fill in the type and number of items in the
+ * array/map.
+ *
+ * Encoded output can be a CBOR Sequence (RFC 8742) in which case
+ * there is no top-level array or map. It starts out with a string,
+ * integer or other non-aggregate type. It may have an array or map
+ * other than at the start, in which case that nesting is tracked
+ * here.
+ *
+ * QCBOR has a special feature to allow constructing byte string
+ * wrapped CBOR directly into the output buffer, so no extra buffer is
+ * needed for byte string wrapping.  This is implemented as nesting
+ * with the type CBOR_MAJOR_TYPE_BYTE_STRING and is tracked here. Byte
+ * string wrapped CBOR is used by COSE for data that is to be hashed.
  */
 inline static void Nesting_Init(QCBORTrackNesting *pNesting)
 {
-   // Assumes pNesting has been zeroed
+   /* Assumes pNesting has been zeroed. */
    pNesting->pCurrentNesting = &pNesting->pArrays[0];
-   // Implied CBOR array at the top nesting level. This is never returned,
-   // but makes the item count work correctly.
+   /* Implied CBOR array at the top nesting level. This is never
+    * returned, but makes the item count work correctly.
+    */
    pNesting->pCurrentNesting->uMajorType = CBOR_MAJOR_TYPE_ARRAY;
 }
 
@@ -77,7 +86,6 @@
                                           uint32_t uPos)
 {
    if(pNesting->pCurrentNesting == &pNesting->pArrays[QCBOR_MAX_ARRAY_NESTING]) {
-      // Trying to open one too many
       return QCBOR_ERR_ARRAY_NESTING_TOO_DEEP;
    } else {
       pNesting->pCurrentNesting++;
@@ -108,16 +116,15 @@
 
 inline static uint16_t Nesting_GetCount(QCBORTrackNesting *pNesting)
 {
-   // The nesting count recorded is always the actual number of individiual
-   // data items in the array or map. For arrays CBOR uses the actual item
-   // count. For maps, CBOR uses the number of pairs.  This function returns
-   // the number needed for the CBOR encoding, so it divides the number of
-   // items by two for maps to get the number of pairs.  This implementation
-   // takes advantage of the map major type being one larger the array major
-   // type, hence uDivisor is either 1 or 2.
-
+   /* The nesting count recorded is always the actual number of
+    * individual data items in the array or map. For arrays CBOR uses
+    * the actual item count. For maps, CBOR uses the number of pairs.
+    * This function returns the number needed for the CBOR encoding,
+    * so it divides the number of items by two for maps to get the
+    * number of pairs.
+    */
    if(pNesting->pCurrentNesting->uMajorType == CBOR_MAJOR_TYPE_MAP) {
-      // Cast back to uint16_t after integer promotion for bit shift
+      /* Cast back to uint16_t after integer promotion from bit shift */
       return (uint16_t)(pNesting->pCurrentNesting->uCount >> 1);
    } else {
       return pNesting->pCurrentNesting->uCount;
@@ -145,71 +152,79 @@
 
 
 /*
- Encoding of the major CBOR types is by these functions:
-
- CBOR Major Type    Public Function
- 0                  QCBOREncode_AddUInt64()
- 0, 1               QCBOREncode_AddUInt64(), QCBOREncode_AddInt64()
- 2, 3               QCBOREncode_AddBuffer(), Also QCBOREncode_OpenMapOrArray(),
-                    QCBOREncode_CloseMapOrArray()
- 4, 5               QCBOREncode_OpenMapOrArray(), QCBOREncode_CloseMapOrArray(),
-                    QCBOREncode_OpenMapOrArrayIndefiniteLength(),
-                    QCBOREncode_CloseMapOrArrayIndefiniteLength()
- 6                  QCBOREncode_AddTag()
- 7                  QCBOREncode_AddDouble(), QCBOREncode_AddType7()
-
- Additionally, encoding of decimal fractions and bigfloats is by
- QCBOREncode_AddExponentAndMantissa()
-*/
-
-/*
- Error tracking plan -- Errors are tracked internally and not returned
- until QCBOREncode_Finish() or QCBOREncode_GetErrorState() is
- called. The CBOR errors are in me->uError.  UsefulOutBuf also tracks
- whether the buffer is full or not in its context.  Once either of
- these errors is set they are never cleared. Only QCBOREncode_Init()
- resets them. Or said another way, they must never be cleared or we'll
- tell the caller all is good when it is not.
-
- Only one error code is reported by QCBOREncode_Finish() even if there
- are multiple errors. The last one set wins. The caller might have to
- fix one error to reveal the next one they have to fix.  This is OK.
-
- The buffer full error tracked by UsefulBuf is only pulled out of
- UsefulBuf in QCBOREncode_Finish() so it is the one that usually wins.
- UsefulBuf will never go off the end of the buffer even if it is
- called again and again when full.
-
- QCBOR_DISABLE_ENCODE_USAGE_GUARDS disables about half of the error
- checks here to reduce code size by about 150 bytes leaving only the
- checks for size to avoid buffer overflow. If the calling code is
- completely correct, checks are completely unnecessary.  For example,
- there is no need to check that all the opens are matched by a close.
-
- 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
- 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.
-
- The 8 errors returned here fall into three categories:
-
- Sizes
-   QCBOR_ERR_BUFFER_TOO_LARGE        -- Encoded output exceeded UINT32_MAX
-   QCBOR_ERR_BUFFER_TOO_SMALL        -- Output buffer too small
-   QCBOR_ERR_ARRAY_NESTING_TOO_DEEP  -- Nesting > QCBOR_MAX_ARRAY_NESTING1
-   QCBOR_ERR_ARRAY_TOO_LONG          -- Too many items added to an array/map [1]
-
- Nesting constructed incorrectly
-   QCBOR_ERR_TOO_MANY_CLOSES         -- More close calls than opens [1]
-   QCBOR_ERR_CLOSE_MISMATCH          -- Type of close does not match open [1]
-   QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN -- Finish called without enough closes [1]
-
- Would generate not-well-formed CBOR
-   QCBOR_ERR_ENCODE_UNSUPPORTED      -- Simple type between 24 and 31 [1]
-
- [1] indicated disabled by QCBOR_DISABLE_ENCODE_USAGE_GUARDS
+ * == Major CBOR Types ==
+ *
+ * Encoding of the major CBOR types is by these functions:
+ *
+ * CBOR Major Type    Public Function
+ * 0                  QCBOREncode_AddUInt64()
+ * 0, 1               QCBOREncode_AddUInt64(), QCBOREncode_AddInt64()
+ * 2, 3               QCBOREncode_AddBuffer()
+ * 4, 5               QCBOREncode_OpenMapOrArray(), QCBOREncode_CloseMapOrArray(),
+ *                    QCBOREncode_OpenMapOrArrayIndefiniteLength(),
+ *                    QCBOREncode_CloseMapOrArrayIndefiniteLength()
+ * 6                  QCBOREncode_AddTag()
+ * 7                  QCBOREncode_AddDouble(), QCBOREncode_AddFloat(),
+ *                    QCBOREncode_AddDoubleNoPreferred(),
+ *                    QCBOREncode_AddFloatNoPreferred(), QCBOREncode_AddType7()
+ *
+ * Additionally, encoding of decimal fractions and bigfloats is by
+ * QCBOREncode_AddExponentAndMantissa() and byte strings that wrap
+ * encoded CBOR are handled by QCBOREncode_OpenMapOrArray() and
+ * QCBOREncode_CloseBstrWrap2().
+ *
+ *
+ * == Error Tracking Plan ==
+ *
+ * Errors are tracked internally and not returned until
+ * QCBOREncode_Finish() or QCBOREncode_GetErrorState() is called. The
+ * CBOR errors are in me->uError.  UsefulOutBuf also tracks whether
+ * the buffer is full or not in its context.  Once either of these
+ * errors is set they are never cleared. Only QCBOREncode_Init()
+ * resets them. Or said another way, they must never be cleared or
+ * we'll tell the caller all is good when it is not.
+ *
+ * Only one error code is reported by QCBOREncode_Finish() even if
+ * there are multiple errors. The last one set wins. The caller might
+ * have to fix one error to reveal the next one they have to fix.
+ * This is OK.
+ *
+ * The buffer full error tracked by UsefulBuf is only pulled out of
+ * UsefulBuf in QCBOREncode_Finish() so it is the one that usually
+ * wins.  UsefulBuf will never go off the end of the buffer even if it
+ * is called again and again when full.
+ *
+ * QCBOR_DISABLE_ENCODE_USAGE_GUARDS disables about half of the error
+ * checks here to reduce code size by about 150 bytes leaving only the
+ * checks for size to avoid buffer overflow. If the calling code is
+ * completely correct, checks are completely unnecessary.  For
+ * example, there is no need to check that all the opens are matched
+ * by a close.
+ *
+ * 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
+ * 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.
+ *
+ * The 8 errors returned here fall into three categories:
+ *
+ * Sizes
+ *   QCBOR_ERR_BUFFER_TOO_LARGE        -- Encoded output exceeded UINT32_MAX
+ *   QCBOR_ERR_BUFFER_TOO_SMALL        -- Output buffer too small
+ *   QCBOR_ERR_ARRAY_NESTING_TOO_DEEP  -- Nesting > QCBOR_MAX_ARRAY_NESTING1
+ *   QCBOR_ERR_ARRAY_TOO_LONG          -- Too many items added to an array/map [1]
+ *
+ * Nesting constructed incorrectly
+ *   QCBOR_ERR_TOO_MANY_CLOSES         -- More close calls than opens [1]
+ *   QCBOR_ERR_CLOSE_MISMATCH          -- Type of close does not match open [1]
+ *   QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN -- Finish called without enough closes [1]
+ *
+ * Would generate not-well-formed CBOR
+ *   QCBOR_ERR_ENCODE_UNSUPPORTED      -- Simple type between 24 and 31 [1]
+ *
+ * [1] indicated disabled by QCBOR_DISABLE_ENCODE_USAGE_GUARDS
  */
 
 
@@ -225,141 +240,201 @@
 
 
 /*
- Public function to encode a CBOR head. See qcbor/qcbor_encode.h
+ * Public function to encode a CBOR head. See qcbor/qcbor_encode.h
  */
 UsefulBufC QCBOREncode_EncodeHead(UsefulBuf buffer,
                                   uint8_t   uMajorType,
                                   uint8_t   uMinLen,
                                   uint64_t  uArgument)
 {
-   /**
-    All CBOR data items have a type and an "argument". The argument is
-    either the value of the item for integer types, the length of the
-    content for string, byte, array and map types, a tag for major type
-    6, and has several uses for major type 7.
-
-    This function encodes the type and the argument. There are several
-    encodings for the argument depending on how large it is and how it is
-    used.
-
-    Every encoding of the type and argument has at least one byte, the
-    "initial byte".
-
-    The top three bits of the initial byte are the major type for the
-    CBOR data item.  The eight major types defined by the standard are
-    defined as CBOR_MAJOR_TYPE_xxxx in qcbor/qcbor_common.h.
-
-    The remaining five bits, known as "additional information", and
-    possibly more bytes encode the argument. If the argument is less than
-    24, then it is encoded entirely in the five bits. This is neat
-    because it allows you to encode an entire CBOR data item in 1 byte
-    for many values and types (integers 0-23, true, false, and tags).
-
-    If the argument is larger than 24, then it is encoded in 1,2,4 or 8
-    additional bytes, with the number of these bytes indicated by the
-    values of the 5 bits 24, 25, 25 and 27.
-
-    It is possible to encode a particular argument in many ways with this
-    representation.  This implementation always uses the smallest
-    possible representation. This conforms with CBOR preferred encoding.
-
-    This function inserts them into the output buffer at the specified
-    position. AppendEncodedTypeAndNumber() appends to the end.
-
-    This function takes care of converting to network byte order.
-
-    This function is also used to insert floats and doubles. Before this
-    function is called the float or double must be copied into a
-    uint64_t. That is how they are passed in. They are then converted to
-    network byte order correctly. The uMinLen parameter makes sure that
-    even if all the digits of a half, float or double are 0 it is still
-    correctly encoded in 2, 4 or 8 bytes.
-    */
    /*
-    This code does endian conversion without hton or knowing the
-    endianness of the machine using masks and shifts. This avoids the
-    dependency on hton and the mess of figuring out how to find the
-    machine's endianness.
-
-    This is a good efficient implementation on little-endian machines.
-    A faster and small implementation is possible on big-endian
-    machines because CBOR/network byte order is big endian. However
-    big endian machines are uncommon.
-
-    On x86, it is about 200 bytes instead of 500 bytes for the more
-    formal unoptimized code.
-
-    This also does the CBOR preferred shortest encoding for integers
-    and is called to do endian conversion for floats.
-
-    It works backwards from the LSB to the MSB as needed.
-
-    Code Reviewers: THIS FUNCTION DOES POINTER MATH
-    */
-   /*
-    The type int is used here for several variables because of the way
-    integer promotion works in C for integer variables that are
-    uint8_t or uint16_t. The basic rule is that they will always be
-    promoted to int if they will fit. All of these integer variables
-    need only hold values less than 255 or are promoted from uint8_t,
-    so they will always fit into an int. Note that promotion is only
-    to unsigned int if the value won't fit into an int even if the
-    promotion is for an unsigned like uint8_t.
-
-    By declaring them int, there are few implicit conversions and fewer
-    casts needed. Code size is reduced a little. It also makes static
-    analyzers happier.
-
-    Note also that declaring them uint8_t won't stop integer wrap
-    around if the code is wrong. It won't make the code more correct.
-
-    https://stackoverflow.com/questions/46073295/implicit-type-promotion-rules
-    https://stackoverflow.com/questions/589575/what-does-the-c-standard-state-the-size-of-int-long-type-to-be
+    * == Description of the CBOR Head ==
+    *
+    *    The head of a CBOR data item
+    *  +---+-----+ +--------+ +--------+ +--------+      +--------+
+    *  |M T|  A R G U M E N T . . .                               |
+    *  +---+-----+ +--------+ +--------+ +--------+ ...  +--------+
+    *
+    * Every CBOR data item has a "head". It is made up of the "major
+    * type" and the "argument".
+    *
+    * The major type indicates whether the data item is an integer,
+    * string, array or such. It is encoded in 3 bits giving it a range
+    * from 0 to 7.  0 indicates the major type is a positive integer,
+    * 1 a negative integer, 2 a byte string and so on.
+    *
+    * These 3 bits are the first part of the "initial byte" in a data
+    * item.  Every data item has an initial byte, and some only have
+    * the initial byte.
+    *
+    * The argument is essentially a number between 0 and UINT64_MAX
+    * (18446744073709551615). This number is interpreted to mean
+    * different things for the different major types. For major type
+    * 0, a positive integer, it is value of the data item. For major
+    * type 2, a byte string, it is the length in bytes of the byte
+    * string. For major type 4, an array, it is the number of data
+    * items in the array.
+    *
+    * Special encoding is used so that the argument values less than
+    * 24 can be encoded very compactly in the same byte as the major
+    * type is encoded. When the lower 5 bits of the initial byte have
+    * a value less than 24, then that is the value of the argument.
+    *
+    * If the lower 5 bits of the initial byte are less than 24, then
+    * they are the value of the argument. This allows integer values 0
+    * - 23 to be CBOR encoded in just one byte.
+    *
+    * When the value of lower 5 bits are 24, 25, 26, or 27 the
+    * argument is encoded in 1, 2, 4 or 8 bytes following the initial
+    * byte in network byte order (bit endian). The cases when it is
+    * 28, 29 and 30 are reserved for future use. The value 31 is a
+    * special indicator for indefinite length strings, arrays and
+    * maps.
+    *
+    * The lower 5 bits are called the "additional information."
+    *
+    * Thus the CBOR head may be 1, 2, 3, 5 or 9 bytes long.
+    *
+    * It is legal in CBOR to encode the argument using any of these
+    * lengths even if it could be encoded in a shorter length. For
+    * example it is legal to encode a data item representing the
+    * positive integer 0 in 9 bytes even though it could be encoded in
+    * only 0. This is legal to allow for for very simple code or even
+    * hardware-only implementations that just output a register
+    * directly.
+    *
+    * CBOR defines preferred encoding as the encoding of the argument
+    * in the smallest number of bytes needed to encode it.
+    *
+    * This function takes the major type and argument as inputs and
+    * outputs the encoded CBOR head for them. It does conversion to
+    * network byte order.  It implements CBOR preferred encoding,
+    * outputting the shortest representation of the argument.
+    *
+    * == Endian Conversion ==
+    *
+    * This code does endian conversion without hton() or knowing the
+    * endianness of the machine by using masks and shifts. This avoids
+    * the dependency on hton() and the mess of figuring out how to
+    * find the machine's endianness.
+    *
+    * This is a good efficient implementation on little-endian
+    * machines.  A faster and smaller implementation is possible on
+    * big-endian machines because CBOR/network byte order is
+    * big-endian. However big-endian machines are uncommon.
+    *
+    * On x86, this is about 150 bytes instead of 500 bytes for the
+    * original, more formal unoptimized code.
+    *
+    * This also does the CBOR preferred shortest encoding for integers
+    * and is called to do endian conversion for floats.
+    *
+    * It works backwards from the least significant byte to the most
+    * significant byte.
+    *
+    * == Floating Point ==
+    *
+    * When the major type is 7 and the 5 lower bits have the values
+    * 25, 26 or 27, the argument is a floating-point number that is
+    * half, single or double-precision. Note that it is not the
+    * conversion from a floating-point value to an integer value like
+    * converting 0x00 to 0.00, it is the interpretation of the bits in
+    * the argument as an IEEE 754 float-point number.
+    *
+    * Floating-point numbers must be converted to network byte
+    * order. That is accomplished here by exactly the same code that
+    * converts integer arguments to network byte order.
+    *
+    * There is preferred encoding for floating-point numbers in CBOR,
+    * but it is very different than for integers and it is not
+    * implemented here.  Half-precision is preferred to
+    * single-precision which is preferred to double-precision only if
+    * the conversion can be performed without loss of precision. Zero
+    * and infinity can always be converted to half-precision, without
+    * loss but 3.141592653589 cannot.
+    *
+    * The way this function knows to not do preferred encoding on the
+    * argument passed here when it is a floating point number is the
+    * uMinLen parameter. It should be 2, 4 or 8 for half, single and
+    * double precision floating point values. This prevents and the
+    * incorrect removal of leading zeros when encoding arguments that
+    * are floating-point numbers.
+    *
+    * == Use of Type int and Static Analyzers ==
+    *
+    * The type int is used here for several variables because of the
+    * way integer promotion works in C for variables that are uint8_t
+    * or uint16_t. The basic rule is that they will always be promoted
+    * to int if they will fit. These integer variables here need only
+    * hold values less than 255 so they will always fit into an int.
+    *
+    * Most of values stored are never negative, so one might think
+    * that unsigned int would be more correct than int. However the C
+    * integer promotion rules only promote to unsigned int if the
+    * result won't fit into an int even if the promotion is for an
+    * unsigned variable like uint8_t.
+    *
+    * By declaring these int, there are few implicit conversions and
+    * fewer casts needed. Code size is reduced a little. It makes
+    * static analyzers happier.
+    *
+    * Note also that declaring these uint8_t won't stop integer wrap
+    * around if the code is wrong. It won't make the code more
+    * correct.
+    *
+    * https://stackoverflow.com/questions/46073295/implicit-type-promotion-rules
+    * https://stackoverflow.com/questions/589575/what-does-the-c-standard-state-the-size-of-int-long-type-to-be
+    *
+    * Code Reviewers: THIS FUNCTION DOES POINTER MATH
     */
 
-   // Buffer must have room for the largest CBOR HEAD + one extra as the
-   // one extra is needed for this code to work as it does a pre-decrement.
+   /* The buffer must have room for the largest CBOR HEAD + one
+    * extra. The one extra is needed for this code to work as it does
+    * a pre-decrement.
+    */
     if(buffer.len < QCBOR_HEAD_BUFFER_SIZE) {
         return NULLUsefulBufC;
     }
 
-   // Pointer to last valid byte in the buffer
+   /* Pointer to last valid byte in the buffer */
    uint8_t * const pBufferEnd = &((uint8_t *)buffer.ptr)[QCBOR_HEAD_BUFFER_SIZE-1];
 
-   // Point to the last byte and work backwards
+   /* Point to the last byte and work backwards */
    uint8_t *pByte = pBufferEnd;
-   // The 5 bits in the initial byte that are not the major type
+   /* The 5 bits in the initial byte that are not the major type */
    int nAdditionalInfo;
 
    if(uMajorType > QCBOR_INDEFINITE_LEN_TYPE_MODIFIER) {
-      // Special case for start & end of indefinite length
+      /* Special case for start & end of indefinite length */
       uMajorType  = uMajorType - QCBOR_INDEFINITE_LEN_TYPE_MODIFIER;
-      // Take advantage of design of CBOR where additional info
-      // is 31 for both opening and closing indefinite length
-      // maps and arrays.
-#if CBOR_SIMPLE_BREAK != LEN_IS_INDEFINITE
-#error additional info for opening array not the same as for closing
-#endif
+      /* This takes advantage of design of CBOR where additional info
+       * is 31 for both opening and closing indefinite length
+       * maps and arrays.
+       */
+       #if CBOR_SIMPLE_BREAK != LEN_IS_INDEFINITE
+       #error additional info for opening array not the same as for closing
+       #endif
       nAdditionalInfo = CBOR_SIMPLE_BREAK;
+
    } else if (uArgument < CBOR_TWENTY_FOUR && uMinLen == 0) {
-      // Simple case where argument is < 24
+      /* Simple case where argument is < 24 */
       nAdditionalInfo = (int)uArgument;
+
    } else  {
-      /*
-       Encode argument in 1,2,4 or 8 bytes. Outer loop
-       runs once for 1 byte and 4 times for 8 bytes.
-       Inner loop runs 1, 2 or 4 times depending on
-       outer loop counter. This works backwards taking
-       8 bits off the argument being encoded at a time
-       until all bits from uNumber have been encoded
-       and the minimum encoding size is reached.
-       Minimum encoding size is for floating point
-       numbers with zero bytes.
+      /* This encodes the argument in 1,2,4 or 8 bytes. The outer loop
+       * runs once for 1 byte and 4 times for 8 bytes.  The inner loop
+       * runs 1, 2 or 4 times depending on outer loop counter. This
+       * works backwards shifting 8 bits off the argument being
+       * encoded at a time until all bits from uArgument have been
+       * encoded and the minimum encoding size is reached.  Minimum
+       * encoding size is for floating-point numbers that have some
+       * zero-value bytes that must be output.
        */
       static const uint8_t aIterate[] = {1,1,2,4};
 
-      // The parameter passed in is unsigned, but goes negative in the loop
-      // so it must be converted to a signed value.
+      /* uMinLen passed in is unsigned, but goes negative in the loop
+       * so it must be converted to a signed value.
+       */
       int nMinLen = (int)uMinLen;
       int i;
       for(i = 0; uArgument || nMinLen > 0; i++) {
@@ -370,51 +445,51 @@
          }
          nMinLen -= nIterations;
       }
-      // Additional info is the encoding of the number of additional
-      // bytes to encode argument.
+
       nAdditionalInfo = LEN_IS_ONE_BYTE-1 + i;
    }
 
-   /*
-    This expression integer-promotes to type int. The code above in
-    function guarantees that nAdditionalInfo will never be larger than
-    0x1f. The caller may pass in a too-large uMajor type. The
-    conversion to unint8_t will cause an integer wrap around and
-    incorrect CBOR will be generated, but no security issue will
-    occur.
+   /* This expression integer-promotes to type int. The code above in
+    * function guarantees that nAdditionalInfo will never be larger
+    * than 0x1f. The caller may pass in a too-large uMajor type. The
+    * conversion to unint8_t will cause an integer wrap around and
+    * incorrect CBOR will be generated, but no security issue will
+    * occur.
     */
-   *--pByte = (uint8_t)((uMajorType << 5) + nAdditionalInfo);
+   const int nInitialByte = (uMajorType << 5) + nAdditionalInfo;
+   *--pByte = (uint8_t)nInitialByte;
 
 #ifdef EXTRA_ENCODE_HEAD_CHECK
-   /* This is a sanity check that can be turned on to verify the pointer
-    * math in this function is not going wrong. Turn it on and run the
-    * whole test suite to perform the check.
+   /* This is a sanity check that can be turned on to verify the
+    * pointer math in this function is not going wrong. Turn it on and
+    * run the whole test suite to perform the check.
     */
    if(pBufferEnd - pByte > 9 || pBufferEnd - pByte < 1 || pByte < (uint8_t *)buffer.ptr) {
       return NULLUsefulBufC;
    }
 #endif
 
-   // Length will not go negative because the loops run for at most 8 decrements
-   // of pByte, only one other decrement is made, and the array is sized
-   // for this.
+   /* Length will not go negative because the loops run for at most 8 decrements
+    * of pByte, only one other decrement is made, and the array is sized
+    * for this.
+    */
    return (UsefulBufC){pByte, (size_t)(pBufferEnd - pByte)};
 }
 
 
 /**
- @brief Append the CBOR head, the major type and argument
-
- @param me          Encoder context.
- @param uMajorType  Major type to insert.
- @param uArgument   The argument (an integer value or a length).
- @param uMinLen     The minimum number of bytes for encoding the CBOR argument.
-
- This formats the CBOR "head" and appends it to the output.
+ * @brief Append the CBOR head, the major type and argument
+ *
+ * @param me          Encoder context.
+ * @param uMajorType  Major type to insert.
+ * @param uArgument   The argument (an integer value or a length).
+ * @param uMinLen     The minimum number of bytes for encoding the CBOR argument.
+ *
+ * This formats the CBOR "head" and appends it to the output.
  */
 static void AppendCBORHead(QCBOREncodeContext *me, uint8_t uMajorType,  uint64_t uArgument, uint8_t uMinLen)
 {
-   // A stack buffer large enough for a CBOR head
+   /* A stack buffer large enough for a CBOR head */
    UsefulBuf_MAKE_STACK_UB  (pBufferForEncodedHead, QCBOR_HEAD_BUFFER_SIZE);
 
    UsefulBufC EncodedHead = QCBOREncode_EncodeHead(pBufferForEncodedHead,
@@ -423,10 +498,10 @@
                                                     uArgument);
 
    /* No check for EncodedHead == NULLUsefulBufC is performed here to
-    * save object code. It is very clear that pBufferForEncodedHead
-    * is the correct size. If EncodedHead == NULLUsefulBufC then
-    * UsefulOutBuf_AppendUsefulBuf() will do nothing so there is
-    * no security hole introduced.
+    * save object code. It is very clear that pBufferForEncodedHead is
+    * the correct size. If EncodedHead == NULLUsefulBufC then
+    * UsefulOutBuf_AppendUsefulBuf() will do nothing so there is no
+    * security hole introduced.
     */
 
    UsefulOutBuf_AppendUsefulBuf(&(me->OutBuf), EncodedHead);
@@ -434,15 +509,15 @@
 
 
 /**
- @brief Insert the CBOR head for a map, array or wrapped bstr
-
- @param me          QCBOR encoding context.
- @param uMajorType  One of CBOR_MAJOR_TYPE_XXXX.
- @param uLen        The length of the data item.
-
- When an array, map or bstr was opened, nothing was done but note
- the position. This function goes back to that position and inserts
- the CBOR Head with the major type and length.
+ * @brief Insert the CBOR head for a map, array or wrapped bstr
+ *
+ * @param me          QCBOR encoding context.
+ * @param uMajorType  One of CBOR_MAJOR_TYPE_XXXX.
+ * @param uLen        The length of the data item.
+ *
+ * When an array, map or bstr was opened, nothing was done but note
+ * the position. This function goes back to that position and inserts
+ * the CBOR Head with the major type and length.
  */
 static void InsertCBORHead(QCBOREncodeContext *me, uint8_t uMajorType, size_t uLen)
 {
@@ -458,7 +533,7 @@
    }
 #endif /* QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
 
-   // A stack buffer large enough for a CBOR head
+   /* A stack buffer large enough for a CBOR head */
    UsefulBuf_MAKE_STACK_UB(pBufferForEncodedHead, QCBOR_HEAD_BUFFER_SIZE);
 
    UsefulBufC EncodedHead = QCBOREncode_EncodeHead(pBufferForEncodedHead,
@@ -467,10 +542,10 @@
                                                    uLen);
 
    /* No check for EncodedHead == NULLUsefulBufC is performed here to
-    * save object code. It is very clear that pBufferForEncodedHead
-    * is the correct size. If EncodedHead == NULLUsefulBufC then
-    * UsefulOutBuf_InsertUsefulBuf() will do nothing so there is
-    * no security whole introduced.
+    * save object code. It is very clear that pBufferForEncodedHead is
+    * the correct size. If EncodedHead == NULLUsefulBufC then
+    * UsefulOutBuf_InsertUsefulBuf() will do nothing so there is no
+    * security whole introduced.
     */
    UsefulOutBuf_InsertUsefulBuf(&(me->OutBuf),
                                 EncodedHead,
@@ -480,10 +555,13 @@
 }
 
 
-/*
- Increment the count of items in a map or array. This is mostly
- a separate function to have fewer occurance of
- #ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
+/**
+ * @brief Increment item counter for maps and arrays.
+ *
+ * @param pMe          QCBOR encoding context.
+ *
+ * This is mostly a separate function to make code more readable and
+ * to have fewer occurrences of #ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
  */
 static inline void IncrementMapOrArrayCount(QCBOREncodeContext *pMe)
 {
@@ -498,7 +576,7 @@
 
 
 /*
- Public functions for adding integers. See qcbor/qcbor_encode.h
+ * Public functions for adding unsigned integers. See qcbor/qcbor_encode.h
  */
 void QCBOREncode_AddUInt64(QCBOREncodeContext *me, uint64_t uValue)
 {
@@ -509,15 +587,15 @@
 
 
 /*
- Public functions for adding unsigned. See qcbor/qcbor_encode.h
+ * Public functions for adding signed integers. See qcbor/qcbor_encode.h
  */
 void QCBOREncode_AddInt64(QCBOREncodeContext *me, int64_t nNum)
 {
-   uint8_t      uMajorType;
-   uint64_t     uValue;
+   uint8_t  uMajorType;
+   uint64_t uValue;
 
    if(nNum < 0) {
-      // In CBOR -1 encodes as 0x00 with major type negative int.
+      /* In CBOR -1 encodes as 0x00 with major type negative int. */
       uValue = (uint64_t)(-nNum - 1);
       uMajorType = CBOR_MAJOR_TYPE_NEGATIVE_INT;
    } else {
@@ -531,28 +609,29 @@
 
 
 /*
- Semi-private function. It is exposed to user of the interface, but
- they will usually call one of the inline wrappers rather than this.
+ * Semi-private function. It is exposed to user of the interface, but
+ * one of its inline wrappers will usually be called instead of this.
+ *
+ * See qcbor/qcbor_encode.h
+ *
+ * This does the work of adding actual strings bytes to the CBOR
+ * output (as opposed to adding numbers and opening / closing
+ * aggregate types).
 
- See qcbor/qcbor_encode.h
-
- Does the work of adding actual strings bytes to the CBOR output (as
- opposed to numbers and opening / closing aggregate types).
-
- There are four use cases:
-   CBOR_MAJOR_TYPE_BYTE_STRING -- Byte strings
-   CBOR_MAJOR_TYPE_TEXT_STRING -- Text strings
-   CBOR_MAJOR_NONE_TYPE_RAW -- Already-encoded CBOR
-   CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY -- Special case
-
- The first two add the type and length plus the actual bytes. The
- third just adds the bytes as the type and length are presumed to be
- in the bytes. The fourth just adds the type and length for the very
- special case of QCBOREncode_AddBytesLenOnly().
+ * There are four use cases:
+ *   CBOR_MAJOR_TYPE_BYTE_STRING -- Byte strings
+ *   CBOR_MAJOR_TYPE_TEXT_STRING -- Text strings
+ *   CBOR_MAJOR_NONE_TYPE_RAW -- Already-encoded CBOR
+ *   CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY -- Special case
+ *
+ * The first two add the head plus the actual bytes. The third just
+ * adds the bytes as the heas is presumed to be in the bytes. The
+ * fourth just adds the head for the very special case of
+ * QCBOREncode_AddBytesLenOnly().
  */
 void QCBOREncode_AddBuffer(QCBOREncodeContext *me, uint8_t uMajorType, UsefulBufC Bytes)
 {
-   // If it is not Raw CBOR, add the type and the length
+   /* If it is not Raw CBOR, add the type and the length */
    if(uMajorType != CBOR_MAJOR_NONE_TYPE_RAW) {
       uint8_t uRealMajorType = uMajorType;
       if(uRealMajorType == CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY) {
@@ -562,7 +641,7 @@
    }
 
    if(uMajorType != CBOR_MAJOR_NONE_TYPE_BSTR_LEN_ONLY) {
-      // Actually add the bytes
+      /* Actually add the bytes */
       UsefulOutBuf_AppendUsefulBuf(&(me->OutBuf), Bytes);
    }
 
@@ -571,7 +650,7 @@
 
 
 /*
- Public functions for adding a tag. See qcbor/qcbor_encode.h
+ * Public functions for adding a tag. See qcbor/qcbor_encode.h
  */
 void QCBOREncode_AddTag(QCBOREncodeContext *me, uint64_t uTag)
 {
@@ -580,10 +659,10 @@
 
 
 /*
- Semi-private function. It is exposed to user of the interface,
- but they will usually call one of the inline wrappers rather than this.
-
- See header qcbor/qcbor_encode.h
+ * Semi-private function. It is exposed to user of the interface, but
+ * one of its inline wrappers will usually be called instead of this.
+ *
+ * See header qcbor/qcbor_encode.h
  */
 void QCBOREncode_AddType7(QCBOREncodeContext *me, uint8_t uMinLen, uint64_t uNum)
 {
@@ -596,7 +675,7 @@
    }
 #endif /* QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
 
-   // AppendHead() does endian swapping for the float / double
+   /* AppendCBORHead() does endian swapping for the float / double */
    AppendCBORHead(me, CBOR_MAJOR_TYPE_SIMPLE, uNum, uMinLen);
    
    IncrementMapOrArrayCount(me);
@@ -604,8 +683,8 @@
 
 
 /*
- Public functions for adding a double. See qcbor/qcbor_encode.h
-*/
+ * Public functions for adding a double. See qcbor/qcbor_encode.h
+ */
 void QCBOREncode_AddDoubleNoPreferred(QCBOREncodeContext *me, double dNum)
 {
    QCBOREncode_AddType7(me,
@@ -615,7 +694,7 @@
 
 
 /*
- Public functions for adding a double. See qcbor/qcbor_encode.h
+ * Public functions for adding a double. See qcbor/qcbor_encode.h
  */
 void QCBOREncode_AddDouble(QCBOREncodeContext *me, double dNum)
 {
@@ -630,8 +709,8 @@
 
 
 /*
- Public functions for adding a float. See qcbor/qcbor_encode.h
-*/
+ * Public functions for adding a float. See qcbor/qcbor_encode.h
+ */
 void QCBOREncode_AddFloatNoPreferred(QCBOREncodeContext *me, float fNum)
 {
    QCBOREncode_AddType7(me,
@@ -641,7 +720,7 @@
 
 
 /*
- Public functions for adding a float. See qcbor/qcbor_encode.h
+ * Public functions for adding a float. See qcbor/qcbor_encode.h
  */
 void QCBOREncode_AddFloat(QCBOREncodeContext *me, float fNum)
 {
@@ -657,14 +736,15 @@
 
 #ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
 /*
- Semi-public function. It is exposed to the user of the interface, but
- one of the inline wrappers will usually be called rather than this.
-
- See qcbor/qcbor_encode.h
-
- Improvement: create another version of this that only
- takes a big number mantissa and converts the output to
- a type 0 or 1 integer when mantissa is small enough.
+ * Semi-public function. It is exposed to the user of the interface,
+ * but one of the inline wrappers will usually be called rather than
+ * this.
+ *
+ * See qcbor/qcbor_encode.h
+ *
+ * Improvement: create another version of this that only takes a big
+ * number mantissa and converts the output to a type 0 or 1 integer
+ * when mantissa is small enough.
  */
 void QCBOREncode_AddExponentAndMantissa(QCBOREncodeContext *pMe,
                                         uint64_t            uTag,
@@ -673,12 +753,11 @@
                                         int64_t             nMantissa,
                                         int64_t             nExponent)
 {
-   /*
-    This is for encoding either a big float or a decimal fraction,
-    both of which are an array of two items, an exponent and a
-    mantissa.  The difference between the two is that the exponent is
-    base-2 for big floats and base-10 for decimal fractions, but that
-    has no effect on the code here.
+   /* This is for encoding either a big float or a decimal fraction,
+    * both of which are an array of two items, an exponent and a
+    * mantissa.  The difference between the two is that the exponent
+    * is base-2 for big floats and base-10 for decimal fractions, but
+    * that has no effect on the code here.
     */
    if(uTag != CBOR_TAG_INVALID64) {
       QCBOREncode_AddTag(pMe, uTag);
@@ -700,64 +779,67 @@
 
 
 /*
- Semi-public function. It is exposed to user of the interface,
- but they will usually call one of the inline wrappers rather than this.
-
- See qcbor/qcbor_encode.h
+ * Semi-public function. It is exposed to the user of the interface,
+ * but one of the inline wrappers will usually be called rather than
+ * this.
+ *
+ * See qcbor/qcbor_encode.h
 */
 void QCBOREncode_OpenMapOrArray(QCBOREncodeContext *me, uint8_t uMajorType)
 {
-   // Add one item to the nesting level we are in for the new map or array
+   /* Add one item to the nesting level we are in for the new map or array */
    IncrementMapOrArrayCount(me);
 
-   /*
-    The offset where the length of an array or map will get written
-    is stored in a uint32_t, not a size_t to keep stack usage
-    smaller. This checks to be sure there is no wrap around when
-    recording the offset.  Note that on 64-bit machines CBOR larger
-    than 4GB can be encoded as long as no array / map offsets occur
-    past the 4GB mark, but the public interface says that the
-    maximum is 4GB to keep the discussion simpler.
-   */
+   /* The offset where the length of an array or map will get written
+    * is stored in a uint32_t, not a size_t to keep stack usage
+    * smaller. This checks to be sure there is no wrap around when
+    * recording the offset.  Note that on 64-bit machines CBOR larger
+    * than 4GB can be encoded as long as no array/map offsets occur
+    * past the 4GB mark, but the public interface says that the
+    * maximum is 4GB to keep the discussion simpler.
+    */
    size_t uEndPosition = UsefulOutBuf_GetEndPosition(&(me->OutBuf));
 
-   /*
-    QCBOR_MAX_ARRAY_OFFSET is slightly less than UINT32_MAX so this
-    code can run on a 32-bit machine and tests can pass on a 32-bit
-    machine. If it was exactly UINT32_MAX, then this code would not
-    compile or run on a 32-bit machine and an #ifdef or some
-    machine size detection would be needed reducing portability.
-   */
+   /* QCBOR_MAX_ARRAY_OFFSET is slightly less than UINT32_MAX so this
+    * code can run on a 32-bit machine and tests can pass on a 32-bit
+    * machine. If it was exactly UINT32_MAX, then this code would not
+    * compile or run on a 32-bit machine and an #ifdef or some machine
+    * size detection would be needed reducing portability.
+    */
    if(uEndPosition >= QCBOR_MAX_ARRAY_OFFSET) {
       me->uError = QCBOR_ERR_BUFFER_TOO_LARGE;
 
    } else {
-      // Increase nesting level because this is a map or array.  Cast
-      // from size_t to uin32_t is safe because of check above
+      /* Increase nesting level because this is a map or array.  Cast
+       * from size_t to uin32_t is safe because of check above.
+       */
       me->uError = Nesting_Increase(&(me->nesting), uMajorType, (uint32_t)uEndPosition);
    }
 }
 
 
 /*
- Semi-public function. It is exposed to user of the interface,
- but they will usually call one of the inline wrappers rather than this.
-
- See qcbor/qcbor_encode.h
-*/
+ * Semi-public function. It is exposed to the user of the interface,
+ * but one of the inline wrappers will usually be called rather than
+ * this.
+ *
+ * See qcbor/qcbor_encode.h
+ */
 void QCBOREncode_OpenMapOrArrayIndefiniteLength(QCBOREncodeContext *me, uint8_t uMajorType)
 {
-   // Insert the indefinite length marker (0x9f for arrays, 0xbf for maps)
+   /* Insert the indefinite length marker (0x9f for arrays, 0xbf for maps) */
    AppendCBORHead(me, uMajorType, 0, 0);
-   // Call the definite-length opener just to do the bookkeeping for
-   // nesting.  It will record the position of the opening item in
-   // the encoded output but this is not used when closing this open.
+
+   /* Call the definite-length opener just to do the bookkeeping for
+    * nesting.  It will record the position of the opening item in the
+    * encoded output but this is not used when closing this open.
+    */
    QCBOREncode_OpenMapOrArray(me, uMajorType);
 }
 
 
 /*
- Public functions for closing arrays and maps. See qcbor/qcbor_encode.h
+ * Public functions for closing arrays and maps. See qcbor/qcbor_encode.h
  */
 void QCBOREncode_CloseMapOrArray(QCBOREncodeContext *me, uint8_t uMajorType)
 {
@@ -766,33 +848,34 @@
 
 
 /*
- Public functions for closing bstr wrapping. See qcbor/qcbor_encode.h
+ * Public functions for closing bstr wrapping. See qcbor/qcbor_encode.h
  */
 void QCBOREncode_CloseBstrWrap2(QCBOREncodeContext *me, bool bIncludeCBORHead, UsefulBufC *pWrappedCBOR)
 {
    const size_t uInsertPosition = Nesting_GetStartPos(&(me->nesting));
    const size_t uEndPosition    = UsefulOutBuf_GetEndPosition(&(me->OutBuf));
 
-   // This can't go negative because the UsefulOutBuf always only grows
-   // and never shrinks. UsefulOutBut itself also has defenses such that
-   // it won't write where it should not even if given hostile input lengths.
+   /* This subtraction can't go negative because the UsefulOutBuf
+    * always only grows and never shrinks. UsefulOutBut itself also
+    * has defenses such that it won't write where it should not even
+    * if given incorrect input lengths.
+    */
    const size_t uBstrLen = uEndPosition - uInsertPosition;
 
-   // Actually insert
+   /* Actually insert */
    InsertCBORHead(me, CBOR_MAJOR_TYPE_BYTE_STRING, uBstrLen);
 
    if(pWrappedCBOR) {
-      /*
-       Return pointer and length to the enclosed encoded CBOR. The
-       intended use is for it to be hashed (e.g., SHA-256) in a COSE
-       implementation.  This must be used right away, as the pointer
-       and length go invalid on any subsequent calls to this function
-       because there might be calls to InsertEncodedTypeAndNumber()
-       that slides data to the right.
+      /* Return pointer and length to the enclosed encoded CBOR. The
+       * intended use is for it to be hashed (e.g., SHA-256) in a COSE
+       * implementation.  This must be used right away, as the pointer
+       * and length go invalid on any subsequent calls to this
+       * function because there might be calls to
+       * InsertEncodedTypeAndNumber() that slides data to the right.
        */
       size_t uStartOfNew = uInsertPosition;
       if(!bIncludeCBORHead) {
-         // Skip over the CBOR head to just get the inserted bstr
+         /* Skip over the CBOR head to just get the inserted bstr */
          const size_t uNewEndPosition = UsefulOutBuf_GetEndPosition(&(me->OutBuf));
          uStartOfNew += uNewEndPosition - uEndPosition;
       }
@@ -803,7 +886,7 @@
 
 
 /*
- Public functions for closing arrays and maps. See qcbor/qcbor_encode.h
+ * Public functions for closing arrays and maps. See qcbor/qcbor_encode.h
  */
 void QCBOREncode_CloseMapOrArrayIndefiniteLength(QCBOREncodeContext *me, uint8_t uMajorType)
 {
@@ -821,14 +904,14 @@
    (void) uMajorType;
 #endif
 
-   // Append the break marker (0xff for both arrays and maps)
+   /* Append the break marker (0xff for both arrays and maps) */
    AppendCBORHead(me, CBOR_MAJOR_NONE_TYPE_SIMPLE_BREAK, CBOR_SIMPLE_BREAK, 0);
    Nesting_Decrease(&(me->nesting));
 }
 
 
 /*
- Public functions to finish and get the encoded result. See qcbor/qcbor_encode.h
+ * Public functions to finish and get the encoded result. See qcbor/qcbor_encode.h
  */
 QCBORError QCBOREncode_Finish(QCBOREncodeContext *me, UsefulBufC *pEncodedCBOR)
 {
@@ -853,7 +936,7 @@
 
 
 /*
- Public functions to finish and get the encoded result. See qcbor/qcbor_encode.h
+ * Public functions to get size of the encoded result. See qcbor/qcbor_encode.h
  */
 QCBORError QCBOREncode_FinishGetSize(QCBOREncodeContext *me, size_t *puEncodedLen)
 {