87 lines
		
	
	
	
		
			2.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			87 lines
		
	
	
	
		
			2.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* SPDX-License-Identifier: MIT */
 | |
| 
 | |
| #pragma once
 | |
| 
 | |
| #ifndef rb_size_t
 | |
| #define rb_size_t int
 | |
| #endif
 | |
| 
 | |
| /** Signatures of allocators */
 | |
| typedef void *(*ALLOC_T)(rb_size_t);
 | |
| 
 | |
| /** Signature of memcpy */
 | |
| typedef void *(*MEMCPY_T)(void *, const void *, rb_size_t);
 | |
| 
 | |
| /**
 | |
|  * @brief 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 count;       /** The number of elements in the buffer */
 | |
|   void     *write_head;  /** Address of the write head */
 | |
|   void     *read_head;   /** Address of the read head */
 | |
|   void     *buffer;      /** The actual data */
 | |
|   void     *buffer_end;  /** The end of the buffer */
 | |
| } __attribute__((packed));
 | |
| 
 | |
| enum WriteResult { Full, WriteOk }; /** Result of a write */
 | |
| enum ReadResult { Empty, ReadOk };  /** Result of a read */
 | |
| 
 | |
| /**
 | |
|  * @brief Initialize the ring buffer
 | |
|  * @param rb The ring buffer to initialize
 | |
|  * @param capacity The capacity of the ring buffer
 | |
|  * @param alloc The allocator function
 | |
|  * @param struct_size The size of the struct
 | |
|  * @return void
 | |
|  */
 | |
| void rb_init(struct RingBuf *rb, rb_size_t capacity, ALLOC_T alloc,
 | |
|              rb_size_t struct_size);
 | |
| 
 | |
| /**
 | |
|  * @brief Insert data to the ring buffer
 | |
|  * @param rb The ring buffer
 | |
|  * @param item The item to insert
 | |
|  * @param memcpy_fn The memcpy function
 | |
|  * @return WriteResult
 | |
|  */
 | |
| enum WriteResult rb_push_back(struct RingBuf *rb, const void *item,
 | |
|                               MEMCPY_T memcpy_fn);
 | |
| 
 | |
| /**
 | |
|  * @brief Insert multiple data to the ring buffer
 | |
|  * 
 | |
|  * @details This function is more efficient than calling rb_push_back multiple
 | |
|  * times. It only advances the write head once, and attempts to write all the
 | |
|  * memory in one go. 
 | |
|  * 
 | |
|  * If n is greater than the capacity, it will return Full.
 | |
|  * If the full write will overflow, it will wrap around.
 | |
|  * 
 | |
|  * If the buffer is full, it will return Full and not write
 | |
|  * anything.
 | |
|  * 
 | |
|  * @param rb The ring buffer
 | |
|  * @param items The items to insert
 | |
|  * @param memcpy_fn The memcpy function
 | |
|  * @param n The number of items to insert
 | |
|  * @return WriteResult
 | |
|  */
 | |
| enum WriteResult rb_push_many(struct RingBuf *rb, const void *items,
 | |
|                               MEMCPY_T memcpy_fn, rb_size_t n);
 | |
| 
 | |
| /**
 | |
|  * @brief Read data from the ring buffer
 | |
|  * @param rb The ring buffer
 | |
|  * @param item The item to read into
 | |
|  * @return ReadResult
 | |
|  */
 | |
| enum ReadResult rb_pop_front(struct RingBuf *rb, void *item);
 | |
| 
 | |
| /**
 | |
|  * @brief Free the ring buffer
 | |
|  * @param rb The ring buffer
 | |
|  * @param free The free function
 | |
|  */
 | |
| void rb_destroy(struct RingBuf *rb, void(free)());
 | 
