libds

a collection of simple data structures
Log | Files | Refs | LICENSE

commit 79305390876395bbd5e1d7de4c598425d4347689
parent 321aa046d5eb8d5e44eacfd268f8eef4269a7851
Author: sin <sin@2f30.org>
Date:   Tue,  8 Apr 2014 10:14:56 +0100

Add simple fifo implementation

Diffstat:
MMakefile | 2+-
Mds.h | 6++++++
Afifo.c | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 80 insertions(+), 1 deletion(-)

diff --git a/Makefile b/Makefile @@ -3,7 +3,7 @@ include config.mk -SRC = vector.c +SRC = vector.c fifo.c OBJ = ${SRC:.c=.o} SOUT = ${NAME}.a diff --git a/ds.h b/ds.h @@ -11,4 +11,10 @@ void *vector_get(struct vector *, size_t); size_t vector_len(struct vector *); void vector_walk(struct vector *, void (*)(struct vector *, void *)); +/* fifo.c */ +struct fifo *fifo_init(size_t); +void fifo_free(struct fifo *); +int fifo_enqueue(struct fifo *, const void *, size_t) +int fifo_dequeue(struct fifo *, void *, size_t); + #endif diff --git a/fifo.c b/fifo.c @@ -0,0 +1,73 @@ +#include <stdlib.h> +#include <string.h> + +struct fifo { + unsigned char *buf; + size_t sz; + size_t cap; +}; + +struct fifo * +fifo_init(size_t cap) +{ + struct fifo *fifo; + + fifo = malloc(sizeof(*fifo)); + if (!fifo) + return NULL; + if (cap > 0) { + fifo->buf = malloc(cap); + if (!fifo->buf) { + free(fifo); + return NULL; + } + } + fifo->sz = 0; + fifo->cap = cap; + return fifo; +} + +void +fifo_free(struct fifo *fifo) +{ + free(fifo->buf); + free(fifo); +} + +int +fifo_enqueue(struct fifo *fifo, const void *buf, size_t sz) +{ + void *tmp; + + if (!sz) + return 0; + + if (fifo->cap - fifo->sz >= sz) { + memcpy(fifo->buf + fifo->sz, buf, sz); + fifo->sz += sz; + return 0; + } + + tmp = realloc(fifo->buf, fifo->cap + sz); + if (!tmp) + return -1; + fifo->buf = tmp; + memcpy(fifo->buf + fifo->sz, buf, sz); + fifo->sz += sz; + fifo->cap += sz; + return 0; +} + +int +fifo_dequeue(struct fifo *fifo, void *buf, size_t sz) +{ + if (!sz) + return 0; + + if (fifo->sz < sz) + return -1; + memcpy(buf, fifo->buf, sz); + memmove(fifo->buf, fifo->buf + sz, fifo->sz - sz); + fifo->sz -= sz; + return 0; +}