mirror of https://github.com/yandex/odyssey.git
100 lines
1.5 KiB
C
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 */
|