数据读取/写入——线型缓存区

      数据的读取和写入管理,可以通过列表和环型列表来实现,文本使用线性列表来实现数据的读取和写入操作。本文是C++的实现。

 

      环型缓存区C代码实现,有一个C的liblcthw开源库。liblcthw的网址为https://github.com/zedshaw/liblcthw,用C代码实现了一些常用的数据结构,list,map,tree,字符串函数,ring buffer等。boost库里也有环形缓冲区的实现类circular_buffer

      内存池类代码:

/*
描述: 内存池类
说明:
	本类只支持同等大小的内存块
	应当在所有Alloc的内存都Free以后再析构对象
*/

#ifndef _MemoryPool_h_
#define _MemoryPool_h_

#include <windows.h>
#include <LIST>
#define BLOCK_SIZE				1024
#define ONCE_BLOCK_COUNT		10

class MemoryPool
{
public:
	MemoryPool(ULONG uBlockSize=BLOCK_SIZE);
	virtual ~MemoryPool();

public:
	//释放,用于代替析构,如果调用了它,不要调用析构,内存将在ReleaseMem时释放
	void Release();
	void* Alloc();
	void Free(void* p);

public:
	//初始化
	static void Init();
	//释放内存,程序结束时调用
	static void ReleaseMem();

private:
	ULONG						m_uBlockSize;
	std::list<void*>			m_listFree;
	CRITICAL_SECTION			m_cs;
	ULONG						m_uBlockCnt;
	ULONG						m_uFreeCnt;

private:
	static std::list<MemoryPool*>	g_listPool;
	static CRITICAL_SECTION				g_cs;
};

#endif

#include "stdafx.h"
#include "MemoryPool.h"

std::list<MemoryPool*>	MemoryPool::g_listPool;
CRITICAL_SECTION		MemoryPool::g_cs;

MemoryPool::MemoryPool(ULONG uBlockSize)
{
	m_uFreeCnt=0;
	m_uBlockCnt=0;
	m_uBlockSize=uBlockSize;
	::InitializeCriticalSection(&m_cs);
}

MemoryPool::~MemoryPool()
{
	BYTE* p;
	::EnterCriticalSection(&m_cs);
	std::list<void*>::iterator iter=m_listFree.begin();
	std::list<void*>::iterator iterEnd=m_listFree.end();
	while(iter!=iterEnd)
	{
		p=(BYTE*)(*iter);
		iter++;
		delete[] p;
	}
	m_listFree.clear();
	::LeaveCriticalSection(&m_cs);
	::DeleteCriticalSection(&m_cs);
}

//释放,用于代替析构,如果调用了它,不要调用析构,内存将在ReleaseMem时释放
void MemoryPool::Release()
{
	//加入g_listPool
	::EnterCriticalSection(&g_cs);
	g_listPool.push_back(this);
	::LeaveCriticalSection(&g_cs);
}

void* MemoryPool::Alloc()
{
	void* p=NULL;
	::EnterCriticalSection(&m_cs);
	std::list<void*>::iterator iter=m_listFree.begin();
	if(iter!=m_listFree.end())
	{
		p=*iter;
		m_listFree.erase(iter);
	}
	if(p)
	{
		m_uFreeCnt--;
		::LeaveCriticalSection(&m_cs);
		return p;
	}

	//一次增加十个
	BYTE* ap[ONCE_BLOCK_COUNT] = {0};
	UINT i = 0;
	for(i=0;i<ONCE_BLOCK_COUNT;i++)
	{
		ap[i]=new BYTE[m_uBlockSize];
	}
	for(i=1;i<ONCE_BLOCK_COUNT;i++)
	{
		m_listFree.push_back(ap[i]);
	}
	p=ap[0];
	m_uBlockCnt+=ONCE_BLOCK_COUNT;
	m_uFreeCnt+=(ONCE_BLOCK_COUNT-1);
	::LeaveCriticalSection(&m_cs);
	return p;
}

void MemoryPool::Free(void* p)
{
	::EnterCriticalSection(&m_cs);
	m_listFree.push_back(p);
	m_uFreeCnt++;
	::LeaveCriticalSection(&m_cs);
}

	//初始化
void MemoryPool::Init()
{
	::InitializeCriticalSection(&g_cs);
}

//释放内存,程序结束时调用
void MemoryPool::ReleaseMem()
{
	MemoryPool* pThis;
	::EnterCriticalSection(&g_cs);
	std::list<MemoryPool*>::iterator iter=g_listPool.begin();
	std::list<MemoryPool*>::iterator iterEnd=g_listPool.end();
	while(iter!=iterEnd)
	{
		pThis=*iter;
		iter++;
		delete pThis;
	}
	g_listPool.clear();
	::LeaveCriticalSection(&g_cs);
	::DeleteCriticalSection(&g_cs);
}

      线性缓存区代码:

//内存管理,线性缓存区操作类 

#pragma once

#define  BUFFER_MAX_SIZE		128*1024		//128K

class MemoryPool;
class CLineBuffer
{
public:
	CLineBuffer(void);
	virtual ~CLineBuffer(void);

public:
	//-------------------------------------------------------------
	// 功能:初始化
	// 参数:缓冲区长度
	// 返回:TRUE 成功,FALSE 失败
	//-------------------------------------------------------------
	BOOL	Initialize(int	nBufferLen,MemoryPool* pPool);
	//-------------------------------------------------------------
	// 功能:反初始化
	// 参数:无
	// 返回:无
	//-------------------------------------------------------------
	void	Uninitialize(); 

	//功能:复位
	void	Clear();

	//功能:增加数据
	int		AddData(char *pBuffer,int nLen);
	//功能:增加数据(返回增加数据的指针)
	int		AddData(char *pBuffer,int nLen,char **pNewBuffer);

	//功能:删除数据
	int		DeleteData(int nLen,int nStartPos=-1);

	//功能:读取数据(提前预读取)
	int		PrepareReadData(char **pBuffer,int nLen);

	//功能:读取数据
	int		ReadData(char **pBuffer,int nLen);

	//功能:获取空间总大小
	int     GetSpaceTotalLength();

	//功能:获取剩余空间大小
	int		GetRemainSpaceLength();
	//功能:获取剩余写空间大小(左边)
	int		GetLeftRemainSpaceLength();
	//功能:获取剩余写空间大小(右边)
	int		GetRightRemainSpaceLength();

	//功能:获取实际数据大小
	int		GetActualDataLength();

	//功能:获取读位置
	int		GetReadPos();

	//功能:设置读位置
	void	SetReadPos(int nNewReadPos);

	//功能:获取写位置
	int		GetWritePos();

	//功能:压缩数据
	int		CompactData();

private:
	MemoryPool*			m_pMemPool;			//内存池对象
	char				*m_pBufferData;		//缓冲区数据
	int					m_nBufferDataLen;	//缓冲区大小
	int                 m_nBufferReadPos;	//读位置
	int                 m_nBufferWritePos;	//写位置
	int                 m_nBufferEmptySize;	//剩余大小
	//临界池保护
	CRITICAL_SECTION	m_critial;
};

#include "StdAfx.h"
#include "LineBuffer.h"
#include <windows.h>
#include "MemoryPool.h"

CLineBuffer::CLineBuffer(void)
{
	m_pMemPool = NULL;
	m_pBufferData = NULL;
	m_nBufferDataLen = 0;
	m_nBufferReadPos = 0;
	m_nBufferWritePos = 0;
	m_nBufferEmptySize = 0;
	InitializeCriticalSection(&m_critial);
}

CLineBuffer::~CLineBuffer(void)
{
	if(m_pBufferData != NULL)
	{
		delete []m_pBufferData;
		m_pBufferData = NULL;
	}

	DeleteCriticalSection(&m_critial);
}

//-------------------------------------------------------------
// 功能:初始化
// 参数:缓冲区长度
// 返回:TRUE 成功,FALSE 失败
//-------------------------------------------------------------
BOOL	CLineBuffer::Initialize(int	nBufferLen,MemoryPool* pPool)
{
	if(m_nBufferDataLen>0 || nBufferLen<=0)
		return FALSE;
	m_pMemPool = pPool;
	if(m_pMemPool)
	{
		m_pBufferData=(char*)m_pMemPool->Alloc();
	}
	else
	{
		m_pBufferData=new char[nBufferLen];
	}
	m_nBufferDataLen = nBufferLen;
	m_nBufferEmptySize = m_nBufferDataLen;

	return TRUE;
}

//-------------------------------------------------------------
// 功能:反初始化
// 参数:无
// 返回:无
//-------------------------------------------------------------
void	CLineBuffer::Uninitialize()
{
	if(m_pBufferData)
	{
		if(m_pMemPool)
			m_pMemPool->Free(m_pBufferData);
		else
			delete[] m_pBufferData;
		m_pBufferData = NULL;
	}
	m_nBufferDataLen = 0;
	m_nBufferEmptySize = 0;
}

//功能:复位
void	CLineBuffer::Clear()
{
	EnterCriticalSection(&m_critial);
	m_nBufferReadPos = 0;
	m_nBufferWritePos = 0;
	m_nBufferEmptySize = m_nBufferDataLen;
	LeaveCriticalSection(&m_critial); 
}

/*
功能:增加数据
参数:pBuffer,表示数据;nLen,表示数据长度
返回值:int类型 0,表示正确;1,表示参数错误;2,表示数据太大
*/
int		CLineBuffer::AddData(char *pBuffer,int nLen)
{
	EnterCriticalSection(&m_critial);
	//参数错误
	if(m_pBufferData == NULL)
	{
		LeaveCriticalSection(&m_critial); 
		return 1;
	}
	if((m_nBufferWritePos%m_nBufferDataLen  - m_nBufferReadPos) == 0)
	{
		m_nBufferReadPos = m_nBufferWritePos  = 0;
		m_nBufferEmptySize = m_nBufferDataLen;
	}
	//数据太大
	if((m_nBufferDataLen - m_nBufferWritePos) <= nLen)
	{
		LeaveCriticalSection(&m_critial); 
		return 2;//超过已有缓冲区大小
	}

	memcpy(m_pBufferData+m_nBufferWritePos,pBuffer,nLen);
	m_nBufferWritePos +=nLen;
	m_nBufferEmptySize = m_nBufferDataLen - (m_nBufferWritePos - m_nBufferReadPos);
	LeaveCriticalSection(&m_critial); 
	return 0;
}
//功能:增加数据(返回增加数据的指针)
int		CLineBuffer::AddData(char *pBuffer,int nLen,char **pNewBuffer)
{
	EnterCriticalSection(&m_critial);
	//参数错误
	if(m_pBufferData == NULL)
	{
		LeaveCriticalSection(&m_critial); 
		return 1;
	}
	if((m_nBufferWritePos%m_nBufferDataLen  - m_nBufferReadPos) == 0)
	{
		m_nBufferReadPos = m_nBufferWritePos  = 0;
		m_nBufferEmptySize = m_nBufferDataLen;
	}
	//数据太大
	if((m_nBufferDataLen - m_nBufferWritePos) <= nLen)
	{
		LeaveCriticalSection(&m_critial); 
		return 2;//超过已有缓冲区大小
	}

	memcpy(m_pBufferData+m_nBufferWritePos,pBuffer,nLen);
	*pNewBuffer = m_pBufferData+m_nBufferWritePos;				//设置新数据位置
	m_nBufferWritePos +=nLen;
	m_nBufferEmptySize = m_nBufferDataLen - (m_nBufferWritePos - m_nBufferReadPos);
	LeaveCriticalSection(&m_critial); 
	return 0;
}

/*
功能:删除数据
参数:nLen,表示需要删除数据的长度;nStartPos,表示开始位置(-1,表示从当前读位置开始)
返回值:int类型 0,表示成功;-1,表示要删除的数据超过了已有数据;-2,表示参数错误
*/
int		CLineBuffer::DeleteData(int nLen,int nStartPos)
{
	EnterCriticalSection(&m_critial);
	if((nStartPos < 0 && nStartPos !=-1) || nLen <= 0)
	{
		//参数错误
		LeaveCriticalSection(&m_critial);
return -2;
	}
	int nStartPosTmp = nStartPos;
	if(-1 == nStartPos)
	{
		nStartPosTmp = m_nBufferReadPos;
	}

	if((nStartPosTmp + nLen) > m_nBufferWritePos)
	{
		//要删除的数据超过了已有数据
LeaveCriticalSection(&m_critial);
		return -1;
	}

	m_nBufferReadPos = nStartPosTmp + nLen;
	m_nBufferEmptySize = m_nBufferDataLen - (m_nBufferWritePos - m_nBufferReadPos);
	LeaveCriticalSection(&m_critial); 

	return 0;
}

//功能:读取数据(提前读取)
int		CLineBuffer::PrepareReadData(char **pBuffer,int nLen)
{
	int nActualReadSize = 0;
	EnterCriticalSection(&m_critial);
	int nDataLength = m_nBufferWritePos - m_nBufferReadPos;
	if(nDataLength > 0)
	{
		if(nDataLength >= nLen)
		{
			*pBuffer = m_pBufferData+m_nBufferReadPos;
			nActualReadSize = nLen;
		}
		else
		{
			*pBuffer = m_pBufferData+m_nBufferReadPos;
			nActualReadSize = nDataLength;
		}
	}
	LeaveCriticalSection(&m_critial);

	return nActualReadSize;
}

//功能:读取数据
int		CLineBuffer::ReadData(char **pBuffer,int nLen)
{
	int nActualReadSize = 0;
	EnterCriticalSection(&m_critial);
	int nDataLength = m_nBufferWritePos - m_nBufferReadPos;
	if(nDataLength > 0)
	{
		if(nDataLength >= nLen)
		{
			*pBuffer = m_pBufferData+m_nBufferReadPos;
			nActualReadSize = nLen;
			m_nBufferReadPos = m_nBufferReadPos + nLen;
		}
		else
		{
			*pBuffer = m_pBufferData+m_nBufferReadPos+nDataLength;
			nActualReadSize = nDataLength;
			m_nBufferReadPos = m_nBufferReadPos + nDataLength;
		}
		m_nBufferEmptySize = m_nBufferDataLen - (m_nBufferWritePos - m_nBufferReadPos);
	}
	if(m_nBufferWritePos  == m_nBufferReadPos)
	{			
		m_nBufferReadPos = m_nBufferWritePos  = 0;
		m_nBufferEmptySize = m_nBufferDataLen;
	}
	LeaveCriticalSection(&m_critial);

	return nActualReadSize;
}

//功能:压缩数据
int		CLineBuffer::CompactData()
{
	EnterCriticalSection(&m_critial);
	if(m_pBufferData != NULL)
	{
		int nActualSize = m_nBufferWritePos - m_nBufferReadPos;
		for(int i=0;i<nActualSize;i++)
		{
			m_pBufferData[i] = m_pBufferData[i+m_nBufferReadPos];
		}

		m_nBufferReadPos = 0;
		m_nBufferWritePos = nActualSize;
		m_nBufferEmptySize = m_nBufferDataLen - (m_nBufferWritePos - m_nBufferReadPos);
	}
	LeaveCriticalSection(&m_critial); 
	return 0;
}

//功能:获取空间总大小
int    CLineBuffer::GetSpaceTotalLength()
{
	return m_nBufferDataLen;
}

//功能:获取剩余空间大小
int		CLineBuffer::GetRemainSpaceLength()
{
	return m_nBufferEmptySize;
}
//功能:获取剩余写空间大小(左边)
int		CLineBuffer::GetLeftRemainSpaceLength()
{
	return m_nBufferReadPos;
}
//功能:获取剩余写空间大小(右边)
int		CLineBuffer::GetRightRemainSpaceLength()
{
	return m_nBufferDataLen - m_nBufferWritePos;
}

//功能:获取实际数据大小
int	   CLineBuffer::GetActualDataLength()
{
	int nActualDataLength = 0;
	nActualDataLength = m_nBufferWritePos - m_nBufferReadPos;
	return nActualDataLength;
}

//功能:获取读位置
int		CLineBuffer::GetReadPos()
{
	return m_nBufferReadPos;
}

//功能:设置读位置
void	CLineBuffer::SetReadPos(int nNewReadPos)
{
	m_nBufferReadPos = nNewReadPos;
}

//功能:获取写位置
int		CLineBuffer::GetWritePos()
{
	return m_nBufferWritePos;
}

                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

byxdaz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值