#pragma once // Guards for C++ usage #ifdef __cplusplus extern "C" { #endif #include #include /* 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