环形缓冲区的c实现

//头文件
#ifndef __XBUF_H__
#define __XBUF_H__

#define XBUFDEFAULTSIZE  (1024*1024)    //缓冲区默认大小

        typedef unsigned int uint32;

        //!创建一个环形缓冲区 size为缓冲区大小
		void *x_buf_create(uint32 size);

		//!获取缓冲区已有数据量的大小
		uint32 x_buf_data_size(void *handle);

		//!获取缓冲区空闲空间的大小
		uint32 x_buf_empty_size(void *handle);

		//!缓冲区是否是满的 0:否  1:是
		uint32 x_buf_is_full(void *handle);

		//!缓冲区是否是空的 0:否  1:是
		uint32 x_buf_is_empty(void *handle);

		//!将buf中的数据写入缓冲区 返回实际写入的数据量大小
		uint32 x_buf_write(void *handle,char *buf,uint32 size);

		//!读取缓冲区的数据 返回实际读取的数据量大小
		uint32 x_buf_read(void *handle,char *buf,uint32 size);

		//!将buf中的数据全部写入缓冲区中 返回实际写入的大小 返回值为0或者size
		uint32 x_buf_write_block(void *handle,char *buf,uint32 size);


#endif //__XBUF_H__




#include "x_buf.h"
#include <malloc.h>
#include <assert.h>
#include <string.h>

//环形缓冲区的结构体信息
typedef struct XBUFINFO
{
	char *buf;        //缓冲区
	uint32 bufSize;   //缓冲区大小
	uint32 head;      //缓冲区数据开始的位置  即读取数据位置
	uint32 tail;      //缓冲区数据结束的位置  即写入数据位置
	uint32 full;      //缓冲区是否是满的 0:否  1:是
	XBUFINFO()
	{
		buf     = 0;
		bufSize = 0;
		head    = 0;
		tail    = 0;
		full    = 0;
	}
}x_buf_info;

//!创建一个环形缓冲区 size为缓冲区大小
void *x_buf_create(uint32 size)
{
	size = size<=0?XBUFDEFAULTSIZE:size;
	x_buf_info *pBuf = (x_buf_info *)malloc(sizeof(x_buf_info) + size);
	if (!pBuf)
	{
		return 0;
	}
	pBuf->buf     = (char *)(pBuf+1);
	//size即缓冲区的初始化大小<=0的话 用默认的值进行初始化
	memset(pBuf->buf,0,size);
	pBuf->bufSize = size;
	pBuf->full    = 0;
	pBuf->head    = 0;
	pBuf->tail    = 0;
	return (void *)pBuf;
}

//!获取缓冲区已有数据量的大小
uint32 x_buf_data_size(void *handle)
{
	//!保证handle不为空
	assert(handle);

	x_buf_info *pBuf = (x_buf_info *)handle;
	if(x_buf_is_full(handle))
	{
		return pBuf->bufSize;
	}
	assert(pBuf->bufSize);

	return (pBuf->tail - pBuf->head + pBuf->bufSize)%pBuf->bufSize;
}

//!获取缓冲区空闲空间的大小
uint32 x_buf_empty_size(void *handle)
{
	assert(handle);
	x_buf_info *pBuf = (x_buf_info *)handle;
	//!缓冲区大小减去已有数据量大小
	return pBuf->bufSize - x_buf_data_size(handle);
}

//!缓冲区是否是满的 0:否  1:是
uint32 x_buf_is_full(void *handle)
{
	assert(handle);
	x_buf_info *pBuf = (x_buf_info *)handle;
	return pBuf->full;
}

//!缓冲区是否是空的 0:否  1:是
uint32 x_buf_is_empty(void *handle)
{
	assert(handle);
	int ret = x_buf_is_full(handle);
	if(!ret)
	{
		x_buf_info *pBuf = (x_buf_info *)handle;
		return pBuf->head == pBuf->tail;
	}
	return 0;
}

//!将buf中的数据写入缓冲区 返回实际写入的数据量大小
uint32 x_buf_write(void *handle,char *buf,uint32 size)
{
	assert(handle);

	uint32 emptySize = x_buf_empty_size(handle);
	//!实际上能写入缓冲区的数据大小
    size = emptySize>=size?size:emptySize;
	if(size<=0)
	{
		return 0;
	}
	x_buf_info *pBuf = (x_buf_info *)handle;
	/*
	    模型:
	     0        tail            head            bufSize - 1 
	     |  data    |    empty     |    data      |

	*/
	if (pBuf->head > pBuf->tail)
	{
		memcpy(pBuf->buf + pBuf->tail,buf,size);
	} 
	/*
	    模型:
	     0         head          tail              bufSize - 1 
	     |  empty    |    data     |    empty      |

	*/
	else
	{
			uint32 datasize = pBuf->bufSize - pBuf->tail;
			datasize = datasize>size?size:datasize;
			memcpy(pBuf->buf + pBuf->tail,buf,datasize);
			if(datasize<size)
			{
				memcpy(pBuf->buf ,buf + datasize,size - datasize);
			}

	}
	assert(pBuf->bufSize);
	pBuf->tail = (pBuf->tail+size+pBuf->bufSize)%pBuf->bufSize;
	if(pBuf->head == pBuf->tail)
	{
		pBuf->full = 1;
	}
	return size; 
}

//!读取缓冲区的数据 返回实际读取的数据量大小
uint32 x_buf_read(void *handle,char *buf,uint32 size)
{
	assert(handle);

	uint32 datasize = x_buf_data_size(handle);
	//!实际上能读出的数据大小
	size = datasize>=size?size:datasize;
	if(size<=0)
	{
		return 0;
	}
	x_buf_info *pBuf = (x_buf_info *)handle;
	/*
	    模型
	     0         head           tail             bufSize - 1 
	     |  empty    |    data     |    empty      |

	*/
	if(pBuf->tail>pBuf->head)
	{
		memcpy(buf,pBuf->buf + pBuf->head,datasize);
	}
	/*
	    模型
	     0        tail            head            bufSize - 1 
	     |  data    |    empty     |    data      |
	*/
	else
	{
		uint32 datasize = pBuf->bufSize - pBuf->head;
		datasize = datasize>size?size:datasize;
		memcpy(buf,pBuf->buf + pBuf->head,datasize);
		if(datasize<size)
		{
			memcpy(buf+datasize,pBuf,size-datasize);
		}
	}
	assert(pBuf->bufSize);
	pBuf->head=(pBuf->head+size+pBuf->bufSize)%pBuf->bufSize;
	pBuf->full = 0;
	return size;
}

//!将buf中的数据全部写入缓冲区中 返回实际写入的大小 返回值为0或者size
uint32 x_buf_write_block(void *handle,char *buf,uint32 size)
{
	assert(handle);
	uint32 bufsize = x_buf_empty_size(handle);
	//!如果空闲空间小于将要写入的buf大小 直接返回0
	if (bufsize<size)
	{
		return 0;
	}
	return x_buf_write(handle,buf,size);
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值