| /* Copyright (c) 2015 Google Inc | 
 |  * Davide Libenzi <dlibenzi@google.com> | 
 |  * See LICENSE for details. | 
 |  * | 
 |  * The circular buffer interface allows to allocate once, and store atomic | 
 |  * data blocks into it, with automatic drop of older blocks, when the buffer | 
 |  * becomes full. | 
 |  * Blocks are written atomically in the sense that when data is dropped from | 
 |  * the head of the buffer, full blocks are dropped, so the circular buffer | 
 |  * never returns partial blocks. | 
 |  * Appending is O(1) WRT the number of blocks, while seeks are O(N). | 
 |  * Reading data from the circular buffer interface, does not drop  the read | 
 |  * data from the head of the buffer (the head is pushed forward only when the | 
 |  * write pointer wraps around and need more space for a new incoming write | 
 |  * operation). | 
 |  * The buffer can either be initialized with caller memory (if the "mem" | 
 |  * parameter of circular_buffer_init() is not NULL), or it can allocate | 
 |  * memory by itself in circular_buffer_init(). | 
 |  * Once the initial (eventual) allocation is done, no more allocations will | 
 |  * be performed. | 
 |  */ | 
 |  | 
 | #pragma once | 
 |  | 
 | #include <sys/types.h> | 
 | #include <stdio.h> | 
 |  | 
 | typedef uint32_t cbuf_size_t; | 
 |  | 
 | struct circular_buffer { | 
 | 	char *mem; | 
 | 	char *base; | 
 | 	char *rdptr; | 
 | 	char *wrptr; | 
 | 	size_t size; | 
 | 	size_t allocated; | 
 | }; | 
 |  | 
 | bool circular_buffer_init(struct circular_buffer *cb, size_t size, char *mem); | 
 | void circular_buffer_destroy(struct circular_buffer *cb); | 
 | void circular_buffer_clear(struct circular_buffer *cb); | 
 | size_t circular_buffer_write(struct circular_buffer *cb, const char *data, | 
 | 			     size_t size); | 
 | size_t circular_buffer_read(struct circular_buffer *cb, char *data, size_t size, | 
 | 			    size_t off); | 
 |  | 
 | static inline size_t circular_buffer_size(const struct circular_buffer *cb) | 
 | { | 
 | 	return cb->size; | 
 | } | 
 |  | 
 | static inline size_t circular_buffer_max_write_size( | 
 | 	const struct circular_buffer *cb) | 
 | { | 
 | 	return cb->allocated - 2 * sizeof(cbuf_size_t); | 
 | } |