Titles and cross-references for documentation
diff --git a/doc/Tagging.md b/doc/Tagging.md
index 4ba5ea2..cdd9756 100644
--- a/doc/Tagging.md
+++ b/doc/Tagging.md
@@ -1,7 +1,7 @@
-#  Types and Tagging in CBOR
-
 @anchor CBORTags
 
+#  Types and Tagging in CBOR
+
 ## New Types
 
 CBOR provides a means for defining new data types beyond the primitive
@@ -28,7 +28,7 @@
 times. This is not true.
 
 As stated above, a tag is exactly a tag number and a single data item
-that is the tag content. It's purpose in the encoded CBOR is to
+that is the tag content. Its purpose in the encoded CBOR is to
 indicate something is of a data type. Ignoring it would be like
 ignoring a typedef or struct in C.
 
@@ -76,7 +76,7 @@
 accept", current wisdom is somewhat the opposite.
 
 
-## Types and Tags in QCBOR 
+## Types and Tags in QCBOR
 
 QCBOR explicitly supports all the tags defined in RFC 7049. It has
 specific APIs and data structures for encoding and decoding them.
@@ -194,7 +194,7 @@
     22 Hint that content should be base64 encoded
     23 Hint that content should be base16 encoded
     57799 Tag that serves as a CBOR magic number
-    
+
 The content format for all these tags is that it can be any valid
 CBOR. Decoding of these tags doesn't have to check the content format.
 
diff --git a/inc/qcbor/qcbor_common.h b/inc/qcbor/qcbor_common.h
index 62858de..1c76a8a 100644
--- a/inc/qcbor/qcbor_common.h
+++ b/inc/qcbor/qcbor_common.h
@@ -199,9 +199,11 @@
     tag. */
 #define CBOR_TAG_CBOR_MAGIC    55799
 
-/** Three different values for invalid tag from the CBOR tags registry */
+/** The 16-bit invalid tag from the CBOR tags registry */
 #define CBOR_TAG_INVALID16 0xffff
+/** The 32-bit invalid tag from the CBOR tags registry */
 #define CBOR_TAG_INVALID32 0xffffffff
+/** The 64-bit invalid tag from the CBOR tags registry */
 #define CBOR_TAG_INVALID64 0xffffffffffffffff
 
 
diff --git a/inc/qcbor/qcbor_decode.h b/inc/qcbor/qcbor_decode.h
index ca294f1..90a1686 100644
--- a/inc/qcbor/qcbor_decode.h
+++ b/inc/qcbor/qcbor_decode.h
@@ -51,85 +51,43 @@
 /**
 @file qcbor_decode.h
 
-Q C B O R    D e c o d e
+ @anchor BasicDecode
+ # QCBOR Basic Decode
 
- This section just discusses decoding assuming familiarity with the general
- description of this encoder / decoder in section XXX.
+ This section just discusses decoding assuming familiarity with the
+ general description of this encoder / decoder in section @ref
+ Overview.
 
- Encoded CBOR can be viewed to have a tree structure
- where the lead nodes are non-aggregate types like
- integers and strings and the intermediate nodes are
- either arrays or maps. Fundamentally, all decoding
- is a pre-order traversal of the tree. Calling
- GetNext() repeatedly will perform this.
+ Encoded CBOR can be viewed to have a tree structure where the leaf
+ nodes are non-aggregate types like integers and strings and the
+ intermediate nodes are either arrays or maps. Fundamentally, all CBOR
+ decoding is a pre-order traversal of the tree. Calling
+ QCBORDecode_GetNext() repeatedly will perform this. It is possible to
+ decode any CBOR by only calling QCBORDecode_GetNext().
 
- This pre-order traversal gives natural decoding of
- arrays where the array members are taken
- in order, but does not give natural decoding of
- maps where access by label is usually preferred.
- Using the EnterMap and GetByLabel methods,
- map items can be accessed by label. EnterMap
-narrows decoding to a particular map. GetByLabel
- allows decoding the item of a particular label in
- the particular map. This can be used with nested
- maps by calling EnterMapByLabel.
+ QCBORDecode_GetNext() returns a 56 byte structure called
+ @ref QCBORItem that describes the decoded item including
+ - The data itself, integer, string, floating-point number...
+ - The label if present
+ - Unprocessed tags
+ - Nesting level
+ - Allocation type (primarily of interest for indefinite length strings)
 
- When EnterMap is called, pre-order traversal
- continues to work. There is a cursor that is run
- over the tree with calls to GetNext. This can be
- intermixed with calls to GetByLabel. The pre-order
- traversal is limited just to the map entered. Attempts
- to GetNext beyond the end of the map will give
- the HIT END error.
+ For strings, this structure contains a pointer and length
+ back into the original data.
 
-  There is also EnterArray to decode arrays. It will
- narrow the traversal to the extent of the array
- entered.
+ All of the tags that QCBOR supports directly are decoded into a
+ representation in @ref QCBORItem.
 
- GetByLabel supports duplicate label detection
- and will result in an error if the map has
- duplicate labels.
+ A string allocator must be used when decoding indefinite length
+ strings. See QCBORDecode_SetMemPool() or
+ QCBORDecode_SetUpAllocator(). @ref QCBORItem indicates if a string
+ was allocated with the string allocator.
 
- GetByLabel is implemented by performing the
- pre-order traversal of the map to find the labeled
- item everytime it is called. It doesn't build up
- a hash table, a binary search tree or some other
- efficiently searchable structure internally. For simple
- trees this is fine and for high-speed CPUs this is
- fine, but for complex trees on slow CPUs,
- it may have performance issues (these have
- not be quantified yet). One way ease this is
- to use GetItems which allows decoding of
- a list of items expected in an map in one
- traveral.
-
- Like encoding, decoding maintains an
- internal error state. Once a call to the
- decoder returns an error, this error state
- is entered and subsequent decoder calls
- do nothing. This allows for prettier and cleaner
- decoding code. The only error check needed
- is in the Finish call.
-
- An easy and clean way to use this decoder
- is to always use EnterMap and EnterArray
- for each array or map. They will error
- if the input CBOR is not the expected
- array or map.  Then use GetInt, GetString
- to get the individual items of of the
- maps and arrays making use of the
- internal error tracking provided by this
- decoder. The only error check needed
- is the call to Finish.
-
- In some CBOR protocols, the type of
- a data item may be variable. Maybe even
- the type of one data item is dependent
- on another. In such designs, GetNext has
- to be used and the internal error checking
- can't be relied upon.
-
-
+ This pre-order traversal gives natural decoding of arrays where the
+ array members are taken in order, but does not give natural decoding
+ of maps where access by label is usually preferred.  See
+ @ref SpiffyDecode for APIs to search maps by label and much more.
 */
 
 /**
diff --git a/inc/qcbor/qcbor_encode.h b/inc/qcbor/qcbor_encode.h
index 3b92943..8243996 100644
--- a/inc/qcbor/qcbor_encode.h
+++ b/inc/qcbor/qcbor_encode.h
@@ -51,13 +51,20 @@
 /**
  @file qcbor_encode.h
 
- Q C B O R   E n c o d e / D e c o d e
+ @anchor Overview
+
+ # QCBOR Overview
 
  This implements CBOR -- Concise Binary Object Representation as
  defined in [RFC 7049] (https://tools.ietf.org/html/rfc7049). More
  info is at http://cbor.io.  This is a near-complete implementation of
  the specification. Limitations are listed further down.
 
+ See @ref Encoding for general discussion on encoding,
+ @ref BasicDecode for general discussion on the basic decode features
+ and @ref SpiffyDecode for general discussion on the easier-to-use
+ decoder functions.
+
  CBOR is intentionally designed to be translatable to JSON, but not
  all CBOR can convert to JSON. See RFC 7049 for more info on how to
  construct CBOR that is the most JSON friendly.
@@ -103,7 +110,7 @@
 
  - "Tag": A data item that is an explicitly labeled new data
  type made up of the tagging integer and the tag content.
- See @Tags-Overview and @Tag-Usage.
+ See @ref Tags-Overview and @ref Tag-Usage.
 
  - "Initial Byte": The first byte of an encoded item. Encoding and
  decoding of this byte is taken care of by the implementation.
@@ -153,6 +160,10 @@
  map. It is possible to use this API to construct and parse such
  labels, but it is not explicitly supported.
 
+ @anchor Encoding
+
+ ## Encoding
+
  A common encoding usage mode is to invoke the encoding twice. First
  with no output buffer to compute the length of the needed output
  buffer. Then the correct sized output buffer is allocated. Last the
@@ -213,15 +224,18 @@
  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.
+ 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.
 
  @anchor Tags-Overview
 
- Any CBOR data item can be made into a tag to add semantics, define a new data
- type or such. Some tags are fully standardized and some are just
- registered. Others are not registered and used in a proprietary way.
+ ## Tags Overview
+
+ Any CBOR data item can be made into a tag to add semantics, define a
+ new data type or such. Some tags are fully standardized and some are
+ just registered. Others are not registered and used in a proprietary
+ way.
 
  Encoding and decoding of many of the registered tags is fully
  implemented by QCBOR. It is also possible to encode and decode tags
@@ -254,6 +268,9 @@
  implemented by the caller.
 
  @anchor Floating-Point
+
+ ## Floating-Point
+
  By default QCBOR fully supports IEEE 754 floating-point:
   - Encode/decode of double, single and half-precision
   - CBOR preferred serialization of floating-point
@@ -295,24 +312,26 @@
  On CPUs that have no floating-point hardware,
  QCBOR_DISABLE_FLOAT_HW_USE should be defined in most cases. If it is
  not, then the compiler will bring in possibly large software
- libraries to compensate. Defining
- QCBOR_DISABLE_FLOAT_HW_USE reduces object code size on CPUs with
- floating-point hardware by a tiny amount and eliminates the need for <math.h>
+ libraries to compensate. Defining QCBOR_DISABLE_FLOAT_HW_USE reduces
+ object code size on CPUs with floating-point hardware by a tiny
+ amount and eliminates the need for <math.h>
 
  When QCBOR_DISABLE_FLOAT_HW_USE is defined, trying to decoding
- floating-point dates will give error @ref
- QCBOR_ERR_FLOAT_DATE_DISABLED and decoded single-precision numbers
- will be returned as @ref QCBOR_TYPE_FLOAT instead of converting them
- to double as usual.
+ floating-point dates will give error
+ @ref QCBOR_ERR_FLOAT_DATE_DISABLED and decoded single-precision
+ numbers will be returned as @ref QCBOR_TYPE_FLOAT instead of
+ converting them to double as usual.
 
  If both QCBOR_DISABLE_FLOAT_HW_USE and QCBOR_DISABLE_PREFERRED_FLOAT
  are defined, then the only thing QCBOR can do is encode/decode a C
  float type as 32-bits and a C double type as 64-bits. Floating-point
  epoch dates will be unsupported.
 
+ ## Limitations
+
  Summary Limits of this implementation:
  - The entire encoded CBOR must fit into contiguous memory.
- - Max size of encoded / decoded CBOR data is @c UINT32_MAX (4GB).
+ - Max size of encoded / decoded CBOR data is a few bytes less than @c UINT32_MAX (4GB).
  - Max array / map nesting level when encoding / decoding is
    @ref QCBOR_MAX_ARRAY_NESTING (this is typically 15).
  - Max items in an array or map when encoding / decoding is
@@ -322,7 +341,7 @@
  - Epoch dates limited to @c INT64_MAX (+/- 292 billion years).
  - Exponents for bigfloats and decimal integers are limited to @c INT64_MAX.
  - Tags on labels are ignored during decoding.
- - There is no duplicate detection of map labels (but duplicates are passed on).
+ - The maximum tag nesting is @c QCBOR_MAX_TAGS_PER_ITEM (typically 4).
  - Works only on 32- and 64-bit CPUs (modifications could make it work
    on 16-bit CPUs).
 
@@ -335,7 +354,6 @@
  <stdint.h> also requires this. It is possible to modify this
  implementation for another integer representation, but all modern
  machines seem to be two's compliment.
-
  */
 
 
@@ -1778,7 +1796,7 @@
                      for them must be encoded.
  @param uNumber      The numeric argument part of the CBOR head.
  @return             Pointer and length of the encoded head or
-                     @NULLUsefulBufC if the output buffer is too small.
+                     @ref NULLUsefulBufC if the output buffer is too small.
 
  Callers do not to need to call this for normal CBOR encoding. Note that it doesn't even
  take a @ref QCBOREncodeContext argument.
@@ -1921,7 +1939,7 @@
  number or an @c int64_t.
 
  This implementation cannot output an exponent further from 0 than
- INT64_MAX.
+ @c INT64_MAX.
 
  To output a mantissa that is bewteen INT64_MAX and UINT64_MAX from 0,
  it must be as a big number.
diff --git a/inc/qcbor/qcbor_spiffy_decode.h b/inc/qcbor/qcbor_spiffy_decode.h
index 8fdec26..df0067b 100644
--- a/inc/qcbor/qcbor_spiffy_decode.h
+++ b/inc/qcbor/qcbor_spiffy_decode.h
@@ -27,12 +27,17 @@
 /**
  @file qcbor_spiffy_decode.h
 
- Q C B O R   S p i f f y   D e c o d e
+ @anchor SpiffyDecode
+ # Spiffy Decode
 
- Spiffy decode is extra decode features over and above the basic
- decode features that generally are easier to use, mirror the encoding
- functions better and can result in smaller code size for larger and
- more complex CBOR protocols.  In particular, spiffy decode
+ This section just discusses spiff decoding assuming familiarity with
+ the general description of this encoder / decoder in section
+ @ref Overview and @ref BasicDecoding.
+
+ Spiffy decode is extra decode features over and above the @ref
+ BasicDecode features that generally are easier to use, mirror the
+ encoding functions better and can result in smaller code size for
+ larger and more complex CBOR protocols.  In particular, spiffy decode
  facilitates getting the next data item of a specific type, setting an
  error if it is not of that type. It facilitates explicitly entering
  and exiting arrays and maps. It facilates fetching items by label
@@ -41,33 +46,34 @@
  Encoded CBOR can be viewed to have a tree structure where the leaf
  nodes are non-aggregate types like integers and strings and the
  intermediate nodes are either arrays or maps. Fundamentally, all
- decoding is a pre-order traversal of the tree. Calling QCBORDecode_GetNext()
- repeatedly will perform this.
+ decoding is a pre-order traversal of the tree. Calling
+ QCBORDecode_GetNext() repeatedly will perform this.
 
  This pre-order traversal gives natural decoding of arrays where the
  array members are taken in order, but does not give natural decoding
  of maps where access by label is usually preferred.  Using the
- QCBORDecode_EnterMap() and GetXxxInMapX methods, map items can be
- accessed by label. QCBORDecode_EnterMap() bounds decoding to a
- particular map. GetXxxInMap methods allows decoding the item of a
- particular label in the particular map. This can be used with nested
- maps by using QCBORDecode_EnterMapFromMapX().
+ QCBORDecode_EnterMap() and QCBORDecode_GetXxxxInMapX() methods like
+ QCBORDecode_GetInt64InMapN(), map items can be accessed by
+ label. QCBORDecode_EnterMap() bounds decoding to a particular
+ map. QCBORDecode_GetXxxxInMapX() methods allows decoding the item of
+ a particular label in the particular map. This can be used with
+ nested maps by using QCBORDecode_EnterMapFromMapX().
 
  When QCBORDecode_EnterMap() is called, pre-order traversal continues
  to work. There is a cursor that is run over the tree with calls to
  QCBORDecode_GetNext(). This can be intermixed with calls to
- GetXxxInMapX. The pre-order traversal is limited just to the map
- entered. Attempts to QCBORDecode_GetNext() beyond the end of the map
- will give the @ref QCBOR_ERR_NO_MORE_ITEMS error.
+ QCBORDecode_GetXxxxInMapX(). The pre-order traversal is limited just
+ to the map entered. Attempts to QCBORDecode_GetNext() beyond the end
+ of the map will give the @ref QCBOR_ERR_NO_MORE_ITEMS error.
 
- There is also QCBORDecode_EnterArray() to decode arrays. It will narrow the
- traversal to the extent of the array entered.
+ There is also QCBORDecode_EnterArray() to decode arrays. It will
+ narrow the traversal to the extent of the array entered.
 
- All the QCBORDecode_GetXxxInMapX methods support duplicate label
+ All the QCBORDecode_GetXxxxInMapX() methods support duplicate label
  detection and will result in an error if the map has duplicate
  labels.
 
- All the QCBORDecode_GetXxxInMapX() methods are implemented by
+ All the QCBORDecode_GetXxxxInMapX() methods are implemented by
  performing the pre-order traversal of the map to find the labeled
  item everytime it is called. It doesn't build up a hash table, a
  binary search tree or some other efficiently searchable structure
@@ -78,6 +84,7 @@
  list of items expected in an map in one traveral.
 
  @anchor Decode-Errors
+ ## Spiffy Decode Errors
 
  Like encoding, decoding maintains an internal error state. Once a
  call to the decoder returns an error, this error state is entered and
@@ -104,25 +111,17 @@
  error. It doesn't set the internal error state. It will attempt to
  decode evening when in the error state.
 
- In some CBOR protocols, the type of a data item may be variable and
- the type of one data item may be dependent on another. To get items
- of unknown type use QCBORDecode_GetNext(), QCBORDecode_VGetNext(),
- QCBORDecode_GetItemInMapN() QCBORDecode_GetItemInMapSZ() or
- QCBORDecode_GetItemsInMap().  This can be used to determine the
- type. Then for use one of the type-specific methods to get the item
- again to take advantage of the type conversion provided.
-
- When getting an item by label from a map the whole map is
- traversed including traversal of nested arrays and maps. If
- there is any unrecoverable error anywhere in the that traversal
- the retrieval by label will fail and the unrecoverable error
- will be returned even if it is not due to the labeled item
- being sought. Recoverable errors will be ignored unless
- they are on the item being sought, in which case the
- unrecoverable error will be returned. Unrecoverable
- errors are those indicated by QCBORDecode_IsUnrecoverableError().
+ When getting an item by label from a map the whole map is traversed
+ including traversal of nested arrays and maps. If there is any
+ unrecoverable error anywhere in the that traversal the retrieval by
+ label will fail and the unrecoverable error will be returned even if
+ it is not due to the labeled item being sought. Recoverable errors
+ will be ignored unless they are on the item being sought, in which
+ case the unrecoverable error will be returned. Unrecoverable errors
+ are those indicated by QCBORDecode_IsUnrecoverableError().
 
  @anchor Tag-Usage
+ ## Tag Usage
 
  Data types beyond the basic CBOR types of numbers, strings, maps and
  arrays are called tags. The main registry of these new types is in in
@@ -152,12 +151,12 @@
  example, to decode an epoch date tag the content must be an integer
  or floating-point value.
 
- If the parameter indicates it should not be a tag(@ref
- QCBOR_TAG_REQUIREMENT_NOT_A_TAG), then @ref QCBOR_ERR_UNEXPECTED_TYPE
- set if it is a tag or the type of the encoded CBOR is not what is
- expected.  In the example of an epoch date, the data type must be an
- integer or floating-point value. This is the case where the content
- format of a tag is borrowed.
+ If the parameter indicates it should not be a tag 
+ (@ref  QCBOR_TAG_REQUIREMENT_NOT_A_TAG), then
+  @ref QCBOR_ERR_UNEXPECTED_TYPE set if it is a tag or the type of the
+ encoded CBOR is not what is expected.  In the example of an epoch
+ date, the data type must be an integer or floating-point value. This
+ is the case where the content format of a tag is borrowed.
 
  The parameter can also indicate that either a tag or no tag is
  allowed ( @ref QCBOR_TAG_REQUIREMENT_OPTIONAL_TAG ).  A good protocol
@@ -166,12 +165,12 @@
  accept", however these days that is less in favor. See
  https://tools.ietf.org/id/draft-thomson-postel-was-wrong-03.html.
 
- Map searching works with indefinite length strings. A string allocator must
- be set up the same as for any handling of indefinite length strings.
- However,  It currently over-allocates memory from the string pool
- and thus requires a much larger string pool than it should. The
- over-allocation happens every time a map is searched by label.
- (This may be corrected in the future).
+ Map searching works with indefinite length strings. A string
+ allocator must be set up the same as for any handling of indefinite
+ length strings.  However, It currently over-allocates memory from the
+ string pool and thus requires a much larger string pool than it
+ should. The over-allocation happens every time a map is searched by
+ label.  (This may be corrected in the future).
 */
 
 
@@ -1008,7 +1007,7 @@
  is the most significant byte. There may be leading zeros.
 
  The negative value is computed as -1 - n, where n is the postive big
- number in @C pValue. There is no standard representation for
+ number in @c pValue. There is no standard representation for
  big numbers, positive or negative in C, so this implementation leaves
  it up to the caller to apply this computation for negative big numbers.