#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct circlebuffer
{
int size;//用于判断环形buffer是否是满的
int wroffset;
int rdoffser;
char * buf;
int buflen;
}circleBuffer;
circleBuffer * cb_init(int bufLen)
{
if(bufLen==0)return NULL;
circleBuffer* cbBuffer=malloc(sizeof(circleBuffer));
memset(cbBuffer,0,sizeof(circleBuffer));
cbBuffer->buflen=bufLen;
cbBuffer->buf=(char *)malloc(bufLen);
memset(cbBuffer->buf,0,bufLen);
return cbBuffer;
}
//返回读的数据的数量
int cb_read(circleBuffer * cb_buffer,char * outbuf,int readLen)
{
int canReadLen=0;
if(outbuf==NULL) return 0;
if(cb_buffer->size==0) return 0;//没有数据可以读
canReadLen=cb_buffer->wroffset-cb_buffer->rdoffser;
if(canReadLen<0) canReadLen+=cb_buffer->buflen;
if(canReadLen<readLen)
{
readLen=canReadLen;//readLen是能读到的数量
}
if(readLen<cb_buffer->buflen-cb_buffer->rdoffser)
{
//说明不用不用折回来读
memcpy(outbuf,&cb_buffer->buf[cb_buffer->rdoffser],readLen);
}else
{
//说明存到最大的地方没存完,需要继续折回来读,第一次读先读到数组的结尾
memcpy(outbuf,&cb_buffer->buf[cb_buffer->rdoffser],cb_buffer->buflen-cb_buffer->rdoffser);
memcpy(&outbuf[cb_buffer->buflen-cb_buffer->rdoffser],cb_buffer->buf,readLen-(cb_buffer->buflen-cb_buffer->rdoffser));
}
//更新下实际的数量大小
cb_buffer->size-=readLen;
//更新读指针
cb_buffer->rdoffser=(readLen+cb_buffer->rdoffser)%cb_buffer->buflen;
return readLen;//返回读到的数据量
}
//返回是否写入成功,如果空间不够就不写入,失败返回0
int cb_write(circleBuffer * cb_buffer,char * inbuf,int wrireLen)
{
int canWriteLen=0;
//老样子,做参数检查
if(cb_buffer==NULL ||inbuf==NULL ||wrireLen==0 )
{
return 0;
}
//检查环形buffer是否是满的
if(cb_buffer->size==cb_buffer->buflen)
{
return 0;
}
//检查剩余的空间是否够写入
canWriteLen=cb_buffer->rdoffser-cb_buffer->wroffset;
if(canWriteLen<=0) canWriteLen+=cb_buffer->buflen;
if(wrireLen>canWriteLen) return -1;//没有足够的空间则不写入
//开始写
if(wrireLen<cb_buffer->buflen-cb_buffer->wroffset)
{
//不用折行,直接写入
memcpy(&cb_buffer->buf[cb_buffer->wroffset],inbuf,wrireLen);
}else
{
//一行写完以后,需要重新折过来,从开头在写入 wrireLen-(cb_buffer->buflen-cb_buffer->wroffset)
memcpy(&cb_buffer->buf[cb_buffer->wroffset],inbuf,cb_buffer->buflen-cb_buffer->wroffset);
memcpy(cb_buffer->buf,&inbuf[cb_buffer->buflen-cb_buffer->wroffset],wrireLen-(cb_buffer->buflen-cb_buffer->wroffset));
}
//更新写指针
cb_buffer->wroffset=(wrireLen+cb_buffer->wroffset)%cb_buffer->buflen;
//更新size
cb_buffer->size+=wrireLen;
return wrireLen;
}
int main()
{
char writeBuf[15]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
char readBuf[15];
circleBuffer * cb_buffer=NULL;
cb_buffer=cb_init(10);
int a=cb_write(cb_buffer,writeBuf,5);
printf("write length is %d\n",a);
printf("size is %d,buflen is %d,content is %s,writeOffset is %d\n",cb_buffer->size,cb_buffer->buflen,cb_buffer->buf,cb_buffer->wroffset);
a=cb_read(cb_buffer,readBuf,10);
printf("read length is %d\n",a);
printf("size is %d,buflen is %d,content is %s,readOffset is %d\n",cb_buffer->size,cb_buffer->buflen,cb_buffer->buf,cb_buffer->rdoffser);
a=cb_read(cb_buffer,readBuf,10);
printf("read length is %d\n",a);
a=cb_write(cb_buffer,writeBuf,9);
printf("write length is %d\n",a);
printf("size is %d,buflen is %d,content is %s,writeOffset is %d\n",cb_buffer->size,cb_buffer->buflen,cb_buffer->buf,cb_buffer->wroffset);
return 0;
}
实验效果:
整体思路就是利用size来保存环形buffer中有多少个元素,然后利用
canReadLen=cb_buffer->wroffset-cb_buffer->rdoffser;
if(canReadLen<0) canReadLen+=cb_buffer->buflen;来记录能读的长度。如果是写的话就是cb_buffer->rdoffser-cb_buffer->wroffset,思路是一样的。
cb_buffer->rdoffser=(readLen+cb_buffer->rdoffser)%cb_buffer->buflen;
利用读写的长度和之前读写的指针来取余buffer中数组总的长度来更新,读写指针的指向。
程序中有注释。
此程序没有释放动态申请的内存,所以执行一次就会有一次的内存泄漏,所以需要使用者自己写一个释放分配内存的函数,这个比较简单,我就不贴在这里了。