开源链接:https://gitee.com/Genicre_wang/circle-buffer
Overview
这是一个环形缓冲区的函数库,你可以添加到你的项目中,然后使用库中的函数来编写你的代码
1 可以申请任何类型和自定义长度的环形缓冲区,默认最多申请10个缓冲区;
2 写入数据当缓冲区满时,可以选择是否覆盖最早的数据;
3 使用简单,无需配置,只需要包含头文件和源文件即可;
4 对外提供函数少,提供4个函数:分别为初始化环形缓冲区,删除环形缓冲区,保存数据,读取数据
Getting started
1 复制\CircleBuffer下的circle_buffer.c和circle_buffer.h文件到你的项目
2 参考circle_buffer_unittest.c,在你的项目中编写代码
Function description
/* 初始化函数,传入入环形缓冲区的长度, *以及数据大小,返回环形缓冲区描述符 */
int CircleBufferInit(int buffer_num, int data_len)
/* 根据传入描述符删除对应环形缓冲区 */
int CircleBufferExit(int bd)
/* 向环形缓冲区中保存一个数组, *传入描述符,数据地址和是否覆盖参数 */
int SendToCircleBuffer(int bd, void *data, int cover)
/* 从环形缓冲区中取出一个数组, *传入描述符,数据地址 */
int GetFromCircleBuffer(int bd, void *data)
函数源码
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#define CircleBufferNum 10
#ifndef NULL
#define NULL (void*)0
#endif
/* 环形缓冲区
* 最多可以创建CircleBufferNum(10)个确定的BufferType_t类型的环形缓冲区
* 使用过程如下
* 包含源文件和头文件到你的项目
* bd0 = CircleBufferInit(bufferlen,sizeof(data_tpye));
* CircleBufferExit(bd0);
* err = int SendToCircleBuffer(int bd, void* data, int cover);
* err = GetFromCircleBuffer(bd0, &readdata);
*/
struct CirleBuffer_t
{
int BufferDescription; //环形缓冲区描述符
size_t pBuffer; //环形缓冲区数组的地址
int iDataLen; //每个数据的长度
int iBufferNum; //环形缓冲区存放数据的数量
int iRead; //写位置
int iWrite; //读位置
};
/* 存有CirleBuffer_t指针的数组 */
static struct CirleBuffer_t* g_pCircleBuffer[CircleBufferNum] = { NULL };
/* private function */
/* 判断环形缓冲区是否为空 */
static int IsBufferEmpty(int bd)
{
return (g_pCircleBuffer[bd]->iRead == g_pCircleBuffer[bd]->iWrite);
}
/* 判断环形缓冲区是否为满*/
static int IsBufferFull(int bd)
{
return (g_pCircleBuffer[bd]->iRead == ((g_pCircleBuffer[bd]->iWrite + 1) % g_pCircleBuffer[bd]->iBufferNum));
}
/*
* @return 环形缓冲区描述符,无空间返回-1
*/
static int AssignBufferDescription(void)
{
int index = 0;
for (index = 0; index < CircleBufferNum; index++)
{
if (g_pCircleBuffer[index] == NULL)
return index;
}
return -1;
}
/* public function */
int CircleBufferInit(int buffer_num, int data_len)
{
int buffernum;
int BufferDescription = AssignBufferDescription();
if (BufferDescription >= 0)
{
g_pCircleBuffer[BufferDescription] = (struct CirleBuffer_t*)malloc(sizeof(struct CirleBuffer_t)); //每个数组存放一个环形缓冲区结构体的地址
g_pCircleBuffer[BufferDescription]->iBufferNum = buffer_num + 1; //多分配一个空间
g_pCircleBuffer[BufferDescription]->iDataLen = data_len;
buffernum = g_pCircleBuffer[BufferDescription]->iBufferNum * g_pCircleBuffer[BufferDescription]->iDataLen;
g_pCircleBuffer[BufferDescription]->pBuffer = (size_t)malloc(buffernum);
g_pCircleBuffer[BufferDescription]->iRead = 0;
g_pCircleBuffer[BufferDescription]->iWrite = 0;
}
return BufferDescription;
}
int CircleBufferExit(int bd)
{
if (g_pCircleBuffer[bd] == NULL)
{
printf("CircleBufferExit,g_pCircleBuffer[%d] == NULL\n", bd);
return -1;
}
free((void*)g_pCircleBuffer[bd]->pBuffer);
free((void*)g_pCircleBuffer[bd]);
g_pCircleBuffer[bd] = NULL;
return 0;
}
int SendToCircleBuffer(int bd, void* data, int cover)
{
if (g_pCircleBuffer[bd] == NULL)
{
printf("SendToCircleBuffer,g_pCircleBuffer[%d] == NULL\n", bd);
return -1;
}
if (!IsBufferFull(bd))
{
void* pPos = (void*)(g_pCircleBuffer[bd]->pBuffer + (ptrdiff_t)(g_pCircleBuffer[bd]->iWrite * g_pCircleBuffer[bd]->iDataLen));
memcpy(pPos, (void*)data, g_pCircleBuffer[bd]->iDataLen);
g_pCircleBuffer[bd]->iWrite = (g_pCircleBuffer[bd]->iWrite + 1) % g_pCircleBuffer[bd]->iBufferNum;
return 0;
}
else if (cover)
{
void* pPos = (void*)(g_pCircleBuffer[bd]->pBuffer + (ptrdiff_t)(g_pCircleBuffer[bd]->iWrite * g_pCircleBuffer[bd]->iDataLen));
memcpy(pPos, (void*)data, g_pCircleBuffer[bd]->iDataLen);
g_pCircleBuffer[bd]->iWrite = (g_pCircleBuffer[bd]->iWrite + 1) % g_pCircleBuffer[bd]->iBufferNum;
g_pCircleBuffer[bd]->iRead = (g_pCircleBuffer[bd]->iRead + 1) % g_pCircleBuffer[bd]->iBufferNum;
return 0;
}
printf("This circlebuffer[%d] is full\n", bd);
return -1;
}
int GetFromCircleBuffer(int bd, void* data)
{
if (g_pCircleBuffer[bd] == NULL)
{
printf("GetFromCircleBuffer,g_pCircleBuffer[%d] == NULL\n", bd);
return -1;
}
if (!IsBufferEmpty(bd))
{
void* pPos = (void*)(g_pCircleBuffer[bd]->pBuffer + (ptrdiff_t)(g_pCircleBuffer[bd]->iRead * g_pCircleBuffer[bd]->iDataLen));
memcpy((void*)data, pPos, g_pCircleBuffer[bd]->iDataLen);
g_pCircleBuffer[bd]->iRead = (g_pCircleBuffer[bd]->iRead + 1) % g_pCircleBuffer[bd]->iBufferNum;
return 0;
}
printf("This circlebuffer[%d] is empty\n", bd);
return -1;
}