参考文章
一、ring buffer初始化
// The definition of our circular buffer structure is hidden from the user
struct circular_buf_t {
uint8_t * buffer;
size_t head;
size_t tail;
size_t max; //of the buffer
bool full;
};
//buffer封装(对buffer的有效数据头尾位置记录,有效数据数量记录),返回句柄
cbuf_handle_t circular_buf_init(uint8_t* buffer, size_t size)
{
//检查实参有效性
assert(buffer && size);
//分配一个circular_buf_t类型变量存放封装后的buffer
cbuf_handle_t cbuf = malloc(sizeof(circular_buf_t));
//检查指向封装后buffer的指针的有效性
assert(cbuf);
//封装buffer
cbuf->buffer = buffer;
cbuf->max = size;
circular_buf_reset(cbuf);
assert(circular_buf_empty(cbuf));
return cbuf;
}
void circular_buf_reset(cbuf_handle_t cbuf)
{
assert(cbuf);
cbuf->head = 0;
cbuf->tail = 0;
cbuf->full = false;
}
二、往buffer中加数据
//buffer中增加数据,可覆盖
void circular_buf_put(cbuf_handle_t cbuf, uint8_t data)
{
assert(cbuf && cbuf->buffer);
cbuf->buffer[cbuf->head] = data;
advance_pointer(cbuf);
}
//往buffer中加数据,不可覆盖,抛出异常
int circular_buf_put2(cbuf_handle_t cbuf, uint8_t data)
{
int r = -1;
assert(cbuf && cbuf->buffer);
if(!circular_buf_full(cbuf))
{
cbuf->buffer[cbuf->head] = data;
advance_pointer(cbuf);
r = 0;
}
return r;
}
//前进指针
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;
}
三、从buffer中取数据
//从buffer中取数据
int circular_buf_get(cbuf_handle_t cbuf, uint8_t * data)
{
assert(cbuf && data && cbuf->buffer);
int r = -1;
if(!circular_buf_empty(cbuf))
{
*data = cbuf->buffer[cbuf->tail];
retreat_pointer(cbuf);
r = 0;
}
return r;
}
四、buffer判空判满
bool circular_buf_empty(cbuf_handle_t cbuf)
{
assert(cbuf);
return (!cbuf->full && (cbuf->head == cbuf->tail));
}
bool circular_buf_full(cbuf_handle_t cbuf)
{
assert(cbuf);
return cbuf->full;
}
五、计算buffer有效数据大小
size_t circular_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 circular_buf_capacity(cbuf_handle_t cbuf)
{
assert(cbuf);
return cbuf->max;
}
六、释放buffer
void circular_buf_free(cbuf_handle_t cbuf)
{
assert(cbuf);
free(cbuf);
}