缓冲管理是个重要而且麻烦的问题,频繁的new绝对不是好事,现在不是提倡节约型社会嘛,咱们也来节约一下,好了废话少说。这个缓冲是个循环缓冲的封装,就是循环利用已有的缓冲区,当然前提是你得申请的足够大。
感谢朋友们的支持,由于这个类是从我的以前的工程中移植过来的,所以很多实现不符合标准,见谅,但我会努力完善的,谢谢你们的支持。拷贝和赋值已经禁止,异常处理已经加上,另外对于hpho的话我不是很理解,其实这个类正如其名,是循环缓冲类,大概用途就是在数据不完整,或者在多线程处理缓冲中使用的,比如一个线程产生数据,不断加入到这个缓冲区,另一个线程不断取得数据,目的就是提供一个临时存放的缓冲,而不用频繁new新的缓冲。由于这个类是循环的,所以外部直接利用缓冲内存指针,只会让外部使用比较麻烦。另外对于不在构造中使用new是我的一个理解,因为如果在构造中new出异常,这个对象是不会析构的。大家的支持是我的动力!
/////////////////////////////////////////////H//////////////////////////////////////////////////////////////////////
#ifndef LGLIB_LOOPBUFFER_H
#define LGLIB_LOOPBUFFER_H
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "lg_MultiEvent.h"
namespace lglib
{
//循环缓冲类 这个类利用循环放置数据的方法节省了一些系统开销
//注意这是个线性缓冲,如果用于多线程需要进行一些处理
//time: 2006-4-26
class __LGLIB__ lg_LoopBuffer
{
public:
lg_LoopBuffer(); //默认构造
virtual ~lg_LoopBuffer();
void InitBuffer(uint32 dwOriginSize);
void ResetBuffer();
//写入数据
int32 WriteBuffer(uint8* buf,uint32 len);
//读出数据
int32 GetBuffer(uint8* buf,uint32 len);
//取得缓冲区剩余数据大小
uint32 GetCountNeedProcess();
private:
//禁止构造或者其他赋值操作比较操作,还是不定义实现比较好,安全第一 : )
lg_LoopBuffer(const lg_LoopBuffer& ); //禁止拷贝构造
lg_LoopBuffer& operator= (const lg_LoopBuffer& ); //禁止赋值
bool operator= =(const lg_LoopBuffer& ); //禁止比较
//.....................
inline uint32 GetPosition(uint64 pos);
private:
uint8 * m_pLoopBuffer;
uint64 m_dwWritePos;
uint64 m_dwReadPos;
uint32 m_dwMaxBuffersize;
};
}
#endif
//////////////////////////////////////////////CPP////////////////////////////////////////////////////
#include "stdafx.h"
#include "lg_LoopBuffer.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
namespace lglib
{
lg_LoopBuffer::lg_LoopBuffer()
: m_pLoopBuffer(NULL) , m_dwWritePos(0) ,
m_dwReadPos(0) , m_dwMaxBuffersize(0)
{
}
lg_LoopBuffer::~lg_LoopBuffer()
{
if(m_pLoopBuffer){
delete [] m_pLoopBuffer;
m_pLoopBuffer = NULL;
}
}
//初始化数据
void lg_LoopBuffer::InitBuffer(uint32 dwOriginSize)
{
//其实单线程这里可以删掉缓冲,再重新初始化,但由于担心在多线程会出问题所以没有这么做
if(NULL != m_pLoopBuffer){
throw lg_Exception("lg_LoopBuffer::InitBuffer","缓冲区已经存在",2);
}
m_dwMaxBuffersize = dwOriginSize;
m_pLoopBuffer = new uint8[m_dwMaxBuffersize];
}
//重置缓冲区,然后可以再利用
void lg_LoopBuffer::ResetBuffer()
{
if(NULL == m_pLoopBuffer)
throw lg_Exception("lg_LoopBuffer::ResetBuffer","缓冲区没有初始化",3);
m_dwWritePos = 0;
m_dwReadPos = 0;
}
//取得当前的位置,由于这个函数是private所以就不加异常处理了
inline uint32 lg_LoopBuffer::GetPosition(uint64 pos)
{
return static_cast<uint32>(pos%m_dwMaxBuffersize);
}
//写入数据
int lg_LoopBuffer::WriteBuffer(uint8* buf,uint32 len)
{
if(NULL == m_pLoopBuffer)
throw lg_Exception("lg_LoopBuffer::WriteBuffer","缓冲区没有初始化",4);
//检测输入有效性
if(len>0&&len<=m_dwMaxBuffersize){
if(((m_dwMaxBuffersize + m_dwReadPos) >= (m_dwWritePos + len))
||(m_dwWritePos == 0&&m_dwReadPos == 0)){
uint32 pos = GetPosition(m_dwWritePos);
uint32 distance = m_dwMaxBuffersize - pos;
if(distance >= len){
memcpy(&m_pLoopBuffer[pos],buf,len);
}else{
memcpy(&m_pLoopBuffer[pos],buf,distance);
memcpy(m_pLoopBuffer,&buf[distance],len-distance);
}
m_dwWritePos+=len;
return len;
}
}
return -1;
}
//读出数据
int32 lg_LoopBuffer::GetBuffer(uint8* buf,uint32 len)
{
if(NULL == m_pLoopBuffer)
throw lg_Exception("lg_LoopBuffer::GetBuffer","缓冲区没有初始化",5);
if(m_dwWritePos < (m_dwReadPos + len)) return 0;
uint32 pos = GetPosition(m_dwReadPos);
uint32 distance = m_dwMaxBuffersize - pos;
if(distance >= len){
memcpy(buf,&m_pLoopBuffer[pos],len);
}else{
memcpy(buf,&m_pLoopBuffer[pos],distance);
memcpy(&buf[distance],m_pLoopBuffer,len-distance);
}
m_dwReadPos += len;
return len;
}
//取得缓冲区剩余数据大小
uint32 lg_LoopBuffer::GetCountNeedProcess()
{
if(NULL == m_pLoopBuffer)
throw lg_Exception("lg_LoopBuffer::GetCountNeedProcess","缓冲区没有初始化",6);
return static_cast<uint32>(m_dwWritePos - m_dwReadPos);
}
}