diff --git a/inc/UsefulBuf.h b/inc/UsefulBuf.h
index a8da83b..f14084e 100644
--- a/inc/UsefulBuf.h
+++ b/inc/UsefulBuf.h
@@ -1,2134 +1 @@
-/*============================================================================
- Copyright (c) 2016-2018, The Linux Foundation.
- Copyright (c) 2018-2020, Laurence Lundblade.
-
-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:  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
- --------     ----            --------------------------------------------------
- 1/25/2020    llundblade      Add some casts so static anlyzers don't complain.
- 5/21/2019    llundblade      #define configs for efficient endianness handling.
- 5/16/2019    llundblade      Add UsefulOutBuf_IsBufferNULL().
- 3/23/2019    llundblade      Big documentation & style update. No interface
-                              change.
- 3/6/2019     llundblade      Add UsefulBuf_IsValue()
- 12/17/2018   llundblade      Remove const from UsefulBuf and UsefulBufC .len
- 12/13/2018   llundblade      Documentation improvements
- 09/18/2018   llundblade      Cleaner distinction between UsefulBuf and
-                              UsefulBufC.
- 02/02/18     llundbla        Full support for integers in and out; fix pointer
-                              alignment bug. Incompatible change: integers
-                              in/out are now in network byte order.
- 08/12/17     llundbla        Added UsefulOutBuf_AtStart and UsefulBuf_Find
- 06/27/17     llundbla        Fix UsefulBuf_Compare() bug. Only affected
-                              comparison for < or > for unequal length buffers.
-                              Added UsefulBuf_Set() function.
- 05/30/17     llundbla        Functions for NULL UsefulBufs and const / unconst
- 11/13/16     llundbla        Initial Version.
-
- =============================================================================*/
-
-#ifndef _UsefulBuf_h
-#define _UsefulBuf_h
-
-
-/*
- Configuration Options
-
- This code is designed so it will work correctly and completely by
- default. No configuration is necessary to make it work. None of the
- following #defines need to be enabled. The code works and is very
- portable with them all turned off.
-
- All configuration options (USEFULBUF_CONFIG_XXX)
-    1) Reduce code size
-    2) Improve efficiency
-    3) Both of the above
-
- The efficiency improvements are not large, so the main reason really
- is to reduce code size.
-
- */
-
-
-/*
- Endianness Configuration
-
- By default, UsefulBuf does not need to know what the endianness of
- the device is. All the code will run correctly on either big or
- little endian CPUs.
-
- Here's the recipe for configuring the endianness-related #defines
- to use more efficient CPU/OS/compiler dependent features to reduce
- code size. Note these only affect the integer arrays (tagged
- arrays) feature of QCBOR. All other endianness handling in
- QCBOR is integrated with code that also handles alignment and
- preferred encoding.
-
- The first option is to not define anything. This will work fine on
- with all CPU's, OS's and compilers. The code for encoding
- integers will be a little larger and slower.
-
- If your CPU is big-endian then define USEFULBUF_CONFIG_BIG_ENDIAN. This
- will give the most efficient code for big-endian CPUs. It will be small
- and efficient because there will be no byte swapping.
-
- Try defining USEFULBUF_CONFIG_HTON. This will work on most CPU's,
- OS's and compilers, but not all. On big-endian CPUs this should give
- the most efficient code, the same as USEFULBUF_CONFIG_BIG_ENDIAN
- does. On little-endian CPUs it should call the system-defined byte
- swapping method which is presumably implemented efficiently. In some
- cases, this will be a dedicated byte swap instruction like Intel's
- bswap.
-
- If USEFULBUF_CONFIG_HTON works and you know your CPU is
- little-endian, it is also good to define
- USEFULBUF_CONFIG_LITTLE_ENDIAN.
-
- if USEFULBUF_CONFIG_HTON doesn't work and you know your system is
- little-endian, try defining both USEFULBUF_CONFIG_LITTLE_ENDIAN and
- USEFULBUF_CONFIG_BSWAP. This should call the most efficient
- system-defined byte swap method. However, note
- https://hardwarebug.org/2010/01/14/beware-the-builtins/.  Perhaps
- this is fixed now. Often hton() and ntoh() will call the built-in
- __builtin_bswapXX()() function, so this size issue could affect
- USEFULBUF_CONFIG_HTON.
-
- Last, run the tests. They must all pass.
-
- These #define config options affect the inline implementation of
- UsefulOutBuf_InsertUint64() and UsefulInputBuf_GetUint64().  They
- also affect the 16-, 32-bit, float and double versions of these
- instructions. Since they are inline, they size effect is not in the
- UsefulBuf object code, but in the calling code.
-
- Summary:
-   USEFULBUF_CONFIG_BIG_ENDIAN -- Force configuration to big-endian.
-   USEFULBUF_CONFIG_LITTLE_ENDIAN -- Force to little-endian.
-   USEFULBUF_CONFIG_HTON -- Use hton(), htonl(), ntohl()... to
-     handle big and little-endian with system option.
-   USEFULBUF_CONFIG_BSWAP -- With USEFULBUF_CONFIG_LITTLE_ENDIAN,
-     use __builtin_bswapXX().
- */
-
-#if defined(USEFULBUF_CONFIG_BIG_ENDIAN) && defined(USEFULBUF_CONFIG_LITTLE_ENDIAN)
-#error "Cannot define both USEFULBUF_CONFIG_BIG_ENDIAN and USEFULBUF_CONFIG_LITTLE_ENDIAN"
-#endif
-
-
-#include <stdint.h> // for uint8_t, uint16_t....
-#include <string.h> // for strlen, memcpy, memmove, memset
-#include <stddef.h> // for size_t
-
-
-#ifdef USEFULBUF_CONFIG_HTON
-#include <arpa/inet.h> // for htons, htonl, htonll, ntohs...
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- @file UsefulBuf.h
-
- The goal of this code is to make buffer and pointer manipulation
- easier and safer when working with binary data.
-
- The @ref UsefulBuf, @ref UsefulOutBuf and @ref UsefulInputBuf
- structures are used 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 written using these and
- has no less 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 effect for most
- use cases. For security-oriented code this is highly
- worthwhile. Clarity, simplicity, reviewability and are more
- important.
-
- There are some extra sanity and double checks in this code to help
- catch coding errors and simple memory corruption. They are helpful,
- but not a substitute for proper code review, input validation and
- such.
-
- This code consists of a lot of inline functions and a few that are
- not.  It should not generate very much object code, especially with
- the optimizer turned up to @c -Os or @c -O3.
- */
-
-
-/**
- @ref UsefulBufC and @ref UsefulBuf are simple data structures to hold
- a pointer and length for 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 coding practice as the length is
- 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 @ref UsefulBuf is usually used to refer a buffer to be
- filled in.  The length is the size of the buffer.
-
- The const @ref 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 @ref UsefulBuf to a function, the function
- fills it in, the function returns a @ref UsefulBufC. The pointer is
- the same in both.
-
- A @ref UsefulBuf is null, it has no value, when @c ptr in it is @c NULL.
-
- There are utility functions for the following:
-  - Initializing
-  - Create initialized const @ref UsefulBufC from compiler literals
-  - Create initialized const @ref UsefulBufC from NULL-terminated string
-  - Make an empty @ref UsefulBuf on the stack
-  - Checking whether a @ref UsefulBuf is null, empty or both
-  - Copying, copying with offset, copying head or tail
-  - Comparing and finding substrings
-
- See also @ref UsefulOutBuf. It is a richer structure that has both
- the size of the valid data and the size of the buffer.
-
- @ref 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.
-
- Another way to look at it is this. C has the NULL-terminated string
- as a means for handling text strings, but no means or convention for
- binary strings. Other languages do have such means, Rust, an
- efficient compiled language, for example.
-
- @ref 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 q_useful_buf_c {
-    const void *ptr;
-    size_t      len;
-} UsefulBufC;
-
-
-/**
- This non-const @ref UsefulBuf is typically used for some allocated
- memory that is to be filled in. The @c len is the amount of memory,
- not the length of the valid data in the buffer.
- */
-typedef struct q_useful_buf {
-   void  *ptr;
-   size_t len;
-} UsefulBuf;
-
-
-/**
- A null @ref UsefulBufC is one that has no value in the same way a @c
- NULL pointer has no value.  A @ref UsefulBufC is @c NULL when the @c
- ptr field is @c NULL. It doesn't matter what @c len is.  See
- UsefulBuf_IsEmpty() for the distinction between null and empty.
- */
-#define NULLUsefulBufC  ((UsefulBufC) {NULL, 0})
-
-
-/**
- A null @ref UsefulBuf is one that has no memory associated the same
- way @c NULL points to nothing. It does not matter what @c len is.
- */
-#define NULLUsefulBuf   ((UsefulBuf) {NULL, 0})
-
-
-/**
- @brief Check if a @ref UsefulBuf is @ref NULLUsefulBuf or not.
-
- @param[in] UB The UsefulBuf to check.
-
- @return 1 if it is @ref NULLUsefulBuf, 0 if not.
- */
-static inline int UsefulBuf_IsNULL(UsefulBuf UB);
-
-
-/**
- @brief Check if a @ref UsefulBufC is @ref NULLUsefulBufC or not.
-
- @param[in] UB The @ref UsefulBufC to check.
-
- @return 1 if it is @c NULLUsefulBufC, 0 if not.
- */
-static inline int UsefulBuf_IsNULLC(UsefulBufC UB);
-
-
-/**
- @brief Check if a @ref UsefulBuf is empty or not.
-
- @param[in] UB The @ref UsefulBuf to check.
-
- @return 1 if it is empty, 0 if not.
-
- An "empty" @ref 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 @c len is zero. It doesn't matter what the @c ptr is.
-
- A lot of uses will not need to clearly distinguish a @c NULL @ref
- UsefulBuf from an empty one and can have the @c ptr @c NULL and the
- @c len 0.  However if a use of @ref UsefulBuf needs to make a
- distinction then @c ptr should not be @c NULL when the @ref UsefulBuf
- is considered empty, but not @c NULL.
- */
-static inline int UsefulBuf_IsEmpty(UsefulBuf UB);
-
-
-/**
- @brief Check if a @ref UsefulBufC is empty or not.
-
- @param[in] UB The @ref UsefulBufC to check.
-
- @return 1 if it is empty, 0 if not.
- */
-static inline int UsefulBuf_IsEmptyC(UsefulBufC UB);
-
-
-/**
- @brief Check if a @ref UsefulBuf is @ref NULLUsefulBuf or empty.
-
- @param[in] UB The @ref UsefulBuf to check.
-
- @return 1 if it is either @ref NULLUsefulBuf or empty, 0 if not.
- */
-static inline int UsefulBuf_IsNULLOrEmpty(UsefulBuf UB);
-
-
-/**
- @brief Check if a @ref UsefulBufC is @ref NULLUsefulBufC or empty.
-
- @param[in] UB The @ref UsefulBufC to check.
-
- @return 1 if it is either @ref NULLUsefulBufC or empty, 0 if not.
- */
-static inline int UsefulBuf_IsNULLOrEmptyC(UsefulBufC UB);
-
-
-/**
- @brief Convert a non-const @ref UsefulBuf to a const @ref UsefulBufC.
-
- @param[in] UB The @ref UsefulBuf to convert.
-
- @return A @ref UsefulBufC struct.
- */
-static inline UsefulBufC UsefulBuf_Const(const UsefulBuf UB);
-
-
-/**
- @brief Convert a const @ref UsefulBufC to a non-const @ref UsefulBuf.
-
- @param[in] UBC The @ref UsefulBuf to convert.
-
- @return A non-const @ref UsefulBuf struct.
- */
-static inline UsefulBuf UsefulBuf_Unconst(const UsefulBufC UBC);
-
-
-/**
- Convert a literal string to a @ref UsefulBufC.
-
- @c szString must be a literal string that @c sizeof() works on.  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})
-
-
-/**
- Convert a literal byte array to a @ref UsefulBufC.
-
- @c pBytes must be a literal string that @c sizeof() works on.  It
- will not work on non-literal arrays.
- */
-#define UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pBytes) \
-    ((UsefulBufC) {(pBytes), sizeof(pBytes)})
-
-
-/**
- Make an automatic variable named @c name of type @ref UsefulBuf and
- point it to a stack variable of the given @c size.
- */
-#define  UsefulBuf_MAKE_STACK_UB(name, size) \
-    uint8_t    __pBuf##name[(size)];\
-    UsefulBuf  name = {__pBuf##name , sizeof( __pBuf##name )}
-
-
-/**
- Make a byte array in to a @ref UsefulBuf. This is usually used on
- stack variables or static variables.  Also see @ref
- UsefulBuf_MAKE_STACK_UB.
- */
-#define UsefulBuf_FROM_BYTE_ARRAY(pBytes) \
-    ((UsefulBuf) {(pBytes), sizeof(pBytes)})
-
-
-/**
- @brief Convert a NULL-terminated string to a @ref UsefulBufC.
-
- @param[in] szString The string to convert.
-
- @return A @ref UsefulBufC struct.
-
- @c UsefulBufC.ptr points to the string so its lifetime must be
- maintained.
-
- The terminating \0 (NULL) is NOT included in the length.
- */
-static inline UsefulBufC UsefulBuf_FromSZ(const char *szString);
-
-
-/**
- @brief Copy one @ref UsefulBuf into another at an offset.
-
- @param[in] Dest     Destination buffer to copy into.
- @param[in] uOffset  The byte offset in @c Dest at which to copy to.
- @param[in] Src      The bytes to copy.
-
- @return Pointer and length of the copy or @ref NULLUsefulBufC.
-
- This fails and returns @ref NULLUsefulBufC if @c offset is beyond the
- size of @c Dest.
-
- This fails and returns @ref NULLUsefulBufC if the @c Src length plus
- @c uOffset is greater than the length of @c Dest.
-
- The results are undefined if @c Dest and @c Src overlap.
-
- This assumes that there is valid data in @c Dest up to @c
- uOffset. The @ref UsefulBufC returned starts at the beginning of @c
- Dest and goes to @c Src.len @c + @c uOffset.
- */
-UsefulBufC UsefulBuf_CopyOffset(UsefulBuf Dest, size_t uOffset, const UsefulBufC Src);
-
-
-/**
- @brief Copy one @ref UsefulBuf into another.
-
- @param[in] Dest  The destination buffer to copy into.
- @param[out] Src  The source to copy from.
-
- @return Filled in @ref UsefulBufC on success, @ref NULLUsefulBufC
-         on failure.
-
- This fails if @c Src.len is greater than @c Dest.len.
-
- Note that like @c memcpy(), the pointers are not checked and this
- will crash rather than return @ref NULLUsefulBufC if they are @c
- NULL or invalid.
-
- The results are undefined if @c Dest and @c Src overlap.
- */
-static inline UsefulBufC UsefulBuf_Copy(UsefulBuf Dest, const UsefulBufC Src);
-
-
-/**
- @brief Set all bytes in a @ref UsefulBuf to a value, for example to 0.
-
- @param[in] pDest  The destination buffer to copy into.
- @param[in] value  The value to set the bytes to.
-
- Note that like @c memset(), the pointer in @c pDest is not checked
- and this will crash if @c NULL or invalid.
- */
-static inline UsefulBufC UsefulBuf_Set(UsefulBuf pDest, uint8_t value);
-
-
-/**
- @brief Copy a pointer into a @ref UsefulBuf.
-
- @param[in,out] Dest  The destination buffer to copy into.
- @param[in] ptr       The source to copy from.
- @param[in] uLen      Length of the source; amount to copy.
-
- @return 0 on success, 1 on failure.
-
- This fails and returns @ref NULLUsefulBufC if @c uLen is greater than
- @c pDest->len.
-
- Note that like @c memcpy(), the pointers are not checked and this
- will crash, rather than return 1 if they are @c NULL or invalid.
- */
-static inline UsefulBufC UsefulBuf_CopyPtr(UsefulBuf Dest,
-                                           const void *ptr,
-                                           size_t uLen);
-
-
-/**
-  @brief Returns a truncation of a @ref UsefulBufC.
-
-  @param[in] UB       The buffer to get the head of.
-  @param[in] uAmount  The number of bytes in the head.
-
-  @return A @ref UsefulBufC that is the head of UB.
- */
-static inline UsefulBufC UsefulBuf_Head(UsefulBufC UB, size_t uAmount);
-
-
-/**
- @brief  Returns bytes from the end of a @ref 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 @ref UsefulBufC that is the tail of @c UB or @ref NULLUsefulBufC
-         if @c uAmount is greater than the length of the @ref UsefulBufC.
-
- If @c UB.ptr is @c NULL, but @c UB.len is not zero, then the result will
- be a @ref UsefulBufC with a @c NULL @c ptr and @c len with the length
- of the tail.
- */
-static inline UsefulBufC UsefulBuf_Tail(UsefulBufC UB, size_t uAmount);
-
-
-/**
- @brief Compare one @ref UsefulBufC to another.
-
- @param[in] UB1  The first buffer to compare.
- @param[in] UB2  The second buffer to compare.
-
- @return 0, positive or negative value.
-
- Returns a negative value if @c UB1 if is less than @c UB2. @c UB1 is
- less than @c UB2 if it is shorter or the first byte that is not the
- same is less.
-
- Returns 0 if the inputs are the same.
-
- Returns a positive value if @c UB2 is less than @c 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 @c memcmp() ).
- */
-int UsefulBuf_Compare(const UsefulBufC UB1, const UsefulBufC UB2);
-
-
-/**
- @brief Find first byte that is not a particular byte value.
-
- @param[in] UB     The destination buffer for byte comparison.
- @param[in] uValue The byte value to compare to.
-
- @return  Offset of first byte that isn't @c uValue or
-          @c SIZE_MAX if all bytes are @c uValue.
-
- Note that unlike most comparison functions, 0
- does not indicate a successful comparison, so the
- test for match is:
-
-      UsefulBuf_IsValue(...) == SIZE_MAX
-
- If @c UB is null or empty, there is no match
- and 0 is returned.
- */
-size_t UsefulBuf_IsValue(const UsefulBufC UB, uint8_t uValue);
-
-
-/**
- @brief Find one @ref UsefulBufC in another.
-
- @param[in] BytesToSearch  Buffer to search through.
- @param[in] BytesToFind    Buffer with bytes to be found.
-
- @return Position of found bytes or @c SIZE_MAX if not found.
- */
-size_t UsefulBuf_FindBytes(UsefulBufC BytesToSearch, UsefulBufC BytesToFind);
-
-
-#if 1 // NOT_DEPRECATED
-/** Deprecated macro; use @ref UsefulBuf_FROM_SZ_LITERAL instead */
-#define SZLiteralToUsefulBufC(szString) \
-    ((UsefulBufC) {(szString), sizeof(szString)-1})
-
-/** Deprecated macro; use UsefulBuf_MAKE_STACK_UB instead */
-#define  MakeUsefulBufOnStack(name, size) \
-    uint8_t    __pBuf##name[(size)];\
-    UsefulBuf  name = {__pBuf##name , sizeof( __pBuf##name )}
-
-/** Deprecated macro; use @ref UsefulBuf_FROM_BYTE_ARRAY_LITERAL instead */
-#define ByteArrayLiteralToUsefulBufC(pBytes) \
-    ((UsefulBufC) {(pBytes), sizeof(pBytes)})
-
-/** Deprecated function; use UsefulBuf_Unconst() instead */
-static inline UsefulBuf UsefulBufC_Unconst(const UsefulBufC UBC)
-{
-    return (UsefulBuf){(void *)UBC.ptr, UBC.len};
-}
-#endif
-
-
-
-
-/**
- @brief Copy a @c float to a @c uint32_t.
-
- @param[in] f  Float value to copy.
-
- @return  A @c uint32_t with the float bits.
-
- Convenience function to avoid type punning, compiler warnings and
- such. The optimizer usually reduces this to a simple assignment.  This
- is a crusty corner of C.
- */
-static inline uint32_t UsefulBufUtil_CopyFloatToUint32(float f);
-
-
-/**
- @brief Copy a @c double to a @c uint64_t.
-
- @param[in] d  Double value to copy.
-
- @return  A @c uint64_t with the double bits.
-
- Convenience function to avoid type punning, compiler warnings and
- such. The optimizer usually reduces this to a simple assignment.  This
- is a crusty corner of C.
- */
-static inline uint64_t UsefulBufUtil_CopyDoubleToUint64(double d);
-
-
-/**
- @brief Copy a @c uint32_t to a @c float.
-
- @param[in] u32  Integer value to copy.
-
- @return  The value as a @c float.
-
- Convenience function to avoid type punning, compiler warnings and
- such. The optimizer usually reduces this to a simple assignment.  This
- is a crusty corner of C.
- */
-static inline float UsefulBufUtil_CopyUint32ToFloat(uint32_t u32);
-
-
-/**
- @brief Copy a @c uint64_t to a @c double.
-
- @param[in] u64  Integer value to copy.
-
- @return  The value as a @c double.
-
- Convenience function to avoid type punning, compiler warnings and
- such. The optimizer usually reduces this to a simple assignment.  This
- is a crusty corner of C.
- */
-static inline double UsefulBufUtil_CopyUint64ToDouble(uint64_t u64);
-
-
-
-
-/**
- UsefulOutBuf is a structure and functions (an object) for serializing
- data into a buffer when encoding a network protocol or writing data
- to file.
-
- The main idea is that all the pointer manipulation is performed by
- @ref UsefulOutBuf functions so the caller doesn't have to do any
- pointer manipulation.  The pointer manipulation is centralized.  This
- code will have been reviewed and written carefully so it spares the
- caller of much of this work and results in safer code with less work.
-
- The @ref UsefulOutBuf methods that 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.
-
- There is no way to ever write off the end of that buffer when calling
- the @c UsefulOutBuf_AddXxx() and @c UsefulOutBuf_InsertXxx()
- functions.
-
- The functions to add data do not return an error. The working model
- is that all calls to add data are made without an error check. Errors
- are just checked for once after all the data has been added before the
- and before serialized data is to be used. This makes the calling code
- cleaner.
-
- There is a utility function to get the error status anytime along the
- way for a special circumstance. 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:
-
-    - Initialize by calling @ref UsefulOutBuf_Init(). The output
-      buffer given to it can be from the heap, stack or
-      otherwise. @ref UsefulOutBuf_MakeOnStack is a convenience macro
-      that makes a buffer on the stack and initializes it.
-
-    - Call methods like UsefulOutBuf_InsertString(),
-      UsefulOutBuf_AppendUint32() and UsefulOutBuf_InsertUsefulBuf()
-      to output data. The append calls add data to the end of the
-      valid data. The insert calls take a position argument.
-
-    - Call UsefulOutBuf_OutUBuf() or UsefulOutBuf_CopyOut() to see
-      there were no errors and to get the serialized output bytes.
-
- @ref UsefulOutBuf can be used in a size calculation mode to calculate
- the size of output that would be generated. This is useful to
- calculate the size of a buffer that is to be allocated to hold the
- output. To use @ref UsefulOutBuf in this mode, call
- UsefulOutBuf_Init() with the @c Storage @ref UsefulBuf as
- @c (UsefulBuf){NULL,MAX_UINT32}. Then call all the Insert and Add
- functions. No attempt will made to actually copy data, so only the
- lengths have to be valid for these calls.
-
- Methods like UsefulOutBuf_InsertUint64() always output in network
- bytes order (big endian).
-
- The possible errors are:
-  - The @ref UsefulOutBuf was not initialized or was corrupted.
-
-  - An attempt was made to add data that will not fit.
-
-  - An attempt was made to insert data at a position beyond the end of
-    the buffer.
-
-  - An attempt was made to insert data at a position beyond the valid
-    data in the buffer.
-
- 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 easier to read, and easier
- to review.
-
- A @ref UsefulOutBuf is small and can go on the stack:
-   - 32 bytes (27 bytes plus alignment padding) on a 64-bit machine
-   - 16 bytes (15 bytes plus alignment padding) on a 32-bit machines
- */
-typedef struct useful_out_buf {
-   // PRIVATE DATA STRUCTURE
-   UsefulBuf  UB;       // Memory that is being output to
-   size_t     data_len; // length of the data
-   uint16_t   magic;    // Used to detect corruption and lack of initialization
-   uint8_t    err;
-} UsefulOutBuf;
-
-
-/**
- @brief Initialize and supply the actual output buffer.
-
- @param[out] pUOutBuf  The @ref UsefulOutBuf to initialize.
- @param[in] Storage    Buffer to output into.
-
- Initializes  the @ref UsefulOutBuf with storage. Sets the current
- position to the beginning of the buffer clears the error.
-
- This must be called before the @ref UsefulOutBuf is used.
- */
-void UsefulOutBuf_Init(UsefulOutBuf *pUOutBuf, UsefulBuf Storage);
-
-
-/**
- Convenience macro to make a @ref UsefulOutBuf on the stack and
- initialize it with a stack buffer of the given size. The variable
- will be named @c name.
- */
-#define  UsefulOutBuf_MakeOnStack(name, size) \
-   uint8_t       __pBuf##name[(size)];\
-   UsefulOutBuf  name;\
-   UsefulOutBuf_Init(&(name), (UsefulBuf){__pBuf##name, (size)});
-
-
-/**
- @brief Reset a @ref UsefulOutBuf for re use
-
- @param[in] pUOutBuf Pointer to the @ref UsefulOutBuf
-
- This sets the amount of data in the output buffer to none and clears
- the error state.
-
- The output buffer is still the same one and size as from the
- UsefulOutBuf_Init() call.
-
- This doesn't zero the data, just resets to 0 bytes of valid data.
- */
-static inline void UsefulOutBuf_Reset(UsefulOutBuf *pUOutBuf);
-
-
-/**
- @brief Returns position of end of data in the @ref UsefulOutBuf.
-
- @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
-
- @return position of end of data.
-
- On a freshly initialized @ref UsefulOutBuf with no data added, this
- will return 0. After 10 bytes have been added, it will return 10 and
- so on.
-
- Generally callers will not need this function for most uses of @ref
- UsefulOutBuf.
- */
-static inline size_t UsefulOutBuf_GetEndPosition(UsefulOutBuf *pUOutBuf);
-
-
-/**
- @brief Returns whether any data has been added to the @ref UsefulOutBuf.
-
- @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
-
- @return 1 if output position is at start.
- */
-static inline int UsefulOutBuf_AtStart(UsefulOutBuf *pUOutBuf);
-
-
-/**
- @brief Inserts bytes into the @ref UsefulOutBuf.
-
- @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
- @param[in] NewData   The bytes to insert.
- @param[in] uPos      Index in output buffer at which to insert.
-
- @c 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 @c
- 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 are slid to
- the right to make room for the new data.
-
- Overlapping buffers are OK. @c NewData can point to data in the
- output buffer.
-
- If an error occurs an error state is set in the @ref UsefulOutBuf. No
- error is returned.  All subsequent attempts to add data will do
- nothing.
-
- The intended use is that all additions are made without checking for
- an error. The error will be taken into account when
- UsefulOutBuf_OutUBuf() returns @c NullUsefulBufC.
- UsefulOutBuf_GetError() can also be called to check for an error.
- */
-void UsefulOutBuf_InsertUsefulBuf(UsefulOutBuf *pUOutBuf,
-                                  UsefulBufC NewData,
-                                  size_t uPos);
-
-
-/**
- @brief Insert a data buffer into the @ref UsefulOutBuf.
-
- @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
- @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
- @ref UsefulBufC.
- */
-static inline void UsefulOutBuf_InsertData(UsefulOutBuf *pUOutBuf,
-                                           const void *pBytes,
-                                           size_t uLen,
-                                           size_t uPos);
-
-
-/**
- @brief Insert a NULL-terminated string into the UsefulOutBuf.
-
- @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
- @param[in] szString  NULL-terminated string to insert.
- @param[in] uPos      Index in output buffer at which to insert.
- */
-static inline void UsefulOutBuf_InsertString(UsefulOutBuf *pUOutBuf,
-                                             const char *szString,
-                                             size_t uPos);
-
-
-/**
- @brief Insert a byte into the @ref UsefulOutBuf.
-
- @param[in] pUOutBuf  Pointer to the UsefulOutBuf.
- @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.
- */
-static inline void UsefulOutBuf_InsertByte(UsefulOutBuf *pUOutBuf,
-                                           uint8_t byte,
-                                           size_t uPos);
-
-
-/**
- @brief Insert a 16-bit integer into the @ref UsefulOutBuf.
-
- @param[in] pUOutBuf    Pointer to the @ref UsefulOutBuf.
- @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 two-byte integer is to be inserted.
-
- The integer will be inserted in network byte order (big endian).
- */
-static inline void UsefulOutBuf_InsertUint16(UsefulOutBuf *pUOutBuf,
-                                             uint16_t uInteger16,
-                                             size_t uPos);
-
-
-/**
- @brief Insert a 32-bit integer into the @ref UsefulOutBuf.
-
- @param[in] pUOutBuf    Pointer to the @ref UsefulOutBuf.
- @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 four-byte integer is to be inserted.
-
- The integer will be inserted in network byte order (big endian).
- */
-static inline void UsefulOutBuf_InsertUint32(UsefulOutBuf *pUOutBuf,
-                                             uint32_t uInteger32,
-                                             size_t uPos);
-
-
-/**
- @brief Insert a 64-bit integer into the @ref UsefulOutBuf.
-
- @param[in] pUOutBuf    Pointer to the @ref UsefulOutBuf.
- @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 an eight-byte integer is to be inserted.
-
- The integer will be inserted in network byte order (big endian).
- */
-static inline void UsefulOutBuf_InsertUint64(UsefulOutBuf *pUOutBuf,
-                                             uint64_t uInteger64,
-                                             size_t uPos);
-
-
-/**
- @brief Insert a @c float into the @ref UsefulOutBuf.
-
- @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
- @param[in] f         @c float 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 @c float is to be inserted.
-
- The @c float will be inserted in network byte order (big endian).
- */
-static inline void UsefulOutBuf_InsertFloat(UsefulOutBuf *pUOutBuf,
-                                            float f,
-                                            size_t uPos);
-
-
-/**
- @brief Insert a @c double into the @ref UsefulOutBuf.
-
- @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
- @param[in] d         @c double  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 @c double is to be inserted.
-
- The @c double will be inserted in network byte order (big endian).
- */
-static inline void UsefulOutBuf_InsertDouble(UsefulOutBuf *pUOutBuf,
-                                             double d,
-                                             size_t uPos);
-
-
-/**
- @brief Append a @ref UsefulBuf into the @ref UsefulOutBuf.
-
- @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
- @param[in] NewData   The @ref 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 *pUOutBuf,
-                                                UsefulBufC NewData);
-
-
-/**
- @brief Append bytes to the @ref UsefulOutBuf.
-
- @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
- @param[in] pBytes    Pointer to bytes to append.
- @param[in] uLen      Length of @c pBytes to append.
-
- See UsefulOutBuf_InsertData() for details. This does the same
- with the insertion point at the end of the valid data.
- */
-static inline void UsefulOutBuf_AppendData(UsefulOutBuf *pUOutBuf,
-                                           const void *pBytes,
-                                           size_t uLen);
-
-
-/**
- @brief Append a NULL-terminated string to the @ref UsefulOutBuf
-
- @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
- @param[in] szString  NULL-terminated string to append.
- */
-static inline void UsefulOutBuf_AppendString(UsefulOutBuf *pUOutBuf,
-                                             const char *szString);
-
-
-/**
- @brief Append a byte to the @ref UsefulOutBuf
-
- @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
- @param[in] byte      Bytes to append.
-
- See UsefulOutBuf_InsertByte() for details. This does the same
- with the insertion point at the end of the valid data.
- */
-static inline void UsefulOutBuf_AppendByte(UsefulOutBuf *pUOutBuf,
-                                           uint8_t byte);
-
-
-/**
- @brief Append an integer to the @ref UsefulOutBuf
-
- @param[in] pUOutBuf    Pointer to the @ref UsefulOutBuf.
- @param[in] uInteger16  Integer to append.
-
- See UsefulOutBuf_InsertUint16() 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 *pUOutBuf,
-                                             uint16_t uInteger16);
-
-
-/**
- @brief Append an integer to the @ref UsefulOutBuf
-
- @param[in] pUOutBuf    Pointer to the @ref UsefulOutBuf.
- @param[in] uInteger32  Integer to append.
-
- See UsefulOutBuf_InsertUint32() 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 *pUOutBuf,
-                                             uint32_t uInteger32);
-
-
-/**
- @brief Append an integer to the @ref UsefulOutBuf
-
- @param[in] pUOutBuf    Pointer to the @ref UsefulOutBuf.
- @param[in] uInteger64  Integer to append.
-
- See UsefulOutBuf_InsertUint64() 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 *pUOutBuf,
-                                             uint64_t uInteger64);
-
-
-/**
- @brief Append a @c float to the @ref UsefulOutBuf
-
- @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
- @param[in] f         @c float to append.
-
- See UsefulOutBuf_InsertFloat() 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 *pUOutBuf,
-                                            float f);
-
-
-/**
- @brief Append a @c double to the @ref UsefulOutBuf
-
- @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
- @param[in] d         @c double to append.
-
- See UsefulOutBuf_InsertDouble() 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 *pUOutBuf,
-                                             double d);
-
-
-/**
- @brief Returns the current error status.
-
- @param[in] pUOutBuf Pointer to the @ref 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
-   - current position is off end of buffer (probably corrupted or uninitialized)
-   - detect corruption / uninitialized by bad magic number
- */
-static inline int UsefulOutBuf_GetError(UsefulOutBuf *pUOutBuf);
-
-
-/**
- @brief Returns number of bytes unused used in the output buffer.
-
- @param[in] pUOutBuf Pointer to the @ref 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.
- */
-static inline size_t UsefulOutBuf_RoomLeft(UsefulOutBuf *pUOutBuf);
-
-
-/**
- @brief Returns 1 if some number of bytes will fit in the @ref UsefulOutBuf.
-
- @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf
- @param[in] uLen      Number of bytes for which to check
-
- @return 1 if @c uLen bytes will fit, 0 if not.
-
- Because of the error handling strategy and checks in
- UsefulOutBuf_InsertUsefulBuf() it is usually not necessary to use
- this.
- */
-static inline int UsefulOutBuf_WillItFit(UsefulOutBuf *pUOutBuf, size_t uLen);
-
-
- /**
- @brief Returns 1 if buffer given to UsefulOutBuf_Init() was @c NULL.
-
- @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf
-
- @return 1 if buffer given to UsefulOutBuf_Init() was @c NULL.
-
- Giving a @c NULL output buffer to UsefulOutBuf_Init() is used
- when just calculating the length of the encoded data.
- */
-static inline int UsefulOutBuf_IsBufferNULL(UsefulOutBuf *pUOutBuf);
-
-
-/**
-   @brief Returns the resulting valid data in a UsefulOutBuf
-
-   @param[in] pUOutBuf Pointer to the @ref UsefulOutBuf.
-
-   @return The valid data in @ref UsefulOutBuf or
-           @ref NULLUsefulBufC if there was an error adding data.
-
-   The storage for the returned data is the @c 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.
- */
-UsefulBufC UsefulOutBuf_OutUBuf(UsefulOutBuf *pUOutBuf);
-
-
-/**
- @brief Copies the valid data into a supplied buffer
-
- @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
- @param[out] Dest     The destination buffer to copy into.
-
- @return Pointer and length of copied data or @c NULLUsefulBufC
-         if it will not fit in the @c Dest buffer.
-
- This is the same as UsefulOutBuf_OutUBuf() except it copies the data
- to @c Dest.
-*/
-UsefulBufC UsefulOutBuf_CopyOut(UsefulOutBuf *pUOutBuf, UsefulBuf Dest);
-
-
-
-
-/**
- @ref UsefulInputBuf is the counterpart to @ref UsefulOutBuf and is
- for parsing data read or received.  Initialize it with the data from
- the network. Then use the functions here to get data chunks of
- various types. A position cursor is maintained internally.
-
- As long as the functions here are used, there will never be a
- reference off the end of the given buffer. This is true even if they
- care called incorrectly, an attempt is made to seek of the end of the
- buffer, etc. This makes it easier to write safe and correct code.
- For example, the QCBOR decoder implementation is safer and easier to
- review through its use of @ref UsefulInputBuf.
-
- @ref UsefulInputBuf maintains an internal error state.  The
- intended use is that data chunks can be fetched without error
- checking until the end.  Once data has been requested off the end of
- the buffer, the error state is entered. In the error state the
- @c UsefulInputBuf_GetXxxx() functions return 0, or @c NULL or
- @ref NULLUsefulBufC. As long as null are not dereferenced, the
- error check can be put off until the end, simplifying the calling
- 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 inline functions are used to keep code size down. The code
- optimizer, particularly with the @c -Os or @c -O3, also reduces code
- size a lot. The only non-inline code is UsefulInputBuf_GetBytes()
- which is less than 100 bytes so use of @ref 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
- */
-typedef struct useful_input_buf {
-   // PRIVATE DATA STRUCTURE
-   UsefulBufC UB;     // Data being parsed
-   size_t     cursor; // Current offset in data being parse
-   uint16_t   magic;  // Check for corrupted or uninitialized UsefulInputBuf
-   uint8_t    err;    // Set request goes off end or magic number is bad
-} UsefulInputBuf;
-
-#define UIB_MAGIC (0xB00F)
-
-
-/**
- @brief Initialize the UsefulInputBuf structure before use.
-
- @param[in] pUInBuf  Pointer to the UsefulInputBuf instance.
- @param[in] UB       The data to parse.
- */
-static inline void UsefulInputBuf_Init(UsefulInputBuf *pUInBuf, UsefulBufC UB);
-
-
-/**
- @brief Returns current position in input buffer.
-
- @param[in] pUInBuf  Pointer to the UsefulInputBuf.
-
- @return Integer position of the cursor.
-
- The position that the next bytes will be returned from.
- */
-static size_t UsefulInputBuf_Tell(UsefulInputBuf *pUInBuf);
-
-
-/**
- @brief Sets the current position in input buffer.
-
- @param[in] pUInBuf  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 void UsefulInputBuf_Seek(UsefulInputBuf *pUInBuf, size_t uPos);
-
-
-/**
- @brief Returns the number of bytes from the cursor to the end of the buffer,
- the unconsumed bytes.
-
- @param[in] pUInBuf  Pointer to the UsefulInputBuf.
-
- @return Number of bytes unconsumed or 0 on error.
-
- This is a critical function for input length validation.
-
- Returns 0 if the cursor it invalid or corruption of the structure is
- detected.
- */
-static size_t UsefulInputBuf_BytesUnconsumed(UsefulInputBuf *pUInBuf);
-
-
-/**
- @brief Check if there are any unconsumed bytes.
-
- @param[in] pUInBuf  Pointer to the UsefulInputBuf.
- @param[in] uLen     Number of bytes to check availability for.
-
- @return 1 if @c uLen bytes are available after the cursor, and 0 if not.
- */
-static int UsefulInputBuf_BytesAvailable(UsefulInputBuf *pUInBuf, size_t uLen);
-
-
-/**
- @brief Get pointer to bytes out of the input buffer.
-
- @param[in] pUInBuf  Pointer to the UsefulInputBuf.
- @param[in] uNum     Number of bytes to get.
-
- @return Pointer to bytes.
-
- This consumes @c uNum bytes from the input buffer. It returns a
- pointer to the start of the @c uNum bytes.
-
- If there are not @c uNum bytes in the input buffer, @c NULL will be
- returned and an error will be set.
-
- It advances the current position by @c uNum bytes.
- */
-const void * UsefulInputBuf_GetBytes(UsefulInputBuf *pUInBuf, size_t uNum);
-
-
-/**
- @brief Get @ref UsefulBuf out of the input buffer.
-
- @param[in] pUInBuf  Pointer to the UsefulInputBuf.
- @param[in] uNum     Number of bytes to get.
-
- @return A @ref UsefulBufC with ptr and length of bytes consumed.
-
- This consumes @c uNum bytes from the input buffer and returns the
- pointer and length for them as a @ref UsefulBufC. The length returned
- will always be @c uNum.
-
- If there are not @c uNum bytes in the input buffer, @ref NULLUsefulBufC
- will be returned and the error state is set.
-
- It advances the current position by @c uNum bytes.
- */
-static inline UsefulBufC UsefulInputBuf_GetUsefulBuf(UsefulInputBuf *pUInBuf, size_t uNum);
-
-
-/**
- @brief Get a byte out of the input buffer.
-
- @param[in] pUInBuf  Pointer to the @ref 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,
- but you may not have to do that right away.  Check the error state
- with UsefulInputBuf_GetError().  You can also know you are in the
- error state if UsefulInputBuf_GetBytes() returns @c NULL or the @c
- ptr from UsefulInputBuf_GetUsefulBuf() is @c NULL.
-
- It advances the current position by 1 byte.
- */
-static inline uint8_t UsefulInputBuf_GetByte(UsefulInputBuf *pUInBuf);
-
-
-/**
- @brief Get a @c uint16_t out of the input buffer.
-
- @param[in] pUInBuf  Pointer to the UsefulInputBuf.
-
- @return The @c uint16_t.
-
- See UsefulInputBuf_GetByte(). This works the same, except it returns
- a @c uint16_t and two bytes are consumed.
-
- The input bytes must be in network order (big endian).
- */
-static inline uint16_t UsefulInputBuf_GetUint16(UsefulInputBuf *pUInBuf);
-
-
-/**
- @brief Get a uint32_t out of the input buffer.
-
- @param[in] pUInBuf  Pointer to the UsefulInputBuf.
-
- @return The @c uint32_t.
-
- See UsefulInputBuf_GetByte(). This works the same, except it returns
- a @c uint32_t and four bytes are consumed.
-
- The input bytes must be in network order (big endian).
- */
-static uint32_t UsefulInputBuf_GetUint32(UsefulInputBuf *pUInBuf);
-
-
-/**
- @brief Get a uint64_t out of the input buffer.
-
- @param[in] pUInBuf  Pointer to the UsefulInputBuf.
-
- @return The uint64_t.
-
- See UsefulInputBuf_GetByte(). This works the same, except it returns
- a @c uint64_t and eight bytes are consumed.
-
- The input bytes must be in network order (big endian).
- */
-static uint64_t UsefulInputBuf_GetUint64(UsefulInputBuf *pUInBuf);
-
-
-/**
- @brief Get a float out of the input buffer.
-
- @param[in] pUInBuf  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 float UsefulInputBuf_GetFloat(UsefulInputBuf *pUInBuf);
-
-
-/**
- @brief Get a double out of the input buffer.
-
- @param[in] pUInBuf  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 double UsefulInputBuf_GetDouble(UsefulInputBuf *pUInBuf);
-
-
-/**
- @brief Get the error status.
-
- @param[in] pUInBuf  Pointer to the @ref UsefulInputBuf.
-
- @return 0 if there is no error, 1 if there is.
-
- The error state is entered for one of these reasons:
- - Attempt to fetch data past the end of the buffer
- - Attempt to seek to a position past the end of the buffer
- - Attempt to get data from an uninitialized  or corrupt instance
-   of @ref UsefulInputBuf
-
- Once in the error state, it can only be cleared by calling
- UsefulInputBuf_Init().
-
- You may be able to only check the error state at the end after all
- the UsefulInputBuf_GetXxxx() calls have been made, 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 int UsefulInputBuf_GetError(UsefulInputBuf *pUInBuf);
-
-
-
-
-/*----------------------------------------------------------
- Inline implementations.
- */
-static inline int UsefulBuf_IsNULL(UsefulBuf UB)
-{
-   return !UB.ptr;
-}
-
-
-static inline int UsefulBuf_IsNULLC(UsefulBufC UB)
-{
-   return !UB.ptr;
-}
-
-
-static inline int UsefulBuf_IsEmpty(UsefulBuf UB)
-{
-   return !UB.len;
-}
-
-
-static inline int UsefulBuf_IsEmptyC(UsefulBufC UB)
-{
-   return !UB.len;
-}
-
-
-static inline int UsefulBuf_IsNULLOrEmpty(UsefulBuf UB)
-{
-   return UsefulBuf_IsEmpty(UB) || UsefulBuf_IsNULL(UB);
-}
-
-
-static inline int UsefulBuf_IsNULLOrEmptyC(UsefulBufC UB)
-{
-   return UsefulBuf_IsEmptyC(UB) || UsefulBuf_IsNULLC(UB);
-}
-
-
-static inline UsefulBufC UsefulBuf_Const(const UsefulBuf UB)
-{
-   return (UsefulBufC){UB.ptr, UB.len};
-}
-
-
-static inline UsefulBuf UsefulBuf_Unconst(const UsefulBufC UBC)
-{
-   return (UsefulBuf){(void *)UBC.ptr, UBC.len};
-}
-
-
-static inline UsefulBufC UsefulBuf_FromSZ(const char *szString)
-{
-   return ((UsefulBufC) {szString, strlen(szString)});
-}
-
-
-static inline UsefulBufC UsefulBuf_Copy(UsefulBuf Dest, const UsefulBufC Src)
-{
-   return UsefulBuf_CopyOffset(Dest, 0, Src);
-}
-
-
-static inline UsefulBufC UsefulBuf_Set(UsefulBuf pDest, uint8_t value)
-{
-   memset(pDest.ptr, value, pDest.len);
-   return (UsefulBufC){pDest.ptr, pDest.len};
-}
-
-
-static inline UsefulBufC UsefulBuf_CopyPtr(UsefulBuf Dest, const void *ptr, size_t len)
-{
-   return UsefulBuf_Copy(Dest, (UsefulBufC){ptr, len});
-}
-
-
-static inline UsefulBufC UsefulBuf_Head(UsefulBufC UB, size_t uAmount)
-{
-   if(uAmount > UB.len) {
-      return NULLUsefulBufC;
-   }
-   return (UsefulBufC){UB.ptr, uAmount};
-}
-
-
-static inline UsefulBufC UsefulBuf_Tail(UsefulBufC UB, size_t uAmount)
-{
-   UsefulBufC ReturnValue;
-
-   if(uAmount > UB.len) {
-      ReturnValue = NULLUsefulBufC;
-   } else if(UB.ptr == NULL) {
-      ReturnValue = (UsefulBufC){NULL, UB.len - uAmount};
-   } else {
-      ReturnValue = (UsefulBufC){(uint8_t *)UB.ptr + uAmount, UB.len - uAmount};
-   }
-
-   return ReturnValue;
-}
-
-
-
-static inline uint32_t UsefulBufUtil_CopyFloatToUint32(float f)
-{
-   uint32_t u32;
-   memcpy(&u32, &f, sizeof(uint32_t));
-   return u32;
-}
-
-static inline uint64_t UsefulBufUtil_CopyDoubleToUint64(double d)
-{
-   uint64_t u64;
-   memcpy(&u64, &d, sizeof(uint64_t));
-   return u64;
-}
-
-static inline double UsefulBufUtil_CopyUint64ToDouble(uint64_t u64)
-{
-   double d;
-   memcpy(&d, &u64, sizeof(uint64_t));
-   return d;
-}
-
-static inline float UsefulBufUtil_CopyUint32ToFloat(uint32_t u32)
-{
-   float f;
-   memcpy(&f, &u32, sizeof(uint32_t));
-   return f;
-}
-
-
-
-
-static inline void UsefulOutBuf_Reset(UsefulOutBuf *pMe)
-{
-   pMe->data_len = 0;
-   pMe->err      = 0;
-}
-
-
-static inline size_t UsefulOutBuf_GetEndPosition(UsefulOutBuf *pMe)
-{
-   return pMe->data_len;
-}
-
-
-static inline int UsefulOutBuf_AtStart(UsefulOutBuf *pMe)
-{
-   return 0 == pMe->data_len;
-}
-
-
-static inline void UsefulOutBuf_InsertData(UsefulOutBuf *pMe,
-                                           const void *pBytes,
-                                           size_t uLen,
-                                           size_t uPos)
-{
-   UsefulBufC Data = {pBytes, uLen};
-   UsefulOutBuf_InsertUsefulBuf(pMe, Data, uPos);
-}
-
-
-static inline void UsefulOutBuf_InsertString(UsefulOutBuf *pMe,
-                                             const char *szString,
-                                             size_t uPos)
-{
-   UsefulOutBuf_InsertUsefulBuf(pMe,
-                                (UsefulBufC){szString, strlen(szString)},
-                                uPos);
-}
-
-
-static inline void UsefulOutBuf_InsertByte(UsefulOutBuf *me,
-                                           uint8_t byte,
-                                           size_t uPos)
-{
-   UsefulOutBuf_InsertData(me, &byte, 1, uPos);
-}
-
-
-static inline void UsefulOutBuf_InsertUint16(UsefulOutBuf *me,
-                                             uint16_t uInteger16,
-                                             size_t uPos)
-{
-   // See UsefulOutBuf_InsertUint64() for comments on this code
-
-   const void *pBytes;
-
-#if defined(USEFULBUF_CONFIG_BIG_ENDIAN)
-   pBytes = &uInteger16;
-
-#elif defined(USEFULBUF_CONFIG_HTON)
-   uint16_t uTmp = htons(uInteger16);
-   pBytes        = &uTmp;
-
-#elif defined(USEFULBUF_CONFIG_LITTLE_ENDIAN) && defined(USEFULBUF_CONFIG_BSWAP)
-   uint16_t uTmp = __builtin_bswap16(uInteger16);
-   pBytes = &uTmp;
-
-#else
-   uint8_t aTmp[2];
-
-   aTmp[0] = (uint8_t)((uInteger16 & 0xff00) >> 8);
-   aTmp[1] = (uint8_t)(uInteger16 & 0xff);
-
-   pBytes = aTmp;
-#endif
-
-   UsefulOutBuf_InsertData(me, pBytes, 2, uPos);
-}
-
-
-static inline void UsefulOutBuf_InsertUint32(UsefulOutBuf *pMe,
-                                             uint32_t uInteger32,
-                                             size_t uPos)
-{
-   // See UsefulOutBuf_InsertUint64() for comments on this code
-
-   const void *pBytes;
-
-#if defined(USEFULBUF_CONFIG_BIG_ENDIAN)
-   pBytes = &uInteger32;
-
-#elif defined(USEFULBUF_CONFIG_HTON)
-   uint32_t uTmp = htonl(uInteger32);
-   pBytes = &uTmp;
-
-#elif defined(USEFULBUF_CONFIG_LITTLE_ENDIAN) && defined(USEFULBUF_CONFIG_BSWAP)
-   uint32_t uTmp = __builtin_bswap32(uInteger32);
-
-   pBytes = &uTmp;
-
-#else
-   uint8_t aTmp[4];
-
-   aTmp[0] = (uint8_t)((uInteger32 & 0xff000000) >> 24);
-   aTmp[1] = (uint8_t)((uInteger32 & 0xff0000) >> 16);
-   aTmp[2] = (uint8_t)((uInteger32 & 0xff00) >> 8);
-   aTmp[3] = (uint8_t)(uInteger32 & 0xff);
-
-   pBytes = aTmp;
-#endif
-
-   UsefulOutBuf_InsertData(pMe, pBytes, 4, uPos);
-}
-
-static inline void UsefulOutBuf_InsertUint64(UsefulOutBuf *pMe,
-                                             uint64_t uInteger64,
-                                             size_t uPos)
-{
-   const void *pBytes;
-
-#if defined(USEFULBUF_CONFIG_BIG_ENDIAN)
-   // We have been told explicitly we are running on a big-endian
-   // machine. Network byte order is big endian, so just copy.  There
-   // is no issue with alignment here because uInter64 is always
-   // aligned (and it doesn't matter if pBytes is aligned).
-   pBytes = &uInteger64;
-
-#elif defined(USEFULBUF_CONFIG_HTON)
-   // Use system function to handle big- and little-endian. This works
-   // on both big- and little-endian machines, but hton() is not
-   // always available or in a standard place so it is not used by
-   // default. With some compilers and CPUs the code for this is very
-   // compact through use of a special swap instruction and on
-   // big-endian machines hton() will reduce to nothing.
-   uint64_t uTmp = htonll(uInteger64);
-
-   pBytes = &uTmp;
-
-#elif defined(USEFULBUF_CONFIG_LITTLE_ENDIAN) && defined(USEFULBUF_CONFIG_BSWAP)
-   // Use built-in function for byte swapping. This usually compiles
-   // to an efficient special byte swap instruction. Unlike hton() it
-   // does not do this conditionally on the CPU endianness, so this
-   // code is also conditional on USEFULBUF_CONFIG_LITTLE_ENDIAN
-   uint64_t uTmp = __builtin_bswap64(uInteger64);
-
-   pBytes = &uTmp;
-
-#else
-   // Default which works on every CPU with no dependency on anything
-   // from the CPU, compiler, libraries or OS.  This always works, but
-   // it is usually a little larger and slower than hton().
-   uint8_t aTmp[8];
-
-   aTmp[0] = (uint8_t)((uInteger64 & 0xff00000000000000) >> 56);
-   aTmp[1] = (uint8_t)((uInteger64 & 0xff000000000000) >> 48);
-   aTmp[2] = (uint8_t)((uInteger64 & 0xff0000000000) >> 40);
-   aTmp[3] = (uint8_t)((uInteger64 & 0xff00000000) >> 32);
-   aTmp[4] = (uint8_t)((uInteger64 & 0xff000000) >> 24);
-   aTmp[5] = (uint8_t)((uInteger64 & 0xff0000) >> 16);
-   aTmp[6] = (uint8_t)((uInteger64 & 0xff00) >> 8);
-   aTmp[7] = (uint8_t)(uInteger64 & 0xff);
-
-   pBytes = aTmp;
-#endif
-
-   // Do the insert
-   UsefulOutBuf_InsertData(pMe, pBytes, sizeof(uint64_t), uPos);
-}
-
-
-static inline void UsefulOutBuf_InsertFloat(UsefulOutBuf *pMe,
-                                            float f,
-                                            size_t uPos)
-{
-   UsefulOutBuf_InsertUint32(pMe, UsefulBufUtil_CopyFloatToUint32(f), uPos);
-}
-
-
-static inline void UsefulOutBuf_InsertDouble(UsefulOutBuf *pMe,
-                                             double d,
-                                             size_t uPos)
-{
-   UsefulOutBuf_InsertUint64(pMe, UsefulBufUtil_CopyDoubleToUint64(d), uPos);
-}
-
-
-static inline void UsefulOutBuf_AppendUsefulBuf(UsefulOutBuf *pMe,
-                                                UsefulBufC NewData)
-{
-   // An append is just a insert at the end
-   UsefulOutBuf_InsertUsefulBuf(pMe, NewData, UsefulOutBuf_GetEndPosition(pMe));
-}
-
-
-static inline void UsefulOutBuf_AppendData(UsefulOutBuf *pMe,
-                                           const void *pBytes,
-                                           size_t uLen)
-{
-   UsefulBufC Data = {pBytes, uLen};
-   UsefulOutBuf_AppendUsefulBuf(pMe, Data);
-}
-
-
-static inline void UsefulOutBuf_AppendString(UsefulOutBuf *pMe,
-                                             const char *szString)
-{
-   UsefulOutBuf_AppendUsefulBuf(pMe, (UsefulBufC){szString, strlen(szString)});
-}
-
-
-static inline void UsefulOutBuf_AppendByte(UsefulOutBuf *pMe,
-                                           uint8_t byte)
-{
-   UsefulOutBuf_AppendData(pMe, &byte, 1);
-}
-
-
-static inline void UsefulOutBuf_AppendUint16(UsefulOutBuf *pMe,
-                                             uint16_t uInteger16)
-{
-   UsefulOutBuf_InsertUint16(pMe, uInteger16, UsefulOutBuf_GetEndPosition(pMe));
-}
-
-static inline void UsefulOutBuf_AppendUint32(UsefulOutBuf *pMe,
-                                             uint32_t uInteger32)
-{
-   UsefulOutBuf_InsertUint32(pMe, uInteger32, UsefulOutBuf_GetEndPosition(pMe));
-}
-
-
-static inline void UsefulOutBuf_AppendUint64(UsefulOutBuf *pMe,
-                                             uint64_t uInteger64)
-{
-   UsefulOutBuf_InsertUint64(pMe, uInteger64, UsefulOutBuf_GetEndPosition(pMe));
-}
-
-
-static inline void UsefulOutBuf_AppendFloat(UsefulOutBuf *pMe,
-                                            float f)
-{
-   UsefulOutBuf_InsertFloat(pMe, f, UsefulOutBuf_GetEndPosition(pMe));
-}
-
-
-static inline void UsefulOutBuf_AppendDouble(UsefulOutBuf *pMe,
-                                             double d)
-{
-   UsefulOutBuf_InsertDouble(pMe, d, UsefulOutBuf_GetEndPosition(pMe));
-}
-
-
-static inline int UsefulOutBuf_GetError(UsefulOutBuf *pMe)
-{
-   return pMe->err;
-}
-
-
-static inline size_t UsefulOutBuf_RoomLeft(UsefulOutBuf *pMe)
-{
-   return pMe->UB.len - pMe->data_len;
-}
-
-
-static inline int UsefulOutBuf_WillItFit(UsefulOutBuf *pMe, size_t uLen)
-{
-   return uLen <= UsefulOutBuf_RoomLeft(pMe);
-}
-
-
-static inline int UsefulOutBuf_IsBufferNULL(UsefulOutBuf *pMe)
-{
-   return pMe->UB.ptr == NULL;
-}
-
-
-
-static inline void UsefulInputBuf_Init(UsefulInputBuf *pMe, UsefulBufC UB)
-{
-   pMe->cursor = 0;
-   pMe->err    = 0;
-   pMe->magic  = UIB_MAGIC;
-   pMe->UB     = UB;
-}
-
-static inline size_t UsefulInputBuf_Tell(UsefulInputBuf *pMe)
-{
-   return pMe->cursor;
-}
-
-
-static inline void UsefulInputBuf_Seek(UsefulInputBuf *pMe, size_t uPos)
-{
-   if(uPos > pMe->UB.len) {
-      pMe->err = 1;
-   } else {
-      pMe->cursor = uPos;
-   }
-}
-
-
-static inline size_t UsefulInputBuf_BytesUnconsumed(UsefulInputBuf *pMe)
-{
-   // Code Reviewers: THIS FUNCTION DOES POINTER MATH
-
-   // Magic number is messed up. Either the structure got overwritten
-   // or was never initialized.
-   if(pMe->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
-   // as a defense in case there is a bug in this code or the struct is
-   // corrupted.
-   if(pMe->cursor > pMe->UB.len) {
-      return 0;
-   }
-
-   // subtraction can't go neative because of check above
-   return pMe->UB.len - pMe->cursor;
-}
-
-
-static inline int UsefulInputBuf_BytesAvailable(UsefulInputBuf *pMe, size_t uLen)
-{
-   return UsefulInputBuf_BytesUnconsumed(pMe) >= uLen ? 1 : 0;
-}
-
-
-static inline UsefulBufC UsefulInputBuf_GetUsefulBuf(UsefulInputBuf *pMe, size_t uNum)
-{
-   const void *pResult = UsefulInputBuf_GetBytes(pMe, uNum);
-   if(!pResult) {
-      return NULLUsefulBufC;
-   } else {
-      return (UsefulBufC){pResult, uNum};
-   }
-}
-
-
-static inline uint8_t UsefulInputBuf_GetByte(UsefulInputBuf *pMe)
-{
-   const void *pResult = UsefulInputBuf_GetBytes(pMe, sizeof(uint8_t));
-
-   // The ternery operator is subject to integer promotion, because the
-   // operands are smaller than int, so cast back to uint8_t is needed
-   // to be completely explicit about types (for static analyzers)
-   return (uint8_t)(pResult ? *(uint8_t *)pResult : 0);
-}
-
-static inline uint16_t UsefulInputBuf_GetUint16(UsefulInputBuf *pMe)
-{
-   const uint8_t *pResult = (const uint8_t *)UsefulInputBuf_GetBytes(pMe, sizeof(uint16_t));
-
-   if(!pResult) {
-      return 0;
-   }
-
-   // See UsefulInputBuf_GetUint64() for comments on this code
-#if defined(USEFULBUF_CONFIG_BIG_ENDIAN) || defined(USEFULBUF_CONFIG_HTON) || defined(USEFULBUF_CONFIG_BSWAP)
-   uint16_t uTmp;
-   memcpy(&uTmp, pResult, sizeof(uint16_t));
-
-#if defined(USEFULBUF_CONFIG_BIG_ENDIAN)
-   return uTmp;
-
-#elif defined(USEFULBUF_CONFIG_HTON)
-   return ntohs(uTmp);
-
-#else
-   return __builtin_bswap16(uTmp);
-
-#endif
-
-#else
-
-   // The operations here are subject to integer promotion because the
-   // operands are smaller than int. They will be promoted to unsigned
-   // int for the shift and addition. The cast back to uint16_t is  is needed
-   // to be completely explicit about types (for static analyzers)
-   return (uint16_t)((pResult[0] << 8) + pResult[1]);
-
-#endif
-}
-
-
-static inline uint32_t UsefulInputBuf_GetUint32(UsefulInputBuf *pMe)
-{
-   const uint8_t *pResult = (const uint8_t *)UsefulInputBuf_GetBytes(pMe, sizeof(uint32_t));
-
-   if(!pResult) {
-      return 0;
-   }
-
-   // See UsefulInputBuf_GetUint64() for comments on this code
-#if defined(USEFULBUF_CONFIG_BIG_ENDIAN) || defined(USEFULBUF_CONFIG_HTON) || defined(USEFULBUF_CONFIG_BSWAP)
-   uint32_t uTmp;
-   memcpy(&uTmp, pResult, sizeof(uint32_t));
-
-#if defined(USEFULBUF_CONFIG_BIG_ENDIAN)
-   return uTmp;
-
-#elif defined(USEFULBUF_CONFIG_HTON)
-   return ntohl(uTmp);
-
-#else
-   return __builtin_bswap32(uTmp);
-
-#endif
-
-#else
-   return ((uint32_t)pResult[0]<<24) +
-          ((uint32_t)pResult[1]<<16) +
-          ((uint32_t)pResult[2]<<8)  +
-           (uint32_t)pResult[3];
-#endif
-}
-
-
-static inline uint64_t UsefulInputBuf_GetUint64(UsefulInputBuf *pMe)
-{
-   const uint8_t *pResult = (const uint8_t *)UsefulInputBuf_GetBytes(pMe, sizeof(uint64_t));
-
-   if(!pResult) {
-      return 0;
-   }
-
-#if defined(USEFULBUF_CONFIG_BIG_ENDIAN) || defined(USEFULBUF_CONFIG_HTON) || defined(USEFULBUF_CONFIG_BSWAP)
-   // pResult will probably not be aligned.  This memcpy() moves the
-   // bytes into a temp variable safely for CPUs that can or can't do
-   // unaligned memory access. Many compilers will optimize the
-   // memcpy() into a simple move instruction.
-   uint64_t uTmp;
-   memcpy(&uTmp, pResult, sizeof(uint64_t));
-
-#if defined(USEFULBUF_CONFIG_BIG_ENDIAN)
-   // We have been told expliclity this is a big-endian CPU.  Since
-   // network byte order is big-endian, there is nothing to do.
-
-   return uTmp;
-
-#elif defined(USEFULBUF_CONFIG_HTON)
-   // We have been told to use ntoh(), the system function to handle
-   // big- and little-endian. This works on both big- and
-   // little-endian machines, but ntoh() is not always available or in
-   // a standard place so it is not used by default. On some CPUs the
-   // code for this is very compact through use of a special swap
-   // instruction.
-
-   return ntohll(uTmp);
-
-#else
-   // Little-endian (since it is not USEFULBUF_CONFIG_BIG_ENDIAN) and
-   // USEFULBUF_CONFIG_BSWAP (since it is not USEFULBUF_CONFIG_HTON).
-   // __builtin_bswap64() and friends are not conditional on CPU
-   // endianness so this must only be used on little-endian machines.
-
-   return __builtin_bswap64(uTmp);
-
-
-#endif
-
-#else
-   // This is the default code that works on every CPU and every
-   // endianness with no dependency on ntoh().  This works on CPUs
-   // that either allow or do not allow unaligned access. It will
-   // always work, but usually is a little less efficient than ntoh().
-
-   return   ((uint64_t)pResult[0]<<56) +
-            ((uint64_t)pResult[1]<<48) +
-            ((uint64_t)pResult[2]<<40) +
-            ((uint64_t)pResult[3]<<32) +
-            ((uint64_t)pResult[4]<<24) +
-            ((uint64_t)pResult[5]<<16) +
-            ((uint64_t)pResult[6]<<8)  +
-            (uint64_t)pResult[7];
-#endif
-}
-
-
-static inline float UsefulInputBuf_GetFloat(UsefulInputBuf *pMe)
-{
-   uint32_t uResult = UsefulInputBuf_GetUint32(pMe);
-
-   return uResult ? UsefulBufUtil_CopyUint32ToFloat(uResult) : 0;
-}
-
-
-static inline double UsefulInputBuf_GetDouble(UsefulInputBuf *pMe)
-{
-   uint64_t uResult = UsefulInputBuf_GetUint64(pMe);
-
-   return uResult ? UsefulBufUtil_CopyUint64ToDouble(uResult) : 0;
-}
-
-
-static inline int UsefulInputBuf_GetError(UsefulInputBuf *pMe)
-{
-   return pMe->err;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif  // _UsefulBuf_h
-
-
+#include "qcbor/UsefulBuf.h"
