some progress
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
Generic buffer structure, both dynamic and static.
|
||||
|
||||
Underlying implementation is very simplistic, but it's done so
|
||||
in assumption that we always bulk allocate, with no fragmentation.
|
||||
*/
|
||||
|
||||
#ifndef COM_BUF_H
|
||||
#define COM_BUF_H
|
||||
|
||||
#include "def.h"
|
||||
#include "str.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define COM_BUF_GROWABLE (1 << 0) /* Potentially growable. */
|
||||
#define COM_BUF_STACK (1 << 1) /* Stack residing. */
|
||||
#define COM_BUF_RING (1 << 2) /* Cycling memory. */
|
||||
#define COM_BUF_SUB (1 << 3) /* Buffer inside of a buffer. */
|
||||
|
||||
typedef struct com_buf {
|
||||
uint32_t len; /* Length in typed number of elements. */
|
||||
uint32_t cap; /* Capacity in typed number of elements. */
|
||||
uint32_t flags;
|
||||
union {
|
||||
uint32_t needle; /* Present for ring type. */
|
||||
} type;
|
||||
uint8_t typesz;
|
||||
char data[] __attribute__((aligned(COM_DEF_ALIGNMENT)));
|
||||
} com_buf;
|
||||
|
||||
/* Creates a stack local buffer. It can grow if is set growable, one must still
|
||||
* free it. */
|
||||
#define com_buf_make_on_stack(p_t, p_v, p_c, p_f) \
|
||||
char p_v##_buf[sizeof(p_t) * (p_c)] \
|
||||
__attribute__((aligned(COM_DEF_ALIGNMENT))); \
|
||||
struct com_buf *p_v = (struct com_buf *)&p_v##_buf; \
|
||||
p_v->cap = (p_c); \
|
||||
p_v->flags = p_f | COM_BUF_STACK; \
|
||||
p_v->typesz = sizeof(p_t);
|
||||
|
||||
#define com_buf_index(p_t, p_v, p_i) \
|
||||
(p_t *)(&(p_v)->data[(p_v)->typesz * (p_i)])
|
||||
|
||||
/* Dynamic allocation to persist no matter the function flow. */
|
||||
struct com_buf *com_buf_make(uint32_t cap, uint32_t flags);
|
||||
|
||||
/* Makes sure there's N elements of capacity at least. Returns false if it
|
||||
* cannot do so. */
|
||||
bool com_buf_make_room(struct com_buf *b, uint32_t n);
|
||||
|
||||
/* Drops the memory, not touching the cap. */
|
||||
static inline void com_buf_clear(struct com_buf *b) { b->len = 0; }
|
||||
|
||||
void com_buf_free(struct com_buf *b);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user