码迷,mamicode.com
首页 > 其他好文 > 详细

环形缓冲区(CirBuf)

时间:2014-11-22 16:04:09      阅读:271      评论:0      收藏:0      [点我收藏+]

标签:style   blog   io   ar   sp   数据   on   2014   log   

cirbuf.h

#ifndef _Cirbuf_h
#define _Cirbuf_h
#include <pthread.h>
#define size_t int
struct Cirbuf
{
	unsigned char *mp_buf;
	size_t m_buf_size;
	size_t m_write, m_read;
	pthread_mutex_t mut_cirbuf;
};
typedef struct Cirbuf mCirbuf;
struct Cirbuf *util_cbuf_create (size_t size);

void util_cbuf_release (struct Cirbuf *buf);
size_t util_cbuf_space (struct Cirbuf *buf);
size_t util_cbuf_data (struct Cirbuf *buf);
size_t util_cbuf_contiguous_data (struct Cirbuf *buf);
void *util_cbuf_get_contiguous_data (struct Cirbuf *buf);
size_t util_cbuf_get_cdata (struct Cirbuf *buf, void **data);
void util_cbuf_save (struct Cirbuf *buf, const void *data, size_t len);

void util_cbuf_consume (struct Cirbuf *buf, size_t cnt);
void popdata (struct Cirbuf *cbuf, void *buf, size_t len);
#endif
</span>


cirbuf.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cirbuf.h"
#define CNT_DATA(write, read, size) (((write)-(read)) & ((size)-1))
#define CNT_SPACE(write, read, size) CNT_DATA((read), ((write)+1), (size))
//已有数据
static size_t DATA_TO_END(size_t write, size_t read, size_t size)
{
	size_t end = size - read;
	size_t n = (write + end) & (size - 1);
	return n < end ? n : end;
}
//剩余空间
static size_t SPACE_TO_END(size_t write, size_t read, size_t size)
{
	size_t end = size - 1 - write;
	size_t n = (read + end) & (size - 1);
	return n <= end ? n : end+1;
}
struct Cirbuf *util_cbuf_create (size_t size)
{
	struct Cirbuf *buf = (struct Cirbuf*)malloc(sizeof(struct Cirbuf));
	buf->mp_buf = (unsigned char*)malloc(size);
	buf->m_buf_size = size;
	buf->m_read = 0;
	buf->m_write = 0;
	pthread_mutex_init(&buf->mut_cirbuf,NULL);
	return (struct Cirbuf*)buf;
}

void util_cbuf_release (struct Cirbuf *buf)
{
	struct Cirbuf *b = (struct Cirbuf*)buf;
	free(b->mp_buf);
	free(b);
}

size_t util_cbuf_space (struct Cirbuf *buf)
{
	struct Cirbuf *b = (struct Cirbuf*)buf;
	return CNT_SPACE(b->m_write, b->m_read, b->m_buf_size);
}

size_t util_cbuf_data (struct Cirbuf *buf)
{
	struct Cirbuf *b = (struct Cirbuf*)buf;
	return CNT_DATA(b->m_write, b->m_read, b->m_buf_size);
}

size_t util_cbuf_contiguous_data (struct Cirbuf *buf)
{
	struct Cirbuf *b = (struct Cirbuf *)buf;
	return DATA_TO_END(b->m_write, b->m_read, b->m_buf_size);
}

void *util_cbuf_get_contiguous_data (struct Cirbuf *buf)
{
	struct Cirbuf *b = (struct Cirbuf*)buf;
	return b->mp_buf + b->m_read;
}

size_t util_cbuf_get_cdata (struct Cirbuf *buf, void **data)
{
	struct Cirbuf *b = (struct Cirbuf*)buf;
	*data = b->mp_buf + b->m_read;
	return DATA_TO_END(b->m_write, b->m_read, b->m_buf_size);
}

void util_cbuf_save (struct Cirbuf *buf, const void *data, size_t len)
{
	struct Cirbuf *b = (struct Cirbuf*)buf;
	size_t c;
	if(len > util_cbuf_space(buf))
	{
		printf("ERROR util_cbuf_save\n");
	}
	c = SPACE_TO_END(b->m_write, b->m_read, b->m_buf_size);
	if (c >= len) {
		memcpy(b->mp_buf+b->m_write, data, len);
	}
	else {
		unsigned char *src = (unsigned char*)data+c;
		memcpy(b->mp_buf+b->m_write, data, c);
		memcpy(b->mp_buf, src, (len-c));
	}

	b->m_write += len;
	b->m_write &= (b->m_buf_size-1);
}
//从队首清空cnt个数据
void util_cbuf_consume (struct Cirbuf *buf, size_t cnt)
{
	struct Cirbuf *b = (struct Cirbuf*)buf;
	if(cnt > util_cbuf_data(buf))
	{
		printf("ERROR util_cbuf_consume\n");
	}
	b->m_read += cnt;
	b->m_read &= (b->m_buf_size-1);
}

// 从 cbuf 中提取数据
void popdata (struct Cirbuf *cbuf, void *buf, size_t len)
{
	if(util_cbuf_data(cbuf) < len)
	{
		printf("ERROR popdata %d < %d\n",util_cbuf_data(cbuf),len);
	}
	void *pdata;
	size_t csize = util_cbuf_get_cdata(cbuf, &pdata);
	if (csize >= len) {
		memcpy(buf, pdata, len);
		util_cbuf_consume(cbuf, len);
	}
	else 
	{
		memcpy(buf, pdata, csize);
		util_cbuf_consume(cbuf, csize);
		buf = (unsigned char*)buf + csize;
		len -= csize;
		csize = util_cbuf_get_cdata(cbuf, &pdata);
		memcpy(buf, pdata, len);
		util_cbuf_consume(cbuf, len);
	}
}



环形缓冲区(CirBuf)

标签:style   blog   io   ar   sp   数据   on   2014   log   

原文地址:http://blog.csdn.net/u012377333/article/details/41382069

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!