#include #include #include #include #include #include "circ_buff.h" // Defines the circular buffer structure struct circ_buf_t { char** buffer; size_t head; size_t tail; size_t max; // of the buffer bool full; }; // Private Functions static void advance_pointer(cbuf_handle_t cbuf) { assert(cbuf); if(cbuf->full) { cbuf->tail = (cbuf->tail + 1) % cbuf->max; } cbuf->head = (cbuf->head + 1) % cbuf->max; // We mark full because we will advance tail on the next time around cbuf->full = (cbuf->head == cbuf->tail); } static void retreat_pointer(cbuf_handle_t cbuf) { assert(cbuf); cbuf->full = false; cbuf->tail = (cbuf->tail + 1) % cbuf->max; } // APIs cbuf_handle_t circ_buf_init(char** buffer, size_t size) { assert(buffer && size); cbuf_handle_t cbuf = malloc(sizeof(circ_buf_t)); assert(cbuf); cbuf->buffer = buffer; cbuf->max = size; circ_buf_reset(cbuf); assert(circ_buf_empty(cbuf)); return cbuf; } void circ_buf_free(cbuf_handle_t cbuf) { assert(cbuf); free(cbuf); } void circ_buf_reset(cbuf_handle_t cbuf) { assert(cbuf); cbuf->head = 0; cbuf->tail = 0; cbuf->full = false; } size_t circ_buf_size(cbuf_handle_t cbuf) { assert(cbuf); size_t size = cbuf->max; if(!cbuf->full) { if(cbuf->head >= cbuf->tail) { size = (cbuf->head - cbuf->tail); } else { size = (cbuf->max + cbuf->head - cbuf->tail); } } return size; } size_t circ_buf_capacity(cbuf_handle_t cbuf) { assert(cbuf); return cbuf->max; } void circ_buf_put(cbuf_handle_t cbuf, char data) { assert(cbuf && cbuf->buffer); strcpy(cbuf->buffer[cbuf->head], data); advance_pointer(cbuf); } int circ_buf_get(cbuf_handle_t cbuf, char* data) { assert(cbuf && data && cbuf->buffer); int r = -1; if(!circ_buf_empty(cbuf)) { strcpy(data, cbuf->buffer[cbuf->tail]); retreat_pointer(cbuf); r = 0; } return r; } bool circ_buf_empty(cbuf_handle_t cbuf) { assert(cbuf); return (!cbuf->full && (cbuf->head == cbuf->tail)); } bool circ_buf_full(cbuf_handle_t cbuf) { assert(cbuf); return cbuf->full; }