odyssey/third_party/machinarium/sources/buf.h

100 lines
1.5 KiB
C

#ifndef MM_BUF_H
#define MM_BUF_H
/*
* machinarium.
*
* cooperative multitasking engine.
*/
typedef struct mm_buf mm_buf_t;
struct mm_buf
{
char *start;
char *pos;
char *end;
};
static inline void
mm_buf_init(mm_buf_t *buf)
{
buf->start = NULL;
buf->pos = NULL;
buf->end = NULL;
}
static inline void
mm_buf_free(mm_buf_t *buf)
{
if (buf->start == NULL)
return;
free(buf->start);
buf->start = NULL;
buf->pos = NULL;
buf->end = NULL;
}
static inline int
mm_buf_size(mm_buf_t *buf)
{
return buf->end - buf->start;
}
static inline int
mm_buf_used(mm_buf_t *buf)
{
return buf->pos - buf->start;
}
static inline int
mm_buf_unused(mm_buf_t *buf)
{
return buf->end - buf->pos;
}
static inline void
mm_buf_reset(mm_buf_t *buf)
{
buf->pos = buf->start;
}
static inline int
mm_buf_ensure(mm_buf_t *buf, int size)
{
if (buf->end - buf->pos >= size)
return 0;
int sz = mm_buf_size(buf) * 2;
int actual = mm_buf_used(buf) + size;
if (actual > sz)
sz = actual;
char *p;
p = realloc(buf->start, sz);
if (p == NULL)
return -1;
buf->pos = p + (buf->pos - buf->start);
buf->end = p + sz;
buf->start = p;
assert((buf->end - buf->pos) >= size);
return 0;
}
static inline void
mm_buf_advance(mm_buf_t *buf, int size)
{
buf->pos += size;
}
static inline int
mm_buf_add(mm_buf_t *buf, void *pointer, int size)
{
int rc = mm_buf_ensure(buf, size);
if (rc == -1)
return -1;
memcpy(buf->pos, pointer, size);
mm_buf_advance(buf, size);
return 0;
}
#endif /* MM_BUF_H */