remove all trailing tabs and spaces
diff --git a/README.md b/README.md
index 0a6c046..ed949dd 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 # QCBOR
 
-QCBOR encodes and decodes [RFC 7049](https://tools.ietf.org/html/rfc7049) CBOR. 
+QCBOR encodes and decodes [RFC 7049](https://tools.ietf.org/html/rfc7049) CBOR.
 
 ## Characteristics
 
@@ -106,7 +106,7 @@
 not partial maps and arrays (simplification; was a dangerous feature)
 * Finish cannot be called repeatedly on a partial decode (some tests used
 this, but it is not really a good thing to use in the first place)
-* UsefulOutBuf_OutUBuf changed to work differently 
+* UsefulOutBuf_OutUBuf changed to work differently
 * UsefulOutBuf_Init works differently
 * The "_3" functions are replaced with a small number of simpler functions
 * There is a new AddTag functon instead of the "_3" functions, making
diff --git a/cmd_line_main.c b/cmd_line_main.c
index 4357d07..927beee 100644
--- a/cmd_line_main.c
+++ b/cmd_line_main.c
@@ -1,9 +1,9 @@
 /*==============================================================================
  cmd_line_mainc.c -- basic tests for qcbor encoder / decoder
- 
+
  Copyright (c) 2018, Laurence Lundblade.
  All rights reserved.
- 
+
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
 met:
@@ -17,7 +17,7 @@
       contributors, nor the name "Laurence Lundblade" may be used to
       endorse or promote products derived from this software without
       specific prior written permission.
- 
+
 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
@@ -46,7 +46,7 @@
 static void PrintSize(const char *szWhat, uint32_t uSize)
 {
     UsefulBuf_MAKE_STACK_UB(foo, 20);
-    
+
     fputs_wrapper(szWhat, stdout);
     fputs_wrapper(" ", stdout);
     fputs_wrapper(NumToString(uSize,foo), stdout);
@@ -67,7 +67,7 @@
     fputs_wrapper("\n", stdout);
 
     int nNumTestsFailed = 0;
-    
+
     if(argc > 1) {
         nNumTestsFailed += run_tests(argv[1], &fputs_wrapper, stdout, NULL);
     } else {
diff --git a/inc/UsefulBuf.h b/inc/UsefulBuf.h
index b9bdf2f..0f6bb6d 100644
--- a/inc/UsefulBuf.h
+++ b/inc/UsefulBuf.h
@@ -2,7 +2,7 @@
  Copyright (c) 2016-2018, The Linux Foundation.
  Copyright (c) 2018, Laurence Lundblade.
  All rights reserved.
- 
+
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
 met:
@@ -16,7 +16,7 @@
       contributors, nor the name "Laurence Lundblade" may be used to
       endorse or promote products derived from this software without
       specific prior written permission.
- 
+
 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
@@ -32,14 +32,14 @@
 
 /*===================================================================================
  FILE:  UsefulBuf.h
- 
+
  DESCRIPTION:  General purpose input and output buffers
- 
+
  EDIT HISTORY FOR FILE:
- 
+
  This section contains comments describing changes made to the module.
  Notice that changes are listed in reverse chronological order.
- 
+
  when               who             what, where, why
  --------           ----            ---------------------------------------------------
  12/13/2018         llundblade      Documentation improvements
@@ -53,7 +53,7 @@
  05/30/17           llundbla        Functions for NULL UsefulBufs and const / unconst
  11/13/16           llundbla        Initial Version.
 
- 
+
  =====================================================================================*/
 
 #ifndef _UsefulBuf_h
@@ -66,18 +66,18 @@
 
 /**
  @file UsefulBuf.h
- 
+
  The goal of this code is to make buffer and pointer manipulation
  easier and safer when working with binary data.
- 
+
  You use the UsefulBuf, UsefulOutBuf and UsefulInputBuf
  structures to represent buffers rather than ad hoc pointers and lengths.
- 
+
  With these it will often be possible to write code that does little or no
  direct pointer manipulation for copying and formatting data. For example
  the QCBOR encoder was rewritten using these and has no direct pointer
  manipulation.
- 
+
  While it is true that object code using these functions will be a little
  larger and slower than a white-knuckle clever use of pointers might be, but
  not by that much or enough to have an affect for most use cases. For
@@ -103,28 +103,28 @@
  length for a binary data.  In C99 this data structure can be passed on the
  stack making a lot of code cleaner than carrying around a pointer and
  length as two parameters.
- 
+
  This is also conducive to secure code practice as the lengths are
  always carried with the pointer and the convention for handling a
  pointer and a length is clear.
- 
+
  While it might be possible to write buffer and pointer code more
  efficiently in some use cases, the thought is that unless there is an
  extreme need for performance (e.g., you are building a gigabit-per-second
  IP router), it is probably better to have cleaner code you can be most
  certain about the security of.
- 
+
  The non-const UsefulBuf is usually used to refer a buffer to be filled in.
  The length is the size of the buffer.
- 
+
  The const UsefulBufC is usually used to refer to some data that has been
  filled in. The length is amount of valid data pointed to.
- 
+
  A common use is to pass a UsefulBuf to a function, the function fills it
  in, the function returns a UsefulBufC. The pointer is the same in both.
- 
+
  A UsefulBuf is NULL, it has no value, when the ptr in it is NULL.
- 
+
  There are utility functions for the following:
   - Checking for UsefulBufs that are NULL, empty or both
   - Copying, copying with offset, copying head or tail
@@ -133,16 +133,16 @@
   - Create initialized const UsefulBufC from compiler literals
   - Create initialized const UsefulBufC from NULL-terminated string
   - Make an empty UsefulBuf on the stack
- 
+
  See also UsefulOutBuf. It is a richer structure that has both the size of
  the valid data and the size of the buffer.
- 
+
  UsefulBuf is only 16 or 8 bytes on a 64- or 32-bit machine so it can go
  on the stack and be a function parameter or return value.
- 
+
  UsefulBuf is kind of like the Useful Pot Pooh gave Eeyore on his birthday.
  Eeyore's balloon fits beautifully, "it goes in and out like anything".
- 
+
 */
 typedef struct {
     const void *ptr;
@@ -176,9 +176,9 @@
 
 /**
  @brief Check if a UsefulBuf is NULL or not
- 
+
  @param[in] UB The UsefulBuf to check
- 
+
  @return 1 if it is NULL, 0 if not.
  */
 static inline int UsefulBuf_IsNULL(UsefulBuf UB) {
@@ -188,9 +188,9 @@
 
 /**
  @brief Check if a UsefulBufC is NULL or not
- 
+
  @param[in] UB The UsefulBufC to check
- 
+
  @return 1 if it is NULL, 0 if not.
  */
 static inline int UsefulBuf_IsNULLC(UsefulBufC UB) {
@@ -200,15 +200,15 @@
 
 /**
  @brief Check if a UsefulBuf is empty or not
- 
+
  @param[in] UB The UsefulBuf to check
- 
+
  @return 1 if it is empty, 0 if not.
- 
+
  An "Empty" UsefulBuf is one that has a value and can be considered to be set,
  but that value is of zero length.  It is empty when len is zero. It
  doesn't matter what the ptr is.
- 
+
  A lot of uses will not need to clearly distinguish a NULL UsefulBuf
  from an empty one and can have the ptr NULL and the len 0.  However
  if a use of UsefulBuf needs to make a distinction then ptr should
@@ -222,9 +222,9 @@
 
 /**
  @brief Check if a UsefulBufC is empty or not
- 
+
  @param[in] UB The UsefulBufC to check
- 
+
  @return 1 if it is empty, 0 if not.
  */
 static inline int UsefulBuf_IsEmptyC(UsefulBufC UB) {
@@ -234,9 +234,9 @@
 
 /**
  @brief Check if a UsefulBuf is NULL or empty
- 
+
  @param[in] UB The UsefulBuf to check
- 
+
  @return 1 if it is either NULL or empty, 0 if not.
  */
 static inline int UsefulBuf_IsNULLOrEmpty(UsefulBuf UB) {
@@ -246,9 +246,9 @@
 
 /**
  @brief Check if a UsefulBufC is NULL or empty
- 
+
  @param[in] UB The UsefulBufC to check
- 
+
  @return 1 if it is either NULL or empty, 0 if not.
  */
 static inline int UsefulBuf_IsNULLOrEmptyC(UsefulBufC UB) {
@@ -258,9 +258,9 @@
 
 /**
  @brief Convert a non const UsefulBuf to a const UsefulBufC
- 
+
  @param[in] UB The UsefulBuf to convert
- 
+
  Returns: a UsefulBufC struct
  */
 
@@ -272,9 +272,9 @@
 
 /**
  @brief Convert a const UsefulBufC to a non-const UsefulBuf
- 
+
  @param[in] UBC The UsefulBuf to convert
- 
+
  Returns: a non const UsefulBuf struct
  */
 static inline UsefulBuf UsefulBuf_Unconst(const UsefulBufC UBC)
@@ -285,14 +285,14 @@
 
 /**
  Convert a literal string to a UsefulBufC.
- 
+
  szString must be a literal string that you can take sizeof.
  This is better for literal strings than UsefulBuf_FromSZ()
  because it generates less code. It will not work on
  non-literal strings.
- 
+
  The terminating \0 (NULL) is NOT included in the length!
- 
+
  */
 #define UsefulBuf_FROM_SZ_LITERAL(szString) \
     ((UsefulBufC) {(szString), sizeof(szString)-1})
@@ -300,10 +300,10 @@
 
 /**
  Convert a literal byte array to a UsefulBufC.
- 
+
  pBytes must be a literal string that you can take sizeof.
  It will not work on  non-literal arrays.
- 
+
  */
 #define UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pBytes) \
     ((UsefulBufC) {(pBytes), sizeof(pBytes)})
@@ -328,14 +328,14 @@
  @brief Convert a NULL terminated string to a UsefulBufC.
 
  @param[in] szString The string to convert
- 
+
  @return a UsefulBufC struct
 
  UsefulBufC.ptr points to the string so it's lifetime
  must be maintained.
- 
+
  The terminating \0 (NULL) is NOT included in the length!
- 
+
  */
 static inline UsefulBufC UsefulBuf_FromSZ(const char *szString){
     return ((UsefulBufC) {szString, strlen(szString)});
@@ -344,42 +344,42 @@
 
 /**
  @brief Copy one UsefulBuf into another at an offset
- 
+
  @param[in] Dest Destiation buffer to copy into
  @param[in] uOffset The byte offset in Dest at which to copy to
  @param[in] Src The bytes to copy
- 
+
  @return Pointer and length of the copy
- 
+
  This fails and returns NULLUsefulBufC Src.len + uOffset > Dest.len.
- 
+
  Like memcpy, there is no check for NULL. If NULL is passed
  this will crash.
- 
+
  There is an assumption that there is valid data in Dest up to
  uOffset as the resulting UsefulBufC returned starts
  at the beginning of Dest and goes to Src.len + uOffset.
- 
+
  */
 UsefulBufC UsefulBuf_CopyOffset(UsefulBuf Dest, size_t uOffset, const UsefulBufC Src);
 
 
 /**
  @brief Copy one UsefulBuf into another
- 
+
  @param[in] Dest The destination buffer to copy into
  @param[out] Src  The source to copy from
- 
+
  @return filled in UsefulBufC on success, NULLUsefulBufC on failure
- 
+
  This fails if Src.len is greater than Dest.len.
- 
+
  Note that like memcpy, the pointers are not checked and
  this will crash, rather than return NULLUsefulBufC if
  they are NULL or invalid.
- 
+
  Results are undefined if Dest and Src overlap.
- 
+
  */
 static inline UsefulBufC UsefulBuf_Copy(UsefulBuf Dest, const UsefulBufC Src) {
    return UsefulBuf_CopyOffset(Dest, 0, Src);
@@ -388,13 +388,13 @@
 
 /**
  @brief Set all bytes in a UsefulBuf to a value, for example 0
- 
+
  @param[in] pDest The destination buffer to copy into
  @param[in] value The value to set the bytes to
- 
+
  Note that like memset, the pointer in pDest is not checked and
  this will crash if NULL or invalid.
- 
+
  */
 static inline UsefulBufC UsefulBuf_Set(UsefulBuf pDest, uint8_t value)
 {
@@ -405,20 +405,20 @@
 
 /**
  @brief Copy a pointer into a UsefulBuf
- 
+
  @param[in,out] Dest The destination buffer to copy into
  @param[in] ptr  The source to copy from
  @param[in] len  Length of the source; amoutn to copy
- 
+
  @return 0 on success, 1 on failure
- 
+
  This fails and returns NULLUsefulBufC if len is greater than
  pDest->len.
- 
+
  Note that like memcpy, the pointers are not checked and
  this will crash, rather than return 1 if they are NULL
  or invalid.
- 
+
  */
 inline static UsefulBufC UsefulBuf_CopyPtr(UsefulBuf Dest, const void *ptr, size_t len)
 {
@@ -428,12 +428,12 @@
 
 /**
   @brief Returns a truncation of a UsefulBufC
- 
+
   @param[in] UB The buffer to get the head of
   @param[in] uAmount The number of bytes in the head
- 
+
   @return A UsefulBufC that is the head of UB
- 
+
  */
 static inline UsefulBufC UsefulBuf_Head(UsefulBufC UB, size_t uAmount)
 {
@@ -446,12 +446,12 @@
 
 /**
  @brief  Returns bytes from the end of a UsefulBufC
- 
+
  @param[in] UB The buffer to get the tail of
  @param[in] uAmount The offset from the start where the tail is to begin
- 
+
  @return A UsefulBufC that is the tail of UB
- 
+
  */
 static inline UsefulBufC UsefulBuf_Tail(UsefulBufC UB, size_t uAmount)
 {
@@ -464,36 +464,36 @@
 
 /**
  @brief Compare two UsefulBufCs
- 
+
  @param[in] UB1 The destination buffer to copy into
  @param[in] UB2  The source to copy from
- 
+
  @return 0 if equal...
- 
+
  Returns a negative value if UB1 if is less than UB2. UB1 is
  less than UB2 if it is shorter or the first byte that is not
- the same is less. 
- 
+ the same is less.
+
  Returns 0 if the UsefulBufs are the same.
- 
+
  Returns a positive value if UB2 is less than UB1.
- 
+
  All that is of significance is that the result is positive,
  negative or 0. (This doesn't return the difference between
  the first non-matching byte like memcmp).
- 
+
  */
 int UsefulBuf_Compare(const UsefulBufC UB1, const UsefulBufC UB2);
 
 
 /**
  @brief Find one UsefulBuf in another
- 
+
  @param[in] BytesToSearch  UsefulBuf to search through
  @param[in] BytesToFind    UsefulBuf with bytes to be found
- 
+
  @return position of found bytes or SIZE_MAX if not found.
- 
+
  */
 size_t UsefulBuf_FindBytes(UsefulBufC BytesToSearch, UsefulBufC BytesToFind);
 
@@ -564,64 +564,64 @@
  UsefulOutBuf is a structure and functions (an object) that are good
  for serializing data into a buffer such as is often done with network
  protocols or data written to files.
- 
+
  The main idea is that all the pointer manipulation for adding data is
  done by UsefulOutBuf functions so the caller doesn't have to do any.
  All the pointer manipulation is centralized here.  This code will
  have been reviewed and written carefully so it spares the caller of
  much of this work and results in much safer code with much less work.
- 
+
  The functions to add data to the output buffer always check the
  length and will never write off the end of the output buffer. If an
  attempt to add data that will not fit is made, an internal error flag
  will be set and further attempts to add data will not do anything.
- 
+
  Basically, if you initialized with the correct buffer, there is no
  way to ever write off the end of that buffer when calling the Add
  and Insert functions here.
- 
+
  The functions to add data do not return an error. The working model
  is that the caller just makes all the calls to add data without any
  error checking on each one. The error is instead checked after all the
  data is added when the result is to be used.  This makes the caller's
  code cleaner.
- 
+
  There is a utility function to get the error status anytime along the
  way if the caller wants. There are functions to see how much room is
  left and see if some data will fit too, but their use is generally
  not necessary.
- 
+
  The general call flow is like this:
 
     - Initialize the UsefulOutBuf with the buffer that is to have the
       data added.  The caller allocates the buffer.  It can be heap
       or stack or shared memory (or other).
-    
+
     - Make calls to add data to the output buffer. Insert and append
       are both supported. The append and insert calls will never write
       off the end of the buffer.
-    
+
     - When all data is added, check the error status to make sure
       everything fit.
-    
+
     - Get the resulting serialized data either as a UsefulBuf (a
       pointer and length) or have it copied to another buffer.
- 
+
  UsefulOutBuf can be initialized with just a buffer length by passing
  NULL as the pointer to the output buffer. This is useful if you want
  to go through the whole serialization process to either see if it
  will fit into a given buffer or compute the size of the buffer
  needed. Pass a very large buffer size when calling Init, if you want
  just to compute the size.
- 
+
  Some inexpensive simple sanity checks are performed before every data
  addition to guard against use of an uninitialized or corrupted
  UsefulOutBuf.
- 
+
  This has been used to create a CBOR encoder. The CBOR encoder has
  almost no pointer manipulation in it, is much easier to read, and
  easier to review.
- 
+
  A UsefulOutBuf is 27 bytes or 15 bytes on 64- or 32-bit machines so it
  can go on the stack or be a C99 function parameter.
  */
@@ -636,13 +636,13 @@
 
 /**
  @brief Initialize and supply the actual output buffer
- 
+
  @param[out] me The UsefulOutBuf to initialize
  @param[in] Storage  Buffer to output into
- 
+
  Intializes the UsefulOutBuf with storage. Sets the current position
  to the beginning of the buffer clears the error.
- 
+
  This must be called before the UsefulOutBuf is used.
  */
 void UsefulOutBuf_Init(UsefulOutBuf *me, UsefulBuf Storage);
@@ -662,15 +662,15 @@
 
 /**
  @brief Reset a UsefulOutBuf for re use
- 
+
  @param[in] me Pointer to the UsefulOutBuf
 
  This sets the amount of data in the output buffer to none and
- clears the error state.  
- 
+ clears the error state.
+
  The output buffer is still the same one and size as from the
  UsefulOutBuf_Init() call.
- 
+
  It doesn't zero the data, just resets to 0 bytes of valid data.
  */
 static inline void UsefulOutBuf_Reset(UsefulOutBuf *me)
@@ -682,18 +682,18 @@
 
 /**
  @brief Returns position of end of data in the UsefulOutBuf
- 
+
  @param[in] me Pointer to the UsefulOutBuf
- 
+
  @return position of end of data
- 
+
  On a freshly initialized UsefulOutBuf with no data added, this will
  return 0. After ten bytes have been added, it will return 10 and so
  on.
- 
+
  Generally callers will not need this function for most uses of
  UsefulOutBuf.
- 
+
  */
 static inline size_t UsefulOutBuf_GetEndPosition(UsefulOutBuf *me)
 {
@@ -703,11 +703,11 @@
 
 /**
  @brief Returns whether any data has been added to the UsefulOutBuf
- 
+
  @param[in] me Pointer to the UsefulOutBuf
- 
+
  @return 1 if output position is at start
- 
+
  */
 static inline int UsefulOutBuf_AtStart(UsefulOutBuf *me)
 {
@@ -717,50 +717,50 @@
 
 /**
  @brief Inserts bytes into the UsefulOutBuf
- 
+
  @param[in] me Pointer to the UsefulOutBuf
  @param[in] NewData UsefulBuf with the bytes to insert
  @param[in] uPos Index in output buffer at which to insert
- 
+
  NewData is the pointer and length for the bytes to be added to the
  output buffer. There must be room in the output buffer for all of
  NewData or an error will occur.
- 
+
  The insertion point must be between 0 and the current valid data. If
  not an error will occur. Appending data to the output buffer is
  achieved by inserting at the end of the valid data. This can be
  retrieved by calling UsefulOutBuf_GetEndPosition().
- 
+
  When insertion is performed, the bytes between the insertion point and
  the end of data previously added to the output buffer is slid to the
  right to make room for the new data.
- 
+
  Overlapping buffers are OK. NewData can point to data in the output
  buffer.
 
  If an error occurs an error state is set in the UsefulOutBuf. No
  error is returned.  All subsequent attempts to add data will do
  nothing.
- 
+
  Call UsefulOutBuf_GetError() to find out if there is an error. This
  is usually not needed until all additions of data are complete.
- 
+
  */
 void UsefulOutBuf_InsertUsefulBuf(UsefulOutBuf *me, UsefulBufC NewData, size_t uPos);
 
 
 /**
  @brief Insert a data buffer into the UsefulOutBuf
- 
+
  @param[in] me Pointer to the UsefulOutBul
  @param[in] pBytes Pointer to the bytes to insert
  @param[in] uLen Length of the bytes to insert
  @param[in] uPos Index in output buffer at which to insert
- 
+
  See UsefulOutBuf_InsertUsefulBuf() for details. This is the same with
  the difference being a pointer and length is passed in rather than an
  UsefulBuf.
- 
+
  */
 static inline void UsefulOutBuf_InsertData(UsefulOutBuf *me, const void *pBytes, size_t uLen, size_t uPos)
 {
@@ -771,10 +771,10 @@
 
 /**
  @brief Insert a NULL-terminated string into the UsefulOutBuf
- 
+
  @param[in] me Pointer to the UsefulOutBuf
  @param[in] szString string to append
- 
+
  */
 static inline void UsefulOutBuf_InsertString(UsefulOutBuf *me, const char *szString, size_t uPos)
 {
@@ -784,11 +784,11 @@
 
 /**
  @brief Insert a byte into the UsefulOutBuf
- 
+
  @param[in] me Pointer to the UsefulOutBul
  @param[in] byte Bytes to insert
  @param[in] uPos Index in output buffer at which to insert
- 
+
  See UsefulOutBuf_InsertUsefulBuf() for details. This is the same with
  the difference being a single byte is to be inserted.
  */
@@ -800,14 +800,14 @@
 
 /**
  @brief Insert a 16-bit integer into the UsefulOutBuf
- 
+
  @param[in] me Pointer to the UsefulOutBul
  @param[in] uInteger16 Integer to insert
  @param[in] uPos Index in output buffer at which to insert
- 
+
  See UsefulOutBuf_InsertUsefulBuf() for details. This is the same with
  the difference being a single byte is to be inserted.
- 
+
  The integer will be inserted in network byte order (big endian)
  */
 static inline void UsefulOutBuf_InsertUint16(UsefulOutBuf *me, uint16_t uInteger16, size_t uPos)
@@ -822,14 +822,14 @@
 
 /**
  @brief Insert a 32-bit integer into the UsefulOutBuf
- 
+
  @param[in] me Pointer to the UsefulOutBul
  @param[in] uInteger32 Integer to insert
  @param[in] uPos Index in output buffer at which to insert
- 
+
  See UsefulOutBuf_InsertUsefulBuf() for details. This is the same with
  the difference being a single byte is to be inserted.
- 
+
  The integer will be inserted in network byte order (big endian)
  */
 static inline void UsefulOutBuf_InsertUint32(UsefulOutBuf *me, uint32_t uInteger32, size_t uPos)
@@ -846,14 +846,14 @@
 
 /**
  @brief Insert a 64-bit integer into the UsefulOutBuf
- 
+
  @param[in] me Pointer to the UsefulOutBul
  @param[in] uInteger64 Integer to insert
  @param[in] uPos Index in output buffer at which to insert
- 
+
  See UsefulOutBuf_InsertUsefulBuf() for details. This is the same with
  the difference being a single byte is to be inserted.
- 
+
  The integer will be inserted in network byte order (big endian)
  */
 static inline void UsefulOutBuf_InsertUint64(UsefulOutBuf *me, uint64_t uInteger64, size_t uPos)
@@ -874,14 +874,14 @@
 
 /**
  @brief Insert a float into the UsefulOutBuf
- 
+
  @param[in] me Pointer to the UsefulOutBul
  @param[in] f Integer to insert
  @param[in] uPos Index in output buffer at which to insert
- 
+
  See UsefulOutBuf_InsertUsefulBuf() for details. This is the same with
  the difference being a single byte is to be inserted.
- 
+
  The float will be inserted in network byte order (big endian)
  */
 static inline void UsefulOutBuf_InsertFloat(UsefulOutBuf *me, float f, size_t uPos)
@@ -892,14 +892,14 @@
 
 /**
  @brief Insert a double into the UsefulOutBuf
- 
+
  @param[in] me Pointer to the UsefulOutBul
  @param[in] d Integer to insert
  @param[in] uPos Index in output buffer at which to insert
- 
+
  See UsefulOutBuf_InsertUsefulBuf() for details. This is the same with
  the difference being a single byte is to be inserted.
- 
+
  The double will be inserted in network byte order (big endian)
  */
 static inline void UsefulOutBuf_InsertDouble(UsefulOutBuf *me, double d, size_t uPos)
@@ -911,13 +911,13 @@
 
 /**
  Append a UsefulBuf into the UsefulOutBuf
- 
+
  @param[in] me Pointer to the UsefulOutBuf
  @param[in] NewData UsefulBuf with the bytes to append
- 
+
  See UsefulOutBuf_InsertUsefulBuf() for details. This does the same
  with the insertion point at the end of the valid data.
- 
+
 */
 static inline void UsefulOutBuf_AppendUsefulBuf(UsefulOutBuf *me, UsefulBufC NewData)
 {
@@ -928,11 +928,11 @@
 
 /**
  Append bytes to the UsefulOutBuf
- 
+
  @param[in] me Pointer to the UsefulOutBuf
  @param[in] pBytes Pointer to bytes to append
  @param[in] uLen Index in output buffer at which to append
- 
+
  See UsefulOutBuf_InsertUsefulBuf() for details. This does the same
  with the insertion point at the end of the valid data.
  */
@@ -946,10 +946,10 @@
 
 /**
  Append a NULL-terminated string to the UsefulOutBuf
- 
+
  @param[in] me Pointer to the UsefulOutBuf
  @param[in] szString string to append
- 
+
  */
 static inline void UsefulOutBuf_AppendString(UsefulOutBuf *me, const char *szString)
 {
@@ -959,10 +959,10 @@
 
 /**
  @brief Append a byte to the UsefulOutBuf
- 
+
  @param[in] me Pointer to the UsefulOutBuf
  @param[in] byte Bytes to append
- 
+
  See UsefulOutBuf_InsertUsefulBuf() for details. This does the same
  with the insertion point at the end of the valid data.
  */
@@ -973,13 +973,13 @@
 
 /**
  @brief Append an integer to the UsefulOutBuf
- 
+
  @param[in] me Pointer to the UsefulOutBuf
  @param[in] uInteger16 Integer to append
- 
+
  See UsefulOutBuf_InsertUsefulBuf() for details. This does the same
  with the insertion point at the end of the valid data.
- 
+
  The integer will be appended in network byte order (big endian).
  */
 static inline void UsefulOutBuf_AppendUint16(UsefulOutBuf *me, uint16_t uInteger16){
@@ -988,13 +988,13 @@
 
 /**
  @brief Append an integer to the UsefulOutBuf
- 
+
  @param[in] me Pointer to the UsefulOutBuf
  @param[in] uInteger32 Integer to append
- 
+
  See UsefulOutBuf_InsertUsefulBuf() for details. This does the same
  with the insertion point at the end of the valid data.
- 
+
  The integer will be appended in network byte order (big endian).
  */
 static inline void UsefulOutBuf_AppendUint32(UsefulOutBuf *me, uint32_t uInteger32){
@@ -1003,13 +1003,13 @@
 
 /**
  @brief Append an integer to the UsefulOutBuf
- 
+
  @param[in] me Pointer to the UsefulOutBuf
  @param[in] uInteger64 Integer to append
- 
+
  See UsefulOutBuf_InsertUsefulBuf() for details. This does the same
  with the insertion point at the end of the valid data.
- 
+
  The integer will be appended in network byte order (big endian).
  */
 static inline void UsefulOutBuf_AppendUint64(UsefulOutBuf *me, uint64_t uInteger64){
@@ -1019,13 +1019,13 @@
 
 /**
  @brief Append a float to the UsefulOutBuf
- 
+
  @param[in] me Pointer to the UsefulOutBuf
  @param[in] f Float to append
- 
+
  See UsefulOutBuf_InsertUsefulBuf() for details. This does the same
  with the insertion point at the end of the valid data.
- 
+
  The float will be appended in network byte order (big endian).
  */
 static inline void UsefulOutBuf_AppendFloat(UsefulOutBuf *me, float f){
@@ -1034,13 +1034,13 @@
 
 /**
  @brief Append a float to the UsefulOutBuf
- 
+
  @param[in] me Pointer to the UsefulOutBuf
  @param[in] d Double to append
- 
+
  See UsefulOutBuf_InsertUsefulBuf() for details. This does the same
  with the insertion point at the end of the valid data.
- 
+
  The double will be appended in network byte order (big endian).
  */
 static inline void UsefulOutBuf_AppendDouble(UsefulOutBuf *me, double d){
@@ -1049,15 +1049,15 @@
 
 /**
  @brief Returns the current error status
- 
+
  @param[in] me Pointer to the UsefulOutBuf
- 
+
  @return 0 if all OK, 1 on error
- 
+
  This is the error status since the call to either
  UsefulOutBuf_Reset() of UsefulOutBuf_Init().  Once it goes into error
  state it will stay until one of those functions is called.
- 
+
  Possible error conditions are:
    - bytes to be inserted will not fit
    - insertion point is out of buffer or past valid data
@@ -1073,11 +1073,11 @@
 
 /**
  @brief Returns number of bytes unused used in the output buffer
- 
+
  @param[in] me Pointer to the UsefulOutBuf
- 
+
  @return Number of unused bytes or zero
- 
+
  Because of the error handling strategy and checks in UsefulOutBuf_InsertUsefulBuf()
  it is usually not necessary to use this.
  */
@@ -1090,12 +1090,12 @@
 
 /**
  @brief Returns true / false if some number of bytes will fit in the UsefulOutBuf
- 
+
  @param[in] me Pointer to the UsefulOutBuf
  @param[in] uLen Number of bytes for which to check
- 
+
  @return 1 or 0 if nLen bytes would fit
- 
+
  Because of the error handling strategy and checks in UsefulOutBuf_InsertUsefulBuf()
  it is usually not necessary to use this.
  */
@@ -1108,14 +1108,14 @@
 
 /**
    @brief Returns the resulting valid data in a UsefulOutBuf
- 
+
    @param[in] me Pointer to the UsefulOutBuf.
- 
+
    @return The valid data in UsefulOutBuf.
- 
+
    The storage for the returned data is Storage parameter passed
    to UsefulOutBuf_Init(). See also UsefulOutBuf_CopyOut().
- 
+
    This can be called anytime and many times to get intermediate
    results. It doesn't change the data or reset the current position
    so you can keep adding data.
@@ -1126,12 +1126,12 @@
 
 /**
  @brief Copies the valid data out into a supplied buffer
- 
+
  @param[in] me Pointer to the UsefulOutBuf
  @param[out] Dest The destination buffer to copy into
- 
+
  @return Pointer and length of copied data.
- 
+
  This is the same as UsefulOutBuf_OutUBuf() except it copies the data.
 */
 
@@ -1159,7 +1159,7 @@
  makes sure it never goes off the end of the buffer.  The QCBOR
  implementation parser makes use of this for all its pointer math and
  length checking.
- 
+
  UsefulInputBuf also maintains an internal error state so you do not have
  to. Once data has been requested off the end of the buffer, it goes
  into an error state. You can keep calling functions to get more data
@@ -1167,17 +1167,17 @@
  dereference the NULL, you can wait until all data items have been
  fetched before checking for the error and this can simplify your
  code.
- 
+
  The integer and float parsing expects network byte order (big endian).
  Network byte order is what is used by TCP/IP, CBOR and most internet
  protocols.
- 
+
  Lots of inlining is used to keep code size down. The code optimizer,
  particularly with the -Os, also reduces code size a lot. The only
  non-inline code is UsefulInputBuf_GetBytes() which is less than 100
  bytes so use of UsefulInputBuf doesn't add much code for all the messy
  hard-to-get right issues with parsing in C that is solves.
- 
+
  The parse context size is:
    64-bit machine: 16 + 8 + 2 + 1 (5 bytes padding to align) = 32 bytes
    32-bit machine: 8 + 4 + 2 + 1 (1 byte padding to align) = 16 bytes
@@ -1198,10 +1198,10 @@
 
 /**
  @brief Initialize the UsefulInputBuf structure before use.
- 
+
  @param[in] me Pointer to the UsefulInputBuf instance.
  @param[in] UB Pointer to the data to parse.
- 
+
  */
 static inline void UsefulInputBuf_Init(UsefulInputBuf *me, UsefulBufC UB)
 {
@@ -1214,13 +1214,13 @@
 
 /**
  @brief Returns current position in input buffer
- 
+
  @param[in] me Pointer to the UsefulInputBuf.
- 
+
  @return Integer position of the cursor
- 
+
  The position that the next bytes will be returned from.
- 
+
  */
 static inline size_t UsefulInputBuf_Tell(UsefulInputBuf *me)
 {
@@ -1230,16 +1230,16 @@
 
 /**
  @brief Sets current position in input buffer
- 
+
  @param[in] me Pointer to the UsefulInputBuf.
  @param[in] uPos  Position to set to
- 
+
  If the position is off the end of the input buffer, the error state
  is entered and all functions will do nothing.
- 
+
  Seeking to a valid position in the buffer will not reset the error
  state. Only re initialization will do that.
- 
+
  */
 static inline void UsefulInputBuf_Seek(UsefulInputBuf *me, size_t uPos)
 {
@@ -1254,17 +1254,17 @@
 /**
  @brief Returns the number of bytes from the cursor to the end of the buffer,
  the uncomsummed bytes.
- 
+
  @param[in] me Pointer to the UsefulInputBuf.
 
  @return number of bytes unconsumed or 0 on error.
- 
+
  This is a critical function for input length validation. This does
  some pointer / offset math.
- 
+
  Returns 0 if the cursor it invalid or corruption of the structure is
  detected.
- 
+
  Code Reviewers: THIS FUNCTION DOES POINTER MATH
  */
 static inline size_t UsefulInputBuf_BytesUnconsumed(UsefulInputBuf *me)
@@ -1274,7 +1274,7 @@
    if(me->magic != UIB_MAGIC) {
       return 0;
    }
-   
+
    // The cursor is off the end of the input buffer given
    // Presuming there are no bugs in this code, this should never happen.
    // If it so, the struct was corrupted. The check is retained as
@@ -1282,7 +1282,7 @@
    if(me->cursor > me->UB.len) {
       return 0;
    }
-   
+
    // subtraction can't go neative because of check above
    return me->UB.len - me->cursor;
 }
@@ -1290,11 +1290,11 @@
 
 /**
  @brief Check if there are any unconsumed bytes
- 
+
  @param[in] me Pointer to the UsefulInputBuf.
 
  @return 1 if len bytes are available after the cursor, and 0 if not
- 
+
  */
 static inline int UsefulInputBuf_BytesAvailable(UsefulInputBuf *me, size_t uLen)
 {
@@ -1304,18 +1304,18 @@
 
 /**
  @brief Get pointer to bytes out of the input buffer
- 
+
  @param[in] me Pointer to the UsefulInputBuf.
  @param[in] uNum  Number of bytes to get
- 
+
  @return Pointer to bytes.
- 
+
  This consumes n bytes from the input buffer. It returns a pointer to
  the start of the n bytes.
- 
+
  If there are not n bytes in the input buffer, NULL will be returned
  and an error will be set.
- 
+
  It advances the current position by n bytes.
  */
 const void * UsefulInputBuf_GetBytes(UsefulInputBuf *me, size_t uNum);
@@ -1323,18 +1323,18 @@
 
 /**
  @brief Get UsefulBuf out of the input buffer
- 
+
  @param[in] me Pointer to the UsefulInputBuf.
  @param[in] uNum  Number of bytes to get
- 
+
  @return UsefulBufC with ptr and length for bytes consumed.
- 
+
  This consumes n bytes from the input buffer and returns the pointer
  and len to them as a UsefulBufC. The len returned will always be n.
- 
+
  If there are not n bytes in the input buffer, UsefulBufC.ptr will be
  NULL and UsefulBufC.len will be 0. An error will be set.
- 
+
  It advances the current position by n bytes.
  */
 static inline UsefulBufC UsefulInputBuf_GetUsefulBuf(UsefulInputBuf *me, size_t uNum)
@@ -1350,13 +1350,13 @@
 
 /**
  @brief Get a byte out of the input buffer.
- 
+
  @param[in] me Pointer to the UsefulInputBuf.
- 
+
  @return The byte
- 
+
  This consumes 1 byte from the input buffer. It returns the byte.
- 
+
  If there is not 1 byte in the buffer, 0 will be returned for the byte
  and an error set internally.  You must check the error at some point
  to know whether the 0 was the real value or just returned in error,
@@ -1364,85 +1364,85 @@
  with UsefulInputBuf_GetError().  You can also know you are in the
  error state if UsefulInputBuf_GetBytes() returns NULL or the ptr from
  UsefulInputBuf_GetUsefulBuf() is NULL.
- 
+
  It advances the current position by 1 byte.
  */
 static inline uint8_t UsefulInputBuf_GetByte(UsefulInputBuf *me)
 {
    const void *pResult = UsefulInputBuf_GetBytes(me, sizeof(uint8_t));
-   
+
    return pResult ? *(uint8_t *)pResult : 0;
 }
 
 
 /**
  @brief Get a uint16_t out of the input buffer
- 
+
  @param[in] me Pointer to the UsefulInputBuf.
- 
+
  @return The uint16_t
- 
+
  See UsefulInputBuf_GetByte(). This works the same, except it returns
  a uint16_t and two bytes are consumed.
- 
+
  The input bytes must be in network order (big endian).
  */
 static inline uint16_t UsefulInputBuf_GetUint16(UsefulInputBuf *me)
 {
    const uint8_t *pResult = (const uint8_t *)UsefulInputBuf_GetBytes(me, sizeof(uint16_t));
-   
+
    if(!pResult) {
       return 0;
    }
-   
+
    return  ((uint16_t)pResult[0] << 8) + (uint16_t)pResult[1];
 }
 
 
 /**
  @brief Get a uint32_t out of the input buffer
- 
+
  @param[in] me Pointer to the UsefulInputBuf.
- 
+
  @return The uint32_t
- 
+
  See UsefulInputBuf_GetByte(). This works the same, except it returns
  a uint32_t and four bytes are consumed.
- 
+
  The input bytes must be in network order (big endian).
  */
 static inline uint32_t UsefulInputBuf_GetUint32(UsefulInputBuf *me)
 {
    const uint8_t *pResult = (const uint8_t *)UsefulInputBuf_GetBytes(me, sizeof(uint32_t));
-   
+
    if(!pResult) {
       return 0;
    }
-   
+
    return ((uint32_t)pResult[0]<<24) + ((uint32_t)pResult[1]<<16) + ((uint32_t)pResult[2]<<8) + (uint32_t)pResult[3];
 }
 
 
 /**
  @brief Get a uint64_t out of the input buffer
- 
+
  @param[in] me Pointer to the UsefulInputBuf.
- 
+
  @return The uint64_t
- 
+
  See UsefulInputBuf_GetByte(). This works the same, except it returns
  a uint64_t and eight bytes are consumed.
- 
+
  The input bytes must be in network order (big endian).
  */
 static inline uint64_t UsefulInputBuf_GetUint64(UsefulInputBuf *me)
 {
    const uint8_t *pResult = (const uint8_t *)UsefulInputBuf_GetBytes(me, sizeof(uint64_t));
-   
+
    if(!pResult) {
       return 0;
    }
-   
+
    return   ((uint64_t)pResult[0]<<56) +
             ((uint64_t)pResult[1]<<48) +
             ((uint64_t)pResult[2]<<40) +
@@ -1456,14 +1456,14 @@
 
 /**
  @brief Get a float out of the input buffer
- 
+
  @param[in] me Pointer to the UsefulInputBuf.
- 
+
  @return The float
- 
+
  See UsefulInputBuf_GetByte(). This works the same, except it returns
  a float and four bytes are consumed.
- 
+
  The input bytes must be in network order (big endian).
  */
 static inline float UsefulInputBuf_GetFloat(UsefulInputBuf *me)
@@ -1475,14 +1475,14 @@
 
 /**
  @brief Get a double out of the input buffer
- 
+
  @param[in] me Pointer to the UsefulInputBuf.
- 
+
  @return The double
- 
+
  See UsefulInputBuf_GetByte(). This works the same, except it returns
  a double and eight bytes are consumed.
- 
+
  The input bytes must be in network order (big endian).
  */
 static inline double UsefulInputBuf_GetDouble(UsefulInputBuf *me)
@@ -1495,19 +1495,19 @@
 
 /**
  @brief Get the error status
- 
+
  @param[in] me Pointer to the UsefulInputBuf.
- 
+
  @return The error.
- 
+
  Zero is success, non-zero is error. Once in the error state, the only
  way to clear it is to call Init again.
- 
+
  You may be able to only check the error state at the end after all
  the Get()'s have been done, but if what you get later depends on what
  you get sooner you cannot. For example if you get a length or count
  of following items you will have to check the error.
- 
+
  */
 static inline int UsefulInputBuf_GetError(UsefulInputBuf *me)
 {
diff --git a/inc/q.h b/inc/q.h
new file mode 100644
index 0000000..6da3913
--- /dev/null
+++ b/inc/q.h
@@ -0,0 +1,2592 @@
+/*==============================================================================
+ Copyright (c) 2016-2018, The Linux Foundation.
+ Copyright (c) 2018, Laurence Lundblade.
+ All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of The Linux Foundation nor the names of its
+      contributors, nor the name "Laurence Lundblade" may be used to
+      endorse or promote products derived from this software without
+      specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ ==============================================================================*/
+
+
+/*===================================================================================
+ FILE:  qcbor.h
+
+ DESCRIPTION:  This is the full public API and data structures for QCBOR
+
+ EDIT HISTORY FOR FILE:
+
+ This section contains comments describing changes made to the module.
+ Notice that changes are listed in reverse chronological order.
+
+ when               who             what, where, why
+ --------           ----            ---------------------------------------------------
+ 12/13/18           llundblade      Documentatation improvements
+ 11/29/18           llundblade      Rework to simpler handling of tags and labels.
+ 11/9/18            llundblade      Error codes are now enums.
+ 11/1/18            llundblade      Floating support.
+ 10/31/18           llundblade      Switch to one license that is almost BSD-3.
+ 10/15/18           llundblade      Indefinite length maps and arrays supported
+ 10/8/18            llundblade      Indefinite length strings supported
+ 09/28/18           llundblade      Added bstr wrapping feature for COSE implementation.
+ 07/05/17           llundbla        Add bstr wrapping of maps/arrays for COSE.
+ 03/01/17           llundbla        More data types; decoding improvements and fixes.
+ 11/13/16           llundbla        Integrate most TZ changes back into github version.
+ 09/30/16           gkanike         Porting to TZ.
+ 03/15/16           llundbla        Initial Version.
+
+ =====================================================================================*/
+
+#ifndef __QCBOR__qcbor__
+#define __QCBOR__qcbor__
+
+/*...... This is a ruler that is 80 characters long...........................*/
+
+/* ===========================================================================
+   BEGINNING OF PRIVATE PART OF THIS FILE
+
+   Caller of QCBOR should not reference any of the details below up until
+   the start of the public part.
+   =========================================================================== */
+
+/*
+ Standard integer types are used in the interface to be precise about
+ sizes to be better at preventing underflow/overflow errors.
+ */
+#include <stdint.h>
+#include <stdbool.h>
+#include "UsefulBuf.h"
+
+
+/*
+ The maxium nesting of arrays and maps when encoding or decoding.
+ (Further down in the file there is a definition that refers to this
+ that is public. This is done this way so there can be a nice
+ separation of public and private parts in this file.
+*/
+#define QCBOR_MAX_ARRAY_NESTING1 15 // Do not increase this over 255
+
+
+/*
+ PRIVATE DATA STRUCTURE
+
+ Holds the data for tracking array and map nesting during encoding. Pairs up with
+ the Nesting_xxx functions to make an "object" to handle nesting encoding.
+
+ uStart is a uint32_t instead of a size_t to keep the size of this
+ struct down so it can be on the stack without any concern.  It would be about
+ double if size_t was used instead.
+
+ Size approximation (varies with CPU/compiler):
+    64-bit machine: (15 + 1) * (4 + 2 + 1 + 1 pad) + 8 = 136 bytes
+    32-bit machine: (15 + 1) * (4 + 2 + 1 + 1 pad) + 4 = 132 bytes
+*/
+typedef struct __QCBORTrackNesting {
+   // PRIVATE DATA STRUCTURE
+   struct {
+      // See function OpenArrayInternal() for detailed comments on how this works
+      uint32_t  uStart;     // uStart is the byte position where the array starts
+      uint16_t  uCount;     // Number of items in the arrary or map; counts items in a map, not pairs of items
+      uint8_t   uMajorType; // Indicates if item is a map or an array
+   } pArrays[QCBOR_MAX_ARRAY_NESTING1+1], // stored state for the nesting levels
+   *pCurrentNesting; // the current nesting level
+} QCBORTrackNesting;
+
+
+/*
+ PRIVATE DATA STRUCTURE
+
+ Context / data object for encoding some CBOR. Used by all encode functions to
+ form a public "object" that does the job of encdoing.
+
+ Size approximation (varies with CPU/compiler):
+   64-bit machine: 27 + 1 (+ 4 padding) + 136 = 32 + 136 = 168 bytes
+   32-bit machine: 15 + 1 + 132 = 148 bytes
+*/
+struct _QCBOREncodeContext {
+   // PRIVATE DATA STRUCTURE
+   UsefulOutBuf      OutBuf;  // Pointer to output buffer, its length and position in it
+   uint8_t           uError;  // Error state
+   QCBORTrackNesting nesting; // Keep track of array and map nesting
+};
+
+
+/*
+ PRIVATE DATA STRUCTURE
+
+ Holds the data for array and map nesting for decoding work. This structure
+ and the DecodeNesting_xxx functions form an "object" that does the work
+ for arrays and maps.
+
+ Size approximation (varies with CPU/compiler):
+   64-bit machine: 4 * 16 + 8 = 72
+   32-bit machine: 4 * 16 + 4 = 68
+ */
+typedef struct __QCBORDecodeNesting  {
+  // PRIVATE DATA STRUCTURE
+   struct {
+      uint16_t uCount;
+      uint8_t  uMajorType;
+   } pMapsAndArrays[QCBOR_MAX_ARRAY_NESTING1+1],
+   *pCurrent;
+} QCBORDecodeNesting;
+
+
+/*
+ PRIVATE DATA STRUCTURE
+
+ The decode context. This data structure plus the public QCBORDecode_xxx
+ functions form an "object" that does CBOR decoding.
+
+ Size approximation (varies with CPU/compiler):
+   64-bit machine: 32 + 1 + 1 + 6 bytes padding + 72 + 16 = 128 bytes
+   32-bit machine: 16 + 1 + 1 + 2 bytes padding + 68 + 8  = 68 bytes
+ */
+struct _QCBORDecodeContext {
+   // PRIVATE DATA STRUCTURE
+   UsefulInputBuf InBuf;
+
+   uint8_t        uDecodeMode;
+   uint8_t        bStringAllocateAll;
+
+   QCBORDecodeNesting nesting;
+
+   // This is NULL or points to a QCBORStringAllocator. It is void
+   // here because _QCBORDecodeContext is defined early in the
+   // private part of this file and QCBORStringAllocat is defined
+   // later in the public part of this file.
+   void *pStringAllocator;
+
+   // This is NULL or points to QCBORTagList.
+   // It is type void for the same reason as above.
+   const void *pCallerConfiguredTagList;
+};
+
+// Used internally in the impementation here
+// Must not conflict with any of the official CBOR types
+#define CBOR_MAJOR_NONE_TYPE_RAW  9
+#define CBOR_MAJOR_NONE_TAG_LABEL_REORDER 10
+
+
+/* ===========================================================================
+   END OF PRIVATE PART OF THIS FILE
+
+   BEGINNING OF PUBLIC PART OF THIS FILE
+   =========================================================================== */
+
+
+
+/* ===========================================================================
+   BEGINNING OF CONSTANTS THAT COME FROM THE CBOR STANDARD, RFC 7049
+
+   It is not necessary to use these directly when encoding or decoding
+   CBOR with this implementation.
+   =========================================================================== */
+
+/* Standard CBOR Major type for positive integers of various lengths */
+#define CBOR_MAJOR_TYPE_POSITIVE_INT 0
+
+/* Standard CBOR Major type for negative integer of various lengths */
+#define CBOR_MAJOR_TYPE_NEGATIVE_INT 1
+
+/* Standard CBOR Major type for an array of arbitrary 8-bit bytes. */
+#define CBOR_MAJOR_TYPE_BYTE_STRING  2
+
+/* Standard CBOR Major type for a UTF-8 string. Note this is true 8-bit UTF8
+ with no encoding and no NULL termination */
+#define CBOR_MAJOR_TYPE_TEXT_STRING  3
+
+/* Standard CBOR Major type for an ordered array of other CBOR data items */
+#define CBOR_MAJOR_TYPE_ARRAY        4
+
+/* Standard CBOR Major type for CBOR MAP. Maps an array of pairs. The
+ first item in the pair is the "label" (key, name or identfier) and the second
+ item is the value.  */
+#define CBOR_MAJOR_TYPE_MAP          5
+
+/* Standard CBOR optional tagging. This tags things like dates and URLs */
+#define CBOR_MAJOR_TYPE_OPTIONAL     6
+
+/* Standard CBOR extra simple types like floats and the values true and false */
+#define CBOR_MAJOR_TYPE_SIMPLE       7
+
+
+/*
+ These are special values for the AdditionalInfo bits that are part of the first byte.
+ Mostly they encode the length of the data item.
+ */
+#define LEN_IS_ONE_BYTE    24
+#define LEN_IS_TWO_BYTES   25
+#define LEN_IS_FOUR_BYTES  26
+#define LEN_IS_EIGHT_BYTES 27
+#define ADDINFO_RESERVED1  28
+#define ADDINFO_RESERVED2  29
+#define ADDINFO_RESERVED3  30
+#define LEN_IS_INDEFINITE  31
+
+
+/*
+ 24 is a special number for CBOR. Integers and lengths
+ less than it are encoded in the same byte as the major type
+ */
+#define CBOR_TWENTY_FOUR   24
+
+
+/*
+ Tags that are used with CBOR_MAJOR_TYPE_OPTIONAL. These are
+ the ones defined in the CBOR spec.
+ */
+/** See QCBOREncode_AddDateString() below */
+#define CBOR_TAG_DATE_STRING    0
+/** See QCBOREncode_AddDateEpoch_2() */
+#define CBOR_TAG_DATE_EPOCH     1
+#define CBOR_TAG_POS_BIGNUM     2
+#define CBOR_TAG_NEG_BIGNUM     3
+#define CBOR_TAG_FRACTION       4
+#define CBOR_TAG_BIGFLOAT       5
+
+#define CBOR_TAG_COSE_ENCRYPTO 16
+#define CBOR_TAG_COSE_MAC0     17
+#define CBOR_TAG_COSE_SIGN1    18
+
+/* The data in byte string should be converted in base 64 URL when encoding in JSON or similar text-based representations */
+#define CBOR_TAG_ENC_AS_B64URL 21
+/* The data in byte string should be encoded in base 64 when encoding in JSON */
+#define CBOR_TAG_ENC_AS_B64    22
+/* The data in byte string should be encoded in base 16 when encoding in JSON */
+#define CBOR_TAG_ENC_AS_B16    23
+#define CBOR_TAG_CBOR          24
+/** The data in the string is a URIs, as defined in RFC3986 */
+#define CBOR_TAG_URI           32
+/** The data in the string is a base 64'd URL */
+#define CBOR_TAG_B64URL        33
+/** The data in the string is base 64'd */
+#define CBOR_TAG_B64           34
+/** regular expressions in Perl Compatible Regular Expressions (PCRE) / JavaScript syntax ECMA262. */
+#define CBOR_TAG_REGEX         35
+/** MIME messages (including all headers), as defined in RFC2045 */
+#define CBOR_TAG_MIME          36
+/** Binary UUID */
+#define CBOR_TAG_BIN_UUID      37
+
+#define CBOR_TAG_CWT           61
+
+#define CBOR_TAG_ENCRYPT       96
+#define CBOR_TAG_MAC           97
+#define CBOR_TAG_SIGN          98
+
+#define CBOR_TAG_GEO_COORD    103
+
+
+/** The data is CBOR data */
+#define CBOR_TAG_CBOR_MAGIC 55799
+#define CBOR_TAG_NONE  UINT64_MAX
+
+
+/*
+ Values for the 5 bits for items of major type 7
+ */
+#define CBOR_SIMPLEV_FALSE   20
+#define CBOR_SIMPLEV_TRUE    21
+#define CBOR_SIMPLEV_NULL    22
+#define CBOR_SIMPLEV_UNDEF   23
+#define CBOR_SIMPLEV_ONEBYTE 24
+#define HALF_PREC_FLOAT      25
+#define SINGLE_PREC_FLOAT    26
+#define DOUBLE_PREC_FLOAT    27
+#define CBOR_SIMPLE_BREAK    31
+
+
+
+/* ===========================================================================
+
+ END OF CONSTANTS THAT COME FROM THE CBOR STANDARD, RFC 7049
+
+ BEGINNING OF PUBLIC INTERFACE FOR QCBOR ENCODER / DECODER
+
+ =========================================================================== */
+
+/**
+
+ @file qcbor.h
+
+ Q C B O R   E n c o d e / D e c o d e
+
+ This implements CBOR -- Concise Binary Object Representation as defined
+ in RFC 7049. More info is at http://cbor.io.  This is a near-complete
+ implementation of the specification. Limitations are listed further down.
+
+ 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.
+
+ The memory model for encoding and decoding is that encoded CBOR
+ must be in a contiguous buffer in memory.  During encoding the
+ caller must supply an output buffer and if the encoding would go
+ off the end of the buffer an error is returned.  During decoding
+ the caller supplies the encoded CBOR in a contiguous buffer
+ and the decoder returns pointers and lengths into that buffer
+ for strings.
+
+ This implementation does not require malloc. All data structures
+ passed in/out of the APIs can fit on the stack.
+
+ Decoding of indefinite length strings is a special case that requires
+ a "string allocator" to allocate memory into which the segments of
+ the string are coalesced. Without this, decoding will error out if
+ an indefinite length string is encountered (indefinite length maps
+ and arrays do not require the string allocator). A simple string
+ allocator called MemPool is built-in and will work if supplied with
+ a block of memory to allocate. The string allocator can optionally
+ use malloc() or some other custom scheme.
+
+ Here are some terms and definitions:
+
+ - "Item", "Data Item": An integer or string or such. The basic "thing" that
+ CBOR is about. An array is an item itself that contains some items.
+
+ - "Array": An ordered sequence of items, the same as JSON.
+
+ - "Map": A collection of label/value pairs. Each pair is a data
+ item. A JSON "object" is the same as a CBOR "map".
+
+ - "Label": The data item in a pair in a map that names or identifies the
+ pair, not the value. This implementation refers to it as a "label".
+ JSON refers to it as the "name". The CBOR RFC refers to it this as a "key".
+ This implementation chooses label instead because key is too easily confused
+ with a cryptographic key. The COSE standard, which uses CBOR, has also
+ chosen to use the term "label" rather than "key" for this same reason.
+
+ - "Key": See "Label" above.
+
+ - "Tag": Optional info that can be added before each data item. This is always
+ CBOR major type 6.
+
+ - "Initial Byte": The first byte of an encoded item. Encoding and decoding of
+ this byte is taken care of by the implementation.
+
+ - "Additional Info": In addition to the major type, all data items have some
+ other info. This is usually the length of the data, but can be several
+ other things. Encoding and decoding of this is taken care of by the
+ implementation.
+
+ CBOR has two mechanisms for tagging and labeling the data
+ values like integers and strings. For example, an integer that
+ represents someone's birthday in epoch seconds since Jan 1, 1970
+ could be encoded like this:
+
+ - First it is CBOR_MAJOR_TYPE_POSITIVE_INT, the primitive positive
+ integer.
+ - Next it has a "tag" CBOR_TAG_DATE_EPOCH indicating the integer
+ represents a date in the form of the number of seconds since
+ Jan 1, 1970.
+ - Last it has a string "label" like "BirthDate" indicating
+ the meaning of the data.
+
+ The encoded binary looks like this:
+   a1                      # Map of 1 item
+      69                   # Indicates text string of 9 bytes
+        426972746844617465 # The text "BirthDate"
+     c1                    # Tags next int as epoch date
+        1a                 # Indicates 4 byte integer
+            580d4172       # unsigned integer date 1477263730
+
+ Implementors using this API will primarily work with labels. Generally
+ tags are only needed for making up new data types. This implementation
+ covers most of the data types defined in the RFC using tags. It also,
+ allows for the creation of news tags if necessary.
+
+ This implementation explicitly supports labels that are text strings
+ and integers. Text strings translate nicely into JSON objects and
+ are very readable.  Integer labels are much less readable, but
+ can be very compact. If they are in the range of -23 to
+ 23 they take up only one byte.
+
+ CBOR allows a label to be any type of data including an array or
+ a map. It is possible to use this API to construct and
+ parse such labels, but it is not explicitly supported.
+
+ 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
+ encoder is invoked again, this time with the output buffer.
+
+ The double invocation is not required if the max output buffer size
+ can be predicted. This is usually possible for simple CBOR structures.
+ If the double invocation is implemented, it can be
+ in a loop or function as in the example code so that the code doesn't
+ have to actually be written twice, saving code size.
+
+ If a buffer too small to hold the encoded output is given, the error
+ QCBOR_ERR_BUFFER_TOO_SMALL will be returned. Data will never be
+ written off the end of the output buffer no matter which functions
+ here are called or what parameters are passed to them.
+
+ The error handling is simple. The only possible errors are trying to
+ encode structures that are too large or too complex. There are no
+ internal malloc calls so there will be no failures for out of memory.
+ Only the final call, QCBOREncode_Finish(), returns an error code.
+ Once an error happens, the encoder goes into an error state and calls
+ to it will do nothing so the encoding can just go on. An error
+ check is not needed after every data item is added.
+
+ Encoding generally proceeds by calling QCBOREncode_Init(), calling
+ lots of "Add" functions and calling QCBOREncode_Finish(). There
+ are many "Add" functions for various data types. The input
+ buffers need only to be valid during the "Add" calls. The
+ data is copied into the output buf during the "Add" call.
+
+ There are three `Add` functions for each data type. The first
+ / main one for the type is for adding the data item to an array.
+ The second one's name ends in `ToMap`, is used for adding
+ data items to maps and takes a string
+ argument that is its label in the map. The third one ends in
+ `ToMapN`, is also used for adding data items to maps, and
+ takes an integer argument that is its label in the map.
+
+ The simplest aggregate type is an array, which is a simple ordered
+ set of items without labels the same as JSON arrays. Call
+ QCBOREncode_OpenArray() to open a new array, then "Add" to
+ put items in the array and then QCBOREncode_CloseArray(). Nesting
+ to a limit is allowed.  All opens must be matched by closes or an
+ encoding error will be returned.
+
+ The other aggregate type is a map which does use labels. The
+ `Add` functions that end in `ToMap` and `ToMapN` are convenient
+ ways to add labeled data items to a map. You can also call
+ any type of `Add` function once to add a label of any time and
+ then call any type of `Add` again to add its value.
+
+ Note that when you nest arrays or maps in a map, the nested
+ array or map has a label.
+
+ Usually it is not necessary to add tags explicitly as most
+ tagged types have functions here, but they can be added by
+ calling QCBOREncode_AddTag().  There is an IANA registry for new tags that are
+ for broad use and standardization as per RFC 7049. It is also
+ allowed for protocols to make up new tags in the range above 256.
+ Note that even arrays and maps can be tagged.
+
+ Summary Limits of this implementation:
+ - The entire encoded CBOR must fit into contiguous memory.
+ - Max size of encoded / decoded CBOR data is UINT32_MAX (4GB).
+ - Max array / map nesting level when encoding / decoding is
+   QCBOR_MAX_ARRAY_NESTING (this is typically 15).
+ - Max items in an array or map when encoding / decoding is
+   QCBOR_MAX_ITEMS_IN_ARRAY (typically 65,536).
+ - Does not support encoding indefinite lengths (decoding is supported).
+ - Does not directly support some tagged types: decimal fractions, big floats
+ - Does not directly support labels in maps other than text strings and ints.
+ - Does not directly support int labels greater than INT64_MAX
+ - Epoch dates limited to INT64_MAX (+/- 292 billion years)
+ - Tags on labels are ignored during decoding
+
+ This implementation is intended to run on 32 and 64-bit CPUs. It
+ will probably work on 16-bit CPUs but less efficiently.
+
+ The public interface uses size_t for all lengths. Internally the
+ implementation uses 32-bit lengths by design to use less memory and
+ fit structures on the stack. This limits the encoded
+ CBOR it can work with to size UINT32_MAX (4GB) which should be
+ enough.
+
+ This implementation assumes two's compliment integer
+ machines. Stdint.h also requires this. It of course would be easy to
+ fix this implementation for another integer representation, but all
+ modern machines seem to be two's compliment.
+
+ */
+
+
+/**
+ The maximum number of items in a single array or map when encoding of decoding.
+*/
+#define QCBOR_MAX_ITEMS_IN_ARRAY (UINT16_MAX) // This value is 65,535 a lot of items for an array
+
+/**
+ The maximum nesting of arrays and maps when encoding or decoding. The
+ error QCBOR_ERR_ARRAY_NESTING_TOO_DEEP will be returned on encoding
+ of decoding if it is exceeded
+*/
+#define QCBOR_MAX_ARRAY_NESTING  QCBOR_MAX_ARRAY_NESTING1
+
+/**
+ The maximum number of tags that can be in QCBORTagListIn and passed to
+ QCBORDecode_SetCallerConfiguredTagList()
+ */
+#define QCBOR_MAX_CUSTOM_TAGS    16
+
+
+typedef enum {
+   /** The encode or decode completely correctly. */
+   QCBOR_SUCCESS = 0,
+
+   /** The buffer provided for the encoded output when doing encoding was
+       too small and the encoded output will not fit. Also, when the buffer
+       given to QCBORDecode_SetMemPool() is too small. */
+   QCBOR_ERR_BUFFER_TOO_SMALL,
+
+   /** During encoding or decoding, the array or map nesting was deeper than
+    this implementation can handle. Note that in the interest of code size
+    and memory use, this implementation has a hard limit on array nesting. The
+    limit is defined as the constant QCBOR_MAX_ARRAY_NESTING. */
+   QCBOR_ERR_ARRAY_NESTING_TOO_DEEP,
+
+   /** During decoding or encoding, the array or map had too many items in it.
+       This limit QCBOR_MAX_ITEMS_IN_ARRAY, typically 65,535. */
+   QCBOR_ERR_ARRAY_TOO_LONG,
+
+   /** During encoding, more arrays or maps were closed than opened. This is a
+       coding error on the part of the caller of the encoder. */
+   QCBOR_ERR_TOO_MANY_CLOSES,
+
+   /** During decoding, some CBOR construct was encountered that this decoder
+        doesn't support, primarily this is the reserved additional info values,
+        28 through 30. */
+   QCBOR_ERR_UNSUPPORTED,
+
+   /** During decoding, hit the end of the given data to decode. For example,
+       a byte string of 100 bytes was expected, but the end of the input was
+       hit before finding those 100 bytes.  Corrupted CBOR input will often
+       result in this error. */
+   QCBOR_ERR_HIT_END,
+
+   /** During encoding, the length of the input buffer was too large. This might
+       happen on a 64-bit machine when a buffer larger than UINT32_MAX is passed.
+     */
+   QCBOR_ERR_BUFFER_TOO_LARGE,
+
+   /** During decoding, an integer smaller than INT64_MIN was received (CBOR
+       can represent integers smaller than INT64_MIN, but C cannot). */
+   QCBOR_ERR_INT_OVERFLOW,
+
+   /** During decoding, the label for a map entry is bad. What causes this
+       error depends on the decoding mode. */
+   QCBOR_ERR_MAP_LABEL_TYPE,
+
+   /** During encoding or decoding, the number of array or map opens was not
+       matched by the number of closes. */
+   QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN,
+
+   /** During encoding, the simple value is not between CBOR_SIMPLEV_FALSE
+       and CBOR_SIMPLEV_UNDEF. */
+   QCBOR_ERR_BAD_SIMPLE,
+
+   /** During decoding, a date greater than +- 292 billion years from Jan 1
+       1970 encountered during parsing. */
+   QCBOR_ERR_DATE_OVERFLOW,
+
+   /** During decoding, the CBOR is not valid, primarily a simple type is encoded in
+      a prohibited way. */
+   QCBOR_ERR_INVALID_CBOR,
+
+   /** Optional tagging that doesn't make sense (an int is tagged as a
+       date string) or can't be handled. */
+   QCBOR_ERR_BAD_OPT_TAG,
+
+   /** Returned by QCBORDecode_Finish() if all the inputs bytes have not
+       been consumed. */
+   QCBOR_ERR_EXTRA_BYTES,
+
+   /** During encoding, QCBOREncode_Close() call with a different type than
+       is currently open. */
+   QCBOR_ERR_CLOSE_MISMATCH,
+
+   /** Unable to decode an indefinite length string because no string
+       allocator was configured. */
+   QCBOR_ERR_NO_STRING_ALLOCATOR,
+
+   /** One of the chunks in an indefinite length string is not of the type of
+       the string. */
+   QCBOR_ERR_INDEFINITE_STRING_CHUNK,
+
+   /** Error allocating space for a string, usually for an indefinite length
+       string. */
+   QCBOR_ERR_STRING_ALLOCATE,
+
+   /** During decoding, a break occurred outside an indefinite length item. */
+   QCBOR_ERR_BAD_BREAK,
+
+   /** During decoding, too many tags in the caller-configured tag list, or not
+       enough space in QCBORTagListOut. */
+   QCBOR_ERR_TOO_MANY_TAGS
+
+} QCBORError;
+
+
+typedef enum {
+   /** See QCBORDecode_Init() */
+   QCBOR_DECODE_MODE_NORMAL = 0,
+   /** See QCBORDecode_Init() */
+   QCBOR_DECODE_MODE_MAP_STRINGS_ONLY = 1,
+   /** See QCBORDecode_Init() */
+   QCBOR_DECODE_MODE_MAP_AS_ARRAY = 2
+} QCBORDecodeMode;
+
+
+
+
+
+/* Do not renumber these. Code depends on some of these values. */
+/** The type is unknown, unset or invalid */
+#define QCBOR_TYPE_NONE           0
+/** Type for an integer that decoded either between INT64_MIN and INT32_MIN or INT32_MAX and INT64_MAX; val.int64 */
+#define QCBOR_TYPE_INT64          2
+/** Type for an integer that decoded to a more than INT64_MAX and UINT64_MAX; val.uint64 */
+#define QCBOR_TYPE_UINT64         3
+/** Type for an array. The number of items in the array is in val.uCount. */
+#define QCBOR_TYPE_ARRAY          4
+/** Type for a map; number of items in map is in val.uCount */
+#define QCBOR_TYPE_MAP            5
+/** Type for a buffer full of bytes. Data is in val.string. */
+#define QCBOR_TYPE_BYTE_STRING    6
+/** Type for a UTF-8 string. It is not NULL terminated. Data is in val.string.  */
+#define QCBOR_TYPE_TEXT_STRING    7
+/** Type for a positive big number. Data is in val.bignum, a pointer and a length. */
+#define QCBOR_TYPE_POSBIGNUM     9
+/** Type for a negative big number. Data is in val.bignum, a pointer and a length. */
+#define QCBOR_TYPE_NEGBIGNUM     10
+/** Type for RFC 3339 date string, possibly with time zone. Data is in val.dateString */
+#define QCBOR_TYPE_DATE_STRING   11
+/** Type for integer seconds since Jan 1970 + floating point fraction. Data is in val.epochDate */
+#define QCBOR_TYPE_DATE_EPOCH    12
+/** A simple type that this CBOR implementation doesn't know about; Type is in val.uSimple. */
+#define QCBOR_TYPE_UKNOWN_SIMPLE 13
+/** Type for the simple value false; nothing more; nothing in val union. */
+#define QCBOR_TYPE_FALSE         20
+/** Type for the simple value true; nothing more; nothing in val union. */
+#define QCBOR_TYPE_TRUE          21
+/** Type for the simple value null; nothing more; nothing in val union. */
+#define QCBOR_TYPE_NULL          22
+/** Type for the simple value undef; nothing more; nothing in val union. */
+#define QCBOR_TYPE_UNDEF         23
+/** Type for a floating point number. Data is in val.float. */
+#define QCBOR_TYPE_FLOAT         26
+/** Type for a double floating point number. Data is in val.double. */
+#define QCBOR_TYPE_DOUBLE        27
+/** For QCBOR_DECODE_MODE_MAP_AS_ARRAY decode mode, a map that is being traversed as an array. See QCBORDecode_Init() */
+#define QCBOR_TYPE_MAP_AS_ARRAY  32
+
+#define QCBOR_TYPE_BREAK         31 // Used internally; never returned
+
+#define QCBOR_TYPE_OPTTAG       254 // Used internally; never returned
+
+
+
+/*
+ Approx Size of this:
+   8 + 8 + 1 + 1 + 1 + (1 padding) + (4 padding on 64-bit machine) = 24 for first part (20 on a 32-bit machine)
+   16 bytes for the val union
+   16 bytes for label union
+   total = 56 bytes (52 bytes on 32-bit machine)
+ */
+
+/**
+ QCBORItem holds the type, value and other info for a decoded item returned by GetNextItem().
+ */
+typedef struct _QCBORItem {
+   uint8_t  uDataType;     /** Tells what element of the val union to use. One of QCBOR_TYPE_XXXX */
+   uint8_t  uNestingLevel; /** How deep the nesting from arrays and maps are. 0 is the top level with no arrays or maps entered */
+   uint8_t  uLabelType;    /** Tells what element of the label union to use */
+   uint8_t  uDataAlloc;    /** 1 if allocated with string allocator, 0 if not. See QCBORDecode_MakeMallocStringAllocator() */
+   uint8_t  uLabelAlloc;   /** Like uDataAlloc, but for label */
+   uint8_t  uNextNestLevel; /** If not equal to uNestingLevel, this item closed out at least one map/array */
+
+   union {
+      int64_t     int64;      /** The value for uDataType QCBOR_TYPE_INT64 */
+      uint64_t    uint64;     /** The value for uDataType QCBOR_TYPE_UINT64 */
+
+      UsefulBufC  string;     /** The value for uDataType QCBOR_TYPE_BYTE_STRING and QCBOR_TYPE_TEXT_STRING */
+      uint16_t    uCount;     /** The "value" for uDataType QCBOR_TYPE_ARRAY or QCBOR_TYPE_MAP -- the number of items in the array or map
+                                  UINT16_MAX when decoding indefinite lengths maps and arrays. */
+      double      dfnum;      /** The value for uDataType QCBOR_TYPE_DOUBLE */
+      struct {
+         int64_t  nSeconds;
+         double   fSecondsFraction;
+      } epochDate;            /** The value for uDataType QCBOR_TYPE_DATE_EPOCH */
+      UsefulBufC  dateString; /** The value for uDataType QCBOR_TYPE_DATE_STRING */
+      UsefulBufC  bigNum;     /** The value for uDataType QCBOR_TYPE_BIGNUM */
+      uint8_t     uSimple;    /** The integer value for unknown simple types */
+      uint64_t    uTagV;
+
+   } val;  /** The union holding the item's value. Select union member based on uDataType */
+
+   union {
+      UsefulBufC  string;  /** The label for uLabelType QCBOR_TYPE_BYTE_STRING and QCBOR_TYPE_TEXT_STRING */
+      int64_t     int64;   /** The label for uLabelType for QCBOR_TYPE_INT64 */
+      uint64_t    uint64;  /** The label for uLabelType for QCBOR_TYPE_UINT64 */
+   } label; /** Union holding the different label types selected based on uLabelType */
+
+   uint64_t uTagBits; /** Bit indicating which tags (major type 6) on this item.  */
+
+} QCBORItem;
+
+
+/**
+ This is a set of functions and pointer context (in object-oriented parlance,
+ an "object") used to allocate memory for coalescing the segments of an indefinite
+ length string into one.
+
+ The fAllocate function works as an initial allocator and a reallocator to
+ expand the string for each new segment. When it is an initial allocator
+ pOldMem is NULL.
+
+ The fFree function is called to clean up an individual allocation when an error occurs.
+
+ The fDesctructor function is called when QCBORDecode_Finish is called.
+
+ Any memory allocated with this will be marked by setting uDataAlloc
+ or uLabelAlloc in the QCBORItem structure so the caller knows they
+ have to free it.
+
+ fAllocate is only ever called to increase the single most recent
+ allocation made, making implementation of a memory pool very simple.
+
+ fFree is also only called on the single most recent allocation.
+ */
+typedef struct {
+   void       *pAllocaterContext;
+   UsefulBuf (*fAllocate)(void *pAllocaterContext, void *pOldMem, size_t uNewSize);
+   void      (*fFree)(void *pAllocaterContext, void *pMem);
+   void      (*fDestructor)(void *pAllocaterContext);
+} QCBORStringAllocator;
+
+
+
+/**
+ This is used to tell the decoder about tags that it should
+ record in uTagBits in QCBORItem beyond the built-in
+ tags. puTags points to an
+ array of uint64_t integers that are the tags. uNumTags
+ is the number of integers in the array. The maximum
+ size is QCBOR_MAX_CUSTOM_TAGS.  See QCBORDecode_IsTagged()
+ and QCBORDecode_SetCallerAddedTagMap().
+ */
+typedef struct {
+   uint8_t uNumTags;
+   const uint64_t *puTags;
+} QCBORTagListIn;
+
+
+/**
+ This is for QCBORDecode_GetNextWithTags() to be able to return the
+ full list of tags on an item. It not needed for most CBOR protocol
+ implementations. Its primary use is for pretty-printing CBOR or
+ protocol conversion to another format.
+
+ On input, puTags points to a buffer to be filled in
+ and uNumAllocated is the number of uint64_t values
+ in the buffer.
+
+ On output the buffer contains the tags for the item.
+ uNumUsed tells how many there are.
+ */
+typedef struct {
+   uint8_t uNumUsed;
+   uint8_t uNumAllocated;
+   uint64_t *puTags;
+} QCBORTagListOut;
+
+
+/**
+ QCBOREncodeContext is the data type that holds context for all the
+ encoding functions. It is less than 200 bytes, so it can go on
+ the stack. The contents are opaque, and the caller should not access
+ any internal items.  A context may be re used serially as long as
+ it is re initialized.
+ */
+typedef struct _QCBOREncodeContext QCBOREncodeContext;
+
+
+/**
+ Initialize the the encoder to prepare to encode some CBOR.
+
+ @param[in,out]  pCtx    The encoder context to initialize.
+ @param[in]      Storage The buffer into which this encoded result will be placed.
+
+ Call this once at the start of an encoding of a CBOR structure. Then
+ call the various QCBOREncode_AddXXX() functions to add the data
+ items. Then call QCBOREncode_Finish().
+
+ The maximum output buffer is UINT32_MAX (4GB). This is not a practical
+ limit in any way and reduces the memory needed by the implementation.
+ The error QCBOR_ERR_BUFFER_TOO_LARGE will be returned by QCBOR_Finish()
+ if a larger buffer length is passed in.
+
+ If this is called with pBuf as NULL and uBufLen a large value like
+ UINT32_MAX, all the QCBOREncode_AddXXXX() functions and
+ QCBORE_Encode_Finish() can still be called. No data will be encoded,
+ but the length of what would be encoded will be calculated. The
+ length of the encoded structure will be handed back in the call to
+ QCBOREncode_Finish(). You can then allocate a buffer of that size
+ and call all the encoding again, this time to fill in the buffer.
+
+ A QCBORContext can be reused over and over as long as
+ QCBOREncode_Init() is called.
+ */
+void QCBOREncode_Init(QCBOREncodeContext *pCtx, UsefulBuf Storage);
+
+
+/**
+ @brief  Add a signed 64-bit integer to the encoded output.
+
+ @param[in] pCtx      The encoding context to add the integer to.
+ @param[in] nNum      The integer to add.
+
+ The integer will be encoded and added to the CBOR output.
+
+ This function figures out the size and the sign and encodes in the
+ correct minimal CBOR. Specifically, it will select CBOR major type 0 or 1
+ based on sign and will encode to 1, 2, 4 or 8 bytes depending on the
+ value of the integer. Values less than 24 effectively encode to one
+ byte because they are encoded in with the CBOR major type.  This is
+ a neat and efficient characteristic of CBOR that can be taken
+ advantage of when designing CBOR-based protocols. If integers like
+ tags 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 int16_t or a small value, say 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 7049
+ Appendix A for more examples of CBOR encoding. This compact encoding
+ is also canonical CBOR as per section 3.9 in RFC 7049.
+
+ There are no functions to add int16_t or 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).
+
+ If the encoding context is in an error state, this will do
+ nothing. If an error occurs when adding this integer, the internal
+ error flag will be set, and the error will be returned when
+ QCBOREncode_Finish() is called.
+
+ See also QCBOREncode_AddUInt64().
+ */
+void QCBOREncode_AddInt64(QCBOREncodeContext *pCtx, int64_t nNum);
+
+static void QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum);
+
+static void QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum);
+
+
+/**
+ @brief  Add an unsigned 64-bit integer to the encoded output.
+
+ @param[in] pCtx      The encoding context to add the integer to.
+ @param[in] uNum      The integer to add.
+
+ The integer will be encoded and added to the CBOR output.
+
+ The only reason so use this function is for integers larger than
+ INT64_MAX and smaller than UINT64_MAX. Otherwise QCBOREncode_AddInt64()
+ will work fine.
+
+ Error handling is the same as for QCBOREncode_AddInt64().
+ */
+void QCBOREncode_AddUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
+
+static void QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum);
+
+static void QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum);
+
+
+/**
+
+ @brief  Add a UTF-8 text string to the encoded output
+
+ @param[in] pCtx     The context to initialize.
+ @param[in] Text    Pointer and length of text to add.
+
+ The text passed in must be unencoded UTF-8 according to RFC
+ 3629. There is no NULL termination. The text is added as CBOR
+ major type 3.
+
+ If called with nBytesLen equal to 0, an empty string will be
+ added. When nBytesLen is 0, pBytes may be NULL.
+
+ Note that the restriction of the buffer length to an uint32_t is
+ entirely intentional as this encoder is not capable of encoding
+ lengths greater. This limit to 4GB for a text string should not be a
+ problem.
+
+ Error handling is the same as QCBOREncode_AddInt64().
+ */
+static void QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text);
+
+static void QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text);
+
+static void QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text);
+
+
+/**
+ @brief  Add a UTF-8 text string to the encoded output
+
+ @param[in] pCtx      The context to initialize.
+ @param[in] szString  Null-terminated text to add.
+
+ This works the same as QCBOREncode_AddText().
+ */
+static void QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString);
+
+static void QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString);
+
+static void QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString);
+
+
+/**
+ @brief  Add a floating-point number to the encoded output
+
+ @param[in] pCtx      The encoding context to add the float to.
+ @param[in] dNum      The double precision number to add.
+
+ This outputs a floating-point number with CBOR major type 7.
+
+ This will selectively encode the double-precision floating point number as either
+ double-precision, single-precision or half-precision. It will always encode infinity, NaN and 0
+ has 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.
+
+ Half-precision floating point numbers take up 2 bytes, half that of single-precision,
+ one quarter of double-precision
+
+ This automatically reduces the size of encoded messages a lot, maybe even by four if most of values are
+ 0, infinity or NaN.
+
+ On decode, these will always be returned as a double.
+
+ Error handling is the same as QCBOREncode_AddInt64().
+ */
+void QCBOREncode_AddDouble(QCBOREncodeContext *pCtx, double dNum);
+
+static void QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
+
+static void QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
+
+
+/**
+ @brief[in] Add an optional tag
+
+ @param[in] pCtx  The encoding context to add the integer to.
+ @param[in] uTag  The tag to add
+
+ This outputs a CBOR major type 6 optional tag.
+
+ The tag is applied to the next data item added to the encoded
+ output. That data item that is to be tagged can be of any major
+ CBOR type. Any number of tags can be added to a data item by calling
+ this multiple times before the data item is added.
+
+ For many of the common standard tags a function to encode
+ data using it already exists and this is not needed. For example,
+ QCBOREncode_AddDateEpoch() already exists to output
+ integers representing dates with the right tag.
+*/
+void QCBOREncode_AddTag(QCBOREncodeContext *pCtx,uint64_t uTag);
+
+
+/**
+ @brief  Add an epoch-based date
+
+ @param[in] pCtx     The encoding context to add the simple value to.
+ @param[in] date     Number of seconds since 1970-01-01T00:00Z in UTC time.
+
+ As per RFC 7049 this is similar to UNIX/Linux/POSIX dates. This is
+ the most compact way to specify a date and time in CBOR. Note that this
+ is always UTC and does not include the time zone.  Use
+ QCBOREncode_AddDateString() if you want to include the time zone.
+
+ The integer encoding rules apply here so the date will be encoded in a
+ minimal number of 1, 2 4 or 8 bytes. Until about the year 2106 these
+ dates should encode in 6 bytes -- one byte for the tag, one byte for the type
+ and 4 bytes for the integer.
+
+ If you care about leap-seconds and that level of accuracy, make sure the
+ system you are running this code on does it correctly. This code just takes
+ the value passed in.
+
+ This implementation cannot encode fractional seconds using float or double
+ even though that is allowed by CBOR, but you can encode them if you
+ want to by calling QCBOREncode_AddDouble()
+ with the right parameters.
+
+ Error handling is the same as QCBOREncode_AddInt64().
+ */
+static void QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx, int64_t date);
+
+static void QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t date);
+
+static  void QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t date);
+
+
+/**
+ @brief Add a byte string to the encoded output.
+
+ @param[in] pCtx      The context to initialize.
+ @param[in] Bytes     Pointer and length of the input data.
+
+ Simply adds the bytes to the encoded output as CBOR major type 2.
+
+ If called with Bytes.len equal to 0, an empty string will be
+ added. When Bytes.len is 0, Bytes.ptr may be NULL.
+
+ Error handling is the same as QCBOREncode_AddInt64().
+ */
+static void QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
+
+static void QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
+
+static void QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
+
+
+
+/**
+ @brief Add a binary UUID to the encoded output.
+
+ @param[in] pCtx      The context to initialize.
+ @param[in] Bytes     Pointer and length of the binary UUID.
+
+ A binary UUID as defined in RFC 4122 is added to the ouput.
+
+ It is output as CBOR major type 2, a binary string, with
+ optional tag 36 indicating the binary string is a UUID.
+ */
+static void QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
+
+static void QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
+
+static void QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
+
+
+/**
+ @brief Add a positive big number to the encoded output.
+
+ @param[in] pCtx      The context to initialize.
+ @param[in] Bytes     Pointer and length of the big number.
+
+ Big numbers are integers larger than 64-bits. Their format
+ is described in RFC 7049.
+
+ It is output as CBOR major type 2, a binary string, with
+ optional tag 2 indicating the binary string is a positive big
+ number.
+
+ Often big numbers are used to represent cryptographic keys,
+ however, COSE which defines representations for keys chose not
+ to use this particular type.
+ */
+static void QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
+
+static void QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
+
+static void QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
+
+
+/**
+ @brief Add a negative big number to the encoded output.
+
+ @param[in] pCtx      The context to initialize.
+ @param[in] Bytes     Pointer and length of the big number.
+
+ Big numbers are integers larger than 64-bits. Their format
+ is described in RFC 7049.
+
+ It is output as CBOR major type 2, a binary string, with
+ optional tag 2 indicating the binary string is a negative big
+ number.
+
+ Often big numbers are used to represent cryptographic keys,
+ however, COSE which defines representations for keys chose not
+ to use this particular type.
+ */
+static void QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
+
+static void QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
+
+static void QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
+
+
+/**
+ @brief Add a text URI to the encoded output.
+
+ @param[in] pCtx    The context to initialize.
+ @param[in] URI     Pointer and length of the URI.
+
+ The format of URI is RFC 3986.
+
+ It is output as CBOR major type 3, a text string, with
+ optional tag 32 indicating the text string is a URI.
+ */
+static void QCBOREncode_AddURI(QCBOREncodeContext *pCtx, UsefulBufC URI);
+
+static void QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC URI);
+
+static void QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC URI);
+
+
+/**
+ @brief Add base 64-encoded text to encoded output.
+
+ @param[in] pCtx     The context to initialize.
+ @param[in] B64Text  Pointer and length of the base-64 encoded text.
+
+ The text content is base 64 encoded data per RFC 4648.
+
+ It is output as CBOR major type 3, a text string, with
+ optional tag 34 indicating the text string is a URI.
+ */
+static void QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx, UsefulBufC B64Text);
+
+static void QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text);
+
+static void QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text);
+
+
+/**
+ @brief Add base 64URL -encoded URL to encoded output.
+
+ @param[in] pCtx    The context to initialize.
+ @param[in] B64Text  Pointer and length of the base-64 encoded text.
+
+ The text content is base 64 URL format encoded text as per RFC 4648.
+
+ It is output as CBOR major type 3, a text string, with
+ optional tag 33 indicating the text string is a URI.
+ */
+static void QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx, UsefulBufC B64Text);
+
+static void QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text);
+
+static void QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text);
+
+
+/**
+ @brief Add Perl Compatible Regular Expression
+
+ @param[in] pCtx    The context to initialize.
+ @param[in] Regex   Pointer and length of the regular expression.
+
+ The text content is Perl Compatible Regular
+ Expressions (PCRE) / JavaScript syntax [ECMA262].
+
+ It is output as CBOR major type 3, a text string, with
+ optional tag 35 indicating the text string is a regular expression.
+ */
+static void QCBOREncode_AddRegex(QCBOREncodeContext *pCtx, UsefulBufC Regex);
+
+static void QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Regex);
+
+static void QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Regex);
+
+
+/**
+ @brief MIME encoded text to the encoded output.
+
+ @param[in] pCtx      The context to initialize.
+ @param[in] MIMEData  Pointer and length of the regular expression.
+
+ The text content is in MIME format per RFC 2045 including the headers.
+
+ It is output as CBOR major type 3, a text string, with
+ optional tag 36 indicating the text string is MIME data.
+ */
+static void QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx, UsefulBufC MIMEData);
+
+static void QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC MIMEData);
+
+static void QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC MIMEData);
+
+
+/**
+ @brief  Add an RFC 3339 date string
+
+ @param[in] pCtx      The encoding context to add the simple value to.
+ @param[in] szDate    Null-terminated string with date to add
+
+ The string szDate should be in the form of RFC 3339 as defined by section
+ 3.3 in RFC 4287. This is as described in section 2.4.1 in RFC 7049.
+
+ Note that this function doesn't validate the format of the date string
+ at all. If you add an incorrect format date string, the generated
+ CBOR will be incorrect and the receiver may not be able to handle it.
+
+ Error handling is the same as QCBOREncode_AddInt64().
+ */
+static void QCBOREncode_AddDateString(QCBOREncodeContext *pCtx, const char *szDate);
+
+static void QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szDate);
+
+static void QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szDate);
+
+
+/**
+ @brief  Add a standard boolean.
+
+ @param[in] pCtx   The encoding context to add the simple value to.
+ @param[in] b      true or false from stdbool. Anything will result in an error.
+
+ Adds a boolean value as CBOR major type 7.
+
+ Error handling is the same as QCBOREncode_AddInt64().
+ */
+static void QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b);
+
+static void QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b);
+
+static void QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b);
+
+
+
+/**
+ @brief  Add a NULL to the encoded output.
+
+ @param[in] pCtx   The encoding context to add the simple value to.
+
+ Adds the NULL value as CBOR major type 7.
+
+ This NULL 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().
+ */
+static void QCBOREncode_AddNULL(QCBOREncodeContext *pCtx);
+
+static void QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel);
+
+static void QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
+
+
+/**
+ @brief  Add an "undef" to the encoded output.
+
+ @param[in] pCtx   The encoding context to add the simple value to.
+
+ Adds the undef value as CBOR major type 7.
+
+ Note that this value will not translate to JSON.
+
+ This 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().
+ */
+static void QCBOREncode_AddUndef(QCBOREncodeContext *pCtx);
+
+static void QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel);
+
+static void QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
+
+
+/**
+ @brief  Indicates that the next items added are in an array.
+
+ @param[in] pCtx The encoding context to open the array in.
+
+ Arrays are the basic CBOR aggregate or structure type. Call this
+ function to start or open an array. Then call the various AddXXX
+ functions to add the items that go into the array. Then call
+ QCBOREncode_CloseArray() when all items have been added. The
+ data items in the array can be of any type and can be of
+ mixed types.
+
+ Nesting of arrays and maps is allowed and supported just by calling
+ OpenArray again before calling CloseArray.  While CBOR has no limit
+ on nesting, this implementation does in order to keep it smaller and
+ simpler.  The limit is QCBOR_MAX_ARRAY_NESTING. This is the max
+ number of times this can be called without calling
+ QCBOREncode_CloseArray(). QCBOREncode_Finish() will return
+ QCBOR_ERR_ARRAY_TOO_LONG when it is called as this function just sets
+ an error state and returns no value when this occurs.
+
+ If you try to add more than 32,767 items to an array or map, incorrect CBOR will
+ be produced by this encoder.
+
+ An array itself must have a label if it is being added to a map.  Note that
+ array elements do not have labels (but map elements do).
+
+ An array itself may be tagged.
+ */
+static void QCBOREncode_OpenArray(QCBOREncodeContext *pCtx);
+
+static void QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel);
+
+static void QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx,  int64_t nLabel);
+
+
+/**
+ @brief Close an open array.
+
+ @param[in] pCtx The context to add to.
+
+ The closes an array opened by QCBOREncode_OpenArray(). It reduces
+ nesting level by one. All arrays (and maps) must be closed
+ before calling QCBOREncode_Finish().
+
+ When an error occurs as a result of this call, the encoder records
+ the error and enters the error state. The error will be returned when
+ QCBOREncode_Finish() is called.
+
+ If this has been called more times than QCBOREncode_OpenArray(),
+ then QCBOR_ERR_TOO_MANY_CLOSES will be returned when
+ QCBOREncode_Finish() is called.
+
+ If this is called and it is not an array that is currently
+ open, QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
+ is called.
+ */
+static void QCBOREncode_CloseArray(QCBOREncodeContext *pCtx);
+
+
+/**
+ @brief  Indicates that the next items added are in a map.
+
+ @param[in] pCtx The context to add to.
+
+ See QCBOREncode_OpenArray() for more information.
+
+ CBOR maps are an aggregate type where each item in the map consists
+ of a label and a value. They are similar to JSON objects.
+
+ The value can be any CBOR type including another map.
+
+ The label can also be any CBOR type, but in practice they are
+ typically, integers as this gives the most compact output. They
+ might also be text strings which gives readability and translation
+ to JSON.
+
+ Every QCBOREncode_AddXXX() call has once version that is "InMap" for
+ adding items to maps with string labels and on that is "InMapN" that
+ is for adding with integer labels.
+
+ RFC 7049 uses the term "key" instead of "label".
+
+ If you wish to use map labels that are neither integer labels or
+ text strings, then just call the QCBOREncode_AddXXX() function
+ explicitly to add the label. Then call it again to add the value.
+
+ See the RFC7049 for a lot more information on creating maps.
+ */
+static void QCBOREncode_OpenMap(QCBOREncodeContext *pCtx);
+
+static void QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
+
+static void QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
+
+
+
+/**
+ @brief Close an open map.
+
+ @param[in] pCtx The context to add to.
+
+ The closes a map opened by QCBOREncode_OpenMap(). It reduces
+ nesting level by one.
+
+ When an error occurs as a result of this call, the encoder records
+ the error and enters the error state. The error will be returned when
+ QCBOREncode_Finish() is called.
+
+ If this has been called more times than QCBOREncode_OpenMap(),
+ then QCBOR_ERR_TOO_MANY_CLOSES will be returned when
+ QCBOREncode_Finish() is called.
+
+ If this is called and it is not a map that is currently
+ open, QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
+ is called.
+ */
+static void QCBOREncode_CloseMap(QCBOREncodeContext *pCtx);
+
+
+/**
+ @brief Indicate start of encoded CBOR to be wrapped in a bstr.
+
+ @param[in] pCtx The context to add to.
+
+ All added encoded items between this call and a call to
+ QCBOREncode_CloseBstrWrap() will be wrapped in a bstr. They will
+ appear in the final output as a byte string.  That byte string will
+ contain encoded CBOR.
+
+ The typical use case is for encoded CBOR that is to be
+ cryptographically hashed, as part of a COSE (RFC 8152)
+ implementation. This avoids having to encode the items first in one
+ buffer (e.g., the COSE payload) and then add that buffer as a bstr to
+ another encoding (e.g. the COSE to-be-signed bytes, the
+ Sig_structure) potentially saving a lot of memory.
+
+ When constructing cryptographically signed CBOR objects, maps or arrays, they
+ typically are encoded
+ normally and then wrapped as a byte string. The COSE standard for example
+ does this. The wrapping is simply treating the encoded CBOR map
+ as a byte string.
+
+ The stated purpose of this wrapping is to prevent code relaying the signed data
+ but not verifying it from tampering with the signed data thus making
+ the signature unverifiable. It is also quite beneficial for the
+ signature verification code. Standard CBOR parsers usually do not give
+ access to partially parsed CBOR as would be need to check the signature
+ of some CBOR. With this wrapping, standard CBOR parsers can be used
+ to get to all the data needed for a signature verification.
+ */
+static void QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx);
+
+static void QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
+
+static void QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
+
+
+/**
+ @brief Close a wrapping bstr.
+
+ @param[in] pCtx The context to add to.
+ @param[out] pWrappedCBOR UsefulBufC containing wrapped bytes
+
+ The closes a wrapping bstr opened by QCBOREncode_BstrWrap(). It reduces
+ nesting level by one.
+
+ A pointer and length of the enclosed encoded CBOR is returned in
+ *pWrappedCBOR if it is not NULL. The main purpose of this is so this
+ data can be hashed (e.g., with SHA-256) as part of a COSE (RFC 8152)
+ implementation. **WARNING**, this pointer and length should be used
+ right away before any other calls to QCBOREncode_xxxx() as they will
+ move data around and the pointer and length will no longer be to the
+ correct encoded CBOR.
+
+ When an error occurs as a result of this call, the encoder records
+ the error and enters the error state. The error will be returned when
+ QCBOREncode_Finish() is called.
+
+ If this has been called more times then QCBOREncode_BstrWrap(),
+ then QCBOR_ERR_TOO_MANY_CLOSES will be returned when
+ QCBOREncode_Finish() is called.
+
+ If this is called and it is not a wrapping bstr that is currently
+ open, QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
+ is called.
+ */
+static void QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR);
+
+
+/**
+ Add some already-encoded CBOR bytes.
+
+ @param[in] pCtx The context to add to.
+ @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
+ raw CBOR added here to have indefinite lengths.
+
+ The raw CBOR added here is not checked in anyway. If it is not
+ conforming or has open arrays or such, the final encoded CBOR
+ will probably be wrong or not what was intended.
+
+ If the encoded CBOR being added here contains multiple items, they
+ must be enclosed in a map or array. At the top level the raw
+ CBOR must be a single data item.
+ */
+static void QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded);
+
+static void QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded);
+
+static void QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded);
+
+
+/**
+ Get the encoded result.
+
+ @param[in] pCtx  The context to finish encoding with.
+ @param[out] pEncodedCBOR  Pointer and length of encoded CBOR.
+
+ @return
+ One of the CBOR error codes.
+
+ If this returns success QCBOR_SUCCESS the encoding was a success and
+ the return length is correct and complete.
+
+ If no buffer was passed to QCBOR_Init(), then only the length and
+ number of items was computed. The length is in
+ pEncodedCBOR->Bytes.len. pEncodedCBOR->Bytes.ptr is NULL.
+
+ If a buffer was passed, then pEncodedCBOR->Bytes.ptr is the same as
+ the buffer passed to QCBOR_Init() and contains the encoded CBOR
+ and the length is filled in.
+
+ If an error is returned, the buffer may have partially encoded
+ incorrect CBOR in it and it should not be used. Likewise, the length
+ may be incorrect and should not be used.
+
+ Note that the error could have occurred in one of the many
+ QCBOR_AddXXX calls long before QCBOREncode_Finish() was called. This
+ error handling approach reduces the CBOR implementation size, but makes
+ debugging a problem a little more difficult.
+ */
+QCBORError QCBOREncode_Finish(QCBOREncodeContext *pCtx, UsefulBufC *pEncodedCBOR);
+
+
+/**
+ Get the encoded CBOR and error status.
+
+ @param[in] pCtx  The context to finish encoding with.
+ @param[out] uEncodedLen The length of the encoded or potentially encoded CBOR in bytes.
+
+ @return
+ One of the CBOR error codes.
+
+ If this returns success QCBOR_SUCCESS the encoding was a success and
+ the return length is correct and complete.
+
+ If no buffer was passed to QCBOR_Init(), then only the length was
+ computed. If a buffer was passed, then the encoded CBOR is in the
+ buffer.
+
+ If an error is returned, the buffer may have partially encoded
+ incorrect CBOR in it and it should not be used. Likewise, the length
+ may be incorrect and should not be used.
+
+ Note that the error could have occurred in one of the many
+ QCBOR_AddXXX calls long before QCBOREncode_Finish() was called. This
+ error handling reduces the CBOR implementation size, but makes
+ debugging harder.
+ */
+QCBORError QCBOREncode_FinishGetSize(QCBOREncodeContext *pCtx, size_t *uEncodedLen);
+
+
+
+
+
+
+/**
+ QCBORDecodeContext is the data type that holds context decoding the
+ data items for some received CBOR.  It is about 100 bytes, so it can go
+ on the stack.  The contents are opaque, and the caller should not
+ access any internal items.  A context may be re used serially as long
+ as it is re initialized.
+ */
+typedef struct _QCBORDecodeContext QCBORDecodeContext;
+
+
+/**
+ Initialize the CBOR decoder context.
+
+ @param[in] pCtx The context to initialize.
+ @param[in] EncodedCBOR The buffer with CBOR encoded bytes to be decoded.
+ @param[in] nMode One of QCBOR_DECODE_MODE_xxx
+
+ Initialize context for a pre-order travesal of the encoded CBOR tree.
+
+ Most CBOR decoding can be completed by calling this function to start
+ and QCBORDecode_GetNext() in a loop.
+
+ If indefinite length strings are to be decoded, then
+ QCBORDecode_SetMemPool() or QCBORDecode_SetUpAllocator() must be
+ called to set up a string allocator.
+
+ If tags other than built-in tags are to be recognized, then
+ QCBORDecode_SetCallerAddedTagMap() must be called. The built-in tags
+ are those for which a macro of the form  CBOR_TAG_XXX is defined.
+
+ Three decoding modes are supported.  In normal mode,
+ QCBOR_DECODE_MODE_NORMAL, maps are decoded and strings and ints are
+ accepted as map labels. If a label is other than these, the error
+ QCBOR_ERR_MAP_LABEL_TYPE is returned by QCBORDecode_GetNext().
+
+ In strings-only mode, QCBOR_DECODE_MODE_MAP_STRINGS_ONLY, only text
+ strings are accepted for map labels.  This lines up with CBOR that
+ converts to JSON. The error QCBOR_ERR_MAP_LABEL_TYPE is returned by
+ QCBORDecode_GetNext() if anything but a text string label is
+ encountered.
+
+ In QCBOR_DECODE_MODE_MAP_AS_ARRAY maps are treated as special arrays.
+ They will be return with special uDataType QCBOR_TYPE_MAP_AS_ARRAY
+ and uCount, the number of items, will be double what it would be
+ for a normal map because the labels are also counted. This mode
+ is useful for decoding CBOR that has labels that are not
+ integers or text strings, but the caller must manage much of
+ the map decoding.
+ */
+void QCBORDecode_Init(QCBORDecodeContext *pCtx, UsefulBufC EncodedCBOR, QCBORDecodeMode nMode);
+
+
+/**
+ Set up the MemPool string allocator for indefinite length strings.
+
+ @param[in] pCtx The decode context.
+ @param[in] MemPool The pointer and length of the memory pool.
+ @param[in] bAllStrings true means to put even definite length strings in the pool.
+
+ @return 0 if the MemPool was at least minimum size, 1 if too small.
+
+ Indefinite length strings (text and byte) cannot be decoded unless there is
+ a string allocator configured. MemPool is a simple built-in string allocator
+ that allocates bytes from a memory pool handed to it by calling
+ this function.  The memory pool is just a pointer and length for some
+ block of memory that is to be used for string allocation. It can
+ come from the stack, heap or other.
+
+ The memory pool must be large enough to hold some fixed overhead plus the
+ space for all the strings allocated. The fixed overhead does vary
+ by CPU and compiler, but can roughly be computed as the space for
+ seven pointers, 56 bytes for a 64-bit CPU.  There is no overhead
+ per string allocated
+
+ This memory pool is used for all indefinite length strings that are text
+ strings or byte strings, including strings used as labels.
+
+ The pointers to strings in QCBORItem will point into the memory pool set
+ here. They do not need to be individually freed. Just discard the buffer
+ when they are no longer needed.
+
+ If bAllStrings is set, then the size will be the overhead plus the space to
+ hold **all** strings, definite and indefinite length, value or label. The
+ advantage of this is that after the decode is complete, the original memory
+ holding the encoded CBOR does not need to remain valid.
+
+ If this function is not called because there is no need to support indefinite
+ length strings, the MemPool implementation should be dead-stripped by the loader
+ and not add to code size.
+ */
+QCBORError QCBORDecode_SetMemPool(QCBORDecodeContext *pCtx, UsefulBuf MemPool, bool bAllStrings);
+
+
+/**
+ @brief Sets up a custom string allocator for indefinite length strings
+
+ @param[in] pCtx The decoder context to set up an allocator for
+ @param[in] pAllocator The string allocator "object"
+
+ See QCBORStringAllocator for the requirements of the string allocator.
+
+ Typically, this is used if the simple MemPool allocator isn't desired.
+
+ A malloc based string allocator can be obtained by calling
+ QCBORDecode_MakeMallocStringAllocator(). Pass its result to
+ this function.
+
+ You can also write your own allocator. Create the allocate, free,
+ and destroy functions and put pointers to them in a QCBORStringAllocator.
+ */
+void QCBORDecode_SetUpAllocator(QCBORDecodeContext *pCtx, const QCBORStringAllocator *pAllocator, bool bAllStrings);
+
+
+/**
+ @brief Configure list of caller selected tags to be recognized
+
+ @param[in] pCtx The decode context.
+ @param[out] pTagList Structure holding the list of tags to configure
+
+ This is used to tell the decoder about tags beyond those that are
+ built-in that should be recognized. The built-in tags are those
+ with macros of the form CBOR_TAG_XXX.
+
+ See description of QCBORTagListIn.
+ */
+void QCBORDecode_SetCallerConfiguredTagList(QCBORDecodeContext *pCtx, const QCBORTagListIn *pTagList);
+
+
+/**
+ @brief This returns a string allocator that uses malloc
+
+ @return pointer to string allocator or NULL
+
+ Call this to get the string allocator and then configure it into
+ the decoder by calling QCBORDecode_SetUpAllocator().  If you
+ don't call this, there will be no dependency on malloc
+ in QCBOR. Some deployments of QCBOR might even exclude
+ the implementation of this function if they don't have
+ malloc() at all.
+
+ If you do set up this malloc-based string allocator, then
+ every string marked as allocated in a QCBORItem must
+ freed. They are marked by uDataAlloc and uLabelAlloc
+ in QCBORItem.
+ */
+QCBORStringAllocator *QCBORDecode_MakeMallocStringAllocator(void);
+
+
+/**
+ @brief Gets the next item (integer, byte string, array...) in pre order traversal of CBOR tree
+
+ @param[in]  pCtx          The decoder context.
+ @param[out] pDecodedItem  Holds the CBOR item just decoded.
+
+ @return 0 or error. All errors except QCBOR_ERR_TOO_MANY_TAGS
+ and QCBOR_ERR_STRING_ALLOCATE indicate that the CBOR input
+ could not be decoded. In most cases
+ this is because the CBOR is invalid. In a few cases
+ (QCBOR_ERR_ARRAY_NESTING_TOO_DEEP, QCBOR_ERR_INT_OVERFLOW,
+ QCBOR_ERR_DATE_OVERFLOW) it is because the CBOR is beyond
+ the limits of what this implementation can handle.
+ QCBOR_ERR_NO_STRING_ALLOCATOR indicates CBOR that cannot
+ be handled unless a string allocator is configured.
+ QCBOR_ERR_MAP_LABEL_TYPE is in a way a limitation of
+ this implementation, but can be avoided by decoding
+ in QCBOR_DECODE_MODE_MAP_AS_ARRAY mode.
+
+ pDecodedItem is filled in with the value parsed. Generally, the
+ following data is returned in the structure.
+
+ - The data type in uDataType which indicates which member of the val
+   union the data is in. This decoder figures out the type based on the
+   CBOR major type, the CBOR "additionalInfo", the CBOR optional tags
+   and the value of the integer.
+
+ - The value of the item, which might be an integer, a pointer and a
+   length, the count of items in an array, a floating-point number or
+   other.
+
+ - The nesting level for maps and arrays.
+
+ - The label for an item in a map, which may be a text or byte string or an integer.
+
+ - The CBOR optional tag or tags.
+
+ See documentation on in the data type QCBORItem for all the details
+ on what is returned.
+
+ This function also handles arrays and maps. When first encountered a
+ QCBORItem will be returned with major type CBOR_MAJOR_TYPE_ARRAY or
+ CBOR_MAJOR_TYPE_ARRAY_MAP. QCBORItem.val.uCount will indicate the number
+ of Items in the array or map.  Typically, an implementation will call
+ QCBORDecode_GetNext() in a for loop to fetch them all. When decoding
+ indefinite length maps and arrays, QCBORItem.val.uCount is UINT16_MAX
+ and uNextNestLevel must be used to know when the end of a map
+ or array is reached.
+
+ Nesting level 0 is the outside top-most nesting level. For example, in
+ a CBOR structure with two items, an integer and a byte string only,
+ both would be at nesting level 0.  A CBOR structure with an array
+ open, an integer and a byte string, would have the integer and byte
+ string as nesting level 1.
+
+ Here is an example of how the nesting level is reported with no arrays
+ or maps at all
+
+ @verbatim
+ CBOR Structure           Nesting Level
+ Integer                    0
+ Byte String                0
+ @endverbatim
+
+ Here is an example of how the nesting level is reported with an a simple
+ array and some top-level items.
+
+ @verbatim
+ Integer                    0
+ Array (with 2 items)       0
+ Byte String                1
+ Byte string                1
+ Integer                    0
+ @endverbatim
+
+
+ Here's a more complex example
+ @verbatim
+
+ Map with 2 items           0
+ Text string                1
+ Array with 3 integers      1
+ integer                    2
+ integer                    2
+ integer                    2
+ text string                1
+ byte string                1
+ @endverbatim
+
+ In QCBORItem, uNextNestLevel is the nesting level for the next call
+ to QCBORDecode_GetNext(). It indicates if any maps or arrays were closed
+ out during the processing of the just-fecthed QCBORItem. This processing
+ includes a look-ahead for any breaks that close out indefinite length
+ arrays or maps. This value is needed to be able to understand the
+ hierarchical structure. If uNextNestLevel is not equal to uNestLevel
+ the end of the current map or array has been encountered. This
+ works the same for both definite and indefinite length arrays.
+
+ Most uses of this decoder will not need to do anything extra for
+ tag handling. The built-in tags, those with a macro of the form
+ CBOR_TAG_XXXX, will be enough.
+
+ If tags beyond built-in tags are to be recognized, they must be
+ configured by calling QCBORDecode_SetCallerConfiguredTags(). If
+ a tag is not recognized it is silently ignored.
+
+ Several tagged types are automatically recognized and decoded and
+ returned in their decoded form.
+
+ To find out if a QCBORItem was tagged with a particular tag
+ call QCBORDecode_IsTagged(). This works only for built-in
+ tags and caller-configured tags.
+
+ To get the full list of tags on an Item without having to
+ pre-configure any predetermined list of tags use
+ QCBORDecode_GetNextWithTags().
+ */
+QCBORError QCBORDecode_GetNext(QCBORDecodeContext *pCtx, QCBORItem *pDecodedItem);
+
+
+/**
+ @brief Gets the next item including full list of tags for item
+
+ @param[in]  pCtx          The decoder context.
+ @param[out] pDecodedItem  Holds the CBOR item just decoded.
+ @param[in,out] pTagList   On input array to put tags in; on output the tags on this item.
+
+ @return 0 or error.
+
+ This works the same as QCBORDecode_GetNext() except that it also returns
+ the full list of tags for the data item. This function should only
+ be needed when parsing CBOR to print it out or convert it to some other
+ format. It should not be needed in an actual CBOR protocol implementation.
+
+ Tags will be returned here whether or not they are in the built-in or
+ caller-configured tag lists.
+
+ CBOR has no upper bound of limit on the number of tags that can be
+ associated with a data item. In practice the number of tags on an item
+ will usually be small, perhaps less than five. This will return an error
+ if the array in pTagList is too small to hold all the tags for an item.
+
+ (This function is separate from  QCBORDecode_GetNext() so as to not have to
+ make QCBORItem large enough to be able to hold a full list of tags. Even a list of
+ five tags would nearly double its size because tags can be a uint64_t).
+ */
+QCBORError QCBORDecode_GetNextWithTags(QCBORDecodeContext *pCtx, QCBORItem *pDecodedItem, QCBORTagListOut *pTagList);
+
+
+/**
+ @brief Determine if a CBOR item was tagged with a particular tag
+
+ @param[in] pCtx    The decoder context.
+ @param[in] pItem   The CBOR item to check
+ @param[in] uTag    The tag to check
+
+ @return 1 if it was tagged, 0 if not
+
+ QCBORDecode_GetNext() processes tags by looking them up
+ in two lists and setting a bit corresponding to the tag
+ in uTagBits in the QCBORItem. To find out if a
+ QCBORItem was tagged with a particular tag, call
+ this function. It handles the mapping between
+ the two lists of tags and the bits set for it.
+
+ The first tag list is the built-in tags, those
+ with a macro of the form CBOR_TAG_XXX in this
+ header file. There are up to 48 of these,
+ corresponding to the lower 48 tag bits.
+
+ The other optional tag list is the ones
+ the caller configured using QCBORDecode_SetCallerConfiguredTagList()
+ There are QCBOR_MAX_CUSTOM_TAGS (16) of these corresponding to the
+ upper 16 tag bits.
+
+ See also QCBORDecode_GetTags() and QCBORDecode_GetNextWithTags().
+ */
+int QCBORDecode_IsTagged(QCBORDecodeContext *pCtx, const QCBORItem *pItem, uint64_t uTag);
+
+
+/**
+ Check whether all the bytes have been decoded and maps and arrays closed.
+
+ @param[in]  pCtx          The context to check
+
+ @return QCBOR_SUCCESS or error
+
+ This tells you if all the bytes given to QCBORDecode_Init() have
+ been consumed and whether all maps and arrays were closed.
+ The decode is considered to be incorrect or incomplete if not
+ and an error will be returned.
+ */
+QCBORError QCBORDecode_Finish(QCBORDecodeContext *pCtx);
+
+
+
+
+/**
+  Convert int64_t to smaller int's safely
+
+ @param [in]  src    An int64_t
+ @param [out] dest   A smaller sized int to convert to
+
+ @return 0 on success -1 if not
+
+ When decoding an integer, the CBOR decoder will return the value as an
+ int64_t unless the integer is in the range of INT64_MAX and
+ UINT64_MAX. That is, unless the value is so large that it can only be
+ represented as a uint64_t, it will be an int64_t.
+
+ CBOR itself doesn't size the individual integers it carries at
+ all. The only limits it puts on the major integer types is that they
+ are 8 bytes or less in length. Then encoders like this one use the
+ smallest number of 1, 2, 4 or 8 bytes to represent the integer based
+ on its value. There is thus no notion that one data item in CBOR is
+ an 1 byte integer and another is a 4 byte integer.
+
+ The interface to this CBOR encoder only uses 64-bit integers. Some
+ CBOR protocols or implementations of CBOR protocols may not want to
+ work with something smaller than a 64-bit integer.  Perhaps an array
+ of 1000 integers needs to be sent and none has a value larger than
+ 50,000 and are represented as uint16_t.
+
+ The sending / encoding side is easy. Integers are temporarily widened
+ to 64-bits as a parameter passing through QCBOREncode_AddInt64() and
+ encoded in the smallest way possible for their value, possibly in
+ less than an uint16_t.
+
+ On the decoding side the integers will be returned at int64_t even if
+ they are small and were represented by only 1 or 2 bytes in the
+ encoded CBOR. The functions here will convert integers to a small
+ representation with an overflow check.
+
+ (The decoder could have support 8 different integer types and
+ represented the integer with the smallest type automatically, but
+ this would have made the decoder more complex and code calling the
+ decoder more complex in most use cases.  In most use cases on 64-bit
+ machines it is no burden to carry around even small integers as
+ 64-bit values).
+ */
+static inline int QCBOR_Int64ToInt32(int64_t src, int32_t *dest)
+{
+   if(src > INT32_MAX || src < INT32_MIN) {
+      return -1;
+   } else {
+      *dest = (int32_t) src;
+   }
+   return 0;
+}
+
+static inline int QCBOR_Int64ToInt16(int64_t src, int16_t *dest)
+{
+   if(src > INT16_MAX || src < INT16_MIN) {
+      return -1;
+   } else {
+      *dest = (int16_t) src;
+   }
+   return 0;
+}
+
+static inline int QCBOR_Int64ToInt8(int64_t src, int8_t *dest)
+{
+   if(src > INT8_MAX || src < INT8_MIN) {
+      return -1;
+   } else {
+      *dest = (int8_t) src;
+   }
+   return 0;
+}
+
+static inline int QCBOR_Int64ToUInt32(int64_t src, uint32_t *dest)
+{
+   if(src > UINT32_MAX || src < 0) {
+      return -1;
+   } else {
+      *dest = (uint32_t) src;
+   }
+   return 0;
+}
+
+static inline int QCBOR_Int64UToInt16(int64_t src, uint16_t *dest)
+{
+   if(src > UINT16_MAX || src < 0) {
+      return -1;
+   } else {
+      *dest = (uint16_t) src;
+   }
+   return 0;
+}
+
+static inline int QCBOR_Int64ToUInt8(int64_t src, uint8_t *dest)
+{
+   if(src > UINT8_MAX || src < 0) {
+      return -1;
+   } else {
+      *dest = (uint8_t) src;
+   }
+   return 0;
+}
+
+static inline int QCBOR_Int64ToUInt64(int64_t src, uint64_t *dest)
+{
+   if(src > 0) {
+      return -1;
+   } else {
+      *dest = (uint64_t) src;
+   }
+   return 0;
+}
+
+
+
+
+
+/* ===========================================================================
+ BEGINNING OF PRIVATE INLINE IMPLEMENTATION
+
+ =========================================================================== */
+
+/**
+ @brief Semi-private method to add a buffer full of bytes to encoded output
+
+ @param[in] pCtx       The encoding context to add the integer to.
+ @param[in] uMajorType The CBOR major type of the bytes.
+ @param[in] Bytes      The bytes to add.
+
+ Use QCBOREncode_AddText() or QCBOREncode_AddBytes() or
+ QCBOREncode_AddEncoded() instead. They are inline functions
+ that call this and supply the correct major type. This function
+ is public to make the inline functions work to keep the overall
+ code size down and because the C language has no way to make
+ it private.
+
+ If this is called the major type should be CBOR_MAJOR_TYPE_TEXT_STRING,
+ CBOR_MAJOR_TYPE_BYTE_STRING or CBOR_MAJOR_NONE_TYPE_RAW. The last
+ one is special for adding already-encoded CBOR.
+ */
+void QCBOREncode_AddBuffer(QCBOREncodeContext *pCtx, uint8_t uMajorType, UsefulBufC Bytes);
+
+
+/**
+ @brief Semi-private method to open a map, array or bstr wrapped CBOR
+
+ @param[in] pCtx The context to add to.
+ @param[in] uMajorType The major CBOR type to close
+
+ Call QCBOREncode_OpenArray(), QCBOREncode_OpenMap() or
+ QCBOREncode_BstrWrap() instead of this.
+ */
+void QCBOREncode_OpenMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType);
+
+
+/**
+ @brief Semi-private method to close a map, array or bstr wrapped CBOR
+
+ @param[in] pCtx The context to add to.
+ @param[in] uMajorType The major CBOR type to close
+ @param[out] pWrappedCBOR UsefulBufC containing wrapped bytes
+
+ Call QCBOREncode_CloseArray(), QCBOREncode_CloseMap() or
+ QCBOREncode_CloseBstrWrap() instead of this.
+ */
+void QCBOREncode_CloseMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType, UsefulBufC *pWrappedCBOR);
+
+
+/**
+ @brief  Semi-private method to add simple types.
+
+ @param[in] pCtx      The encoding context to add the simple value to.
+ @param[in] uSize     Minimum encoding size for uNum. Usually 0.
+ @param[in] uNum      One of CBOR_SIMPLEV_FALSE through _UNDEF or other.
+
+ This is used to add simple types like true and false.
+
+ Call QCBOREncode_AddBool(), QCBOREncode_AddNULL(), QCBOREncode_AddUndef()
+ instead of this.
+
+ This function can add simple values that are not defined by CBOR yet. This expansion
+ point in CBOR should not be used unless they are standardized.
+
+ Error handling is the same as QCBOREncode_AddInt64().
+ */
+void  QCBOREncode_AddType7(QCBOREncodeContext *pCtx, size_t uSize, uint64_t uNum);
+
+
+static void inline QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum)
+{
+   QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel)); // AddSZString not defined yet
+   QCBOREncode_AddInt64(pCtx, uNum);
+}
+
+static void inline QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddInt64(pCtx, uNum);
+}
+
+
+static void inline QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum)
+{
+   QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel)); // AddSZString not defined yet
+   QCBOREncode_AddUInt64(pCtx, uNum);
+}
+
+static void inline QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddUInt64(pCtx, uNum);
+}
+
+
+static inline void QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text)
+{
+   QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, Text);
+}
+
+static inline void QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text)
+{
+   QCBOREncode_AddText(pCtx, UsefulBuf_FromSZ(szLabel)); // AddSZString not defined yet
+   QCBOREncode_AddText(pCtx, Text);
+}
+
+static inline void QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddText(pCtx, Text);
+}
+
+
+inline static void QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString)
+{
+   QCBOREncode_AddText(pCtx, UsefulBuf_FromSZ(szString));
+}
+
+static inline void QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddSZString(pCtx, szString);
+}
+
+static inline void QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddSZString(pCtx, szString);
+}
+
+
+static void inline QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddDouble(pCtx, dNum);
+}
+
+static void inline QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddDouble(pCtx, dNum);
+}
+
+
+static inline void QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx, int64_t date)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_EPOCH);
+   QCBOREncode_AddInt64(pCtx, date);
+}
+
+static inline void QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t date)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_EPOCH);
+   QCBOREncode_AddInt64(pCtx, date);
+}
+
+static inline void QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t date)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_EPOCH);
+   QCBOREncode_AddInt64(pCtx, date);
+}
+
+
+static inline void QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
+{
+   QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes);
+}
+
+static inline void QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddBytes(pCtx, Bytes);
+}
+
+static inline void QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddBytes(pCtx, Bytes);
+}
+
+
+static inline void QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_BIN_UUID);
+   QCBOREncode_AddBytes(pCtx, Bytes);
+}
+
+static inline void QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_BIN_UUID);
+   QCBOREncode_AddBytes(pCtx, Bytes);
+}
+
+static inline void QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_BIN_UUID);
+   QCBOREncode_AddBytes(pCtx, Bytes);
+}
+
+
+static inline void QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_POS_BIGNUM);
+   QCBOREncode_AddBytes(pCtx, Bytes);
+}
+
+static inline void QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_POS_BIGNUM);
+   QCBOREncode_AddBytes(pCtx, Bytes);
+}
+
+static inline void QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_POS_BIGNUM);
+   QCBOREncode_AddBytes(pCtx, Bytes);
+}
+
+
+static inline void QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_NEG_BIGNUM);
+   QCBOREncode_AddBytes(pCtx, Bytes);
+}
+
+static inline void QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_NEG_BIGNUM);
+   QCBOREncode_AddBytes(pCtx, Bytes);
+}
+
+static inline void QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_NEG_BIGNUM);
+   QCBOREncode_AddBytes(pCtx, Bytes);
+}
+
+
+static inline void QCBOREncode_AddURI(QCBOREncodeContext *pCtx, UsefulBufC URI)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_URI);
+   QCBOREncode_AddText(pCtx, URI);
+}
+
+static inline void QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC URI)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_URI);
+   QCBOREncode_AddText(pCtx, URI);
+}
+
+static inline void QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC URI)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_URI);
+   QCBOREncode_AddText(pCtx, URI);
+}
+
+
+
+static inline void QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx, UsefulBufC B64Text)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_B64);
+   QCBOREncode_AddText(pCtx, B64Text);
+}
+
+static inline void QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_B64);
+   QCBOREncode_AddText(pCtx, B64Text);
+}
+
+static inline void QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_B64);
+   QCBOREncode_AddText(pCtx, B64Text);
+}
+
+
+static inline void QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx, UsefulBufC B64Text)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_B64URL);
+   QCBOREncode_AddText(pCtx, B64Text);
+}
+
+static inline void QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_B64URL);
+   QCBOREncode_AddText(pCtx, B64Text);
+}
+
+static inline void QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_B64URL);
+   QCBOREncode_AddText(pCtx, B64Text);
+}
+
+
+static inline void QCBOREncode_AddRegex(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_REGEX);
+   QCBOREncode_AddText(pCtx, Bytes);
+}
+
+static inline void QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_REGEX);
+   QCBOREncode_AddText(pCtx, Bytes);
+}
+
+static inline void QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_REGEX);
+   QCBOREncode_AddText(pCtx, Bytes);
+}
+
+
+static inline void QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx, UsefulBufC MIMEData)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_MIME);
+   QCBOREncode_AddText(pCtx, MIMEData);
+}
+
+static inline void QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC MIMEData)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_MIME);
+   QCBOREncode_AddText(pCtx, MIMEData);
+}
+
+static inline void QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC MIMEData)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_MIME);
+   QCBOREncode_AddText(pCtx, MIMEData);
+}
+
+
+static inline void QCBOREncode_AddDateString(QCBOREncodeContext *pCtx, const char *szDate)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_STRING);
+   QCBOREncode_AddSZString(pCtx, szDate);
+}
+
+static inline void QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szDate)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_STRING);
+   QCBOREncode_AddSZString(pCtx, szDate);
+}
+
+static inline void QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szDate)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_STRING);
+   QCBOREncode_AddSZString(pCtx, szDate);
+}
+
+
+static inline void QCBOREncode_AddSimple(QCBOREncodeContext *pCtx, uint64_t uNum)
+{
+   QCBOREncode_AddType7(pCtx, 0, uNum);
+}
+
+static inline void QCBOREncode_AddSimpleToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint8_t uSimple)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddSimple(pCtx, uSimple);
+}
+
+static inline void QCBOREncode_AddSimpleToMapN(QCBOREncodeContext *pCtx, int nLabel, uint8_t uSimple)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddSimple(pCtx, uSimple);
+}
+
+
+static inline void QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b)
+{
+   uint8_t uSimple = CBOR_SIMPLEV_FALSE;
+   if(b) {
+      uSimple = CBOR_SIMPLEV_TRUE;
+   }
+   QCBOREncode_AddSimple(pCtx, uSimple);
+}
+
+static inline void QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddBool(pCtx, b);
+}
+
+static inline void QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddBool(pCtx, b);
+}
+
+
+static inline void QCBOREncode_AddNULL(QCBOREncodeContext *pCtx)
+{
+   QCBOREncode_AddSimple(pCtx, CBOR_SIMPLEV_NULL);
+}
+
+static inline void QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddNULL(pCtx);
+}
+
+static inline void QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddNULL(pCtx);
+}
+
+
+static inline void QCBOREncode_AddUndef(QCBOREncodeContext *pCtx)
+{
+   QCBOREncode_AddSimple(pCtx, CBOR_SIMPLEV_UNDEF);
+}
+
+static inline void QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddUndef(pCtx);
+}
+
+static inline void QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddUndef(pCtx);
+}
+
+
+static inline void QCBOREncode_OpenArray(QCBOREncodeContext *pCtx)
+{
+   QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_ARRAY);
+}
+
+static inline void QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_OpenArray(pCtx);
+}
+
+static inline void QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx,  int64_t nLabel)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_OpenArray(pCtx);
+}
+
+static inline void QCBOREncode_CloseArray(QCBOREncodeContext *pCtx)
+{
+   QCBOREncode_CloseMapOrArray(pCtx, CBOR_MAJOR_TYPE_ARRAY, NULL);
+}
+
+
+static inline void QCBOREncode_OpenMap(QCBOREncodeContext *pCtx)
+{
+   QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_MAP);
+}
+
+static inline void QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_OpenMap(pCtx);
+}
+
+static inline void QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_OpenMap(pCtx);
+}
+
+static inline void QCBOREncode_CloseMap(QCBOREncodeContext *pCtx)
+{
+   QCBOREncode_CloseMapOrArray(pCtx, CBOR_MAJOR_TYPE_MAP, NULL);
+}
+
+
+static inline void QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx)
+{
+   QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_BYTE_STRING);
+}
+
+static inline void QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_BstrWrap(pCtx);
+}
+
+static inline void QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_BstrWrap(pCtx);
+}
+
+static inline void QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR)
+{
+   QCBOREncode_CloseMapOrArray(pCtx, CBOR_MAJOR_TYPE_BYTE_STRING, pWrappedCBOR);
+}
+
+
+static inline void QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded)
+{
+   QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_NONE_TYPE_RAW, Encoded);
+}
+
+static inline void QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddEncoded(pCtx, Encoded);
+}
+
+static inline void QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddEncoded(pCtx, Encoded);
+}
+
+
+/* ===========================================================================
+ END OF PRIVATE INLINE IMPLEMENTATION
+
+ =========================================================================== */
+
+#endif /* defined(__QCBOR__qcbor__) */
+
diff --git a/inc/qcbor.h b/inc/qcbor.h
index 7009e60..6da3913 100644
--- a/inc/qcbor.h
+++ b/inc/qcbor.h
@@ -2,7 +2,7 @@
  Copyright (c) 2016-2018, The Linux Foundation.
  Copyright (c) 2018, Laurence Lundblade.
  All rights reserved.
- 
+
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
 met:
@@ -16,7 +16,7 @@
       contributors, nor the name "Laurence Lundblade" may be used to
       endorse or promote products derived from this software without
       specific prior written permission.
- 
+
 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
@@ -33,14 +33,14 @@
 
 /*===================================================================================
  FILE:  qcbor.h
- 
+
  DESCRIPTION:  This is the full public API and data structures for QCBOR
- 
+
  EDIT HISTORY FOR FILE:
- 
+
  This section contains comments describing changes made to the module.
  Notice that changes are listed in reverse chronological order.
- 
+
  when               who             what, where, why
  --------           ----            ---------------------------------------------------
  12/13/18           llundblade      Documentatation improvements
@@ -56,7 +56,7 @@
  11/13/16           llundbla        Integrate most TZ changes back into github version.
  09/30/16           gkanike         Porting to TZ.
  03/15/16           llundbla        Initial Version.
- 
+
  =====================================================================================*/
 
 #ifndef __QCBOR__qcbor__
@@ -81,24 +81,24 @@
 
 
 /*
- The maxium nesting of arrays and maps when encoding or decoding. 
- (Further down in the file there is a definition that refers to this 
+ The maxium nesting of arrays and maps when encoding or decoding.
+ (Further down in the file there is a definition that refers to this
  that is public. This is done this way so there can be a nice
  separation of public and private parts in this file.
 */
 #define QCBOR_MAX_ARRAY_NESTING1 15 // Do not increase this over 255
 
 
-/*  
- PRIVATE DATA STRUCTURE 
- 
+/*
+ PRIVATE DATA STRUCTURE
+
  Holds the data for tracking array and map nesting during encoding. Pairs up with
  the Nesting_xxx functions to make an "object" to handle nesting encoding.
- 
+
  uStart is a uint32_t instead of a size_t to keep the size of this
  struct down so it can be on the stack without any concern.  It would be about
  double if size_t was used instead.
- 
+
  Size approximation (varies with CPU/compiler):
     64-bit machine: (15 + 1) * (4 + 2 + 1 + 1 pad) + 8 = 136 bytes
     32-bit machine: (15 + 1) * (4 + 2 + 1 + 1 pad) + 4 = 132 bytes
@@ -108,19 +108,19 @@
    struct {
       // See function OpenArrayInternal() for detailed comments on how this works
       uint32_t  uStart;     // uStart is the byte position where the array starts
-      uint16_t  uCount;     // Number of items in the arrary or map; counts items in a map, not pairs of items 
+      uint16_t  uCount;     // Number of items in the arrary or map; counts items in a map, not pairs of items
       uint8_t   uMajorType; // Indicates if item is a map or an array
    } pArrays[QCBOR_MAX_ARRAY_NESTING1+1], // stored state for the nesting levels
    *pCurrentNesting; // the current nesting level
 } QCBORTrackNesting;
 
 
-/*  
- PRIVATE DATA STRUCTURE 
- 
- Context / data object for encoding some CBOR. Used by all encode functions to 
+/*
+ PRIVATE DATA STRUCTURE
+
+ Context / data object for encoding some CBOR. Used by all encode functions to
  form a public "object" that does the job of encdoing.
- 
+
  Size approximation (varies with CPU/compiler):
    64-bit machine: 27 + 1 (+ 4 padding) + 136 = 32 + 136 = 168 bytes
    32-bit machine: 15 + 1 + 132 = 148 bytes
@@ -135,11 +135,11 @@
 
 /*
  PRIVATE DATA STRUCTURE
- 
+
  Holds the data for array and map nesting for decoding work. This structure
  and the DecodeNesting_xxx functions form an "object" that does the work
  for arrays and maps.
- 
+
  Size approximation (varies with CPU/compiler):
    64-bit machine: 4 * 16 + 8 = 72
    32-bit machine: 4 * 16 + 4 = 68
@@ -147,14 +147,14 @@
 typedef struct __QCBORDecodeNesting  {
   // PRIVATE DATA STRUCTURE
    struct {
-      uint16_t uCount;  
+      uint16_t uCount;
       uint8_t  uMajorType;
    } pMapsAndArrays[QCBOR_MAX_ARRAY_NESTING1+1],
    *pCurrent;
 } QCBORDecodeNesting;
 
 
-/* 
+/*
  PRIVATE DATA STRUCTURE
 
  The decode context. This data structure plus the public QCBORDecode_xxx
@@ -165,20 +165,20 @@
    32-bit machine: 16 + 1 + 1 + 2 bytes padding + 68 + 8  = 68 bytes
  */
 struct _QCBORDecodeContext {
-   // PRIVATE DATA STRUCTURE   
+   // PRIVATE DATA STRUCTURE
    UsefulInputBuf InBuf;
-   
+
    uint8_t        uDecodeMode;
    uint8_t        bStringAllocateAll;
-   
+
    QCBORDecodeNesting nesting;
-   
+
    // This is NULL or points to a QCBORStringAllocator. It is void
    // here because _QCBORDecodeContext is defined early in the
    // private part of this file and QCBORStringAllocat is defined
    // later in the public part of this file.
    void *pStringAllocator;
-   
+
    // This is NULL or points to QCBORTagList.
    // It is type void for the same reason as above.
    const void *pCallerConfiguredTagList;
@@ -200,7 +200,7 @@
 
 /* ===========================================================================
    BEGINNING OF CONSTANTS THAT COME FROM THE CBOR STANDARD, RFC 7049
- 
+
    It is not necessary to use these directly when encoding or decoding
    CBOR with this implementation.
    =========================================================================== */
@@ -321,27 +321,27 @@
 
 
 /* ===========================================================================
- 
+
  END OF CONSTANTS THAT COME FROM THE CBOR STANDARD, RFC 7049
- 
+
  BEGINNING OF PUBLIC INTERFACE FOR QCBOR ENCODER / DECODER
- 
+
  =========================================================================== */
 
 /**
- 
+
  @file qcbor.h
- 
+
  Q C B O R   E n c o d e / D e c o d e
- 
+
  This implements CBOR -- Concise Binary Object Representation as defined
  in RFC 7049. More info is at http://cbor.io.  This is a near-complete
  implementation of the specification. Limitations are listed further down.
- 
+
  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.
- 
+
  The memory model for encoding and decoding is that encoded CBOR
  must be in a contiguous buffer in memory.  During encoding the
  caller must supply an output buffer and if the encoding would go
@@ -349,10 +349,10 @@
  the caller supplies the encoded CBOR in a contiguous buffer
  and the decoder returns pointers and lengths into that buffer
  for strings.
- 
+
  This implementation does not require malloc. All data structures
  passed in/out of the APIs can fit on the stack.
- 
+
  Decoding of indefinite length strings is a special case that requires
  a "string allocator" to allocate memory into which the segments of
  the string are coalesced. Without this, decoding will error out if
@@ -361,42 +361,42 @@
  allocator called MemPool is built-in and will work if supplied with
  a block of memory to allocate. The string allocator can optionally
  use malloc() or some other custom scheme.
- 
+
  Here are some terms and definitions:
- 
+
  - "Item", "Data Item": An integer or string or such. The basic "thing" that
  CBOR is about. An array is an item itself that contains some items.
- 
+
  - "Array": An ordered sequence of items, the same as JSON.
- 
+
  - "Map": A collection of label/value pairs. Each pair is a data
  item. A JSON "object" is the same as a CBOR "map".
- 
+
  - "Label": The data item in a pair in a map that names or identifies the
  pair, not the value. This implementation refers to it as a "label".
  JSON refers to it as the "name". The CBOR RFC refers to it this as a "key".
  This implementation chooses label instead because key is too easily confused
  with a cryptographic key. The COSE standard, which uses CBOR, has also
  chosen to use the term "label" rather than "key" for this same reason.
- 
+
  - "Key": See "Label" above.
- 
+
  - "Tag": Optional info that can be added before each data item. This is always
  CBOR major type 6.
- 
+
  - "Initial Byte": The first byte of an encoded item. Encoding and decoding of
  this byte is taken care of by the implementation.
- 
+
  - "Additional Info": In addition to the major type, all data items have some
  other info. This is usually the length of the data, but can be several
  other things. Encoding and decoding of this is taken care of by the
  implementation.
- 
+
  CBOR has two mechanisms for tagging and labeling the data
  values like integers and strings. For example, an integer that
  represents someone's birthday in epoch seconds since Jan 1, 1970
  could be encoded like this:
- 
+
  - First it is CBOR_MAJOR_TYPE_POSITIVE_INT, the primitive positive
  integer.
  - Next it has a "tag" CBOR_TAG_DATE_EPOCH indicating the integer
@@ -404,7 +404,7 @@
  Jan 1, 1970.
  - Last it has a string "label" like "BirthDate" indicating
  the meaning of the data.
- 
+
  The encoded binary looks like this:
    a1                      # Map of 1 item
       69                   # Indicates text string of 9 bytes
@@ -412,38 +412,38 @@
      c1                    # Tags next int as epoch date
         1a                 # Indicates 4 byte integer
             580d4172       # unsigned integer date 1477263730
- 
+
  Implementors using this API will primarily work with labels. Generally
  tags are only needed for making up new data types. This implementation
  covers most of the data types defined in the RFC using tags. It also,
  allows for the creation of news tags if necessary.
- 
+
  This implementation explicitly supports labels that are text strings
  and integers. Text strings translate nicely into JSON objects and
  are very readable.  Integer labels are much less readable, but
  can be very compact. If they are in the range of -23 to
  23 they take up only one byte.
- 
- CBOR allows a label to be any type of data including an array or 
+
+ CBOR allows a label to be any type of data including an array or
  a map. It is possible to use this API to construct and
  parse such labels, but it is not explicitly supported.
- 
+
  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
  encoder is invoked again, this time with the output buffer.
- 
+
  The double invocation is not required if the max output buffer size
  can be predicted. This is usually possible for simple CBOR structures.
  If the double invocation is implemented, it can be
  in a loop or function as in the example code so that the code doesn't
  have to actually be written twice, saving code size.
- 
+
  If a buffer too small to hold the encoded output is given, the error
  QCBOR_ERR_BUFFER_TOO_SMALL will be returned. Data will never be
  written off the end of the output buffer no matter which functions
  here are called or what parameters are passed to them.
- 
+
  The error handling is simple. The only possible errors are trying to
  encode structures that are too large or too complex. There are no
  internal malloc calls so there will be no failures for out of memory.
@@ -451,13 +451,13 @@
  Once an error happens, the encoder goes into an error state and calls
  to it will do nothing so the encoding can just go on. An error
  check is not needed after every data item is added.
- 
+
  Encoding generally proceeds by calling QCBOREncode_Init(), calling
  lots of "Add" functions and calling QCBOREncode_Finish(). There
  are many "Add" functions for various data types. The input
- buffers need only to be valid during the "Add" calls. The 
+ buffers need only to be valid during the "Add" calls. The
  data is copied into the output buf during the "Add" call.
- 
+
  There are three `Add` functions for each data type. The first
  / main one for the type is for adding the data item to an array.
  The second one's name ends in `ToMap`, is used for adding
@@ -465,30 +465,30 @@
  argument that is its label in the map. The third one ends in
  `ToMapN`, is also used for adding data items to maps, and
  takes an integer argument that is its label in the map.
- 
+
  The simplest aggregate type is an array, which is a simple ordered
- set of items without labels the same as JSON arrays. Call 
+ set of items without labels the same as JSON arrays. Call
  QCBOREncode_OpenArray() to open a new array, then "Add" to
  put items in the array and then QCBOREncode_CloseArray(). Nesting
  to a limit is allowed.  All opens must be matched by closes or an
  encoding error will be returned.
- 
+
  The other aggregate type is a map which does use labels. The
  `Add` functions that end in `ToMap` and `ToMapN` are convenient
  ways to add labeled data items to a map. You can also call
  any type of `Add` function once to add a label of any time and
  then call any type of `Add` again to add its value.
- 
+
  Note that when you nest arrays or maps in a map, the nested
  array or map has a label.
 
  Usually it is not necessary to add tags explicitly as most
  tagged types have functions here, but they can be added by
  calling QCBOREncode_AddTag().  There is an IANA registry for new tags that are
- for broad use and standardization as per RFC 7049. It is also 
+ for broad use and standardization as per RFC 7049. It is also
  allowed for protocols to make up new tags in the range above 256.
  Note that even arrays and maps can be tagged.
- 
+
  Summary Limits of this implementation:
  - The entire encoded CBOR must fit into contiguous memory.
  - Max size of encoded / decoded CBOR data is UINT32_MAX (4GB).
@@ -502,21 +502,21 @@
  - Does not directly support int labels greater than INT64_MAX
  - Epoch dates limited to INT64_MAX (+/- 292 billion years)
  - Tags on labels are ignored during decoding
- 
+
  This implementation is intended to run on 32 and 64-bit CPUs. It
  will probably work on 16-bit CPUs but less efficiently.
- 
+
  The public interface uses size_t for all lengths. Internally the
  implementation uses 32-bit lengths by design to use less memory and
  fit structures on the stack. This limits the encoded
  CBOR it can work with to size UINT32_MAX (4GB) which should be
  enough.
- 
+
  This implementation assumes two's compliment integer
  machines. Stdint.h also requires this. It of course would be easy to
  fix this implementation for another integer representation, but all
  modern machines seem to be two's compliment.
- 
+
  */
 
 
@@ -525,7 +525,7 @@
 */
 #define QCBOR_MAX_ITEMS_IN_ARRAY (UINT16_MAX) // This value is 65,535 a lot of items for an array
 
-/** 
+/**
  The maximum nesting of arrays and maps when encoding or decoding. The
  error QCBOR_ERR_ARRAY_NESTING_TOO_DEEP will be returned on encoding
  of decoding if it is exceeded
@@ -632,7 +632,7 @@
    /** During decoding, too many tags in the caller-configured tag list, or not
        enough space in QCBORTagListOut. */
    QCBOR_ERR_TOO_MANY_TAGS
-   
+
 } QCBORError;
 
 
@@ -713,7 +713,7 @@
    uint8_t  uDataAlloc;    /** 1 if allocated with string allocator, 0 if not. See QCBORDecode_MakeMallocStringAllocator() */
    uint8_t  uLabelAlloc;   /** Like uDataAlloc, but for label */
    uint8_t  uNextNestLevel; /** If not equal to uNestingLevel, this item closed out at least one map/array */
-   
+
    union {
       int64_t     int64;      /** The value for uDataType QCBOR_TYPE_INT64 */
       uint64_t    uint64;     /** The value for uDataType QCBOR_TYPE_UINT64 */
@@ -730,17 +730,17 @@
       UsefulBufC  bigNum;     /** The value for uDataType QCBOR_TYPE_BIGNUM */
       uint8_t     uSimple;    /** The integer value for unknown simple types */
       uint64_t    uTagV;
-      
+
    } val;  /** The union holding the item's value. Select union member based on uDataType */
-   
+
    union {
       UsefulBufC  string;  /** The label for uLabelType QCBOR_TYPE_BYTE_STRING and QCBOR_TYPE_TEXT_STRING */
       int64_t     int64;   /** The label for uLabelType for QCBOR_TYPE_INT64 */
       uint64_t    uint64;  /** The label for uLabelType for QCBOR_TYPE_UINT64 */
    } label; /** Union holding the different label types selected based on uLabelType */
-   
+
    uint64_t uTagBits; /** Bit indicating which tags (major type 6) on this item.  */
-   
+
 } QCBORItem;
 
 
@@ -748,22 +748,22 @@
  This is a set of functions and pointer context (in object-oriented parlance,
  an "object") used to allocate memory for coalescing the segments of an indefinite
  length string into one.
- 
+
  The fAllocate function works as an initial allocator and a reallocator to
  expand the string for each new segment. When it is an initial allocator
  pOldMem is NULL.
- 
+
  The fFree function is called to clean up an individual allocation when an error occurs.
- 
+
  The fDesctructor function is called when QCBORDecode_Finish is called.
- 
+
  Any memory allocated with this will be marked by setting uDataAlloc
  or uLabelAlloc in the QCBORItem structure so the caller knows they
  have to free it.
- 
+
  fAllocate is only ever called to increase the single most recent
  allocation made, making implementation of a memory pool very simple.
- 
+
  fFree is also only called on the single most recent allocation.
  */
 typedef struct {
@@ -795,11 +795,11 @@
  full list of tags on an item. It not needed for most CBOR protocol
  implementations. Its primary use is for pretty-printing CBOR or
  protocol conversion to another format.
- 
+
  On input, puTags points to a buffer to be filled in
  and uNumAllocated is the number of uint64_t values
  in the buffer.
- 
+
  On output the buffer contains the tags for the item.
  uNumUsed tells how many there are.
  */
@@ -822,19 +822,19 @@
 
 /**
  Initialize the the encoder to prepare to encode some CBOR.
- 
+
  @param[in,out]  pCtx    The encoder context to initialize.
  @param[in]      Storage The buffer into which this encoded result will be placed.
- 
+
  Call this once at the start of an encoding of a CBOR structure. Then
  call the various QCBOREncode_AddXXX() functions to add the data
  items. Then call QCBOREncode_Finish().
- 
+
  The maximum output buffer is UINT32_MAX (4GB). This is not a practical
  limit in any way and reduces the memory needed by the implementation.
  The error QCBOR_ERR_BUFFER_TOO_LARGE will be returned by QCBOR_Finish()
  if a larger buffer length is passed in.
-  
+
  If this is called with pBuf as NULL and uBufLen a large value like
  UINT32_MAX, all the QCBOREncode_AddXXXX() functions and
  QCBORE_Encode_Finish() can still be called. No data will be encoded,
@@ -842,7 +842,7 @@
  length of the encoded structure will be handed back in the call to
  QCBOREncode_Finish(). You can then allocate a buffer of that size
  and call all the encoding again, this time to fill in the buffer.
- 
+
  A QCBORContext can be reused over and over as long as
  QCBOREncode_Init() is called.
  */
@@ -851,12 +851,12 @@
 
 /**
  @brief  Add a signed 64-bit integer to the encoded output.
- 
+
  @param[in] pCtx      The encoding context to add the integer to.
  @param[in] nNum      The integer to add.
- 
+
  The integer will be encoded and added to the CBOR output.
- 
+
  This function figures out the size and the sign and encodes in the
  correct minimal CBOR. Specifically, it will select CBOR major type 0 or 1
  based on sign and will encode to 1, 2, 4 or 8 bytes depending on the
@@ -866,7 +866,7 @@
  advantage of when designing CBOR-based protocols. If integers like
  tags 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 int16_t or a small value, say 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,
@@ -874,17 +874,17 @@
  as an integer too as the major type for an integer is 0. See RFC 7049
  Appendix A for more examples of CBOR encoding. This compact encoding
  is also canonical CBOR as per section 3.9 in RFC 7049.
- 
+
  There are no functions to add int16_t or 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).
- 
+
  If the encoding context is in an error state, this will do
  nothing. If an error occurs when adding this integer, the internal
  error flag will be set, and the error will be returned when
  QCBOREncode_Finish() is called.
- 
+
  See also QCBOREncode_AddUInt64().
  */
 void QCBOREncode_AddInt64(QCBOREncodeContext *pCtx, int64_t nNum);
@@ -896,16 +896,16 @@
 
 /**
  @brief  Add an unsigned 64-bit integer to the encoded output.
- 
+
  @param[in] pCtx      The encoding context to add the integer to.
  @param[in] uNum      The integer to add.
- 
+
  The integer will be encoded and added to the CBOR output.
- 
+
  The only reason so use this function is for integers larger than
  INT64_MAX and smaller than UINT64_MAX. Otherwise QCBOREncode_AddInt64()
  will work fine.
- 
+
  Error handling is the same as for QCBOREncode_AddInt64().
  */
 void QCBOREncode_AddUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
@@ -916,24 +916,24 @@
 
 
 /**
- 
+
  @brief  Add a UTF-8 text string to the encoded output
- 
+
  @param[in] pCtx     The context to initialize.
  @param[in] Text    Pointer and length of text to add.
- 
+
  The text passed in must be unencoded UTF-8 according to RFC
  3629. There is no NULL termination. The text is added as CBOR
  major type 3.
- 
+
  If called with nBytesLen equal to 0, an empty string will be
  added. When nBytesLen is 0, pBytes may be NULL.
- 
+
  Note that the restriction of the buffer length to an uint32_t is
  entirely intentional as this encoder is not capable of encoding
  lengths greater. This limit to 4GB for a text string should not be a
  problem.
- 
+
  Error handling is the same as QCBOREncode_AddInt64().
  */
 static void QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text);
@@ -945,10 +945,10 @@
 
 /**
  @brief  Add a UTF-8 text string to the encoded output
- 
+
  @param[in] pCtx      The context to initialize.
  @param[in] szString  Null-terminated text to add.
- 
+
  This works the same as QCBOREncode_AddText().
  */
 static void QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString);
@@ -960,27 +960,27 @@
 
 /**
  @brief  Add a floating-point number to the encoded output
- 
+
  @param[in] pCtx      The encoding context to add the float to.
  @param[in] dNum      The double precision number to add.
- 
+
  This outputs a floating-point number with CBOR major type 7.
- 
+
  This will selectively encode the double-precision floating point number as either
  double-precision, single-precision or half-precision. It will always encode infinity, NaN and 0
  has 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.
- 
+
  Half-precision floating point numbers take up 2 bytes, half that of single-precision,
  one quarter of double-precision
- 
+
  This automatically reduces the size of encoded messages a lot, maybe even by four if most of values are
  0, infinity or NaN.
- 
+
  On decode, these will always be returned as a double.
- 
+
  Error handling is the same as QCBOREncode_AddInt64().
  */
 void QCBOREncode_AddDouble(QCBOREncodeContext *pCtx, double dNum);
@@ -992,17 +992,17 @@
 
 /**
  @brief[in] Add an optional tag
- 
+
  @param[in] pCtx  The encoding context to add the integer to.
  @param[in] uTag  The tag to add
- 
+
  This outputs a CBOR major type 6 optional tag.
- 
+
  The tag is applied to the next data item added to the encoded
  output. That data item that is to be tagged can be of any major
  CBOR type. Any number of tags can be added to a data item by calling
  this multiple times before the data item is added.
- 
+
  For many of the common standard tags a function to encode
  data using it already exists and this is not needed. For example,
  QCBOREncode_AddDateEpoch() already exists to output
@@ -1013,29 +1013,29 @@
 
 /**
  @brief  Add an epoch-based date
- 
+
  @param[in] pCtx     The encoding context to add the simple value to.
  @param[in] date     Number of seconds since 1970-01-01T00:00Z in UTC time.
- 
+
  As per RFC 7049 this is similar to UNIX/Linux/POSIX dates. This is
  the most compact way to specify a date and time in CBOR. Note that this
  is always UTC and does not include the time zone.  Use
  QCBOREncode_AddDateString() if you want to include the time zone.
- 
+
  The integer encoding rules apply here so the date will be encoded in a
  minimal number of 1, 2 4 or 8 bytes. Until about the year 2106 these
  dates should encode in 6 bytes -- one byte for the tag, one byte for the type
  and 4 bytes for the integer.
- 
+
  If you care about leap-seconds and that level of accuracy, make sure the
  system you are running this code on does it correctly. This code just takes
  the value passed in.
- 
+
  This implementation cannot encode fractional seconds using float or double
  even though that is allowed by CBOR, but you can encode them if you
  want to by calling QCBOREncode_AddDouble()
  with the right parameters.
- 
+
  Error handling is the same as QCBOREncode_AddInt64().
  */
 static void QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx, int64_t date);
@@ -1047,15 +1047,15 @@
 
 /**
  @brief Add a byte string to the encoded output.
- 
+
  @param[in] pCtx      The context to initialize.
  @param[in] Bytes     Pointer and length of the input data.
- 
+
  Simply adds the bytes to the encoded output as CBOR major type 2.
- 
+
  If called with Bytes.len equal to 0, an empty string will be
  added. When Bytes.len is 0, Bytes.ptr may be NULL.
- 
+
  Error handling is the same as QCBOREncode_AddInt64().
  */
 static void QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
@@ -1068,12 +1068,12 @@
 
 /**
  @brief Add a binary UUID to the encoded output.
- 
+
  @param[in] pCtx      The context to initialize.
  @param[in] Bytes     Pointer and length of the binary UUID.
- 
+
  A binary UUID as defined in RFC 4122 is added to the ouput.
- 
+
  It is output as CBOR major type 2, a binary string, with
  optional tag 36 indicating the binary string is a UUID.
  */
@@ -1086,17 +1086,17 @@
 
 /**
  @brief Add a positive big number to the encoded output.
- 
+
  @param[in] pCtx      The context to initialize.
  @param[in] Bytes     Pointer and length of the big number.
- 
+
  Big numbers are integers larger than 64-bits. Their format
  is described in RFC 7049.
- 
+
  It is output as CBOR major type 2, a binary string, with
  optional tag 2 indicating the binary string is a positive big
  number.
- 
+
  Often big numbers are used to represent cryptographic keys,
  however, COSE which defines representations for keys chose not
  to use this particular type.
@@ -1110,17 +1110,17 @@
 
 /**
  @brief Add a negative big number to the encoded output.
- 
+
  @param[in] pCtx      The context to initialize.
  @param[in] Bytes     Pointer and length of the big number.
- 
+
  Big numbers are integers larger than 64-bits. Their format
  is described in RFC 7049.
- 
+
  It is output as CBOR major type 2, a binary string, with
  optional tag 2 indicating the binary string is a negative big
  number.
- 
+
  Often big numbers are used to represent cryptographic keys,
  however, COSE which defines representations for keys chose not
  to use this particular type.
@@ -1134,12 +1134,12 @@
 
 /**
  @brief Add a text URI to the encoded output.
- 
+
  @param[in] pCtx    The context to initialize.
  @param[in] URI     Pointer and length of the URI.
- 
+
  The format of URI is RFC 3986.
- 
+
  It is output as CBOR major type 3, a text string, with
  optional tag 32 indicating the text string is a URI.
  */
@@ -1152,12 +1152,12 @@
 
 /**
  @brief Add base 64-encoded text to encoded output.
- 
+
  @param[in] pCtx     The context to initialize.
  @param[in] B64Text  Pointer and length of the base-64 encoded text.
- 
+
  The text content is base 64 encoded data per RFC 4648.
- 
+
  It is output as CBOR major type 3, a text string, with
  optional tag 34 indicating the text string is a URI.
  */
@@ -1170,12 +1170,12 @@
 
 /**
  @brief Add base 64URL -encoded URL to encoded output.
- 
+
  @param[in] pCtx    The context to initialize.
  @param[in] B64Text  Pointer and length of the base-64 encoded text.
- 
+
  The text content is base 64 URL format encoded text as per RFC 4648.
- 
+
  It is output as CBOR major type 3, a text string, with
  optional tag 33 indicating the text string is a URI.
  */
@@ -1188,13 +1188,13 @@
 
 /**
  @brief Add Perl Compatible Regular Expression
- 
+
  @param[in] pCtx    The context to initialize.
  @param[in] Regex   Pointer and length of the regular expression.
- 
+
  The text content is Perl Compatible Regular
  Expressions (PCRE) / JavaScript syntax [ECMA262].
- 
+
  It is output as CBOR major type 3, a text string, with
  optional tag 35 indicating the text string is a regular expression.
  */
@@ -1207,12 +1207,12 @@
 
 /**
  @brief MIME encoded text to the encoded output.
- 
+
  @param[in] pCtx      The context to initialize.
  @param[in] MIMEData  Pointer and length of the regular expression.
- 
+
  The text content is in MIME format per RFC 2045 including the headers.
- 
+
  It is output as CBOR major type 3, a text string, with
  optional tag 36 indicating the text string is MIME data.
  */
@@ -1225,17 +1225,17 @@
 
 /**
  @brief  Add an RFC 3339 date string
- 
+
  @param[in] pCtx      The encoding context to add the simple value to.
  @param[in] szDate    Null-terminated string with date to add
 
  The string szDate should be in the form of RFC 3339 as defined by section
  3.3 in RFC 4287. This is as described in section 2.4.1 in RFC 7049.
- 
+
  Note that this function doesn't validate the format of the date string
  at all. If you add an incorrect format date string, the generated
  CBOR will be incorrect and the receiver may not be able to handle it.
- 
+
  Error handling is the same as QCBOREncode_AddInt64().
  */
 static void QCBOREncode_AddDateString(QCBOREncodeContext *pCtx, const char *szDate);
@@ -1247,12 +1247,12 @@
 
 /**
  @brief  Add a standard boolean.
- 
+
  @param[in] pCtx   The encoding context to add the simple value to.
  @param[in] b      true or false from stdbool. Anything will result in an error.
- 
+
  Adds a boolean value as CBOR major type 7.
- 
+
  Error handling is the same as QCBOREncode_AddInt64().
  */
 static void QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b);
@@ -1265,14 +1265,14 @@
 
 /**
  @brief  Add a NULL to the encoded output.
- 
+
  @param[in] pCtx   The encoding context to add the simple value to.
- 
+
  Adds the NULL value as CBOR major type 7.
- 
+
  This NULL 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().
  */
 static void QCBOREncode_AddNULL(QCBOREncodeContext *pCtx);
@@ -1284,16 +1284,16 @@
 
 /**
  @brief  Add an "undef" to the encoded output.
- 
+
  @param[in] pCtx   The encoding context to add the simple value to.
- 
+
  Adds the undef value as CBOR major type 7.
- 
+
  Note that this value will not translate to JSON.
- 
+
  This 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().
  */
 static void QCBOREncode_AddUndef(QCBOREncodeContext *pCtx);
@@ -1305,16 +1305,16 @@
 
 /**
  @brief  Indicates that the next items added are in an array.
- 
+
  @param[in] pCtx The encoding context to open the array in.
- 
+
  Arrays are the basic CBOR aggregate or structure type. Call this
  function to start or open an array. Then call the various AddXXX
  functions to add the items that go into the array. Then call
  QCBOREncode_CloseArray() when all items have been added. The
  data items in the array can be of any type and can be of
  mixed types.
- 
+
  Nesting of arrays and maps is allowed and supported just by calling
  OpenArray again before calling CloseArray.  While CBOR has no limit
  on nesting, this implementation does in order to keep it smaller and
@@ -1323,13 +1323,13 @@
  QCBOREncode_CloseArray(). QCBOREncode_Finish() will return
  QCBOR_ERR_ARRAY_TOO_LONG when it is called as this function just sets
  an error state and returns no value when this occurs.
- 
+
  If you try to add more than 32,767 items to an array or map, incorrect CBOR will
  be produced by this encoder.
- 
+
  An array itself must have a label if it is being added to a map.  Note that
  array elements do not have labels (but map elements do).
- 
+
  An array itself may be tagged.
  */
 static void QCBOREncode_OpenArray(QCBOREncodeContext *pCtx);
@@ -1341,21 +1341,21 @@
 
 /**
  @brief Close an open array.
- 
+
  @param[in] pCtx The context to add to.
- 
+
  The closes an array opened by QCBOREncode_OpenArray(). It reduces
  nesting level by one. All arrays (and maps) must be closed
  before calling QCBOREncode_Finish().
- 
+
  When an error occurs as a result of this call, the encoder records
  the error and enters the error state. The error will be returned when
  QCBOREncode_Finish() is called.
- 
+
  If this has been called more times than QCBOREncode_OpenArray(),
  then QCBOR_ERR_TOO_MANY_CLOSES will be returned when
  QCBOREncode_Finish() is called.
- 
+
  If this is called and it is not an array that is currently
  open, QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
  is called.
@@ -1365,31 +1365,31 @@
 
 /**
  @brief  Indicates that the next items added are in a map.
- 
+
  @param[in] pCtx The context to add to.
- 
+
  See QCBOREncode_OpenArray() for more information.
- 
+
  CBOR maps are an aggregate type where each item in the map consists
  of a label and a value. They are similar to JSON objects.
- 
+
  The value can be any CBOR type including another map.
- 
+
  The label can also be any CBOR type, but in practice they are
  typically, integers as this gives the most compact output. They
  might also be text strings which gives readability and translation
  to JSON.
- 
+
  Every QCBOREncode_AddXXX() call has once version that is "InMap" for
  adding items to maps with string labels and on that is "InMapN" that
  is for adding with integer labels.
- 
+
  RFC 7049 uses the term "key" instead of "label".
- 
+
  If you wish to use map labels that are neither integer labels or
  text strings, then just call the QCBOREncode_AddXXX() function
  explicitly to add the label. Then call it again to add the value.
- 
+
  See the RFC7049 for a lot more information on creating maps.
  */
 static void QCBOREncode_OpenMap(QCBOREncodeContext *pCtx);
@@ -1402,20 +1402,20 @@
 
 /**
  @brief Close an open map.
- 
+
  @param[in] pCtx The context to add to.
- 
+
  The closes a map opened by QCBOREncode_OpenMap(). It reduces
  nesting level by one.
- 
+
  When an error occurs as a result of this call, the encoder records
  the error and enters the error state. The error will be returned when
  QCBOREncode_Finish() is called.
- 
+
  If this has been called more times than QCBOREncode_OpenMap(),
  then QCBOR_ERR_TOO_MANY_CLOSES will be returned when
  QCBOREncode_Finish() is called.
- 
+
  If this is called and it is not a map that is currently
  open, QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
  is called.
@@ -1425,27 +1425,27 @@
 
 /**
  @brief Indicate start of encoded CBOR to be wrapped in a bstr.
- 
+
  @param[in] pCtx The context to add to.
- 
+
  All added encoded items between this call and a call to
  QCBOREncode_CloseBstrWrap() will be wrapped in a bstr. They will
  appear in the final output as a byte string.  That byte string will
  contain encoded CBOR.
- 
+
  The typical use case is for encoded CBOR that is to be
  cryptographically hashed, as part of a COSE (RFC 8152)
  implementation. This avoids having to encode the items first in one
  buffer (e.g., the COSE payload) and then add that buffer as a bstr to
  another encoding (e.g. the COSE to-be-signed bytes, the
  Sig_structure) potentially saving a lot of memory.
- 
+
  When constructing cryptographically signed CBOR objects, maps or arrays, they
  typically are encoded
  normally and then wrapped as a byte string. The COSE standard for example
  does this. The wrapping is simply treating the encoded CBOR map
  as a byte string.
- 
+
  The stated purpose of this wrapping is to prevent code relaying the signed data
  but not verifying it from tampering with the signed data thus making
  the signature unverifiable. It is also quite beneficial for the
@@ -1463,13 +1463,13 @@
 
 /**
  @brief Close a wrapping bstr.
- 
+
  @param[in] pCtx The context to add to.
  @param[out] pWrappedCBOR UsefulBufC containing wrapped bytes
- 
+
  The closes a wrapping bstr opened by QCBOREncode_BstrWrap(). It reduces
  nesting level by one.
- 
+
  A pointer and length of the enclosed encoded CBOR is returned in
  *pWrappedCBOR if it is not NULL. The main purpose of this is so this
  data can be hashed (e.g., with SHA-256) as part of a COSE (RFC 8152)
@@ -1477,15 +1477,15 @@
  right away before any other calls to QCBOREncode_xxxx() as they will
  move data around and the pointer and length will no longer be to the
  correct encoded CBOR.
- 
+
  When an error occurs as a result of this call, the encoder records
  the error and enters the error state. The error will be returned when
  QCBOREncode_Finish() is called.
- 
+
  If this has been called more times then QCBOREncode_BstrWrap(),
  then QCBOR_ERR_TOO_MANY_CLOSES will be returned when
  QCBOREncode_Finish() is called.
- 
+
  If this is called and it is not a wrapping bstr that is currently
  open, QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
  is called.
@@ -1495,19 +1495,19 @@
 
 /**
  Add some already-encoded CBOR bytes.
- 
+
  @param[in] pCtx The context to add to.
  @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
  raw CBOR added here to have indefinite lengths.
- 
+
  The raw CBOR added here is not checked in anyway. If it is not
  conforming or has open arrays or such, the final encoded CBOR
  will probably be wrong or not what was intended.
- 
+
  If the encoded CBOR being added here contains multiple items, they
  must be enclosed in a map or array. At the top level the raw
  CBOR must be a single data item.
@@ -1521,28 +1521,28 @@
 
 /**
  Get the encoded result.
- 
+
  @param[in] pCtx  The context to finish encoding with.
  @param[out] pEncodedCBOR  Pointer and length of encoded CBOR.
- 
+
  @return
  One of the CBOR error codes.
- 
+
  If this returns success QCBOR_SUCCESS the encoding was a success and
  the return length is correct and complete.
- 
+
  If no buffer was passed to QCBOR_Init(), then only the length and
  number of items was computed. The length is in
  pEncodedCBOR->Bytes.len. pEncodedCBOR->Bytes.ptr is NULL.
- 
+
  If a buffer was passed, then pEncodedCBOR->Bytes.ptr is the same as
  the buffer passed to QCBOR_Init() and contains the encoded CBOR
  and the length is filled in.
- 
+
  If an error is returned, the buffer may have partially encoded
  incorrect CBOR in it and it should not be used. Likewise, the length
  may be incorrect and should not be used.
- 
+
  Note that the error could have occurred in one of the many
  QCBOR_AddXXX calls long before QCBOREncode_Finish() was called. This
  error handling approach reduces the CBOR implementation size, but makes
@@ -1553,24 +1553,24 @@
 
 /**
  Get the encoded CBOR and error status.
- 
+
  @param[in] pCtx  The context to finish encoding with.
  @param[out] uEncodedLen The length of the encoded or potentially encoded CBOR in bytes.
- 
+
  @return
  One of the CBOR error codes.
- 
+
  If this returns success QCBOR_SUCCESS the encoding was a success and
  the return length is correct and complete.
- 
+
  If no buffer was passed to QCBOR_Init(), then only the length was
  computed. If a buffer was passed, then the encoded CBOR is in the
  buffer.
- 
+
  If an error is returned, the buffer may have partially encoded
  incorrect CBOR in it and it should not be used. Likewise, the length
  may be incorrect and should not be used.
- 
+
  Note that the error could have occurred in one of the many
  QCBOR_AddXXX calls long before QCBOREncode_Finish() was called. This
  error handling reduces the CBOR implementation size, but makes
@@ -1595,35 +1595,35 @@
 
 /**
  Initialize the CBOR decoder context.
- 
+
  @param[in] pCtx The context to initialize.
  @param[in] EncodedCBOR The buffer with CBOR encoded bytes to be decoded.
  @param[in] nMode One of QCBOR_DECODE_MODE_xxx
- 
+
  Initialize context for a pre-order travesal of the encoded CBOR tree.
- 
+
  Most CBOR decoding can be completed by calling this function to start
  and QCBORDecode_GetNext() in a loop.
- 
+
  If indefinite length strings are to be decoded, then
  QCBORDecode_SetMemPool() or QCBORDecode_SetUpAllocator() must be
  called to set up a string allocator.
- 
+
  If tags other than built-in tags are to be recognized, then
  QCBORDecode_SetCallerAddedTagMap() must be called. The built-in tags
  are those for which a macro of the form  CBOR_TAG_XXX is defined.
- 
+
  Three decoding modes are supported.  In normal mode,
  QCBOR_DECODE_MODE_NORMAL, maps are decoded and strings and ints are
  accepted as map labels. If a label is other than these, the error
  QCBOR_ERR_MAP_LABEL_TYPE is returned by QCBORDecode_GetNext().
- 
+
  In strings-only mode, QCBOR_DECODE_MODE_MAP_STRINGS_ONLY, only text
  strings are accepted for map labels.  This lines up with CBOR that
  converts to JSON. The error QCBOR_ERR_MAP_LABEL_TYPE is returned by
  QCBORDecode_GetNext() if anything but a text string label is
  encountered.
- 
+
  In QCBOR_DECODE_MODE_MAP_AS_ARRAY maps are treated as special arrays.
  They will be return with special uDataType QCBOR_TYPE_MAP_AS_ARRAY
  and uCount, the number of items, will be double what it would be
@@ -1637,38 +1637,38 @@
 
 /**
  Set up the MemPool string allocator for indefinite length strings.
- 
+
  @param[in] pCtx The decode context.
  @param[in] MemPool The pointer and length of the memory pool.
  @param[in] bAllStrings true means to put even definite length strings in the pool.
- 
+
  @return 0 if the MemPool was at least minimum size, 1 if too small.
- 
+
  Indefinite length strings (text and byte) cannot be decoded unless there is
  a string allocator configured. MemPool is a simple built-in string allocator
  that allocates bytes from a memory pool handed to it by calling
  this function.  The memory pool is just a pointer and length for some
  block of memory that is to be used for string allocation. It can
  come from the stack, heap or other.
- 
+
  The memory pool must be large enough to hold some fixed overhead plus the
  space for all the strings allocated. The fixed overhead does vary
  by CPU and compiler, but can roughly be computed as the space for
  seven pointers, 56 bytes for a 64-bit CPU.  There is no overhead
  per string allocated
- 
+
  This memory pool is used for all indefinite length strings that are text
  strings or byte strings, including strings used as labels.
- 
+
  The pointers to strings in QCBORItem will point into the memory pool set
  here. They do not need to be individually freed. Just discard the buffer
  when they are no longer needed.
- 
+
  If bAllStrings is set, then the size will be the overhead plus the space to
  hold **all** strings, definite and indefinite length, value or label. The
  advantage of this is that after the decode is complete, the original memory
  holding the encoded CBOR does not need to remain valid.
- 
+
  If this function is not called because there is no need to support indefinite
  length strings, the MemPool implementation should be dead-stripped by the loader
  and not add to code size.
@@ -1678,18 +1678,18 @@
 
 /**
  @brief Sets up a custom string allocator for indefinite length strings
- 
+
  @param[in] pCtx The decoder context to set up an allocator for
  @param[in] pAllocator The string allocator "object"
- 
+
  See QCBORStringAllocator for the requirements of the string allocator.
- 
+
  Typically, this is used if the simple MemPool allocator isn't desired.
- 
+
  A malloc based string allocator can be obtained by calling
  QCBORDecode_MakeMallocStringAllocator(). Pass its result to
  this function.
- 
+
  You can also write your own allocator. Create the allocate, free,
  and destroy functions and put pointers to them in a QCBORStringAllocator.
  */
@@ -1698,14 +1698,14 @@
 
 /**
  @brief Configure list of caller selected tags to be recognized
- 
+
  @param[in] pCtx The decode context.
  @param[out] pTagList Structure holding the list of tags to configure
- 
+
  This is used to tell the decoder about tags beyond those that are
  built-in that should be recognized. The built-in tags are those
  with macros of the form CBOR_TAG_XXX.
- 
+
  See description of QCBORTagListIn.
  */
 void QCBORDecode_SetCallerConfiguredTagList(QCBORDecodeContext *pCtx, const QCBORTagListIn *pTagList);
@@ -1713,16 +1713,16 @@
 
 /**
  @brief This returns a string allocator that uses malloc
- 
+
  @return pointer to string allocator or NULL
- 
+
  Call this to get the string allocator and then configure it into
  the decoder by calling QCBORDecode_SetUpAllocator().  If you
  don't call this, there will be no dependency on malloc
  in QCBOR. Some deployments of QCBOR might even exclude
  the implementation of this function if they don't have
  malloc() at all.
- 
+
  If you do set up this malloc-based string allocator, then
  every string marked as allocated in a QCBORItem must
  freed. They are marked by uDataAlloc and uLabelAlloc
@@ -1733,10 +1733,10 @@
 
 /**
  @brief Gets the next item (integer, byte string, array...) in pre order traversal of CBOR tree
- 
+
  @param[in]  pCtx          The decoder context.
  @param[out] pDecodedItem  Holds the CBOR item just decoded.
- 
+
  @return 0 or error. All errors except QCBOR_ERR_TOO_MANY_TAGS
  and QCBOR_ERR_STRING_ALLOCATE indicate that the CBOR input
  could not be decoded. In most cases
@@ -1749,28 +1749,28 @@
  QCBOR_ERR_MAP_LABEL_TYPE is in a way a limitation of
  this implementation, but can be avoided by decoding
  in QCBOR_DECODE_MODE_MAP_AS_ARRAY mode.
- 
+
  pDecodedItem is filled in with the value parsed. Generally, the
  following data is returned in the structure.
- 
+
  - The data type in uDataType which indicates which member of the val
    union the data is in. This decoder figures out the type based on the
    CBOR major type, the CBOR "additionalInfo", the CBOR optional tags
    and the value of the integer.
- 
+
  - The value of the item, which might be an integer, a pointer and a
    length, the count of items in an array, a floating-point number or
    other.
- 
+
  - The nesting level for maps and arrays.
- 
+
  - The label for an item in a map, which may be a text or byte string or an integer.
- 
+
  - The CBOR optional tag or tags.
- 
+
  See documentation on in the data type QCBORItem for all the details
  on what is returned.
- 
+
  This function also handles arrays and maps. When first encountered a
  QCBORItem will be returned with major type CBOR_MAJOR_TYPE_ARRAY or
  CBOR_MAJOR_TYPE_ARRAY_MAP. QCBORItem.val.uCount will indicate the number
@@ -1779,25 +1779,25 @@
  indefinite length maps and arrays, QCBORItem.val.uCount is UINT16_MAX
  and uNextNestLevel must be used to know when the end of a map
  or array is reached.
- 
+
  Nesting level 0 is the outside top-most nesting level. For example, in
  a CBOR structure with two items, an integer and a byte string only,
  both would be at nesting level 0.  A CBOR structure with an array
  open, an integer and a byte string, would have the integer and byte
  string as nesting level 1.
- 
+
  Here is an example of how the nesting level is reported with no arrays
  or maps at all
- 
+
  @verbatim
  CBOR Structure           Nesting Level
  Integer                    0
  Byte String                0
  @endverbatim
- 
+
  Here is an example of how the nesting level is reported with an a simple
  array and some top-level items.
- 
+
  @verbatim
  Integer                    0
  Array (with 2 items)       0
@@ -1805,11 +1805,11 @@
  Byte string                1
  Integer                    0
  @endverbatim
- 
- 
+
+
  Here's a more complex example
  @verbatim
- 
+
  Map with 2 items           0
  Text string                1
  Array with 3 integers      1
@@ -1819,7 +1819,7 @@
  text string                1
  byte string                1
  @endverbatim
- 
+
  In QCBORItem, uNextNestLevel is the nesting level for the next call
  to QCBORDecode_GetNext(). It indicates if any maps or arrays were closed
  out during the processing of the just-fecthed QCBORItem. This processing
@@ -1828,7 +1828,7 @@
  hierarchical structure. If uNextNestLevel is not equal to uNestLevel
  the end of the current map or array has been encountered. This
  works the same for both definite and indefinite length arrays.
- 
+
  Most uses of this decoder will not need to do anything extra for
  tag handling. The built-in tags, those with a macro of the form
  CBOR_TAG_XXXX, will be enough.
@@ -1836,14 +1836,14 @@
  If tags beyond built-in tags are to be recognized, they must be
  configured by calling QCBORDecode_SetCallerConfiguredTags(). If
  a tag is not recognized it is silently ignored.
- 
+
  Several tagged types are automatically recognized and decoded and
  returned in their decoded form.
- 
+
  To find out if a QCBORItem was tagged with a particular tag
  call QCBORDecode_IsTagged(). This works only for built-in
  tags and caller-configured tags.
- 
+
  To get the full list of tags on an Item without having to
  pre-configure any predetermined list of tags use
  QCBORDecode_GetNextWithTags().
@@ -1853,26 +1853,26 @@
 
 /**
  @brief Gets the next item including full list of tags for item
- 
+
  @param[in]  pCtx          The decoder context.
  @param[out] pDecodedItem  Holds the CBOR item just decoded.
  @param[in,out] pTagList   On input array to put tags in; on output the tags on this item.
- 
+
  @return 0 or error.
- 
+
  This works the same as QCBORDecode_GetNext() except that it also returns
  the full list of tags for the data item. This function should only
  be needed when parsing CBOR to print it out or convert it to some other
  format. It should not be needed in an actual CBOR protocol implementation.
- 
+
  Tags will be returned here whether or not they are in the built-in or
  caller-configured tag lists.
- 
+
  CBOR has no upper bound of limit on the number of tags that can be
  associated with a data item. In practice the number of tags on an item
  will usually be small, perhaps less than five. This will return an error
  if the array in pTagList is too small to hold all the tags for an item.
- 
+
  (This function is separate from  QCBORDecode_GetNext() so as to not have to
  make QCBORItem large enough to be able to hold a full list of tags. Even a list of
  five tags would nearly double its size because tags can be a uint64_t).
@@ -1882,30 +1882,30 @@
 
 /**
  @brief Determine if a CBOR item was tagged with a particular tag
- 
+
  @param[in] pCtx    The decoder context.
  @param[in] pItem   The CBOR item to check
  @param[in] uTag    The tag to check
 
  @return 1 if it was tagged, 0 if not
- 
+
  QCBORDecode_GetNext() processes tags by looking them up
  in two lists and setting a bit corresponding to the tag
  in uTagBits in the QCBORItem. To find out if a
  QCBORItem was tagged with a particular tag, call
  this function. It handles the mapping between
  the two lists of tags and the bits set for it.
- 
+
  The first tag list is the built-in tags, those
  with a macro of the form CBOR_TAG_XXX in this
  header file. There are up to 48 of these,
  corresponding to the lower 48 tag bits.
- 
+
  The other optional tag list is the ones
  the caller configured using QCBORDecode_SetCallerConfiguredTagList()
  There are QCBOR_MAX_CUSTOM_TAGS (16) of these corresponding to the
  upper 16 tag bits.
- 
+
  See also QCBORDecode_GetTags() and QCBORDecode_GetNextWithTags().
  */
 int QCBORDecode_IsTagged(QCBORDecodeContext *pCtx, const QCBORItem *pItem, uint64_t uTag);
@@ -1913,11 +1913,11 @@
 
 /**
  Check whether all the bytes have been decoded and maps and arrays closed.
- 
+
  @param[in]  pCtx          The context to check
- 
+
  @return QCBOR_SUCCESS or error
- 
+
  This tells you if all the bytes given to QCBORDecode_Init() have
  been consumed and whether all maps and arrays were closed.
  The decode is considered to be incorrect or incomplete if not
@@ -1930,40 +1930,40 @@
 
 /**
   Convert int64_t to smaller int's safely
- 
+
  @param [in]  src    An int64_t
  @param [out] dest   A smaller sized int to convert to
-  
+
  @return 0 on success -1 if not
- 
+
  When decoding an integer, the CBOR decoder will return the value as an
  int64_t unless the integer is in the range of INT64_MAX and
  UINT64_MAX. That is, unless the value is so large that it can only be
  represented as a uint64_t, it will be an int64_t.
- 
+
  CBOR itself doesn't size the individual integers it carries at
  all. The only limits it puts on the major integer types is that they
  are 8 bytes or less in length. Then encoders like this one use the
  smallest number of 1, 2, 4 or 8 bytes to represent the integer based
  on its value. There is thus no notion that one data item in CBOR is
  an 1 byte integer and another is a 4 byte integer.
- 
+
  The interface to this CBOR encoder only uses 64-bit integers. Some
  CBOR protocols or implementations of CBOR protocols may not want to
  work with something smaller than a 64-bit integer.  Perhaps an array
  of 1000 integers needs to be sent and none has a value larger than
  50,000 and are represented as uint16_t.
- 
+
  The sending / encoding side is easy. Integers are temporarily widened
  to 64-bits as a parameter passing through QCBOREncode_AddInt64() and
  encoded in the smallest way possible for their value, possibly in
  less than an uint16_t.
- 
+
  On the decoding side the integers will be returned at int64_t even if
  they are small and were represented by only 1 or 2 bytes in the
  encoded CBOR. The functions here will convert integers to a small
  representation with an overflow check.
- 
+
  (The decoder could have support 8 different integer types and
  represented the integer with the smallest type automatically, but
  this would have made the decoder more complex and code calling the
@@ -2047,23 +2047,23 @@
 
 /* ===========================================================================
  BEGINNING OF PRIVATE INLINE IMPLEMENTATION
- 
+
  =========================================================================== */
 
 /**
  @brief Semi-private method to add a buffer full of bytes to encoded output
- 
+
  @param[in] pCtx       The encoding context to add the integer to.
  @param[in] uMajorType The CBOR major type of the bytes.
  @param[in] Bytes      The bytes to add.
- 
+
  Use QCBOREncode_AddText() or QCBOREncode_AddBytes() or
  QCBOREncode_AddEncoded() instead. They are inline functions
  that call this and supply the correct major type. This function
  is public to make the inline functions work to keep the overall
  code size down and because the C language has no way to make
  it private.
- 
+
  If this is called the major type should be CBOR_MAJOR_TYPE_TEXT_STRING,
  CBOR_MAJOR_TYPE_BYTE_STRING or CBOR_MAJOR_NONE_TYPE_RAW. The last
  one is special for adding already-encoded CBOR.
@@ -2073,10 +2073,10 @@
 
 /**
  @brief Semi-private method to open a map, array or bstr wrapped CBOR
- 
+
  @param[in] pCtx The context to add to.
  @param[in] uMajorType The major CBOR type to close
- 
+
  Call QCBOREncode_OpenArray(), QCBOREncode_OpenMap() or
  QCBOREncode_BstrWrap() instead of this.
  */
@@ -2085,11 +2085,11 @@
 
 /**
  @brief Semi-private method to close a map, array or bstr wrapped CBOR
- 
+
  @param[in] pCtx The context to add to.
  @param[in] uMajorType The major CBOR type to close
  @param[out] pWrappedCBOR UsefulBufC containing wrapped bytes
- 
+
  Call QCBOREncode_CloseArray(), QCBOREncode_CloseMap() or
  QCBOREncode_CloseBstrWrap() instead of this.
  */
@@ -2098,19 +2098,19 @@
 
 /**
  @brief  Semi-private method to add simple types.
- 
+
  @param[in] pCtx      The encoding context to add the simple value to.
  @param[in] uSize     Minimum encoding size for uNum. Usually 0.
  @param[in] uNum      One of CBOR_SIMPLEV_FALSE through _UNDEF or other.
- 
+
  This is used to add simple types like true and false.
- 
+
  Call QCBOREncode_AddBool(), QCBOREncode_AddNULL(), QCBOREncode_AddUndef()
  instead of this.
- 
+
  This function can add simple values that are not defined by CBOR yet. This expansion
  point in CBOR should not be used unless they are standardized.
- 
+
  Error handling is the same as QCBOREncode_AddInt64().
  */
 void  QCBOREncode_AddType7(QCBOREncodeContext *pCtx, size_t uSize, uint64_t uNum);
@@ -2585,7 +2585,7 @@
 
 /* ===========================================================================
  END OF PRIVATE INLINE IMPLEMENTATION
- 
+
  =========================================================================== */
 
 #endif /* defined(__QCBOR__qcbor__) */
diff --git a/inc/xx.c b/inc/xx.c
new file mode 100644
index 0000000..7009e60
--- /dev/null
+++ b/inc/xx.c
@@ -0,0 +1,2592 @@
+/*==============================================================================
+ Copyright (c) 2016-2018, The Linux Foundation.
+ Copyright (c) 2018, Laurence Lundblade.
+ All rights reserved.
+ 
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of The Linux Foundation nor the names of its
+      contributors, nor the name "Laurence Lundblade" may be used to
+      endorse or promote products derived from this software without
+      specific prior written permission.
+ 
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ ==============================================================================*/
+
+
+/*===================================================================================
+ FILE:  qcbor.h
+ 
+ DESCRIPTION:  This is the full public API and data structures for QCBOR
+ 
+ EDIT HISTORY FOR FILE:
+ 
+ This section contains comments describing changes made to the module.
+ Notice that changes are listed in reverse chronological order.
+ 
+ when               who             what, where, why
+ --------           ----            ---------------------------------------------------
+ 12/13/18           llundblade      Documentatation improvements
+ 11/29/18           llundblade      Rework to simpler handling of tags and labels.
+ 11/9/18            llundblade      Error codes are now enums.
+ 11/1/18            llundblade      Floating support.
+ 10/31/18           llundblade      Switch to one license that is almost BSD-3.
+ 10/15/18           llundblade      Indefinite length maps and arrays supported
+ 10/8/18            llundblade      Indefinite length strings supported
+ 09/28/18           llundblade      Added bstr wrapping feature for COSE implementation.
+ 07/05/17           llundbla        Add bstr wrapping of maps/arrays for COSE.
+ 03/01/17           llundbla        More data types; decoding improvements and fixes.
+ 11/13/16           llundbla        Integrate most TZ changes back into github version.
+ 09/30/16           gkanike         Porting to TZ.
+ 03/15/16           llundbla        Initial Version.
+ 
+ =====================================================================================*/
+
+#ifndef __QCBOR__qcbor__
+#define __QCBOR__qcbor__
+
+/*...... This is a ruler that is 80 characters long...........................*/
+
+/* ===========================================================================
+   BEGINNING OF PRIVATE PART OF THIS FILE
+
+   Caller of QCBOR should not reference any of the details below up until
+   the start of the public part.
+   =========================================================================== */
+
+/*
+ Standard integer types are used in the interface to be precise about
+ sizes to be better at preventing underflow/overflow errors.
+ */
+#include <stdint.h>
+#include <stdbool.h>
+#include "UsefulBuf.h"
+
+
+/*
+ The maxium nesting of arrays and maps when encoding or decoding. 
+ (Further down in the file there is a definition that refers to this 
+ that is public. This is done this way so there can be a nice
+ separation of public and private parts in this file.
+*/
+#define QCBOR_MAX_ARRAY_NESTING1 15 // Do not increase this over 255
+
+
+/*  
+ PRIVATE DATA STRUCTURE 
+ 
+ Holds the data for tracking array and map nesting during encoding. Pairs up with
+ the Nesting_xxx functions to make an "object" to handle nesting encoding.
+ 
+ uStart is a uint32_t instead of a size_t to keep the size of this
+ struct down so it can be on the stack without any concern.  It would be about
+ double if size_t was used instead.
+ 
+ Size approximation (varies with CPU/compiler):
+    64-bit machine: (15 + 1) * (4 + 2 + 1 + 1 pad) + 8 = 136 bytes
+    32-bit machine: (15 + 1) * (4 + 2 + 1 + 1 pad) + 4 = 132 bytes
+*/
+typedef struct __QCBORTrackNesting {
+   // PRIVATE DATA STRUCTURE
+   struct {
+      // See function OpenArrayInternal() for detailed comments on how this works
+      uint32_t  uStart;     // uStart is the byte position where the array starts
+      uint16_t  uCount;     // Number of items in the arrary or map; counts items in a map, not pairs of items 
+      uint8_t   uMajorType; // Indicates if item is a map or an array
+   } pArrays[QCBOR_MAX_ARRAY_NESTING1+1], // stored state for the nesting levels
+   *pCurrentNesting; // the current nesting level
+} QCBORTrackNesting;
+
+
+/*  
+ PRIVATE DATA STRUCTURE 
+ 
+ Context / data object for encoding some CBOR. Used by all encode functions to 
+ form a public "object" that does the job of encdoing.
+ 
+ Size approximation (varies with CPU/compiler):
+   64-bit machine: 27 + 1 (+ 4 padding) + 136 = 32 + 136 = 168 bytes
+   32-bit machine: 15 + 1 + 132 = 148 bytes
+*/
+struct _QCBOREncodeContext {
+   // PRIVATE DATA STRUCTURE
+   UsefulOutBuf      OutBuf;  // Pointer to output buffer, its length and position in it
+   uint8_t           uError;  // Error state
+   QCBORTrackNesting nesting; // Keep track of array and map nesting
+};
+
+
+/*
+ PRIVATE DATA STRUCTURE
+ 
+ Holds the data for array and map nesting for decoding work. This structure
+ and the DecodeNesting_xxx functions form an "object" that does the work
+ for arrays and maps.
+ 
+ Size approximation (varies with CPU/compiler):
+   64-bit machine: 4 * 16 + 8 = 72
+   32-bit machine: 4 * 16 + 4 = 68
+ */
+typedef struct __QCBORDecodeNesting  {
+  // PRIVATE DATA STRUCTURE
+   struct {
+      uint16_t uCount;  
+      uint8_t  uMajorType;
+   } pMapsAndArrays[QCBOR_MAX_ARRAY_NESTING1+1],
+   *pCurrent;
+} QCBORDecodeNesting;
+
+
+/* 
+ PRIVATE DATA STRUCTURE
+
+ The decode context. This data structure plus the public QCBORDecode_xxx
+ functions form an "object" that does CBOR decoding.
+
+ Size approximation (varies with CPU/compiler):
+   64-bit machine: 32 + 1 + 1 + 6 bytes padding + 72 + 16 = 128 bytes
+   32-bit machine: 16 + 1 + 1 + 2 bytes padding + 68 + 8  = 68 bytes
+ */
+struct _QCBORDecodeContext {
+   // PRIVATE DATA STRUCTURE   
+   UsefulInputBuf InBuf;
+   
+   uint8_t        uDecodeMode;
+   uint8_t        bStringAllocateAll;
+   
+   QCBORDecodeNesting nesting;
+   
+   // This is NULL or points to a QCBORStringAllocator. It is void
+   // here because _QCBORDecodeContext is defined early in the
+   // private part of this file and QCBORStringAllocat is defined
+   // later in the public part of this file.
+   void *pStringAllocator;
+   
+   // This is NULL or points to QCBORTagList.
+   // It is type void for the same reason as above.
+   const void *pCallerConfiguredTagList;
+};
+
+// Used internally in the impementation here
+// Must not conflict with any of the official CBOR types
+#define CBOR_MAJOR_NONE_TYPE_RAW  9
+#define CBOR_MAJOR_NONE_TAG_LABEL_REORDER 10
+
+
+/* ===========================================================================
+   END OF PRIVATE PART OF THIS FILE
+
+   BEGINNING OF PUBLIC PART OF THIS FILE
+   =========================================================================== */
+
+
+
+/* ===========================================================================
+   BEGINNING OF CONSTANTS THAT COME FROM THE CBOR STANDARD, RFC 7049
+ 
+   It is not necessary to use these directly when encoding or decoding
+   CBOR with this implementation.
+   =========================================================================== */
+
+/* Standard CBOR Major type for positive integers of various lengths */
+#define CBOR_MAJOR_TYPE_POSITIVE_INT 0
+
+/* Standard CBOR Major type for negative integer of various lengths */
+#define CBOR_MAJOR_TYPE_NEGATIVE_INT 1
+
+/* Standard CBOR Major type for an array of arbitrary 8-bit bytes. */
+#define CBOR_MAJOR_TYPE_BYTE_STRING  2
+
+/* Standard CBOR Major type for a UTF-8 string. Note this is true 8-bit UTF8
+ with no encoding and no NULL termination */
+#define CBOR_MAJOR_TYPE_TEXT_STRING  3
+
+/* Standard CBOR Major type for an ordered array of other CBOR data items */
+#define CBOR_MAJOR_TYPE_ARRAY        4
+
+/* Standard CBOR Major type for CBOR MAP. Maps an array of pairs. The
+ first item in the pair is the "label" (key, name or identfier) and the second
+ item is the value.  */
+#define CBOR_MAJOR_TYPE_MAP          5
+
+/* Standard CBOR optional tagging. This tags things like dates and URLs */
+#define CBOR_MAJOR_TYPE_OPTIONAL     6
+
+/* Standard CBOR extra simple types like floats and the values true and false */
+#define CBOR_MAJOR_TYPE_SIMPLE       7
+
+
+/*
+ These are special values for the AdditionalInfo bits that are part of the first byte.
+ Mostly they encode the length of the data item.
+ */
+#define LEN_IS_ONE_BYTE    24
+#define LEN_IS_TWO_BYTES   25
+#define LEN_IS_FOUR_BYTES  26
+#define LEN_IS_EIGHT_BYTES 27
+#define ADDINFO_RESERVED1  28
+#define ADDINFO_RESERVED2  29
+#define ADDINFO_RESERVED3  30
+#define LEN_IS_INDEFINITE  31
+
+
+/*
+ 24 is a special number for CBOR. Integers and lengths
+ less than it are encoded in the same byte as the major type
+ */
+#define CBOR_TWENTY_FOUR   24
+
+
+/*
+ Tags that are used with CBOR_MAJOR_TYPE_OPTIONAL. These are
+ the ones defined in the CBOR spec.
+ */
+/** See QCBOREncode_AddDateString() below */
+#define CBOR_TAG_DATE_STRING    0
+/** See QCBOREncode_AddDateEpoch_2() */
+#define CBOR_TAG_DATE_EPOCH     1
+#define CBOR_TAG_POS_BIGNUM     2
+#define CBOR_TAG_NEG_BIGNUM     3
+#define CBOR_TAG_FRACTION       4
+#define CBOR_TAG_BIGFLOAT       5
+
+#define CBOR_TAG_COSE_ENCRYPTO 16
+#define CBOR_TAG_COSE_MAC0     17
+#define CBOR_TAG_COSE_SIGN1    18
+
+/* The data in byte string should be converted in base 64 URL when encoding in JSON or similar text-based representations */
+#define CBOR_TAG_ENC_AS_B64URL 21
+/* The data in byte string should be encoded in base 64 when encoding in JSON */
+#define CBOR_TAG_ENC_AS_B64    22
+/* The data in byte string should be encoded in base 16 when encoding in JSON */
+#define CBOR_TAG_ENC_AS_B16    23
+#define CBOR_TAG_CBOR          24
+/** The data in the string is a URIs, as defined in RFC3986 */
+#define CBOR_TAG_URI           32
+/** The data in the string is a base 64'd URL */
+#define CBOR_TAG_B64URL        33
+/** The data in the string is base 64'd */
+#define CBOR_TAG_B64           34
+/** regular expressions in Perl Compatible Regular Expressions (PCRE) / JavaScript syntax ECMA262. */
+#define CBOR_TAG_REGEX         35
+/** MIME messages (including all headers), as defined in RFC2045 */
+#define CBOR_TAG_MIME          36
+/** Binary UUID */
+#define CBOR_TAG_BIN_UUID      37
+
+#define CBOR_TAG_CWT           61
+
+#define CBOR_TAG_ENCRYPT       96
+#define CBOR_TAG_MAC           97
+#define CBOR_TAG_SIGN          98
+
+#define CBOR_TAG_GEO_COORD    103
+
+
+/** The data is CBOR data */
+#define CBOR_TAG_CBOR_MAGIC 55799
+#define CBOR_TAG_NONE  UINT64_MAX
+
+
+/*
+ Values for the 5 bits for items of major type 7
+ */
+#define CBOR_SIMPLEV_FALSE   20
+#define CBOR_SIMPLEV_TRUE    21
+#define CBOR_SIMPLEV_NULL    22
+#define CBOR_SIMPLEV_UNDEF   23
+#define CBOR_SIMPLEV_ONEBYTE 24
+#define HALF_PREC_FLOAT      25
+#define SINGLE_PREC_FLOAT    26
+#define DOUBLE_PREC_FLOAT    27
+#define CBOR_SIMPLE_BREAK    31
+
+
+
+/* ===========================================================================
+ 
+ END OF CONSTANTS THAT COME FROM THE CBOR STANDARD, RFC 7049
+ 
+ BEGINNING OF PUBLIC INTERFACE FOR QCBOR ENCODER / DECODER
+ 
+ =========================================================================== */
+
+/**
+ 
+ @file qcbor.h
+ 
+ Q C B O R   E n c o d e / D e c o d e
+ 
+ This implements CBOR -- Concise Binary Object Representation as defined
+ in RFC 7049. More info is at http://cbor.io.  This is a near-complete
+ implementation of the specification. Limitations are listed further down.
+ 
+ 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.
+ 
+ The memory model for encoding and decoding is that encoded CBOR
+ must be in a contiguous buffer in memory.  During encoding the
+ caller must supply an output buffer and if the encoding would go
+ off the end of the buffer an error is returned.  During decoding
+ the caller supplies the encoded CBOR in a contiguous buffer
+ and the decoder returns pointers and lengths into that buffer
+ for strings.
+ 
+ This implementation does not require malloc. All data structures
+ passed in/out of the APIs can fit on the stack.
+ 
+ Decoding of indefinite length strings is a special case that requires
+ a "string allocator" to allocate memory into which the segments of
+ the string are coalesced. Without this, decoding will error out if
+ an indefinite length string is encountered (indefinite length maps
+ and arrays do not require the string allocator). A simple string
+ allocator called MemPool is built-in and will work if supplied with
+ a block of memory to allocate. The string allocator can optionally
+ use malloc() or some other custom scheme.
+ 
+ Here are some terms and definitions:
+ 
+ - "Item", "Data Item": An integer or string or such. The basic "thing" that
+ CBOR is about. An array is an item itself that contains some items.
+ 
+ - "Array": An ordered sequence of items, the same as JSON.
+ 
+ - "Map": A collection of label/value pairs. Each pair is a data
+ item. A JSON "object" is the same as a CBOR "map".
+ 
+ - "Label": The data item in a pair in a map that names or identifies the
+ pair, not the value. This implementation refers to it as a "label".
+ JSON refers to it as the "name". The CBOR RFC refers to it this as a "key".
+ This implementation chooses label instead because key is too easily confused
+ with a cryptographic key. The COSE standard, which uses CBOR, has also
+ chosen to use the term "label" rather than "key" for this same reason.
+ 
+ - "Key": See "Label" above.
+ 
+ - "Tag": Optional info that can be added before each data item. This is always
+ CBOR major type 6.
+ 
+ - "Initial Byte": The first byte of an encoded item. Encoding and decoding of
+ this byte is taken care of by the implementation.
+ 
+ - "Additional Info": In addition to the major type, all data items have some
+ other info. This is usually the length of the data, but can be several
+ other things. Encoding and decoding of this is taken care of by the
+ implementation.
+ 
+ CBOR has two mechanisms for tagging and labeling the data
+ values like integers and strings. For example, an integer that
+ represents someone's birthday in epoch seconds since Jan 1, 1970
+ could be encoded like this:
+ 
+ - First it is CBOR_MAJOR_TYPE_POSITIVE_INT, the primitive positive
+ integer.
+ - Next it has a "tag" CBOR_TAG_DATE_EPOCH indicating the integer
+ represents a date in the form of the number of seconds since
+ Jan 1, 1970.
+ - Last it has a string "label" like "BirthDate" indicating
+ the meaning of the data.
+ 
+ The encoded binary looks like this:
+   a1                      # Map of 1 item
+      69                   # Indicates text string of 9 bytes
+        426972746844617465 # The text "BirthDate"
+     c1                    # Tags next int as epoch date
+        1a                 # Indicates 4 byte integer
+            580d4172       # unsigned integer date 1477263730
+ 
+ Implementors using this API will primarily work with labels. Generally
+ tags are only needed for making up new data types. This implementation
+ covers most of the data types defined in the RFC using tags. It also,
+ allows for the creation of news tags if necessary.
+ 
+ This implementation explicitly supports labels that are text strings
+ and integers. Text strings translate nicely into JSON objects and
+ are very readable.  Integer labels are much less readable, but
+ can be very compact. If they are in the range of -23 to
+ 23 they take up only one byte.
+ 
+ CBOR allows a label to be any type of data including an array or 
+ a map. It is possible to use this API to construct and
+ parse such labels, but it is not explicitly supported.
+ 
+ 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
+ encoder is invoked again, this time with the output buffer.
+ 
+ The double invocation is not required if the max output buffer size
+ can be predicted. This is usually possible for simple CBOR structures.
+ If the double invocation is implemented, it can be
+ in a loop or function as in the example code so that the code doesn't
+ have to actually be written twice, saving code size.
+ 
+ If a buffer too small to hold the encoded output is given, the error
+ QCBOR_ERR_BUFFER_TOO_SMALL will be returned. Data will never be
+ written off the end of the output buffer no matter which functions
+ here are called or what parameters are passed to them.
+ 
+ The error handling is simple. The only possible errors are trying to
+ encode structures that are too large or too complex. There are no
+ internal malloc calls so there will be no failures for out of memory.
+ Only the final call, QCBOREncode_Finish(), returns an error code.
+ Once an error happens, the encoder goes into an error state and calls
+ to it will do nothing so the encoding can just go on. An error
+ check is not needed after every data item is added.
+ 
+ Encoding generally proceeds by calling QCBOREncode_Init(), calling
+ lots of "Add" functions and calling QCBOREncode_Finish(). There
+ are many "Add" functions for various data types. The input
+ buffers need only to be valid during the "Add" calls. The 
+ data is copied into the output buf during the "Add" call.
+ 
+ There are three `Add` functions for each data type. The first
+ / main one for the type is for adding the data item to an array.
+ The second one's name ends in `ToMap`, is used for adding
+ data items to maps and takes a string
+ argument that is its label in the map. The third one ends in
+ `ToMapN`, is also used for adding data items to maps, and
+ takes an integer argument that is its label in the map.
+ 
+ The simplest aggregate type is an array, which is a simple ordered
+ set of items without labels the same as JSON arrays. Call 
+ QCBOREncode_OpenArray() to open a new array, then "Add" to
+ put items in the array and then QCBOREncode_CloseArray(). Nesting
+ to a limit is allowed.  All opens must be matched by closes or an
+ encoding error will be returned.
+ 
+ The other aggregate type is a map which does use labels. The
+ `Add` functions that end in `ToMap` and `ToMapN` are convenient
+ ways to add labeled data items to a map. You can also call
+ any type of `Add` function once to add a label of any time and
+ then call any type of `Add` again to add its value.
+ 
+ Note that when you nest arrays or maps in a map, the nested
+ array or map has a label.
+
+ Usually it is not necessary to add tags explicitly as most
+ tagged types have functions here, but they can be added by
+ calling QCBOREncode_AddTag().  There is an IANA registry for new tags that are
+ for broad use and standardization as per RFC 7049. It is also 
+ allowed for protocols to make up new tags in the range above 256.
+ Note that even arrays and maps can be tagged.
+ 
+ Summary Limits of this implementation:
+ - The entire encoded CBOR must fit into contiguous memory.
+ - Max size of encoded / decoded CBOR data is UINT32_MAX (4GB).
+ - Max array / map nesting level when encoding / decoding is
+   QCBOR_MAX_ARRAY_NESTING (this is typically 15).
+ - Max items in an array or map when encoding / decoding is
+   QCBOR_MAX_ITEMS_IN_ARRAY (typically 65,536).
+ - Does not support encoding indefinite lengths (decoding is supported).
+ - Does not directly support some tagged types: decimal fractions, big floats
+ - Does not directly support labels in maps other than text strings and ints.
+ - Does not directly support int labels greater than INT64_MAX
+ - Epoch dates limited to INT64_MAX (+/- 292 billion years)
+ - Tags on labels are ignored during decoding
+ 
+ This implementation is intended to run on 32 and 64-bit CPUs. It
+ will probably work on 16-bit CPUs but less efficiently.
+ 
+ The public interface uses size_t for all lengths. Internally the
+ implementation uses 32-bit lengths by design to use less memory and
+ fit structures on the stack. This limits the encoded
+ CBOR it can work with to size UINT32_MAX (4GB) which should be
+ enough.
+ 
+ This implementation assumes two's compliment integer
+ machines. Stdint.h also requires this. It of course would be easy to
+ fix this implementation for another integer representation, but all
+ modern machines seem to be two's compliment.
+ 
+ */
+
+
+/**
+ The maximum number of items in a single array or map when encoding of decoding.
+*/
+#define QCBOR_MAX_ITEMS_IN_ARRAY (UINT16_MAX) // This value is 65,535 a lot of items for an array
+
+/** 
+ The maximum nesting of arrays and maps when encoding or decoding. The
+ error QCBOR_ERR_ARRAY_NESTING_TOO_DEEP will be returned on encoding
+ of decoding if it is exceeded
+*/
+#define QCBOR_MAX_ARRAY_NESTING  QCBOR_MAX_ARRAY_NESTING1
+
+/**
+ The maximum number of tags that can be in QCBORTagListIn and passed to
+ QCBORDecode_SetCallerConfiguredTagList()
+ */
+#define QCBOR_MAX_CUSTOM_TAGS    16
+
+
+typedef enum {
+   /** The encode or decode completely correctly. */
+   QCBOR_SUCCESS = 0,
+
+   /** The buffer provided for the encoded output when doing encoding was
+       too small and the encoded output will not fit. Also, when the buffer
+       given to QCBORDecode_SetMemPool() is too small. */
+   QCBOR_ERR_BUFFER_TOO_SMALL,
+
+   /** During encoding or decoding, the array or map nesting was deeper than
+    this implementation can handle. Note that in the interest of code size
+    and memory use, this implementation has a hard limit on array nesting. The
+    limit is defined as the constant QCBOR_MAX_ARRAY_NESTING. */
+   QCBOR_ERR_ARRAY_NESTING_TOO_DEEP,
+
+   /** During decoding or encoding, the array or map had too many items in it.
+       This limit QCBOR_MAX_ITEMS_IN_ARRAY, typically 65,535. */
+   QCBOR_ERR_ARRAY_TOO_LONG,
+
+   /** During encoding, more arrays or maps were closed than opened. This is a
+       coding error on the part of the caller of the encoder. */
+   QCBOR_ERR_TOO_MANY_CLOSES,
+
+   /** During decoding, some CBOR construct was encountered that this decoder
+        doesn't support, primarily this is the reserved additional info values,
+        28 through 30. */
+   QCBOR_ERR_UNSUPPORTED,
+
+   /** During decoding, hit the end of the given data to decode. For example,
+       a byte string of 100 bytes was expected, but the end of the input was
+       hit before finding those 100 bytes.  Corrupted CBOR input will often
+       result in this error. */
+   QCBOR_ERR_HIT_END,
+
+   /** During encoding, the length of the input buffer was too large. This might
+       happen on a 64-bit machine when a buffer larger than UINT32_MAX is passed.
+     */
+   QCBOR_ERR_BUFFER_TOO_LARGE,
+
+   /** During decoding, an integer smaller than INT64_MIN was received (CBOR
+       can represent integers smaller than INT64_MIN, but C cannot). */
+   QCBOR_ERR_INT_OVERFLOW,
+
+   /** During decoding, the label for a map entry is bad. What causes this
+       error depends on the decoding mode. */
+   QCBOR_ERR_MAP_LABEL_TYPE,
+
+   /** During encoding or decoding, the number of array or map opens was not
+       matched by the number of closes. */
+   QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN,
+
+   /** During encoding, the simple value is not between CBOR_SIMPLEV_FALSE
+       and CBOR_SIMPLEV_UNDEF. */
+   QCBOR_ERR_BAD_SIMPLE,
+
+   /** During decoding, a date greater than +- 292 billion years from Jan 1
+       1970 encountered during parsing. */
+   QCBOR_ERR_DATE_OVERFLOW,
+
+   /** During decoding, the CBOR is not valid, primarily a simple type is encoded in
+      a prohibited way. */
+   QCBOR_ERR_INVALID_CBOR,
+
+   /** Optional tagging that doesn't make sense (an int is tagged as a
+       date string) or can't be handled. */
+   QCBOR_ERR_BAD_OPT_TAG,
+
+   /** Returned by QCBORDecode_Finish() if all the inputs bytes have not
+       been consumed. */
+   QCBOR_ERR_EXTRA_BYTES,
+
+   /** During encoding, QCBOREncode_Close() call with a different type than
+       is currently open. */
+   QCBOR_ERR_CLOSE_MISMATCH,
+
+   /** Unable to decode an indefinite length string because no string
+       allocator was configured. */
+   QCBOR_ERR_NO_STRING_ALLOCATOR,
+
+   /** One of the chunks in an indefinite length string is not of the type of
+       the string. */
+   QCBOR_ERR_INDEFINITE_STRING_CHUNK,
+
+   /** Error allocating space for a string, usually for an indefinite length
+       string. */
+   QCBOR_ERR_STRING_ALLOCATE,
+
+   /** During decoding, a break occurred outside an indefinite length item. */
+   QCBOR_ERR_BAD_BREAK,
+
+   /** During decoding, too many tags in the caller-configured tag list, or not
+       enough space in QCBORTagListOut. */
+   QCBOR_ERR_TOO_MANY_TAGS
+   
+} QCBORError;
+
+
+typedef enum {
+   /** See QCBORDecode_Init() */
+   QCBOR_DECODE_MODE_NORMAL = 0,
+   /** See QCBORDecode_Init() */
+   QCBOR_DECODE_MODE_MAP_STRINGS_ONLY = 1,
+   /** See QCBORDecode_Init() */
+   QCBOR_DECODE_MODE_MAP_AS_ARRAY = 2
+} QCBORDecodeMode;
+
+
+
+
+
+/* Do not renumber these. Code depends on some of these values. */
+/** The type is unknown, unset or invalid */
+#define QCBOR_TYPE_NONE           0
+/** Type for an integer that decoded either between INT64_MIN and INT32_MIN or INT32_MAX and INT64_MAX; val.int64 */
+#define QCBOR_TYPE_INT64          2
+/** Type for an integer that decoded to a more than INT64_MAX and UINT64_MAX; val.uint64 */
+#define QCBOR_TYPE_UINT64         3
+/** Type for an array. The number of items in the array is in val.uCount. */
+#define QCBOR_TYPE_ARRAY          4
+/** Type for a map; number of items in map is in val.uCount */
+#define QCBOR_TYPE_MAP            5
+/** Type for a buffer full of bytes. Data is in val.string. */
+#define QCBOR_TYPE_BYTE_STRING    6
+/** Type for a UTF-8 string. It is not NULL terminated. Data is in val.string.  */
+#define QCBOR_TYPE_TEXT_STRING    7
+/** Type for a positive big number. Data is in val.bignum, a pointer and a length. */
+#define QCBOR_TYPE_POSBIGNUM     9
+/** Type for a negative big number. Data is in val.bignum, a pointer and a length. */
+#define QCBOR_TYPE_NEGBIGNUM     10
+/** Type for RFC 3339 date string, possibly with time zone. Data is in val.dateString */
+#define QCBOR_TYPE_DATE_STRING   11
+/** Type for integer seconds since Jan 1970 + floating point fraction. Data is in val.epochDate */
+#define QCBOR_TYPE_DATE_EPOCH    12
+/** A simple type that this CBOR implementation doesn't know about; Type is in val.uSimple. */
+#define QCBOR_TYPE_UKNOWN_SIMPLE 13
+/** Type for the simple value false; nothing more; nothing in val union. */
+#define QCBOR_TYPE_FALSE         20
+/** Type for the simple value true; nothing more; nothing in val union. */
+#define QCBOR_TYPE_TRUE          21
+/** Type for the simple value null; nothing more; nothing in val union. */
+#define QCBOR_TYPE_NULL          22
+/** Type for the simple value undef; nothing more; nothing in val union. */
+#define QCBOR_TYPE_UNDEF         23
+/** Type for a floating point number. Data is in val.float. */
+#define QCBOR_TYPE_FLOAT         26
+/** Type for a double floating point number. Data is in val.double. */
+#define QCBOR_TYPE_DOUBLE        27
+/** For QCBOR_DECODE_MODE_MAP_AS_ARRAY decode mode, a map that is being traversed as an array. See QCBORDecode_Init() */
+#define QCBOR_TYPE_MAP_AS_ARRAY  32
+
+#define QCBOR_TYPE_BREAK         31 // Used internally; never returned
+
+#define QCBOR_TYPE_OPTTAG       254 // Used internally; never returned
+
+
+
+/*
+ Approx Size of this:
+   8 + 8 + 1 + 1 + 1 + (1 padding) + (4 padding on 64-bit machine) = 24 for first part (20 on a 32-bit machine)
+   16 bytes for the val union
+   16 bytes for label union
+   total = 56 bytes (52 bytes on 32-bit machine)
+ */
+
+/**
+ QCBORItem holds the type, value and other info for a decoded item returned by GetNextItem().
+ */
+typedef struct _QCBORItem {
+   uint8_t  uDataType;     /** Tells what element of the val union to use. One of QCBOR_TYPE_XXXX */
+   uint8_t  uNestingLevel; /** How deep the nesting from arrays and maps are. 0 is the top level with no arrays or maps entered */
+   uint8_t  uLabelType;    /** Tells what element of the label union to use */
+   uint8_t  uDataAlloc;    /** 1 if allocated with string allocator, 0 if not. See QCBORDecode_MakeMallocStringAllocator() */
+   uint8_t  uLabelAlloc;   /** Like uDataAlloc, but for label */
+   uint8_t  uNextNestLevel; /** If not equal to uNestingLevel, this item closed out at least one map/array */
+   
+   union {
+      int64_t     int64;      /** The value for uDataType QCBOR_TYPE_INT64 */
+      uint64_t    uint64;     /** The value for uDataType QCBOR_TYPE_UINT64 */
+
+      UsefulBufC  string;     /** The value for uDataType QCBOR_TYPE_BYTE_STRING and QCBOR_TYPE_TEXT_STRING */
+      uint16_t    uCount;     /** The "value" for uDataType QCBOR_TYPE_ARRAY or QCBOR_TYPE_MAP -- the number of items in the array or map
+                                  UINT16_MAX when decoding indefinite lengths maps and arrays. */
+      double      dfnum;      /** The value for uDataType QCBOR_TYPE_DOUBLE */
+      struct {
+         int64_t  nSeconds;
+         double   fSecondsFraction;
+      } epochDate;            /** The value for uDataType QCBOR_TYPE_DATE_EPOCH */
+      UsefulBufC  dateString; /** The value for uDataType QCBOR_TYPE_DATE_STRING */
+      UsefulBufC  bigNum;     /** The value for uDataType QCBOR_TYPE_BIGNUM */
+      uint8_t     uSimple;    /** The integer value for unknown simple types */
+      uint64_t    uTagV;
+      
+   } val;  /** The union holding the item's value. Select union member based on uDataType */
+   
+   union {
+      UsefulBufC  string;  /** The label for uLabelType QCBOR_TYPE_BYTE_STRING and QCBOR_TYPE_TEXT_STRING */
+      int64_t     int64;   /** The label for uLabelType for QCBOR_TYPE_INT64 */
+      uint64_t    uint64;  /** The label for uLabelType for QCBOR_TYPE_UINT64 */
+   } label; /** Union holding the different label types selected based on uLabelType */
+   
+   uint64_t uTagBits; /** Bit indicating which tags (major type 6) on this item.  */
+   
+} QCBORItem;
+
+
+/**
+ This is a set of functions and pointer context (in object-oriented parlance,
+ an "object") used to allocate memory for coalescing the segments of an indefinite
+ length string into one.
+ 
+ The fAllocate function works as an initial allocator and a reallocator to
+ expand the string for each new segment. When it is an initial allocator
+ pOldMem is NULL.
+ 
+ The fFree function is called to clean up an individual allocation when an error occurs.
+ 
+ The fDesctructor function is called when QCBORDecode_Finish is called.
+ 
+ Any memory allocated with this will be marked by setting uDataAlloc
+ or uLabelAlloc in the QCBORItem structure so the caller knows they
+ have to free it.
+ 
+ fAllocate is only ever called to increase the single most recent
+ allocation made, making implementation of a memory pool very simple.
+ 
+ fFree is also only called on the single most recent allocation.
+ */
+typedef struct {
+   void       *pAllocaterContext;
+   UsefulBuf (*fAllocate)(void *pAllocaterContext, void *pOldMem, size_t uNewSize);
+   void      (*fFree)(void *pAllocaterContext, void *pMem);
+   void      (*fDestructor)(void *pAllocaterContext);
+} QCBORStringAllocator;
+
+
+
+/**
+ This is used to tell the decoder about tags that it should
+ record in uTagBits in QCBORItem beyond the built-in
+ tags. puTags points to an
+ array of uint64_t integers that are the tags. uNumTags
+ is the number of integers in the array. The maximum
+ size is QCBOR_MAX_CUSTOM_TAGS.  See QCBORDecode_IsTagged()
+ and QCBORDecode_SetCallerAddedTagMap().
+ */
+typedef struct {
+   uint8_t uNumTags;
+   const uint64_t *puTags;
+} QCBORTagListIn;
+
+
+/**
+ This is for QCBORDecode_GetNextWithTags() to be able to return the
+ full list of tags on an item. It not needed for most CBOR protocol
+ implementations. Its primary use is for pretty-printing CBOR or
+ protocol conversion to another format.
+ 
+ On input, puTags points to a buffer to be filled in
+ and uNumAllocated is the number of uint64_t values
+ in the buffer.
+ 
+ On output the buffer contains the tags for the item.
+ uNumUsed tells how many there are.
+ */
+typedef struct {
+   uint8_t uNumUsed;
+   uint8_t uNumAllocated;
+   uint64_t *puTags;
+} QCBORTagListOut;
+
+
+/**
+ QCBOREncodeContext is the data type that holds context for all the
+ encoding functions. It is less than 200 bytes, so it can go on
+ the stack. The contents are opaque, and the caller should not access
+ any internal items.  A context may be re used serially as long as
+ it is re initialized.
+ */
+typedef struct _QCBOREncodeContext QCBOREncodeContext;
+
+
+/**
+ Initialize the the encoder to prepare to encode some CBOR.
+ 
+ @param[in,out]  pCtx    The encoder context to initialize.
+ @param[in]      Storage The buffer into which this encoded result will be placed.
+ 
+ Call this once at the start of an encoding of a CBOR structure. Then
+ call the various QCBOREncode_AddXXX() functions to add the data
+ items. Then call QCBOREncode_Finish().
+ 
+ The maximum output buffer is UINT32_MAX (4GB). This is not a practical
+ limit in any way and reduces the memory needed by the implementation.
+ The error QCBOR_ERR_BUFFER_TOO_LARGE will be returned by QCBOR_Finish()
+ if a larger buffer length is passed in.
+  
+ If this is called with pBuf as NULL and uBufLen a large value like
+ UINT32_MAX, all the QCBOREncode_AddXXXX() functions and
+ QCBORE_Encode_Finish() can still be called. No data will be encoded,
+ but the length of what would be encoded will be calculated. The
+ length of the encoded structure will be handed back in the call to
+ QCBOREncode_Finish(). You can then allocate a buffer of that size
+ and call all the encoding again, this time to fill in the buffer.
+ 
+ A QCBORContext can be reused over and over as long as
+ QCBOREncode_Init() is called.
+ */
+void QCBOREncode_Init(QCBOREncodeContext *pCtx, UsefulBuf Storage);
+
+
+/**
+ @brief  Add a signed 64-bit integer to the encoded output.
+ 
+ @param[in] pCtx      The encoding context to add the integer to.
+ @param[in] nNum      The integer to add.
+ 
+ The integer will be encoded and added to the CBOR output.
+ 
+ This function figures out the size and the sign and encodes in the
+ correct minimal CBOR. Specifically, it will select CBOR major type 0 or 1
+ based on sign and will encode to 1, 2, 4 or 8 bytes depending on the
+ value of the integer. Values less than 24 effectively encode to one
+ byte because they are encoded in with the CBOR major type.  This is
+ a neat and efficient characteristic of CBOR that can be taken
+ advantage of when designing CBOR-based protocols. If integers like
+ tags 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 int16_t or a small value, say 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 7049
+ Appendix A for more examples of CBOR encoding. This compact encoding
+ is also canonical CBOR as per section 3.9 in RFC 7049.
+ 
+ There are no functions to add int16_t or 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).
+ 
+ If the encoding context is in an error state, this will do
+ nothing. If an error occurs when adding this integer, the internal
+ error flag will be set, and the error will be returned when
+ QCBOREncode_Finish() is called.
+ 
+ See also QCBOREncode_AddUInt64().
+ */
+void QCBOREncode_AddInt64(QCBOREncodeContext *pCtx, int64_t nNum);
+
+static void QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum);
+
+static void QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum);
+
+
+/**
+ @brief  Add an unsigned 64-bit integer to the encoded output.
+ 
+ @param[in] pCtx      The encoding context to add the integer to.
+ @param[in] uNum      The integer to add.
+ 
+ The integer will be encoded and added to the CBOR output.
+ 
+ The only reason so use this function is for integers larger than
+ INT64_MAX and smaller than UINT64_MAX. Otherwise QCBOREncode_AddInt64()
+ will work fine.
+ 
+ Error handling is the same as for QCBOREncode_AddInt64().
+ */
+void QCBOREncode_AddUInt64(QCBOREncodeContext *pCtx, uint64_t uNum);
+
+static void QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum);
+
+static void QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum);
+
+
+/**
+ 
+ @brief  Add a UTF-8 text string to the encoded output
+ 
+ @param[in] pCtx     The context to initialize.
+ @param[in] Text    Pointer and length of text to add.
+ 
+ The text passed in must be unencoded UTF-8 according to RFC
+ 3629. There is no NULL termination. The text is added as CBOR
+ major type 3.
+ 
+ If called with nBytesLen equal to 0, an empty string will be
+ added. When nBytesLen is 0, pBytes may be NULL.
+ 
+ Note that the restriction of the buffer length to an uint32_t is
+ entirely intentional as this encoder is not capable of encoding
+ lengths greater. This limit to 4GB for a text string should not be a
+ problem.
+ 
+ Error handling is the same as QCBOREncode_AddInt64().
+ */
+static void QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text);
+
+static void QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text);
+
+static void QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text);
+
+
+/**
+ @brief  Add a UTF-8 text string to the encoded output
+ 
+ @param[in] pCtx      The context to initialize.
+ @param[in] szString  Null-terminated text to add.
+ 
+ This works the same as QCBOREncode_AddText().
+ */
+static void QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString);
+
+static void QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString);
+
+static void QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString);
+
+
+/**
+ @brief  Add a floating-point number to the encoded output
+ 
+ @param[in] pCtx      The encoding context to add the float to.
+ @param[in] dNum      The double precision number to add.
+ 
+ This outputs a floating-point number with CBOR major type 7.
+ 
+ This will selectively encode the double-precision floating point number as either
+ double-precision, single-precision or half-precision. It will always encode infinity, NaN and 0
+ has 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.
+ 
+ Half-precision floating point numbers take up 2 bytes, half that of single-precision,
+ one quarter of double-precision
+ 
+ This automatically reduces the size of encoded messages a lot, maybe even by four if most of values are
+ 0, infinity or NaN.
+ 
+ On decode, these will always be returned as a double.
+ 
+ Error handling is the same as QCBOREncode_AddInt64().
+ */
+void QCBOREncode_AddDouble(QCBOREncodeContext *pCtx, double dNum);
+
+static void QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum);
+
+static void QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum);
+
+
+/**
+ @brief[in] Add an optional tag
+ 
+ @param[in] pCtx  The encoding context to add the integer to.
+ @param[in] uTag  The tag to add
+ 
+ This outputs a CBOR major type 6 optional tag.
+ 
+ The tag is applied to the next data item added to the encoded
+ output. That data item that is to be tagged can be of any major
+ CBOR type. Any number of tags can be added to a data item by calling
+ this multiple times before the data item is added.
+ 
+ For many of the common standard tags a function to encode
+ data using it already exists and this is not needed. For example,
+ QCBOREncode_AddDateEpoch() already exists to output
+ integers representing dates with the right tag.
+*/
+void QCBOREncode_AddTag(QCBOREncodeContext *pCtx,uint64_t uTag);
+
+
+/**
+ @brief  Add an epoch-based date
+ 
+ @param[in] pCtx     The encoding context to add the simple value to.
+ @param[in] date     Number of seconds since 1970-01-01T00:00Z in UTC time.
+ 
+ As per RFC 7049 this is similar to UNIX/Linux/POSIX dates. This is
+ the most compact way to specify a date and time in CBOR. Note that this
+ is always UTC and does not include the time zone.  Use
+ QCBOREncode_AddDateString() if you want to include the time zone.
+ 
+ The integer encoding rules apply here so the date will be encoded in a
+ minimal number of 1, 2 4 or 8 bytes. Until about the year 2106 these
+ dates should encode in 6 bytes -- one byte for the tag, one byte for the type
+ and 4 bytes for the integer.
+ 
+ If you care about leap-seconds and that level of accuracy, make sure the
+ system you are running this code on does it correctly. This code just takes
+ the value passed in.
+ 
+ This implementation cannot encode fractional seconds using float or double
+ even though that is allowed by CBOR, but you can encode them if you
+ want to by calling QCBOREncode_AddDouble()
+ with the right parameters.
+ 
+ Error handling is the same as QCBOREncode_AddInt64().
+ */
+static void QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx, int64_t date);
+
+static void QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t date);
+
+static  void QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t date);
+
+
+/**
+ @brief Add a byte string to the encoded output.
+ 
+ @param[in] pCtx      The context to initialize.
+ @param[in] Bytes     Pointer and length of the input data.
+ 
+ Simply adds the bytes to the encoded output as CBOR major type 2.
+ 
+ If called with Bytes.len equal to 0, an empty string will be
+ added. When Bytes.len is 0, Bytes.ptr may be NULL.
+ 
+ Error handling is the same as QCBOREncode_AddInt64().
+ */
+static void QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
+
+static void QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
+
+static void QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
+
+
+
+/**
+ @brief Add a binary UUID to the encoded output.
+ 
+ @param[in] pCtx      The context to initialize.
+ @param[in] Bytes     Pointer and length of the binary UUID.
+ 
+ A binary UUID as defined in RFC 4122 is added to the ouput.
+ 
+ It is output as CBOR major type 2, a binary string, with
+ optional tag 36 indicating the binary string is a UUID.
+ */
+static void QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
+
+static void QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
+
+static void QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
+
+
+/**
+ @brief Add a positive big number to the encoded output.
+ 
+ @param[in] pCtx      The context to initialize.
+ @param[in] Bytes     Pointer and length of the big number.
+ 
+ Big numbers are integers larger than 64-bits. Their format
+ is described in RFC 7049.
+ 
+ It is output as CBOR major type 2, a binary string, with
+ optional tag 2 indicating the binary string is a positive big
+ number.
+ 
+ Often big numbers are used to represent cryptographic keys,
+ however, COSE which defines representations for keys chose not
+ to use this particular type.
+ */
+static void QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
+
+static void QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
+
+static void QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
+
+
+/**
+ @brief Add a negative big number to the encoded output.
+ 
+ @param[in] pCtx      The context to initialize.
+ @param[in] Bytes     Pointer and length of the big number.
+ 
+ Big numbers are integers larger than 64-bits. Their format
+ is described in RFC 7049.
+ 
+ It is output as CBOR major type 2, a binary string, with
+ optional tag 2 indicating the binary string is a negative big
+ number.
+ 
+ Often big numbers are used to represent cryptographic keys,
+ however, COSE which defines representations for keys chose not
+ to use this particular type.
+ */
+static void QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes);
+
+static void QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes);
+
+static void QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
+
+
+/**
+ @brief Add a text URI to the encoded output.
+ 
+ @param[in] pCtx    The context to initialize.
+ @param[in] URI     Pointer and length of the URI.
+ 
+ The format of URI is RFC 3986.
+ 
+ It is output as CBOR major type 3, a text string, with
+ optional tag 32 indicating the text string is a URI.
+ */
+static void QCBOREncode_AddURI(QCBOREncodeContext *pCtx, UsefulBufC URI);
+
+static void QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC URI);
+
+static void QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC URI);
+
+
+/**
+ @brief Add base 64-encoded text to encoded output.
+ 
+ @param[in] pCtx     The context to initialize.
+ @param[in] B64Text  Pointer and length of the base-64 encoded text.
+ 
+ The text content is base 64 encoded data per RFC 4648.
+ 
+ It is output as CBOR major type 3, a text string, with
+ optional tag 34 indicating the text string is a URI.
+ */
+static void QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx, UsefulBufC B64Text);
+
+static void QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text);
+
+static void QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text);
+
+
+/**
+ @brief Add base 64URL -encoded URL to encoded output.
+ 
+ @param[in] pCtx    The context to initialize.
+ @param[in] B64Text  Pointer and length of the base-64 encoded text.
+ 
+ The text content is base 64 URL format encoded text as per RFC 4648.
+ 
+ It is output as CBOR major type 3, a text string, with
+ optional tag 33 indicating the text string is a URI.
+ */
+static void QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx, UsefulBufC B64Text);
+
+static void QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text);
+
+static void QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text);
+
+
+/**
+ @brief Add Perl Compatible Regular Expression
+ 
+ @param[in] pCtx    The context to initialize.
+ @param[in] Regex   Pointer and length of the regular expression.
+ 
+ The text content is Perl Compatible Regular
+ Expressions (PCRE) / JavaScript syntax [ECMA262].
+ 
+ It is output as CBOR major type 3, a text string, with
+ optional tag 35 indicating the text string is a regular expression.
+ */
+static void QCBOREncode_AddRegex(QCBOREncodeContext *pCtx, UsefulBufC Regex);
+
+static void QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Regex);
+
+static void QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Regex);
+
+
+/**
+ @brief MIME encoded text to the encoded output.
+ 
+ @param[in] pCtx      The context to initialize.
+ @param[in] MIMEData  Pointer and length of the regular expression.
+ 
+ The text content is in MIME format per RFC 2045 including the headers.
+ 
+ It is output as CBOR major type 3, a text string, with
+ optional tag 36 indicating the text string is MIME data.
+ */
+static void QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx, UsefulBufC MIMEData);
+
+static void QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC MIMEData);
+
+static void QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC MIMEData);
+
+
+/**
+ @brief  Add an RFC 3339 date string
+ 
+ @param[in] pCtx      The encoding context to add the simple value to.
+ @param[in] szDate    Null-terminated string with date to add
+
+ The string szDate should be in the form of RFC 3339 as defined by section
+ 3.3 in RFC 4287. This is as described in section 2.4.1 in RFC 7049.
+ 
+ Note that this function doesn't validate the format of the date string
+ at all. If you add an incorrect format date string, the generated
+ CBOR will be incorrect and the receiver may not be able to handle it.
+ 
+ Error handling is the same as QCBOREncode_AddInt64().
+ */
+static void QCBOREncode_AddDateString(QCBOREncodeContext *pCtx, const char *szDate);
+
+static void QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szDate);
+
+static void QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szDate);
+
+
+/**
+ @brief  Add a standard boolean.
+ 
+ @param[in] pCtx   The encoding context to add the simple value to.
+ @param[in] b      true or false from stdbool. Anything will result in an error.
+ 
+ Adds a boolean value as CBOR major type 7.
+ 
+ Error handling is the same as QCBOREncode_AddInt64().
+ */
+static void QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b);
+
+static void QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b);
+
+static void QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b);
+
+
+
+/**
+ @brief  Add a NULL to the encoded output.
+ 
+ @param[in] pCtx   The encoding context to add the simple value to.
+ 
+ Adds the NULL value as CBOR major type 7.
+ 
+ This NULL 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().
+ */
+static void QCBOREncode_AddNULL(QCBOREncodeContext *pCtx);
+
+static void QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel);
+
+static void QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
+
+
+/**
+ @brief  Add an "undef" to the encoded output.
+ 
+ @param[in] pCtx   The encoding context to add the simple value to.
+ 
+ Adds the undef value as CBOR major type 7.
+ 
+ Note that this value will not translate to JSON.
+ 
+ This 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().
+ */
+static void QCBOREncode_AddUndef(QCBOREncodeContext *pCtx);
+
+static void QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel);
+
+static void QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
+
+
+/**
+ @brief  Indicates that the next items added are in an array.
+ 
+ @param[in] pCtx The encoding context to open the array in.
+ 
+ Arrays are the basic CBOR aggregate or structure type. Call this
+ function to start or open an array. Then call the various AddXXX
+ functions to add the items that go into the array. Then call
+ QCBOREncode_CloseArray() when all items have been added. The
+ data items in the array can be of any type and can be of
+ mixed types.
+ 
+ Nesting of arrays and maps is allowed and supported just by calling
+ OpenArray again before calling CloseArray.  While CBOR has no limit
+ on nesting, this implementation does in order to keep it smaller and
+ simpler.  The limit is QCBOR_MAX_ARRAY_NESTING. This is the max
+ number of times this can be called without calling
+ QCBOREncode_CloseArray(). QCBOREncode_Finish() will return
+ QCBOR_ERR_ARRAY_TOO_LONG when it is called as this function just sets
+ an error state and returns no value when this occurs.
+ 
+ If you try to add more than 32,767 items to an array or map, incorrect CBOR will
+ be produced by this encoder.
+ 
+ An array itself must have a label if it is being added to a map.  Note that
+ array elements do not have labels (but map elements do).
+ 
+ An array itself may be tagged.
+ */
+static void QCBOREncode_OpenArray(QCBOREncodeContext *pCtx);
+
+static void QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel);
+
+static void QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx,  int64_t nLabel);
+
+
+/**
+ @brief Close an open array.
+ 
+ @param[in] pCtx The context to add to.
+ 
+ The closes an array opened by QCBOREncode_OpenArray(). It reduces
+ nesting level by one. All arrays (and maps) must be closed
+ before calling QCBOREncode_Finish().
+ 
+ When an error occurs as a result of this call, the encoder records
+ the error and enters the error state. The error will be returned when
+ QCBOREncode_Finish() is called.
+ 
+ If this has been called more times than QCBOREncode_OpenArray(),
+ then QCBOR_ERR_TOO_MANY_CLOSES will be returned when
+ QCBOREncode_Finish() is called.
+ 
+ If this is called and it is not an array that is currently
+ open, QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
+ is called.
+ */
+static void QCBOREncode_CloseArray(QCBOREncodeContext *pCtx);
+
+
+/**
+ @brief  Indicates that the next items added are in a map.
+ 
+ @param[in] pCtx The context to add to.
+ 
+ See QCBOREncode_OpenArray() for more information.
+ 
+ CBOR maps are an aggregate type where each item in the map consists
+ of a label and a value. They are similar to JSON objects.
+ 
+ The value can be any CBOR type including another map.
+ 
+ The label can also be any CBOR type, but in practice they are
+ typically, integers as this gives the most compact output. They
+ might also be text strings which gives readability and translation
+ to JSON.
+ 
+ Every QCBOREncode_AddXXX() call has once version that is "InMap" for
+ adding items to maps with string labels and on that is "InMapN" that
+ is for adding with integer labels.
+ 
+ RFC 7049 uses the term "key" instead of "label".
+ 
+ If you wish to use map labels that are neither integer labels or
+ text strings, then just call the QCBOREncode_AddXXX() function
+ explicitly to add the label. Then call it again to add the value.
+ 
+ See the RFC7049 for a lot more information on creating maps.
+ */
+static void QCBOREncode_OpenMap(QCBOREncodeContext *pCtx);
+
+static void QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
+
+static void QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
+
+
+
+/**
+ @brief Close an open map.
+ 
+ @param[in] pCtx The context to add to.
+ 
+ The closes a map opened by QCBOREncode_OpenMap(). It reduces
+ nesting level by one.
+ 
+ When an error occurs as a result of this call, the encoder records
+ the error and enters the error state. The error will be returned when
+ QCBOREncode_Finish() is called.
+ 
+ If this has been called more times than QCBOREncode_OpenMap(),
+ then QCBOR_ERR_TOO_MANY_CLOSES will be returned when
+ QCBOREncode_Finish() is called.
+ 
+ If this is called and it is not a map that is currently
+ open, QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
+ is called.
+ */
+static void QCBOREncode_CloseMap(QCBOREncodeContext *pCtx);
+
+
+/**
+ @brief Indicate start of encoded CBOR to be wrapped in a bstr.
+ 
+ @param[in] pCtx The context to add to.
+ 
+ All added encoded items between this call and a call to
+ QCBOREncode_CloseBstrWrap() will be wrapped in a bstr. They will
+ appear in the final output as a byte string.  That byte string will
+ contain encoded CBOR.
+ 
+ The typical use case is for encoded CBOR that is to be
+ cryptographically hashed, as part of a COSE (RFC 8152)
+ implementation. This avoids having to encode the items first in one
+ buffer (e.g., the COSE payload) and then add that buffer as a bstr to
+ another encoding (e.g. the COSE to-be-signed bytes, the
+ Sig_structure) potentially saving a lot of memory.
+ 
+ When constructing cryptographically signed CBOR objects, maps or arrays, they
+ typically are encoded
+ normally and then wrapped as a byte string. The COSE standard for example
+ does this. The wrapping is simply treating the encoded CBOR map
+ as a byte string.
+ 
+ The stated purpose of this wrapping is to prevent code relaying the signed data
+ but not verifying it from tampering with the signed data thus making
+ the signature unverifiable. It is also quite beneficial for the
+ signature verification code. Standard CBOR parsers usually do not give
+ access to partially parsed CBOR as would be need to check the signature
+ of some CBOR. With this wrapping, standard CBOR parsers can be used
+ to get to all the data needed for a signature verification.
+ */
+static void QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx);
+
+static void QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel);
+
+static void QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel);
+
+
+/**
+ @brief Close a wrapping bstr.
+ 
+ @param[in] pCtx The context to add to.
+ @param[out] pWrappedCBOR UsefulBufC containing wrapped bytes
+ 
+ The closes a wrapping bstr opened by QCBOREncode_BstrWrap(). It reduces
+ nesting level by one.
+ 
+ A pointer and length of the enclosed encoded CBOR is returned in
+ *pWrappedCBOR if it is not NULL. The main purpose of this is so this
+ data can be hashed (e.g., with SHA-256) as part of a COSE (RFC 8152)
+ implementation. **WARNING**, this pointer and length should be used
+ right away before any other calls to QCBOREncode_xxxx() as they will
+ move data around and the pointer and length will no longer be to the
+ correct encoded CBOR.
+ 
+ When an error occurs as a result of this call, the encoder records
+ the error and enters the error state. The error will be returned when
+ QCBOREncode_Finish() is called.
+ 
+ If this has been called more times then QCBOREncode_BstrWrap(),
+ then QCBOR_ERR_TOO_MANY_CLOSES will be returned when
+ QCBOREncode_Finish() is called.
+ 
+ If this is called and it is not a wrapping bstr that is currently
+ open, QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish()
+ is called.
+ */
+static void QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR);
+
+
+/**
+ Add some already-encoded CBOR bytes.
+ 
+ @param[in] pCtx The context to add to.
+ @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
+ raw CBOR added here to have indefinite lengths.
+ 
+ The raw CBOR added here is not checked in anyway. If it is not
+ conforming or has open arrays or such, the final encoded CBOR
+ will probably be wrong or not what was intended.
+ 
+ If the encoded CBOR being added here contains multiple items, they
+ must be enclosed in a map or array. At the top level the raw
+ CBOR must be a single data item.
+ */
+static void QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded);
+
+static void QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded);
+
+static void QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded);
+
+
+/**
+ Get the encoded result.
+ 
+ @param[in] pCtx  The context to finish encoding with.
+ @param[out] pEncodedCBOR  Pointer and length of encoded CBOR.
+ 
+ @return
+ One of the CBOR error codes.
+ 
+ If this returns success QCBOR_SUCCESS the encoding was a success and
+ the return length is correct and complete.
+ 
+ If no buffer was passed to QCBOR_Init(), then only the length and
+ number of items was computed. The length is in
+ pEncodedCBOR->Bytes.len. pEncodedCBOR->Bytes.ptr is NULL.
+ 
+ If a buffer was passed, then pEncodedCBOR->Bytes.ptr is the same as
+ the buffer passed to QCBOR_Init() and contains the encoded CBOR
+ and the length is filled in.
+ 
+ If an error is returned, the buffer may have partially encoded
+ incorrect CBOR in it and it should not be used. Likewise, the length
+ may be incorrect and should not be used.
+ 
+ Note that the error could have occurred in one of the many
+ QCBOR_AddXXX calls long before QCBOREncode_Finish() was called. This
+ error handling approach reduces the CBOR implementation size, but makes
+ debugging a problem a little more difficult.
+ */
+QCBORError QCBOREncode_Finish(QCBOREncodeContext *pCtx, UsefulBufC *pEncodedCBOR);
+
+
+/**
+ Get the encoded CBOR and error status.
+ 
+ @param[in] pCtx  The context to finish encoding with.
+ @param[out] uEncodedLen The length of the encoded or potentially encoded CBOR in bytes.
+ 
+ @return
+ One of the CBOR error codes.
+ 
+ If this returns success QCBOR_SUCCESS the encoding was a success and
+ the return length is correct and complete.
+ 
+ If no buffer was passed to QCBOR_Init(), then only the length was
+ computed. If a buffer was passed, then the encoded CBOR is in the
+ buffer.
+ 
+ If an error is returned, the buffer may have partially encoded
+ incorrect CBOR in it and it should not be used. Likewise, the length
+ may be incorrect and should not be used.
+ 
+ Note that the error could have occurred in one of the many
+ QCBOR_AddXXX calls long before QCBOREncode_Finish() was called. This
+ error handling reduces the CBOR implementation size, but makes
+ debugging harder.
+ */
+QCBORError QCBOREncode_FinishGetSize(QCBOREncodeContext *pCtx, size_t *uEncodedLen);
+
+
+
+
+
+
+/**
+ QCBORDecodeContext is the data type that holds context decoding the
+ data items for some received CBOR.  It is about 100 bytes, so it can go
+ on the stack.  The contents are opaque, and the caller should not
+ access any internal items.  A context may be re used serially as long
+ as it is re initialized.
+ */
+typedef struct _QCBORDecodeContext QCBORDecodeContext;
+
+
+/**
+ Initialize the CBOR decoder context.
+ 
+ @param[in] pCtx The context to initialize.
+ @param[in] EncodedCBOR The buffer with CBOR encoded bytes to be decoded.
+ @param[in] nMode One of QCBOR_DECODE_MODE_xxx
+ 
+ Initialize context for a pre-order travesal of the encoded CBOR tree.
+ 
+ Most CBOR decoding can be completed by calling this function to start
+ and QCBORDecode_GetNext() in a loop.
+ 
+ If indefinite length strings are to be decoded, then
+ QCBORDecode_SetMemPool() or QCBORDecode_SetUpAllocator() must be
+ called to set up a string allocator.
+ 
+ If tags other than built-in tags are to be recognized, then
+ QCBORDecode_SetCallerAddedTagMap() must be called. The built-in tags
+ are those for which a macro of the form  CBOR_TAG_XXX is defined.
+ 
+ Three decoding modes are supported.  In normal mode,
+ QCBOR_DECODE_MODE_NORMAL, maps are decoded and strings and ints are
+ accepted as map labels. If a label is other than these, the error
+ QCBOR_ERR_MAP_LABEL_TYPE is returned by QCBORDecode_GetNext().
+ 
+ In strings-only mode, QCBOR_DECODE_MODE_MAP_STRINGS_ONLY, only text
+ strings are accepted for map labels.  This lines up with CBOR that
+ converts to JSON. The error QCBOR_ERR_MAP_LABEL_TYPE is returned by
+ QCBORDecode_GetNext() if anything but a text string label is
+ encountered.
+ 
+ In QCBOR_DECODE_MODE_MAP_AS_ARRAY maps are treated as special arrays.
+ They will be return with special uDataType QCBOR_TYPE_MAP_AS_ARRAY
+ and uCount, the number of items, will be double what it would be
+ for a normal map because the labels are also counted. This mode
+ is useful for decoding CBOR that has labels that are not
+ integers or text strings, but the caller must manage much of
+ the map decoding.
+ */
+void QCBORDecode_Init(QCBORDecodeContext *pCtx, UsefulBufC EncodedCBOR, QCBORDecodeMode nMode);
+
+
+/**
+ Set up the MemPool string allocator for indefinite length strings.
+ 
+ @param[in] pCtx The decode context.
+ @param[in] MemPool The pointer and length of the memory pool.
+ @param[in] bAllStrings true means to put even definite length strings in the pool.
+ 
+ @return 0 if the MemPool was at least minimum size, 1 if too small.
+ 
+ Indefinite length strings (text and byte) cannot be decoded unless there is
+ a string allocator configured. MemPool is a simple built-in string allocator
+ that allocates bytes from a memory pool handed to it by calling
+ this function.  The memory pool is just a pointer and length for some
+ block of memory that is to be used for string allocation. It can
+ come from the stack, heap or other.
+ 
+ The memory pool must be large enough to hold some fixed overhead plus the
+ space for all the strings allocated. The fixed overhead does vary
+ by CPU and compiler, but can roughly be computed as the space for
+ seven pointers, 56 bytes for a 64-bit CPU.  There is no overhead
+ per string allocated
+ 
+ This memory pool is used for all indefinite length strings that are text
+ strings or byte strings, including strings used as labels.
+ 
+ The pointers to strings in QCBORItem will point into the memory pool set
+ here. They do not need to be individually freed. Just discard the buffer
+ when they are no longer needed.
+ 
+ If bAllStrings is set, then the size will be the overhead plus the space to
+ hold **all** strings, definite and indefinite length, value or label. The
+ advantage of this is that after the decode is complete, the original memory
+ holding the encoded CBOR does not need to remain valid.
+ 
+ If this function is not called because there is no need to support indefinite
+ length strings, the MemPool implementation should be dead-stripped by the loader
+ and not add to code size.
+ */
+QCBORError QCBORDecode_SetMemPool(QCBORDecodeContext *pCtx, UsefulBuf MemPool, bool bAllStrings);
+
+
+/**
+ @brief Sets up a custom string allocator for indefinite length strings
+ 
+ @param[in] pCtx The decoder context to set up an allocator for
+ @param[in] pAllocator The string allocator "object"
+ 
+ See QCBORStringAllocator for the requirements of the string allocator.
+ 
+ Typically, this is used if the simple MemPool allocator isn't desired.
+ 
+ A malloc based string allocator can be obtained by calling
+ QCBORDecode_MakeMallocStringAllocator(). Pass its result to
+ this function.
+ 
+ You can also write your own allocator. Create the allocate, free,
+ and destroy functions and put pointers to them in a QCBORStringAllocator.
+ */
+void QCBORDecode_SetUpAllocator(QCBORDecodeContext *pCtx, const QCBORStringAllocator *pAllocator, bool bAllStrings);
+
+
+/**
+ @brief Configure list of caller selected tags to be recognized
+ 
+ @param[in] pCtx The decode context.
+ @param[out] pTagList Structure holding the list of tags to configure
+ 
+ This is used to tell the decoder about tags beyond those that are
+ built-in that should be recognized. The built-in tags are those
+ with macros of the form CBOR_TAG_XXX.
+ 
+ See description of QCBORTagListIn.
+ */
+void QCBORDecode_SetCallerConfiguredTagList(QCBORDecodeContext *pCtx, const QCBORTagListIn *pTagList);
+
+
+/**
+ @brief This returns a string allocator that uses malloc
+ 
+ @return pointer to string allocator or NULL
+ 
+ Call this to get the string allocator and then configure it into
+ the decoder by calling QCBORDecode_SetUpAllocator().  If you
+ don't call this, there will be no dependency on malloc
+ in QCBOR. Some deployments of QCBOR might even exclude
+ the implementation of this function if they don't have
+ malloc() at all.
+ 
+ If you do set up this malloc-based string allocator, then
+ every string marked as allocated in a QCBORItem must
+ freed. They are marked by uDataAlloc and uLabelAlloc
+ in QCBORItem.
+ */
+QCBORStringAllocator *QCBORDecode_MakeMallocStringAllocator(void);
+
+
+/**
+ @brief Gets the next item (integer, byte string, array...) in pre order traversal of CBOR tree
+ 
+ @param[in]  pCtx          The decoder context.
+ @param[out] pDecodedItem  Holds the CBOR item just decoded.
+ 
+ @return 0 or error. All errors except QCBOR_ERR_TOO_MANY_TAGS
+ and QCBOR_ERR_STRING_ALLOCATE indicate that the CBOR input
+ could not be decoded. In most cases
+ this is because the CBOR is invalid. In a few cases
+ (QCBOR_ERR_ARRAY_NESTING_TOO_DEEP, QCBOR_ERR_INT_OVERFLOW,
+ QCBOR_ERR_DATE_OVERFLOW) it is because the CBOR is beyond
+ the limits of what this implementation can handle.
+ QCBOR_ERR_NO_STRING_ALLOCATOR indicates CBOR that cannot
+ be handled unless a string allocator is configured.
+ QCBOR_ERR_MAP_LABEL_TYPE is in a way a limitation of
+ this implementation, but can be avoided by decoding
+ in QCBOR_DECODE_MODE_MAP_AS_ARRAY mode.
+ 
+ pDecodedItem is filled in with the value parsed. Generally, the
+ following data is returned in the structure.
+ 
+ - The data type in uDataType which indicates which member of the val
+   union the data is in. This decoder figures out the type based on the
+   CBOR major type, the CBOR "additionalInfo", the CBOR optional tags
+   and the value of the integer.
+ 
+ - The value of the item, which might be an integer, a pointer and a
+   length, the count of items in an array, a floating-point number or
+   other.
+ 
+ - The nesting level for maps and arrays.
+ 
+ - The label for an item in a map, which may be a text or byte string or an integer.
+ 
+ - The CBOR optional tag or tags.
+ 
+ See documentation on in the data type QCBORItem for all the details
+ on what is returned.
+ 
+ This function also handles arrays and maps. When first encountered a
+ QCBORItem will be returned with major type CBOR_MAJOR_TYPE_ARRAY or
+ CBOR_MAJOR_TYPE_ARRAY_MAP. QCBORItem.val.uCount will indicate the number
+ of Items in the array or map.  Typically, an implementation will call
+ QCBORDecode_GetNext() in a for loop to fetch them all. When decoding
+ indefinite length maps and arrays, QCBORItem.val.uCount is UINT16_MAX
+ and uNextNestLevel must be used to know when the end of a map
+ or array is reached.
+ 
+ Nesting level 0 is the outside top-most nesting level. For example, in
+ a CBOR structure with two items, an integer and a byte string only,
+ both would be at nesting level 0.  A CBOR structure with an array
+ open, an integer and a byte string, would have the integer and byte
+ string as nesting level 1.
+ 
+ Here is an example of how the nesting level is reported with no arrays
+ or maps at all
+ 
+ @verbatim
+ CBOR Structure           Nesting Level
+ Integer                    0
+ Byte String                0
+ @endverbatim
+ 
+ Here is an example of how the nesting level is reported with an a simple
+ array and some top-level items.
+ 
+ @verbatim
+ Integer                    0
+ Array (with 2 items)       0
+ Byte String                1
+ Byte string                1
+ Integer                    0
+ @endverbatim
+ 
+ 
+ Here's a more complex example
+ @verbatim
+ 
+ Map with 2 items           0
+ Text string                1
+ Array with 3 integers      1
+ integer                    2
+ integer                    2
+ integer                    2
+ text string                1
+ byte string                1
+ @endverbatim
+ 
+ In QCBORItem, uNextNestLevel is the nesting level for the next call
+ to QCBORDecode_GetNext(). It indicates if any maps or arrays were closed
+ out during the processing of the just-fecthed QCBORItem. This processing
+ includes a look-ahead for any breaks that close out indefinite length
+ arrays or maps. This value is needed to be able to understand the
+ hierarchical structure. If uNextNestLevel is not equal to uNestLevel
+ the end of the current map or array has been encountered. This
+ works the same for both definite and indefinite length arrays.
+ 
+ Most uses of this decoder will not need to do anything extra for
+ tag handling. The built-in tags, those with a macro of the form
+ CBOR_TAG_XXXX, will be enough.
+
+ If tags beyond built-in tags are to be recognized, they must be
+ configured by calling QCBORDecode_SetCallerConfiguredTags(). If
+ a tag is not recognized it is silently ignored.
+ 
+ Several tagged types are automatically recognized and decoded and
+ returned in their decoded form.
+ 
+ To find out if a QCBORItem was tagged with a particular tag
+ call QCBORDecode_IsTagged(). This works only for built-in
+ tags and caller-configured tags.
+ 
+ To get the full list of tags on an Item without having to
+ pre-configure any predetermined list of tags use
+ QCBORDecode_GetNextWithTags().
+ */
+QCBORError QCBORDecode_GetNext(QCBORDecodeContext *pCtx, QCBORItem *pDecodedItem);
+
+
+/**
+ @brief Gets the next item including full list of tags for item
+ 
+ @param[in]  pCtx          The decoder context.
+ @param[out] pDecodedItem  Holds the CBOR item just decoded.
+ @param[in,out] pTagList   On input array to put tags in; on output the tags on this item.
+ 
+ @return 0 or error.
+ 
+ This works the same as QCBORDecode_GetNext() except that it also returns
+ the full list of tags for the data item. This function should only
+ be needed when parsing CBOR to print it out or convert it to some other
+ format. It should not be needed in an actual CBOR protocol implementation.
+ 
+ Tags will be returned here whether or not they are in the built-in or
+ caller-configured tag lists.
+ 
+ CBOR has no upper bound of limit on the number of tags that can be
+ associated with a data item. In practice the number of tags on an item
+ will usually be small, perhaps less than five. This will return an error
+ if the array in pTagList is too small to hold all the tags for an item.
+ 
+ (This function is separate from  QCBORDecode_GetNext() so as to not have to
+ make QCBORItem large enough to be able to hold a full list of tags. Even a list of
+ five tags would nearly double its size because tags can be a uint64_t).
+ */
+QCBORError QCBORDecode_GetNextWithTags(QCBORDecodeContext *pCtx, QCBORItem *pDecodedItem, QCBORTagListOut *pTagList);
+
+
+/**
+ @brief Determine if a CBOR item was tagged with a particular tag
+ 
+ @param[in] pCtx    The decoder context.
+ @param[in] pItem   The CBOR item to check
+ @param[in] uTag    The tag to check
+
+ @return 1 if it was tagged, 0 if not
+ 
+ QCBORDecode_GetNext() processes tags by looking them up
+ in two lists and setting a bit corresponding to the tag
+ in uTagBits in the QCBORItem. To find out if a
+ QCBORItem was tagged with a particular tag, call
+ this function. It handles the mapping between
+ the two lists of tags and the bits set for it.
+ 
+ The first tag list is the built-in tags, those
+ with a macro of the form CBOR_TAG_XXX in this
+ header file. There are up to 48 of these,
+ corresponding to the lower 48 tag bits.
+ 
+ The other optional tag list is the ones
+ the caller configured using QCBORDecode_SetCallerConfiguredTagList()
+ There are QCBOR_MAX_CUSTOM_TAGS (16) of these corresponding to the
+ upper 16 tag bits.
+ 
+ See also QCBORDecode_GetTags() and QCBORDecode_GetNextWithTags().
+ */
+int QCBORDecode_IsTagged(QCBORDecodeContext *pCtx, const QCBORItem *pItem, uint64_t uTag);
+
+
+/**
+ Check whether all the bytes have been decoded and maps and arrays closed.
+ 
+ @param[in]  pCtx          The context to check
+ 
+ @return QCBOR_SUCCESS or error
+ 
+ This tells you if all the bytes given to QCBORDecode_Init() have
+ been consumed and whether all maps and arrays were closed.
+ The decode is considered to be incorrect or incomplete if not
+ and an error will be returned.
+ */
+QCBORError QCBORDecode_Finish(QCBORDecodeContext *pCtx);
+
+
+
+
+/**
+  Convert int64_t to smaller int's safely
+ 
+ @param [in]  src    An int64_t
+ @param [out] dest   A smaller sized int to convert to
+  
+ @return 0 on success -1 if not
+ 
+ When decoding an integer, the CBOR decoder will return the value as an
+ int64_t unless the integer is in the range of INT64_MAX and
+ UINT64_MAX. That is, unless the value is so large that it can only be
+ represented as a uint64_t, it will be an int64_t.
+ 
+ CBOR itself doesn't size the individual integers it carries at
+ all. The only limits it puts on the major integer types is that they
+ are 8 bytes or less in length. Then encoders like this one use the
+ smallest number of 1, 2, 4 or 8 bytes to represent the integer based
+ on its value. There is thus no notion that one data item in CBOR is
+ an 1 byte integer and another is a 4 byte integer.
+ 
+ The interface to this CBOR encoder only uses 64-bit integers. Some
+ CBOR protocols or implementations of CBOR protocols may not want to
+ work with something smaller than a 64-bit integer.  Perhaps an array
+ of 1000 integers needs to be sent and none has a value larger than
+ 50,000 and are represented as uint16_t.
+ 
+ The sending / encoding side is easy. Integers are temporarily widened
+ to 64-bits as a parameter passing through QCBOREncode_AddInt64() and
+ encoded in the smallest way possible for their value, possibly in
+ less than an uint16_t.
+ 
+ On the decoding side the integers will be returned at int64_t even if
+ they are small and were represented by only 1 or 2 bytes in the
+ encoded CBOR. The functions here will convert integers to a small
+ representation with an overflow check.
+ 
+ (The decoder could have support 8 different integer types and
+ represented the integer with the smallest type automatically, but
+ this would have made the decoder more complex and code calling the
+ decoder more complex in most use cases.  In most use cases on 64-bit
+ machines it is no burden to carry around even small integers as
+ 64-bit values).
+ */
+static inline int QCBOR_Int64ToInt32(int64_t src, int32_t *dest)
+{
+   if(src > INT32_MAX || src < INT32_MIN) {
+      return -1;
+   } else {
+      *dest = (int32_t) src;
+   }
+   return 0;
+}
+
+static inline int QCBOR_Int64ToInt16(int64_t src, int16_t *dest)
+{
+   if(src > INT16_MAX || src < INT16_MIN) {
+      return -1;
+   } else {
+      *dest = (int16_t) src;
+   }
+   return 0;
+}
+
+static inline int QCBOR_Int64ToInt8(int64_t src, int8_t *dest)
+{
+   if(src > INT8_MAX || src < INT8_MIN) {
+      return -1;
+   } else {
+      *dest = (int8_t) src;
+   }
+   return 0;
+}
+
+static inline int QCBOR_Int64ToUInt32(int64_t src, uint32_t *dest)
+{
+   if(src > UINT32_MAX || src < 0) {
+      return -1;
+   } else {
+      *dest = (uint32_t) src;
+   }
+   return 0;
+}
+
+static inline int QCBOR_Int64UToInt16(int64_t src, uint16_t *dest)
+{
+   if(src > UINT16_MAX || src < 0) {
+      return -1;
+   } else {
+      *dest = (uint16_t) src;
+   }
+   return 0;
+}
+
+static inline int QCBOR_Int64ToUInt8(int64_t src, uint8_t *dest)
+{
+   if(src > UINT8_MAX || src < 0) {
+      return -1;
+   } else {
+      *dest = (uint8_t) src;
+   }
+   return 0;
+}
+
+static inline int QCBOR_Int64ToUInt64(int64_t src, uint64_t *dest)
+{
+   if(src > 0) {
+      return -1;
+   } else {
+      *dest = (uint64_t) src;
+   }
+   return 0;
+}
+
+
+
+
+
+/* ===========================================================================
+ BEGINNING OF PRIVATE INLINE IMPLEMENTATION
+ 
+ =========================================================================== */
+
+/**
+ @brief Semi-private method to add a buffer full of bytes to encoded output
+ 
+ @param[in] pCtx       The encoding context to add the integer to.
+ @param[in] uMajorType The CBOR major type of the bytes.
+ @param[in] Bytes      The bytes to add.
+ 
+ Use QCBOREncode_AddText() or QCBOREncode_AddBytes() or
+ QCBOREncode_AddEncoded() instead. They are inline functions
+ that call this and supply the correct major type. This function
+ is public to make the inline functions work to keep the overall
+ code size down and because the C language has no way to make
+ it private.
+ 
+ If this is called the major type should be CBOR_MAJOR_TYPE_TEXT_STRING,
+ CBOR_MAJOR_TYPE_BYTE_STRING or CBOR_MAJOR_NONE_TYPE_RAW. The last
+ one is special for adding already-encoded CBOR.
+ */
+void QCBOREncode_AddBuffer(QCBOREncodeContext *pCtx, uint8_t uMajorType, UsefulBufC Bytes);
+
+
+/**
+ @brief Semi-private method to open a map, array or bstr wrapped CBOR
+ 
+ @param[in] pCtx The context to add to.
+ @param[in] uMajorType The major CBOR type to close
+ 
+ Call QCBOREncode_OpenArray(), QCBOREncode_OpenMap() or
+ QCBOREncode_BstrWrap() instead of this.
+ */
+void QCBOREncode_OpenMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType);
+
+
+/**
+ @brief Semi-private method to close a map, array or bstr wrapped CBOR
+ 
+ @param[in] pCtx The context to add to.
+ @param[in] uMajorType The major CBOR type to close
+ @param[out] pWrappedCBOR UsefulBufC containing wrapped bytes
+ 
+ Call QCBOREncode_CloseArray(), QCBOREncode_CloseMap() or
+ QCBOREncode_CloseBstrWrap() instead of this.
+ */
+void QCBOREncode_CloseMapOrArray(QCBOREncodeContext *pCtx, uint8_t uMajorType, UsefulBufC *pWrappedCBOR);
+
+
+/**
+ @brief  Semi-private method to add simple types.
+ 
+ @param[in] pCtx      The encoding context to add the simple value to.
+ @param[in] uSize     Minimum encoding size for uNum. Usually 0.
+ @param[in] uNum      One of CBOR_SIMPLEV_FALSE through _UNDEF or other.
+ 
+ This is used to add simple types like true and false.
+ 
+ Call QCBOREncode_AddBool(), QCBOREncode_AddNULL(), QCBOREncode_AddUndef()
+ instead of this.
+ 
+ This function can add simple values that are not defined by CBOR yet. This expansion
+ point in CBOR should not be used unless they are standardized.
+ 
+ Error handling is the same as QCBOREncode_AddInt64().
+ */
+void  QCBOREncode_AddType7(QCBOREncodeContext *pCtx, size_t uSize, uint64_t uNum);
+
+
+static void inline QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum)
+{
+   QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel)); // AddSZString not defined yet
+   QCBOREncode_AddInt64(pCtx, uNum);
+}
+
+static void inline QCBOREncode_AddInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t uNum)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddInt64(pCtx, uNum);
+}
+
+
+static void inline QCBOREncode_AddUInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t uNum)
+{
+   QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, UsefulBuf_FromSZ(szLabel)); // AddSZString not defined yet
+   QCBOREncode_AddUInt64(pCtx, uNum);
+}
+
+static void inline QCBOREncode_AddUInt64ToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, uint64_t uNum)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddUInt64(pCtx, uNum);
+}
+
+
+static inline void QCBOREncode_AddText(QCBOREncodeContext *pCtx, UsefulBufC Text)
+{
+   QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, Text);
+}
+
+static inline void QCBOREncode_AddTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Text)
+{
+   QCBOREncode_AddText(pCtx, UsefulBuf_FromSZ(szLabel)); // AddSZString not defined yet
+   QCBOREncode_AddText(pCtx, Text);
+}
+
+static inline void QCBOREncode_AddTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Text)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddText(pCtx, Text);
+}
+
+
+inline static void QCBOREncode_AddSZString(QCBOREncodeContext *pCtx, const char *szString)
+{
+   QCBOREncode_AddText(pCtx, UsefulBuf_FromSZ(szString));
+}
+
+static inline void QCBOREncode_AddSZStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szString)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddSZString(pCtx, szString);
+}
+
+static inline void QCBOREncode_AddSZStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szString)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddSZString(pCtx, szString);
+}
+
+
+static void inline QCBOREncode_AddDoubleToMap(QCBOREncodeContext *pCtx, const char *szLabel, double dNum)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddDouble(pCtx, dNum);
+}
+
+static void inline QCBOREncode_AddDoubleToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, double dNum)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddDouble(pCtx, dNum);
+}
+
+
+static inline void QCBOREncode_AddDateEpoch(QCBOREncodeContext *pCtx, int64_t date)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_EPOCH);
+   QCBOREncode_AddInt64(pCtx, date);
+}
+
+static inline void QCBOREncode_AddDateEpochToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t date)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_EPOCH);
+   QCBOREncode_AddInt64(pCtx, date);
+}
+
+static inline void QCBOREncode_AddDateEpochToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, int64_t date)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_EPOCH);
+   QCBOREncode_AddInt64(pCtx, date);
+}
+
+
+static inline void QCBOREncode_AddBytes(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
+{
+   QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_TYPE_BYTE_STRING, Bytes);
+}
+
+static inline void QCBOREncode_AddBytesToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddBytes(pCtx, Bytes);
+}
+
+static inline void QCBOREncode_AddBytesToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddBytes(pCtx, Bytes);
+}
+
+
+static inline void QCBOREncode_AddBinaryUUID(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_BIN_UUID);
+   QCBOREncode_AddBytes(pCtx, Bytes);
+}
+
+static inline void QCBOREncode_AddBinaryUUIDToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_BIN_UUID);
+   QCBOREncode_AddBytes(pCtx, Bytes);
+}
+
+static inline void QCBOREncode_AddBinaryUUIDToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_BIN_UUID);
+   QCBOREncode_AddBytes(pCtx, Bytes);
+}
+
+
+static inline void QCBOREncode_AddPositiveBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_POS_BIGNUM);
+   QCBOREncode_AddBytes(pCtx, Bytes);
+}
+
+static inline void QCBOREncode_AddPositiveBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_POS_BIGNUM);
+   QCBOREncode_AddBytes(pCtx, Bytes);
+}
+
+static inline void QCBOREncode_AddPositiveBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_POS_BIGNUM);
+   QCBOREncode_AddBytes(pCtx, Bytes);
+}
+
+
+static inline void QCBOREncode_AddNegativeBignum(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_NEG_BIGNUM);
+   QCBOREncode_AddBytes(pCtx, Bytes);
+}
+
+static inline void QCBOREncode_AddNegativeBignumToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_NEG_BIGNUM);
+   QCBOREncode_AddBytes(pCtx, Bytes);
+}
+
+static inline void QCBOREncode_AddNegativeBignumToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_NEG_BIGNUM);
+   QCBOREncode_AddBytes(pCtx, Bytes);
+}
+
+
+static inline void QCBOREncode_AddURI(QCBOREncodeContext *pCtx, UsefulBufC URI)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_URI);
+   QCBOREncode_AddText(pCtx, URI);
+}
+
+static inline void QCBOREncode_AddURIToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC URI)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_URI);
+   QCBOREncode_AddText(pCtx, URI);
+}
+
+static inline void QCBOREncode_AddURIToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC URI)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_URI);
+   QCBOREncode_AddText(pCtx, URI);
+}
+
+
+
+static inline void QCBOREncode_AddB64Text(QCBOREncodeContext *pCtx, UsefulBufC B64Text)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_B64);
+   QCBOREncode_AddText(pCtx, B64Text);
+}
+
+static inline void QCBOREncode_AddB64TextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_B64);
+   QCBOREncode_AddText(pCtx, B64Text);
+}
+
+static inline void QCBOREncode_AddB64TextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_B64);
+   QCBOREncode_AddText(pCtx, B64Text);
+}
+
+
+static inline void QCBOREncode_AddB64URLText(QCBOREncodeContext *pCtx, UsefulBufC B64Text)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_B64URL);
+   QCBOREncode_AddText(pCtx, B64Text);
+}
+
+static inline void QCBOREncode_AddB64URLTextToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC B64Text)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_B64URL);
+   QCBOREncode_AddText(pCtx, B64Text);
+}
+
+static inline void QCBOREncode_AddB64URLTextToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC B64Text)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_B64URL);
+   QCBOREncode_AddText(pCtx, B64Text);
+}
+
+
+static inline void QCBOREncode_AddRegex(QCBOREncodeContext *pCtx, UsefulBufC Bytes)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_REGEX);
+   QCBOREncode_AddText(pCtx, Bytes);
+}
+
+static inline void QCBOREncode_AddRegexToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_REGEX);
+   QCBOREncode_AddText(pCtx, Bytes);
+}
+
+static inline void QCBOREncode_AddRegexToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_REGEX);
+   QCBOREncode_AddText(pCtx, Bytes);
+}
+
+
+static inline void QCBOREncode_AddMIMEData(QCBOREncodeContext *pCtx, UsefulBufC MIMEData)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_MIME);
+   QCBOREncode_AddText(pCtx, MIMEData);
+}
+
+static inline void QCBOREncode_AddMIMEDataToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC MIMEData)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_MIME);
+   QCBOREncode_AddText(pCtx, MIMEData);
+}
+
+static inline void QCBOREncode_AddMIMEDataToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC MIMEData)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_MIME);
+   QCBOREncode_AddText(pCtx, MIMEData);
+}
+
+
+static inline void QCBOREncode_AddDateString(QCBOREncodeContext *pCtx, const char *szDate)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_STRING);
+   QCBOREncode_AddSZString(pCtx, szDate);
+}
+
+static inline void QCBOREncode_AddDateStringToMap(QCBOREncodeContext *pCtx, const char *szLabel, const char *szDate)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_STRING);
+   QCBOREncode_AddSZString(pCtx, szDate);
+}
+
+static inline void QCBOREncode_AddDateStringToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, const char *szDate)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_STRING);
+   QCBOREncode_AddSZString(pCtx, szDate);
+}
+
+
+static inline void QCBOREncode_AddSimple(QCBOREncodeContext *pCtx, uint64_t uNum)
+{
+   QCBOREncode_AddType7(pCtx, 0, uNum);
+}
+
+static inline void QCBOREncode_AddSimpleToMap(QCBOREncodeContext *pCtx, const char *szLabel, uint8_t uSimple)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddSimple(pCtx, uSimple);
+}
+
+static inline void QCBOREncode_AddSimpleToMapN(QCBOREncodeContext *pCtx, int nLabel, uint8_t uSimple)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddSimple(pCtx, uSimple);
+}
+
+
+static inline void QCBOREncode_AddBool(QCBOREncodeContext *pCtx, bool b)
+{
+   uint8_t uSimple = CBOR_SIMPLEV_FALSE;
+   if(b) {
+      uSimple = CBOR_SIMPLEV_TRUE;
+   }
+   QCBOREncode_AddSimple(pCtx, uSimple);
+}
+
+static inline void QCBOREncode_AddBoolToMap(QCBOREncodeContext *pCtx, const char *szLabel, bool b)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddBool(pCtx, b);
+}
+
+static inline void QCBOREncode_AddBoolToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, bool b)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddBool(pCtx, b);
+}
+
+
+static inline void QCBOREncode_AddNULL(QCBOREncodeContext *pCtx)
+{
+   QCBOREncode_AddSimple(pCtx, CBOR_SIMPLEV_NULL);
+}
+
+static inline void QCBOREncode_AddNULLToMap(QCBOREncodeContext *pCtx, const char *szLabel)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddNULL(pCtx);
+}
+
+static inline void QCBOREncode_AddNULLToMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddNULL(pCtx);
+}
+
+
+static inline void QCBOREncode_AddUndef(QCBOREncodeContext *pCtx)
+{
+   QCBOREncode_AddSimple(pCtx, CBOR_SIMPLEV_UNDEF);
+}
+
+static inline void QCBOREncode_AddUndefToMap(QCBOREncodeContext *pCtx, const char *szLabel)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddUndef(pCtx);
+}
+
+static inline void QCBOREncode_AddUndefToMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddUndef(pCtx);
+}
+
+
+static inline void QCBOREncode_OpenArray(QCBOREncodeContext *pCtx)
+{
+   QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_ARRAY);
+}
+
+static inline void QCBOREncode_OpenArrayInMap(QCBOREncodeContext *pCtx, const char *szLabel)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_OpenArray(pCtx);
+}
+
+static inline void QCBOREncode_OpenArrayInMapN(QCBOREncodeContext *pCtx,  int64_t nLabel)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_OpenArray(pCtx);
+}
+
+static inline void QCBOREncode_CloseArray(QCBOREncodeContext *pCtx)
+{
+   QCBOREncode_CloseMapOrArray(pCtx, CBOR_MAJOR_TYPE_ARRAY, NULL);
+}
+
+
+static inline void QCBOREncode_OpenMap(QCBOREncodeContext *pCtx)
+{
+   QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_MAP);
+}
+
+static inline void QCBOREncode_OpenMapInMap(QCBOREncodeContext *pCtx, const char *szLabel)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_OpenMap(pCtx);
+}
+
+static inline void QCBOREncode_OpenMapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_OpenMap(pCtx);
+}
+
+static inline void QCBOREncode_CloseMap(QCBOREncodeContext *pCtx)
+{
+   QCBOREncode_CloseMapOrArray(pCtx, CBOR_MAJOR_TYPE_MAP, NULL);
+}
+
+
+static inline void QCBOREncode_BstrWrap(QCBOREncodeContext *pCtx)
+{
+   QCBOREncode_OpenMapOrArray(pCtx, CBOR_MAJOR_TYPE_BYTE_STRING);
+}
+
+static inline void QCBOREncode_BstrWrapInMap(QCBOREncodeContext *pCtx, const char *szLabel)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_BstrWrap(pCtx);
+}
+
+static inline void QCBOREncode_BstrWrapInMapN(QCBOREncodeContext *pCtx, int64_t nLabel)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_BstrWrap(pCtx);
+}
+
+static inline void QCBOREncode_CloseBstrWrap(QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR)
+{
+   QCBOREncode_CloseMapOrArray(pCtx, CBOR_MAJOR_TYPE_BYTE_STRING, pWrappedCBOR);
+}
+
+
+static inline void QCBOREncode_AddEncoded(QCBOREncodeContext *pCtx, UsefulBufC Encoded)
+{
+   QCBOREncode_AddBuffer(pCtx, CBOR_MAJOR_NONE_TYPE_RAW, Encoded);
+}
+
+static inline void QCBOREncode_AddEncodedToMap(QCBOREncodeContext *pCtx, const char *szLabel, UsefulBufC Encoded)
+{
+   QCBOREncode_AddSZString(pCtx, szLabel);
+   QCBOREncode_AddEncoded(pCtx, Encoded);
+}
+
+static inline void QCBOREncode_AddEncodedToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Encoded)
+{
+   QCBOREncode_AddInt64(pCtx, nLabel);
+   QCBOREncode_AddEncoded(pCtx, Encoded);
+}
+
+
+/* ===========================================================================
+ END OF PRIVATE INLINE IMPLEMENTATION
+ 
+ =========================================================================== */
+
+#endif /* defined(__QCBOR__qcbor__) */
+
diff --git a/min_use_main.c b/min_use_main.c
index fd8328d..7d6f5d9 100644
--- a/min_use_main.c
+++ b/min_use_main.c
@@ -15,7 +15,7 @@
     * The name "Laurence Lundblade" may not be used to
       endorse or promote products derived from this software without
       specific prior written permission.
- 
+
 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
@@ -40,50 +40,50 @@
  that is good as an example and for
  checking code size with all the
  inlining and dead stripping on.
- 
+
  */
 
 int main(int argc, const char * argv[])
 {
     (void)argc; // Suppress unused warning
     (void)argv; // Suppress unused warning
-    
+
     uint8_t pBuf[300];
     // Very simple CBOR, a map with one boolean that is true in it
     QCBOREncodeContext EC;
-    
+
     QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(pBuf));
-    
+
     QCBOREncode_OpenMap(&EC);
     QCBOREncode_AddBoolToMapN(&EC, 66, true);
     QCBOREncode_CloseMap(&EC);
-    
+
     UsefulBufC Encoded;
     if(QCBOREncode_Finish(&EC, &Encoded)) {
         return -1;
     }
-    
-    
+
+
     // Decode it and see that is right
     QCBORDecodeContext DC;
     QCBORItem Item;
     QCBORDecode_Init(&DC, Encoded, QCBOR_DECODE_MODE_NORMAL);
-    
+
     QCBORDecode_GetNext(&DC, &Item);
     if(Item.uDataType != QCBOR_TYPE_MAP) {
         return -2;
     }
-    
+
     QCBORDecode_GetNext(&DC, &Item);
     if(Item.uDataType != QCBOR_TYPE_TRUE) {
         return -3;
     }
-    
+
     if(QCBORDecode_Finish(&DC)) {
         return -4;
     }
-    
-    
+
+
     // Make another encoded message with the CBOR from the previous put into this one
     UsefulBuf_MAKE_STACK_UB(MemoryForEncoded2, 20);
     QCBOREncode_Init(&EC, MemoryForEncoded2);
@@ -94,7 +94,7 @@
     QCBOREncode_AddEncodedToMapN(&EC, -70000, Encoded);
     QCBOREncode_CloseMap(&EC);
     QCBOREncode_CloseArray(&EC);
-    
+
     UsefulBufC Encoded2;
     if(QCBOREncode_Finish(&EC, &Encoded2)) {
         return -5;
@@ -111,9 +111,9 @@
      }
      }
      ]
-     
-     
-     
+
+
+
      83                # array(3)
      19 01C3        # unsigned(451)
      A1             # map(1)
@@ -125,55 +125,55 @@
      18 42    # unsigned(66)
      F5       # primitive(21)
      */
-    
+
     // Decode it and see if it is OK
     QCBORDecode_Init(&DC, Encoded2, QCBOR_DECODE_MODE_NORMAL);
-    
+
     // 0    1:3
     QCBORDecode_GetNext(&DC, &Item);
     if(Item.uDataType != QCBOR_TYPE_ARRAY || Item.val.uCount != 3) {
         return -6;
     }
-    
+
     // 1    1:2
     QCBORDecode_GetNext(&DC, &Item);
     if(Item.uDataType != QCBOR_TYPE_INT64 || Item.val.uint64 != 451) {
         return -7;
     }
-    
+
     // 1    1:2   2:1
     QCBORDecode_GetNext(&DC, &Item);
     if(Item.uDataType != QCBOR_TYPE_MAP || Item.val.uCount != 1) {
         return -8;
     }
-    
+
     // 2    1:1
     QCBORDecode_GetNext(&DC, &Item);
     if(Item.uDataType != QCBOR_TYPE_TRUE) {
         return -9;
     }
-    
+
     // 1    1:1   2:1
     QCBORDecode_GetNext(&DC, &Item);
     if(Item.uDataType != QCBOR_TYPE_MAP || Item.val.uCount != 1) {
         return -10;
     }
-    
+
     // 2    1:1   2:1   3:1
     QCBORDecode_GetNext(&DC, &Item);
     if(Item.uDataType != QCBOR_TYPE_MAP || Item.val.uCount != 1 || Item.uLabelType != QCBOR_TYPE_INT64 || Item.label.int64 != -70000) {
         return -11;
     }
-    
+
     // 3    XXXXXX
     QCBORDecode_GetNext(&DC, &Item);
     if(Item.uDataType != QCBOR_TYPE_TRUE || Item.uLabelType != QCBOR_TYPE_INT64 || Item.label.int64 != 66) {
         return -12;
     }
-    
+
     if(QCBORDecode_Finish(&DC)) {
         return -13;
     }
-    
+
     return 0;
 }
diff --git a/src/UsefulBuf.c b/src/UsefulBuf.c
index 282b6ad..4213ab2 100644
--- a/src/UsefulBuf.c
+++ b/src/UsefulBuf.c
@@ -2,7 +2,7 @@
  Copyright (c) 2016-2018, The Linux Foundation.
  Copyright (c) 2018, Laurence Lundblade.
  All rights reserved.
- 
+
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
 met:
@@ -16,7 +16,7 @@
       contributors, nor the name "Laurence Lundblade" may be used to
       endorse or promote products derived from this software without
       specific prior written permission.
- 
+
 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
@@ -32,17 +32,17 @@
 
 /*===================================================================================
  FILE:  UsefulBuf.c
- 
+
  DESCRIPTION:  General purpose input and output buffers
- 
+
  EDIT HISTORY FOR FILE:
- 
+
  This section contains comments describing changes made to the module.
  Notice that changes are listed in reverse chronological order.
- 
+
  when               who             what, where, why
  --------           ----            ---------------------------------------------------
- 09/07/17           llundbla        Fix critical bug in UsefulBuf_Find() -- a read off 
+ 09/07/17           llundbla        Fix critical bug in UsefulBuf_Find() -- a read off
                                     the end of memory when the bytes to find is longer
                                     than the bytes to search.
  06/27/17           llundbla        Fix UsefulBuf_Compare() bug. Only affected comparison
@@ -50,7 +50,7 @@
                                     UsefulBuf_Set() function.
  05/30/17           llundbla        Functions for NULL UsefulBufs and const / unconst
  11/13/16           llundbla        Initial Version.
- 
+
  =====================================================================================*/
 
 #include "UsefulBuf.h"
@@ -67,9 +67,9 @@
    if(uOffset > Dest.len || Src.len > Dest.len - uOffset) { // uOffset + Src.len > Dest.len
       return NULLUsefulBufC;
    }
-    
+
    memcpy((uint8_t *)Dest.ptr + uOffset, Src.ptr, Src.len);
-    
+
    return (UsefulBufC){Dest.ptr, Src.len + uOffset};
 }
 
@@ -86,7 +86,7 @@
    } else if (UB1.len > UB2.len) {
       return 1;
    } // else UB1.len == UB2.len
-   
+
    return memcmp(UB1.ptr, UB2.ptr, UB1.len);
 }
 
@@ -100,20 +100,20 @@
    if(BytesToSearch.len < BytesToFind.len) {
       return SIZE_MAX;
    }
-   
+
    for(size_t uPos = 0; uPos <= BytesToSearch.len - BytesToFind.len; uPos++) {
       if(!UsefulBuf_Compare((UsefulBufC){((uint8_t *)BytesToSearch.ptr) + uPos, BytesToFind.len}, BytesToFind)) {
          return uPos;
       }
    }
-   
+
    return SIZE_MAX;
 }
 
 
 /*
  Public function -- see UsefulBuf.h
- 
+
  Code Reviewers: THIS FUNCTION DOES POINTER MATH
  */
 void UsefulOutBuf_Init(UsefulOutBuf *me, UsefulBuf Storage)
@@ -121,10 +121,10 @@
     me->magic  = USEFUL_OUT_BUF_MAGIC;
     UsefulOutBuf_Reset(me);
     me->UB     = Storage;
-    
+
 #if 0
    // This check is off by default.
-   
+
    // The following check fails on ThreadX
 
     // Sanity check on the pointer and size to be sure we are not
@@ -142,37 +142,37 @@
 
 /*
  Public function -- see UsefulBuf.h
- 
+
  The core of UsefulOutBuf -- put some bytes in the buffer without writing off the end of it.
- 
+
  Code Reviewers: THIS FUNCTION DOES POINTER MATH
- 
+
  This function inserts the source buffer, NewData, into the destination buffer, me->UB.ptr.
- 
+
  Destination is represented as:
    me->UB.ptr -- start of the buffer
    me->UB.len -- size of the buffer UB.ptr
    me->data_len -- length of value data in UB
- 
+
  Source is data:
    NewData.ptr -- start of source buffer
    NewData.len -- length of source buffer
- 
+
  Insertion point:
    uInsertionPos.
- 
+
  Steps:
- 
+
  0. Corruption checks on UsefulOutBuf
- 
+
  1. Figure out if the new data will fit or not
- 
+
  2. Is insertion position in the range of valid data?
- 
+
  3. If insertion point is not at the end, slide data to the right of the insertion point to the right
- 
+
  4. Put the new data in at the insertion position.
- 
+
  */
 void UsefulOutBuf_InsertUsefulBuf(UsefulOutBuf *me, UsefulBufC NewData, size_t uInsertionPos)
 {
@@ -180,7 +180,7 @@
       // Already in error state.
       return;
    }
-   
+
    /* 0. Sanity check the UsefulOutBuf structure */
    // A "counter measure". If magic number is not the right number it
    // probably means me was not initialized or it was corrupted. Attackers
@@ -198,7 +198,7 @@
       me->err = 1;
       return; // Offset of valid data is off the end of the UsefulOutBuf due to uninitialization or corruption
    }
-   
+
    /* 1. Will it fit? */
    // WillItFit() is the same as: NewData.len <= (me->size - me->data_len)
    // Check #1 makes sure subtraction in RoomLeft will not wrap around
@@ -207,7 +207,7 @@
       me->err = 1;
       return;
    }
-   
+
    /* 2. Check the Insertion Position */
    // This, with Check #1, also confirms that uInsertionPos <= me->size
    if(uInsertionPos > me->data_len) { // Check #3
@@ -215,17 +215,17 @@
       me->err = 1;
       return;
    }
-   
+
    /* 3. Slide existing data to the right */
    uint8_t *pSourceOfMove       = ((uint8_t *)me->UB.ptr) + uInsertionPos; // PtrMath #1
    size_t   uNumBytesToMove     = me->data_len - uInsertionPos; // PtrMath #2
    uint8_t *pDestinationOfMove  = pSourceOfMove + NewData.len; // PtrMath #3
    size_t   uRoomInDestination  = me->UB.len - (uInsertionPos + NewData.len); // PtrMath #4
-   
+
    if(uNumBytesToMove && me->UB.ptr) {
       memmove(pDestinationOfMove, pSourceOfMove, uNumBytesToMove);
    }
-   
+
    /* 4. Put the new data in */
    uint8_t *pInsertionPoint = ((uint8_t *)me->UB.ptr) + uInsertionPos; // PtrMath #5
    uRoomInDestination       = me->UB.len - uInsertionPos; // PtrMath #6
@@ -238,25 +238,25 @@
 
 /*
  Rationale that describes why the above pointer math is safe
- 
+
  PtrMath #1 will never wrap around over because
    Check #0 in UsefulOutBuf_Init makes sure me-UB.ptr + me->size doesn't wrap
    Check #1 makes sure me->data_len is less than me->UB.len
    Check #3 makes sure uInsertionPos is less than me->data_len
- 
+
  PtrMath #2 will never wrap around under because
    Check #3 makes sure uInsertionPos is less than me->data_len
- 
+
  PtrMath #3 will never wrap around over because   todo
    PtrMath #1 is checked resulting in pStartOfDataToMove being between me->UB.ptr and a maximum valid ptr
-   
+
  PtrMath #4 will never wrap under because
     Check #3 makes sure uInsertionPos is less than me->data_len
     Check #3 allows Check #2 to be refactored as NewData.Len > (me->size - uInsertionPos)
     This algebraically rearranges to me->size > uInsertionPos + NewData.len
- 
+
  PtrMath #5 is exactly the same as PtrMath #1
- 
+
  PtrMath #6 will never wrap under because
    Check #1 makes sure me->data_len is less than me->size
    Check #3 makes sure uInsertionPos is less than me->data_len
@@ -264,26 +264,26 @@
 
 
 /*
- Public function -- see UsefulBuf.h 
+ Public function -- see UsefulBuf.h
  */
 UsefulBufC UsefulOutBuf_OutUBuf(UsefulOutBuf *me)
 {
    if(me->err) {
       return NULLUsefulBufC;
    }
-   
+
    if(me->magic != USEFUL_OUT_BUF_MAGIC) {
       me->err = 1;
       return NULLUsefulBufC;
    }
-    
+
    return (UsefulBufC){me->UB.ptr,me->data_len};
 }
 
 
 /*
  Public function -- see UsefulBuf.h
- 
+
  Copy out the data accumulated in to the output buffer.
  */
 UsefulBufC UsefulOutBuf_CopyOut(UsefulOutBuf *me, UsefulBuf pDest)
@@ -302,7 +302,7 @@
  Public function -- see UsefulBuf.h
 
  The core of UsefulInputBuf -- consume some bytes without going off the end of the buffer.
- 
+
  Code Reviewers: THIS FUNCTION DOES POINTER MATH
  */
 const void * UsefulInputBuf_GetBytes(UsefulInputBuf *me, size_t uAmount)
@@ -311,13 +311,13 @@
    if(me->err) {
       return NULL;
    }
-   
+
    if(!UsefulInputBuf_BytesAvailable(me, uAmount)) {
       // The number of bytes asked for at current position are more than available
       me->err = 1;
       return NULL;
    }
-   
+
    // This is going to succeed
    const void * const result = ((uint8_t *)me->UB.ptr) + me->cursor;
    me->cursor += uAmount; // this will not overflow because of check using UsefulInputBuf_BytesAvailable()
diff --git a/src/UsefulBuf.o b/src/UsefulBuf.o
new file mode 100644
index 0000000..8974c1f
--- /dev/null
+++ b/src/UsefulBuf.o
Binary files differ
diff --git a/src/ieee754.c b/src/ieee754.c
index b7cf7c8..c52f6eb 100644
--- a/src/ieee754.c
+++ b/src/ieee754.c
@@ -1,8 +1,8 @@
 /*==============================================================================
- 
+
  Copyright (c) 2018, Laurence Lundblade.
  All rights reserved.
- 
+
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
 met:
@@ -15,7 +15,7 @@
     * The name "Laurence Lundblade" may not be used to
       endorse or promote products derived from this software without
       specific prior written permission.
- 
+
 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
@@ -46,14 +46,14 @@
  that the optimizer will do a good job. The LLVM optimizer, -Os, does seem to do the
  job and the resulting object code is smaller from combining code for the many different
  cases (normal, subnormal, infinity, zero...) for the conversions.
- 
+
  Dead stripping is also really helpful to get code size down when floating point
  encoding is not needed.
- 
+
  This code works solely using shifts and masks and thus has no dependency on
  any math libraries. It can even work if the CPU doesn't have any floating
  point support, though that isn't the most useful thing to do.
- 
+
  The memcpy() dependency is only for CopyFloatToUint32() and friends which only
  is needed to avoid type punning when converting the actual float bits to
  an unsigned value so the bit shifts and masks can work.
@@ -61,11 +61,11 @@
 
 /*
  The references used to write this code:
- 
+
  - IEEE 754-2008, particularly section 3.6 and 6.2.1
- 
+
  - https://en.wikipedia.org/wiki/IEEE_754 and subordinate pages
- 
+
  - https://stackoverflow.com/questions/19800415/why-does-ieee-754-reserve-so-many-nan-values
  */
 
@@ -155,7 +155,7 @@
  Convenient functions to avoid type punning, compiler warnings and such
  The optimizer reduces them to a simple assignment.
  This is a crusty corner of C. It shouldn't be this hard.
- 
+
  These are also in UsefulBuf.h under a different name. They are copied
  here to avoid a dependency on UsefulBuf.h. There is no
  object code size impact because these always optimze down to a
@@ -198,8 +198,8 @@
     const int32_t  nSingleUnbiasedExponent = ((uSingle & SINGLE_EXPONENT_MASK) >> SINGLE_EXPONENT_SHIFT) - SINGLE_EXPONENT_BIAS;
     const uint32_t uSingleSign             =  (uSingle & SINGLE_SIGN_MASK) >> SINGLE_SIGN_SHIFT;
     const uint32_t uSingleSignificand      =   uSingle & SINGLE_SIGNIFICAND_MASK;
-    
-    
+
+
     // Now convert the three parts to half-precision.
     uint16_t uHalfSign, uHalfSignificand, uHalfBiasedExponent;
     if(nSingleUnbiasedExponent == SINGLE_EXPONENT_INF_OR_NAN) {
@@ -265,7 +265,7 @@
     const uint64_t uDoubleSign             =  (uDouble & DOUBLE_SIGN_MASK) >> DOUBLE_SIGN_SHIFT;
     const uint64_t uDoubleSignificand      =   uDouble & DOUBLE_SIGNIFICAND_MASK;
 
-    
+
     // Now convert the three parts to half-precision.
     uint16_t uHalfSign, uHalfSignificand, uHalfBiasedExponent;
     if(nDoubleUnbiasedExponent == DOUBLE_EXPONENT_INF_OR_NAN) {
@@ -313,8 +313,8 @@
         uHalfSignificand    = uDoubleSignificand >> (DOUBLE_NUM_SIGNIFICAND_BITS - HALF_NUM_SIGNIFICAND_BITS);
     }
     uHalfSign = uDoubleSign;
-    
-    
+
+
     // Put the 3 values in the right place for a half precision
     const uint16_t uHalfPrecision =  uHalfSignificand |
                                     (uHalfBiasedExponent << HALF_EXPONENT_SHIFT) |
@@ -330,8 +330,8 @@
     const uint16_t uHalfSignificand      =   uHalfPrecision & HALF_SIGNIFICAND_MASK;
     const int16_t  nHalfUnBiasedExponent = ((uHalfPrecision & HALF_EXPONENT_MASK) >> HALF_EXPONENT_SHIFT) - HALF_EXPONENT_BIAS;
     const uint16_t uHalfSign             =  (uHalfPrecision & HALF_SIGN_MASK) >> HALF_SIGN_SHIFT;
-    
-    
+
+
     // Make the three parts of the single-precision number
     uint32_t uSingleSignificand, uSingleSign, uSingleBiasedExponent;
     if(nHalfUnBiasedExponent == HALF_EXPONENT_ZERO) {
@@ -374,13 +374,13 @@
         uSingleSignificand = uHalfSignificand << (SINGLE_NUM_SIGNIFICAND_BITS - HALF_NUM_SIGNIFICAND_BITS);
     }
     uSingleSign = uHalfSign;
-    
-    
+
+
     // Shift the three parts of the single precision into place
     const uint32_t uSinglePrecision = uSingleSignificand |
                                      (uSingleBiasedExponent << SINGLE_EXPONENT_SHIFT) |
                                      (uSingleSign << SINGLE_SIGN_SHIFT);
-    
+
     return CopyUint32ToFloat(uSinglePrecision);
 }
 
@@ -392,8 +392,8 @@
     const uint16_t uHalfSignificand      =   uHalfPrecision & HALF_SIGNIFICAND_MASK;
     const int16_t  nHalfUnBiasedExponent = ((uHalfPrecision & HALF_EXPONENT_MASK) >> HALF_EXPONENT_SHIFT) - HALF_EXPONENT_BIAS;
     const uint16_t uHalfSign             =  (uHalfPrecision & HALF_SIGN_MASK) >> HALF_SIGN_SHIFT;
-    
-    
+
+
     // Make the three parts of hte single-precision number
     uint64_t uDoubleSignificand, uDoubleSign, uDoubleBiasedExponent;
     if(nHalfUnBiasedExponent == HALF_EXPONENT_ZERO) {
@@ -436,8 +436,8 @@
         uDoubleSignificand    = (uint64_t)uHalfSignificand << (DOUBLE_NUM_SIGNIFICAND_BITS - HALF_NUM_SIGNIFICAND_BITS);
     }
     uDoubleSign = uHalfSign;
-    
-    
+
+
     // Shift the 3 parts into place as a double-precision
     const uint64_t uDouble = uDoubleSignificand |
                             (uDoubleBiasedExponent << DOUBLE_EXPONENT_SHIFT) |
@@ -450,12 +450,12 @@
 IEEE754_union IEEE754_FloatToSmallest(float f)
 {
     IEEE754_union result;
-    
+
     // Pull the neeed two parts out of the single-precision float
     const uint32_t uSingle = CopyFloatToUint32(f);
     const int32_t  nSingleExponent    = ((uSingle & SINGLE_EXPONENT_MASK) >> SINGLE_EXPONENT_SHIFT) - SINGLE_EXPONENT_BIAS;
     const uint32_t uSingleSignificand =   uSingle & SINGLE_SIGNIFICAND_MASK;
-    
+
     // Bit mask that is the significand bits that would be lost when converting
     // from single-precision to half-precision
     const uint64_t uDroppedSingleBits = SINGLE_SIGNIFICAND_MASK >> HALF_NUM_SIGNIFICAND_BITS;
@@ -478,7 +478,7 @@
         result.uSize = IEEE754_UNION_IS_SINGLE;
         result.uValue  = uSingle;
     }
-    
+
     return result;
 }
 
@@ -486,16 +486,16 @@
 IEEE754_union IEEE754_DoubleToSmallestInternal(double d, int bAllowHalfPrecision)
 {
     IEEE754_union result;
-    
+
     // Pull the needed two parts out of the double-precision float
     const uint64_t uDouble = CopyDoubleToUint64(d);
     const int64_t  nDoubleExponent     = ((uDouble & DOUBLE_EXPONENT_MASK) >> DOUBLE_EXPONENT_SHIFT) - DOUBLE_EXPONENT_BIAS;
     const uint64_t uDoubleSignificand  =   uDouble & DOUBLE_SIGNIFICAND_MASK;
-    
+
     // Masks to check whether dropped significand bits are zero or not
     const uint64_t uDroppedDoubleBits = DOUBLE_SIGNIFICAND_MASK >> HALF_NUM_SIGNIFICAND_BITS;
     const uint64_t uDroppedSingleBits = DOUBLE_SIGNIFICAND_MASK >> SINGLE_NUM_SIGNIFICAND_BITS;
-        
+
     // The various cases
     if(d == 0.0) { // Take care of positive and negative zero
         // Value is 0.0000, not a a subnormal
@@ -518,7 +518,7 @@
         result.uSize  = IEEE754_UNION_IS_DOUBLE;
         result.uValue = uDouble;
     }
-    
+
     return result;
 }
 
diff --git a/src/ieee754.h b/src/ieee754.h
index e6570c8..fc94646 100644
--- a/src/ieee754.h
+++ b/src/ieee754.h
@@ -1,5 +1,5 @@
 /*==============================================================================
- 
+
  Copyright (c) 2018, Laurence Lundblade.
  All rights reserved.
 
@@ -15,7 +15,7 @@
     * The name "Laurence Lundblade" may not be used to
       endorse or promote products derived from this software without
       specific prior written permission.
- 
+
 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
@@ -45,25 +45,25 @@
 
 /*
  General comments
- 
+
  This is a complete in that it handles all conversion cases
  including +/- infinity, +/- zero, subnormal numbers, qNaN, sNaN
  and NaN payloads.
- 
+
  This confirms to IEEE 754-2008, but note that this doesn't
  specify conversions, just the encodings.
- 
+
  NaN payloads are preserved with alignment on the LSB. The
  qNaN bit is handled differently and explicity copied. It
  is always the MSB of the significand. The NaN payload MSBs
  (except the qNaN bit) are truncated when going from
  double or single to half.
- 
+
  TODO: what does the C cast do with NaN payloads from
  double to single?
- 
- 
- 
+
+
+
  */
 
 /*
@@ -72,26 +72,26 @@
  these types and so does qcbor.  This encoder also supports
  half precision and there's a few ways to use it to encode
  floating point numbers in less space.
- 
+
  Without losing precision, you can encode a single or double
  such that the special values of 0, NaN and Infinity encode
  as half-precision.  This CBOR decodoer and most others
  should handle this properly.
- 
+
  If you don't mind losing precision, then you can use half-precision.
  One way to do this is to set up your environment to use
  ___fp_16. Some compilers and CPUs support it even though it is not
  standard C. What is nice about this is that your program
  will use less memory and floating point operations like
  multiplying, adding and such will be faster.
- 
+
  Another way to make use of half-precision is to represent
  the values in your program as single or double, but encode
  them in CBOR as half-precision. This cuts the size
  of the encoded messages by 2 or 4, but doesn't reduce
  memory needs or speed because you are still using
  single or double in your code.
- 
+
 
  encode:
     - float as float
@@ -101,10 +101,10 @@
  - double as half_precision, for environments that don't support a half-precision type
  - float with NaN, Infinity and 0 as half
  - double with NaN, Infinity and 0 as half
- 
- 
- 
- 
+
+
+
+
  */
 
 
diff --git a/src/ieee754.o b/src/ieee754.o
new file mode 100644
index 0000000..17c315e
--- /dev/null
+++ b/src/ieee754.o
Binary files differ
diff --git a/src/qcbor_decode.c b/src/qcbor_decode.c
index 8a1b151..b015dd8 100644
--- a/src/qcbor_decode.c
+++ b/src/qcbor_decode.c
@@ -2,7 +2,7 @@
  Copyright (c) 2016-2018, The Linux Foundation.
  Copyright (c) 2018, Laurence Lundblade.
  All rights reserved.
- 
+
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
 met:
@@ -16,7 +16,7 @@
       contributors, nor the name "Laurence Lundblade" may be used to
       endorse or promote products derived from this software without
       specific prior written permission.
- 
+
 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
@@ -32,14 +32,14 @@
 
 /*===================================================================================
  FILE:  qcbor_decode.c
- 
+
  DESCRIPTION:  This file contains the implementation of QCBOR.
- 
+
  EDIT HISTORY FOR FILE:
- 
+
  This section contains comments describing changes made to the module.
  Notice that changes are listed in reverse chronological order.
- 
+
  when               who             what, where, why
  --------           ----            ---------------------------------------------------
  11/9/18            llundblade      Error codes are now enums.
@@ -55,7 +55,7 @@
  11/13/16           llundbla        Integrate most TZ changes back into github version.
  09/30/16           gkanike         Porting to TZ.
  03/15/16           llundbla        Initial Version.
- 
+
  =====================================================================================*/
 
 #include "qcbor.h"
@@ -98,7 +98,7 @@
    if(!DecodeNesting_IsNested(pNesting)) {
       return 0;
    }
-   
+
    return CBOR_MAJOR_TYPE_MAP == pNesting->pCurrent->uMajorType;
 }
 
@@ -109,15 +109,15 @@
    if(!DecodeNesting_IsNested(pNesting)) {
       return QCBOR_ERR_BAD_BREAK;
    }
-   
+
    // breaks can only occur when the map/array is indefinite length
    if(!DecodeNesting_IsIndefiniteLength(pNesting)) {
       return QCBOR_ERR_BAD_BREAK;
    }
-   
+
    // if all OK, the break reduces the level of nesting
    pNesting->pCurrent--;
-   
+
    return QCBOR_SUCCESS;
 }
 
@@ -128,12 +128,12 @@
       // at top level where there is no tracking
       return;
    }
-   
+
    if(DecodeNesting_IsIndefiniteLength(pNesting)) {
       // There is no count for indefinite length arrays/maps
       return;
    }
-   
+
    // Decrement the count of items in this array/map
    pNesting->pCurrent->uCount--;
 
@@ -150,33 +150,33 @@
 inline static QCBORError DecodeNesting_Descend(QCBORDecodeNesting *pNesting, QCBORItem *pItem)
 {
    QCBORError nReturn = QCBOR_SUCCESS;
-   
+
    if(pItem->val.uCount == 0) {
       // Nothing to do for empty definite lenth arrays. They are just are
       // effectively the same as an item that is not a map or array
       goto Done;
       // Empty indefinite length maps and arrays are handled elsewhere
    }
-   
+
    // Error out if arrays is too long to handle
    if(pItem->val.uCount != UINT16_MAX && pItem->val.uCount > QCBOR_MAX_ITEMS_IN_ARRAY) {
       nReturn = QCBOR_ERR_ARRAY_TOO_LONG;
       goto Done;
    }
-   
+
    // Error out if nesting is too deep
    if(pNesting->pCurrent >= &(pNesting->pMapsAndArrays[QCBOR_MAX_ARRAY_NESTING])) {
       nReturn = QCBOR_ERR_ARRAY_NESTING_TOO_DEEP;
       goto Done;
    }
-   
+
    // The actual descend
    pNesting->pCurrent++;
-   
+
    // Record a few details for this nesting level
    pNesting->pCurrent->uMajorType = pItem->uDataType;
    pNesting->pCurrent->uCount     = pItem->val.uCount;
-   
+
 Done:
    return nReturn;;
 }
@@ -250,12 +250,12 @@
       // as all the values are known at compile time.
       return -1;
    }
-   
+
    if(uTag > UINT16_MAX) {
       // This tag map works only on 16-bit tags
       return -1;
    }
-   
+
    for(int nTagBitIndex = 0; nTagBitIndex < (int)(sizeof(spBuiltInTagMap)/sizeof(uint16_t)); nTagBitIndex++) {
       if(spBuiltInTagMap[nTagBitIndex] == uTag) {
          return nTagBitIndex;
@@ -271,15 +271,15 @@
          return nTagBitIndex + TAG_MAPPER_CUSTOM_TAGS_BASE_INDEX;
       }
    }
-   
+
    return -1; // Indicates no match
 }
 
 /*
   Find the tag bit index for a given tag value, or error out
- 
+
  This and the above functions could probably be optimized and made
- clearer and neater. 
+ clearer and neater.
  */
 static QCBORError TagMapper_Lookup(const QCBORTagListIn *pCallerConfiguredTagMap, uint64_t uTag, uint8_t *puTagBitIndex)
 {
@@ -289,7 +289,7 @@
       *puTagBitIndex = (uint8_t)nTagBitIndex;
       return QCBOR_SUCCESS;
    }
-   
+
    if(pCallerConfiguredTagMap) {
       if(pCallerConfiguredTagMap->uNumTags > QCBOR_MAX_CUSTOM_TAGS) {
          return QCBOR_ERR_TOO_MANY_TAGS;
@@ -302,7 +302,7 @@
          return QCBOR_SUCCESS;
       }
    }
-   
+
    return QCBOR_ERR_BAD_OPT_TAG;
 }
 
@@ -340,52 +340,52 @@
 
 /*
  This decodes the fundamental part of a CBOR data item, the type and number
- 
+
  This is the Counterpart to InsertEncodedTypeAndNumber().
- 
+
  This does the network->host byte order conversion. The conversion here
  also results in the conversion for floats in addition to that for
  lengths, tags and integer values.
- 
+
  This returns:
    pnMajorType -- the major type for the item
    puNumber -- the "number" which is used a the value for integers, tags and floats and length for strings and arrays
    puAdditionalInfo -- Pass this along to know what kind of float or if length is indefinite
- 
+
  */
 inline static QCBORError DecodeTypeAndNumber(UsefulInputBuf *pUInBuf, int *pnMajorType, uint64_t *puNumber, uint8_t *puAdditionalInfo)
 {
    // Stack usage: int/ptr 5 -- 40
    QCBORError nReturn;
-   
+
    // Get the initial byte that every CBOR data item has
    const uint8_t InitialByte = UsefulInputBuf_GetByte(pUInBuf);
-   
+
    // Break down the initial byte
    const uint8_t uTmpMajorType   = InitialByte >> 5;
    const uint8_t uAdditionalInfo = InitialByte & 0x1f;
-   
+
    // Get the integer that follows the major type. Do not know if this is a length, value, float or tag at this point
    // Also convert from network byte order.
    uint64_t uTmpValue;
    switch(uAdditionalInfo) {
-         
+
       case LEN_IS_ONE_BYTE:
          uTmpValue = UsefulInputBuf_GetByte(pUInBuf);
          break;
-         
+
       case LEN_IS_TWO_BYTES:
          uTmpValue = UsefulInputBuf_GetUint16(pUInBuf);
          break;
-         
+
       case LEN_IS_FOUR_BYTES:
          uTmpValue = UsefulInputBuf_GetUint32(pUInBuf);
          break;
-         
+
       case LEN_IS_EIGHT_BYTES:
          uTmpValue = UsefulInputBuf_GetUint64(pUInBuf);
          break;
-         
+
       case ADDINFO_RESERVED1: // reserved by CBOR spec
       case ADDINFO_RESERVED2: // reserved by CBOR spec
       case ADDINFO_RESERVED3: // reserved by CBOR spec
@@ -397,22 +397,22 @@
          uTmpValue = uAdditionalInfo;
          break;
    }
-   
+
    // If any of the UsefulInputBuf_Get calls fail we will get here with uTmpValue as 0.
    // There is no harm in this. This following check takes care of catching all of
-   // these errors. 
-   
+   // these errors.
+
    if(UsefulInputBuf_GetError(pUInBuf)) {
       nReturn = QCBOR_ERR_HIT_END;
       goto Done;
    }
-   
+
    // All successful if we got here.
    nReturn           = QCBOR_SUCCESS;
    *pnMajorType      = uTmpMajorType;
    *puNumber         = uTmpValue;
    *puAdditionalInfo = uAdditionalInfo;
-   
+
 Done:
    return nReturn;
 }
@@ -427,7 +427,7 @@
  more away from zero than positive.
  Stdint, as far as I can tell, uses two's compliment to represent
  negative integers.
- 
+
  See http://www.unix.org/whitepapers/64bit.html for reasons int isn't
  used here in any way including in the interface
  */
@@ -435,29 +435,29 @@
 {
    // Stack usage: int/ptr 1 -- 8
    QCBORError nReturn = QCBOR_SUCCESS;
-   
+
    if(nMajorType == CBOR_MAJOR_TYPE_POSITIVE_INT) {
       if (uNumber <= INT64_MAX) {
          pDecodedItem->val.int64 = (int64_t)uNumber;
          pDecodedItem->uDataType = QCBOR_TYPE_INT64;
-         
+
       } else {
          pDecodedItem->val.uint64 = uNumber;
          pDecodedItem->uDataType  = QCBOR_TYPE_UINT64;
-         
+
       }
    } else {
       if(uNumber <= INT64_MAX) {
          pDecodedItem->val.int64 = -uNumber-1;
          pDecodedItem->uDataType = QCBOR_TYPE_INT64;
-         
+
       } else {
          // C can't represent a negative integer in this range
          // so it is an error.  todo -- test this condition
          nReturn = QCBOR_ERR_INT_OVERFLOW;
       }
    }
-   
+
    return nReturn;
 }
 
@@ -498,18 +498,18 @@
 {
    // Stack usage: 0
    QCBORError nReturn = QCBOR_SUCCESS;
-   
+
    // uAdditionalInfo is 5 bits from the initial byte
    // compile time checks above make sure uAdditionalInfo values line up with uDataType values
    pDecodedItem->uDataType = uAdditionalInfo;
-   
+
    switch(uAdditionalInfo) {
       case ADDINFO_RESERVED1:  // 28
       case ADDINFO_RESERVED2:  // 29
       case ADDINFO_RESERVED3:  // 30
          nReturn = QCBOR_ERR_UNSUPPORTED;
          break;
-           
+
       case HALF_PREC_FLOAT:
          pDecodedItem->val.dfnum = IEEE754_HalfToDouble((uint16_t)uNumber);
          pDecodedItem->uDataType = QCBOR_TYPE_DOUBLE;
@@ -522,14 +522,14 @@
          pDecodedItem->val.dfnum = UsefulBufUtil_CopyUint64ToDouble(uNumber);
          pDecodedItem->uDataType = QCBOR_TYPE_DOUBLE;
          break;
-         
+
       case CBOR_SIMPLEV_FALSE: // 20
       case CBOR_SIMPLEV_TRUE:  // 21
       case CBOR_SIMPLEV_NULL:  // 22
       case CBOR_SIMPLEV_UNDEF: // 23
       case CBOR_SIMPLE_BREAK:  // 31
          break; // nothing to do
-         
+
       case CBOR_SIMPLEV_ONEBYTE: // 24
          if(uNumber <= CBOR_SIMPLE_BREAK) {
             // This takes out f8 00 ... f8 1f which should be encoded as e0 … f7
@@ -537,7 +537,7 @@
             goto Done;
          }
          // fall through intentionally
-         
+
       default: // 0-19
          pDecodedItem->uDataType   = QCBOR_TYPE_UKNOWN_SIMPLE;
          // DecodeTypeAndNumber will make uNumber equal to uAdditionalInfo when uAdditionalInfo is < 24
@@ -545,7 +545,7 @@
          pDecodedItem->val.uSimple = (uint8_t)uNumber;
          break;
    }
-   
+
 Done:
    return nReturn;
 }
@@ -559,7 +559,7 @@
 {
    // Stack usage: UsefulBuf 2, int/ptr 1  40
    QCBORError nReturn = QCBOR_SUCCESS;
-   
+
    const UsefulBufC Bytes = UsefulInputBuf_GetUsefulBuf(pUInBuf, uStrLen);
    if(UsefulBuf_IsNULLC(Bytes)) {
       // Failed to get the bytes for this string item
@@ -580,7 +580,7 @@
       pDecodedItem->val.string = Bytes;
    }
    pDecodedItem->uDataType  = (nMajorType == CBOR_MAJOR_TYPE_BYTE_STRING) ? QCBOR_TYPE_BYTE_STRING : QCBOR_TYPE_TEXT_STRING;
-   
+
 Done:
    return nReturn;
 }
@@ -595,7 +595,7 @@
    if(pDecodedItem->uDataType != QCBOR_TYPE_TEXT_STRING) {
       return QCBOR_ERR_BAD_OPT_TAG;
    }
-   
+
    const UsefulBufC Temp        = pDecodedItem->val.string;
    pDecodedItem->val.dateString = Temp;
    pDecodedItem->uDataType      = QCBOR_TYPE_DATE_STRING;
@@ -626,15 +626,15 @@
 {
    // Stack usage: 1
    QCBORError nReturn = QCBOR_SUCCESS;
-   
+
    pDecodedItem->val.epochDate.fSecondsFraction = 0;
-   
+
    switch (pDecodedItem->uDataType) {
-         
+
       case QCBOR_TYPE_INT64:
          pDecodedItem->val.epochDate.nSeconds = pDecodedItem->val.int64;
          break;
-         
+
       case QCBOR_TYPE_UINT64:
          if(pDecodedItem->val.uint64 > INT64_MAX) {
             nReturn = QCBOR_ERR_DATE_OVERFLOW;
@@ -642,7 +642,7 @@
          }
          pDecodedItem->val.epochDate.nSeconds = pDecodedItem->val.uint64;
          break;
-         
+
       case QCBOR_TYPE_DOUBLE:
          {
             const double d = pDecodedItem->val.dfnum;
@@ -654,13 +654,13 @@
             pDecodedItem->val.epochDate.fSecondsFraction = d - pDecodedItem->val.epochDate.nSeconds;
          }
          break;
-         
+
       default:
          nReturn = QCBOR_ERR_BAD_OPT_TAG;
          goto Done;
    }
    pDecodedItem->uDataType = QCBOR_TYPE_DATE_EPOCH;
-   
+
 Done:
    return nReturn;
 }
@@ -680,7 +680,7 @@
  This gets a single data item and decodes it including preceding optional tagging. This does not
  deal with arrays and maps and nesting except to decode the data item introducing them. Arrays and
  maps are handled at the next level up in GetNext().
- 
+
  Errors detected here include: an array that is too long to decode, hit end of buffer unexpectedly,
     a few forms of invalid encoded CBOR
  */
@@ -688,22 +688,22 @@
 {
    // Stack usage: int/ptr 3 -- 24
    QCBORError nReturn;
-   
+
    // Get the major type and the number. Number could be length of more bytes or the value depending on the major type
    // nAdditionalInfo is an encoding of the length of the uNumber and is needed to decode floats and doubles
    int      uMajorType;
    uint64_t uNumber;
    uint8_t  uAdditionalInfo;
-   
+
    nReturn = DecodeTypeAndNumber(pUInBuf, &uMajorType, &uNumber, &uAdditionalInfo);
-   
+
    // Error out here if we got into trouble on the type and number.
    // The code after this will not work if the type and number is not good.
    if(nReturn)
       goto Done;
-   
+
    memset(pDecodedItem, 0, sizeof(QCBORItem));
-   
+
    // At this point the major type and the value are valid. We've got the type and the number that
    // starts every CBOR data item.
    switch (uMajorType) {
@@ -711,7 +711,7 @@
       case CBOR_MAJOR_TYPE_NEGATIVE_INT: // Major type 1
          nReturn = DecodeInteger(uMajorType, uNumber, pDecodedItem);
          break;
-         
+
       case CBOR_MAJOR_TYPE_BYTE_STRING: // Major type 2
       case CBOR_MAJOR_TYPE_TEXT_STRING: // Major type 3
          if(uAdditionalInfo == LEN_IS_INDEFINITE) {
@@ -721,7 +721,7 @@
             nReturn = DecodeBytes(pAlloc, uMajorType, uNumber, pUInBuf, pDecodedItem);
          }
          break;
-         
+
       case CBOR_MAJOR_TYPE_ARRAY: // Major type 4
       case CBOR_MAJOR_TYPE_MAP:   // Major type 5
          // Record the number of items in the array or map
@@ -736,21 +736,21 @@
          }
          pDecodedItem->uDataType  = uMajorType; // C preproc #if above makes sure constants align
          break;
-         
+
       case CBOR_MAJOR_TYPE_OPTIONAL: // Major type 6, optional prepended tags
          pDecodedItem->val.uTagV = uNumber;
          pDecodedItem->uDataType = QCBOR_TYPE_OPTTAG;
          break;
-         
+
       case CBOR_MAJOR_TYPE_SIMPLE: // Major type 7, float, double, true, false, null...
          nReturn = DecodeSimple(uAdditionalInfo, uNumber, pDecodedItem);
          break;
-         
+
       default: // Should never happen because DecodeTypeAndNumber() should never return > 7
          nReturn = QCBOR_ERR_UNSUPPORTED;
          break;
    }
-   
+
 Done:
    return nReturn;
 }
@@ -761,7 +761,7 @@
  This layer deals with indefinite length strings. It pulls all the
  individual chunk items together into one QCBORItem using the
  string allocator.
- 
+
  Code Reviewers: THIS FUNCTION DOES A LITTLE POINTER MATH
  */
 static inline QCBORError GetNext_FullItem(QCBORDecodeContext *me, QCBORItem *pDecodedItem)
@@ -770,36 +770,36 @@
    QCBORError nReturn;
    QCBORStringAllocator *pAlloc = (QCBORStringAllocator *)me->pStringAllocator;
    UsefulBufC FullString = NULLUsefulBufC;
-   
+
    nReturn = GetNext_Item(&(me->InBuf), pDecodedItem, me->bStringAllocateAll ? pAlloc: NULL);
    if(nReturn) {
       goto Done;
    }
-   
+
    // To reduce code size by removing support for indefinite length strings, the
    // code in this function from here down can be eliminated. Run tests, except
    // indefinite length string tests, to be sure all is OK if this is removed.
-   
+
    // Only do indefinite length processing on strings
    if(pDecodedItem->uDataType != QCBOR_TYPE_BYTE_STRING && pDecodedItem->uDataType != QCBOR_TYPE_TEXT_STRING) {
       goto Done; // no need to do any work here on non-string types
    }
-   
+
    // Is this a string with an indefinite length?
    if(pDecodedItem->val.string.len != SIZE_MAX) {
       goto Done; // length is not indefinite, so no work to do here
    }
-   
+
    // Can't do indefinite length strings without a string allocator
    if(pAlloc == NULL) {
       nReturn = QCBOR_ERR_NO_STRING_ALLOCATOR;
       goto Done;
    }
-   
+
    // There is an indefinite length string to work on...
    // Track which type of string it is
    const uint8_t uStringType = pDecodedItem->uDataType;
-   
+
    // Loop getting chunk of indefinite string
    for(;;) {
       // Get item for next chunk
@@ -809,7 +809,7 @@
       if(nReturn) {
          break;  // Error getting the next chunk
       }
-      
+
       // See if it is a marker at end of indefinite length string
       if(StringChunkItem.uDataType == QCBOR_TYPE_BREAK) {
          // String is complete
@@ -817,14 +817,14 @@
          pDecodedItem->uDataAlloc = 1;
          break;
       }
-      
+
       // Match data type of chunk to type at beginning.
       // Also catches error of other non-string types that don't belong.
       if(StringChunkItem.uDataType != uStringType) {
          nReturn = QCBOR_ERR_INDEFINITE_STRING_CHUNK;
          break;
       }
-      
+
       // Alloc new buffer or expand previously allocated buffer so it can fit
       UsefulBuf NewMem = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext,
                                               UNCONST_POINTER(FullString.ptr),
@@ -834,17 +834,17 @@
          nReturn = QCBOR_ERR_STRING_ALLOCATE;
          break;
       }
-      
+
       // Copy new string chunk at the end of string so far.
       FullString = UsefulBuf_CopyOffset(NewMem, FullString.len, StringChunkItem.val.string);
    }
-   
+
 Done:
    if(pAlloc && nReturn && !UsefulBuf_IsNULLC(FullString)) {
       // Getting item failed, clean up the allocated memory
       (pAlloc->fFree)(pAlloc->pAllocaterContext, UNCONST_POINTER(FullString.ptr));
    }
-   
+
    return nReturn;
 }
 
@@ -867,31 +867,31 @@
       if(nReturn) {
          goto Done; // Error out of the loop
       }
-      
+
       if(pDecodedItem->uDataType != QCBOR_TYPE_OPTTAG) {
          // Successful exit from loop; maybe got some tags, maybe not
          pDecodedItem->uTagBits = uTagBits;
          break;
       }
-   
+
       uint8_t uTagBitIndex;
       // Tag was mapped, tag was not mapped, error with tag list
       switch(TagMapper_Lookup(me->pCallerConfiguredTagList, pDecodedItem->val.uTagV, &uTagBitIndex)) {
-            
+
          case QCBOR_SUCCESS:
             // Successfully mapped the tag
             uTagBits |= 0x01ULL << uTagBitIndex;
             break;
-            
+
          case QCBOR_ERR_BAD_OPT_TAG:
             // Tag is not recognized. Do nothing
             break;
-            
+
          default:
             // Error Condition
             goto Done;
       }
-      
+
       if(pTags) {
          // Caller wants all tags recorded in the provided buffer
          if(pTags->uNumUsed >= pTags->uNumAllocated) {
@@ -902,33 +902,33 @@
          pTags->uNumUsed++;
       }
    }
-   
+
    switch(pDecodedItem->uTagBits & TAG_MAPPER_FIRST_FOUR) {
       case 0:
          // No tags at all or none we know about. Nothing to do.
          // This is part of the pass-through path of this function
          // that will mostly be taken when decoding any item.
          break;
-         
+
       case QCBOR_TAGFLAG_DATE_STRING:
          nReturn = DecodeDateString(pDecodedItem);
          break;
-         
+
       case QCBOR_TAGFLAG_DATE_EPOCH:
          nReturn = DecodeDateEpoch(pDecodedItem);
          break;
-         
+
       case QCBOR_TAGFLAG_POS_BIGNUM:
       case QCBOR_TAGFLAG_NEG_BIGNUM:
          nReturn = DecodeBigNum(pDecodedItem);
          break;
-         
+
       default:
          // Encountering some mixed up CBOR like something that
          // is tagged as both a string and integer date.
          nReturn = QCBOR_ERR_BAD_OPT_TAG;
    }
-   
+
 Done:
    return nReturn;
 }
@@ -943,12 +943,12 @@
    QCBORError nReturn = GetNext_TaggedItem(me, pDecodedItem, pTags);
    if(nReturn)
       goto Done;
-   
+
    if(pDecodedItem->uDataType == QCBOR_TYPE_BREAK) {
       // Break can't be a map entry
       goto Done;
    }
-   
+
    if(me->uDecodeMode != QCBOR_DECODE_MODE_MAP_AS_ARRAY) {
       // In a map and caller wants maps decoded, not treated as arrays
 
@@ -960,7 +960,7 @@
          nReturn = GetNext_TaggedItem(me, pDecodedItem, pTags);
          if(nReturn)
             goto Done;
-         
+
          pDecodedItem->uLabelAlloc = LabelItem.uDataAlloc;
 
          if(LabelItem.uDataType == QCBOR_TYPE_TEXT_STRING) {
@@ -996,7 +996,7 @@
          pDecodedItem->val.uCount *= 2;
       }
    }
-   
+
 Done:
    return nReturn;
 }
@@ -1012,7 +1012,7 @@
    // The public entry point for fetching and parsing the next QCBORItem.
    // All the CBOR parsing work is here and in subordinate calls.
    QCBORError nReturn;
-   
+
    nReturn = GetNext_MapEntry(me, pDecodedItem, pTags);
    if(nReturn) {
       goto Done;
@@ -1024,11 +1024,11 @@
       nReturn = QCBOR_ERR_BAD_BREAK;
       goto Done;
    }
-   
+
    // Record the nesting level for this data item before processing any of
    // decrementing and descending.
    pDecodedItem->uNestingLevel = DecodeNesting_GetLevel(&(me->nesting));
-   
+
    // Process the item just received for descent or decrement, and
    // ascent if decrements are enough to close out a definite length array/map
    if(IsMapOrArray(pDecodedItem->uDataType)) {
@@ -1048,7 +1048,7 @@
    if(nReturn) {
       goto Done;
    }
-   
+
    // For indefinite length maps/arrays, looking at any and
    // all breaks that might terminate them. The equivalent
    // for definite length maps/arrays happens in
@@ -1076,12 +1076,12 @@
          }
       }
    }
-   
+
    // Tell the caller what level is next. This tells them what maps/arrays
    // were closed out and makes it possible for them to reconstruct
    // the tree with just the information returned by GetNext
    pDecodedItem->uNextNestLevel = DecodeNesting_GetLevel(&(me->nesting));
-   
+
 Done:
    return nReturn;
 }
@@ -1097,34 +1097,34 @@
  Decoding items is done in 5 layered functions, one calling the
  next one down. If a layer has no work to do for a particular item
  it returns quickly.
- 
+
  - QCBORDecode_GetNext -- The top layer manages the beginnings and
  ends of maps and arrays. It tracks descending into and ascending
  out of maps/arrays. It processes all breaks that terminate
  maps and arrays.
- 
+
  - GetNext_MapEntry -- This handles the combining of two
  items, the label and the data, that make up a map entry.
  It only does work on maps. It combines the label and data
  items into one labeled item.
- 
+
  - GetNext_TaggedItem -- This handles the type 6 tagged items.
  It accumulates all the tags and combines them with the following
  non-tagged item. If the tagged item is something that is understood
  like a date, the decoding of that item is invoked.
- 
+
  - GetNext_FullItem -- This assembles the sub items that make up
  an indefinte length string into one string item. It uses the
  string allocater to create contiguous space for the item. It
  processes all breaks that are part of indefinite length strings.
- 
+
  - GetNext_Item -- This gets and decodes the most atomic
  item in CBOR, the thing with an initial byte containing
  the major type.
- 
+
  Roughly this takes 300 bytes of stack for vars. Need to
  evaluate this more carefully and correctly.
- 
+
  */
 
 
@@ -1134,14 +1134,14 @@
 int QCBORDecode_IsTagged(QCBORDecodeContext *me, const QCBORItem *pItem, uint64_t uTag)
 {
    const QCBORTagListIn *pCallerConfiguredTagMap = me->pCallerConfiguredTagList;
-   
+
    uint8_t uTagBitIndex;
    // Do not care about errors in pCallerConfiguredTagMap here. They are
    // caught during GetNext() before this is called.
    if(TagMapper_Lookup(pCallerConfiguredTagMap, uTag, &uTagBitIndex)) {
       return 0;
    }
-   
+
    const uint64_t uTagBit = 0x01ULL << uTagBitIndex;
    return (uTagBit & pItem->uTagBits) != 0;
 }
@@ -1153,7 +1153,7 @@
 QCBORError QCBORDecode_Finish(QCBORDecodeContext *me)
 {
    int nReturn = QCBOR_SUCCESS;
-   
+
    // Error out if all the maps/arrays are not closed out
    if(DecodeNesting_IsNested(&(me->nesting))) {
       nReturn = QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN;
@@ -1164,7 +1164,7 @@
    if(UsefulInputBuf_BytesUnconsumed(&(me->InBuf))) {
       nReturn = QCBOR_ERR_EXTRA_BYTES;
    }
-   
+
 Done:
    // Call the destructor for the string allocator if there is one.
    // Always called, even if there are errors; always have to clean up
@@ -1174,34 +1174,34 @@
          (pAllocator->fDestructor)(pAllocator->pAllocaterContext);
       }
    }
-   
+
    return nReturn;
 }
 
 
 
-/* 
- 
+/*
+
 Decoder errors handled in this file
- 
+
  - Hit end of input before it was expected while decoding type and number QCBOR_ERR_HIT_END
-  
+
  - negative integer that is too large for C QCBOR_ERR_INT_OVERFLOW
- 
+
  - Hit end of input while decoding a text or byte string QCBOR_ERR_HIT_END
- 
+
  - Encountered conflicting tags -- e.g., an item is tagged both a date string and an epoch date QCBOR_ERR_UNSUPPORTED
-  
+
  - Encontered an array or mapp that has too many items QCBOR_ERR_ARRAY_TOO_LONG
- 
+
  - Encountered array/map nesting that is too deep QCBOR_ERR_ARRAY_NESTING_TOO_DEEP
- 
+
  - An epoch date > INT64_MAX or < INT64_MIN was encountered QCBOR_ERR_DATE_OVERFLOW
- 
+
  - The type of a map label is not a string or int QCBOR_ERR_MAP_LABEL_TYPE
- 
+
  - Hit end with arrays or maps still open -- QCBOR_ERR_EXTRA_BYTES
- 
+
  */
 
 
@@ -1211,7 +1211,7 @@
  This is a very primitive memory allocator. It does not track individual
  allocations, only a high-water mark. A free or reallotcation must be of
  the last chunk allocated.
- 
+
  All of this following code will get dead-stripped if QCBORDecode_SetMemPool()
  is not called.
  */
@@ -1226,14 +1226,14 @@
 
 /*
  Internal function for an allocation
- 
+
  Code Reviewers: THIS FUNCTION DOES POINTER MATH
  */
 static UsefulBuf MemPool_Alloc(void *ctx, void *pMem, size_t uNewSize)
 {
    MemPool *me      = (MemPool *)ctx;
    void    *pReturn = NULL;
-   
+
    if(pMem) {
       // Realloc case
       // This check will work even if uNewSize is a super-large value like UINT64_MAX
@@ -1249,7 +1249,7 @@
          me->pFree += uNewSize;
       }
    }
-   
+
    return (UsefulBuf){pReturn, uNewSize};
 }
 
@@ -1273,26 +1273,26 @@
    if(Pool.len < sizeof(MemPool)+1) {
       return QCBOR_ERR_BUFFER_TOO_SMALL;
    }
-   
+
    MemPool *pMP = (MemPool *)Pool.ptr;
-   
+
    // Fill in the "vtable"
    pMP->StringAllocator.fAllocate   = MemPool_Alloc;
    pMP->StringAllocator.fFree       = MemPool_Free;
    pMP->StringAllocator.fDestructor = NULL;
-   
+
    // Set up the pointers to the memory to be allocated
    pMP->pStart = (uint8_t *)Pool.ptr + sizeof(MemPool);
    pMP->pFree  = pMP->pStart;
    pMP->pEnd   = (uint8_t *)Pool.ptr + Pool.len;
-   
+
    // More book keeping of context
    pMP->StringAllocator.pAllocaterContext = pMP;
    me->pStringAllocator   = pMP;
-   
+
    // The flag indicating when to use the allocator
    me->bStringAllocateAll = bAllStrings;
-   
+
    return QCBOR_SUCCESS;
 }
 
@@ -1301,13 +1301,13 @@
  Extra little hook to make MemPool testing work right
  without adding any code size or overhead to non-test
  uses. This will get dead-stripped for non-test use.
- 
- This is not a public function. 
+
+ This is not a public function.
  */
 size_t MemPoolTestHook_GetPoolSize(void *ctx)
 {
    MemPool *me = (MemPool *)ctx;
-   
+
    return me->pEnd - me->pStart;
 }
 
diff --git a/src/qcbor_decode.o b/src/qcbor_decode.o
new file mode 100644
index 0000000..5db18c0
--- /dev/null
+++ b/src/qcbor_decode.o
Binary files differ
diff --git a/src/qcbor_decode_malloc.c b/src/qcbor_decode_malloc.c
index 33b5d6c..fae095a 100644
--- a/src/qcbor_decode_malloc.c
+++ b/src/qcbor_decode_malloc.c
@@ -1,12 +1,12 @@
 /*==============================================================================
- 
+
  Copyright (c) 2018, Laurence Lundblade.
  All rights reserved.
- 
+
  Redistribution and use in source and binary forms, with or without
  Copyright (c) 2018, Laurence Lundblade.
  All rights reserved.
- 
+
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
 met:
@@ -19,7 +19,7 @@
     * The name "Laurence Lundblade" may not be used to
       endorse or promote products derived from this software without
       specific prior written permission.
- 
+
 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
@@ -64,7 +64,7 @@
         pAllocaterContext->fDestructor = MemMallocDestructor;
         pAllocaterContext->pAllocaterContext = pAllocaterContext; // So that destructor can work.
     }
-    
+
     return pAllocaterContext;
 }
 
diff --git a/src/qcbor_decode_malloc.o b/src/qcbor_decode_malloc.o
new file mode 100644
index 0000000..cee53c1
--- /dev/null
+++ b/src/qcbor_decode_malloc.o
Binary files differ
diff --git a/src/qcbor_encode.c b/src/qcbor_encode.c
index a99da1f..f660d7c 100644
--- a/src/qcbor_encode.c
+++ b/src/qcbor_encode.c
@@ -2,7 +2,7 @@
  Copyright (c) 2016-2018, The Linux Foundation.
  Copyright (c) 2018, Laurence Lundblade.
  All rights reserved.
- 
+
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
 met:
@@ -16,7 +16,7 @@
       contributors, nor the name "Laurence Lundblade" may be used to
       endorse or promote products derived from this software without
       specific prior written permission.
- 
+
 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
@@ -32,14 +32,14 @@
 
 /*===================================================================================
  FILE:  qcbor_encode.c
- 
+
  DESCRIPTION:  This file contains the implementation of QCBOR.
- 
+
  EDIT HISTORY FOR FILE:
- 
+
  This section contains comments describing changes made to the module.
  Notice that changes are listed in reverse chronological order.
- 
+
  when               who             what, where, why
  --------           ----            ---------------------------------------------------
  11/29/18           llundblade      Rework to simpler handling of tags and labels.
@@ -47,14 +47,14 @@
  11/1/18            llundblade      Floating support.
  10/31/18           llundblade      Switch to one license that is almost BSD-3.
  09/28/18           llundblade      Added bstr wrapping feature for COSE implementation.
- 02/05/18           llundbla        Works on CPUs which require integer alignment. 
+ 02/05/18           llundbla        Works on CPUs which require integer alignment.
                                     Requires new version of UsefulBuf.
  07/05/17           llundbla        Add bstr wrapping of maps/arrays for COSE
  03/01/17           llundbla        More data types
  11/13/16           llundbla        Integrate most TZ changes back into github version.
  09/30/16           gkanike         Porting to TZ.
  03/15/16           llundbla        Initial Version.
- 
+
  =====================================================================================*/
 
 #include "qcbor.h"
@@ -69,13 +69,13 @@
  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 accumluates 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 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.
@@ -92,7 +92,7 @@
 inline static QCBORError Nesting_Increase(QCBORTrackNesting *pNesting, uint8_t uMajorType, uint32_t uPos)
 {
    QCBORError nReturn = QCBOR_SUCCESS;
-   
+
    if(pNesting->pCurrentNesting == &pNesting->pArrays[QCBOR_MAX_ARRAY_NESTING]) {
       // trying to open one too many
       nReturn = QCBOR_ERR_ARRAY_NESTING_TOO_DEEP;
@@ -115,7 +115,7 @@
    if(uAmount >= QCBOR_MAX_ITEMS_IN_ARRAY - pNesting->pCurrentNesting->uCount) {
       return QCBOR_ERR_ARRAY_TOO_LONG;
    }
-      
+
    pNesting->pCurrentNesting->uCount += uAmount;
    return QCBOR_SUCCESS;
 }
@@ -157,23 +157,23 @@
  context.  Once either of these errors is set they are never
  cleared. Only 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 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 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.
- 
+
  It is really tempting to not check for overflow on the count in the
  number of items in an array. It would save a lot of code, it is
  extremely unlikely that any one will every put 65,000 items in an
  array, and the only bad thing that would happen is the CBOR would be
  bogus.  Once we prove that is the only consequence, then we can make
  the change.
- 
+
  Since this does not parse any input, you could in theory remove all
  error checks in this code if you knew the caller called it
  correctly. Maybe someday CDDL or some such language will be able to
@@ -181,24 +181,24 @@
  correct. This could also automatically size some of the data
  structures like array/map nesting resulting in some good memory
  savings.
- 
+
  Errors returned here fall into three categories:
- 
+
  Sizes
    QCBOR_ERR_BUFFER_TOO_LARGE -- A buffer passed in > UINT32_MAX
    QCBOR_ERR_BUFFER_TOO_SMALL -- output buffer too small
- 
+
    QCBOR_ERR_ARRAY_NESTING_TOO_DEEP -- Too many opens without closes
    QCBOR_ERR_ARRAY_TOO_LONG -- Too many things added to an array/map
- 
+
  Nesting constructed incorrectly
    QCBOR_ERR_TOO_MANY_CLOSES -- more close calls than opens
    QCBOR_ERR_CLOSE_MISMATCH -- Type of close does not match open
    QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN -- Finish called without enough closes
- 
+
  Bad data
    QCBOR_ERR_BAD_SIMPLE -- Simple value integer not valid
- 
+
  */
 
 
@@ -221,50 +221,50 @@
 
 
 
-/* 
+/*
  All CBOR data items have a type and a number. The number 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 serveral uses for major type 7.
- 
+
  This function encodes the type and the number. There are several
  encodings for the number depending on how large it is and how it is
  used.
- 
- Every encoding of the type and number has at least one byte, the 
+
+ Every encoding of the type and number 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.h.
- 
+
  The remaining five bits, known as "additional information", and
  possibly more bytes encode the number. If the number 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 number 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 number in many ways with this
  representation.  This implementation always uses the smallest
  possible representation. This is also the suggestion made in the RFC
  for cannonical CBOR.
- 
+
  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 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 param makes sure that even
  if all the digits of a halft, float or double are 0 it is still correctly
  encoded in 2, 4 or 8 bytes.
- 
+
  */
 static void InsertEncodedTypeAndNumber(QCBOREncodeContext *me, uint8_t uMajorType, size_t uMinLen, uint64_t uNumber, size_t uPos)
 {
@@ -273,20 +273,20 @@
    // _generation_, not parsing c) a mistake will result in bad CBOR generation,
    // not a security vulnerability.
    uMajorType <<= 5;
-   
+
    if(uNumber > 0xffffffff || uMinLen >= 8) {
       UsefulOutBuf_InsertByte(&(me->OutBuf), uMajorType + LEN_IS_EIGHT_BYTES, uPos);
       UsefulOutBuf_InsertUint64(&(me->OutBuf), (uint64_t)uNumber, uPos+1);
-      
+
    } else if(uNumber > 0xffff || uMinLen >= 4) {
       UsefulOutBuf_InsertByte(&(me->OutBuf), uMajorType + LEN_IS_FOUR_BYTES, uPos);
       UsefulOutBuf_InsertUint32(&(me->OutBuf), (uint32_t)uNumber, uPos+1);
-      
+
    } else if (uNumber > 0xff || uMinLen>= 2) {
       // Between 0 and 65535
       UsefulOutBuf_InsertByte(&(me->OutBuf), uMajorType + LEN_IS_TWO_BYTES, uPos);
       UsefulOutBuf_InsertUint16(&(me->OutBuf), (uint16_t)uNumber, uPos+1);
-      
+
    } else if(uNumber >= 24) {
       // Between 0 and 255, but only between 24 and 255 is ever encoded here
       UsefulOutBuf_InsertByte(&(me->OutBuf), uMajorType + LEN_IS_ONE_BYTE, uPos);
@@ -301,7 +301,7 @@
 
 /*
  Append the type and number info to the end of the buffer.
- 
+
  See InsertEncodedTypeAndNumber() function above for details
 */
 inline static void AppendEncodedTypeAndNumber(QCBOREncodeContext *me, uint8_t uMajorType, uint64_t uNumber)
@@ -332,7 +332,7 @@
    if(me->uError == QCBOR_SUCCESS) {
       uint8_t      uMajorType;
       uint64_t     uValue;
-      
+
       if(nNum < 0) {
          uValue = (uint64_t)(-nNum - 1); // This is the way negative ints work in CBOR. -1 encodes as 0x00 with major type negative int.
          uMajorType = CBOR_MAJOR_TYPE_NEGATIVE_INT;
@@ -340,7 +340,7 @@
          uValue = (uint64_t)nNum;
          uMajorType = CBOR_MAJOR_TYPE_POSITIVE_INT;
       }
-      
+
       AppendEncodedTypeAndNumber(me, uMajorType, uValue);
       me->uError = Nesting_Increment(&(me->nesting), 1);
    }
@@ -350,9 +350,9 @@
 /*
  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.h
- 
+
  Does the work of adding some bytes to the CBOR output. Works for a
  byte and text strings, which are the same in in CBOR though they have
  different major types.  This is also used to insert raw
@@ -367,7 +367,7 @@
       // it is entirely impractical to create tokens bigger than 4GB in
       // contiguous RAM
       me->uError = QCBOR_ERR_BUFFER_TOO_LARGE;
-      
+
    } else {
       if(!me->uError) {
          // If it is not Raw CBOR, add the type and the length
@@ -377,10 +377,10 @@
             // type and number so the buffer being added goes to the
             // right place
          }
-         
+
          // Actually add the bytes
          UsefulOutBuf_AppendUsefulBuf(&(me->OutBuf), Bytes);
-         
+
          // Update the array counting if there is any nesting at all
          me->uError = Nesting_Increment(&(me->nesting), 1);
       }
@@ -402,7 +402,7 @@
 /*
  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.h
  */
 void QCBOREncode_AddType7(QCBOREncodeContext *me, size_t uSize, uint64_t uNum)
@@ -417,7 +417,7 @@
                                  uNum,                    // Bytes of the floating
                                  // point number as a uint
                                  UsefulOutBuf_GetEndPosition(&(me->OutBuf))); // end position for append
-      
+
       me->uError = Nesting_Increment(&(me->nesting), 1);
    }
 }
@@ -429,7 +429,7 @@
 void QCBOREncode_AddDouble(QCBOREncodeContext *me, double dNum)
 {
    const IEEE754_union uNum = IEEE754_DoubleToSmallest(dNum);
-   
+
    QCBOREncode_AddType7(me, uNum.uSize, uNum.uValue);
 }
 
@@ -437,7 +437,7 @@
 /*
  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 header qcbor.h
 */
 void QCBOREncode_OpenMapOrArray(QCBOREncodeContext *me, uint8_t uMajorType)
@@ -477,18 +477,18 @@
          // and never shrinks. UsefulOutBut itself also has defenses such that
          // it won't write were it should not even if given hostile input lengths
          const size_t uLenOfEncodedMapOrArray = uEndPosition - uInsertPosition;
-         
+
          // Length is number of bytes for a bstr and number of items a for map & array
          const size_t uLength = uMajorType == CBOR_MAJOR_TYPE_BYTE_STRING ?
                                     uLenOfEncodedMapOrArray : Nesting_GetCount(&(me->nesting));
-         
+
          // Actually insert
          InsertEncodedTypeAndNumber(me,
                                     uMajorType,       // major type bstr, array or map
                                     0,                // no minimum length for encoding
                                     uLength,          // either len of bstr or num items in array or map
                                     uInsertPosition); // position in out buffer
-         
+
          // 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
@@ -512,16 +512,16 @@
 QCBORError QCBOREncode_Finish(QCBOREncodeContext *me, UsefulBufC *pEncodedCBOR)
 {
    QCBORError uReturn = me->uError;
-   
+
    if(uReturn != QCBOR_SUCCESS) {
       goto Done;
    }
-   
+
    if (Nesting_IsInNest(&(me->nesting))) {
       uReturn = QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN;
       goto Done;
    }
-   
+
    if(UsefulOutBuf_GetError(&(me->OutBuf))) {
       // Stuff didn't fit in the buffer.
       // This check catches this condition for all the appends and inserts
@@ -534,7 +534,7 @@
    }
 
    *pEncodedCBOR = UsefulOutBuf_OutUBuf(&(me->OutBuf));
-   
+
 Done:
    return uReturn;
 }
@@ -546,13 +546,13 @@
 QCBORError QCBOREncode_FinishGetSize(QCBOREncodeContext *me, size_t *puEncodedLen)
 {
    UsefulBufC Enc;
-   
+
    QCBORError nReturn = QCBOREncode_Finish(me, &Enc);
-   
+
    if(nReturn == QCBOR_SUCCESS) {
       *puEncodedLen = Enc.len;
    }
-   
+
    return nReturn;
 }
 
@@ -561,7 +561,7 @@
 
 /*
  Notes on the code
- 
+
  CBOR Major Type     Public Function
  0                   QCBOREncode_AddUInt64
  0, 1                QCBOREncode_AddUInt64, QCBOREncode_AddInt64
@@ -569,9 +569,9 @@
  4, 5                QCBOREncode_OpenMapOrArray
  6                   QCBOREncode_AddTag
  7                   QCBOREncode_AddDouble, QCBOREncode_AddSimple
- 
+
  Object code sizes on X86 with LLVM compiler and -Os (Nov 27, 2018)
- 
+
  _QCBOREncode_Init   84
  _QCBOREncode_AddUInt64   76
  _QCBOREncode_AddInt64   87
@@ -582,23 +582,23 @@
  _QCBOREncode_CloseMapOrArray   181
  _InsertEncodedTypeAndNumber   480
  _QCBOREncode_Finish   72
- 
+
  Total is about 1.4KB (including FinishGetSize and AddTag and AddDouble)
- 
+
  _InsertEncodedTypeAndNumber is large because a lot of UsefulBuf
  code inlines into it including the conversion to network byte
  order. This could be optimized to at least half the size, but
  code would probably not be quite as clean.
- 
+
  _QCBOREncode_CloseMapOrArray is larger because it has a lot
  of nesting tracking to do and much of Nesting_ inlines
  into it. It probably can't be reduced much.
- 
+
  If the error returned by Nesting_Increment() can be ignored
  because the limit is so high and the consequence of exceeding
  is proved to be inconsequential, then a lot of if(me->uError)
  instance can be removed, saving some code.
- 
+
  */
 
 
diff --git a/src/qcbor_encode.o b/src/qcbor_encode.o
new file mode 100644
index 0000000..32117c3
--- /dev/null
+++ b/src/qcbor_encode.o
Binary files differ
diff --git a/test/UsefulBuf_Tests.c b/test/UsefulBuf_Tests.c
index 82f2da6..3ec2529 100644
--- a/test/UsefulBuf_Tests.c
+++ b/test/UsefulBuf_Tests.c
@@ -2,7 +2,7 @@
  Copyright (c) 2016-2018, The Linux Foundation.
  Copyright (c) 2018, Laurence Lundblade.
  All rights reserved.
- 
+
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
 met:
@@ -16,7 +16,7 @@
       contributors, nor the name "Laurence Lundblade" may be used to
       endorse or promote products derived from this software without
       specific prior written permission.
- 
+
 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
@@ -34,11 +34,11 @@
 
 
 /* Basic exercise...
-   
+
    Call all the main public functions.
- 
+
    Binary compare the result to the expected.
- 
+
    There is nothing adversarial in this test
  */
 const char * UOBTest_NonAdversarial()
@@ -46,16 +46,16 @@
    const char *szReturn = NULL;
 
    UsefulBuf_MAKE_STACK_UB(outbuf,50);
-   
+
    UsefulOutBuf UOB;
-   
+
    UsefulOutBuf_Init(&UOB, outbuf);
-   
+
    if(!UsefulOutBuf_AtStart(&UOB)) {
       szReturn = "Not at start";
       goto Done;
    }
-   
+
    // Put 7 bytes at beginning of buf
    UsefulOutBuf_AppendData(&UOB, "bluster", 7);
 
@@ -63,41 +63,41 @@
       szReturn = "At start";
       goto Done;
    }
-   
+
    // add a space to end
    UsefulOutBuf_AppendByte(&UOB, ' ');
-   
+
    // Add 5 bytes to the end
    UsefulBufC UBC = {"hunny", 5};
    UsefulOutBuf_AppendUsefulBuf(&UOB, UBC);
-   
+
    // Insert 9 bytes at the beginning, slide the previous stuff right
    UsefulOutBuf_InsertData(&UOB, "heffalump", 9, 0);
    UsefulOutBuf_InsertByte(&UOB, ' ', 9);
-   
+
    // Put 9 bytes in at position 10 -- just after "heffalump "
    UsefulBufC UBC2 = {"unbounce ", 9};
    UsefulOutBuf_InsertUsefulBuf(&UOB, UBC2, 10);
-   
+
    // Make it a null terminated string (because all the appends and inserts above not strcpy !)
    UsefulOutBuf_AppendByte(&UOB, '\0');
-   
-   
+
+
    UsefulBufC U = UsefulOutBuf_OutUBuf(&UOB);
-   
+
    const char *expected = "heffalump unbounce bluster hunny";
-   
+
    if(UsefulBuf_IsNULLC(U) || U.len-1 != strlen(expected) || strcmp(expected, U.ptr) || UsefulOutBuf_GetError(&UOB)) {
       szReturn = "OutUBuf";
    }
-   
+
    UsefulBuf_MAKE_STACK_UB(buf, 50);
    UsefulBufC Out =  UsefulOutBuf_CopyOut(&UOB, buf);
-   
+
    if(UsefulBuf_IsNULLC(Out) || Out.len-1 != strlen(expected) || strcmp(expected, Out.ptr)) {
       szReturn = "CopyOut";
    }
-   
+
 Done:
    return szReturn;
 }
@@ -108,26 +108,26 @@
     pUOB is the buffer to append too
     num is the amount to append
     expected is the expected return code, 0 or 1
- 
+
  returns 0 if test passed
- 
+
  */
 static int AppendTest(UsefulOutBuf *pUOB, size_t num, int expected)
 {
    //reset
    UsefulOutBuf_Reset(pUOB);
-   
+
    // check status first
    if(UsefulOutBuf_GetError(pUOB))
       return 1;
-   
+
    // append the bytes
    UsefulOutBuf_AppendData(pUOB, (const uint8_t *)"bluster", num);
-   
+
    // check error status after
    if(UsefulOutBuf_GetError(pUOB) != expected)
       return 1;
-   
+
    return 0;
 }
 
@@ -139,16 +139,16 @@
 {
    // reset
    UsefulOutBuf_Reset(pUOB);
-   
+
    // check
    if(UsefulOutBuf_GetError(pUOB))
       return 1;
-   
+
    UsefulOutBuf_InsertData(pUOB, (const uint8_t *)"bluster", num, pos);
-   
+
    if(UsefulOutBuf_GetError(pUOB) != expected)
       return 1;
-   
+
    return 0;
 }
 
@@ -158,28 +158,28 @@
    - around 0
    - around the buffer size
    - around MAX size_t
- 
- 
+
+
  Test these for the buffer size and the cursor, the insert amount, the append amount and the insert position
- 
+
  */
 
 const char *UOBTest_BoundaryConditionsTest()
 {
    UsefulBuf_MAKE_STACK_UB(outbuf,2);
-   
+
    UsefulOutBuf UOB;
-   
+
    UsefulOutBuf_Init(&UOB, outbuf);
 
    // append 0 byte to a 2 byte buffer --> success
    if(AppendTest(&UOB, 0, 0))
       return "Append 0 bytes failed";
-   
+
    // append 1 byte to a 2 byte buffer --> success
    if(AppendTest(&UOB, 1, 0))
       return "Append of 1 byte failed";
-   
+
    // append 2 byte to a 2 byte buffer --> success
    if(AppendTest(&UOB, 2, 0))
       return "Append to fill buffer failed";
@@ -191,53 +191,53 @@
    // append max size_t to a 2 byte buffer --> failure
    if(AppendTest(&UOB, SIZE_MAX, 1))
       return "Append of SIZE_MAX error not caught";
-   
+
    if(InsertTest(&UOB, 1, 0, 0))
       return "Insert 1 byte at start failed";
 
    if(InsertTest(&UOB, 2, 0, 0))
       return "Insert 2 bytes at start failed";
-   
+
    if(InsertTest(&UOB, 3, 0, 1))
       return "Insert overflow not caught";
-   
+
    if(InsertTest(&UOB, 1, 1, 1))
       return "Bad insertion point not caught";
-   
-   
+
+
    UsefulBuf_MAKE_STACK_UB(outBuf2,10);
-   
+
    UsefulOutBuf_Init(&UOB, outBuf2);
-   
+
    UsefulOutBuf_Reset(&UOB);
    // put data in the buffer
    UsefulOutBuf_AppendString(&UOB, "abc123");
-   
+
    UsefulOutBuf_InsertString(&UOB, "xyz*&^", 0);
-   
+
    if(!UsefulOutBuf_GetError(&UOB)) {
       return "insert with data should have failed";
    }
-   
+
 
    UsefulOutBuf_Init(&UOB, (UsefulBuf){NULL, SIZE_MAX - 5});
    UsefulOutBuf_AppendData(&UOB, "123456789", SIZE_MAX -6);
    if(UsefulOutBuf_GetError(&UOB)) {
       return "insert in huge should have succeeded";
    }
-   
+
    UsefulOutBuf_Init(&UOB, (UsefulBuf){NULL, SIZE_MAX - 5});
    UsefulOutBuf_AppendData(&UOB, "123456789", SIZE_MAX -5);
    if(UsefulOutBuf_GetError(&UOB)) {
       return "insert in huge should have succeeded";
    }
-   
+
    UsefulOutBuf_Init(&UOB, (UsefulBuf){NULL, SIZE_MAX - 5});
    UsefulOutBuf_AppendData(&UOB, "123456789", SIZE_MAX - 4);
    if(!UsefulOutBuf_GetError(&UOB)) {
       return "lengths near max size";
    }
-   
+
    return NULL;
 }
 
@@ -250,15 +250,15 @@
 const char *TestBasicSanity()
 {
    UsefulBuf_MAKE_STACK_UB(outbuf,10);
-   
+
    UsefulOutBuf UOB;
-   
+
    // First -- make sure that the room left function returns the right amount
    UsefulOutBuf_Init(&UOB, outbuf);
- 
+
    if(UsefulOutBuf_RoomLeft(&UOB) != 10)
       return "room left failed";
-   
+
    if(!UsefulOutBuf_WillItFit(&UOB, 9)) {
       return "it did not fit";
    }
@@ -266,27 +266,27 @@
    if(UsefulOutBuf_WillItFit(&UOB, 11)) {
       return "it should have not fit";
    }
-   
-   
+
+
    // Next -- make sure that the magic number checking is working right
    UOB.magic = 8888; // make magic bogus
-   
+
    UsefulOutBuf_AppendData(&UOB, (const uint8_t *)"bluster", 7);
-   
+
    if(!UsefulOutBuf_GetError(&UOB))
       return "magic corruption check failed";
-   
-   
-   
+
+
+
    // Next make sure that the valid data length check is working right
    UsefulOutBuf_Init(&UOB, outbuf);
-   
+
    UOB.data_len = UOB.UB.len+1; // make size bogus
-   
+
    UsefulOutBuf_AppendData(&UOB, (const uint8_t *)"bluster", 7);
    if(!UsefulOutBuf_GetError(&UOB))
       return "valid data check failed";
-   
+
    return NULL;
 }
 
@@ -295,11 +295,11 @@
 const char *UBMacroConversionsTest()
 {
    char *szFoo = "foo";
-   
+
    UsefulBufC Foo = UsefulBuf_FromSZ(szFoo);
    if(Foo.len != 3 || strncmp(Foo.ptr, szFoo, 3))
       return "SZToUsefulBufC failed";
-   
+
    UsefulBufC Too = UsefulBuf_FROM_SZ_LITERAL("Toooo");
    if(Too.len != 5 || strncmp(Too.ptr, "Toooo", 5))
       return "UsefulBuf_FROM_SZ_LITERAL failed";
@@ -308,13 +308,13 @@
    UsefulBufC Boo = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pB);
    if(Boo.len != 3 || strncmp(Boo.ptr, "Boo", 3))
      return "UsefulBuf_FROM_BYTE_ARRAY_LITERAL failed";
-   
+
    char *sz = "not const"; // some data for the test
    UsefulBuf B = (UsefulBuf){sz, sizeof(sz)};
    UsefulBufC BC = UsefulBuf_Const(B);
    if(BC.len != sizeof(sz) || BC.ptr != sz)
       return "UsefulBufConst failed";
-   
+
    return NULL;
 }
 
@@ -322,7 +322,7 @@
 const char *UBUtilTests()
 {
    UsefulBuf UB = NULLUsefulBuf;
-   
+
    if(!UsefulBuf_IsNULL(UB)){
       return "IsNull failed";
    }
@@ -330,64 +330,64 @@
    if(!UsefulBuf_IsEmpty(UB)){
       return "IsEmpty failed";
    }
-   
+
    if(!UsefulBuf_IsNULLOrEmpty(UB)) {
       return "IsNULLOrEmpty failed";
    }
-   
+
    const UsefulBufC UBC = UsefulBuf_Const(UB);
-   
+
    if(!UsefulBuf_IsNULLC(UBC)){
       return "IsNull const failed";
    }
-   
+
    if(!UsefulBuf_IsEmptyC(UBC)){
       return "IsEmptyC failed";
    }
-   
+
    if(!UsefulBuf_IsNULLOrEmptyC(UBC)){
       return "IsNULLOrEmptyC failed";
    }
-   
+
    const UsefulBuf UB2 = UsefulBuf_Unconst(UBC);
    if(!UsefulBuf_IsEmpty(UB2)) {
       return "Back to UB is Empty failed";
    }
-   
+
    UB.ptr = "x"; // just some valid pointer
-   
+
    if(UsefulBuf_IsNULL(UB)){
       return "IsNull failed";
    }
-   
+
    if(!UsefulBuf_IsEmptyC(UBC)){
       return "IsEmpty failed";
    }
-   
+
    // test the Unconst.
    if(UsefulBuf_Unconst(UBC).ptr != NULL) {
       return "Unconst failed";
    }
-   
+
    // Set 100 bytes of '+'; validated a few tests later
    UsefulBuf_MAKE_STACK_UB(Temp, 100);
    const UsefulBufC TempC = UsefulBuf_Set(Temp, '+');
-   
+
    // Try to copy into a buf that is too small and see failure
    UsefulBuf_MAKE_STACK_UB(Temp2, 99);
    if(!UsefulBuf_IsNULLC(UsefulBuf_Copy(Temp2, TempC))) {
       return "Copy should have failed";
    }
-   
+
    if(UsefulBuf_IsNULLC(UsefulBuf_CopyPtr(Temp2, "xx", 2))) {
       return "CopyPtr failed";
    }
-   
+
    UsefulBufC xxyy = UsefulBuf_CopyOffset(Temp2, 2, UsefulBuf_FROM_SZ_LITERAL("yy"));
    if(UsefulBuf_IsNULLC(xxyy)) {
       return "CopyOffset Failed";
    }
-   
+
    if(UsefulBuf_Compare(UsefulBuf_Head(xxyy, 3), UsefulBuf_FROM_SZ_LITERAL("xxy"))) {
       return "head failed";
    }
@@ -395,7 +395,7 @@
    if(UsefulBuf_Compare(UsefulBuf_Tail(xxyy, 1), UsefulBuf_FROM_SZ_LITERAL("xyy"))) {
       return "tail failed";
    }
-   
+
    if(!UsefulBuf_IsNULLC(UsefulBuf_Head(xxyy, 5))) {
       return "head should have failed";
    }
@@ -403,27 +403,27 @@
    if(!UsefulBuf_IsNULLC(UsefulBuf_Tail(xxyy, 5))) {
       return "tail should have failed";
    }
-   
+
    if(!UsefulBuf_IsNULLC(UsefulBuf_CopyOffset(Temp2, 100, UsefulBuf_FROM_SZ_LITERAL("yy")))) {
       return "Copy Offset should have failed";
    }
-   
+
    // Try to copy into a NULL/empty buf and see failure
    const UsefulBuf UBNull = NULLUsefulBuf;
    if(!UsefulBuf_IsNULLC(UsefulBuf_Copy(UBNull, TempC))) {
       return "Copy to NULL should have failed";
    }
-   
-   
+
+
    // Try to set a NULL/empty buf; nothing should happen
    UsefulBuf_Set(UBNull, '+'); // This will crash on failure
-   
+
    // Copy successfully to a buffer
    UsefulBuf_MAKE_STACK_UB(Temp3, 101);
    if(UsefulBuf_IsNULLC(UsefulBuf_Copy(Temp3, TempC))) {
       return "Copy should not have failed";
    }
-   
+
    static const uint8_t pExpected[] = {
       '+',  '+',  '+',  '+', '+',  '+',  '+', '+',  '+',  '+',
       '+',  '+',  '+',  '+', '+',  '+',  '+', '+',  '+',  '+',
@@ -441,12 +441,12 @@
    if(UsefulBuf_Compare(Expected, TempC)) {
       return "Set / Copy / Compare failed";
    }
-   
+
    // Compare two empties and expect success
    if(UsefulBuf_Compare(NULLUsefulBufC, NULLUsefulBufC)){
       return "Compare Empties failed";
    }
-   
+
    // Compare with empty and expect the first to be larger
    if(UsefulBuf_Compare(Expected, NULLUsefulBufC) <= 0){
       return "Compare with empty failed";
@@ -466,13 +466,13 @@
       '+',  '+',  '+',  '+', '+',  '+',  '+', '+',  '+',  ',',
    };
    const UsefulBufC ExpectedBigger = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpectedBigger);
-   
+
    // Expect -1 when the first arg is smaller
    if(UsefulBuf_Compare(Expected, ExpectedBigger) >= 0){
       return "Compare with bigger";
    }
 
-   
+
    static const uint8_t pExpectedSmaller[] = {
       '+',  '+',  '+',  '+', '+',  '+',  '+', '+',  '+',  '+',
       '+',  '+',  '+',  '+', '+',  '+',  '+', '+',  '+',  '+',
@@ -490,8 +490,8 @@
    if(UsefulBuf_Compare(Expected, ExpectedSmaller) <= 0){
       return "Compare with smaller";
    }
-   
-   
+
+
    static const uint8_t pExpectedLonger[] = {
       '+',  '+',  '+',  '+', '+',  '+',  '+', '+',  '+',  '+',
       '+',  '+',  '+',  '+', '+',  '+',  '+', '+',  '+',  '+',
@@ -505,13 +505,13 @@
       '+',  '+',  '+',  '+', '+',  '+',  '+', '+',  '+',  '+', '+'
    };
    const UsefulBufC ExpectedLonger = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpectedLonger);
-   
+
    // Expect -1 when the first arg is smaller
    if(UsefulBuf_Compare(Expected, ExpectedLonger) >= 0){
       return "Compare with longer";
    }
 
-   
+
    static const uint8_t pExpectedShorter[] = {
       '+',  '+',  '+',  '+', '+',  '+',  '+', '+',  '+',  '+',
       '+',  '+',  '+',  '+', '+',  '+',  '+', '+',  '+',  '+',
@@ -529,21 +529,21 @@
    if(UsefulBuf_Compare(Expected, ExpectedShorter) <= 0){
       return "Compare with shorter";
    }
-   
-   
+
+
    if(UsefulBuf_IsNULLC(UsefulBuf_Copy(Temp, NULLUsefulBufC))) {
       return "Copy null/empty failed";
    }
-   
+
    // Look for +++++... in +++++... and find it at the beginning
    if(0 != UsefulBuf_FindBytes(ExpectedLonger, ExpectedShorter)){
       return "Failed to find";
    }
-   
+
    // look for ++* in ....++* and find it at the end
    static const uint8_t pToFind[] = {'+', '+', '*'};
    const UsefulBufC ToBeFound = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pToFind);
-   
+
    if(97 != UsefulBuf_FindBytes(ExpectedSmaller, ToBeFound)){
       return "Failed to find 2";
    }
@@ -552,12 +552,12 @@
    if(SIZE_MAX != UsefulBuf_FindBytes(ExpectedBigger, ToBeFound)){
       return "Failed to not find";
    }
-   
+
    // Look for the whole buffer in itself and succeed.
    if(0 != UsefulBuf_FindBytes(ExpectedLonger, ExpectedLonger)){
       return "Failed to find 3";
    }
-   
+
    return NULL;
 }
 
@@ -565,40 +565,40 @@
 const char *  UIBTest_IntegerFormat()
 {
    UsefulOutBuf_MakeOnStack(UOB,100);
-   
+
    const uint32_t u32 = 0x0A0B0C0D; // from https://en.wikipedia.org/wiki/Endianness
    const uint64_t u64 = 1984738472938472;
    const uint16_t u16 = 40000;
    const uint8_t  u8 = 9;
    const float    f  = (float)314.15;
    const double   d  = 2.1e10;
-   
-   
+
+
    UsefulOutBuf_AppendUint32(&UOB, u32); // Also tests UsefulOutBuf_InsertUint64 and UsefulOutBuf_GetEndPosition
    UsefulOutBuf_AppendUint64(&UOB, u64); // Also tests UsefulOutBuf_InsertUint32
    UsefulOutBuf_AppendUint16(&UOB, u16); // Also tests UsefulOutBuf_InsertUint16
    UsefulOutBuf_AppendByte(&UOB, u8);
    UsefulOutBuf_AppendFloat(&UOB, f); // Also tests UsefulOutBuf_InsertFloat
    UsefulOutBuf_AppendDouble(&UOB, d); // Also tests UsefulOutBuf_InsertDouble
-   
+
    const UsefulBufC O = UsefulOutBuf_OutUBuf(&UOB);
    if(UsefulBuf_IsNULLC(O))
       return "Couldn't output integers";
-   
+
    // from https://en.wikipedia.org/wiki/Endianness
    const uint8_t pExpectedNetworkOrder[4] = {0x0A, 0x0B, 0x0C, 0x0D};
    if(memcmp(O.ptr, pExpectedNetworkOrder, 4)) {
       return "not in network order";
    }
-   
+
    UsefulInputBuf UIB;
-   
+
    UsefulInputBuf_Init(&UIB, O);
-   
+
    if(UsefulInputBuf_Tell(&UIB) != 0) {
       return "UsefulInputBuf_Tell failed";
    }
-   
+
    if(UsefulInputBuf_GetUint32(&UIB) != u32) {
       return "u32 out then in failed";
    }
@@ -620,7 +620,7 @@
 
    // Reset and go again for a few more tests
    UsefulInputBuf_Init(&UIB, O);
-   
+
    const UsefulBufC Four = UsefulInputBuf_GetUsefulBuf(&UIB, 4);
    if(UsefulBuf_IsNULLC(Four)) {
       return "Four is NULL";
@@ -628,7 +628,7 @@
    if(UsefulBuf_Compare(Four, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpectedNetworkOrder))) {
       return "Four compare failed";
    }
-   
+
    if(UsefulInputBuf_BytesUnconsumed(&UIB) != 23){
       return "Wrong number of unconsumed bytes";
    }
@@ -640,28 +640,28 @@
    if(UsefulInputBuf_BytesAvailable(&UIB, 24)){
       return "Wrong number of bytes available II";
    }
-   
+
    UsefulInputBuf_Seek(&UIB, 0);
-   
+
    if(UsefulInputBuf_GetError(&UIB)) {
       return "unexpected error after seek";
    }
-   
+
    const uint8_t *pGetBytes = (const uint8_t *)UsefulInputBuf_GetBytes(&UIB, 4);
    if(pGetBytes == NULL) {
       return "GetBytes returns NULL";
    }
-   
+
    if(memcmp(pGetBytes, pExpectedNetworkOrder, 4)) {
       return "Got wrong bytes";
    }
-   
+
    UsefulInputBuf_Seek(&UIB, 28);
 
    if(!UsefulInputBuf_GetError(&UIB)) {
       return "expected error after seek";
    }
-   
+
    return NULL;
 }
 
@@ -675,15 +675,15 @@
    if(UsefulBufUtil_CopyDoubleToUint64(4e-40F) != 0X37C16C2800000000ULL) {
       return "CopyDoubleToUint64 failed";
    }
-   
+
    if(UsefulBufUtil_CopyUint64ToDouble(0X37C16C2800000000ULL) != 4e-40F) {
       return "CopyUint64ToDouble failed";
    }
-   
+
    if(UsefulBufUtil_CopyUint32ToFloat(0x47800000) != 65536.0F) {
       return "CopyUint32ToFloat failed";
    }
-   
+
    return NULL;
 }
 
diff --git a/test/UsefulBuf_Tests.h b/test/UsefulBuf_Tests.h
index 649d6a8..976de62 100644
--- a/test/UsefulBuf_Tests.h
+++ b/test/UsefulBuf_Tests.h
@@ -2,7 +2,7 @@
  Copyright (c) 2016-2018, The Linux Foundation.
  Copyright (c) 2018, Laurence Lundblade.
  All rights reserved.
- 
+
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
 met:
@@ -16,7 +16,7 @@
       contributors, nor the name "Laurence Lundblade" may be used to
       endorse or promote products derived from this software without
       specific prior written permission.
- 
+
 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
diff --git a/test/UsefulBuf_Tests.o b/test/UsefulBuf_Tests.o
new file mode 100644
index 0000000..cf71175
--- /dev/null
+++ b/test/UsefulBuf_Tests.o
Binary files differ
diff --git a/test/float_tests.c b/test/float_tests.c
index 2b472f3..7bc23aa 100644
--- a/test/float_tests.c
+++ b/test/float_tests.c
@@ -3,7 +3,7 @@
 
  Copyright (c) 2018, Laurence Lundblade.
  All rights reserved.
- 
+
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
 met:
@@ -16,7 +16,7 @@
     * The name "Laurence Lundblade" may not be used to
       endorse or promote products derived from this software without
       specific prior written permission.
- 
+
 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
@@ -86,17 +86,17 @@
         0xF9, 0x7E, 0x0F,    // qNaN with payload 0x0f
         0x07,
         0xF9, 0x7C, 0x0F,    // sNaN with payload 0x0f
-    
+
 };
 
 
 int HalfPrecisionDecodeBasicTests()
 {
     UsefulBufC HalfPrecision = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spExpectedHalf);
-    
+
     QCBORDecodeContext DC;
     QCBORDecode_Init(&DC, HalfPrecision, 0);
-    
+
     QCBORItem Item;
 
     QCBORDecode_GetNext(&DC, &Item);
@@ -108,7 +108,7 @@
     if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != 0.0F) {
         return -2;
     }
-    
+
     QCBORDecode_GetNext(&DC, &Item);
     if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != INFINITY) {
         return -3;
@@ -128,7 +128,7 @@
     if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != 1.0F) {
         return -6;
     }
-    
+
     QCBORDecode_GetNext(&DC, &Item);
     if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != 0.333251953125F) {
         return -7;
@@ -143,7 +143,7 @@
     if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != INFINITY) {
         return -9;
     }
-    
+
     QCBORDecode_GetNext(&DC, &Item); // TODO: check this
     if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != 0.0000000596046448F) {
         return -10;
@@ -158,17 +158,17 @@
     if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != 0.0000610351563F) {
         return -12;
     }
-    
-    QCBORDecode_GetNext(&DC, &Item); 
+
+    QCBORDecode_GetNext(&DC, &Item);
     if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != 0) {
         return -13;
     }
-    
+
     QCBORDecode_GetNext(&DC, &Item);
     if(Item.uDataType != QCBOR_TYPE_DOUBLE || Item.val.dfnum != -2.0F) {
         return -14;
     }
-    
+
     // TODO: double check these four tests
     QCBORDecode_GetNext(&DC, &Item); // qNaN
     if(Item.uDataType != QCBOR_TYPE_DOUBLE || UsefulBufUtil_CopyDoubleToUint64(Item.val.dfnum) != 0x7ff8000000000000ULL) {
@@ -190,7 +190,7 @@
     if(QCBORDecode_Finish(&DC)) {
         return -19;
     }
-    
+
     return 0;
 }
 
@@ -204,12 +204,12 @@
         x[1] = uHalfP & 0xff;
         x[0] = uHalfP >> 8;
         double d = decode_half(x);
-        
+
         // Contruct the CBOR for the half-precision float by hand
         UsefulBuf_MAKE_STACK_UB(__xx, 3);
         UsefulOutBuf UOB;
         UsefulOutBuf_Init(&UOB, __xx);
-        
+
         const uint8_t uHalfPrecInitialByte = HALF_PREC_FLOAT + (CBOR_MAJOR_TYPE_SIMPLE << 5); // 0xf9
         UsefulOutBuf_AppendByte(&UOB, uHalfPrecInitialByte); // The initial byte for a half-precision float
         UsefulOutBuf_AppendUint16(&UOB, (uint16_t)uHalfP);
@@ -217,16 +217,16 @@
         // Now parse the hand-constructed CBOR. This will invoke the conversion to a float
         QCBORDecodeContext DC;
         QCBORDecode_Init(&DC, UsefulOutBuf_OutUBuf(&UOB), 0);
-        
+
         QCBORItem Item;
-        
+
         QCBORDecode_GetNext(&DC, &Item);
         if(Item.uDataType != QCBOR_TYPE_DOUBLE) {
             return -1;
         }
-        
+
         //printf("%04x  QCBOR:%15.15f  RFC: %15.15f (%8x)\n", uHalfP,Item.val.fnum, d , UsefulBufUtil_CopyFloatToUint32(d));
-        
+
         if(isnan(d)) {
             // The RFC code uses the native instructions which may or may not
             // handle sNaN, qNaN and NaN payloads correctly. This test just
@@ -315,11 +315,11 @@
 int DoubleAsSmallestTest()
 {
     UsefulBuf_MAKE_STACK_UB(EncodedHalfsMem, 420);
-    
+
 #define QCBOREncode_AddDoubleAsSmallestToMap QCBOREncode_AddDoubleToMap
 #define QCBOREncode_AddDoubleAsSmallestToMapN QCBOREncode_AddDoubleToMapN
 
-    
+
     QCBOREncodeContext EC;
     QCBOREncode_Init(&EC, EncodedHalfsMem);
     // These are mostly from https://en.wikipedia.org/wiki/Half-precision_floating-point_format
@@ -333,34 +333,34 @@
     //    7A65726F                          # "negative zero"
     // F9 8000                              # primitive(0)
     QCBOREncode_AddDoubleAsSmallestToMap(&EC, "negative zero", -0.00);
-    
+
     // 6A                                   # text(10)
     //    696E66696E6974697479              # "infinitity"
     // F9 7C00                              # primitive(31744)
     QCBOREncode_AddDoubleAsSmallestToMap(&EC, "infinitity", INFINITY);
-    
+
     // 73                                   # text(19)
     //    6E6567617469766520696E66696E6974697479 # "negative infinitity"
     // F9 FC00                              # primitive(64512)
     QCBOREncode_AddDoubleAsSmallestToMap(&EC, "negative infinitity", -INFINITY);
-    
+
     // 63                                   # text(3)
     //    4E614E                            # "NaN"
     // F9 7E00                              # primitive(32256)
     QCBOREncode_AddDoubleAsSmallestToMap(&EC, "NaN", NAN);
-    
+
     // TODO: test a few NaN variants
-    
+
     // 63                                   # text(3)
     //    6F6E65                            # "one"
     // F9 3C00                              # primitive(15360)
     QCBOREncode_AddDoubleAsSmallestToMap(&EC, "one", 1.0);
-    
+
     // 69                                   # text(9)
     //    6F6E65207468697264                # "one third"
     // F9 3555                              # primitive(13653)
     QCBOREncode_AddDoubleAsSmallestToMap(&EC, "one third", 0.333251953125);
-    
+
     // 76                                   # text(22)
     //    6C6172676573742068616C662D707265636973696F6E # "largest half-precision"
     // F9 7BFF                              # primitive(31743)
@@ -370,20 +370,20 @@
     //    6C6172676573742068616C662D707265636973696F6E # "largest half-precision"
     // F9 7BFF                              # primitive(31743)
     QCBOREncode_AddDoubleAsSmallestToMap(&EC, "largest half-precision point one",65504.1);
-    
+
     // Float 65536.0F is 0x47800000 in hex. It has an exponent of 16, which is larger than 15, the largest half-precision exponent
     // 78 18                                # text(24)
     //    746F6F2D6C617267652068616C662D707265636973696F6E # "too-large half-precision"
     // FA 47800000                          # primitive(31743)
     QCBOREncode_AddDoubleAsSmallestToMap(&EC, "too-large half-precision", 65536.0);
-    
+
     // The smallest possible half-precision subnormal, but digitis are lost converting
     // to half, so this turns into a double
     // 72                                   # text(18)
     //    736D616C6C657374207375626E6F726D616C # "smallest subnormal"
     // FB 3E700000001C5F68                  # primitive(4499096027744984936)
     QCBOREncode_AddDoubleAsSmallestToMap(&EC, "smallest subnormal", 0.0000000596046448);
-    
+
     // The smallest possible half-precision snormal, but digitis are lost converting
     // to half, so this turns into a single TODO: confirm this is right
     // 6F                                   # text(15)
@@ -391,22 +391,22 @@
     // FA 387FFFFF                          # primitive(947912703)
     // in hex single is 0x387fffff, exponent -15, significand 7fffff
     QCBOREncode_AddDoubleAsSmallestToMap(&EC, "smallest normal",    0.0000610351526F);
-    
+
     // 71                                   # text(17)
     //    62696767657374207375626E6F726D616C # "biggest subnormal"
     // F9 0400                              # primitive(1024)
     // in hex single is 0x38800000, exponent -14, significand 0
     QCBOREncode_AddDoubleAsSmallestToMap(&EC, "biggest subnormal",  0.0000610351563F);
-    
+
     // 70                                   # text(16)
     //    7375626E6F726D616C2073696E676C65  # "subnormal single"
     // FB 37C16C2800000000                  # primitive(4017611261645684736)
     QCBOREncode_AddDoubleAsSmallestToMap(&EC, "subnormal single", 4e-40F);
-    
+
     // 03                                   # unsigned(3)
     // F9 C000                              # primitive(49152)
     QCBOREncode_AddDoubleAsSmallestToMapN(&EC, 3, -2.0);
-    
+
     // 70                                   # text(16)
     //    6C617267652073696E676C6520657870  # "large single exp"
     // FA 7F400000                          # primitive(2134900736)
@@ -423,27 +423,27 @@
     //    646664666465                      # "dfdfde"
     // FA 4B800000                          # primitive(1266679808)
     QCBOREncode_AddDoubleAsSmallestToMap(&EC, "biggest single with prec",16777216); // Single with no precision loss
-    
+
     // 78 18                                # text(24)
     //    626967676573742073696E676C6520776974682070726563 # "biggest single with prec"
     // FA 4B800000                          # primitive(1266679808)
     QCBOREncode_AddDoubleAsSmallestToMap(&EC, "first single with prec loss",16777217); // Double becuase of precision loss
-    
+
     // Just a convenient marker when cutting and pasting encoded CBOR
     QCBOREncode_AddSZStringToMapN(&EC, 1, "fin");
 
     QCBOREncode_CloseMap(&EC);
-    
+
     UsefulBufC EncodedHalfs;
     int nReturn = QCBOREncode_Finish(&EC, &EncodedHalfs);
     if(nReturn) {
         return -1;
     }
-    
+
     if(UsefulBuf_Compare(EncodedHalfs, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spExpectedSmallest))) {
         return -3;
     }
-    
+
     return 0;
 }
 
@@ -474,20 +474,20 @@
     double dqNaN = UsefulBufUtil_CopyUint64ToDouble(DOUBLE_EXPONENT_MASK | DOUBLE_QUIET_NAN_BIT);
     double dsNaN = UsefulBufUtil_CopyUint64ToDouble(DOUBLE_EXPONENT_MASK | 0x01);
     double dqNaNPayload = UsefulBufUtil_CopyUint64ToDouble(DOUBLE_EXPONENT_MASK | DOUBLE_QUIET_NAN_BIT | 0xf00f);
-    
+
     float f1 = (float)dqNaN;
     float f2 = (float)dsNaN;
     float f3 = (float)dqNaNPayload;
-    
-    
+
+
     uint32_t uqNaN = UsefulBufUtil_CopyFloatToUint32((float)dqNaN);
     uint32_t usNaN = UsefulBufUtil_CopyFloatToUint32((float)dsNaN);
     uint32_t uqNaNPayload = UsefulBufUtil_CopyFloatToUint32((float)dqNaNPayload);
-    
+
     // Result of this on x86 is that every NaN is a qNaN. The intel
     // CVTSD2SS instruction ignores the NaN payload and even converts
     // a sNaN to a qNaN.
-    
+
     return 0;
 }
 #endif
diff --git a/test/float_tests.h b/test/float_tests.h
index 6bc0af1..ffd8aac 100644
--- a/test/float_tests.h
+++ b/test/float_tests.h
@@ -3,7 +3,7 @@
 
  Copyright (c) 2018, Laurence Lundblade.
  All rights reserved.
- 
+
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
 met:
@@ -16,7 +16,7 @@
     * The name "Laurence Lundblade" may not be used to
       endorse or promote products derived from this software without
       specific prior written permission.
- 
+
 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
diff --git a/test/float_tests.o b/test/float_tests.o
new file mode 100644
index 0000000..7cd2a48
--- /dev/null
+++ b/test/float_tests.o
Binary files differ
diff --git a/test/half_to_double_from_rfc7049.c b/test/half_to_double_from_rfc7049.c
index 68d03cb..6380e51 100644
--- a/test/half_to_double_from_rfc7049.c
+++ b/test/half_to_double_from_rfc7049.c
@@ -1,8 +1,8 @@
 /*
- 
+
  Copyright (c) 2013 IETF Trust and the persons identified as the
  document authors.  All rights reserved.
- 
+
  This document is subject to BCP 78 and the IETF Trust's Legal
  Provisions Relating to IETF Documents
  (http://trustee.ietf.org/license-info) in effect on the date of
@@ -12,7 +12,7 @@
  include Simplified BSD License text as described in Section 4.e of
  the Trust Legal Provisions and are provided without warranty as
  described in the Simplified BSD License.
- 
+
  */
 
 /*
@@ -20,13 +20,13 @@
  because:
    a) it adds a dependency on <math.h> and ldexp().
    b) the license may be an issue
- 
+
  QCBOR does support half-precision, but rather than using
  floating point math like this, it does it with bit shifting
  and masking.
- 
+
  This code is here to test that code.
- 
+
  */
 
 #include "half_to_double_from_rfc7049.h"
diff --git a/test/half_to_double_from_rfc7049.h b/test/half_to_double_from_rfc7049.h
index c8b2a06..a971c6c 100644
--- a/test/half_to_double_from_rfc7049.h
+++ b/test/half_to_double_from_rfc7049.h
@@ -1,11 +1,11 @@
 /*==============================================================================
- 
+
  Copyright (c) 2018, Laurence Lundblade.
  All rights reserved.
- 
+
  Copyright (c) 2018, Laurence Lundblade.
  All rights reserved.
- 
+
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
 met:
@@ -18,7 +18,7 @@
     * The name "Laurence Lundblade" may not be used to
       endorse or promote products derived from this software without
       specific prior written permission.
- 
+
 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
diff --git a/test/half_to_double_from_rfc7049.o b/test/half_to_double_from_rfc7049.o
new file mode 100644
index 0000000..84eac79
--- /dev/null
+++ b/test/half_to_double_from_rfc7049.o
Binary files differ
diff --git a/test/qcbor_decode_malloc_tests.c b/test/qcbor_decode_malloc_tests.c
index ea184b5..903f560 100644
--- a/test/qcbor_decode_malloc_tests.c
+++ b/test/qcbor_decode_malloc_tests.c
@@ -1,8 +1,8 @@
 /*==============================================================================
- 
+
  Copyright (c) 2018, Laurence Lundblade.
  All rights reserved.
- 
+
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
 met:
@@ -15,7 +15,7 @@
     * The name "Laurence Lundblade" may not be used to
       endorse or promote products derived from this software without
       specific prior written permission.
- 
+
 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
@@ -63,11 +63,11 @@
 int MallocAllStringsTest()
 {
     QCBORDecodeContext DC;
-    
+
     // Next parse, save pointers to a few strings, destroy original and see all is OK.
     UsefulBuf_MAKE_STACK_UB(CopyOfStorage, 160);
     const UsefulBufC CopyOf = UsefulBuf_Copy(CopyOfStorage, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pValidMapEncoded));
-    
+
     QCBORDecode_Init(&DC, CopyOf, QCBOR_DECODE_MODE_NORMAL);
     QCBORStringAllocator *pAlloc = QCBORDecode_MakeMallocStringAllocator();
     QCBORDecode_SetUpAllocator(&DC, pAlloc, true);
@@ -88,35 +88,35 @@
         return nCBORError;
     if((nCBORError = QCBORDecode_GetNext(&DC, &Item4)))
         return nCBORError;
-    
+
     UsefulBuf_Set(CopyOfStorage, '_');
-    
+
     if(Item1.uLabelType != QCBOR_TYPE_TEXT_STRING ||
        Item1.label.string.len != 13 ||
        Item1.uDataType != QCBOR_TYPE_INT64 ||
        Item1.val.int64 != 42 ||
        memcmp(Item1.label.string.ptr, "first integer", 13))
         return -1;
-    
+
     if(Item2.uLabelType != QCBOR_TYPE_TEXT_STRING ||
        Item2.label.string.len != 23 ||
        memcmp(Item2.label.string.ptr, "an array of two strings", 23) ||
        Item2.uDataType != QCBOR_TYPE_ARRAY ||
        Item2.val.uCount != 2)
         return -1;
-    
+
     if(Item3.uDataType != QCBOR_TYPE_TEXT_STRING ||
        Item3.val.string.len != 7 ||
        memcmp(Item3.val.string.ptr, "string1", 7))
         return -1;
-    
+
     if(Item4.uDataType != QCBOR_TYPE_TEXT_STRING ||
        Item4.val.string.len != 7 ||
        memcmp(Item4.val.string.ptr, "string2", 7))
         return -1;
-    
+
     (void)QCBORDecode_Finish(&DC);
-    
+
     free(UNCONST_POINTER(Item1.label.string.ptr));
     free(UNCONST_POINTER(Item2.label.string.ptr));
     free(UNCONST_POINTER(Item3.val.string.ptr));
diff --git a/test/qcbor_decode_malloc_tests.h b/test/qcbor_decode_malloc_tests.h
index 9682f26..c9a7da3 100644
--- a/test/qcbor_decode_malloc_tests.h
+++ b/test/qcbor_decode_malloc_tests.h
@@ -1,8 +1,8 @@
 /*==============================================================================
- 
+
  Copyright (c) 2018, Laurence Lundblade.
  All rights reserved.
- 
+
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
 met:
@@ -15,7 +15,7 @@
     * The name "Laurence Lundblade" may not be used to
       endorse or promote products derived from this software without
       specific prior written permission.
- 
+
 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
diff --git a/test/qcbor_decode_malloc_tests.o b/test/qcbor_decode_malloc_tests.o
new file mode 100644
index 0000000..3bec7b3
--- /dev/null
+++ b/test/qcbor_decode_malloc_tests.o
Binary files differ
diff --git a/test/qcbor_decode_tests.c b/test/qcbor_decode_tests.c
index 6e8f282..be84e65 100644
--- a/test/qcbor_decode_tests.c
+++ b/test/qcbor_decode_tests.c
@@ -2,7 +2,7 @@
  Copyright (c) 2016-2018, The Linux Foundation.
  Copyright (c) 2018, Laurence Lundblade.
  All rights reserved.
- 
+
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
 met:
@@ -16,7 +16,7 @@
       contributors, nor the name "Laurence Lundblade" may be used to
       endorse or promote products derived from this software without
       specific prior written permission.
- 
+
 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
@@ -43,7 +43,7 @@
    if(szLabel) {
       printf("%s ", szLabel);
    }
-   
+
    size_t i;
    for(i = 0; i < nLen; i++) {
       uint8_t Z = pEncoded[i];
@@ -89,7 +89,7 @@
 {
    QCBORItem          Item;
    int nCBORError;
-   
+
    if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_ARRAY)
@@ -106,165 +106,165 @@
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != -4294967297)
       return -1;
-   
+
    if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != -4294967296)
       return -1;
-   
+
    if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != -4294967295)
       return -1;
-   
+
    if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != -4294967294)
       return -1;
-   
-   
+
+
    if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != -2147483648)
       return -1;
-  
+
    if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != -2147483647)
       return -1;
-   
+
    if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != -65538)
       return  -1;
-   
+
    if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != -65537)
       return  -1;
-   
+
    if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != -65536)
       return  -1;
 
-   
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != -65535)
       return  -1;
 
-   
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != -65534)
       return  -1;
 
-   
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != -257)
       return  -1;
-   
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != -256)
       return  -1;
-   
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != -255)
       return  -1;
-   
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != -254)
       return  -1;
-   
-   
+
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != -25)
       return  -1;
 
-   
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != -24)
       return  -1;
 
-   
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != -23)
       return  -1;
 
-   
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != -1)
       return  -1;
 
-   
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != 0)
       return  -1;
 
-   
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != 0)
       return  -1;
-   
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != 1)
       return  -1;
 
-   
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != 22)
       return  -1;
 
-   
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != 23)
       return  -1;
 
-   
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != 24)
       return  -1;
 
-   
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
@@ -277,143 +277,143 @@
       Item.val.int64 != 26)
       return  -1;
 
-   
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != 254)
       return  -1;
-   
-   
+
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != 255)
       return  -1;
-   
-   
+
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != 256)
       return  -1;
 
-   
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != 257)
       return  -1;
-   
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != 65534)
       return  -1;
 
-   
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != 65535)
       return  -1;
 
-   
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != 65536)
       return  -1;
-   
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != 65537)
       return  -1;
-   
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != 65538)
       return  -1;
-   
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != 2147483647)
       return  -1;
-   
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != 2147483647)
       return  -1;
-   
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != 2147483648)
       return  -1;
-   
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != 2147483649)
       return  -1;
-  
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != 4294967294)
       return  -1;
-   
-   
+
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != 4294967295)
       return  -1;
-   
-   
+
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != 4294967296)
       return  -1;
-   
-   
+
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != 4294967297)
       return  -1;
 
-   
-   
+
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != 9223372036854775807LL)
       return  -1;
-   
-   
+
+
    if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_UINT64 ||
       Item.val.uint64 != 18446744073709551615ULL)
       return  -1;
-   
-   
+
+
    if(QCBORDecode_Finish(pDCtx) != QCBOR_SUCCESS) {
       return -1;
    }
-   
+
    return 0;
 }
 
 
-/* 
-   Tests the decoding of lots of different integers sizes 
+/*
+   Tests the decoding of lots of different integers sizes
    and values.
  */
 
@@ -421,31 +421,31 @@
 {
    int n;
    QCBORDecodeContext DCtx;
-   
+
    QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spExpectedEncodedInts), QCBOR_DECODE_MODE_NORMAL);
-   
+
    n = IntegerValuesParseTestInternal(&DCtx);
-   
+
    return(n);
 }
 
 
 /*
    Creates a simple CBOR array and returns it in *pEncoded. The array is malloced
-   and needs to be freed. This is used by several tests. 
- 
+   and needs to be freed. This is used by several tests.
+
    Two of the inputs can be set. Two other items in the array are fixed.
- 
+
  */
 
 static int CreateSimpleArray(int nInt1, int nInt2, uint8_t **pEncoded, size_t *pEncodedLen)
 {
    QCBOREncodeContext ECtx;
    int nReturn = -1;
-   
+
    *pEncoded = NULL;
    *pEncodedLen = INT32_MAX;
-   
+
    // loop runs CBOR encoding twice. First with no buffer to
    // calucate the length so buffer can be allocated correctly,
    // and last with the buffer to do the actual encoding
@@ -457,7 +457,7 @@
       QCBOREncode_AddBytes(&ECtx, ((UsefulBufC) {"galactic", 8}));
       QCBOREncode_AddBytes(&ECtx, ((UsefulBufC) {"haven token", 11}));
       QCBOREncode_CloseArray(&ECtx);
-      
+
       UsefulBufC Encoded;
       if(QCBOREncode_Finish(&ECtx, &Encoded))
          goto Done;
@@ -472,11 +472,11 @@
          nReturn = -1;
          goto Done;
       }
-      
+
    } while(1);
 Done:
    return (nReturn);
-   
+
 }
 
 
@@ -517,37 +517,37 @@
    QCBORDecodeContext DCtx;
    QCBORItem          Item;
    int                nReturn = -1; // assume error until success
-   
+
    QCBORDecode_Init(&DCtx, (UsefulBufC){pEncoded, nLen}, QCBOR_DECODE_MODE_NORMAL);
-   
+
    // Make sure the first thing is a map
    if(QCBORDecode_GetNext(&DCtx, &Item) != 0 || Item.uDataType != QCBOR_TYPE_ARRAY)
       goto Done;
-   
+
    // First integer
    if(QCBORDecode_GetNext(&DCtx, &Item) != 0 || Item.uDataType != QCBOR_TYPE_INT64)
       goto Done;
    *pInt1 = Item.val.int64;
-   
+
    // Second integer
    if(QCBORDecode_GetNext(&DCtx, &Item) != 0 || Item.uDataType != QCBOR_TYPE_INT64)
       goto Done;
    *pInt2 = Item.val.int64;
-   
+
    // First string
    if(QCBORDecode_GetNext(&DCtx, &Item) != 0 || Item.uDataType != QCBOR_TYPE_BYTE_STRING)
       goto Done;
    *pBuf3 = Item.val.string.ptr;
    *pBuf3Len = Item.val.string.len;
-   
+
    // Second string
    if(QCBORDecode_GetNext(&DCtx, &Item) != 0 || Item.uDataType != QCBOR_TYPE_BYTE_STRING)
       goto Done;
    *pBuf4 = Item.val.string.ptr;
    *pBuf4Len = Item.val.string.len;
-   
+
    nReturn = 0;
-   
+
 Done:
    return(nReturn);
 }
@@ -559,18 +559,18 @@
 {
    uint8_t *pEncoded;
    size_t  nEncodedLen;
-   
+
    int64_t i1, i2;
    size_t i3, i4;
    const uint8_t *s3, *s4;
-   
-   
+
+
    if(CreateSimpleArray(23, 6000, &pEncoded, &nEncodedLen) < 0) {
       return(-1);
    }
-   
+
    ParseOrderedArray(pEncoded, nEncodedLen, &i1, &i2, &s3, &i3, &s4, &i4);
-   
+
    if(i1 != 23 ||
       i2 != 6000 ||
       i3 != 8 ||
@@ -579,7 +579,7 @@
       memcmp("haven token", s4, 11) !=0) {
       return(-1);
    }
-   
+
    return(0);
 }
 
@@ -592,12 +592,12 @@
    QCBORDecodeContext DCtx;
    int nReturn = 0;
    int i;
-   
+
    QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spDeepArrays), QCBOR_DECODE_MODE_NORMAL);
-   
+
    for(i = 0; i < 10; i++) {
       QCBORItem Item;
-      
+
       if(QCBORDecode_GetNext(&DCtx, &Item) != 0 ||
          Item.uDataType != QCBOR_TYPE_ARRAY ||
          Item.uNestingLevel != i) {
@@ -605,7 +605,7 @@
          break;
       }
    }
-   
+
    return(nReturn);
 }
 
@@ -621,12 +621,12 @@
    int nReturn = 0;
    int i;
    QCBORItem Item;
-   
-   
+
+
    QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spTooDeepArrays), QCBOR_DECODE_MODE_NORMAL);
-   
+
    for(i = 0; i < QCBOR_MAX_ARRAY_NESTING1; i++) {
-      
+
       if(QCBORDecode_GetNext(&DCtx, &Item) != 0 ||
          Item.uDataType != QCBOR_TYPE_ARRAY ||
          Item.uNestingLevel != i) {
@@ -634,10 +634,10 @@
          break;
       }
    }
-   
+
    if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_ARRAY_NESTING_TOO_DEEP)
       nReturn = -1;
-   
+
    return(nReturn);
 }
 
@@ -649,16 +649,16 @@
    int nResult  = 0;
    QCBORDecodeContext DCtx;
    int num;
-   
+
    for(num = sizeof(spExpectedEncodedInts)-1; num; num--) {
       int n;
-      
+
       QCBORDecode_Init(&DCtx, (UsefulBufC){spExpectedEncodedInts, num}, QCBOR_DECODE_MODE_NORMAL);
-      
+
       n = IntegerValuesParseTestInternal(&DCtx);
-      
+
       //printf("Len %d, result: %d\n", num, n);
-      
+
       if(n != QCBOR_ERR_HIT_END) {
          nResult = -1;
          goto Done;
@@ -675,24 +675,24 @@
    uint8_t *pEncoded;
    int      nReturn;
    size_t   nEncodedLen;
-   
+
    int64_t i1, i2;
    size_t i3, i4;
    const uint8_t *s3, *s4;
-   
+
    nReturn = 0;
-   
+
    if(CreateSimpleArray(23, 6000, &pEncoded, &nEncodedLen) < 0) {
       return(-1);
    }
-   
+
    for(nEncodedLen--; nEncodedLen; nEncodedLen--) {
       int nResult = ParseOrderedArray(pEncoded, (uint32_t)nEncodedLen, &i1, &i2, &s3, &i3, &s4, &i4);
       if(nResult == 0) {
          nReturn = -1;
       }
    }
-   
+
    return(nReturn);
 }
 
@@ -705,16 +705,16 @@
    QCBORDecodeContext DCtx;
    QCBORItem Item;
    int nCBORError;
-   
+
    QCBORDecode_Init(&DCtx, (UsefulBufC){pValidMapEncoded, sizeof(pValidMapEncoded)}, nMode);
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
    if(Item.uDataType != QCBOR_TYPE_MAP ||
       Item.val.uCount != 3)
       return -1;
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -726,7 +726,7 @@
       UsefulBuf_Compare(Item.label.string, UsefulBuf_FromSZ("first integer"))) {
       return -1;
    }
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -737,7 +737,7 @@
       Item.uDataType != QCBOR_TYPE_ARRAY ||
       Item.val.uCount != 2)
       return -1;
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -747,7 +747,7 @@
       UsefulBuf_Compare(Item.val.string, UsefulBuf_FromSZ("string1"))) {
       return -1;
    }
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -757,7 +757,7 @@
       UsefulBuf_Compare(Item.val.string, UsefulBuf_FromSZ("string2"))) {
       return -1;
    }
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -769,7 +769,7 @@
       Item.val.uCount != 4) {
       return -1;
    }
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -781,7 +781,7 @@
       UsefulBuf_Compare(Item.val.string, UsefulBuf_FromSZ("xxxx"))) {
       return -1;
    }
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -793,7 +793,7 @@
       UsefulBuf_Compare(Item.val.string, UsefulBuf_FromSZ("yyyy"))) {
       return -1;
    }
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -804,7 +804,7 @@
       Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != 98)
       return -1;
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -816,7 +816,7 @@
       UsefulBuf_Compare(Item.val.string, UsefulBuf_FromSZ("lies, damn lies and statistics"))) {
       return -1;
    }
-   
+
    return 0;
 }
 
@@ -830,9 +830,9 @@
    QCBORDecodeContext DCtx;
    QCBORItem Item;
    int nCBORError;
-   
+
    QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pValidMapEncoded), QCBOR_DECODE_MODE_MAP_AS_ARRAY);
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -840,7 +840,7 @@
       Item.val.uCount != 6) {
       return -1;
    }
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -862,7 +862,7 @@
       Item.uLabelAlloc) {
       return -3;
    }
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -884,7 +884,7 @@
       Item.val.uCount != 2) {
       return -5;
    }
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -895,7 +895,7 @@
       UsefulBuf_Compare(Item.val.string, UsefulBuf_FromSZ("string1"))) {
       return -6;
    }
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -905,8 +905,8 @@
       UsefulBuf_Compare(Item.val.string, UsefulBuf_FromSZ("string2"))) {
       return -7;
    }
-   
-   
+
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -927,7 +927,7 @@
       Item.val.uCount != 8) {
       return -9;
    }
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -938,7 +938,7 @@
       Item.uLabelAlloc) {
       return -10;
    }
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -949,7 +949,7 @@
       UsefulBuf_Compare(Item.val.string, UsefulBuf_FromSZ("xxxx"))) {
       return -11;
    }
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -960,7 +960,7 @@
       Item.uLabelAlloc) {
       return -12;
    }
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -971,7 +971,7 @@
       UsefulBuf_Compare(Item.val.string, UsefulBuf_FromSZ("yyyy"))) {
       return -13;
    }
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -982,7 +982,7 @@
       Item.uDataType != QCBOR_TYPE_TEXT_STRING) {
       return -14;
    }
-  
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -993,7 +993,7 @@
       Item.val.int64 != 98) {
       return -15;
    }
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -1015,7 +1015,7 @@
       UsefulBuf_Compare(Item.val.string, UsefulBuf_FromSZ("lies, damn lies and statistics"))) {
       return -17;
    }
-   
+
    return 0;
 }
 
@@ -1024,10 +1024,10 @@
  Fully or partially decode pValidMapEncoded. When
  partially decoding check for the right error code.
  How much partial decoding depends on nLevel.
- 
+
  The partial decodes test error conditions of
  incomplete encoded input.
- 
+
  This could be combined with the above test
  and made prettier and maybe a little more
  thorough.
@@ -1037,9 +1037,9 @@
    QCBORDecodeContext DCtx;
    QCBORItem Item;
    int nCBORError;
-   
+
    QCBORDecode_Init(&DCtx, (UsefulBufC){pValidMapEncoded, sizeof(pValidMapEncoded)}, QCBOR_DECODE_MODE_NORMAL);
-   
+
    if(nLevel < 1) {
       if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_EXTRA_BYTES) {
          return -1;
@@ -1048,7 +1048,7 @@
       }
    }
 
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -1063,8 +1063,8 @@
          return 0;
       }
    }
-   
-   
+
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -1074,7 +1074,7 @@
       UsefulBuf_Compare(Item.label.string, UsefulBuf_FromSZ("first integer"))) {
       return -1;
    }
-   
+
    if(nLevel < 3) {
       if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
          return -1;
@@ -1082,7 +1082,7 @@
          return 0;
       }
    }
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -1092,8 +1092,8 @@
       Item.val.uCount != 2) {
       return -1;
    }
-   
-   
+
+
    if(nLevel < 4) {
       if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
          return -1;
@@ -1101,8 +1101,8 @@
          return 0;
       }
    }
-   
-   
+
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -1110,7 +1110,7 @@
       UsefulBuf_Compare(Item.val.string, UsefulBuf_FromSZ("string1"))) {
       return -1;
    }
-   
+
    if(nLevel < 5) {
       if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
          return -1;
@@ -1118,7 +1118,7 @@
          return 0;
       }
    }
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -1126,7 +1126,7 @@
       UsefulBuf_Compare(Item.val.string, UsefulBuf_FromSZ("string2"))) {
       return -1;
    }
- 
+
    if(nLevel < 6) {
       if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
          return -1;
@@ -1134,7 +1134,7 @@
          return 0;
       }
    }
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -1143,7 +1143,7 @@
       Item.uDataType != QCBOR_TYPE_MAP ||
       Item.val.uCount != 4)
       return -1;
-   
+
    if(nLevel < 7) {
       if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
          return -1;
@@ -1151,7 +1151,7 @@
          return 0;
       }
    }
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -1161,7 +1161,7 @@
       UsefulBuf_Compare(Item.val.string, UsefulBuf_FromSZ("xxxx"))) {
       return -1;
    }
-   
+
    if(nLevel < 8) {
       if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
          return -1;
@@ -1169,7 +1169,7 @@
          return 0;
       }
    }
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -1179,7 +1179,7 @@
       UsefulBuf_Compare(Item.val.string, UsefulBuf_FromSZ("yyyy"))) {
       return -1;
    }
-   
+
    if(nLevel < 9) {
       if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
          return -1;
@@ -1187,7 +1187,7 @@
          return 0;
       }
    }
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -1196,7 +1196,7 @@
       Item.uDataType != QCBOR_TYPE_INT64 ||
       Item.val.int64 != 98)
       return -1;
-   
+
    if(nLevel < 10) {
       if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
          return -1;
@@ -1204,7 +1204,7 @@
          return 0;
       }
    }
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return nCBORError;
    }
@@ -1214,11 +1214,11 @@
       UsefulBuf_Compare(Item.val.string, UsefulBuf_FromSZ("lies, damn lies and statistics"))) {
       return -1;
    }
-   
+
    if(QCBORDecode_Finish(&DCtx)) {
       return -1;
    }
-   
+
    return 0;
 }
 
@@ -1240,7 +1240,7 @@
          }
       }
    }
-   
+
    return(n);
 }
 
@@ -1252,17 +1252,17 @@
    QCBORDecodeContext DCtx;
    QCBORItem Item;
    int nCBORError;
-   
-   
+
+
    QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spSimpleValues), QCBOR_DECODE_MODE_NORMAL);
-   
-   
+
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_ARRAY ||
       Item.val.uCount != 10)
       return -1;
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_FALSE)
@@ -1272,12 +1272,12 @@
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_TRUE)
       return -1;
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_NULL)
       return -1;
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_UNDEF)
@@ -1299,25 +1299,25 @@
 
    if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_INVALID_CBOR)
       return -1;
-   
+
    if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_INVALID_CBOR)
       return -1;
 
    if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_INVALID_CBOR)
       return -1;
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_UKNOWN_SIMPLE || Item.val.uSimple != 32)
       return -1;
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
       return nCBORError;
    if(Item.uDataType != QCBOR_TYPE_UKNOWN_SIMPLE || Item.val.uSimple != 255)
       return -1;
-   
+
    return 0;
-   
+
 }
 
 
@@ -1357,16 +1357,16 @@
 int FailureTests()
 {
    int nResult = 0;
-   
+
    struct FailInput *pFEnd = &Failures[0] + sizeof(Failures)/sizeof(struct FailInput);
-   
+
    for(struct FailInput *pF = &Failures[0]; pF < pFEnd ;pF++) {
       QCBORDecodeContext DCtx;
       QCBORItem Item;
       int nCBORError;
-      
+
       QCBORDecode_Init(&DCtx, pF->Input, QCBOR_DECODE_MODE_NORMAL);
-      
+
       while(1) {
          nCBORError = QCBORDecode_GetNext(&DCtx, &Item);
          if(QCBOR_ERR_HIT_END == nCBORError) {
@@ -1378,12 +1378,12 @@
          }
       }
    }
-   
+
    {
       QCBORDecodeContext DCtx;
       QCBORItem Item;
       int nCBORError;
-      
+
       QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spSimpleValues), QCBOR_DECODE_MODE_NORMAL);
 
       if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
@@ -1391,15 +1391,15 @@
       if(Item.uDataType != QCBOR_TYPE_ARRAY ||
          Item.val.uCount != 10)
          return -1;
-      
+
       DCtx.InBuf.magic = 0; // Corrupt the UsefulInputBuf
-      
+
       nCBORError = QCBORDecode_GetNext(&DCtx, &Item);
       if(nCBORError != QCBOR_ERR_HIT_END)
          return -1;
    }
-   
-   
+
+
    return nResult;
 }
 
@@ -1408,24 +1408,24 @@
 
 static void Recurser(uint8_t *pBuf, int nLen, int nLenMax)
 {
-   
+
    if(nLen >= nLenMax) {
       return;
    }
 
    //printf("__%d__%d__\n", nLen, nLenMax);
-   
+
    for(int i = 0; i < 256; i++) {
       pBuf[nLen] = i;
-      
+
       QCBORDecodeContext DCtx;
       QCBORItem Item;
       int nCBORError;
-      
+
       const UsefulBufC Input = {pBuf, nLen+1};
-      
+
       QCBORDecode_Init(&DCtx, Input, QCBOR_DECODE_MODE_NORMAL);
-      
+
       while(1) {
          nCBORError =  QCBORDecode_GetNext(&DCtx, &Item);
          if(QCBOR_ERR_HIT_END == nCBORError) {
@@ -1438,14 +1438,14 @@
          }
       }
 
-   
+
       Recurser(pBuf, nLen+1, nLenMax);
    }
 }
 
 
 /*
- Runs all possible input strings of a given length. This is set to 3 to make the test 
+ Runs all possible input strings of a given length. This is set to 3 to make the test
  run in reasonable time.
  Main point of this test is to not crash.
  */
@@ -1453,16 +1453,16 @@
 int ComprehensiveInputTest()
 {
    uint8_t pBuf[3]; // 3 keeps it running in reasonable time. 4 takes tens of minutes.
-   
+
    Recurser(pBuf, 0, sizeof(pBuf));
-   
+
    return 0;
 }
 
 static uint8_t spDateTestInput[] = {
    0xc0, // tag for string date
    0x6a, '1','9','8','5','-','0','4','-','1','2', // Date string
-   
+
    0xc1, // tag for epoch date
    0x1a, 0x53, 0x72, 0x4E, 0x00, // Epoch date 1400000000; Tue, 13 May 2014 16:53:20 GMT
 
@@ -1472,10 +1472,10 @@
 
    0xc1, // tag for epoch date
    0x1b, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // Too large integer
-   
+
    0xc1, // tag for epoch date
    0xfa, 0x3f, 0x8c, 0xcc, 0xcd, // double with value 1.1
-   
+
    0xc1, // tag for epoch date
    0xfa, 0x7f, 0x7f, 0xff, 0xff // 3.4028234663852886e+38 too large
 
@@ -1484,11 +1484,11 @@
 
 // have to check float expected only to within an epsilon
 int CHECK_EXPECTED_DOUBLE(double val, double expected) {
-   
+
    double diff = val - expected;
-   
+
    diff = fabs(diff);
-   
+
    return diff > 0.0000001;
 }
 
@@ -1498,14 +1498,14 @@
    QCBORDecodeContext DCtx;
    QCBORItem Item;
    int nCBORError;
-   
+
    QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spDateTestInput), QCBOR_DECODE_MODE_NORMAL);
-   
+
    const uint64_t uTags[] = {15};
    QCBORTagListIn TagList = {1, uTags};
-      
+
    QCBORDecode_SetCallerConfiguredTagList(&DCtx, &TagList);
-   
+
    // String date
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
       return -1;
@@ -1522,7 +1522,7 @@
       Item.val.epochDate.fSecondsFraction != 0 ) {
       return -4;
    }
-   
+
    // Epoch date with extra CBOR_TAG_B64 tag that doesn't really mean anything
    // but want to be sure extra tag doesn't cause a problem
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
@@ -1533,12 +1533,12 @@
       !QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_B64)) {
       return -6;
    }
-   
+
    // Epoch date that is too large for our representation
    if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_DATE_OVERFLOW) {
       return -7;
    }
-   
+
    // Epoch date in float format with fractional seconds
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
       return -8;
@@ -1547,12 +1547,12 @@
       CHECK_EXPECTED_DOUBLE(Item.val.epochDate.fSecondsFraction, 0.1 )) {
       return -9;
    }
-   
+
    // Epoch date float that is too large for our representation
    if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_DATE_OVERFLOW) {
       return -10;
    }
-   
+
    // TODO: could use a few more tests with float, double, and half precsion and negative (but coverage is still pretty good)
 
    return 0;
@@ -1620,9 +1620,9 @@
 {
    QCBORDecodeContext DCtx;
    QCBORItem Item;
-   
+
    QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spOptTestInput), QCBOR_DECODE_MODE_NORMAL);
-   
+
    //-------------------------
    // This text matches the magic number tag and the fraction tag
    if(QCBORDecode_GetNext(&DCtx, &Item)) {
@@ -1632,7 +1632,7 @@
       !QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_CBOR_MAGIC)) {
       return -3;
    }
-   
+
    if(QCBORDecode_GetNext(&DCtx, &Item)) {
       return -4;
    }
@@ -1641,7 +1641,7 @@
       Item.val.uCount != 2) {
       return -5;
    }
-   
+
    // --------------------------------
    // This test decodes the very large tag, but it is not in
    // any list so it is ignored.
@@ -1652,14 +1652,14 @@
    if(Item.uTagBits) {
       return -7;
    }
-   
+
    // ----------------------------------
    // This test sets up a caller-config list that includes the very large tage and then matches it.
    QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spEncodedLargeTag), QCBOR_DECODE_MODE_NORMAL);
    const uint64_t puList[] = {0x9192939495969798, 257};
    const QCBORTagListIn TL = {2, puList};
    QCBORDecode_SetCallerConfiguredTagList(&DCtx, &TL);
-   
+
    if(QCBORDecode_GetNext(&DCtx, &Item)) {
       return -8;
    }
@@ -1670,7 +1670,7 @@
       Item.val.uCount != 0) {
       return -9;
    }
-   
+
    //------------------------
    // This test sets up a caller-configured list, and looks up something not in it
    const uint64_t puLongList[17] = {1,2,1};
@@ -1680,7 +1680,7 @@
    if(QCBORDecode_GetNext(&DCtx, &Item)) {
       return -11;
    }
-   
+
    // -----------------------
    // This tests retrievel of the full tag list
    QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spLotsOfTags), QCBOR_DECODE_MODE_NORMAL);
@@ -1695,7 +1695,7 @@
       puTags[3] != 0x04) {
       return -13;
    }
-   
+
    // ----------------------
    // This text if too small of an out list
    QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spLotsOfTags), QCBOR_DECODE_MODE_NORMAL);
@@ -1703,7 +1703,7 @@
    if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &OutSmall) != QCBOR_ERR_TOO_MANY_TAGS) {
       return -14;
    }
-   
+
    // ---------------
    // Parse a version of the "CSR" that has had a ton of tags randomly inserted
    QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRWithTags), QCBOR_DECODE_MODE_NORMAL);
@@ -1711,15 +1711,15 @@
    if(n) {
       return n-2000;
    }
-   
+
    Out = (QCBORTagListOut){0,16, puTags};
    QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRWithTags), QCBOR_DECODE_MODE_NORMAL);
-   
+
    const uint64_t puTagList[] = {773, 1, 90599561};
    const QCBORTagListIn TagList = {3, puTagList};
    QCBORDecode_SetCallerConfiguredTagList(&DCtx, &TagList);
-   
-   
+
+
    if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
       return -100;
    }
@@ -1734,7 +1734,7 @@
       Out.uNumUsed != 3) {
       return -101;
    }
-   
+
    if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
       return -102;
    }
@@ -1748,7 +1748,7 @@
       Out.uNumUsed != 2) {
       return -103;
    }
-   
+
    if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
       return -104;
    }
@@ -1759,7 +1759,7 @@
       Out.uNumUsed != 1) {
       return -105;
    }
-   
+
    if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
       return -106;
    }
@@ -1772,7 +1772,7 @@
       Out.uNumUsed != 3) {
       return -105;
    }
-   
+
    if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
       return -107;
    }
@@ -1783,7 +1783,7 @@
       Out.uNumUsed != 1) {
       return -108;
    }
-   
+
    if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
       return -109;
    }
@@ -1795,7 +1795,7 @@
       Out.uNumUsed != 12) {
       return -110;
    }
-   
+
    if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
       return -111;
    }
@@ -1806,7 +1806,7 @@
       Out.uNumUsed != 1) {
       return -112;
    }
-   
+
    if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
       return -111;
    }
@@ -1828,7 +1828,7 @@
       Out.uNumUsed != 1) {
       return -114;
    }
-   
+
    if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
       return -115;
    }
@@ -1861,7 +1861,7 @@
       Out.uNumUsed != 1) {
       return -119;
    }
-   
+
    if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
       return -120;
    }
@@ -1872,7 +1872,7 @@
       Out.uNumUsed != 1) {
       return -121;
    }
-   
+
    if(QCBORDecode_GetNextWithTags(&DCtx, &Item, &Out)) {
       return -122;
    }
@@ -1883,17 +1883,17 @@
       Out.uNumUsed != 1) {
       return -123;
    }
-   
+
    if(QCBORDecode_Finish(&DCtx)) {
       return -124;
    }
-   
+
    return 0;
 }
 
 
 
-   
+
 static uint8_t spBigNumInput[] = {
  0x83,
    0xC2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -1917,18 +1917,18 @@
    QCBORDecodeContext DCtx;
    QCBORItem Item;
    int nCBORError;
-   
+
    QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spBigNumInput), QCBOR_DECODE_MODE_NORMAL);
-   
-   
+
+
    //
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
       return -1;
    if(Item.uDataType != QCBOR_TYPE_ARRAY) {
       return -1;
    }
-   
-   // 
+
+   //
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
       return -1;
    if(Item.uDataType != QCBOR_TYPE_POSBIGNUM ||
@@ -1943,14 +1943,14 @@
       UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spBigNum))){
       return -1;
    }
-   
+
    //
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
       return -1;
    if(Item.uDataType != QCBOR_TYPE_MAP) {
       return -1;
    }
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
       return -1;
    if(Item.uDataType != QCBOR_TYPE_POSBIGNUM ||
@@ -1967,7 +1967,7 @@
       UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spBigNum))){
       return -1;
    }
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
       return -1;
    if(Item.uDataType != QCBOR_TYPE_NEGBIGNUM ||
@@ -1975,7 +1975,7 @@
       UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spBigNum))){
       return -1;
    }
-   
+
    if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
       return -1;
    if(Item.uDataType != QCBOR_TYPE_NEGBIGNUM ||
@@ -1984,7 +1984,7 @@
       UsefulBuf_Compare(Item.val.bigNum, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spBigNum))){
       return -1;
    }
-   
+
    return 0;
 }
 
@@ -1994,7 +1994,7 @@
 {
    QCBORItem Item;
    int nCBORError;
-   
+
    if((nCBORError = QCBORDecode_GetNext(pCtx, &Item))) return -1;
    if(Item.uDataType != uDataType) return -1;
    if(uNestingLevel > 0) {
@@ -2007,7 +2007,7 @@
    }
    if(Item.uNestingLevel != uNestingLevel) return -1;
    if(Item.uNextNestLevel != uNextNest) return -1;
-   
+
    if(pItem) {
       *pItem = Item;
    }
@@ -2019,28 +2019,28 @@
 static int CheckCSRMaps(QCBORDecodeContext *pDC)
 {
    if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 0, 1, 0, NULL)) return -1;
-   
+
    if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 1, 2, -23, NULL)) return -1;
-   
+
    if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 2, 3, -20, NULL)) return -1;
-   
+
    if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 3, -18, NULL)) return -1;
    if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 3, -17, NULL)) return -1;
    if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 3, -15, NULL)) return -1;
    if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 3, -16, NULL)) return -1;
    if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_TEXT_STRING, 3, 2, -14, NULL)) return -1;
-   
+
    if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 2, 3, -19, NULL)) return -1;
    if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 3, 4, -11, NULL)) return -1;
-   
+
    if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_INT64, 4, 3, -9, NULL)) return -1;
    if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_BYTE_STRING, 3, 1, -10, NULL)) return -1;
-   
+
    if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_MAP, 1, 2, -22, NULL)) return -1;
    if(CheckItemWithIntLabel(pDC, QCBOR_TYPE_INT64, 2, 0, -5, NULL)) return -1;
-   
+
    if(QCBORDecode_Finish(pDC)) return -2;
-   
+
    return 0;
 }
 
@@ -2084,9 +2084,9 @@
 int NestedMapTest()
 {
    QCBORDecodeContext DCtx;
-   
+
    QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRInput), QCBOR_DECODE_MODE_NORMAL);
-   
+
    return CheckCSRMaps(&DCtx);
 }
 
@@ -2095,19 +2095,19 @@
 int StringDecoderModeFailTest()
 {
    QCBORDecodeContext DCtx;
-   
+
    QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRInput), QCBOR_DECODE_MODE_MAP_STRINGS_ONLY);
-   
+
    QCBORItem Item;
    QCBORError nCBORError;
-   
+
    if(QCBORDecode_GetNext(&DCtx, &Item)) {
       return -1;
    }
    if(Item.uDataType != QCBOR_TYPE_MAP) {
       return -2;
    }
-   
+
    nCBORError = QCBORDecode_GetNext(&DCtx, &Item);
    if(nCBORError != QCBOR_ERR_MAP_LABEL_TYPE) {
       return -3;
@@ -2133,9 +2133,9 @@
 int NestedMapTestIndefLen()
 {
    QCBORDecodeContext DCtx;
-   
+
    QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRInputIndefLen), QCBOR_DECODE_MODE_NORMAL);
-   
+
    return CheckCSRMaps(&DCtx);
 }
 
@@ -2145,7 +2145,7 @@
 {
    UsefulOutBuf UOB;
    UsefulOutBuf_Init(&UOB, Storage);
-   
+
    int i;
    for(i = 0; i < n; i++) {
       UsefulOutBuf_AppendByte(&UOB, 0x9f);
@@ -2162,7 +2162,7 @@
 {
    QCBORDecodeContext DC;
    QCBORDecode_Init(&DC, Nested, 0);
-   
+
    int j;
    for(j = 0; j < nNestLevel; j++) {
       QCBORItem Item;
@@ -2196,7 +2196,7 @@
 {
    UsefulBuf_MAKE_STACK_UB(Storage, 50);
    int i;
-   for(i=1; i < QCBOR_MAX_ARRAY_NESTING+4; i++) { 
+   for(i=1; i < QCBOR_MAX_ARRAY_NESTING+4; i++) {
       const UsefulBufC Nested = make_nested_indefinite_arrays(i, Storage);
       int nReturn = parse_indeflen_nested(Nested, i);
       if(nReturn) {
@@ -2220,15 +2220,15 @@
    int nResult;
    // --- first test -----
     UsefulBufC IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteArray);
-   
+
     // Decode it and see if it is OK
     UsefulBuf_MAKE_STACK_UB(MemPool, 150);
     QCBORDecodeContext DC;
     QCBORItem Item;
     QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
-    
+
     QCBORDecode_SetMemPool(&DC, MemPool, false);
-        
+
     QCBORDecode_GetNext(&DC, &Item);
 
     if(Item.uDataType != QCBOR_TYPE_ARRAY ||
@@ -2236,64 +2236,64 @@
        Item.uNextNestLevel != 1) {
        return -111;
     }
-    
+
     QCBORDecode_GetNext(&DC, &Item);
     if(Item.uDataType != QCBOR_TYPE_INT64 ||
        Item.uNestingLevel != 1 ||
        Item.uNextNestLevel != 1) {
         return -2;
     }
-    
+
     QCBORDecode_GetNext(&DC, &Item);
     if(Item.uDataType != QCBOR_TYPE_ARRAY ||
        Item.uNestingLevel != 1 ||
        Item.uNextNestLevel != 2) {
         return -3;
     }
-    
+
     QCBORDecode_GetNext(&DC, &Item);
     if(Item.uDataType != QCBOR_TYPE_INT64 ||
        Item.uNestingLevel != 2 ||
        Item.uNextNestLevel != 2) {
         return -4;
     }
-    
+
     QCBORDecode_GetNext(&DC, &Item);
     if(Item.uDataType != QCBOR_TYPE_INT64 ||
        Item.uNestingLevel != 2 ||
        Item.uNextNestLevel != 0) {
         return -5;
     }
-    
+
     if(QCBORDecode_Finish(&DC)) {
         return -6;
     }
-   
+
    // --- next test -----
    IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteArrayBad1);
-   
+
    QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
-   
+
    QCBORDecode_SetMemPool(&DC, MemPool, false);
-   
+
    nResult = QCBORDecode_GetNext(&DC, &Item);
    if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
       return -7;
    }
-   
+
    nResult = QCBORDecode_Finish(&DC);
    if(nResult != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
       return -8;
    }
 
-   
+
    // --- next test -----
    IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteArrayBad2);
-   
+
    QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
-   
+
    QCBORDecode_SetMemPool(&DC, MemPool, false);
-   
+
    nResult = QCBORDecode_GetNext(&DC, &Item);
    if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
       return -9;
@@ -2303,75 +2303,75 @@
    if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
       return -10;
    }
-   
+
    nResult = QCBORDecode_GetNext(&DC, &Item);
    if(nResult || Item.uDataType != QCBOR_TYPE_INT64) {
       return -11;
    }
-   
+
    nResult = QCBORDecode_Finish(&DC);
    if(nResult != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
       return -12;
    }
-   
-   
+
+
    // --- next test -----
    IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteArrayBad3);
-   
+
    QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
-   
+
    QCBORDecode_SetMemPool(&DC, MemPool, false);
-   
+
    nResult = QCBORDecode_GetNext(&DC, &Item);
    if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
       return -13;
    }
-   
+
    nResult = QCBORDecode_GetNext(&DC, &Item);
    if(nResult != QCBOR_ERR_BAD_BREAK) {
       return -14;
    }
 
-   
+
    // --- next test -----
    IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteArrayBad4);
-   
+
    QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
-   
+
    QCBORDecode_SetMemPool(&DC, MemPool, false);
-   
+
    nResult = QCBORDecode_GetNext(&DC, &Item);
    if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
       return -15;
    }
-   
+
    nResult = QCBORDecode_GetNext(&DC, &Item);
    if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
       return -16;
    }
-   
+
    nResult = QCBORDecode_Finish(&DC);
    if(nResult != QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN) {
       return -17;
    }
-   
+
    // --- next test -----
    IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteArrayBad5);
-   
+
    QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
-   
+
    QCBORDecode_SetMemPool(&DC, MemPool, false);
-   
+
    nResult = QCBORDecode_GetNext(&DC, &Item);
    if(nResult || Item.uDataType != QCBOR_TYPE_ARRAY) {
       return -18;
    }
-   
+
    nResult = QCBORDecode_GetNext(&DC, &Item);
    if(nResult != QCBOR_ERR_BAD_BREAK) {
       return -19;
    }
-   
+
     return 0;
 }
 
@@ -2419,11 +2419,11 @@
 static UsefulBufC MakeIndefiniteBigBstr(UsefulBuf Storage)
 {
    UsefulOutBuf UOB;
-   
+
    UsefulOutBuf_Init(&UOB, Storage);
    UsefulOutBuf_AppendByte(&UOB, 0x81);
    UsefulOutBuf_AppendByte(&UOB, 0x5f);
-   
+
    int i = 0;
    for(int nChunkSize = 1; nChunkSize <= 128; nChunkSize *= 2) {
       UsefulOutBuf_AppendByte(&UOB, 0x58);
@@ -2443,7 +2443,7 @@
    if(BigString.len != 255) {
       return 1;
    }
-   
+
    for(uint8_t i = 0; i < 255; i++){
       if(((const uint8_t *)BigString.ptr)[i] != i) {
          return 1;
@@ -2459,22 +2459,22 @@
    QCBORItem Item;
    // big enough for MakeIndefiniteBigBstr() + MemPool overhead
    UsefulBuf_MAKE_STACK_UB(MemPool, 320);
-   
+
    // --- Simple normal indefinite length string ------
    UsefulBufC IndefLen = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteLenString);
    QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
-    
+
    if(QCBORDecode_SetMemPool(&DC, MemPool, false)) {
       return -1;
    }
-    
+
    if(QCBORDecode_GetNext(&DC, &Item)) {
       return -2;
    }
    if(Item.uDataType != QCBOR_TYPE_ARRAY || Item.uDataAlloc) {
       return -3;
    }
-    
+
    if(QCBORDecode_GetNext(&DC, &Item)) {
       return -4;
    }
@@ -2487,70 +2487,70 @@
 
    // ----- types mismatch ---
    QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteLenStringBad2), QCBOR_DECODE_MODE_NORMAL);
-   
+
    if(QCBORDecode_SetMemPool(&DC,  MemPool, false)) {
       return -7;
    }
-   
+
    if(QCBORDecode_GetNext(&DC, &Item)) {
       return -8;
    }
    if(Item.uDataType != QCBOR_TYPE_ARRAY) {
       return -9;
    }
-   
+
    if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_INDEFINITE_STRING_CHUNK) {
       return -10;
    }
 
    // ----- not a string ---
    QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteLenStringBad3), QCBOR_DECODE_MODE_NORMAL);
-   
+
    if(QCBORDecode_SetMemPool(&DC,  MemPool, false)) {
       return -11;
    }
-   
+
    if(QCBORDecode_GetNext(&DC, &Item)) {
       return -12;
    }
    if(Item.uDataType != QCBOR_TYPE_ARRAY) {
       return -13;
    }
-   
+
    if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_INDEFINITE_STRING_CHUNK) {
       return -14;
    }
 
    // ----- no end -----
    QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteLenStringBad4), QCBOR_DECODE_MODE_NORMAL);
-   
+
    if(QCBORDecode_SetMemPool(&DC,  MemPool, false)) {
       return -15;
    }
-   
+
    if(QCBORDecode_GetNext(&DC, &Item)) {
       return -16;
    }
    if(Item.uDataType != QCBOR_TYPE_ARRAY) {
       return -17;
    }
-   
+
    if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_HIT_END) {
       return -18;
    }
-   
+
    // ------ Don't set a string allocator and see an error -----
    QCBORDecode_Init(&DC, IndefLen, QCBOR_DECODE_MODE_NORMAL);
-   
+
    QCBORDecode_GetNext(&DC, &Item);
    if(Item.uDataType != QCBOR_TYPE_ARRAY) {
       return -19;
    }
-   
+
    if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_NO_STRING_ALLOCATOR) {
       return -20;
    }
-   
+
    // ----- Mempool is way too small -----
    UsefulBuf_MAKE_STACK_UB(MemPoolTooSmall, 20); // 20 is too small no matter what
 
@@ -2558,18 +2558,18 @@
    if(!QCBORDecode_SetMemPool(&DC,  MemPoolTooSmall, false)) {
       return -21;
    }
-   
+
    // ----- Mempool is way too small -----
    UsefulBuf_MAKE_STACK_UB(BigIndefBStrStorage, 290);
    const UsefulBufC BigIndefBStr = MakeIndefiniteBigBstr(BigIndefBStrStorage);
-   
+
    UsefulBuf_MAKE_STACK_UB(MemPoolSmall, 80); // 80 is big enough for MemPool overhead, but not BigIndefBStr
-   
+
    QCBORDecode_Init(&DC, BigIndefBStr, QCBOR_DECODE_MODE_NORMAL);
    if(QCBORDecode_SetMemPool(&DC,  MemPoolSmall, false)) {
       return -22;
    }
-   
+
    QCBORDecode_GetNext(&DC, &Item);
    if(Item.uDataType != QCBOR_TYPE_ARRAY) {
       return -23;
@@ -2577,21 +2577,21 @@
    if(QCBORDecode_GetNext(&DC, &Item) != QCBOR_ERR_STRING_ALLOCATE) {
       return -24;
    }
-   
+
    // ---- big bstr -----
    QCBORDecode_Init(&DC, BigIndefBStr, QCBOR_DECODE_MODE_NORMAL);
-   
+
    if(QCBORDecode_SetMemPool(&DC,  MemPool, false)) {
       return -25;
    }
-   
+
    if(QCBORDecode_GetNext(&DC, &Item)) {
       return -26;
    }
    if(Item.uDataType != QCBOR_TYPE_ARRAY || Item.uDataAlloc) {
       return -26;
    }
-   
+
    if(QCBORDecode_GetNext(&DC, &Item)) {
       return -27;
    }
@@ -2604,19 +2604,19 @@
    if(QCBORDecode_Finish(&DC)) {
       return -29;
    }
-   
+
    // --- label is an indefinite length string ------
    QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spIndefiniteLenStringLabel), QCBOR_DECODE_MODE_NORMAL);
-   
+
    if(QCBORDecode_SetMemPool(&DC,  MemPool, false)) {
       return -30;
    }
-   
+
    QCBORDecode_GetNext(&DC, &Item);
    if(Item.uDataType != QCBOR_TYPE_MAP) {
       return -31;
    }
-   
+
    if(QCBORDecode_GetNext(&DC, &Item)){
       return -32;
    }
@@ -2625,11 +2625,11 @@
       UsefulBuf_Compare(Item.label.string, UsefulBuf_FromSZ("struuming"))) {
       return -33;
    }
-   
+
    if(QCBORDecode_Finish(&DC)) {
       return -34;
    }
-   
+
     return 0;
 }
 
@@ -2637,25 +2637,25 @@
 int AllocAllStringsTest()
 {
    QCBORDecodeContext DC;
-   
+
    // First test, use the "CSRMap" as easy input and checking
    QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spCSRInput), QCBOR_DECODE_MODE_NORMAL);
-   
+
    UsefulBuf_MAKE_STACK_UB(Pool, 300);
-   
+
    QCBORDecode_SetMemPool(&DC, Pool, 1); // Turn on copying.
-   
+
    if(CheckCSRMaps(&DC)) {
       return -1;
    }
-   
+
    // Next parse, save pointers to a few strings, destroy original and see all is OK.
    UsefulBuf_MAKE_STACK_UB(CopyOfStorage, 160);
    const UsefulBufC CopyOf = UsefulBuf_Copy(CopyOfStorage, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pValidMapEncoded));
 
    QCBORDecode_Init(&DC, CopyOf, QCBOR_DECODE_MODE_NORMAL);
    QCBORDecode_SetMemPool(&DC, Pool, 1); // Turn on copying.
-   
+
    int nCBORError;
    QCBORItem Item1, Item2, Item3, Item4;
    if((nCBORError = QCBORDecode_GetNext(&DC, &Item1)))
@@ -2671,33 +2671,33 @@
       return nCBORError;
    if((nCBORError = QCBORDecode_GetNext(&DC, &Item4)))
       return nCBORError;
-   
+
    UsefulBuf_Set(CopyOfStorage, '_');
-   
+
    if(Item1.uLabelType != QCBOR_TYPE_TEXT_STRING ||
       Item1.uDataType != QCBOR_TYPE_INT64 ||
       Item1.val.int64 != 42 ||
       UsefulBuf_Compare(Item1.label.string, UsefulBuf_FromSZ("first integer"))) {
       return -1;
    }
-   
+
 
    if(Item2.uLabelType != QCBOR_TYPE_TEXT_STRING ||
       UsefulBuf_Compare(Item2.label.string, UsefulBuf_FromSZ("an array of two strings")) ||
       Item2.uDataType != QCBOR_TYPE_ARRAY ||
       Item2.val.uCount != 2)
       return -1;
-   
+
    if(Item3.uDataType != QCBOR_TYPE_TEXT_STRING ||
       UsefulBuf_Compare(Item3.val.string, UsefulBuf_FromSZ("string1"))) {
       return -1;
    }
-   
+
    if(Item4.uDataType != QCBOR_TYPE_TEXT_STRING ||
       UsefulBuf_Compare(Item4.val.string, UsefulBuf_FromSZ("string2"))) {
       return -1;
    }
-   
+
    // Next parse with a pool that is too small
    UsefulBuf_MAKE_STACK_UB(SmallPool, 80);
    QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pValidMapEncoded), QCBOR_DECODE_MODE_NORMAL);
@@ -2732,15 +2732,15 @@
    QCBORDecodeContext DC;
    const uint8_t pMinimalCBOR[] = {0xa0}; // One empty map
    QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pMinimalCBOR),0);
-   
+
    // Set up an memory pool of 100 bytes
    UsefulBuf_MAKE_STACK_UB(Pool, 100);
    QCBORDecode_SetMemPool(&DC, Pool, 0);
-    
+
    // Cheat a little to get to the string allocator object
    // so we can call it directly to test it
    QCBORStringAllocator *pAlloc = (QCBORStringAllocator *)DC.pStringAllocator;
-   // Cheat some more to know exactly the 
+   // Cheat some more to know exactly the
    size_t uAvailPool = MemPoolTestHook_GetPoolSize(pAlloc);
 
    // First test -- ask for too much in one go
@@ -2748,21 +2748,21 @@
    if(!UsefulBuf_IsNULL(Allocated)) {
       return -1;
    }
-   
-   
+
+
    // Re do the set up for the next test that will do a successful alloc,
    // a fail, a free and then success
    // This test should work on 32 and 64-bit machines if the compiler
    // does the expected thing with pointer sizes for the internal
    // MemPool implementation leaving 44 or 72 bytes of pool memory.
    QCBORDecode_SetMemPool(&DC, Pool, 0);
-    
+
    // Cheat a little to get to the string allocator object
    // so we can call it directly to test it
    pAlloc = (QCBORStringAllocator *)DC.pStringAllocator;
    // Cheat some more to know exactly the
    uAvailPool = MemPoolTestHook_GetPoolSize(pAlloc);
-    
+
    Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, uAvailPool-1);
    if(UsefulBuf_IsNULL(Allocated)) { // expected to succeed
       return -2;
@@ -2776,12 +2776,12 @@
    if(UsefulBuf_IsNULL(Allocated)) { // succeed because of the free
       return -4;
    }
-    
-   
+
+
    // Re do set up for next test that involves a successful alloc,
    // and a successful realloc and a failed realloc
    QCBORDecode_SetMemPool(&DC, Pool, 0);
-    
+
    // Cheat a little to get to the string allocator object
    // so we can call it directly to test it
    pAlloc = (QCBORStringAllocator *)DC.pStringAllocator;
@@ -2800,7 +2800,7 @@
    if(!UsefulBuf_IsNULL(Allocated3)) { // expected to fail
       return -8;
    }
-    
+
    return 0;
 }
 
diff --git a/test/qcbor_decode_tests.h b/test/qcbor_decode_tests.h
index 398a8af..8a91929 100644
--- a/test/qcbor_decode_tests.h
+++ b/test/qcbor_decode_tests.h
@@ -2,7 +2,7 @@
  Copyright (c) 2016-2018, The Linux Foundation.
  Copyright (c) 2018, Laurence Lundblade.
  All rights reserved.
- 
+
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
 met:
@@ -16,7 +16,7 @@
       contributors, nor the name "Laurence Lundblade" may be used to
       endorse or promote products derived from this software without
       specific prior written permission.
- 
+
 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
@@ -36,16 +36,16 @@
 #include "qcbor.h"
 
 
-/* 
+/*
  Notes:
- 
+
  - All the functions in qcbor.h are called once in the aggregation of all the tests below.
- 
+
  - All the types that are supported are given as input and parsed by these tests
- 
+
  - There is some hostile input such as invalid lengths and CBOR too complex
    and types this parser doesn't handle
- 
+
  */
 
 
@@ -90,7 +90,7 @@
 int UnsupportedCBORDecodeTest(void);
 
 
-/* 
+/*
   This takes the encoded CBOR integers used in the above test and parses
   it over and over with one more byte less each time. It should fail
   every time on incorrect CBOR input. This is a hostile input decode test.
@@ -98,7 +98,7 @@
 int ShortBufferParseTest(void);
 
 
-/* 
+/*
    Same as ShortBufferParseTest, but with a different encoded CBOR input.
    It is another hostile input test
  */
@@ -121,7 +121,7 @@
 
 
 /*
- 
+
  */
 int ParseMapAsArrayTest(void);
 
diff --git a/test/qcbor_decode_tests.o b/test/qcbor_decode_tests.o
new file mode 100644
index 0000000..c18a6c5
--- /dev/null
+++ b/test/qcbor_decode_tests.o
Binary files differ
diff --git a/test/qcbor_encode_tests.c b/test/qcbor_encode_tests.c
index 97cee3d..8553dbe 100644
--- a/test/qcbor_encode_tests.c
+++ b/test/qcbor_encode_tests.c
@@ -2,7 +2,7 @@
  Copyright (c) 2016-2018, The Linux Foundation.
  Copyright (c) 2018, Laurence Lundblade.
  All rights reserved.
- 
+
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
 met:
@@ -16,7 +16,7 @@
       contributors, nor the name "Laurence Lundblade" may be used to
       endorse or promote products derived from this software without
       specific prior written permission.
- 
+
 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
@@ -36,15 +36,15 @@
 
 /*
  This is the test set for CBOR encoding.
- 
+
  This is largely complete for the implemented.
- 
+
  A few more things to do include:
    - Add a test for counting the top level items and adding it back in with AddRaw()
    - Run on some different CPUs like 32-bit and maybe even 16-bit
    - Test the large array count limit
    - Add the CBOR diagnostic output for every expected
- 
+
  */
 
 //#define PRINT_FUNCTIONS_FOR_DEBUGGINGXX
@@ -76,7 +76,7 @@
       }
    }
    return 0;
-   
+
 }
 
 #define CheckResults(Enc, Expected) \
@@ -105,39 +105,39 @@
 {
    // Very simple CBOR, a map with one boolean that is true in it
    QCBOREncodeContext EC;
-   
+
    QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
 
    QCBOREncode_OpenMap(&EC);
    QCBOREncode_AddBoolToMapN(&EC, 66, true);
    QCBOREncode_CloseMap(&EC);
-   
+
    UsefulBufC Encoded;
    if(QCBOREncode_Finish(&EC, &Encoded)) {
       return -1;
    }
-   
-   
+
+
    // Decode it and see that is right
    QCBORDecodeContext DC;
    QCBORItem Item;
    QCBORDecode_Init(&DC, Encoded, QCBOR_DECODE_MODE_NORMAL);
-   
+
    QCBORDecode_GetNext(&DC, &Item);
    if(Item.uDataType != QCBOR_TYPE_MAP) {
       return -2;
    }
-   
+
    QCBORDecode_GetNext(&DC, &Item);
    if(Item.uDataType != QCBOR_TYPE_TRUE) {
       return -3;
    }
-   
+
    if(QCBORDecode_Finish(&DC)) {
       return -4;
    }
-   
-   
+
+
    // Make another encoded message with the CBOR from the previous put into this one
    UsefulBuf_MAKE_STACK_UB(MemoryForEncoded2, 20);
    QCBOREncode_Init(&EC, MemoryForEncoded2);
@@ -148,7 +148,7 @@
    QCBOREncode_AddEncodedToMapN(&EC, -70000, Encoded);
    QCBOREncode_CloseMap(&EC);
    QCBOREncode_CloseArray(&EC);
-   
+
    UsefulBufC Encoded2;
    if(QCBOREncode_Finish(&EC, &Encoded2)) {
       return -5;
@@ -165,9 +165,9 @@
           }
         }
      ]
-     
-     
-     
+
+
+
       83                # array(3)
          19 01C3        # unsigned(451)
          A1             # map(1)
@@ -179,56 +179,56 @@
                18 42    # unsigned(66)
                F5       # primitive(21)
      */
-   
+
    // Decode it and see if it is OK
    QCBORDecode_Init(&DC, Encoded2, QCBOR_DECODE_MODE_NORMAL);
-   
+
    // 0    1:3
    QCBORDecode_GetNext(&DC, &Item);
    if(Item.uDataType != QCBOR_TYPE_ARRAY || Item.val.uCount != 3) {
       return -6;
    }
-   
+
    // 1    1:2
    QCBORDecode_GetNext(&DC, &Item);
    if(Item.uDataType != QCBOR_TYPE_INT64 || Item.val.uint64 != 451) {
       return -7;
    }
-   
+
    // 1    1:2   2:1
    QCBORDecode_GetNext(&DC, &Item);
    if(Item.uDataType != QCBOR_TYPE_MAP || Item.val.uCount != 1) {
       return -8;
    }
-   
+
    // 2    1:1
    QCBORDecode_GetNext(&DC, &Item);
    if(Item.uDataType != QCBOR_TYPE_TRUE) {
       return -9;
    }
-   
+
    // 1    1:1   2:1
    QCBORDecode_GetNext(&DC, &Item);
    if(Item.uDataType != QCBOR_TYPE_MAP || Item.val.uCount != 1) {
       return -10;
    }
-   
+
    // 2    1:1   2:1   3:1
    QCBORDecode_GetNext(&DC, &Item);
    if(Item.uDataType != QCBOR_TYPE_MAP || Item.val.uCount != 1 || Item.uLabelType != QCBOR_TYPE_INT64 || Item.label.int64 != -70000) {
       return -11;
    }
-   
+
    // 3    XXXXXX
    QCBORDecode_GetNext(&DC, &Item);
    if(Item.uDataType != QCBOR_TYPE_TRUE || Item.uLabelType != QCBOR_TYPE_INT64 || Item.label.int64 != 66) {
       return -12;
    }
-   
+
    if(QCBORDecode_Finish(&DC)) {
       return -13;
    }
-   
+
    return 0;
 }
 
@@ -471,9 +471,9 @@
    // TODO: this test should be broken down into several so it is more managable. Tags and labels could be more sensible
    QCBOREncodeContext ECtx;
    int nReturn = 0;
-   
+
    QCBOREncode_Init(&ECtx, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
-   
+
    QCBOREncode_OpenArray(&ECtx);
 
    // Some ints that are tagged and have strings preceeding them (not labels becase it is not a map)
@@ -493,17 +493,17 @@
    QCBOREncode_AddInt64ToMap(&ECtx, "NEGLBLTHAT IS KIND OF LONG", -2394893489238);
    QCBOREncode_AddInt64ToMapN(&ECtx, -100000000, -800000000);
    QCBOREncode_CloseMap(&ECtx);
-   
+
    // Epoch Date
    QCBOREncode_AddDateEpoch(&ECtx, 2383748234);
-   
+
    // Epoch date with labels
    QCBOREncode_OpenMap(&ECtx);
    QCBOREncode_AddDateEpochToMap(&ECtx, "LongLiveDenisRitchie", 1400000000);
    QCBOREncode_AddDateEpochToMap(&ECtx, "time()", 1477263730);
    QCBOREncode_AddDateEpochToMapN(&ECtx, -1969, 1477263222);
    QCBOREncode_CloseMap(&ECtx);
-   
+
    // Binary blobs
    QCBOREncode_AddBytes(&ECtx, ((UsefulBufC) {(uint8_t []){0xff, 0x00}, 2}));
 
@@ -515,7 +515,7 @@
    QCBOREncode_AddBytesToMap(&ECtx, "blabel", ((UsefulBufC) {(uint8_t []){0x01, 0x02, 0x03}, 3}));
    QCBOREncode_AddBytesToMapN(&ECtx, 0, ((UsefulBufC){(uint8_t []){0x04, 0x02, 0x03, 0xfe}, 4}));
    QCBOREncode_CloseMap(&ECtx);
-   
+
    // text blobs
    QCBOREncode_AddText(&ECtx, UsefulBuf_FROM_SZ_LITERAL("bar bar foo bar"));
    QCBOREncode_AddSZString(&ECtx, "oof\n");
@@ -523,7 +523,7 @@
    QCBOREncode_AddB64Text(&ECtx, UsefulBuf_FROM_SZ_LITERAL("YW55IGNhcm5hbCBwbGVhc3VyZQ=="));
    QCBOREncode_AddRegex(&ECtx, UsefulBuf_FROM_SZ_LITERAL("[^abc]+"));
    QCBOREncode_AddMIMEData(&ECtx, UsefulBuf_FromSZ(szMIME));
-   
+
    // text blobs in maps
    QCBOREncode_OpenMap(&ECtx);
    QCBOREncode_AddTextToMap(&ECtx, "#####", UsefulBuf_FROM_SZ_LITERAL("foo bar foo foo"));
@@ -550,7 +550,7 @@
    QCBOREncode_AddDateStringToMap(&ECtx, "Bed time", "2003-12-13T18:30:02.25+01:00");
    QCBOREncode_AddDateStringToMapN(&ECtx, 88, "2003-12-13T18:30:02.25+01:00");
    QCBOREncode_CloseMap(&ECtx);
-   
+
    // true / false ...
    QCBOREncode_AddSimple(&ECtx, CBOR_SIMPLEV_UNDEF);
    QCBOREncode_OpenMap(&ECtx);
@@ -560,7 +560,7 @@
    QCBOREncode_AddBoolToMap(&ECtx, "uu", false);
    QCBOREncode_AddSimpleToMapN(&ECtx, 737634, CBOR_SIMPLEV_NULL);
    QCBOREncode_CloseMap(&ECtx);
-   
+
    // opening an array
    QCBOREncode_OpenArray(&ECtx);
    QCBOREncode_CloseArray(&ECtx);
@@ -574,9 +574,9 @@
    QCBOREncode_OpenArrayInMap(&ECtx, "alabl");
    QCBOREncode_CloseArray(&ECtx);
    QCBOREncode_OpenArrayInMapN(&ECtx, 42);
-   QCBOREncode_CloseArray(&ECtx); 
+   QCBOREncode_CloseArray(&ECtx);
    QCBOREncode_CloseMap(&ECtx);
- 
+
    // opening maps with labels and tagging
    QCBOREncode_OpenMap(&ECtx);
    QCBOREncode_OpenMapInMap(&ECtx, "in a map");
@@ -588,7 +588,7 @@
    QCBOREncode_CloseMap(&ECtx);
    QCBOREncode_CloseMap(&ECtx);
    QCBOREncode_CloseMap(&ECtx);
-   
+
 
    // Extended simple values (these are not standard...)
    QCBOREncode_OpenMap(&ECtx);
@@ -606,7 +606,7 @@
    QCBOREncode_AddTag(&ECtx, 88);
    QCBOREncode_AddSimple(&ECtx, 19);
    QCBOREncode_CloseMap(&ECtx);
-   
+
    // UUIDs
    static const uint8_t ppppUUID[] = {0x53, 0x4D, 0x41, 0x52, 0x54, 0x43, 0x53, 0x4C, 0x54, 0x54, 0x43, 0x46, 0x49, 0x43, 0x41, 0x32};
    const UsefulBufC XXUUID = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(ppppUUID);
@@ -615,7 +615,7 @@
    QCBOREncode_AddBinaryUUIDToMap(&ECtx, "UUUU", XXUUID);
    QCBOREncode_AddBinaryUUIDToMapN(&ECtx, 99, XXUUID);
    QCBOREncode_CloseMap(&ECtx);
-   
+
    // Bool
    QCBOREncode_AddBool(&ECtx, true);
    QCBOREncode_AddBool(&ECtx, false);
@@ -635,19 +635,19 @@
    QCBOREncode_AddNegativeBignumToMap(&ECtx, "BN-", BIGNUM);
    QCBOREncode_AddNegativeBignumToMapN(&ECtx, -64, BIGNUM);
    QCBOREncode_CloseMap(&ECtx);
-   
+
    QCBOREncode_CloseArray(&ECtx);
 
    UsefulBufC Enc;
-   
+
    if(QCBOREncode_Finish(&ECtx, &Enc)) {
       nReturn = -1;
       goto Done;
    }
-   
+
    if(CheckResults(Enc, spExpectedEncodedAll))
       nReturn = -2;
-   
+
 Done:
    return nReturn;
 }
@@ -729,19 +729,19 @@
    0xff, 0xff};
 
 /*
- 
+
   Test the generation of integers. This also ends up testing
   encoding of all the different lengths. It encodes integers
   of many lengths and values, especially around the boundaries
   for different types of integers.  It compares the output
   to expected values generated from http://cbor.me.
- 
+
  */
 int IntegerValuesTest1()
 {
    QCBOREncodeContext ECtx;
    int nReturn = 0;
-   
+
    QCBOREncode_Init(&ECtx, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
    QCBOREncode_OpenArray(&ECtx);
 
@@ -792,17 +792,17 @@
    QCBOREncode_AddInt64(&ECtx, 4294967297);
    QCBOREncode_AddInt64(&ECtx, 9223372036854775807LL);
    QCBOREncode_AddUInt64(&ECtx, 18446744073709551615ULL);
-   
+
    QCBOREncode_CloseArray(&ECtx);
-   
+
    UsefulBufC Enc;
    if(QCBOREncode_Finish(&ECtx, &Enc)) {
       nReturn = -1;
    }
-   
+
    if(CheckResults(Enc, spExpectedEncodedInts))
      return -2;
-   
+
    return(nReturn);
 }
 
@@ -825,7 +825,7 @@
 {
    QCBOREncodeContext ECtx;
    int nReturn = 0;
-   
+
    QCBOREncode_Init(&ECtx, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
    QCBOREncode_OpenArray(&ECtx);
 
@@ -833,22 +833,22 @@
    QCBOREncode_AddSimple(&ECtx, CBOR_SIMPLEV_FALSE);
    QCBOREncode_AddSimple(&ECtx, CBOR_SIMPLEV_NULL);
    QCBOREncode_AddSimple(&ECtx, CBOR_SIMPLEV_UNDEF);
-   
+
    QCBOREncode_OpenMap(&ECtx);
 
    QCBOREncode_AddSimpleToMap(&ECtx, "UNDef", CBOR_SIMPLEV_UNDEF);
    QCBOREncode_CloseMap(&ECtx);
 
    QCBOREncode_CloseArray(&ECtx);
-   
+
    UsefulBufC ECBOR;
    if(QCBOREncode_Finish(&ECtx, &ECBOR)) {
       nReturn = -1;
    }
-   
+
    if(CheckResults(ECBOR, spExpectedEncodedSimple))
       return -2;
-   
+
    return(nReturn);
 }
 
@@ -887,24 +887,24 @@
 {
    QCBOREncodeContext ECtx;
    int nReturn = 0;
-   
+
    QCBOREncode_Init(&ECtx, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
-   
+
    QCBOREncode_OpenArray(&ECtx);
 
-   
+
    QCBOREncode_AddDateString(&ECtx, "2013-03-21T20:04:00Z"); // from CBOR RFC
    QCBOREncode_AddDateEpoch(&ECtx, 1363896240); // from CBOR RFC
 
-   
+
    QCBOREncode_OpenMap(&ECtx);
 
    QCBOREncode_AddDateStringToMap(&ECtx, "Sample Date from RFC 3339", "1985-04-12T23:20:50.52Z");
-   
+
    QCBOREncode_AddDateEpochToMap(&ECtx, "SD", 999);
-   
+
    QCBOREncode_CloseMap(&ECtx);
-   
+
    QCBOREncode_CloseArray(&ECtx);
 
    UsefulBufC ECBOR;
@@ -912,10 +912,10 @@
    if(QCBOREncode_Finish(&ECtx, &ECBOR)) {
       nReturn = -1;
    }
-   
+
    if(CheckResults(ECBOR, spExpectedEncodedDates))
       return -2;
-   
+
    return(nReturn);
 }
 
@@ -925,7 +925,7 @@
    QCBOREncodeContext ECtx;
    int i;
    int nReturn = 0;
-   
+
    QCBOREncode_Init(&ECtx, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
    for(i = QCBOR_MAX_ARRAY_NESTING; i; i--) {
       QCBOREncode_OpenArray(&ECtx);
@@ -948,7 +948,7 @@
    QCBOREncodeContext ECtx;
    int i;
    int nReturn = 0;
-   
+
    QCBOREncode_Init(&ECtx, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
    for(i = QCBOR_MAX_ARRAY_NESTING+1; i; i--) {
       QCBOREncode_OpenArray(&ECtx);
@@ -956,12 +956,12 @@
    for(i = QCBOR_MAX_ARRAY_NESTING; i; i--) {
       QCBOREncode_CloseArray(&ECtx);
    }
-   
+
    UsefulBufC Encoded;
    if(QCBOREncode_Finish(&ECtx, &Encoded) != QCBOR_ERR_ARRAY_NESTING_TOO_DEEP) {
       nReturn = -1;
    }
-   
+
    return(nReturn);
 }
 
@@ -972,7 +972,7 @@
    QCBOREncodeContext ECtx;
    int i;
    int nReturn = 0;
-   
+
    QCBOREncode_Init(&ECtx, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
    for(i = QCBOR_MAX_ARRAY_NESTING; i; i--) {
       QCBOREncode_OpenArray(&ECtx);
@@ -984,7 +984,7 @@
    if(QCBOREncode_Finish(&ECtx, &Encoded) != QCBOR_ERR_TOO_MANY_CLOSES) {
       nReturn = -1;
    }
-   
+
    return(nReturn);
 }
 
@@ -1091,17 +1091,17 @@
    QCBOREncode_AddEncoded(&ECtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spFiveArrarys));
    QCBOREncode_AddEncoded(&ECtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spExpectedEncodedInts));
    QCBOREncode_CloseArray(&ECtx);
-   
+
    UsefulBufC EncodedRawTest;
-   
+
    if(QCBOREncode_Finish(&ECtx, &EncodedRawTest)) {
       return -4;
    }
-   
+
    if(CheckResults(EncodedRawTest, spEncodeRawExpected)) {
       return -5;
    }
-   
+
    return 0;
 }
 
@@ -1112,11 +1112,11 @@
 {
    QCBOREncodeContext ECtx;
    int nReturn = -1;
-   
+
    *pEncoded = NULL;
    *pEncodedLen = INT32_MAX;
    size_t uFirstSizeEstimate = 0;
-   
+
    // loop runs CBOR encoding twice. First with no buffer to
    // calucate the length so buffer can be allocated correctly,
    // and last with the buffer to do the actual encoding
@@ -1135,7 +1135,7 @@
       QCBOREncode_AddTextToMap(&ECtx, "text 2", ((UsefulBufC) {"lies, damn lies and statistics", 30}));
       QCBOREncode_CloseMap(&ECtx);
       QCBOREncode_CloseMap(&ECtx);
-      
+
       if(QCBOREncode_FinishGetSize(&ECtx, pEncodedLen))
          goto Done;
       if(*pEncoded != NULL) {
@@ -1148,9 +1148,9 @@
       }
       *pEncoded = spBigBuf;
       uFirstSizeEstimate = *pEncodedLen;
-      
+
    } while(1);
-   
+
  Done:
    return(nReturn);
 }
@@ -1209,38 +1209,38 @@
 {
    uint8_t *pEncodedMaps;
    size_t nEncodedMapLen;
-   
+
    if(CreateMap(&pEncodedMaps, &nEncodedMapLen)) {
       return -1;
    }
-   
+
    int nReturn = 0;
    if(memcmp(spValidMapEncoded, pEncodedMaps, sizeof(spValidMapEncoded)))
       nReturn = 2;
-   
+
    return(nReturn);
 }
 
 
 /*
  @brief  Encode the RTIC results
- 
+
  @param[in]     nRResult        CBOR_SIMPLEV_TRUE, CBOR_SIMPLEV_FALSE or CBOR_SIMPLEV_NULL
  @param[in]     time            Time stamp in UNIX epoch time or 0 for no time stamp
  @param[in]     szAlexString    Diagnostic code.
  @param[in[     pOut            Buffer to put the result in
  @param[in/out] pnLen           Size of pOut buffer when called; length of data output in buffer on return
- 
+
  @return
  One of the CBOR encoder errors. QCBOR_SUCCESS, which is has value 0, if no error.
- 
+
  The size of pOut should be 30 bytes plus the length of pnLen.  If you make it too
- short an error will be returned. This function will never write off the end 
+ short an error will be returned. This function will never write off the end
  of the buffer passed to it.
- 
+
  If the result is 0, then the correct encoded CBOR is in pOut and *pnLen is the
  length of the encoded CBOR.
- 
+
  */
 
 static UsefulBufC FormatRTICResults(int nRResult, uint64_t time, const char *szType, const char *szAlexString, UsefulBuf Storage)
@@ -1248,17 +1248,17 @@
    // Buffer that the result will be written in to
    // It is fixed size and small that a stack variable will be fine
    // QCBOREncode will never write off the end of this buffer. If it won't fit QCBOREncode_Finish will return an error.
-   
+
    // Context for the encoder
    QCBOREncodeContext ECtx;
    QCBOREncode_Init(&ECtx, Storage);
-   
+
    // All the RTIC results are grouped in a CBOR Map which will get turned into a JSON Object
    // Contents are label / value pairs
    QCBOREncode_OpenMap(&ECtx);
-   
+
    { // Brace / indention just to show CBOR encoding nesting
-      
+
       // The result: 0 if scan happened and found nothing; 1 if it happened and found something wrong; 2 if it didn't happen
       QCBOREncode_AddSimpleToMap(&ECtx, "integrity", nRResult);
 
@@ -1277,7 +1277,7 @@
       QCBOREncode_OpenMapInMap(&ECtx, "telemetry");
 
       { // Brace / indention just to show CBOR encoding nesting
-         
+
          // Add a few fake integers and buffers for now.
          QCBOREncode_AddInt64ToMap(&ECtx, "Shoe Size", 12);
 
@@ -1287,21 +1287,21 @@
          // Add a few fake integers and buffers for now.
          static const uint8_t pPV[] = {0x66, 0x67, 0x00, 0x56, 0xaa, 0xbb, 0x01, 0x01};
          const UsefulBufC WSPV = {pPV, sizeof(pPV)};
-            
+
          QCBOREncode_AddBytesToMap(&ECtx, "WhaleSharkPatternVector", WSPV);
       }
    }
-   
+
    // Close the telemetry map
    QCBOREncode_CloseMap(&ECtx);
-   
+
    // Close the map
    QCBOREncode_CloseMap(&ECtx);
-   
+
    UsefulBufC Result;
-   
+
    QCBOREncode_Finish(&ECtx, &Result);
-   
+
    return Result;
 }
 
@@ -1360,12 +1360,12 @@
    if(UsefulBuf_IsNULLC(Encoded)) {
       return -1;
    }
-   
+
    if(CheckResults(Encoded, spExpectedRTIC)) {
       return -2;
    }
-   
-   return 0;  
+
+   return 0;
 }
 
 
@@ -1383,29 +1383,29 @@
 int BstrWrapTest()
 {
    QCBOREncodeContext EC;
-   
+
    QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
-   
+
    QCBOREncode_OpenArray(&EC);
    QCBOREncode_AddUInt64(&EC, 451);
-   
+
    QCBOREncode_BstrWrap(&EC);
    QCBOREncode_AddUInt64(&EC, 466);
-   
+
    UsefulBufC Wrapped;
    QCBOREncode_CloseBstrWrap(&EC, &Wrapped);
-   
+
    QCBOREncode_CloseArray(&EC);
-   
+
    UsefulBufC Encoded;
    if(QCBOREncode_Finish(&EC, &Encoded)) {
       return -1;
    }
-   
+
    if(CheckResults(Encoded, spExpectedBstrWrap)) {
       return -2;
    }
-   
+
    return 0;
 }
 
@@ -1415,48 +1415,48 @@
 {
    // -------------- Test closing a bstrwrap when it is an array that is open -----------
    QCBOREncodeContext EC;
-   
+
    QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
-   
+
    QCBOREncode_OpenArray(&EC);
    QCBOREncode_AddUInt64(&EC, 451);
-   
+
    QCBOREncode_BstrWrap(&EC);
    QCBOREncode_AddUInt64(&EC, 466);
    QCBOREncode_OpenArray(&EC);
-   
+
    UsefulBufC Wrapped;
    QCBOREncode_CloseBstrWrap(&EC, &Wrapped);
-   
+
    QCBOREncode_CloseArray(&EC);
-   
+
    UsefulBufC Encoded2;
    if(QCBOREncode_Finish(&EC, &Encoded2) != QCBOR_ERR_CLOSE_MISMATCH) {
       return -1;
    }
-   
+
    // ----------- test closing a bstrwrap when nothing is open ---------------------
    QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
    QCBOREncode_CloseBstrWrap(&EC, &Wrapped);
    if(QCBOREncode_Finish(&EC, &Encoded2) != QCBOR_ERR_TOO_MANY_CLOSES) {
       return -2;
    }
-   
+
    // --------------- test nesting too deep ----------------------------------
    QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
    for(int i = 1; i < 18; i++) {
       QCBOREncode_BstrWrap(&EC);
    }
    QCBOREncode_AddBool(&EC, true);
-   
+
    for(int i = 1; i < 18; i++) {
       QCBOREncode_CloseBstrWrap(&EC, &Wrapped);
    }
-   
+
    if(QCBOREncode_Finish(&EC, &Encoded2) != QCBOR_ERR_ARRAY_NESTING_TOO_DEEP) {
       return -3;
    }
-   
+
    return 0;
 }
 
@@ -1502,8 +1502,8 @@
  18 31 integer value 31
  18 41 integer label 41
  65 68 65 6C 6C 6F text string hello
- 
- 
+
+
  */
 
 
@@ -1538,7 +1538,7 @@
    int nReturn;
    QCBORDecodeContext DC;
    QCBORDecode_Init(&DC, Wrapped, QCBOR_DECODE_MODE_NORMAL);
-   
+
    QCBORItem Item;
    nReturn = QCBORDecode_GetNext(&DC, &Item);
    if(nReturn) {
@@ -1547,7 +1547,7 @@
    if(Item.uDataType != QCBOR_TYPE_INT64) {
       return -12;
    }
-   
+
    nReturn = QCBORDecode_GetNext(&DC, &Item);
    if(nReturn == QCBOR_ERR_HIT_END) {
       return 0;
@@ -1559,7 +1559,7 @@
    if(nReturn) {
       return nReturn;
    }
-   
+
    nReturn = QCBORDecode_GetNext(&DC, &Item);
    if(nReturn) {
       return -14;
@@ -1567,11 +1567,11 @@
    if(Item.uDataType != QCBOR_TYPE_INT64) {
       return -15;
    }
-   
+
    if(QCBORDecode_Finish(&DC)) {
       return -16;
    }
-   
+
    return 0;
 }
 
@@ -1581,7 +1581,7 @@
    int nReturn;
    QCBORDecodeContext DC;
    QCBORDecode_Init(&DC, Wrapped, QCBOR_DECODE_MODE_NORMAL);
-   
+
    QCBORItem Item;
    nReturn = QCBORDecode_GetNext(&DC, &Item);
    if(nReturn) {
@@ -1590,7 +1590,7 @@
    if(Item.uDataType != QCBOR_TYPE_ARRAY) {
       return -12;
    }
-   
+
    nReturn = QCBORDecode_GetNext(&DC, &Item);
    if(nReturn) {
       return -11;
@@ -1598,7 +1598,7 @@
    if(Item.uDataType != QCBOR_TYPE_INT64) {
       return -12;
    }
-   
+
    nReturn = QCBORDecode_GetNext(&DC, &Item);
    if(nReturn) {
       return -11;
@@ -1606,7 +1606,7 @@
    if(Item.uDataType != QCBOR_TYPE_MAP) {
       return 0;
    }
-   
+
    nReturn = QCBORDecode_GetNext(&DC, &Item);
    if(nReturn) {
       return -11;
@@ -1618,7 +1618,7 @@
    if(nReturn) {
       return nReturn;
    }
-   
+
    nReturn = QCBORDecode_GetNext(&DC, &Item);
    if(nReturn) {
       return -11;
@@ -1633,11 +1633,11 @@
    if(Item.uDataType != QCBOR_TYPE_INT64) {
       return -12;
    }
-   
+
    if(QCBORDecode_Finish(&DC)) {
       return -16;
    }
-   
+
    return 0;
 }
 
@@ -1646,29 +1646,29 @@
 {
    QCBOREncodeContext EC;
    QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
-   
+
    // ---- Make a complicated nested CBOR structure ---
 #define BSTR_TEST_DEPTH 10
-   
+
    QCBOREncode_OpenArray(&EC);
 
    for(int i = 0; i < BSTR_TEST_DEPTH-2; i++) {
       QCBOREncode_BstrWrap(&EC);
       QCBOREncode_AddUInt64(&EC, i);
    }
-   
+
    for(int i = 0; i < BSTR_TEST_DEPTH-2; i++) {
       QCBOREncode_CloseBstrWrap(&EC, NULL);
       QCBOREncode_AddUInt64(&EC, i);
    }
-   
+
    for(int i = 0; i < (BSTR_TEST_DEPTH-2)/3; i++) {
       QCBOREncode_OpenMap(&EC);
       QCBOREncode_BstrWrapInMapN(&EC, i+0x20);
       QCBOREncode_OpenArray(&EC);
       QCBOREncode_AddUInt64(&EC, i+0x10);
    }
-   
+
    for(int i = 0; i < (BSTR_TEST_DEPTH-2)/3; i++) {
       QCBOREncode_CloseArray(&EC);
       QCBOREncode_AddUInt64(&EC, i+0x30);
@@ -1677,38 +1677,38 @@
       QCBOREncode_CloseMap(&EC);
    }
    QCBOREncode_CloseArray(&EC);
-   
+
    UsefulBufC Encoded;
    if(QCBOREncode_Finish(&EC, &Encoded)) {
       return -1;
    }
-   
+
    // ---Compare it to expected. Expected was hand checked with use of CBOR playground ----
    if(UsefulBuf_Compare(UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spExpectedDeepBstr), Encoded)) {
       return -25;
    }
-   
-   
+
+
    // ---- Decode it and see if it is OK ------
    QCBORDecodeContext DC;
    QCBORDecode_Init(&DC, Encoded, QCBOR_DECODE_MODE_NORMAL);
-   
+
    QCBORItem Item;
    QCBORDecode_GetNext(&DC, &Item);
    if(Item.uDataType != QCBOR_TYPE_ARRAY || Item.val.uCount != 3) {
       return -2;
    }
-   
+
    QCBORDecode_GetNext(&DC, &Item);
    if(Item.uDataType != QCBOR_TYPE_BYTE_STRING) {
       return -3;
    }
-   
+
    int nReturn = DecodeNextNested(Item.val.string);
    if(nReturn) {
       return nReturn;
    }
-   
+
    nReturn = QCBORDecode_GetNext(&DC, &Item);
    if(nReturn) {
       return -11;
@@ -1716,12 +1716,12 @@
    if(Item.uDataType != QCBOR_TYPE_INT64) {
       return -12;
    }
-   
+
    QCBORDecode_GetNext(&DC, &Item);
    if(Item.uDataType != QCBOR_TYPE_MAP || Item.val.uCount != 2) {
       return -2;
    }
-   
+
    QCBORDecode_GetNext(&DC, &Item);
    if(Item.uDataType != QCBOR_TYPE_BYTE_STRING) {
       return -3;
@@ -1730,7 +1730,7 @@
    if(nReturn) {
       return nReturn;
    }
-   
+
    nReturn = QCBORDecode_GetNext(&DC, &Item);
    if(nReturn) {
       return -11;
@@ -1738,11 +1738,11 @@
    if(Item.uDataType != QCBOR_TYPE_TEXT_STRING) {
       return -12;
    }
-   
+
    if(QCBORDecode_Finish(&DC)) {
       return -16;
    }
-   
+
    return 0;
 }
 
@@ -1803,52 +1803,52 @@
    // a COSE implementation like COSE-C. It has been checked
    // against the CBOR playground.
    const UsefulBufC Signature = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spSignature);
-   
+
    QCBOREncodeContext EC;
    QCBOREncode_Init(&EC, UsefulBuf_FROM_BYTE_ARRAY(spBigBuf));
-   
+
    // top level array for cose sign1, 18 is the tag for COSE sign
    QCBOREncode_AddTag(&EC, CBOR_TAG_COSE_SIGN1);
    QCBOREncode_OpenArray(&EC);
-   
+
    // Add protected headers
    QCBOREncode_AddBytes(&EC, ProtectedHeaders);
-   
+
    // Empty map with unprotected headers
    QCBOREncode_OpenMap(&EC);
    QCBOREncode_AddBytesToMapN(&EC, 4, Kid);
    QCBOREncode_CloseMap(&EC);
-   
+
    // The payload
    UsefulBufC WrappedPayload;
    QCBOREncode_BstrWrap(&EC);
    QCBOREncode_AddEncoded(&EC, Payload); // Payload is not actually CBOR in example C.2.1
    QCBOREncode_CloseBstrWrap(&EC, &WrappedPayload);
-   
+
    // Check we got back the actual payload expected
    if(UsefulBuf_Compare(WrappedPayload, Payload)) {
       return -1;
    }
-   
+
    // The signature
    QCBOREncode_AddBytes(&EC, Signature);
    QCBOREncode_CloseArray(&EC);
-   
+
    // Finish and check the results
    UsefulBufC COSE_Sign1;
    if(QCBOREncode_Finish(&EC, &COSE_Sign1)) {
       return -2;
    }
-   
+
    // 98 is the size from RFC 8152 C.2.1
    if(COSE_Sign1.len != 98) {
       return -3;
    }
-   
+
    if(CheckResults(COSE_Sign1, spExpected)) {
       return -4;
    }
-   
+
    return 0;
 }
 
diff --git a/test/qcbor_encode_tests.h b/test/qcbor_encode_tests.h
index 5575e10..ed2fa75 100644
--- a/test/qcbor_encode_tests.h
+++ b/test/qcbor_encode_tests.h
@@ -2,7 +2,7 @@
  Copyright (c) 2016-2018, The Linux Foundation.
  Copyright (c) 2018, Laurence Lundblade.
  All rights reserved.
- 
+
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
 met:
@@ -16,7 +16,7 @@
       contributors, nor the name "Laurence Lundblade" may be used to
       endorse or promote products derived from this software without
       specific prior written permission.
- 
+
 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
@@ -36,16 +36,16 @@
 #include "qcbor.h"
 
 
-/* 
+/*
  Notes:
- 
+
  - All the functions in qcbor.h are called once in the aggregation of all the tests below.
- 
+
  - All the types that are supported are given as input and parsed by these tests
- 
+
  - There is some hostile input such as invalid lengths and CBOR too complex
    and types this parser doesn't handle
- 
+
  */
 
 
diff --git a/test/qcbor_encode_tests.o b/test/qcbor_encode_tests.o
new file mode 100644
index 0000000..8bd84fe
--- /dev/null
+++ b/test/qcbor_encode_tests.o
Binary files differ
diff --git a/test/run_tests.c b/test/run_tests.c
index dea81d7..2b0288f 100644
--- a/test/run_tests.c
+++ b/test/run_tests.c
@@ -1,10 +1,10 @@
 
 /*==============================================================================
  run_tests.c -- test aggregator and results reporting
- 
+
  Copyright (c) 2018, Laurence Lundblade.
  All rights reserved.
- 
+
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
 met:
@@ -17,7 +17,7 @@
     * The name "Laurence Lundblade" may not be used to
       endorse or promote products derived from this software without
       specific prior written permission.
- 
+
 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
@@ -57,10 +57,10 @@
 const char *NumToString(int32_t nNum, UsefulBuf StringMem)
 {
     const int32_t nMax = 1000000000;
-    
+
     UsefulOutBuf OutBuf;
     UsefulOutBuf_Init(&OutBuf, StringMem);
-    
+
     if(nNum < 0) {
         UsefulOutBuf_AppendByte(&OutBuf, '-');
         nNum = -nNum;
@@ -68,7 +68,7 @@
     if(nNum > nMax-1) {
         return "XXX";
     }
-    
+
     bool bDidSomeOutput = false;
     for(int n = nMax; n > 0; n/=10) {
         int x = nNum/n;
@@ -82,7 +82,7 @@
         UsefulOutBuf_AppendByte(&OutBuf, '0');
     }
     UsefulOutBuf_AppendByte(&OutBuf, '\0');
-    
+
     return UsefulOutBuf_GetError(&OutBuf) ? "" : StringMem.ptr;
 }
 
@@ -167,7 +167,7 @@
 
     test_entry2 *t2;
     const test_entry2 *s_tests2_end = s_tests2 + sizeof(s_tests2)/sizeof(test_entry2);
-    
+
     for(t2 = s_tests2; t2 < s_tests2_end; t2++) {
         if(szTestName && strcmp(szTestName, t2->szTestName)) {
             continue;
@@ -177,7 +177,7 @@
         if(output) {
             (*output)(t2->szTestName, poutCtx);
         }
-        
+
         if(x) {
             if(output) {
                 (*output)(" FAILED (returned ", poutCtx);
@@ -191,11 +191,11 @@
             }
         }
     }
-    
-    
+
+
     test_entry *t;
     const test_entry *s_tests_end = s_tests + sizeof(s_tests)/sizeof(test_entry);
-    
+
     for(t = s_tests; t < s_tests_end; t++) {
         if(szTestName && strcmp(szTestName, t->szTestName)) {
             continue;
@@ -205,7 +205,7 @@
         if(output) {
             (*output)(t->szTestName, poutCtx);
         }
-        
+
         if(x) {
             if(output) {
                 (*output)(" FAILED (returned ", poutCtx);
@@ -219,11 +219,11 @@
             }
         }
     }
-    
+
     if(pNumTestsRun) {
         *pNumTestsRun = nTestsRun;
     }
-    
+
     if(output) {
         (*output)( "SUMMARY: ", poutCtx);
         (*output)( NumToString(nTestsRun, StringStorage), poutCtx);
@@ -231,6 +231,6 @@
         (*output)( NumToString(nTestsFailed, StringStorage), poutCtx);
         (*output)( " tests failed\n", poutCtx);
     }
-    
+
     return nTestsFailed;
 }
diff --git a/test/run_tests.h b/test/run_tests.h
index 498554e..431ef22 100644
--- a/test/run_tests.h
+++ b/test/run_tests.h
@@ -1,10 +1,10 @@
 
 /*==============================================================================
  run_tests.c -- test aggregator and results reporting
-  
+
  Copyright (c) 2018, Laurence Lundblade.
  All rights reserved.
- 
+
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
 met:
@@ -17,7 +17,7 @@
     * The name "Laurence Lundblade" may not be used to
       endorse or promote products derived from this software without
       specific prior written permission.
- 
+
 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
diff --git a/test/run_tests.o b/test/run_tests.o
new file mode 100644
index 0000000..8aac1ed
--- /dev/null
+++ b/test/run_tests.o
Binary files differ