/* SPDX-License-Identifier: MIT */ #pragma once #ifndef rb_size_t #define rb_size_t int #endif /** Signatures of generic functions */ typedef void *(*ALLOC_T)(rb_size_t); typedef void *(*MEMCPY_T)(void *, const void *, rb_size_t); /** * Ring buffer, also known as circular buffer. */ struct RingBuf { rb_size_t struct_size; /* Size of the struct */ rb_size_t capacity; /* The physical capacity of the entire ringbuf */ rb_size_t size; /* The current size of the ring buffer */ void *write_head; /* Address of the write head */ rb_size_t write_idx; /* The write head */ rb_size_t read_idx; /* THe read head */ rb_size_t count; /* The number of elements in the buffer */ void *buffer; /* The actual data */ void *buffer_end; /* The end of the buffer */ } __attribute__((packed)); enum WriteResult { CollisionError, Ok }; /** Initialize the ring buffer */ void rb_init(struct RingBuf *rb, rb_size_t capacity, void *(*alloc)(rb_size_t), rb_size_t struct_size); /** Insert data to the ring buffer */ enum WriteResult rb_push(struct RingBuf *rb, void *data, rb_size_t amount, void *(*memcpy)(void *, const void *, rb_size_t)); enum WriteResult rb_push_back(struct RingBuf *rb, const void *item, MEMCPY_T memcpy_fn); /** Read data from the ring buffer */ void rb_read(struct RingBuf *rb, void *dest, int amount); /** Free the ring buffer */ void rb_destroy(struct RingBuf *rb, void(free)()); void print_seq(void *begin, int amount);