环行缓冲区实现(V0.3) C++源码

  1. //---------------------------------------------------------------------------
  2. // 模块:          环形缓冲区类 TFengRingBuf
  3. // 版本号:        V0.3
  4. // 编写人:        Twicave(twicave@yahoo.com.cn)
  5. //
  6. // 简要说明:      实现了环形缓冲区(频繁的读取写入操作时,无需进行缓冲区的重整)
  7. //                主要用于通讯类的操作.代码用C++ template编写,可直接以源代码
  8. //                的方式包含进工程中使用.BC6.0测试通过.不含BC Local代码,可用
  9. //                于其他编译环境.
  10. //
  11. // !警告!:     (对象数组的初始化)如果以数组的方式使用本类,那么缺省的尺
  12. //                寸是0。请特别注意。改变尺寸,请使用Resize()函数。
  13. // 备注:
  14. //    Aug06,2008  V0.3
  15. //                添加一条警告信息(关于对象数组的初始化),并完善缺省、拷贝
  16. //                构造函数、赋值函数和相等、不等验证函数。
  17. //
  18. //    Aug05,2008  V0.21
  19. //                初步完成。支持接近手工编码的方案。需要解释一下"只读"的概念.
  20. //                在尝试对环形缓冲区进行写入操作时,因为Context中的函数均是对
  21. //                标准缓冲区进行操作的.此时涉及缓冲区的转换操作.这里采用的方案
  22. //                是先用WriteBuf()取出一个缓冲区,这个缓冲区可能就位于原始缓冲
  23. //                区内,也可能是因为接近边界处而生成的一个临时缓冲区.因为此时
  24. //                可能已经对环形缓冲区的内容进行写入操作(在相当高的概率下),所
  25. //                以后续的写入操作必须延迟(写入操作涉及Resize和Push).对于缓冲
  26. //                区的察看,有类似的情形.一旦用户通过ReadBuf()注册了对缓冲区的
  27. //                察看操作,则后续的对读指针的修改也必须挂起.否则可能导致正在读
  28. //                取的内容被后续写入操作污染.
  29. //                目前尚需要改进的地方有循环概念的实现.(目前一旦缓冲区满就不再
  30. //                接受最新的输入了.)不过环形缓冲区 != 循环缓冲区.对不对?
  31. //                Bug修正:    Reset()时CommitRead&WriteBuf.
  32. //
  33. //    Aug04,2008  V0.2
  34. //                发现最重要的工作是如何替换标准的缓冲区。性能必须要接近标准缓
  35. //                冲区,否则就失去意义了。
  36. //
  37. //    Aug02,2008  开始编码
  38. //---------------------------------------------------------------------------
  39. #ifndef FengRingBufH
  40. #define FengRingBufH
  41. #include <ctype.h> //for size_t定义
  42. #include <assert.h> //for assert()
  43. //---------------------------------------------------------------------------
  44. template<class TYPE = unsigned char>
  45. class TFengRingBuf
  46. {
  47. public:
  48.    //构造函数
  49.                            TFengRingBuf(size_t size = 0);
  50.    //析构函数
  51.    virtual                 ~TFengRingBuf(void);
  52.    //拷贝构造函数
  53.                            TFengRingBuf(const TFengRingBuf<TYPE>& rhs);
  54.    //赋值函数
  55.    TFengRingBuf<TYPE>&     operator=(const TFengRingBuf<TYPE>& rhs);
  56.    //取容量
  57.    inline size_t           Size(voidconst;
  58.    //取长度
  59.    size_t                  Len(voidconst;
  60.    //取元素
  61.    TYPE                    operator[](size_t pos);
  62.    //归零
  63.    inline void             Reset(void);
  64.    //重设缓冲区尺寸
  65.    void                    Resize(size_t size);
  66.    //导入数据
  67.    size_t                  Push(TYPE *buf, size_t len);
  68.    //导入数据,用于缓冲区之间转移 (buf=>本地,buf相关指针不变)
  69.    size_t                  Push(const TFengRingBuf<TYPE>& buf, size_t len);
  70.    //缓冲区转换(用户负责对返回的数组析构)
  71.    TYPE*                   Get(size_t& len) const;
  72.    //读取数据
  73.    size_t                  Get(TYPE *buf, size_t len) const;
  74.    //取出数据(用户负责对返回的数组析构)
  75.    TYPE*                   Pop(size_t& len);
  76.    //取出数据
  77.    size_t                  Pop(TYPE *buf, size_t len);
  78.    //导出数据,用于缓冲区之间转移 (本地=>buf,本地相关指针改变)
  79.    size_t                  Pop(TFengRingBuf<TYPE>& buf, size_t& len);
  80.    //导出写入缓冲区(本操作执行以后无法对缓冲区进行写入操作)
  81.    TYPE*                   WriteBuf(size_t size = 0);
  82.    //写入缓冲区尺寸
  83.    inline size_t           SizeOfWriteBuf(void);
  84.    //写入缓冲区长度
  85.    inline size_t&          LenOfWriteBuf(void);
  86.    //导出的写入缓冲区提交(提交后恢复对缓冲区进行写入操作响应)
  87.    size_t                  CommitWriteBuf(size_t len);
  88.    //导出读取缓冲区(本操作执行以后不可对读指针进行移动,实际的缓冲区尺寸可能不足size,请查询SizeOfReadBuf())
  89.    TYPE*                   ReadBuf(size_t size = 0);
  90.    //读取缓冲区尺寸
  91.    inline size_t           SizeOfReadBuf(void);
  92.    //读取缓冲区位置指针
  93.    inline size_t&          PosOfReadBuf(void);
  94.    //导出的读取缓冲区提交(提交后恢复对对读指针移动的响应)
  95.    size_t                  CommitReadBuf(size_t len);
  96. private:
  97.    TYPE                    *_buf;            //缓冲区指针
  98.    size_t                  _pRead;           //读指针
  99.    size_t                  _pWrite;          //写指针
  100.    size_t                  _size;            //尺寸
  101.    TYPE                    *_writeBuf;       //写入缓冲区首地址
  102.    size_t                  _sizeWriteBuf;    //写入缓冲区尺寸
  103.    size_t                  _lenWriteBuf;     //写入缓冲区位置指针
  104.    bool                    _isWriteBufTemp;  //写入缓冲区是否为临时缓冲区
  105.    TYPE                    *_readBuf;        //读取缓冲区首地址
  106.    size_t                  _sizeReadBuf;     //读取缓冲区尺寸
  107.    size_t                  _posReadBuf;      //读取缓冲区读取指针
  108.    bool                    _isReadBufTemp;   //读取缓冲区是否为临时缓冲区
  109. };
  110. template<class TYPE>
  111. TFengRingBuf<TYPE>::TFengRingBuf(size_t size)
  112. {
  113.    _pRead = _pWrite = 0;
  114.    _buf = new TYPE[size + 1];
  115.    assert(NULL != _buf);
  116.    _size = size;
  117.    _writeBuf = NULL;
  118.    _sizeWriteBuf = 0;
  119.    _lenWriteBuf = 0;
  120.    _isWriteBufTemp = false;
  121.    _readBuf = NULL;
  122.    _sizeReadBuf = 0;
  123.    _posReadBuf = 0;
  124.    _isReadBufTemp = false;
  125. }
  126. template<class TYPE>
  127. TFengRingBuf<TYPE>::~TFengRingBuf(void)
  128. {
  129.    if(0 != SizeOfWriteBuf()) CommitWriteBuf(0); //writeBuf只读处理
  130.    if(0 != SizeOfReadBuf()) CommitReadBuf(0); //readBuf只读处理
  131.    delete[] _buf;
  132. }
  133. template<class TYPE>
  134. TFengRingBuf<TYPE>::TFengRingBuf(const TFengRingBuf<TYPE>& rhs)
  135. {
  136.    _pRead = _pWrite = 0;
  137.    _buf = new TYPE[rhs.Size() + 1];
  138.    assert(NULL != _buf);
  139.    _size = rhs.Size();
  140.    _writeBuf = NULL;
  141.    _sizeWriteBuf = 0;
  142.    _lenWriteBuf = 0;
  143.    _isWriteBufTemp = false;
  144.    _readBuf = NULL;
  145.    _sizeReadBuf = 0;
  146.    _posReadBuf = 0;
  147.    _isReadBufTemp = false;
  148.    Push(rhs, rhs.Len());
  149. }
  150. template<class TYPE>
  151. TFengRingBuf<TYPE>& TFengRingBuf<TYPE>::operator=(const TFengRingBuf<TYPE>& rhs)
  152. {
  153.    Reset();
  154.    Push(rhs, rhs.Len());
  155.    return *this;
  156. }
  157. template<class TYPE>
  158. size_t TFengRingBuf<TYPE>::Size(voidconst
  159. {
  160.    return _size;
  161. }
  162. template<class TYPE>
  163. size_t TFengRingBuf<TYPE>::Len(voidconst
  164. {
  165.    return ((_pWrite+Size()+1) - _pRead) % (Size()+1);
  166. }
  167. template<class TYPE>
  168. TYPE TFengRingBuf<TYPE>::operator[](size_t pos)
  169. {
  170.    return _buf[(_pRead+pos)%(Size()+1)];
  171. }
  172. template<class TYPE>
  173. void TFengRingBuf<TYPE>::Reset(void)
  174. {
  175.    if(0 != SizeOfWriteBuf()) CommitWriteBuf(0); //writeBuf只读处理
  176.    if(0 != SizeOfReadBuf()) CommitReadBuf(0); //readBuf只读处理
  177.    _pRead = _pWrite = 0;
  178. }
  179. template<class TYPE>
  180. void TFengRingBuf<TYPE>::Resize(size_t size)
  181. {
  182.    if(0 != SizeOfWriteBuf()) return//writeBuf只读处理
  183.    //取出所有数据,并删除原始数组
  184.    size_t len;
  185.    TYPE *buf = Get(len);
  186.    delete[] _buf;
  187.    Reset();
  188.    _buf = new TYPE[size + 1];
  189.    _size = size;
  190.    assert(NULL != _buf);
  191.    Push(buf, len);
  192.    delete[] buf;
  193. }
  194. template<class TYPE>
  195. size_t TFengRingBuf<TYPE>::Push(TYPE *buf, size_t len)
  196. {
  197.    if(0 != SizeOfWriteBuf()) return 0; //writeBuf只读处理
  198.    //传入数据溢出处理(仅移入尾部)
  199.    if(len > Size() - Len())
  200.    {
  201.       size_t oldLen = len;
  202.       len = Size() - Len();
  203.       buf += oldLen - len;
  204.    }
  205.    if(0 == len) return 0;
  206.    //尝试分两步拷贝
  207.    size_t tryMove = (0 == _pRead) ?
  208.                         Size()+1-_pWrite-1 : Size()+1-_pWrite;
  209.    if( tryMove >= len)
  210.    {
  211.       memcpy(&_buf[_pWrite], buf, sizeof(TYPE)*len);
  212.    }
  213.    else
  214.    {
  215.       memcpy(&_buf[_pWrite], buf, sizeof(TYPE)*tryMove);
  216.       memcpy(&_buf[0], &buf[tryMove], sizeof(TYPE)*(len - tryMove));
  217.    }
  218.    //指针移动
  219.    _pWrite += len;
  220.    _pWrite %= Size() + 1;
  221.    return len;
  222. }
  223. template<class TYPE>
  224. size_t TFengRingBuf<TYPE>::Push(const TFengRingBuf<TYPE>& buf, size_t len)
  225. {
  226.    if(0 != SizeOfWriteBuf()) return 0; //writeBuf只读处理
  227.    size_t ret, tempLen;
  228.    tempLen = len > buf.Len() ? buf.Len() : len;
  229.    TYPE *tempBuf = new TYPE[tempLen];
  230.    tempLen = buf.Get(tempBuf, tempLen);
  231.    ret = Push(tempBuf, tempLen);
  232.    delete[] tempBuf;
  233.    return ret;
  234. }
  235. template<class TYPE>
  236. TYPE * TFengRingBuf<TYPE>::Get(size_t& len) const
  237. {
  238.    TYPE *buf(NULL);
  239.    len = Len();
  240.    if(0 != len)
  241.    {
  242.       buf = new TYPE[Len()];
  243.       Get(buf, Len());
  244.    }
  245.    return buf;
  246. }
  247. template<class TYPE>
  248. size_t TFengRingBuf<TYPE>::Get(TYPE *buf, size_t len) const
  249. {
  250.    //传入参数合法化
  251.    if(len > Len())
  252.    {
  253.       len = Len();
  254.    }
  255.    //尝试分两步拷贝
  256.    size_t tryMove = (_pWrite > _pRead) ?
  257.       _pWrite - _pRead : (Size()+1 - _pRead);
  258.    if(len <= tryMove)
  259.    {
  260.       memcpy(buf, &_buf[_pRead], len);
  261.    }
  262.    else
  263.    {
  264.       memcpy(&buf[0], &_buf[_pRead], tryMove);
  265.       memcpy(&buf[tryMove], &_buf[0], len-tryMove);
  266.    }
  267.    return len;
  268. }
  269. template<class TYPE>
  270. size_t TFengRingBuf<TYPE>::Pop(TYPE *buf, size_t len)
  271. {
  272.    if(0 != SizeOfReadBuf()) return 0; //readBuf只读处理
  273.    len = Get(buf, len);
  274.    _pRead += len;
  275.    _pRead %= Size() + 1;
  276.    return len;
  277. }
  278. template<class TYPE>
  279. TYPE * TFengRingBuf<TYPE>::Pop(size_t& len)
  280. {
  281.    len = 0;
  282.    if(0 != SizeOfReadBuf()) return NULL; //readBuf只读处理
  283.    TYPE *buf = Get(len);
  284.    _pRead += len;
  285.    _pRead %= Size() + 1;
  286.    return buf;
  287. }
  288. template<class TYPE>
  289. size_t TFengRingBuf<TYPE>::Pop(TFengRingBuf<TYPE>& buf, size_t& len)
  290. {
  291.    if(0 != SizeOfReadBuf()) return 0; //readBuf只读处理
  292.    if(len > this->Len())
  293.    {
  294.       len = this->Len();
  295.    }
  296.    size_t ret = buf.Push(*this, len);
  297.    _pRead += len;
  298.    _pRead %= Size() + 1;
  299.    return ret;
  300. }
  301. template<class TYPE>
  302. TYPE* TFengRingBuf<TYPE>::WriteBuf(size_t size)
  303. {
  304.    if(0 == size) return _writeBuf;
  305.    if(0 != _sizeWriteBuf && 0 != size) return NULL; //writeBuf仅可取出一次,不支持多重导出
  306.    _sizeWriteBuf = size;
  307.    _lenWriteBuf = 0;
  308.    if(Size()+1 - _pWrite >= size)
  309.    {
  310.       _writeBuf = &_buf[_pWrite];
  311.       _isWriteBufTemp = false;
  312.    }
  313.    else
  314.    {
  315.       _writeBuf = new TYPE[size];
  316.       assert(NULL != _writeBuf);
  317.       _isWriteBufTemp = true;
  318.    }
  319.    return _writeBuf;
  320. }
  321. template<class TYPE>
  322. size_t TFengRingBuf<TYPE>::SizeOfWriteBuf(void)
  323. {
  324.    return _sizeWriteBuf;
  325. }
  326. template<class TYPE>
  327. size_t& TFengRingBuf<TYPE>::LenOfWriteBuf(void)
  328. {
  329.    return _lenWriteBuf;
  330. }
  331. template<class TYPE>
  332. size_t TFengRingBuf<TYPE>::CommitWriteBuf(size_t len)
  333. {
  334.    if(0 == _sizeWriteBuf) return 0;
  335.    if(len > _sizeWriteBuf) len = _sizeWriteBuf; //防止越界访问
  336.    TYPE *pOuterBuf = _writeBuf;
  337.    _writeBuf = NULL;
  338.    _sizeWriteBuf = 0; //首先脱离outerBuf状态,否则无法写入
  339.    if(_isWriteBufTemp)
  340.    {
  341.       len = Push(pOuterBuf, len);
  342.       delete[] pOuterBuf;
  343.       _isWriteBufTemp = false;
  344.    }
  345.    else
  346.    {
  347.       _pWrite += len; //无需处理指针回环
  348.    }
  349.    _lenWriteBuf = 0;
  350.    return len;
  351. }
  352. template<class TYPE>
  353. TYPE* TFengRingBuf<TYPE>::ReadBuf(size_t size)
  354. {
  355.    if(size > Len()) size = Len(); //防止越界访问
  356.    if(0 == size) return _readBuf; //注意与上条语句的顺序
  357.    if(0 != _sizeReadBuf && 0 != size) return NULL; //ReadBuf仅可取出一次,不支持多重导出
  358.    if(Size()+1 - _pRead >= size)
  359.    {
  360.       _readBuf = &_buf[_pRead];
  361.       _isReadBufTemp = false;
  362.    }
  363.    else
  364.    {
  365.       _readBuf = new TYPE[size];
  366.       assert(NULL != _readBuf);
  367.       Get(_readBuf, size);
  368.       _isReadBufTemp = true;
  369.    }
  370.    _sizeReadBuf = size;
  371.    _posReadBuf = 0;
  372.    return _readBuf;
  373. }
  374. template<class TYPE>
  375. size_t TFengRingBuf<TYPE>::SizeOfReadBuf(void)
  376. {
  377.    return _sizeReadBuf;
  378. }
  379. template<class TYPE>
  380. size_t& TFengRingBuf<TYPE>::PosOfReadBuf(void)
  381. {
  382.    return _posReadBuf;
  383. }
  384. template<class TYPE>
  385. size_t TFengRingBuf<TYPE>::CommitReadBuf(size_t len)
  386. {
  387.    if(len > Len()) len = Len(); //防止越界访问
  388.    _pRead += len;
  389.    _pRead %= Size() + 1;
  390.    if(0 == _sizeReadBuf) return 0; //对于普通的读指针移动已经执行完毕
  391.    if(_isReadBufTemp)
  392.    {
  393.       delete[] _readBuf;
  394.       _isReadBufTemp = false;
  395.    }
  396.    _posReadBuf = 0;
  397.    _sizeReadBuf = 0;
  398.    _readBuf = NULL;
  399.    return len;
  400. }
  401. //---------------------------------------------------------------------------
  402. //相等函数(仅判断尺寸是否一致)
  403. template<class TYPE>
  404. bool operator==(const TFengRingBuf<TYPE>& lhs, const TFengRingBuf<TYPE>& rhs)
  405. {
  406.    return lhs.Size() == rhs.Size();
  407. }
  408. //不等函数(仅判断尺寸是否一致)
  409. template<class TYPE>
  410. bool operator!=(const TFengRingBuf<TYPE>& lhs, const TFengRingBuf<TYPE>& rhs)
  411. {
  412.    return !(lhs == rhs);
  413. }
  414. #endif
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

子正

thanks, bro...

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

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

打赏作者

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

抵扣说明:

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

余额充值