#include #include #include #include #include #include "circ_buff.h" // Defines the circular buffer structure struct circ_buf_t { message_handle_t *buffer; size_t head; size_t tail; size_t max; // of the buffer bool full; }; // Private Functions unit_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); } unit_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(message_handle_t *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, const message_handle_t *data) { assert(cbuf && cbuf->buffer); // TODO: sort and check if new data actually older!! cbuf->buffer[cbuf->head] = *data; advance_pointer(cbuf); } int circ_buf_get(cbuf_handle_t cbuf, message_handle_t *data) { assert(cbuf && data && cbuf->buffer); int r = -1; if(!circ_buf_empty(cbuf)) { data = &(cbuf->buffer[cbuf->tail]); retreat_pointer(cbuf); r = 0; } return r; } int circ_buf_read(cbuf_handle_t cbuf, size_t position, message_handle_t *data) { assert(cbuf && data && cbuf->buffer && (position < circ_buf_size(cbuf))); int r = -1; if(!circ_buf_empty(cbuf)) { data = &(cbuf->buffer[(cbuf->tail + position) % cbuf->max]); 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; } /*void circ_buf_mul_add(cbuf_handle_t cbuf, char **data, uint8_t size, int (*compar)(const void *, const void *)) { assert(cbuf && data && cbuf->buffer); qsort(data, size, sizeof(char*), compar); char *last_element = (char*) malloc(circ_buf_element_size(cbuf) * sizeof(char)); for (uint8_t i = 0; i < size; ++i) { circ_buf_read(cbuf, 0, last_element); if (compar(&data[i], &last_element) < 0) { continue; } circ_buf_put(cbuf, data[i]); } free(last_element); int end_buffer_size = circ_buf_size(cbuf); char **temp_array = (char **) malloc(end_buffer_size * sizeof(char *)); for (uint8_t buff_el = 0; buff_el < end_buffer_size; ++buff_el) { temp_array[buff_el] = (char *) malloc(circ_buf_element_size(cbuf) * sizeof(char)); circ_buf_get(cbuf, temp_array[buff_el]); } qsort(temp_array, end_buffer_size, sizeof(char*), compar); for (uint8_t i = 0; i < end_buffer_size; ++i) { circ_buf_put(cbuf, temp_array[i]); } for (uint8_t buff_el = 0; buff_el < end_buffer_size; ++buff_el) { free(temp_array[buff_el]); } free(temp_array); }*/ /*int circ_buf_serialize(cbuf_handle_t cbuf, char **serialized) { char *temp = (char*) malloc(circ_buf_element_size(cbuf) * sizeof(char)); const char separator[2] = "\r"; uint8_t char_sum = circ_buf_size(cbuf) - 1; uint8_t i; for (i = 0; i < circ_buf_size(cbuf); ++i) { circ_buf_read(cbuf, i, temp); char_sum += strlen(temp); } (*serialized) = (char*) malloc((char_sum + 1) * sizeof(char)); strcpy((*serialized), ""); for (i = 0; i < circ_buf_size(cbuf) - 1; ++i) { circ_buf_read(cbuf, i, temp); strcat((*serialized), temp); strcat((*serialized), separator); } circ_buf_read(cbuf, i, temp); strcat((*serialized), temp); free(temp); return strlen((*serialized)); } int circ_buf_deserialize(cbuf_handle_t cbuf, const char *serialized) { char *str = calloc(strlen(serialized) + 1, sizeof(char)); strcpy(str, serialized); const char separator[2] = "\r"; char *token; token = strtok(str, separator); while (token != NULL) { circ_buf_put(cbuf, token); token = strtok(NULL, separator); } return circ_buf_size(cbuf); }*/