环行缓冲区实现(C++版本)V0.31

//---------------------------------------------------------------------------
// 模块:          环形缓冲区类 TFengRingBuf
// 版本号:        V0.31
// 编写人:        Twicave(twicave@yahoo.com.cn)
//
// 简要说明:      实现了环形缓冲区(频繁的读取写入操作时,无需进行缓冲区的重整)
//                主要用于通讯类的操作.代码用C++ template编写,可直接以源代码
//                的方式包含进工程中使用.BC6.0测试通过.不含BC Local代码,可用
//                于其他编译环境.
//
// !警告!:     (对象数组的初始化)如果以数组的方式使用本类,那么缺省的尺
//                寸是0。请特别注意。改变尺寸,请使用Resize()函数。
// 备注:
//    Aug08,2008  v0.31
//                修改了取出缓冲区内容的一个bug.内部的内存拷贝没有考虑TYPE元
//                素的尺寸。
//
//    Aug06,2008  V0.3
//                添加一条警告信息(关于对象数组的初始化),并完善缺省、拷贝
//                构造函数、赋值函数和相等、不等验证函数。
//
//    Aug05,2008  V0.21
//                初步完成。支持接近手工编码的方案。需要解释一下"只读"的概念.
//                在尝试对环形缓冲区进行写入操作时,因为Context中的函数均是对
//                标准缓冲区进行操作的.此时涉及缓冲区的转换操作.这里采用的方案
//                是先用WriteBuf()取出一个缓冲区,这个缓冲区可能就位于原始缓冲
//                区内,也可能是因为接近边界处而生成的一个临时缓冲区.因为此时
//                可能已经对环形缓冲区的内容进行写入操作(在相当高的概率下),所
//                以后续的写入操作必须延迟(写入操作涉及Resize和Push).对于缓冲
//                区的察看,有类似的情形.一旦用户通过ReadBuf()注册了对缓冲区的
//                察看操作,则后续的对读指针的修改也必须挂起.否则可能导致正在读
//                取的内容被后续写入操作污染.
//                目前尚需要改进的地方有循环概念的实现.(目前一旦缓冲区满就不再
//                接受最新的输入了.)不过环形缓冲区 != 循环缓冲区.对不对?
//                Bug修正:    Reset()时CommitRead&WriteBuf.
//
//    Aug04,2008  V0.2
//                发现最重要的工作是如何替换标准的缓冲区。性能必须要接近标准缓
//                冲区,否则就失去意义了。
//
//    Aug02,2008  开始编码
//---------------------------------------------------------------------------
#ifndef FengRingBufH
#define FengRingBufH
#include <ctype.h> //for size_t定义
#include <assert.h> //for assert()
//---------------------------------------------------------------------------
template<class TYPE = unsigned char>
class TFengRingBuf
{
public:
   //构造函数
                           TFengRingBuf(size_t size = 0);
   //析构函数
   virtual                 ~TFengRingBuf(void);
   //拷贝构造函数
                           TFengRingBuf(const TFengRingBuf<TYPE>& rhs);
   //赋值函数
   TFengRingBuf<TYPE>&     operator=(const TFengRingBuf<TYPE>& rhs);

   //取容量
   inline size_t           Size(void) const;
   //取长度
   size_t                  Len(void) const;
   //取元素
   TYPE                    operator[](size_t pos);
   //归零
   inline void             Reset(void);
   //重设缓冲区尺寸
   void                    Resize(size_t size);

   //导入数据
   size_t                  Push(TYPE *buf, size_t len);
   //导入数据,用于缓冲区之间转移 (buf=>本地,buf相关指针不变)
   size_t                  Push(const TFengRingBuf<TYPE>& buf, size_t len);

   //缓冲区转换(用户负责对返回的数组析构)
   TYPE*                   Get(size_t& len) const;
   //读取数据
   size_t                  Get(TYPE *buf, size_t len) const;

   //取出数据(用户负责对返回的数组析构)
   TYPE*                   Pop(size_t& len);
   //取出数据
   size_t                  Pop(TYPE *buf, size_t len);
   //导出数据,用于缓冲区之间转移 (本地=>buf,本地相关指针改变)
   size_t                  Pop(TFengRingBuf<TYPE>& buf, size_t& len);

   //导出写入缓冲区(本操作执行以后无法对缓冲区进行写入操作)
   TYPE*                   WriteBuf(size_t size = 0);
   //写入缓冲区尺寸
   inline size_t           SizeOfWriteBuf(void);
   //写入缓冲区长度
   inline size_t&          LenOfWriteBuf(void);
   //导出的写入缓冲区提交(提交后恢复对缓冲区进行写入操作响应)
   size_t                  CommitWriteBuf(size_t len);

   //导出读取缓冲区(本操作执行以后不可对读指针进行移动,实际的缓冲区尺寸可能不足size,请查询SizeOfReadBuf())
   TYPE*                   ReadBuf(size_t size = 0);
   //读取缓冲区尺寸
   inline size_t           SizeOfReadBuf(void);
   //读取缓冲区位置指针
   inline size_t&          PosOfReadBuf(void);
   //导出的读取缓冲区提交(提交后恢复对对读指针移动的响应)
   size_t                  CommitReadBuf(size_t len);

private:
   TYPE                    *_buf;            //缓冲区指针
   size_t                  _pRead;           //读指针
   size_t                  _pWrite;          //写指针
   size_t                  _size;            //尺寸

   TYPE                    *_writeBuf;       //写入缓冲区首地址
   size_t                  _sizeWriteBuf;    //写入缓冲区尺寸
   size_t                  _lenWriteBuf;     //写入缓冲区位置指针
   bool                    _isWriteBufTemp;  //写入缓冲区是否为临时缓冲区

   TYPE                    *_readBuf;        //读取缓冲区首地址
   size_t                  _sizeReadBuf;     //读取缓冲区尺寸
   size_t                  _posReadBuf;      //读取缓冲区读取指针
   bool                    _isReadBufTemp;   //读取缓冲区是否为临时缓冲区

};

template<class TYPE>
TFengRingBuf<TYPE>::TFengRingBuf(size_t size)
{
   _pRead = _pWrite = 0;
   _buf = new TYPE[size + 1];
   assert(NULL != _buf);
   _size = size;

   _writeBuf = NULL;
   _sizeWriteBuf = 0;
   _lenWriteBuf = 0;
   _isWriteBufTemp = false;

   _readBuf = NULL;
   _sizeReadBuf = 0;
   _posReadBuf = 0;
   _isReadBufTemp = false;
}

template<class TYPE>
TFengRingBuf<TYPE>::~TFengRingBuf(void)
{
   if(0 != SizeOfWriteBuf()) CommitWriteBuf(0); //writeBuf只读处理
   if(0 != SizeOfReadBuf()) CommitReadBuf(0); //readBuf只读处理
   delete[] _buf;
}

template<class TYPE>
TFengRingBuf<TYPE>::TFengRingBuf(const TFengRingBuf<TYPE>& rhs)
{
   _pRead = _pWrite = 0;
   _buf = new TYPE[rhs.Size() + 1];
   assert(NULL != _buf);
   _size = rhs.Size();

   _writeBuf = NULL;
   _sizeWriteBuf = 0;
   _lenWriteBuf = 0;
   _isWriteBufTemp = false;

   _readBuf = NULL;
   _sizeReadBuf = 0;
   _posReadBuf = 0;
   _isReadBufTemp = false;

   Push(rhs, rhs.Len());
}

template<class TYPE>
TFengRingBuf<TYPE>& TFengRingBuf<TYPE>::operator=(const TFengRingBuf<TYPE>& rhs)
{
   Reset();
   Push(rhs, rhs.Len());
   return *this;
}

template<class TYPE>
size_t TFengRingBuf<TYPE>::Size(void) const
{
   return _size;
}

template<class TYPE>
size_t TFengRingBuf<TYPE>::Len(void) const
{
   return ((_pWrite+Size()+1) - _pRead) % (Size()+1);
}

template<class TYPE>
TYPE TFengRingBuf<TYPE>::operator[](size_t pos)
{
   return _buf[(_pRead+pos)%(Size()+1)];
}

template<class TYPE>
void TFengRingBuf<TYPE>::Reset(void)
{
   if(0 != SizeOfWriteBuf()) CommitWriteBuf(0); //writeBuf只读处理
   if(0 != SizeOfReadBuf()) CommitReadBuf(0); //readBuf只读处理
   _pRead = _pWrite = 0;
}

template<class TYPE>
void TFengRingBuf<TYPE>::Resize(size_t size)
{
   if(0 != SizeOfWriteBuf()) return; //writeBuf只读处理

   //取出所有数据,并删除原始数组
   size_t len;
   TYPE *buf = Get(len);
   delete[] _buf;
   Reset();

   _buf = new TYPE[size + 1];
   _size = size;
   assert(NULL != _buf);
   Push(buf, len);
   delete[] buf;
}


template<class TYPE>
size_t TFengRingBuf<TYPE>::Push(TYPE *buf, size_t len)
{
   if(0 != SizeOfWriteBuf()) return 0; //writeBuf只读处理

   //传入数据溢出处理(仅移入尾部)
   if(len > Size() - Len())
   {
      size_t oldLen = len;
      len = Size() - Len();
      buf += oldLen - len;
   }
   if(0 == len) return 0;

   //尝试分两步拷贝
   size_t tryMove = (0 == _pRead) ?
                        Size()+1-_pWrite-1 : Size()+1-_pWrite;
   if( tryMove >= len)
   {
      memcpy(&_buf[_pWrite], buf, sizeof(TYPE)*len);
   }
   else
   {
      memcpy(&_buf[_pWrite], buf, sizeof(TYPE)*tryMove);
      memcpy(&_buf[0], &buf[tryMove], sizeof(TYPE)*(len - tryMove));
   }

   //指针移动
   _pWrite += len;
   _pWrite %= Size() + 1;

   return len;
}

template<class TYPE>
size_t TFengRingBuf<TYPE>::Push(const TFengRingBuf<TYPE>& buf, size_t len)
{
   if(0 != SizeOfWriteBuf()) return 0; //writeBuf只读处理

   size_t ret, tempLen;
   tempLen = len > buf.Len() ? buf.Len() : len;
   TYPE *tempBuf = new TYPE[tempLen];

   tempLen = buf.Get(tempBuf, tempLen);
   ret = Push(tempBuf, tempLen);
   delete[] tempBuf;
   return ret;
}

template<class TYPE>
TYPE * TFengRingBuf<TYPE>::Get(size_t& len) const
{
   TYPE *buf(NULL);
   len = Len();
   if(0 != len)
   {
      buf = new TYPE[Len()];
      Get(buf, Len());
   }
   return buf;
}

template<class TYPE>
size_t TFengRingBuf<TYPE>::Get(TYPE *buf, size_t len) const
{
   //传入参数合法化
   if(len > Len())
   {
      len = Len();
   }

   //尝试分两步拷贝
   size_t tryMove = (_pWrite > _pRead) ?
      _pWrite - _pRead : (Size()+1 - _pRead);
   if(len <= tryMove)
   {
      memcpy(buf, &_buf[_pRead], len*sizeof(TYPE));
   }
   else
   {
      memcpy(&buf[0], &_buf[_pRead], tryMove*sizeof(TYPE));
      memcpy(&buf[tryMove], &_buf[0], (len-tryMove)*sizeof(TYPE));
   }

   return len;
}

template<class TYPE>
size_t TFengRingBuf<TYPE>::Pop(TYPE *buf, size_t len)
{
   if(0 != SizeOfReadBuf()) return 0; //readBuf只读处理

   len = Get(buf, len);

   _pRead += len;
   _pRead %= Size() + 1;

   return len;
}

template<class TYPE>
TYPE * TFengRingBuf<TYPE>::Pop(size_t& len)
{
   len = 0;
   if(0 != SizeOfReadBuf()) return NULL; //readBuf只读处理

   TYPE *buf = Get(len);

   _pRead += len;
   _pRead %= Size() + 1;

   return buf;
}

template<class TYPE>
size_t TFengRingBuf<TYPE>::Pop(TFengRingBuf<TYPE>& buf, size_t& len)
{
   if(0 != SizeOfReadBuf()) return 0; //readBuf只读处理

   if(len > this->Len())
   {
      len = this->Len();
   }
   size_t ret = buf.Push(*this, len);

   _pRead += len;
   _pRead %= Size() + 1;

   return ret;
}

template<class TYPE>
TYPE* TFengRingBuf<TYPE>::WriteBuf(size_t size)
{
   if(0 == size) return _writeBuf;
   if(0 != _sizeWriteBuf && 0 != size) return NULL; //writeBuf仅可取出一次,不支持多重导出

   _sizeWriteBuf = size;
   _lenWriteBuf = 0;

   if(Size()+1 - _pWrite >= size)
   {
      _writeBuf = &_buf[_pWrite];
      _isWriteBufTemp = false;
   }
   else
   {
      _writeBuf = new TYPE[size];
      assert(NULL != _writeBuf);
      _isWriteBufTemp = true;
   }
   return _writeBuf;
}

template<class TYPE>
size_t TFengRingBuf<TYPE>::SizeOfWriteBuf(void)
{
   return _sizeWriteBuf;
}

template<class TYPE>
size_t& TFengRingBuf<TYPE>::LenOfWriteBuf(void)
{
   return _lenWriteBuf;
}

template<class TYPE>
size_t TFengRingBuf<TYPE>::CommitWriteBuf(size_t len)
{
   if(0 == _sizeWriteBuf) return 0;
   if(len > _sizeWriteBuf) len = _sizeWriteBuf; //防止越界访问

   TYPE *pOuterBuf = _writeBuf;
   _writeBuf = NULL;
   _sizeWriteBuf = 0; //首先脱离outerBuf状态,否则无法写入

   if(_isWriteBufTemp)
   {
      len = Push(pOuterBuf, len);
      delete[] pOuterBuf;
      _isWriteBufTemp = false;
   }
   else
   {
      _pWrite += len; //无需处理指针回环
   }
   _lenWriteBuf = 0;

   return len;
}

template<class TYPE>
TYPE* TFengRingBuf<TYPE>::ReadBuf(size_t size)
{
   if(size > Len()) size = Len(); //防止越界访问
   if(0 == size) return _readBuf; //注意与上条语句的顺序
   if(0 != _sizeReadBuf && 0 != size) return NULL; //ReadBuf仅可取出一次,不支持多重导出

   if(Size()+1 - _pRead >= size)
   {
      _readBuf = &_buf[_pRead];
      _isReadBufTemp = false;
   }
   else
   {
      _readBuf = new TYPE[size];
      assert(NULL != _readBuf);
      Get(_readBuf, size);
      _isReadBufTemp = true;
   }
   _sizeReadBuf = size;
   _posReadBuf = 0;

   return _readBuf;
}

template<class TYPE>
size_t TFengRingBuf<TYPE>::SizeOfReadBuf(void)
{
   return _sizeReadBuf;
}

template<class TYPE>
size_t& TFengRingBuf<TYPE>::PosOfReadBuf(void)
{
   return _posReadBuf;
}

template<class TYPE>
size_t TFengRingBuf<TYPE>::CommitReadBuf(size_t len)
{
   if(len > Len()) len = Len(); //防止越界访问

   _pRead += len;
   _pRead %= Size() + 1;

   if(0 == _sizeReadBuf) return 0; //对于普通的读指针移动已经执行完毕

   if(_isReadBufTemp)
   {
      delete[] _readBuf;
      _isReadBufTemp = false;
   }
   _posReadBuf = 0;
   _sizeReadBuf = 0;
   _readBuf = NULL;

   return len;
}

//---------------------------------------------------------------------------
//相等函数(仅判断尺寸是否一致)
template<class TYPE>
bool operator==(const TFengRingBuf<TYPE>& lhs, const TFengRingBuf<TYPE>& rhs)
{
   return lhs.Size() == rhs.Size();
}

//不等函数(仅判断尺寸是否一致)
template<class TYPE>
bool operator!=(const TFengRingBuf<TYPE>& lhs, const TFengRingBuf<TYPE>& rhs)
{
   return !(lhs == rhs);
}

#endif

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

子正

thanks, bro...

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

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

打赏作者

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

抵扣说明:

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

余额充值