環形buffer C語言簡單實現

#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中數組總的長度來更新,讀寫指針的指向。

程序中有註釋。

此程序沒有釋放動態申請的內存,所以執行一次就會有一次的內存泄漏,所以需要使用者自己寫一個釋放分配內存的函數,這個比較簡單,我就不貼在這裏了。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章