环形buffer C语言简单实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011123091/article/details/82082779
#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中数组总的长度来更新,读写指针的指向。

程序中有注释。

此程序没有释放动态申请的内存,所以执行一次就会有一次的内存泄漏,所以需要使用者自己写一个释放分配内存的函数,这个比较简单,我就不贴在这里了。

猜你喜欢

转载自blog.csdn.net/u011123091/article/details/82082779