QCBOR: Add CBOR encoder / decoder library

QCBOR supports encoding and decoding of most
of the CBOR standard, RFC 7049. QCBOR is open
source maintained at
  https://github.com/laurencelundblade/QCBOR

Change-Id: I5632379e4a1fdb16e0df7f03dfa2374160b7ed7f
Signed-off-by: Laurence Lundblade <lgl@securitytheory.com>
diff --git a/lib/ext/qcbor/inc/UsefulBuf.h b/lib/ext/qcbor/inc/UsefulBuf.h
new file mode 100644
index 0000000..fa17b6c
--- /dev/null
+++ b/lib/ext/qcbor/inc/UsefulBuf.h
@@ -0,0 +1,1536 @@
+/*==============================================================================
+ Copyright (c) 2016-2018, The Linux Foundation.
+ Copyright (c) 2018-2019, Laurence Lundblade.
+ All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of The Linux Foundation nor the names of its
+      contributors, nor the name "Laurence Lundblade" may be used to
+      endorse or promote products derived from this software without
+      specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ ==============================================================================*/
+
+/*===================================================================================
+ FILE:  UsefulBuf.h
+
+ DESCRIPTION:  General purpose input and output buffers
+
+ EDIT HISTORY FOR FILE:
+
+ This section contains comments describing changes made to the module.
+ Notice that changes are listed in reverse chronological order.
+
+ when               who             what, where, why
+ --------           ----            ---------------------------------------------------
+ 12/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
+
+
+#include <stdint.h> // for uint8_t, uint16_t....
+#include <string.h> // for strlen, memcpy, memmove, memset
+#include <stddef.h> // for size_t
+
+/**
+ @file UsefulBuf.h
+
+ The goal of this code is to make buffer and pointer manipulation
+ easier and safer when working with binary data.
+
+ You use the UsefulBuf, UsefulOutBuf and UsefulInputBuf
+ structures to represent buffers rather than ad hoc pointers and lengths.
+
+ With these it will often be possible to write code that does little or no
+ direct pointer manipulation for copying and formatting data. For example
+ the QCBOR encoder was rewritten using these and has no direct pointer
+ manipulation.
+
+ While it is true that object code using these functions will be a little
+ larger and slower than a white-knuckle clever use of pointers might be, but
+ not by that much or enough to have an affect for most use cases. For
+ 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 -Os or -O3. The idea is that the inline
+ functions are easier to review and understand and the optimizer does
+ the work of making the code small.
+ */
+
+
+/*...... This is a ruler that is 80 characters long...........................*/
+
+/**
+ UsefulBufC and UsefulBuf are simple data structures to hold a pointer and
+ length for a binary data.  In C99 this data structure can be passed on the
+ stack making a lot of code cleaner than carrying around a pointer and
+ length as two parameters.
+
+ This is also conducive to secure code practice as the lengths are
+ always carried with the pointer and the convention for handling a
+ pointer and a length is clear.
+
+ While it might be possible to write buffer and pointer code more
+ efficiently in some use cases, the thought is that unless there is an
+ extreme need for performance (e.g., you are building a gigabit-per-second
+ IP router), it is probably better to have cleaner code you can be most
+ certain about the security of.
+
+ The non-const UsefulBuf is usually used to refer a buffer to be filled in.
+ The length is the size of the buffer.
+
+ The const UsefulBufC is usually used to refer to some data that has been
+ filled in. The length is amount of valid data pointed to.
+
+ A common use is to pass a UsefulBuf to a function, the function fills it
+ in, the function returns a UsefulBufC. The pointer is the same in both.
+
+ A UsefulBuf is NULL, it has no value, when the ptr in it is NULL.
+
+ There are utility functions for the following:
+  - Checking for UsefulBufs that are NULL, empty or both
+  - Copying, copying with offset, copying head or tail
+  - Comparing and finding substrings
+  - Initializating
+  - Create initialized const UsefulBufC from compiler literals
+  - Create initialized const UsefulBufC from NULL-terminated string
+  - Make an empty UsefulBuf on the stack
+
+ See also UsefulOutBuf. It is a richer structure that has both the size of
+ the valid data and the size of the buffer.
+
+ UsefulBuf is only 16 or 8 bytes on a 64- or 32-bit machine so it can go
+ on the stack and be a function parameter or return value.
+
+ UsefulBuf is kind of like the Useful Pot Pooh gave Eeyore on his birthday.
+ Eeyore's balloon fits beautifully, "it goes in and out like anything".
+
+*/
+typedef struct useful_buf_c {
+    const void *ptr;
+    size_t      len;
+} UsefulBufC;
+
+
+/**
+ The non-const UsefulBuf typically used for some allocated memory
+ that is to be filled in. The len is the amount of memory,
+ not the length of the valid data in the buffer.
+ */
+typedef struct useful_buf {
+   void  *ptr;
+   size_t len;
+} UsefulBuf;
+
+
+/**
+ A "NULL" UsefulBufC is one that has no value in the same way a NULL pointer has no value.
+ A UsefulBuf is NULL when the ptr field is NULL. It doesn't matter what len is.
+ See UsefulBuf_IsEmpty() for the distinction between NULL and empty.
+ */
+#define NULLUsefulBufC  ((UsefulBufC) {NULL, 0})
+
+/** A NULL UsefulBuf is one that has no memory associated the say way
+ NULL points to nothing. It does not matter what len is.
+ */
+#define NULLUsefulBuf   ((UsefulBuf) {NULL, 0})
+
+
+/**
+ @brief Check if a UsefulBuf is NULL or not
+
+ @param[in] UB The UsefulBuf to check
+
+ @return 1 if it is NULL, 0 if not.
+ */
+static inline int UsefulBuf_IsNULL(UsefulBuf UB) {
+   return !UB.ptr;
+}
+
+
+/**
+ @brief Check if a UsefulBufC is NULL or not
+
+ @param[in] UB The UsefulBufC to check
+
+ @return 1 if it is NULL, 0 if not.
+ */
+static inline int UsefulBuf_IsNULLC(UsefulBufC UB) {
+   return !UB.ptr;
+}
+
+
+/**
+ @brief Check if a UsefulBuf is empty or not
+
+ @param[in] UB The UsefulBuf to check
+
+ @return 1 if it is empty, 0 if not.
+
+ An "Empty" UsefulBuf is one that has a value and can be considered to be set,
+ but that value is of zero length.  It is empty when len is zero. It
+ doesn't matter what the ptr is.
+
+ A lot of uses will not need to clearly distinguish a NULL UsefulBuf
+ from an empty one and can have the ptr NULL and the len 0.  However
+ if a use of UsefulBuf needs to make a distinction then ptr should
+ not be NULL when the UsefulBuf is considered empty, but not NULL.
+
+ */
+static inline int UsefulBuf_IsEmpty(UsefulBuf UB) {
+   return !UB.len;
+}
+
+
+/**
+ @brief Check if a UsefulBufC is empty or not
+
+ @param[in] UB The UsefulBufC to check
+
+ @return 1 if it is empty, 0 if not.
+ */
+static inline int UsefulBuf_IsEmptyC(UsefulBufC UB) {
+   return !UB.len;
+}
+
+
+/**
+ @brief Check if a UsefulBuf is NULL or empty
+
+ @param[in] UB The UsefulBuf to check
+
+ @return 1 if it is either NULL or empty, 0 if not.
+ */
+static inline int UsefulBuf_IsNULLOrEmpty(UsefulBuf UB) {
+   return UsefulBuf_IsEmpty(UB) || UsefulBuf_IsNULL(UB);
+}
+
+
+/**
+ @brief Check if a UsefulBufC is NULL or empty
+
+ @param[in] UB The UsefulBufC to check
+
+ @return 1 if it is either NULL or empty, 0 if not.
+ */
+static inline int UsefulBuf_IsNULLOrEmptyC(UsefulBufC UB) {
+   return UsefulBuf_IsEmptyC(UB) || UsefulBuf_IsNULLC(UB);
+}
+
+
+/**
+ @brief Convert a non const UsefulBuf to a const UsefulBufC
+
+ @param[in] UB The UsefulBuf to convert
+
+ Returns: a UsefulBufC struct
+ */
+
+static inline UsefulBufC UsefulBuf_Const(const UsefulBuf UB)
+{
+   return (UsefulBufC){UB.ptr, UB.len};
+}
+
+
+/**
+ @brief Convert a const UsefulBufC to a non-const UsefulBuf
+
+ @param[in] UBC The UsefulBuf to convert
+
+ Returns: a non const UsefulBuf struct
+ */
+static inline UsefulBuf UsefulBuf_Unconst(const UsefulBufC UBC)
+{
+   return (UsefulBuf){(void *)UBC.ptr, UBC.len};
+}
+
+
+/**
+ Convert a literal string to a UsefulBufC.
+
+ szString must be a literal string that you can take sizeof.
+ This is better for literal strings than UsefulBuf_FromSZ()
+ because it generates less code. It will not work on
+ non-literal strings.
+
+ The terminating \0 (NULL) is NOT included in the length!
+
+ */
+#define UsefulBuf_FROM_SZ_LITERAL(szString) \
+    ((UsefulBufC) {(szString), sizeof(szString)-1})
+
+
+/**
+ Convert a literal byte array to a UsefulBufC.
+
+ pBytes must be a literal string that you can take sizeof.
+ It will not work on  non-literal arrays.
+
+ */
+#define UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pBytes) \
+    ((UsefulBufC) {(pBytes), sizeof(pBytes)})
+
+
+/**
+ Make an automatic variable with name of type UsefulBuf and point it to a stack
+ variable of the give 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 UsefulBuf
+ */
+#define UsefulBuf_FROM_BYTE_ARRAY(pBytes) \
+    ((UsefulBuf) {(pBytes), sizeof(pBytes)})
+
+/**
+ @brief Convert a NULL terminated string to a UsefulBufC.
+
+ @param[in] szString The string to convert
+
+ @return a UsefulBufC struct
+
+ UsefulBufC.ptr points to the string so it's lifetime
+ must be maintained.
+
+ The terminating \0 (NULL) is NOT included in the length!
+
+ */
+static inline UsefulBufC UsefulBuf_FromSZ(const char *szString){
+    return ((UsefulBufC) {szString, strlen(szString)});
+}
+
+
+/**
+ @brief Copy one UsefulBuf into another at an offset
+
+ @param[in] Dest Destiation buffer to copy into
+ @param[in] uOffset The byte offset in Dest at which to copy to
+ @param[in] Src The bytes to copy
+
+ @return Pointer and length of the copy
+
+ This fails and returns NULLUsefulBufC Src.len + uOffset > Dest.len.
+
+ Like memcpy, there is no check for NULL. If NULL is passed
+ this will crash.
+
+ There is an assumption that there is valid data in Dest up to
+ uOffset as the resulting UsefulBufC returned starts
+ at the beginning of Dest and goes to Src.len + uOffset.
+
+ */
+UsefulBufC UsefulBuf_CopyOffset(UsefulBuf Dest, size_t uOffset, const UsefulBufC Src);
+
+
+/**
+ @brief Copy one UsefulBuf into another
+
+ @param[in] Dest The destination buffer to copy into
+ @param[out] Src  The source to copy from
+
+ @return filled in UsefulBufC on success, NULLUsefulBufC on failure
+
+ This fails if Src.len is greater than Dest.len.
+
+ Note that like memcpy, the pointers are not checked and
+ this will crash, rather than return NULLUsefulBufC if
+ they are NULL or invalid.
+
+ Results are undefined if Dest and Src overlap.
+
+ */
+static inline UsefulBufC UsefulBuf_Copy(UsefulBuf Dest, const UsefulBufC Src) {
+   return UsefulBuf_CopyOffset(Dest, 0, Src);
+}
+
+
+/**
+ @brief Set all bytes in a UsefulBuf to a value, for example 0
+
+ @param[in] pDest The destination buffer to copy into
+ @param[in] value The value to set the bytes to
+
+ Note that like memset, the pointer in pDest is not checked and
+ this will crash if NULL or invalid.
+
+ */
+static inline UsefulBufC UsefulBuf_Set(UsefulBuf pDest, uint8_t value)
+{
+   memset(pDest.ptr, value, pDest.len);
+   return (UsefulBufC){pDest.ptr, pDest.len};
+}
+
+
+/**
+ @brief Copy a pointer into a UsefulBuf
+
+ @param[in,out] Dest The destination buffer to copy into
+ @param[in] ptr  The source to copy from
+ @param[in] len  Length of the source; amoutn to copy
+
+ @return 0 on success, 1 on failure
+
+ This fails and returns NULLUsefulBufC if len is greater than
+ pDest->len.
+
+ Note that like memcpy, the pointers are not checked and
+ this will crash, rather than return 1 if they are NULL
+ or invalid.
+
+ */
+inline static UsefulBufC UsefulBuf_CopyPtr(UsefulBuf Dest, const void *ptr, size_t len)
+{
+   return UsefulBuf_Copy(Dest, (UsefulBufC){ptr, len});
+}
+
+
+/**
+  @brief Returns a truncation of a UsefulBufC
+
+  @param[in] UB The buffer to get the head of
+  @param[in] uAmount The number of bytes in the head
+
+  @return A UsefulBufC that is the head of UB
+
+ */
+static inline UsefulBufC UsefulBuf_Head(UsefulBufC UB, size_t uAmount)
+{
+   if(uAmount > UB.len) {
+      return NULLUsefulBufC;
+   }
+   return (UsefulBufC){UB.ptr, uAmount};
+}
+
+
+/**
+ @brief  Returns bytes from the end of a UsefulBufC
+
+ @param[in] UB       The buffer to get the tail of
+ @param[in] uAmount  The offset from the start where the tail is to begin
+
+ @return A UsefulBufC that is the tail of UB or NULLUsefulBufC if
+         uAmount is greater than the length of the UsefulBufC
+
+ If the input UsefulBufC is NULL, but the len is not, then the
+ length of the tail will be calculated and returned along
+ with a NULL ptr.
+ */
+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;
+}
+
+
+/**
+ @brief Compare two UsefulBufCs
+
+ @param[in] UB1 The destination buffer to copy into
+ @param[in] UB2  The source to copy from
+
+ @return 0 if equal...
+
+ Returns a negative value if UB1 if is less than UB2. UB1 is
+ less than UB2 if it is shorter or the first byte that is not
+ the same is less.
+
+ Returns 0 if the UsefulBufs are the same.
+
+ Returns a positive value if UB2 is less than UB1.
+
+ All that is of significance is that the result is positive,
+ negative or 0. (This doesn't return the difference between
+ the first non-matching byte like memcmp).
+
+ */
+int UsefulBuf_Compare(const UsefulBufC UB1, const UsefulBufC UB2);
+
+
+/**
+ @brief Find one UsefulBuf in another
+
+ @param[in] BytesToSearch  UsefulBuf to search through
+ @param[in] BytesToFind    UsefulBuf with bytes to be found
+
+ @return position of found bytes or SIZE_MAX if not found.
+
+ */
+size_t UsefulBuf_FindBytes(UsefulBufC BytesToSearch, UsefulBufC BytesToFind);
+
+
+
+
+#if 0 // NOT_DEPRECATED
+/** Deprecated macro; use 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 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
+
+
+
+/*
+ Convenient functions to avoid type punning, compiler warnings and such
+ The optimizer reduces them to a simple assignment
+ This is a crusty corner of C. It shouldn't be this hard.
+ */
+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;
+}
+
+
+
+
+
+/**
+ UsefulOutBuf is a structure and functions (an object) that are good
+ for serializing data into a buffer such as is often done with network
+ protocols or data written to files.
+
+ The main idea is that all the pointer manipulation for adding data is
+ done by UsefulOutBuf functions so the caller doesn't have to do any.
+ All the pointer manipulation is centralized here.  This code will
+ have been reviewed and written carefully so it spares the caller of
+ much of this work and results in much safer code with much less work.
+
+ The functions to add data to the output buffer always check the
+ length and will never write off the end of the output buffer. If an
+ attempt to add data that will not fit is made, an internal error flag
+ will be set and further attempts to add data will not do anything.
+
+ Basically, if you initialized with the correct buffer, there is no
+ way to ever write off the end of that buffer when calling the Add
+ and Insert functions here.
+
+ The functions to add data do not return an error. The working model
+ is that the caller just makes all the calls to add data without any
+ error checking on each one. The error is instead checked after all the
+ data is added when the result is to be used.  This makes the caller's
+ code cleaner.
+
+ There is a utility function to get the error status anytime along the
+ way if the caller wants. There are functions to see how much room is
+ left and see if some data will fit too, but their use is generally
+ not necessary.
+
+ The general call flow is like this:
+
+    - Initialize the UsefulOutBuf with the buffer that is to have the
+      data added.  The caller allocates the buffer.  It can be heap
+      or stack or shared memory (or other).
+
+    - Make calls to add data to the output buffer. Insert and append
+      are both supported. The append and insert calls will never write
+      off the end of the buffer.
+
+    - When all data is added, check the error status to make sure
+      everything fit.
+
+    - Get the resulting serialized data either as a UsefulBuf (a
+      pointer and length) or have it copied to another buffer.
+
+ UsefulOutBuf can be initialized with just a buffer length by passing
+ NULL as the pointer to the output buffer. This is useful if you want
+ to go through the whole serialization process to either see if it
+ will fit into a given buffer or compute the size of the buffer
+ needed. Pass a very large buffer size when calling Init, if you want
+ just to compute the size.
+
+ Some inexpensive simple sanity checks are performed before every data
+ addition to guard against use of an uninitialized or corrupted
+ UsefulOutBuf.
+
+ This has been used to create a CBOR encoder. The CBOR encoder has
+ almost no pointer manipulation in it, is much easier to read, and
+ easier to review.
+
+ A UsefulOutBuf is 27 bytes or 15 bytes on 64- or 32-bit machines so it
+ can go on the stack or be a C99 function parameter.
+ */
+
+typedef struct useful_out_buf {
+   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] me The UsefulOutBuf to initialize
+ @param[in] Storage  Buffer to output into
+
+ Intializes the UsefulOutBuf with storage. Sets the current position
+ to the beginning of the buffer clears the error.
+
+ This must be called before the UsefulOutBuf is used.
+ */
+void UsefulOutBuf_Init(UsefulOutBuf *me, UsefulBuf Storage);
+
+
+
+
+/** Convenience marco to make a UsefulOutBuf on the stack and
+   initialize it with stack buffer
+ */
+#define  UsefulOutBuf_MakeOnStack(name, size) \
+   uint8_t       __pBuf##name[(size)];\
+   UsefulOutBuf  name;\
+   UsefulOutBuf_Init(&(name), (UsefulBuf){__pBuf##name, (size)});
+
+
+
+/**
+ @brief Reset a UsefulOutBuf for re use
+
+ @param[in] me Pointer to the UsefulOutBuf
+
+ This sets the amount of data in the output buffer to none and
+ clears the error state.
+
+ The output buffer is still the same one and size as from the
+ UsefulOutBuf_Init() call.
+
+ It doesn't zero the data, just resets to 0 bytes of valid data.
+ */
+static inline void UsefulOutBuf_Reset(UsefulOutBuf *me)
+{
+   me->data_len = 0;
+   me->err    = 0;
+}
+
+
+/**
+ @brief Returns position of end of data in the UsefulOutBuf
+
+ @param[in] me Pointer to the UsefulOutBuf
+
+ @return position of end of data
+
+ On a freshly initialized UsefulOutBuf with no data added, this will
+ return 0. After ten bytes have been added, it will return 10 and so
+ on.
+
+ Generally callers will not need this function for most uses of
+ UsefulOutBuf.
+
+ */
+static inline size_t UsefulOutBuf_GetEndPosition(UsefulOutBuf *me)
+{
+   return me->data_len;
+}
+
+
+/**
+ @brief Returns whether any data has been added to the UsefulOutBuf
+
+ @param[in] me Pointer to the UsefulOutBuf
+
+ @return 1 if output position is at start
+
+ */
+static inline int UsefulOutBuf_AtStart(UsefulOutBuf *me)
+{
+   return 0 == me->data_len;
+}
+
+
+/**
+ @brief Inserts bytes into the UsefulOutBuf
+
+ @param[in] me Pointer to the UsefulOutBuf
+ @param[in] NewData UsefulBuf with the bytes to insert
+ @param[in] uPos Index in output buffer at which to insert
+
+ NewData is the pointer and length for the bytes to be added to the
+ output buffer. There must be room in the output buffer for all of
+ NewData or an error will occur.
+
+ The insertion point must be between 0 and the current valid data. If
+ not an error will occur. Appending data to the output buffer is
+ achieved by inserting at the end of the valid data. This can be
+ retrieved by calling UsefulOutBuf_GetEndPosition().
+
+ When insertion is performed, the bytes between the insertion point and
+ the end of data previously added to the output buffer is slid to the
+ right to make room for the new data.
+
+ Overlapping buffers are OK. NewData can point to data in the output
+ buffer.
+
+ If an error occurs an error state is set in the UsefulOutBuf. No
+ error is returned.  All subsequent attempts to add data will do
+ nothing.
+
+ Call UsefulOutBuf_GetError() to find out if there is an error. This
+ is usually not needed until all additions of data are complete.
+
+ */
+void UsefulOutBuf_InsertUsefulBuf(UsefulOutBuf *me, UsefulBufC NewData, size_t uPos);
+
+
+/**
+ @brief Insert a data buffer into the UsefulOutBuf
+
+ @param[in] me Pointer to the UsefulOutBul
+ @param[in] pBytes Pointer to the bytes to insert
+ @param[in] uLen Length of the bytes to insert
+ @param[in] uPos Index in output buffer at which to insert
+
+ See UsefulOutBuf_InsertUsefulBuf() for details. This is the same with
+ the difference being a pointer and length is passed in rather than an
+ UsefulBuf.
+
+ */
+static inline void UsefulOutBuf_InsertData(UsefulOutBuf *me, const void *pBytes, size_t uLen, size_t uPos)
+{
+   UsefulBufC Data = {pBytes, uLen};
+   UsefulOutBuf_InsertUsefulBuf(me, Data, uPos);
+}
+
+
+/**
+ @brief Insert a NULL-terminated string into the UsefulOutBuf
+
+ @param[in] me Pointer to the UsefulOutBuf
+ @param[in] szString string to append
+
+ */
+static inline void UsefulOutBuf_InsertString(UsefulOutBuf *me, const char *szString, size_t uPos)
+{
+   UsefulOutBuf_InsertUsefulBuf(me, (UsefulBufC){szString, strlen(szString)}, uPos);
+}
+
+
+/**
+ @brief Insert a byte into the UsefulOutBuf
+
+ @param[in] me Pointer to the UsefulOutBul
+ @param[in] byte Bytes to insert
+ @param[in] uPos Index in output buffer at which to insert
+
+ See UsefulOutBuf_InsertUsefulBuf() for details. This is the same with
+ the difference being a single byte is to be inserted.
+ */
+static inline void UsefulOutBuf_InsertByte(UsefulOutBuf *me, uint8_t byte, size_t uPos)
+{
+   UsefulOutBuf_InsertData(me, &byte, 1, uPos);
+}
+
+
+/**
+ @brief Insert a 16-bit integer into the UsefulOutBuf
+
+ @param[in] me Pointer to the UsefulOutBul
+ @param[in] uInteger16 Integer to insert
+ @param[in] uPos Index in output buffer at which to insert
+
+ See UsefulOutBuf_InsertUsefulBuf() for details. This is the same with
+ the difference being a single byte is to be inserted.
+
+ The integer will be inserted in network byte order (big endian)
+ */
+static inline void UsefulOutBuf_InsertUint16(UsefulOutBuf *me, uint16_t uInteger16, size_t uPos)
+{
+   // Converts native integer format to network byte order (big endian)
+   uint8_t tmp[2];
+   tmp[0] = (uInteger16 & 0xff00) >> 8;
+   tmp[1] = (uInteger16 & 0xff);
+   UsefulOutBuf_InsertData(me, tmp, 2, uPos);
+}
+
+
+/**
+ @brief Insert a 32-bit integer into the UsefulOutBuf
+
+ @param[in] me Pointer to the UsefulOutBul
+ @param[in] uInteger32 Integer to insert
+ @param[in] uPos Index in output buffer at which to insert
+
+ See UsefulOutBuf_InsertUsefulBuf() for details. This is the same with
+ the difference being a single byte is to be inserted.
+
+ The integer will be inserted in network byte order (big endian)
+ */
+static inline void UsefulOutBuf_InsertUint32(UsefulOutBuf *me, uint32_t uInteger32, size_t uPos)
+{
+   // Converts native integer format to network byte order (big endian)
+   uint8_t tmp[4];
+   tmp[0] = (uInteger32 & 0xff000000) >> 24;
+   tmp[1] = (uInteger32 & 0xff0000) >> 16;
+   tmp[2] = (uInteger32 & 0xff00) >> 8;
+   tmp[3] = (uInteger32 & 0xff);
+   UsefulOutBuf_InsertData(me, tmp, 4, uPos);
+}
+
+
+/**
+ @brief Insert a 64-bit integer into the UsefulOutBuf
+
+ @param[in] me Pointer to the UsefulOutBul
+ @param[in] uInteger64 Integer to insert
+ @param[in] uPos Index in output buffer at which to insert
+
+ See UsefulOutBuf_InsertUsefulBuf() for details. This is the same with
+ the difference being a single byte is to be inserted.
+
+ The integer will be inserted in network byte order (big endian)
+ */
+static inline void UsefulOutBuf_InsertUint64(UsefulOutBuf *me, uint64_t uInteger64, size_t uPos)
+{
+   // Converts native integer format to network byte order (big endian)
+   uint8_t tmp[8];
+   tmp[0] = (uInteger64 & 0xff00000000000000) >> 56;
+   tmp[1] = (uInteger64 & 0xff000000000000) >> 48;
+   tmp[2] = (uInteger64 & 0xff0000000000) >> 40;
+   tmp[3] = (uInteger64 & 0xff00000000) >> 32;
+   tmp[4] = (uInteger64 & 0xff000000) >> 24;
+   tmp[5] = (uInteger64 & 0xff0000) >> 16;
+   tmp[6] = (uInteger64 & 0xff00) >> 8;
+   tmp[7] = (uInteger64 & 0xff);
+   UsefulOutBuf_InsertData(me, tmp, 8, uPos);
+}
+
+
+/**
+ @brief Insert a float into the UsefulOutBuf
+
+ @param[in] me Pointer to the UsefulOutBul
+ @param[in] f Integer to insert
+ @param[in] uPos Index in output buffer at which to insert
+
+ See UsefulOutBuf_InsertUsefulBuf() for details. This is the same with
+ the difference being a single byte is to be inserted.
+
+ The float will be inserted in network byte order (big endian)
+ */
+static inline void UsefulOutBuf_InsertFloat(UsefulOutBuf *me, float f, size_t uPos)
+{
+   UsefulOutBuf_InsertUint32(me, UsefulBufUtil_CopyFloatToUint32(f), uPos);
+}
+
+
+/**
+ @brief Insert a double into the UsefulOutBuf
+
+ @param[in] me Pointer to the UsefulOutBul
+ @param[in] d Integer to insert
+ @param[in] uPos Index in output buffer at which to insert
+
+ See UsefulOutBuf_InsertUsefulBuf() for details. This is the same with
+ the difference being a single byte is to be inserted.
+
+ The double will be inserted in network byte order (big endian)
+ */
+static inline void UsefulOutBuf_InsertDouble(UsefulOutBuf *me, double d, size_t uPos)
+{
+   UsefulOutBuf_InsertUint64(me, UsefulBufUtil_CopyDoubleToUint64(d), uPos);
+}
+
+
+
+/**
+ Append a UsefulBuf into the UsefulOutBuf
+
+ @param[in] me Pointer to the UsefulOutBuf
+ @param[in] NewData UsefulBuf with the bytes to append
+
+ See UsefulOutBuf_InsertUsefulBuf() for details. This does the same
+ with the insertion point at the end of the valid data.
+
+*/
+static inline void UsefulOutBuf_AppendUsefulBuf(UsefulOutBuf *me, UsefulBufC NewData)
+{
+   // An append is just a insert at the end
+   UsefulOutBuf_InsertUsefulBuf(me, NewData, UsefulOutBuf_GetEndPosition(me));
+}
+
+
+/**
+ Append bytes to the UsefulOutBuf
+
+ @param[in] me Pointer to the UsefulOutBuf
+ @param[in] pBytes Pointer to bytes to append
+ @param[in] uLen Index in output buffer at which to append
+
+ See UsefulOutBuf_InsertUsefulBuf() for details. This does the same
+ with the insertion point at the end of the valid data.
+ */
+
+static inline void UsefulOutBuf_AppendData(UsefulOutBuf *me, const void *pBytes, size_t uLen)
+{
+   UsefulBufC Data = {pBytes, uLen};
+   UsefulOutBuf_AppendUsefulBuf(me, Data);
+}
+
+
+/**
+ Append a NULL-terminated string to the UsefulOutBuf
+
+ @param[in] me Pointer to the UsefulOutBuf
+ @param[in] szString string to append
+
+ */
+static inline void UsefulOutBuf_AppendString(UsefulOutBuf *me, const char *szString)
+{
+   UsefulOutBuf_AppendUsefulBuf(me, (UsefulBufC){szString, strlen(szString)});
+}
+
+
+/**
+ @brief Append a byte to the UsefulOutBuf
+
+ @param[in] me Pointer to the UsefulOutBuf
+ @param[in] byte Bytes to append
+
+ See UsefulOutBuf_InsertUsefulBuf() for details. This does the same
+ with the insertion point at the end of the valid data.
+ */
+static inline void UsefulOutBuf_AppendByte(UsefulOutBuf *me, uint8_t byte)
+{
+   UsefulOutBuf_AppendData(me, &byte, 1);
+}
+
+/**
+ @brief Append an integer to the UsefulOutBuf
+
+ @param[in] me Pointer to the UsefulOutBuf
+ @param[in] uInteger16 Integer to append
+
+ See UsefulOutBuf_InsertUsefulBuf() for details. This does the same
+ with the insertion point at the end of the valid data.
+
+ The integer will be appended in network byte order (big endian).
+ */
+static inline void UsefulOutBuf_AppendUint16(UsefulOutBuf *me, uint16_t uInteger16){
+   UsefulOutBuf_InsertUint16(me, uInteger16, UsefulOutBuf_GetEndPosition(me));
+}
+
+/**
+ @brief Append an integer to the UsefulOutBuf
+
+ @param[in] me Pointer to the UsefulOutBuf
+ @param[in] uInteger32 Integer to append
+
+ See UsefulOutBuf_InsertUsefulBuf() for details. This does the same
+ with the insertion point at the end of the valid data.
+
+ The integer will be appended in network byte order (big endian).
+ */
+static inline void UsefulOutBuf_AppendUint32(UsefulOutBuf *me, uint32_t uInteger32){
+   UsefulOutBuf_InsertUint32(me, uInteger32, UsefulOutBuf_GetEndPosition(me));
+}
+
+/**
+ @brief Append an integer to the UsefulOutBuf
+
+ @param[in] me Pointer to the UsefulOutBuf
+ @param[in] uInteger64 Integer to append
+
+ See UsefulOutBuf_InsertUsefulBuf() for details. This does the same
+ with the insertion point at the end of the valid data.
+
+ The integer will be appended in network byte order (big endian).
+ */
+static inline void UsefulOutBuf_AppendUint64(UsefulOutBuf *me, uint64_t uInteger64){
+   UsefulOutBuf_InsertUint64(me, uInteger64, UsefulOutBuf_GetEndPosition(me));
+}
+
+
+/**
+ @brief Append a float to the UsefulOutBuf
+
+ @param[in] me Pointer to the UsefulOutBuf
+ @param[in] f Float to append
+
+ See UsefulOutBuf_InsertUsefulBuf() for details. This does the same
+ with the insertion point at the end of the valid data.
+
+ The float will be appended in network byte order (big endian).
+ */
+static inline void UsefulOutBuf_AppendFloat(UsefulOutBuf *me, float f){
+   UsefulOutBuf_InsertFloat(me, f, UsefulOutBuf_GetEndPosition(me));
+}
+
+/**
+ @brief Append a float to the UsefulOutBuf
+
+ @param[in] me Pointer to the UsefulOutBuf
+ @param[in] d Double to append
+
+ See UsefulOutBuf_InsertUsefulBuf() for details. This does the same
+ with the insertion point at the end of the valid data.
+
+ The double will be appended in network byte order (big endian).
+ */
+static inline void UsefulOutBuf_AppendDouble(UsefulOutBuf *me, double d){
+   UsefulOutBuf_InsertDouble(me, d, UsefulOutBuf_GetEndPosition(me));
+}
+
+/**
+ @brief Returns the current error status
+
+ @param[in] me Pointer to the UsefulOutBuf
+
+ @return 0 if all OK, 1 on error
+
+ This is the error status since the call to either
+ UsefulOutBuf_Reset() of UsefulOutBuf_Init().  Once it goes into error
+ state it will stay until one of those functions is called.
+
+ Possible error conditions are:
+   - bytes to be inserted will not fit
+   - insertion point is out of buffer or past valid data
+   - current position is off end of buffer (probably corruption or uninitialized)
+   - detect corruption / uninitialized by bad magic number
+ */
+
+static inline int UsefulOutBuf_GetError(UsefulOutBuf *me)
+{
+   return me->err;
+}
+
+
+/**
+ @brief Returns number of bytes unused used in the output buffer
+
+ @param[in] me Pointer to the UsefulOutBuf
+
+ @return Number of unused bytes or zero
+
+ Because of the error handling strategy and checks in UsefulOutBuf_InsertUsefulBuf()
+ it is usually not necessary to use this.
+ */
+
+static inline size_t UsefulOutBuf_RoomLeft(UsefulOutBuf *me)
+{
+   return me->UB.len - me->data_len;
+}
+
+
+/**
+ @brief Returns true / false if some number of bytes will fit in the UsefulOutBuf
+
+ @param[in] me Pointer to the UsefulOutBuf
+ @param[in] uLen Number of bytes for which to check
+
+ @return 1 or 0 if nLen bytes would fit
+
+ Because of the error handling strategy and checks in UsefulOutBuf_InsertUsefulBuf()
+ it is usually not necessary to use this.
+ */
+
+static inline int UsefulOutBuf_WillItFit(UsefulOutBuf *me, size_t uLen)
+{
+   return uLen <= UsefulOutBuf_RoomLeft(me);
+}
+
+
+/**
+   @brief Returns the resulting valid data in a UsefulOutBuf
+
+   @param[in] me Pointer to the UsefulOutBuf.
+
+   @return The valid data in UsefulOutBuf.
+
+   The storage for the returned data is Storage parameter passed
+   to UsefulOutBuf_Init(). See also UsefulOutBuf_CopyOut().
+
+   This can be called anytime and many times to get intermediate
+   results. It doesn't change the data or reset the current position
+   so you can keep adding data.
+ */
+
+UsefulBufC UsefulOutBuf_OutUBuf(UsefulOutBuf *me);
+
+
+/**
+ @brief Copies the valid data out into a supplied buffer
+
+ @param[in] me Pointer to the UsefulOutBuf
+ @param[out] Dest The destination buffer to copy into
+
+ @return Pointer and length of copied data.
+
+ This is the same as UsefulOutBuf_OutUBuf() except it copies the data.
+*/
+
+UsefulBufC UsefulOutBuf_CopyOut(UsefulOutBuf *me, UsefulBuf Dest);
+
+
+
+
+
+
+
+
+
+
+
+
+
+/**
+ UsefulInputBuf is the counterpart to UsefulOutBuf and is for parsing
+ data read or received.  Initialize it with the data
+ from the network and its length. Then  use the functions
+ here to get the various data types out of it. It maintains a position
+ for getting the next item. This means you don't have to track a
+ pointer as you get each object. UsefulInputBuf does that for you and
+ makes sure it never goes off the end of the buffer.  The QCBOR
+ implementation parser makes use of this for all its pointer math and
+ length checking.
+
+ UsefulInputBuf also maintains an internal error state so you do not have
+ to. Once data has been requested off the end of the buffer, it goes
+ into an error state. You can keep calling functions to get more data
+ but they will either return 0 or NULL. As long as you don't
+ dereference the NULL, you can wait until all data items have been
+ fetched before checking for the error and this can simplify your
+ code.
+
+ The integer and float parsing expects network byte order (big endian).
+ Network byte order is what is used by TCP/IP, CBOR and most internet
+ protocols.
+
+ Lots of inlining is used to keep code size down. The code optimizer,
+ particularly with the -Os, also reduces code size a lot. The only
+ non-inline code is UsefulInputBuf_GetBytes() which is less than 100
+ bytes so use of UsefulInputBuf doesn't add much code for all the messy
+ hard-to-get right issues with parsing in C that is solves.
+
+ The parse context size is:
+   64-bit machine: 16 + 8 + 2 + 1 (5 bytes padding to align) = 32 bytes
+   32-bit machine: 8 + 4 + 2 + 1 (1 byte padding to align) = 16 bytes
+
+ */
+
+#define UIB_MAGIC (0xB00F)
+
+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;
+
+
+
+/**
+ @brief Initialize the UsefulInputBuf structure before use.
+
+ @param[in] me Pointer to the UsefulInputBuf instance.
+ @param[in] UB Pointer to the data to parse.
+
+ */
+static inline void UsefulInputBuf_Init(UsefulInputBuf *me, UsefulBufC UB)
+{
+   me->cursor = 0;
+   me->err    = 0;
+   me->magic  = UIB_MAGIC;
+   me->UB     = UB;
+}
+
+
+/**
+ @brief Returns current position in input buffer
+
+ @param[in] me Pointer to the UsefulInputBuf.
+
+ @return Integer position of the cursor
+
+ The position that the next bytes will be returned from.
+
+ */
+static inline size_t UsefulInputBuf_Tell(UsefulInputBuf *me)
+{
+   return me->cursor;
+}
+
+
+/**
+ @brief Sets current position in input buffer
+
+ @param[in] me Pointer to the UsefulInputBuf.
+ @param[in] uPos  Position to set to
+
+ If the position is off the end of the input buffer, the error state
+ is entered and all functions will do nothing.
+
+ Seeking to a valid position in the buffer will not reset the error
+ state. Only re initialization will do that.
+
+ */
+static inline void UsefulInputBuf_Seek(UsefulInputBuf *me, size_t uPos)
+{
+   if(uPos > me->UB.len) {
+      me->err = 1;
+   } else {
+      me->cursor = uPos;
+   }
+}
+
+
+/**
+ @brief Returns the number of bytes from the cursor to the end of the buffer,
+ the uncomsummed bytes.
+
+ @param[in] me Pointer to the UsefulInputBuf.
+
+ @return number of bytes unconsumed or 0 on error.
+
+ This is a critical function for input length validation. This does
+ some pointer / offset math.
+
+ Returns 0 if the cursor it invalid or corruption of the structure is
+ detected.
+
+ Code Reviewers: THIS FUNCTION DOES POINTER MATH
+ */
+static inline size_t UsefulInputBuf_BytesUnconsumed(UsefulInputBuf *me)
+{
+   // Magic number is messed up. Either the structure got overwritten
+   // or was never initialized.
+   if(me->magic != UIB_MAGIC) {
+      return 0;
+   }
+
+   // The cursor is off the end of the input buffer given
+   // Presuming there are no bugs in this code, this should never happen.
+   // If it so, the struct was corrupted. The check is retained as
+   // as a defense in case there is a bug in this code or the struct is corrupted.
+   if(me->cursor > me->UB.len) {
+      return 0;
+   }
+
+   // subtraction can't go neative because of check above
+   return me->UB.len - me->cursor;
+}
+
+
+/**
+ @brief Check if there are any unconsumed bytes
+
+ @param[in] me Pointer to the UsefulInputBuf.
+
+ @return 1 if len bytes are available after the cursor, and 0 if not
+
+ */
+static inline int UsefulInputBuf_BytesAvailable(UsefulInputBuf *me, size_t uLen)
+{
+   return UsefulInputBuf_BytesUnconsumed(me) >= uLen ? 1 : 0;
+}
+
+
+/**
+ @brief Get pointer to bytes out of the input buffer
+
+ @param[in] me Pointer to the UsefulInputBuf.
+ @param[in] uNum  Number of bytes to get
+
+ @return Pointer to bytes.
+
+ This consumes n bytes from the input buffer. It returns a pointer to
+ the start of the n bytes.
+
+ If there are not n bytes in the input buffer, NULL will be returned
+ and an error will be set.
+
+ It advances the current position by n bytes.
+ */
+const void * UsefulInputBuf_GetBytes(UsefulInputBuf *me, size_t uNum);
+
+
+/**
+ @brief Get UsefulBuf out of the input buffer
+
+ @param[in] me Pointer to the UsefulInputBuf.
+ @param[in] uNum  Number of bytes to get
+
+ @return UsefulBufC with ptr and length for bytes consumed.
+
+ This consumes n bytes from the input buffer and returns the pointer
+ and len to them as a UsefulBufC. The len returned will always be n.
+
+ If there are not n bytes in the input buffer, UsefulBufC.ptr will be
+ NULL and UsefulBufC.len will be 0. An error will be set.
+
+ It advances the current position by n bytes.
+ */
+static inline UsefulBufC UsefulInputBuf_GetUsefulBuf(UsefulInputBuf *me, size_t uNum)
+{
+   const void *pResult = UsefulInputBuf_GetBytes(me, uNum);
+   if(!pResult) {
+      return NULLUsefulBufC;
+   } else {
+      return (UsefulBufC){pResult, uNum};
+   }
+}
+
+
+/**
+ @brief Get a byte out of the input buffer.
+
+ @param[in] me Pointer to the UsefulInputBuf.
+
+ @return The byte
+
+ This consumes 1 byte from the input buffer. It returns the byte.
+
+ If there is not 1 byte in the buffer, 0 will be returned for the byte
+ and an error set internally.  You must check the error at some point
+ to know whether the 0 was the real value or just returned in error,
+ 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 NULL or the ptr from
+ UsefulInputBuf_GetUsefulBuf() is NULL.
+
+ It advances the current position by 1 byte.
+ */
+static inline uint8_t UsefulInputBuf_GetByte(UsefulInputBuf *me)
+{
+   const void *pResult = UsefulInputBuf_GetBytes(me, sizeof(uint8_t));
+
+   return pResult ? *(uint8_t *)pResult : 0;
+}
+
+
+/**
+ @brief Get a uint16_t out of the input buffer
+
+ @param[in] me Pointer to the UsefulInputBuf.
+
+ @return The uint16_t
+
+ See UsefulInputBuf_GetByte(). This works the same, except it returns
+ a uint16_t and two bytes are consumed.
+
+ The input bytes must be in network order (big endian).
+ */
+static inline uint16_t UsefulInputBuf_GetUint16(UsefulInputBuf *me)
+{
+   const uint8_t *pResult = (const uint8_t *)UsefulInputBuf_GetBytes(me, sizeof(uint16_t));
+
+   if(!pResult) {
+      return 0;
+   }
+
+   return  ((uint16_t)pResult[0] << 8) + (uint16_t)pResult[1];
+}
+
+
+/**
+ @brief Get a uint32_t out of the input buffer
+
+ @param[in] me Pointer to the UsefulInputBuf.
+
+ @return The uint32_t
+
+ See UsefulInputBuf_GetByte(). This works the same, except it returns
+ a uint32_t and four bytes are consumed.
+
+ The input bytes must be in network order (big endian).
+ */
+static inline uint32_t UsefulInputBuf_GetUint32(UsefulInputBuf *me)
+{
+   const uint8_t *pResult = (const uint8_t *)UsefulInputBuf_GetBytes(me, sizeof(uint32_t));
+
+   if(!pResult) {
+      return 0;
+   }
+
+   return ((uint32_t)pResult[0]<<24) +
+          ((uint32_t)pResult[1]<<16) +
+          ((uint32_t)pResult[2]<<8) +
+           (uint32_t)pResult[3];
+}
+
+
+/**
+ @brief Get a uint64_t out of the input buffer
+
+ @param[in] me Pointer to the UsefulInputBuf.
+
+ @return The uint64_t
+
+ See UsefulInputBuf_GetByte(). This works the same, except it returns
+ a uint64_t and eight bytes are consumed.
+
+ The input bytes must be in network order (big endian).
+ */
+static inline uint64_t UsefulInputBuf_GetUint64(UsefulInputBuf *me)
+{
+   const uint8_t *pResult = (const uint8_t *)UsefulInputBuf_GetBytes(me, sizeof(uint64_t));
+
+   if(!pResult) {
+      return 0;
+   }
+
+   return   ((uint64_t)pResult[0]<<56) +
+            ((uint64_t)pResult[1]<<48) +
+            ((uint64_t)pResult[2]<<40) +
+            ((uint64_t)pResult[3]<<32) +
+            ((uint64_t)pResult[4]<<24) +
+            ((uint64_t)pResult[5]<<16) +
+            ((uint64_t)pResult[6]<<8)  +
+            (uint64_t)pResult[7];
+}
+
+
+/**
+ @brief Get a float out of the input buffer
+
+ @param[in] me Pointer to the UsefulInputBuf.
+
+ @return The float
+
+ See UsefulInputBuf_GetByte(). This works the same, except it returns
+ a float and four bytes are consumed.
+
+ The input bytes must be in network order (big endian).
+ */
+static inline float UsefulInputBuf_GetFloat(UsefulInputBuf *me)
+{
+   uint32_t uResult = UsefulInputBuf_GetUint32(me);
+
+   return uResult ? UsefulBufUtil_CopyUint32ToFloat(uResult) : 0;
+}
+
+/**
+ @brief Get a double out of the input buffer
+
+ @param[in] me Pointer to the UsefulInputBuf.
+
+ @return The double
+
+ See UsefulInputBuf_GetByte(). This works the same, except it returns
+ a double and eight bytes are consumed.
+
+ The input bytes must be in network order (big endian).
+ */
+static inline double UsefulInputBuf_GetDouble(UsefulInputBuf *me)
+{
+   uint64_t uResult = UsefulInputBuf_GetUint64(me);
+
+   return uResult ? UsefulBufUtil_CopyUint64ToDouble(uResult) : 0;
+}
+
+
+/**
+ @brief Get the error status
+
+ @param[in] me Pointer to the UsefulInputBuf.
+
+ @return The error.
+
+ Zero is success, non-zero is error. Once in the error state, the only
+ way to clear it is to call Init again.
+
+ You may be able to only check the error state at the end after all
+ the Get()'s have been done, but if what you get later depends on what
+ you get sooner you cannot. For example if you get a length or count
+ of following items you will have to check the error.
+
+ */
+static inline int UsefulInputBuf_GetError(UsefulInputBuf *me)
+{
+   return me->err;
+}
+
+
+#endif  // _UsefulBuf_h
+
+