#include #include "circle_buffer.h" static int circle_get_write_space(c_buffer_t *cbuff); static int circle_get_read_space(c_buffer_t *cbuff); void circle_buffer_init(c_buffer_t *cbuff, uint8_t *buffer, int16_t max_len){ cbuff->buffer = buffer; cbuff->buffer_len = max_len; circle_reset(cbuff); } void circle_reset(c_buffer_t *cbuff){ cbuff->r_pos = cbuff->w_pos = 0; } int circle_put_data(c_buffer_t *cbuff, uint8_t *data, int16_t len){ int16_t size = circle_get_write_space(cbuff); int16_t w_len = len; int16_t w1_len = len; if (size < 0){ return size; } w_len = min(len, size); while(w_len > 0){ //wrapper if (cbuff->w_pos + w_len > cbuff->buffer_len){ w1_len = cbuff->buffer_len - cbuff->w_pos; }else{ w1_len = w_len; } memcpy(cbuff->buffer + cbuff->w_pos, data, w1_len); cbuff->w_pos = (cbuff->w_pos + w1_len); if (cbuff->w_pos == cbuff->buffer_len){ cbuff->w_pos = 0; } w_len -= w1_len; data += w1_len; } return min(len, size); } int circle_put_one_data(c_buffer_t *cbuff, uint8_t data){ int16_t size = circle_get_write_space(cbuff); if (size < 0){ return size; } cbuff->buffer[cbuff->w_pos] = data; cbuff->w_pos = cbuff->w_pos + 1; if (cbuff->w_pos == cbuff->buffer_len){ cbuff->w_pos = 0; } return 1; } int circle_get_data(c_buffer_t *cbuff, uint8_t *data, int16_t len){ int16_t size = circle_get_read_space(cbuff); int16_t r_len = len; int16_t r1_len = 0; if (size <= 0){ return size; } r_len = min(size, len); while(r_len > 0){ if (cbuff->r_pos + r_len > cbuff->buffer_len){ r1_len = cbuff->buffer_len - cbuff->r_pos; }else{ r1_len = r_len; } memcpy(data, cbuff->buffer + cbuff->r_pos, r1_len); cbuff->r_pos = (cbuff->r_pos + r1_len); if (cbuff->r_pos == cbuff->buffer_len){ cbuff->r_pos = 0; } r_len -= r1_len; data += r1_len; } return min(size, len); } int circle_get_one_data(c_buffer_t *cbuff, uint8_t *data){ int16_t size = circle_get_read_space(cbuff); if (size <= 0){ return size; } *data = cbuff->buffer[cbuff->r_pos]; cbuff->r_pos = cbuff->r_pos + 1; if (cbuff->r_pos == cbuff->buffer_len){ cbuff->r_pos = 0; } return 1; } #if 0 static __inline__ int circle_get_write_space(c_buffer_t *cbuff){ int16_t size = (cbuff->w_pos >= cbuff->r_pos)?(cbuff->buffer_len - cbuff->w_pos + cbuff->r_pos):(cbuff->r_pos - cbuff->w_pos); size -= 1; if (size <= 0){ return CBUFF_FULL; } return size; } #endif static __inline__ int circle_get_read_space(c_buffer_t *cbuff){ int16_t size = (cbuff->r_pos > cbuff->w_pos) ? (cbuff->buffer_len - cbuff->r_pos + cbuff->w_pos) : (cbuff->w_pos - cbuff->r_pos); if (size <= 0){ return CBUFF_EMPTY; } return size; }