Restructured includes to be in a subfolder and added `make install`. (#33)

Signed-off-by: Michael Eckel <michael.eckel@sit.fraunhofer.de>
diff --git a/inc/qcbor/UsefulBuf.h b/inc/qcbor/UsefulBuf.h
new file mode 100644
index 0000000..a8da83b
--- /dev/null
+++ b/inc/qcbor/UsefulBuf.h
@@ -0,0 +1,2134 @@
+/*============================================================================
+ 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
+
+