diff options
Diffstat (limited to 'qbuf.c')
-rw-r--r-- | qbuf.c | 62 |
1 files changed, 62 insertions, 0 deletions
@@ -0,0 +1,62 @@ +#include <assert.h> +#include <string.h> +#include <stdlib.h> + +#include "qbuf.h" + +void qbuf_init(struct qbuf *q, size_t length) { + assert(q && length); + memset(q, 0, sizeof(struct qbuf)); + + q->data = malloc(q->length = length*2); + assert(q->data); +} + +void qbuf_done(struct qbuf *q) { + assert(q); + free(q->data); +} + +static void move_to_front(struct qbuf *q) { + assert(q); + + if (q->index+q->fill <= q->length/2) + return; + + memmove(q->data, q->data+q->index, q->fill); + q->index = 0; +} + +void* qbuf_push(struct qbuf *q, size_t *l) { + size_t m; + assert(q); + + move_to_front(q); + m = q->length - q->fill - q->index; + *l = m; + return q->data + q->index + q->fill; +} + +void qbuf_push_validate(struct qbuf *q, size_t l) { + assert(q); + q->fill += l; + assert(q->index+q->fill <= q->length); +} + +void* qbuf_pull(struct qbuf *q, size_t *l) { + assert(q); + *l = q->fill; + return q->data + q->index; +} + +void qbuf_pull_invalidate(struct qbuf *q, size_t l) { + assert(q); + + assert(l <= q->fill); + q->fill -= l; + q->index += l; + + assert(q->index+q->fill <= q->length); + if (!q->fill) + q->index = 0; +} |