环行缓冲区的实现(V0.2,C++源码)

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