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,
©.m_pRingBuffer[copy.m_popPos],
copy.m_count);
}
else {
::memmove(m_pRingBuffer,
©.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;
};
|