82 lines
1.8 KiB
C
82 lines
1.8 KiB
C
#pragma once
|
|
|
|
// Guards for C++ usage
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#include <string.h>
|
|
#include <stdbool.h>
|
|
|
|
/* A sized buffer abstraction.
|
|
*
|
|
* Functions that return int's will return 0 on success and nonzero otherwise.
|
|
*/
|
|
|
|
typedef struct sized_buf SizedBuf;
|
|
|
|
struct sized_buf
|
|
{
|
|
char *data;
|
|
size_t size;
|
|
};
|
|
|
|
// Returns 0 if the given buffer has at least size bytes available
|
|
inline int sb_check(const SizedBuf sb, const size_t size)
|
|
{
|
|
return !(sb.size >= size);
|
|
}
|
|
|
|
// Moves the buffer size bytes forward, makes no checks
|
|
inline void sb_update(SizedBuf *const sb, const size_t size)
|
|
{
|
|
sb->data += size;
|
|
sb->size -= size;
|
|
}
|
|
|
|
// Copies size bytes of data from the source to the buffer
|
|
inline int sb_copyin(SizedBuf *const sb, const char *const source, const size_t size)
|
|
{
|
|
int ret = sb_check(*sb, size);
|
|
if (!ret) {
|
|
memcpy(sb->data, source, size);
|
|
sb_update(sb, size);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
// "Recasts" size bytes of memory and returns a pointer to said memory in out
|
|
inline int sb_recast(SizedBuf *const sb, const size_t size, const void **const out)
|
|
{
|
|
int ret = sb_check(*sb, size);
|
|
if (!ret) {
|
|
*out = sb->data;
|
|
sb_update(sb, size);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
// "Recasts" size bytes of memory without actually consuming the buffer
|
|
inline int sb_peek(const SizedBuf sb, const size_t size, const void **const out)
|
|
{
|
|
*out = sb.data;
|
|
return sb_check(sb, size);
|
|
}
|
|
|
|
// Returns a pointer just after the end of the sized buffer
|
|
inline char *sb_end(const SizedBuf sb)
|
|
{
|
|
return sb.data + sb.size;
|
|
}
|
|
|
|
inline bool sb_empty(const SizedBuf sb)
|
|
{
|
|
return sb.size == 0;
|
|
}
|
|
|
|
// End C++ guard
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|