You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
124 lines
2.7 KiB
124 lines
2.7 KiB
/**
|
|
* @file circbuf.h
|
|
* @author Ondřej Hruška, 2016,2023
|
|
*
|
|
* Circular buffer / queue / stack.
|
|
*
|
|
* The buffer may be used as a stack, event queue or a simple buffer.
|
|
*
|
|
* -------------------------------------
|
|
*
|
|
* NW LR
|
|
* append -> [][][][] -> pop
|
|
* <- push
|
|
*
|
|
* NW - next write pointer (stack base)
|
|
* LR - last read position (stack top)
|
|
*
|
|
* -------------------------------------
|
|
*
|
|
* MIT license
|
|
*/
|
|
|
|
#ifndef CIRCBUF_H
|
|
#define CIRCBUF_H
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <stdlib.h>
|
|
|
|
// Enable to zero a freed slots after pop, useful for debugging
|
|
#define CIRCBUF_ZERO_FREE_SLOTS
|
|
|
|
|
|
typedef uint32_t circbuf_size_t;
|
|
|
|
/** Instance structure - public to allow static allocation, but consider the structure internal matter */
|
|
struct circbuf_struct {
|
|
void *buf;
|
|
circbuf_size_t elem_size;
|
|
circbuf_size_t cap;
|
|
circbuf_size_t lr; // last read pos
|
|
circbuf_size_t nw; // next write pos
|
|
};
|
|
|
|
typedef struct circbuf_struct CircBuf;
|
|
|
|
/**
|
|
* @brief Initialize a circular buffer
|
|
*
|
|
* @param[in,out] cb - pointer to the buffer to init, can be statically or dynamically allocated
|
|
* @param buf : backing buffer, can be statically or dynamically allocated
|
|
* @param capacity : buffer capacity
|
|
* @param elem_size : size of one element
|
|
*/
|
|
void cbuf_init(CircBuf *cb, void *buf, circbuf_size_t capacity, circbuf_size_t elem_size);
|
|
|
|
|
|
/** Test for full buffer */
|
|
bool cbuf_full(const CircBuf *cb);
|
|
|
|
|
|
/** Test for empty buffer */
|
|
bool cbuf_empty(const CircBuf *cb);
|
|
|
|
|
|
/**
|
|
* @brief Push to front
|
|
* @param cb : buffer
|
|
* @param source : pointer to a value (will be copied)
|
|
* @return success
|
|
*/
|
|
bool cbuf_push(CircBuf *cb, const void *source);
|
|
|
|
|
|
/**
|
|
* @brief Pop from front
|
|
* @param cb : buffer
|
|
* @param dest : read destination. If NULL, value is discarded.
|
|
* @return success
|
|
*/
|
|
bool cbuf_pop(CircBuf *cb, void *dest);
|
|
|
|
|
|
/**
|
|
* @brief Push to end
|
|
* @param cb : buffer
|
|
* @param source : pointer to a value (will be copied)
|
|
* @return success
|
|
*/
|
|
bool cbuf_push_back(CircBuf *cb, const void *source);
|
|
|
|
|
|
/**
|
|
* @brief Pop from end
|
|
* @param cb : buffer
|
|
* @param dest : read destination. If NULL, value is discarded.
|
|
* @return success
|
|
*/
|
|
bool cbuf_pop_back(CircBuf *cb, void *dest);
|
|
|
|
|
|
/**
|
|
* @brief Copy the frontmost element without changing the buffer
|
|
* @param cb : buffer
|
|
* @param dest : read destination
|
|
* @return success
|
|
*/
|
|
bool cbuf_peek(const CircBuf *cb, void *dest);
|
|
|
|
|
|
/**
|
|
* @brief Copy the backmost element without changing the buffer
|
|
* @param cb : buffer
|
|
* @param dest : read destination
|
|
* @return success
|
|
*/
|
|
bool cbuf_peek_back(const CircBuf *cb, void *dest);
|
|
|
|
|
|
/** @brief Remove all data from buffer */
|
|
void cbuf_clear(CircBuf *cb);
|
|
|
|
|
|
#endif // CIRCBUF_H
|
|
|