/*==============================================================================
 Copyright (c) 2016-2018, The Linux Foundation.
 Copyright (c) 2018, Laurence Lundblade.
 All rights reserved.
 
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above
      copyright notice, this list of conditions and the following
      disclaimer in the documentation and/or other materials provided
      with the distribution.
    * Neither the name of The Linux Foundation nor the names of its
      contributors, nor the name "Laurence Lundblade" may be used to
      endorse or promote products derived from this software without
      specific prior written permission.
 
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ==============================================================================*/

/*===================================================================================
 FILE:  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
 --------           ----            ---------------------------------------------------
 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 {
    const void *ptr;
    const 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 {
   void  *ptr;
   const 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
 
 */
static inline UsefulBufC UsefulBuf_Tail(UsefulBufC UB, size_t uAmount)
{
   if(uAmount > UB.len) {
      return NULLUsefulBufC;
   }
   return (UsefulBufC){(uint8_t *)UB.ptr + uAmount, UB.len - uAmount};
}


/**
 @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 {
   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);

static inline void UsefulOutBuf_Realloc(UsefulOutBuf *me, UsefulBuf Storage)
{
   me->UB = 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 {
   // Private data structure
   UsefulBufC UB;
   size_t     cursor;
   uint16_t   magic;
   uint8_t    err; // set if off end of buffer; also can set if this structure is corrupt or inconsistent.
} 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


