QCBOR
Loading...
Searching...
No Matches
UsefulBuf.h File Reference
#include <stdint.h>
#include <string.h>
#include <stddef.h>

Go to the source code of this file.

Data Structures

struct  q_useful_buf_c
struct  q_useful_buf
struct  useful_out_buf
struct  useful_input_buf

Macros

#define NULLUsefulBufC   ((UsefulBufC) {NULL, 0})
#define NULLUsefulBuf   ((UsefulBuf) {NULL, 0})
#define UsefulBuf_FROM_SZ_LITERAL(szString)
#define UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pBytes)
#define UsefulBuf_MAKE_STACK_UB(name, size)
#define UsefulBuf_FROM_BYTE_ARRAY(pBytes)
#define SZLiteralToUsefulBufC(szString)
#define MakeUsefulBufOnStack(name, size)
#define ByteArrayLiteralToUsefulBufC(pBytes)
#define SizeCalculateUsefulBuf   ((UsefulBuf) {NULL, SIZE_MAX})
#define UsefulOutBuf_MakeOnStack(name, size)
#define UIB_MAGIC   (0xB00F)

Typedefs

typedef struct q_useful_buf_c UsefulBufC
typedef struct q_useful_buf UsefulBuf
typedef struct useful_out_buf UsefulOutBuf
typedef struct useful_input_buf UsefulInputBuf

Functions

static int UsefulBuf_IsNULL (UsefulBuf UB)
 Check if a UsefulBuf is NULLUsefulBuf or not.
static int UsefulBuf_IsNULLC (UsefulBufC UB)
 Check if a UsefulBufC is NULLUsefulBufC or not.
static int UsefulBuf_IsEmpty (UsefulBuf UB)
 Check if a UsefulBuf is empty or not.
static int UsefulBuf_IsEmptyC (UsefulBufC UB)
 Check if a UsefulBufC is empty or not.
static int UsefulBuf_IsNULLOrEmpty (UsefulBuf UB)
 Check if a UsefulBuf is NULLUsefulBuf or empty.
static int UsefulBuf_IsNULLOrEmptyC (UsefulBufC UB)
 Check if a UsefulBufC is NULLUsefulBufC or empty.
static UsefulBufC UsefulBuf_Const (const UsefulBuf UB)
 Convert a non-const UsefulBuf to a const UsefulBufC.
static UsefulBuf UsefulBuf_Unconst (const UsefulBufC UBC)
 Convert a const UsefulBufC to a non-const UsefulBuf.
static UsefulBufC UsefulBuf_FromSZ (const char *szString)
 Convert a NULL-terminated string to a UsefulBufC.
UsefulBufC UsefulBuf_CopyOffset (UsefulBuf Dest, size_t uOffset, const UsefulBufC Src)
 Copy one UsefulBuf into another at an offset.
static UsefulBufC UsefulBuf_Copy (UsefulBuf Dest, const UsefulBufC Src)
 Copy one UsefulBuf into another.
static UsefulBufC UsefulBuf_Set (UsefulBuf pDest, uint8_t value)
 Set all bytes in a UsefulBuf to a value, for example to 0.
static UsefulBufC UsefulBuf_CopyPtr (UsefulBuf Dest, const void *ptr, size_t uLen)
 Copy a pointer into a UsefulBuf.
static UsefulBufC UsefulBuf_Head (UsefulBufC UB, size_t uAmount)
 Returns a truncation of a UsefulBufC.
static UsefulBufC UsefulBuf_Tail (UsefulBufC UB, size_t uAmount)
 Returns bytes from the end of a UsefulBufC.
int UsefulBuf_Compare (const UsefulBufC UB1, const UsefulBufC UB2)
 Compare one UsefulBufC to another.
size_t UsefulBuf_IsValue (const UsefulBufC UB, uint8_t uValue)
 Find first byte that is not a particular byte value.
size_t UsefulBuf_FindBytes (UsefulBufC BytesToSearch, UsefulBufC BytesToFind)
 Find one UsefulBufC in another.
static size_t UsefulBuf_PointerToOffset (UsefulBufC UB, const void *p)
 Convert a pointer to an offset with bounds checking.
static const void * UsefulBuf_OffsetToPointer (UsefulBufC UB, size_t uOffset)
 Convert an offset to a pointer with bounds checking.
static UsefulBuf UsefulBufC_Unconst (const UsefulBufC UBC)
static uint32_t UsefulBufUtil_CopyFloatToUint32 (float f)
 Copy a float to a uint32_t.
static uint64_t UsefulBufUtil_CopyDoubleToUint64 (double d)
 Copy a double to a uint64_t.
static float UsefulBufUtil_CopyUint32ToFloat (uint32_t u32)
 Copy a uint32_t to a float.
static double UsefulBufUtil_CopyUint64ToDouble (uint64_t u64)
 Copy a uint64_t to a double.
void UsefulOutBuf_Init (UsefulOutBuf *pUOutBuf, UsefulBuf Storage)
 Initialize and supply the actual output buffer.
static void UsefulOutBuf_Reset (UsefulOutBuf *pUOutBuf)
 Reset a UsefulOutBuf for re use.
static size_t UsefulOutBuf_GetEndPosition (UsefulOutBuf *pUOutBuf)
 Returns position of end of data in the UsefulOutBuf.
static int UsefulOutBuf_AtStart (UsefulOutBuf *pUOutBuf)
 Returns whether any data has been added to the UsefulOutBuf.
void UsefulOutBuf_InsertUsefulBuf (UsefulOutBuf *pUOutBuf, UsefulBufC NewData, size_t uPos)
 Inserts bytes into the UsefulOutBuf.
static void UsefulOutBuf_InsertData (UsefulOutBuf *pUOutBuf, const void *pBytes, size_t uLen, size_t uPos)
 Insert a data buffer into the UsefulOutBuf.
static void UsefulOutBuf_InsertString (UsefulOutBuf *pUOutBuf, const char *szString, size_t uPos)
 Insert a NULL-terminated string into the UsefulOutBuf.
static void UsefulOutBuf_InsertByte (UsefulOutBuf *pUOutBuf, uint8_t byte, size_t uPos)
 Insert a byte into the UsefulOutBuf.
static void UsefulOutBuf_InsertUint16 (UsefulOutBuf *pUOutBuf, uint16_t uInteger16, size_t uPos)
 Insert a 16-bit integer into the UsefulOutBuf.
static void UsefulOutBuf_InsertUint32 (UsefulOutBuf *pUOutBuf, uint32_t uInteger32, size_t uPos)
 Insert a 32-bit integer into the UsefulOutBuf.
static void UsefulOutBuf_InsertUint64 (UsefulOutBuf *pUOutBuf, uint64_t uInteger64, size_t uPos)
 Insert a 64-bit integer into the UsefulOutBuf.
static void UsefulOutBuf_InsertFloat (UsefulOutBuf *pUOutBuf, float f, size_t uPos)
 Insert a float into the UsefulOutBuf.
static void UsefulOutBuf_InsertDouble (UsefulOutBuf *pUOutBuf, double d, size_t uPos)
 Insert a double into the UsefulOutBuf.
static void UsefulOutBuf_AppendUsefulBuf (UsefulOutBuf *pUOutBuf, UsefulBufC NewData)
 Append a UsefulBuf into the UsefulOutBuf.
static void UsefulOutBuf_AppendData (UsefulOutBuf *pUOutBuf, const void *pBytes, size_t uLen)
 Append bytes to the UsefulOutBuf.
static void UsefulOutBuf_AppendString (UsefulOutBuf *pUOutBuf, const char *szString)
 Append a NULL-terminated string to the UsefulOutBuf.
static void UsefulOutBuf_AppendByte (UsefulOutBuf *pUOutBuf, uint8_t byte)
 Append a byte to the UsefulOutBuf.
static void UsefulOutBuf_AppendUint16 (UsefulOutBuf *pUOutBuf, uint16_t uInteger16)
 Append an integer to the UsefulOutBuf.
static void UsefulOutBuf_AppendUint32 (UsefulOutBuf *pUOutBuf, uint32_t uInteger32)
 Append an integer to the UsefulOutBuf.
static void UsefulOutBuf_AppendUint64 (UsefulOutBuf *pUOutBuf, uint64_t uInteger64)
 Append an integer to the UsefulOutBuf.
static void UsefulOutBuf_AppendFloat (UsefulOutBuf *pUOutBuf, float f)
 Append a float to the UsefulOutBuf.
static void UsefulOutBuf_AppendDouble (UsefulOutBuf *pUOutBuf, double d)
 Append a double to the UsefulOutBuf.
static int UsefulOutBuf_GetError (UsefulOutBuf *pUOutBuf)
 Returns the current error status.
static size_t UsefulOutBuf_RoomLeft (UsefulOutBuf *pUOutBuf)
 Returns number of bytes unused used in the output buffer.
static int UsefulOutBuf_WillItFit (UsefulOutBuf *pUOutBuf, size_t uLen)
 Returns 1 if some number of bytes will fit in the UsefulOutBuf.
static int UsefulOutBuf_IsBufferNULL (UsefulOutBuf *pUOutBuf)
 Returns 1 if buffer given to UsefulOutBuf_Init() was NULL.
static UsefulBuf UsefulOutBuf_GetOutPlace (UsefulOutBuf *pUOutBuf)
 Returns pointer and length of the output buffer not yet used.
void UsefulOutBuf_Advance (UsefulOutBuf *pUOutBuf, size_t uAmount)
 Advance the amount output assuming it was written by the caller.
UsefulBufC UsefulOutBuf_OutUBuf (UsefulOutBuf *pUOutBuf)
 Returns the resulting valid data in a UsefulOutBuf.
UsefulBufC UsefulOutBuf_CopyOut (UsefulOutBuf *pUOutBuf, UsefulBuf Dest)
 Copies the valid data into a supplied buffer.
UsefulBufC UsefulOutBuf_SubString (UsefulOutBuf *pUOutBuf, const size_t uStart, const size_t uLen)
 Return a substring of the output data.
static UsefulBuf UsefulOutBuf_RetrieveOutputStorage (UsefulOutBuf *pUOutBuf)
 Retrieve the storage buffer passed in to UsefulOutBuf_Init().
static void UsefulInputBuf_Init (UsefulInputBuf *pUInBuf, UsefulBufC UB)
 Initialize the UsefulInputBuf structure before use.
static size_t UsefulInputBuf_Tell (UsefulInputBuf *pUInBuf)
 Returns current position in input buffer.
static void UsefulInputBuf_Seek (UsefulInputBuf *pUInBuf, size_t uPos)
 Sets the current position in input buffer.
static size_t UsefulInputBuf_BytesUnconsumed (UsefulInputBuf *pUInBuf)
 Returns the number of bytes from the cursor to the end of the buffer, the unconsumed bytes.
static int UsefulInputBuf_BytesAvailable (UsefulInputBuf *pUInBuf, size_t uLen)
 Check if there are unconsumed bytes.
static size_t UsefulInputBuf_PointerToOffset (UsefulInputBuf *pUInBuf, const void *p)
 Convert a pointer to an offset with bounds checking.
static const void * UsefulInputBuf_OffsetToPointer (UsefulInputBuf *pUInBuf, size_t uOffset)
 Convert an offset to a pointer with bounds checking.
const void * UsefulInputBuf_GetBytes (UsefulInputBuf *pUInBuf, size_t uNum)
 Get pointer to bytes out of the input buffer.
static UsefulBufC UsefulInputBuf_GetUsefulBuf (UsefulInputBuf *pUInBuf, size_t uNum)
 Get UsefulBuf out of the input buffer.
static uint8_t UsefulInputBuf_GetByte (UsefulInputBuf *pUInBuf)
 Get a byte out of the input buffer.
static uint16_t UsefulInputBuf_GetUint16 (UsefulInputBuf *pUInBuf)
 Get a uint16_t out of the input buffer.
static uint32_t UsefulInputBuf_GetUint32 (UsefulInputBuf *pUInBuf)
 Get a uint32_t out of the input buffer.
static uint64_t UsefulInputBuf_GetUint64 (UsefulInputBuf *pUInBuf)
 Get a uint64_t out of the input buffer.
static float UsefulInputBuf_GetFloat (UsefulInputBuf *pUInBuf)
 Get a float out of the input buffer.
static double UsefulInputBuf_GetDouble (UsefulInputBuf *pUInBuf)
 Get a double out of the input buffer.
static int UsefulInputBuf_GetError (UsefulInputBuf *pUInBuf)
 Get the error status.
static size_t UsefulInputBuf_GetBufferLength (UsefulInputBuf *pUInBuf)
 Gets the input buffer length.
static void UsefulInputBuf_SetBufferLength (UsefulInputBuf *pUInBuf, size_t uNewLen)
 Alters the input buffer length (use with caution).
static UsefulBufC UsefulInputBuf_RetrieveUndecodedInput (UsefulInputBuf *pUInBuf)
 Retrieve the undecoded input buffer.

Detailed Description

The goal of this code is to make buffer and pointer manipulation easier and safer when working with binary data.

The UsefulBuf, UsefulOutBuf and UsefulInputBuf structures are used to represent buffers rather than ad hoc pointers and lengths.

With these it is possible to write code that does little or no direct pointer manipulation for copying and formatting data. For example, the QCBOR encoder was written using these and has less pointer manipulation.

While it is true that object code using these functions will be a little larger and slower than a white-knuckle clever use of pointers might be, but not by that much or enough to have an effect for most use cases. For security-oriented code this is highly worthwhile. Clarity, simplicity, reviewability and are more important.

There are some extra sanity and double checks in this code to help catch coding errors and simple memory corruption. They are helpful, but not a substitute for proper code review, input validation and such.

This code consists of a lot of inline functions and a few that are not. It should not generate very much object code, especially with the optimizer turned up to -Os or -O3.

Macro Definition Documentation

◆ ByteArrayLiteralToUsefulBufC

#define ByteArrayLiteralToUsefulBufC ( pBytes)
Value:
#define UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pBytes)
Definition UsefulBuf.h:454

Deprecated macro; use UsefulBuf_FROM_BYTE_ARRAY_LITERAL instead

◆ MakeUsefulBufOnStack

#define MakeUsefulBufOnStack ( name,
size )
Value:
uint8_t __pBuf##name[(size)];\
UsefulBuf name = {__pBuf##name , sizeof( __pBuf##name )}
struct q_useful_buf UsefulBuf

Deprecated macro; use UsefulBuf_MAKE_STACK_UB instead

◆ NULLUsefulBuf

#define NULLUsefulBuf   ((UsefulBuf) {NULL, 0})

A null UsefulBuf is one that has no memory associated the same way NULL points to nothing. It does not matter what len is.

◆ NULLUsefulBufC

#define NULLUsefulBufC   ((UsefulBufC) {NULL, 0})

A null UsefulBufC is one that has no value in the same way a NULL pointer has no value. A UsefulBufC 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.

◆ SizeCalculateUsefulBuf

#define SizeCalculateUsefulBuf   ((UsefulBuf) {NULL, SIZE_MAX})

This is a UsefulBuf value that can be passed to UsefulOutBuf_Init() to have it calculate the size of the output buffer needed. Pass this for Storage, call all the append and insert functions normally, then call UsefulOutBuf_OutUBuf(). The returned UsefulBufC has the size.

As one can see, this is just a NULL pointer and very large size. The NULL pointer tells UsefulOutputBuf to not copy any data.

◆ SZLiteralToUsefulBufC

#define SZLiteralToUsefulBufC ( szString)
Value:
#define UsefulBuf_FROM_SZ_LITERAL(szString)
Definition UsefulBuf.h:440

Deprecated macro; use UsefulBuf_FROM_SZ_LITERAL instead

◆ UsefulBuf_FROM_BYTE_ARRAY

#define UsefulBuf_FROM_BYTE_ARRAY ( pBytes)
Value:
((UsefulBuf) {(pBytes), sizeof(pBytes)})

Make a byte array in to a UsefulBuf. This is usually used on stack variables or static variables. Also see UsefulBuf_MAKE_STACK_UB.

◆ UsefulBuf_FROM_BYTE_ARRAY_LITERAL

#define UsefulBuf_FROM_BYTE_ARRAY_LITERAL ( pBytes)
Value:
((UsefulBufC) {(pBytes), sizeof(pBytes)})
struct q_useful_buf_c UsefulBufC

Convert a literal byte array to a UsefulBufC.

pBytes must be a literal string that sizeof() works on. It will not work on non-literal arrays.

◆ UsefulBuf_FROM_SZ_LITERAL

#define UsefulBuf_FROM_SZ_LITERAL ( szString)
Value:
((UsefulBufC) {(szString), sizeof(szString)-1})

Convert a literal string to a UsefulBufC.

szString must be a literal string that sizeof() works on. This is better for literal strings than UsefulBuf_FromSZ() because it generates less code. It will not work on non-literal strings.

The terminating \0 (NULL) is NOT included in the length!

◆ UsefulBuf_MAKE_STACK_UB

#define UsefulBuf_MAKE_STACK_UB ( name,
size )
Value:
uint8_t __pBuf##name[(size)];\
UsefulBuf name = {__pBuf##name , sizeof( __pBuf##name )}

Make an automatic variable named name of type UsefulBuf and point it to a stack variable of the given size.

◆ UsefulOutBuf_MakeOnStack

#define UsefulOutBuf_MakeOnStack ( name,
size )
Value:
uint8_t __pBuf##name[(size)];\
UsefulOutBuf_Init(&(name), (UsefulBuf){__pBuf##name, (size)});
struct useful_out_buf UsefulOutBuf

Convenience macro to make a UsefulOutBuf on the stack and initialize it with a stack buffer of the given size. The variable will be named name.

Typedef Documentation

◆ UsefulBuf

typedef struct q_useful_buf UsefulBuf

This non-const UsefulBuf is 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.

◆ UsefulBufC

typedef struct q_useful_buf_c UsefulBufC

UsefulBufC and UsefulBuf are simple data structures to hold a pointer and length for binary data. In C99 this data structure can be passed on the stack making a lot of code cleaner than carrying around a pointer and length as two parameters.

This is also conducive to secure coding practice as the length is always carried with the pointer and the convention for handling a pointer and a length is clear.

While it might be possible to write buffer and pointer code more efficiently in some use cases, the thought is that unless there is an extreme need for performance (e.g., you are building a gigabit-per-second IP router), it is probably better to have cleaner code you can be most certain about the security of.

The non-const UsefulBuf is usually used to refer an empty 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 mode is to pass a UsefulBuf to a function, the function puts some data in it, then the function returns a UsefulBufC refering to the data. The UsefulBuf is a non-const "in" parameter and the UsefulBufC is a const "out" parameter so the constness stays correct. There is no single "in,out" parameter (if there was, it would have to be non-const). Note that the pointer returned in the UsefulBufC usually ends up being the same pointer passed in as a UsefulBuf, though this is not striclty required.

A UsefulBuf is null, it has no value, when ptr in it is NULL.

There are functions and macros for the following:

  • Initializing
  • Create initialized const UsefulBufC from compiler literals
  • Create initialized const UsefulBufC from NULL-terminated string
  • Make an empty UsefulBuf on the stack
  • Checking whether a UsefulBuf is null, empty or both
  • Copying, copying with offset, copying head or tail
  • Comparing and finding substrings

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.

Another way to look at it is this. C has the NULL-terminated string as a means for handling text strings, but no means or convention for binary strings. Other languages do have such means, Rust, an efficient compiled language, for example.

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".

◆ UsefulInputBuf

UsefulInputBuf is the counterpart to UsefulOutBuf. It is for parsing data received. Initialize it with the data from the network. Then use the functions like UsefulInputBuf_GetBytes() to get data chunks of various types. A position cursor is maintained internally.

As long as the functions here are used, there will never be any reference off the end of the given buffer (except UsefulInputBuf_SetBufferLength()). This is true even if they are called incorrectly, an attempt is made to seek off the end of the buffer or such. This makes it easier to write safe and correct code. For example, the QCBOR decoder implementation is safer and easier to review through its use of UsefulInputBuf.

UsefulInputBuf maintains an internal error state. The intended use is fetching data chunks without any error checks until the end. If there was any error, such as an attempt to fetch data off the end, the error state is entered and no further data will be returned. In the error state the UsefulInputBuf_GetXxxx() functions return 0, or NULL or NULLUsefulBufC. As long as null is not dereferenced, the error check can be put off until the end, simplifying the calling code.

The integer and float parsing expects network byte order (big endian). Network byte order is what is used by TCP/IP, CBOR and most internet protocols.

Lots of inline functions are used to keep code size down. The optimizer, particularly with the -Os or -O3, also reduces code size a lot. The only non-inline code is UsefulInputBuf_GetBytes(). It 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 binary protocols in C that it 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

◆ UsefulOutBuf

typedef struct useful_out_buf UsefulOutBuf

UsefulOutBuf is a structure and functions (an object) for serializing data into a buffer to encode for a network protocol or write data to a file.

The main idea is that all the pointer manipulation is performed by UsefulOutBuf functions so the caller doesn't have to do any pointer manipulation. The pointer manipulation is centralized. This code has been reviewed and written carefully so it spares the caller of much of this work and results in safer code with less effort.

The UsefulOutBuf methods that add data to the output buffer always check the length and will never write off the end of the output buffer. If an attempt to add data that will not fit is made, an internal error flag will be set and further attempts to add data will not do anything.

There is no way to ever write off the end of that buffer when calling the UsefulOutBuf_AddXxx() and UsefulOutBuf_InsertXxx() functions.

The functions to add data do not report success of failure. The caller only needs to check for an error in the final call, either UsefulOutBuf_OutUBuf() or UsefulOutBuf_CopyOut() to get the result. This makes the calling code cleaner.

There is a utility function to get the error status anytime along the way for a special circumstance. There are functions to see how much room is left and see if some data will fit too, but their use is generally unnecessary.

The general call flow is:

UsefulOutBuf can be used in a mode to calculate the size of what would be output without actually outputting anything. This is useful to calculate the size of a buffer that is to be allocated to hold the output. See SizeCalculateUsefulBuf.

Methods like UsefulOutBuf_InsertUint64() always output in network byte order (big endian).

The possible errors are:

  • The UsefulOutBuf was not initialized or was corrupted.
  • An attempt was made to add data that will not fit.
  • An attempt was made to insert data at a position beyond the end of the buffer.
  • An attempt was made to insert data at a position beyond the valid data in the buffer.

Some inexpensive simple sanity checks are performed before every data addition to guard against use of an uninitialized or corrupted UsefulOutBuf.

UsefulOutBuf has been used to create a CBOR encoder. The CBOR encoder has almost no pointer manipulation in it, is easier to read, and easier to review.

A UsefulOutBuf is small and can go on the stack:

  • 32 bytes (27 bytes plus alignment padding) on a 64-bit CPU
  • 16 bytes (15 bytes plus alignment padding) on a 32-bit CPU

Function Documentation

◆ UsefulBuf_Compare()

int UsefulBuf_Compare ( const UsefulBufC UB1,
const UsefulBufC UB2 )

Compare one UsefulBufC to another.

Parameters
[in]UB1The first buffer to compare.
[in]UB2The second buffer to compare.
Returns
0, positive or negative value.

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 inputs 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() ).

◆ UsefulBuf_Const()

UsefulBufC UsefulBuf_Const ( const UsefulBuf UB)
inlinestatic

Convert a non-const UsefulBuf to a const UsefulBufC.

Parameters
[in]UBThe UsefulBuf to convert.
Returns
A UsefulBufC struct.

◆ UsefulBuf_Copy()

UsefulBufC UsefulBuf_Copy ( UsefulBuf Dest,
const UsefulBufC Src )
inlinestatic

Copy one UsefulBuf into another.

Parameters
[in]DestThe destination buffer to copy into.
[out]SrcThe source to copy from.
Returns
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.

The results are undefined if Dest and Src overlap.

◆ UsefulBuf_CopyOffset()

UsefulBufC UsefulBuf_CopyOffset ( UsefulBuf Dest,
size_t uOffset,
const UsefulBufC Src )

Copy one UsefulBuf into another at an offset.

Parameters
[in]DestDestination buffer to copy into.
[in]uOffsetThe byte offset in Dest at which to copy to.
[in]SrcThe bytes to copy.
Returns
Pointer and length of the copy or NULLUsefulBufC.

This fails and returns NULLUsefulBufC if offset is beyond the size of Dest.

This fails and returns NULLUsefulBufC if the Src length plus uOffset is greater than the length of Dest.

The results are undefined if Dest and Src overlap.

This assumes that there is valid data in Dest up to uOffset. The UsefulBufC returned starts at the beginning of Dest and goes to Src.len + uOffset.

◆ UsefulBuf_CopyPtr()

UsefulBufC UsefulBuf_CopyPtr ( UsefulBuf Dest,
const void * ptr,
size_t uLen )
inlinestatic

Copy a pointer into a UsefulBuf.

Parameters
[in,out]DestThe destination buffer to copy into.
[in]ptrThe source to copy from.
[in]uLenLength of the source; amount to copy.
Returns
Filled in UsefulBufC on success, NULLUsefulBufC on failure.

This fails and returns NULLUsefulBufC if uLen 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.

◆ UsefulBuf_FindBytes()

size_t UsefulBuf_FindBytes ( UsefulBufC BytesToSearch,
UsefulBufC BytesToFind )

Find one UsefulBufC in another.

Parameters
[in]BytesToSearchBuffer to search through.
[in]BytesToFindBuffer with bytes to be found.
Returns
Position of found bytes or SIZE_MAX if not found.

◆ UsefulBuf_FromSZ()

UsefulBufC UsefulBuf_FromSZ ( const char * szString)
inlinestatic

Convert a NULL-terminated string to a UsefulBufC.

Parameters
[in]szStringThe string to convert.
Returns
A UsefulBufC struct.

UsefulBufC.ptr points to the string so its lifetime must be maintained.

The terminating \0 (NULL) is NOT included in the length.

◆ UsefulBuf_Head()

UsefulBufC UsefulBuf_Head ( UsefulBufC UB,
size_t uAmount )
inlinestatic

Returns a truncation of a UsefulBufC.

Parameters
[in]UBThe buffer to get the head of.
[in]uAmountThe number of bytes in the head.
Returns
A UsefulBufC that is the head of UB.

◆ UsefulBuf_IsEmpty()

int UsefulBuf_IsEmpty ( UsefulBuf UB)
inlinestatic

Check if a UsefulBuf is empty or not.

Parameters
[in]UBThe UsefulBuf to check.
Returns
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.

Many 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.

◆ UsefulBuf_IsEmptyC()

int UsefulBuf_IsEmptyC ( UsefulBufC UB)
inlinestatic

Check if a UsefulBufC is empty or not.

Parameters
[in]UBThe UsefulBufC to check.
Returns
1 if it is empty, 0 if not.

◆ UsefulBuf_IsNULL()

int UsefulBuf_IsNULL ( UsefulBuf UB)
inlinestatic

Check if a UsefulBuf is NULLUsefulBuf or not.

Parameters
[in]UBThe UsefulBuf to check.
Returns
1 if it is NULLUsefulBuf, 0 if not.

◆ UsefulBuf_IsNULLC()

int UsefulBuf_IsNULLC ( UsefulBufC UB)
inlinestatic

Check if a UsefulBufC is NULLUsefulBufC or not.

Parameters
[in]UBThe UsefulBufC to check.
Returns
1 if it is NULLUsefulBufC, 0 if not.

◆ UsefulBuf_IsNULLOrEmpty()

int UsefulBuf_IsNULLOrEmpty ( UsefulBuf UB)
inlinestatic

Check if a UsefulBuf is NULLUsefulBuf or empty.

Parameters
[in]UBThe UsefulBuf to check.
Returns
1 if it is either NULLUsefulBuf or empty, 0 if not.

◆ UsefulBuf_IsNULLOrEmptyC()

int UsefulBuf_IsNULLOrEmptyC ( UsefulBufC UB)
inlinestatic

Check if a UsefulBufC is NULLUsefulBufC or empty.

Parameters
[in]UBThe UsefulBufC to check.
Returns
1 if it is either NULLUsefulBufC or empty, 0 if not.

◆ UsefulBuf_IsValue()

size_t UsefulBuf_IsValue ( const UsefulBufC UB,
uint8_t uValue )

Find first byte that is not a particular byte value.

Parameters
[in]UBThe destination buffer for byte comparison.
[in]uValueThe byte value to compare to.
Returns
Offset of first byte that isn't uValue or SIZE_MAX if all bytes are uValue.

Note that unlike most comparison functions, 0 does not indicate a successful comparison, so the test for match is:

 UsefulBuf_IsValue(...) == SIZE_MAX

If UB is null or empty, there is no match and 0 is returned.

◆ UsefulBuf_OffsetToPointer()

const void * UsefulBuf_OffsetToPointer ( UsefulBufC UB,
size_t uOffset )
inlinestatic

Convert an offset to a pointer with bounds checking.

Parameters
[in]UBA UsefulBuf.
[in]uOffsetOffset in pUInBuf.
Returns
NULL if uOffset is out of range, a pointer into the buffer if not.

◆ UsefulBuf_PointerToOffset()

size_t UsefulBuf_PointerToOffset ( UsefulBufC UB,
const void * p )
inlinestatic

Convert a pointer to an offset with bounds checking.

Parameters
[in]UBA UsefulBuf.
[in]pPointer to convert to offset.
Returns
SIZE_MAX if p is out of range, the byte offset if not.

◆ UsefulBuf_Set()

UsefulBufC UsefulBuf_Set ( UsefulBuf pDest,
uint8_t value )
inlinestatic

Set all bytes in a UsefulBuf to a value, for example to 0.

Parameters
[in]pDestThe destination buffer to copy into.
[in]valueThe 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.

◆ UsefulBuf_Tail()

UsefulBufC UsefulBuf_Tail ( UsefulBufC UB,
size_t uAmount )
inlinestatic

Returns bytes from the end of a UsefulBufC.

Parameters
[in]UBThe buffer to get the tail of.
[in]uAmountThe offset from the start where the tail is to begin.
Returns
A UsefulBufC that is the tail of UB or NULLUsefulBufC if uAmount is greater than the length of the UsefulBufC.

If UB.ptr is NULL, but UB.len is not zero, then the result will be a UsefulBufC with a NULL ptr and len with the length of the tail.

◆ UsefulBuf_Unconst()

UsefulBuf UsefulBuf_Unconst ( const UsefulBufC UBC)
inlinestatic

Convert a const UsefulBufC to a non-const UsefulBuf.

Parameters
[in]UBCThe UsefulBuf to convert.
Returns
A non-const UsefulBuf struct.

Use of this is not necessary for the intended use mode of UsefulBufC and UsefulBuf. In that mode, the UsefulBuf is created to describe a buffer that has not had any data put in it. Then the data is put in it. Then a UsefulBufC is create to describe the part with the data in it. This goes from non-const to const, so this function is not needed.

If the -Wcast-qual warning is enabled, this function can be used to avoid that warning.

◆ UsefulBufC_Unconst()

UsefulBuf UsefulBufC_Unconst ( const UsefulBufC UBC)
inlinestatic

Deprecated function; use UsefulBuf_Unconst() instead

◆ UsefulBufUtil_CopyDoubleToUint64()

uint64_t UsefulBufUtil_CopyDoubleToUint64 ( double d)
inlinestatic

Copy a double to a uint64_t.

Parameters
[in]dDouble value to copy.
Returns
A uint64_t with the double bits.

Convenience function to avoid type punning, compiler warnings and such. The optimizer usually reduces this to a simple assignment. This is a crusty corner of C.

◆ UsefulBufUtil_CopyFloatToUint32()

uint32_t UsefulBufUtil_CopyFloatToUint32 ( float f)
inlinestatic

Copy a float to a uint32_t.

Parameters
[in]fFloat value to copy.
Returns
A uint32_t with the float bits.

Convenience function to avoid type punning, compiler warnings and such. The optimizer usually reduces this to a simple assignment. This is a crusty corner of C.

◆ UsefulBufUtil_CopyUint32ToFloat()

float UsefulBufUtil_CopyUint32ToFloat ( uint32_t u32)
inlinestatic

Copy a uint32_t to a float.

Parameters
[in]u32Integer value to copy.
Returns
The value as a float.

Convenience function to avoid type punning, compiler warnings and such. The optimizer usually reduces this to a simple assignment. This is a crusty corner of C.

◆ UsefulBufUtil_CopyUint64ToDouble()

double UsefulBufUtil_CopyUint64ToDouble ( uint64_t u64)
inlinestatic

Copy a uint64_t to a double.

Parameters
[in]u64Integer value to copy.
Returns
The value as a double.

Convenience function to avoid type punning, compiler warnings and such. The optimizer usually reduces this to a simple assignment. This is a crusty corner of C.

◆ UsefulInputBuf_BytesAvailable()

int UsefulInputBuf_BytesAvailable ( UsefulInputBuf * pUInBuf,
size_t uLen )
inlinestatic

Check if there are unconsumed bytes.

Parameters
[in]pUInBufPointer to the UsefulInputBuf.
[in]uLenNumber of bytes to check availability for.
Returns
1 if uLen bytes are available after the cursor, and 0 if not.

◆ UsefulInputBuf_BytesUnconsumed()

size_t UsefulInputBuf_BytesUnconsumed ( UsefulInputBuf * pUInBuf)
inlinestatic

Returns the number of bytes from the cursor to the end of the buffer, the unconsumed bytes.

Parameters
[in]pUInBufPointer to the UsefulInputBuf.
Returns
Number of bytes unconsumed or 0 on error.

Returns 0 if the cursor is invalid or corruption of the UsefulInputBuf structure is detected.

◆ UsefulInputBuf_GetBufferLength()

size_t UsefulInputBuf_GetBufferLength ( UsefulInputBuf * pUInBuf)
inlinestatic

Gets the input buffer length.

Parameters
[in]pUInBufPointer to the UsefulInputBuf.
Returns
The length of the input buffer.

This returns the length of the input buffer set by UsefulInputBuf_Init() or UsefulInputBuf_SetBufferLength().

◆ UsefulInputBuf_GetByte()

uint8_t UsefulInputBuf_GetByte ( UsefulInputBuf * pUInBuf)
inlinestatic

Get a byte out of the input buffer.

Parameters
[in]pUInBufPointer to the UsefulInputBuf.
Returns
The byte.

This consumes 1 byte from the input buffer, returns it and advances the position cursor by 1.

If there is not 1 byte in the buffer, 0 will be returned for the byte and the error state is entered. To know if the 0 returned was in error or the real value, the error state must be checked. If possible, put this off until all values are retrieved to have smaller and simpler code, but if not possible UsefulInputBuf_GetError() can be called. Also, in the error state UsefulInputBuf_GetBytes() returns NULL *or the ptr from UsefulInputBuf_GetUsefulBuf() is NULL.

◆ UsefulInputBuf_GetBytes()

const void * UsefulInputBuf_GetBytes ( UsefulInputBuf * pUInBuf,
size_t uNum )

Get pointer to bytes out of the input buffer.

Parameters
[in]pUInBufPointer to the UsefulInputBuf.
[in]uNumNumber of bytes to get.
Returns
Pointer to bytes.

This consumes uNum bytes from the input buffer. This returns a pointer to the start of the uNum bytes.

If there are not uNum bytes in the input buffer, NULL will be returned and the error state is entered.

This advances the position cursor by uNum bytes.

◆ UsefulInputBuf_GetDouble()

double UsefulInputBuf_GetDouble ( UsefulInputBuf * pUInBuf)
inlinestatic

Get a double out of the input buffer.

Parameters
[in]pUInBufPointer to the UsefulInputBuf.
Returns
The double.

See UsefulInputBuf_GetByte(). This works the same, except it returns a double and eight bytes are consumed.

The input bytes are interpreted in network order (big endian).

◆ UsefulInputBuf_GetError()

int UsefulInputBuf_GetError ( UsefulInputBuf * pUInBuf)
inlinestatic

Get the error status.

Parameters
[in]pUInBufPointer to the UsefulInputBuf.
Returns
0 if not in the error state, 1 if in the error state.

This returns whether the UsefulInputBuf is in the error state or not.

The error state is entered for one of these reasons:

  • Attempt to fetch data past the end of the buffer
  • Attempt to seek to a position past the end of the buffer
  • Attempt to get data from an uninitialized or corrupt instance of UsefulInputBuf

Once in the error state, it can only be cleared by calling UsefulInputBuf_Init().

For many use cases, it is possible to only call this once after all the UsefulInputBuf_GetXxxx() calls have been made. This is possible if no reference to the data returned are needed before the error state is checked.

In some cases UsefulInputBuf_GetUsefulBuf() or UsefulInputBuf_GetBytes() can stand in for this because they return NULL if the error state has been entered. (The others can't stand in because they don't return a clearly distinct error value.)

◆ UsefulInputBuf_GetFloat()

float UsefulInputBuf_GetFloat ( UsefulInputBuf * pUInBuf)
inlinestatic

Get a float out of the input buffer.

Parameters
[in]pUInBufPointer to the UsefulInputBuf.
Returns
The float.

See UsefulInputBuf_GetByte(). This works the same, except it returns a float and four bytes are consumed.

The input bytes are interpreted in network order (big endian).

◆ UsefulInputBuf_GetUint16()

uint16_t UsefulInputBuf_GetUint16 ( UsefulInputBuf * pUInBuf)
inlinestatic

Get a uint16_t out of the input buffer.

Parameters
[in]pUInBufPointer to the UsefulInputBuf.
Returns
The uint16_t.

See UsefulInputBuf_GetByte(). This works the same, except it returns a uint16_t and two bytes are consumed.

The input bytes are interpreted in network order (big endian).

◆ UsefulInputBuf_GetUint32()

uint32_t UsefulInputBuf_GetUint32 ( UsefulInputBuf * pUInBuf)
inlinestatic

Get a uint32_t out of the input buffer.

Parameters
[in]pUInBufPointer to the UsefulInputBuf.
Returns
The uint32_t.

See UsefulInputBuf_GetByte(). This works the same, except it returns a uint32_t and four bytes are consumed.

The input bytes are interpreted in network order (big endian).

◆ UsefulInputBuf_GetUint64()

uint64_t UsefulInputBuf_GetUint64 ( UsefulInputBuf * pUInBuf)
inlinestatic

Get a uint64_t out of the input buffer.

Parameters
[in]pUInBufPointer to the UsefulInputBuf.
Returns
The uint64_t.

See UsefulInputBuf_GetByte(). This works the same, except it returns a uint64_t and eight bytes are consumed.

The input bytes are interpreted in network order (big endian).

◆ UsefulInputBuf_GetUsefulBuf()

UsefulBufC UsefulInputBuf_GetUsefulBuf ( UsefulInputBuf * pUInBuf,
size_t uNum )
inlinestatic

Get UsefulBuf out of the input buffer.

Parameters
[in]pUInBufPointer to the UsefulInputBuf.
[in]uNumNumber of bytes to get.
Returns
A UsefulBufC with ptr and length of bytes consumed.

This consumes uNum bytes from the input buffer and returns the pointer and length for them as a UsefulBufC. The length returned will always be uNum. The position cursor is advanced by uNum bytes.

If there are not uNum bytes in the input buffer, NULLUsefulBufC will be returned and the error state is entered.

◆ UsefulInputBuf_Init()

void UsefulInputBuf_Init ( UsefulInputBuf * pUInBuf,
UsefulBufC UB )
inlinestatic

Initialize the UsefulInputBuf structure before use.

Parameters
[in]pUInBufPointer to the UsefulInputBuf.
[in]UBThe data to parse.

◆ UsefulInputBuf_OffsetToPointer()

const void * UsefulInputBuf_OffsetToPointer ( UsefulInputBuf * pUInBuf,
size_t uOffset )
inlinestatic

Convert an offset to a pointer with bounds checking.

Parameters
[in]pUInBufPointer to the UsefulInputBuf.
[in]uOffsetOffset in pUInBuf.
Returns
NULL if uOffset is out of range, a pointer into the buffer if not.

◆ UsefulInputBuf_PointerToOffset()

size_t UsefulInputBuf_PointerToOffset ( UsefulInputBuf * pUInBuf,
const void * p )
inlinestatic

Convert a pointer to an offset with bounds checking.

Parameters
[in]pUInBufPointer to the UsefulInputBuf.
[in]pPointer to convert to offset.
Returns
SIZE_MAX if p is out of range, the byte offset if not.

◆ UsefulInputBuf_RetrieveUndecodedInput()

UsefulBufC UsefulInputBuf_RetrieveUndecodedInput ( UsefulInputBuf * pUInBuf)
inlinestatic

Retrieve the undecoded input buffer.

Parameters
[in]pUInBufPointer to the UsefulInputBuf.
Returns
The input that was given to UsefulInputBuf_Init().

A simple convenience method, should it be useful to get the original input back.

◆ UsefulInputBuf_Seek()

void UsefulInputBuf_Seek ( UsefulInputBuf * pUInBuf,
size_t uPos )
inlinestatic

Sets the current position in input buffer.

Parameters
[in]pUInBufPointer to the UsefulInputBuf.
[in]uPosPosition to set to.

If the position is off the end of the input buffer, the error state is entered.

Seeking to a valid position in the buffer will not reset the error state. Only re-initialization will do that.

◆ UsefulInputBuf_SetBufferLength()

void UsefulInputBuf_SetBufferLength ( UsefulInputBuf * pUInBuf,
size_t uNewLen )
inlinestatic

Alters the input buffer length (use with caution).

Parameters
[in]pUInBufPointer to the UsefulInputBuf.
[in]uNewLenThe new length of the input buffer.

This alters the internal remembered length of the input buffer set when UsefulInputBuf_Init() was called.

The new length given here should always be equal to or less than the length given when UsefulInputBuf_Init() was called. Making it larger allows UsefulInputBuf to run off the input buffer.

The typical use is to set a length shorter than that when initialized to constrain parsing. If UsefulInputBuf_GetBufferLength() was called before this, then the original length can be restored with another call to this.

This should be used with caution. It is the only UsefulInputBuf method that can violate the safety of input buffer parsing.

◆ UsefulInputBuf_Tell()

size_t UsefulInputBuf_Tell ( UsefulInputBuf * pUInBuf)
inlinestatic

Returns current position in input buffer.

Parameters
[in]pUInBufPointer to the UsefulInputBuf.
Returns
Integer position of the cursor.

The position that the next bytes will be returned from.

◆ UsefulOutBuf_Advance()

void UsefulOutBuf_Advance ( UsefulOutBuf * pUOutBuf,
size_t uAmount )

Advance the amount output assuming it was written by the caller.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf.
[in]uAmountThe amount to advance.

This advances the position in the output buffer by uAmount. This assumes that the caller has written uAmount to the pointer obtained with UsefulOutBuf_GetOutPlace().

Warning: this bypasses the buffer safety provided by UsefulOutBuf!

◆ UsefulOutBuf_AppendByte()

void UsefulOutBuf_AppendByte ( UsefulOutBuf * pUOutBuf,
uint8_t byte )
inlinestatic

Append a byte to the UsefulOutBuf.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf.
[in]byteBytes to append.

See UsefulOutBuf_InsertByte() for details. This does the same with the insertion point at the end of the valid data.

◆ UsefulOutBuf_AppendData()

void UsefulOutBuf_AppendData ( UsefulOutBuf * pUOutBuf,
const void * pBytes,
size_t uLen )
inlinestatic

Append bytes to the UsefulOutBuf.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf.
[in]pBytesPointer to bytes to append.
[in]uLenLength of pBytes to append.

See UsefulOutBuf_InsertData() for details. This does the same with the insertion point at the end of the valid data.

◆ UsefulOutBuf_AppendDouble()

void UsefulOutBuf_AppendDouble ( UsefulOutBuf * pUOutBuf,
double d )
inlinestatic

Append a double to the UsefulOutBuf.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf.
[in]ddouble to append.

See UsefulOutBuf_InsertDouble() for details. This does the same with the insertion point at the end of the valid data.

The double will be appended in network byte order (big endian).

◆ UsefulOutBuf_AppendFloat()

void UsefulOutBuf_AppendFloat ( UsefulOutBuf * pUOutBuf,
float f )
inlinestatic

Append a float to the UsefulOutBuf.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf.
[in]ffloat to append.

See UsefulOutBuf_InsertFloat() for details. This does the same with the insertion point at the end of the valid data.

The float will be appended in network byte order (big endian).

◆ UsefulOutBuf_AppendString()

void UsefulOutBuf_AppendString ( UsefulOutBuf * pUOutBuf,
const char * szString )
inlinestatic

Append a NULL-terminated string to the UsefulOutBuf.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf.
[in]szStringNULL-terminated string to append.

◆ UsefulOutBuf_AppendUint16()

void UsefulOutBuf_AppendUint16 ( UsefulOutBuf * pUOutBuf,
uint16_t uInteger16 )
inlinestatic

Append an integer to the UsefulOutBuf.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf.
[in]uInteger16Integer to append.

See UsefulOutBuf_InsertUint16() for details. This does the same with the insertion point at the end of the valid data.

The integer will be appended in network byte order (big endian).

◆ UsefulOutBuf_AppendUint32()

void UsefulOutBuf_AppendUint32 ( UsefulOutBuf * pUOutBuf,
uint32_t uInteger32 )
inlinestatic

Append an integer to the UsefulOutBuf.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf.
[in]uInteger32Integer to append.

See UsefulOutBuf_InsertUint32() for details. This does the same with the insertion point at the end of the valid data.

The integer will be appended in network byte order (big endian).

◆ UsefulOutBuf_AppendUint64()

void UsefulOutBuf_AppendUint64 ( UsefulOutBuf * pUOutBuf,
uint64_t uInteger64 )
inlinestatic

Append an integer to the UsefulOutBuf.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf.
[in]uInteger64Integer to append.

See UsefulOutBuf_InsertUint64() for details. This does the same with the insertion point at the end of the valid data.

The integer will be appended in network byte order (big endian).

◆ UsefulOutBuf_AppendUsefulBuf()

void UsefulOutBuf_AppendUsefulBuf ( UsefulOutBuf * pUOutBuf,
UsefulBufC NewData )
inlinestatic

Append a UsefulBuf into the UsefulOutBuf.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf.
[in]NewDataThe 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.

◆ UsefulOutBuf_AtStart()

int UsefulOutBuf_AtStart ( UsefulOutBuf * pUOutBuf)
inlinestatic

Returns whether any data has been added to the UsefulOutBuf.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf.
Returns
1 if output position is at start, 0 if not.

◆ UsefulOutBuf_CopyOut()

UsefulBufC UsefulOutBuf_CopyOut ( UsefulOutBuf * pUOutBuf,
UsefulBuf Dest )

Copies the valid data into a supplied buffer.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf.
[out]DestThe destination buffer to copy into.
Returns
Pointer and length of copied data or NULLUsefulBufC if it will not fit in the Dest buffer or the error state was entered.

This is the same as UsefulOutBuf_OutUBuf() except it copies the data to Dest.

◆ UsefulOutBuf_GetEndPosition()

size_t UsefulOutBuf_GetEndPosition ( UsefulOutBuf * pUOutBuf)
inlinestatic

Returns position of end of data in the UsefulOutBuf.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf.
Returns
position of end of data.

On a freshly initialized UsefulOutBuf with no data added, this will return 0. After 10 bytes have been added, it will return 10 and so on.

Generally, there is no need to call this for most uses of UsefulOutBuf.

◆ UsefulOutBuf_GetError()

int UsefulOutBuf_GetError ( UsefulOutBuf * pUOutBuf)
inlinestatic

Returns the current error status.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf.
Returns
0 if all OK, 1 on error.

This returns the error status since a call to either UsefulOutBuf_Reset() of UsefulOutBuf_Init(). Once a UsefulOutBuf goes into the error state, it will stay until one of those functions is called.

Possible error conditions are:

  • bytes to be inserted will not fit
  • insertion point is out of buffer or past valid data
  • current position is off end of buffer (probably corrupted or uninitialized)
  • detect corruption / uninitialized by bad magic number

◆ UsefulOutBuf_GetOutPlace()

UsefulBuf UsefulOutBuf_GetOutPlace ( UsefulOutBuf * pUOutBuf)
inlinestatic

Returns pointer and length of the output buffer not yet used.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf.
Returns
pointer and length of output buffer not used.

This is an escape that allows the caller to write directly to the output buffer without any checks. This doesn't change the output buffer or state. It just returns a pointer and length of the bytes remaining.

This is useful to avoid having the bytes to be added all in a contiguous buffer. Its use can save memory. A good example is in the COSE encrypt implementation where the output of the symmetric cipher can go directly into the output buffer, rather than having to go into an intermediate buffer.

See UsefulOutBuf_Advance() which is used to tell UsefulOutBuf how much was written.

Warning: this bypasses the buffer safety provided by UsefulOutBuf!

◆ UsefulOutBuf_Init()

void UsefulOutBuf_Init ( UsefulOutBuf * pUOutBuf,
UsefulBuf Storage )

Initialize and supply the actual output buffer.

Parameters
[out]pUOutBufThe UsefulOutBuf to initialize.
[in]StorageBuffer to output into.

This initializes the UsefulOutBuf with storage, sets the current position to the beginning of the buffer and clears the error state.

See SizeCalculateUsefulBuf for instructions on how to initialize a UsefulOutBuf to calculate the size that would be output without actually outputting.

This must be called before the UsefulOutBuf is used.

◆ UsefulOutBuf_InsertByte()

void UsefulOutBuf_InsertByte ( UsefulOutBuf * pUOutBuf,
uint8_t byte,
size_t uPos )
inlinestatic

Insert a byte into the UsefulOutBuf.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf.
[in]byteBytes to insert.
[in]uPosIndex 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.

◆ UsefulOutBuf_InsertData()

void UsefulOutBuf_InsertData ( UsefulOutBuf * pUOutBuf,
const void * pBytes,
size_t uLen,
size_t uPos )
inlinestatic

Insert a data buffer into the UsefulOutBuf.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf.
[in]pBytesPointer to the bytes to insert
[in]uLenLength of the bytes to insert
[in]uPosIndex 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 UsefulBufC.

◆ UsefulOutBuf_InsertDouble()

void UsefulOutBuf_InsertDouble ( UsefulOutBuf * pUOutBuf,
double d,
size_t uPos )
inlinestatic

Insert a double into the UsefulOutBuf.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf.
[in]ddouble to insert.
[in]uPosIndex in output buffer at which to insert.

See UsefulOutBuf_InsertUsefulBuf() for details. This is the same with the difference being a double is to be inserted.

The double will be inserted in network byte order (big endian).

◆ UsefulOutBuf_InsertFloat()

void UsefulOutBuf_InsertFloat ( UsefulOutBuf * pUOutBuf,
float f,
size_t uPos )
inlinestatic

Insert a float into the UsefulOutBuf.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf.
[in]ffloat to insert.
[in]uPosIndex in output buffer at which to insert.

See UsefulOutBuf_InsertUsefulBuf() for details. This is the same with the difference being a float is to be inserted.

The float will be inserted in network byte order (big endian).

◆ UsefulOutBuf_InsertString()

void UsefulOutBuf_InsertString ( UsefulOutBuf * pUOutBuf,
const char * szString,
size_t uPos )
inlinestatic

Insert a NULL-terminated string into the UsefulOutBuf.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf.
[in]szStringNULL-terminated string to insert.
[in]uPosIndex in output buffer at which to insert.

◆ UsefulOutBuf_InsertUint16()

void UsefulOutBuf_InsertUint16 ( UsefulOutBuf * pUOutBuf,
uint16_t uInteger16,
size_t uPos )
inlinestatic

Insert a 16-bit integer into the UsefulOutBuf.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf.
[in]uInteger16Integer to insert.
[in]uPosIndex in output buffer at which to insert.

See UsefulOutBuf_InsertUsefulBuf() for details. This is the same with the difference being a two-byte integer is to be inserted.

The integer will be inserted in network byte order (big endian).

◆ UsefulOutBuf_InsertUint32()

void UsefulOutBuf_InsertUint32 ( UsefulOutBuf * pUOutBuf,
uint32_t uInteger32,
size_t uPos )
inlinestatic

Insert a 32-bit integer into the UsefulOutBuf.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf.
[in]uInteger32Integer to insert.
[in]uPosIndex in output buffer at which to insert.

See UsefulOutBuf_InsertUsefulBuf() for details. This is the same with the difference being a four-byte integer is to be inserted.

The integer will be inserted in network byte order (big endian).

◆ UsefulOutBuf_InsertUint64()

void UsefulOutBuf_InsertUint64 ( UsefulOutBuf * pUOutBuf,
uint64_t uInteger64,
size_t uPos )
inlinestatic

Insert a 64-bit integer into the UsefulOutBuf.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf.
[in]uInteger64Integer to insert.
[in]uPosIndex in output buffer at which to insert.

See UsefulOutBuf_InsertUsefulBuf() for details. This is the same with the difference being an eight-byte integer is to be inserted.

The integer will be inserted in network byte order (big endian).

◆ UsefulOutBuf_InsertUsefulBuf()

void UsefulOutBuf_InsertUsefulBuf ( UsefulOutBuf * pUOutBuf,
UsefulBufC NewData,
size_t uPos )

Inserts bytes into the UsefulOutBuf.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf.
[in]NewDataThe bytes to insert.
[in]uPosIndex 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 are slid to the right to make room for the new data.

Overlapping buffers are OK. NewData can point to data in the output buffer.

NewData.len may be 0 in which case nothing will be inserted.

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.

The intended use is that all additions are made without checking for an error. The error will be taken into account when UsefulOutBuf_OutUBuf() returns NullUsefulBufC. UsefulOutBuf_GetError() can also be called to check for an error.

◆ UsefulOutBuf_IsBufferNULL()

int UsefulOutBuf_IsBufferNULL ( UsefulOutBuf * pUOutBuf)
inlinestatic

Returns 1 if buffer given to UsefulOutBuf_Init() was NULL.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf
Returns
1 if buffer given to UsefulOutBuf_Init() was NULL.

Giving a NULL output buffer to UsefulOutBuf_Init() is used when just calculating the length of the encoded data.

◆ UsefulOutBuf_OutUBuf()

UsefulBufC UsefulOutBuf_OutUBuf ( UsefulOutBuf * pUOutBuf)

Returns the resulting valid data in a UsefulOutBuf.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf.
Returns
The valid data in UsefulOutBuf or NULLUsefulBufC if there was an error adding data.

The storage for the returned data is the 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 further data can be added.

◆ UsefulOutBuf_Reset()

void UsefulOutBuf_Reset ( UsefulOutBuf * pUOutBuf)
inlinestatic

Reset a UsefulOutBuf for re use.

Parameters
[in]pUOutBufPointer 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.

This doesn't zero the data, just resets to 0 bytes of valid data.

◆ UsefulOutBuf_RetrieveOutputStorage()

UsefulBuf UsefulOutBuf_RetrieveOutputStorage ( UsefulOutBuf * pUOutBuf)
inlinestatic

Retrieve the storage buffer passed in to UsefulOutBuf_Init().

Parameters
[in]pUOutBufThe encoding context.
Returns
The output storage buffer passed to UsefulOutBuf_Init().

This doesn't give any information about how much has been encoded or the error state. It just returns the exact UsefulOutBuf given to UsefulOutBuf_Init().

◆ UsefulOutBuf_RoomLeft()

size_t UsefulOutBuf_RoomLeft ( UsefulOutBuf * pUOutBuf)
inlinestatic

Returns number of bytes unused used in the output buffer.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf.
Returns
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.

◆ UsefulOutBuf_SubString()

UsefulBufC UsefulOutBuf_SubString ( UsefulOutBuf * pUOutBuf,
const size_t uStart,
const size_t uLen )

Return a substring of the output data.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf.
[in]uStartOffset of start of substring.
[in]uLenLength of substring.

This is the same as UsefulOutBuf_OutUBuf(), but returns a substring. NULLUsefulBufC is returned if the requested substring is off the end of the output bytes or if in error state.

◆ UsefulOutBuf_WillItFit()

int UsefulOutBuf_WillItFit ( UsefulOutBuf * pUOutBuf,
size_t uLen )
inlinestatic

Returns 1 if some number of bytes will fit in the UsefulOutBuf.

Parameters
[in]pUOutBufPointer to the UsefulOutBuf
[in]uLenNumber of bytes for which to check
Returns
1 if uLen bytes will fit, 0 if not.

Because of the error handling strategy and checks in UsefulOutBuf_InsertUsefulBuf() it is usually not necessary to use this.