diff options
Diffstat (limited to 'kern/cbuf.h')
-rw-r--r-- | kern/cbuf.h | 50 |
1 files changed, 37 insertions, 13 deletions
diff --git a/kern/cbuf.h b/kern/cbuf.h index 3ea38418..4d69334d 100644 --- a/kern/cbuf.h +++ b/kern/cbuf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Richard Braun. + * Copyright (c) 2015-2017 Richard Braun. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,6 +21,9 @@ #ifndef _KERN_CBUF_H #define _KERN_CBUF_H +#include <stdbool.h> +#include <stddef.h> + /* * Circular buffer descriptor. * @@ -29,30 +32,30 @@ */ struct cbuf { char *buf; - unsigned long capacity; - unsigned long start; - unsigned long end; + size_t capacity; + size_t start; + size_t end; }; -static inline unsigned long +static inline size_t cbuf_capacity(const struct cbuf *cbuf) { return cbuf->capacity; } -static inline unsigned long +static inline size_t cbuf_start(const struct cbuf *cbuf) { return cbuf->start; } -static inline unsigned long +static inline size_t cbuf_end(const struct cbuf *cbuf) { return cbuf->end; } -static inline unsigned long +static inline size_t cbuf_size(const struct cbuf *cbuf) { return cbuf->end - cbuf->start; @@ -64,13 +67,21 @@ cbuf_clear(struct cbuf *cbuf) cbuf->start = cbuf->end; } +static inline bool +cbuf_range_valid(const struct cbuf *cbuf, size_t start, size_t end) +{ + return (((end - start) <= cbuf_size(cbuf)) + && ((start - cbuf->start) <= cbuf_size(cbuf)) + && ((cbuf->end - end) <= cbuf_size(cbuf))); +} + /* * Initialize a circular buffer. * * The descriptor is set to use the given buffer for storage. Capacity * must be a power-of-two. */ -void cbuf_init(struct cbuf *cbuf, char *buf, unsigned long capacity); +void cbuf_init(struct cbuf *cbuf, char *buf, size_t capacity); /* * Append a byte to a circular buffer. @@ -90,12 +101,25 @@ void cbuf_push(struct cbuf *cbuf, char byte); int cbuf_pop(struct cbuf *cbuf, char *bytep); /* - * Read a byte at a specific location. + * Write into a circular buffer at a specific location. + * + * If the given index is outside buffer boundaries, ERROR_INVAL is returned. + * Otherwise size bytes are copied into the circular buffer. If the range + * in the circular buffer goes beyond its end, the end index is updated as + * appropriate. If the buffer is full when extending its end, the oldest + * bytes are overwritten and the start index is updated accordingly. + */ +int cbuf_write(struct cbuf *cbuf, size_t index, const void *buf, size_t size); + +/* + * Read from a circular buffer at a specific location. * * If the given index is outside buffer boundaries, ERROR_INVAL is returned. - * Otherwise the byte is stored at the bytep address and 0 is returned. - * The buffer isn't changed by this operation. + * Otherwise at most *sizep bytes are copied into the given byte buffer, + * and *sizep is updated to the number of bytes actually copied. + * + * The circular buffer isn't changed by this operation. */ -int cbuf_read(const struct cbuf *cbuf, unsigned long index, char *bytep); +int cbuf_read(const struct cbuf *cbuf, size_t index, void *buf, size_t *sizep); #endif /* _KERN_CBUF_H */ |