#ifndef RINGBUFFER_H #define RINGBUFFER_H #ifdef __cplusplus extern "C" { #endif #include typedef struct { uint32_t head; uint32_t tail; uint32_t size; uint8_t data[]; } ringbuffer; #define RINGBUFFER_STORAGE(NAME, SIZE) \ uint8_t buf_##NAME##__LINE__[sizeof(ringbuffer) + SIZE]; \ ringbuffer *NAME = (ringbuffer *)buf_##NAME##__LINE__; #define RINGBUFFER_INIT(NAME, SIZE) \ NAME->head = NAME->tail = 0; \ NAME->size = SIZE; #define RINGBUFFER(NAME, SIZE) \ RINGBUFFER_STORAGE(NAME, SIZE); \ RINGBUFFER_INIT(NAME, SIZE); /** Fully empties the ringbuffer */ void ringbuffer_rst(ringbuffer *buf); /** The total capacity of the ringbuffer */ unsigned ringbuffer_capacity(ringbuffer *buf); /** The free capacity of the ringbuffer */ unsigned ringbuffer_free(ringbuffer *buf); /** The used capacity of the ringbuffer */ unsigned ringbuffer_level(ringbuffer *buf); /** Non-zero if the ringbuffer is empty */ unsigned ringbuffer_empty(ringbuffer *buf); /** Add data to the ringbuffer, return actual length of added data */ unsigned ringbuffer_add(ringbuffer *buf, void const *dat, unsigned len); /** Get data from the ringbuffer, return actual length of retrieved data */ unsigned ringbuffer_get(ringbuffer *buf, void *dst, unsigned len); /** Get data from the ringbuffer, but do not remove it. Return actual length of retrieved data. */ unsigned ringbuffer_peek(ringbuffer *buf, void *dst, unsigned len); /** Remove data from the ringbuffer without reading it */ void ringbuffer_skip(ringbuffer *buf, unsigned len); #ifdef __cplusplus } #endif #endif