关闭

如何实现一个循环缓冲区模型

标签: byteconstructornulldeletebufferclass
1954人阅读 评论(2) 收藏 举报
分类:

下面是一个RingBuffer模型的完整实现,欢迎读者参考和指正:

 

typedef  unsigned char  BYTE;
 template<unsigned int N  /*容量(字节数)*/>
 class RingBuffer {
 public:
    typedef size_t   size_type;
    typedef GenericLocker<CriticalSection>  _BufferLocker;

    RingBuffer() : m_pushPos(0), m_popPos(0), m_count(0) {
        assert(N > 0);
        m_pRingBuffer = new BYTE[N];
    }

    ~RingBuffer() { delete []m_pRingBuffer; }

    RingBuffer(const RingBuffer<N>& copy) : m_popPos(0) {
        assert(N > 0);
        m_pRingBuffer = new BYTE[N];
        size_type rearLen = N - copy.m_popPos;
        if (rearLen >= copy.m_count) {
              ::memmove(m_pRingBuffer,
                                  &copy.m_pRingBuffer[copy.m_popPos],
                                  copy.m_count);
        }
        else {
              ::memmove(m_pRingBuffer,
                                  &copy.m_pRingBuffer[copy.m_popPos],
                                  rearLen);
              ::memmove(m_pRingBuffer + rearLen,
                                  copy.m_pRingBuffer,

                                  copy.m_count - rearLen);
        }
        m_pushPos = m_count = copy.m_count;
    }

    RingBuffer& operator=(const RingBuffer<N>& other) {
        if (this != &other) {
              _BufferLocker guard(m_mutex);
              RingBuffer<N> temp(other);        // invoke copy constructor
              _Swap(temp);                      // this->_Swap();
        }
        return (*this);
    }

    bool is_full() const {
        _BufferLocker guard(m_mutex);
        return (m_count == N);
    }

    bool is_empty() const {
        _BufferLocker guard(m_mutex);
        return (m_count == 0);
    }

    size_type size() const {
        _BufferLocker guard(m_mutex);
        return m_count;
    }

    size_type capacity() const { return N; }

    size_type push(const BYTE *data, size_type length) {
        assert(data != NULL);
        _BufferLocker guard(m_mutex);
        if (length == 0 || length > (N - m_count))
            return 0;
        size_type rearLen = N - m_pushPos;    // 尾部剩余空间
        if (length <= rearLen) {
            ::memmove(&m_pRingBuffer[m_pushPos], data, length);
            m_pushPos += length;
            m_pushPos %= N;              // 调整新的push位置
        }else{
            ::memmove(&m_pRingBuffer[m_pushPos], data, rearLen);
            ::memmove(m_pRingBuffer, data + rearLen, length - rearLen);
            m_pushPos = length - rearLen;    // 调整新的push位置
            }
        m_count += length;
        return (length);
    }

    size_type pop(BYTE *buf, size_type length) {
        assert(buf != NULL);
        _BufferLocker guard(m_mutex);
        if (length == 0 || length > m_count)
            return 0;
        size_type rearLen = N - m_popPos;    // 尾部剩余数据
        if (length <= rearLen) {
            ::memmove(buf, &m_pRingBuffer[m_popPos], length);
            m_popPos += length;
            m_popPos %= N;             // 调整新的pop位置
        }else {
            ::memmove(buf, &m_pRingBuffer[m_popPos], rearLen);
            ::memmove(buf + rearLen, m_pRingBuffer, length - rearLen);
            m_popPos = length - rearLen;    // 调整新的pop位置
            }
        m_count -= length;
        return (length);
    }

    void clear() {
        _BufferLocker guard(m_mutex);
        m_pushPos = 0, m_popPos = 0, m_count = 0;
    }

private:
    BYTE                *m_pRingBuffer;     // buffer
    size_type           m_pushPos;          // 新的push位置:pushPos=

                                                            // (popPos+count)% N
    size_type           m_popPos;           // 新的pop位置
    size_type           m_count;              // 有效字节数
    CriticalSection  m_mutex;
};

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:66029次
    • 积分:1089
    • 等级:
    • 排名:千里之外
    • 原创:36篇
    • 转载:0篇
    • 译文:0篇
    • 评论:99条
    文章分类
    最新评论