环形缓冲区的实现
作者:互联网
环形缓冲区
//缓存区大小
#define PM_BUF_SIZE 1024
//获取当前缓冲区的数据个数
#define circ_cnt(head, tail, size) (((head) > (tail)) ? \
((head) - (tail)) : \
((head) - (tail)) & ((size) - 1))
//计算缓冲区的可写大小
#define circ_space(head, tail, size) circ_cnt((tail), ((head) + 1), (size))
//把指针n移动1个位置
#define circ_inc(n, s) (((n) + 1) % (s))
//把指针n移动v个位置
#define circ_add(n, v, s) (((n) + (v)) % (s))
//返回小的数
#define min(a, b) \
({ \
typeof(a) __a = (a); \
typeof(b) __b = (b); \
__a < __b ? __a : __b; \
})
int GetData(char* buff, int pwr, int &prd, char *bufret, int size)
{
int pr = prd, i = 0;
char *tmpx= bufret;
char ch = '\0';
int bitflag = 0;
int cnt = 0;
*bufret = 0;
while (circ_cnt(pwr, pr, PM_BUF_SIZE) > 0) {
ch = buff[pr];
//pr指针指向下一个位置
pr = circ_inc(pr, PM_BUF_SIZE); // 读指针超出环形缓冲区末尾,会返回头部
switch(ch)
{
//假设S为数据头
case 'S':
bitflag = 1;
bufret[i++] = ch;
break;
//假设E为数据尾
case 'E':
if ((bitflag & 0x1) == 0x1) {
bitflag |= 0x2;
bufret[i++] = ch;
}
break;
//只有当接收到数据头时,将有效数据写入bufert中
default:
if (bitflag & 0x1) {
bufret[i++] = ch;
}
break;
}
if (i >= size)
break;
if (bitflag & 0x3) {
break;
}
}
if ((bitflag & 0x3) == 0x3) {
//进入这里就表示接收到了一段有效的数据
prd = pr;
bufret[i++] = 0;
return 1;
} else {
return 0;
}
}
void RingBufferLoop()
{
int pw = 0; //写指针
int pr = 0; //读指针
char p_buf[PM_BUF_SIZE];
int ret;
char temp[128] = {0};
while(1) {
// * min(circ_space(pw, pr, PM_BUF_SIZE), (PM_BUF_SIZE - pw))的
// * 作用就是计算出缓冲区可写的大小。
ret = read(fd, &p_buf[pw], min(circ_space(pw, pr, PM_BUF_SIZE), (PM_BUF_SIZE - pw)));
if(ret > 0)
{
//接收到了数据
//把pw指向最后一个字符
pw = circ_add(pw, ret, PM_BUF_SIZE);
//在结尾添加\0
p_buf[circ_inc(pw, PM_BUF_SIZE)] = '\0';
}
//检查缓冲区中是否有数据,如果有就处理
while (circ_cnt(pw, pr, PM_BUF_SIZE) > 0)
{
//将有效数据段放入temp中
ret = GetData(p_buf, pw, pr, temp, sizeof(temp));
if(!ret)
break; //当前没有有效数据段
processbuf(temp); //处理有效数据temp
}
}
}
标签:pr,pw,实现,环形,circ,缓冲区,SIZE,BUF,PM 来源: https://www.cnblogs.com/r1chie/p/15630296.html