//CircleBuf.h #ifndef _CIRCLE_BUF_H #define _CIRCLE_BUF_H #pragma once class CCircleBuf { public: CCircleBuf(void); public: ~CCircleBuf(void); /* 环形缓冲区的两种实现方式 */ /* 通过增加一个标志来判断头尾值相等时,缓冲区是否满 */ bool WriteData(const unsigned char* buf, int size); bool ReadData(unsigned char* buf, int size = READSIZE); /* 通过在缓冲区中保留一元素的空间,当尾的下一个位置和头值相当时即缓冲区满 */ bool WriteDataEx(const unsigned char* buf, int size); bool ReadDataEx(unsigned char* buf, int size = READSIZE); private: static int BUFSIZE; static int READSIZE; unsigned char* m_pucBuf; int m_iHead; int m_iTail; bool m_bFull; }; #endif //CircleBuf.cpp #include "CircleBuf.h" #include <new> #include <iostream> CCircleBuf::CCircleBuf(void):m_bFull(false), m_iHead(0), m_iTail(0), m_pucBuf(NULL) { try { m_pucBuf = new unsigned char[BUFSIZE]; } catch(std::bad_alloc& e) { std::cout << e.what() << std::endl; } } CCircleBuf::~CCircleBuf(void) { delete[] m_pucBuf; m_pucBuf = NULL; m_iHead = 0; m_iTail = 0; m_bFull = false; } int CCircleBuf::BUFSIZE = 188 * 1024 * 128 + 1; int CCircleBuf::READSIZE = 188 * 256; bool CCircleBuf::WriteData(const unsigned char* buf, int size) { if (m_bFull) { return false; } else { int iAvail = 0; int iAvailTail = 0; if (m_iHead <= m_iTail) { iAvail = BUFSIZE - (m_iTail - m_iHead); if (iAvail < size) { return false; } else { iAvailTail = BUFSIZE - m_iTail; if (iAvailTail < size) { memcpy(m_pucBuf + m_iTail, buf, iAvailTail); memcpy(m_pucBuf, buf + iAvailTail, size - iAvailTail); m_iTail = size - iAvailTail; } else { memcpy(m_pucBuf + m_iTail, buf, size); m_iTail += size; if (m_iTail == BUFSIZE) { m_iTail = 0; } } } } else { iAvail = m_iHead - m_iTail; if (iAvail < size) { return false; } else { memcpy(m_pucBuf + m_iTail, buf, size); m_iTail += size; } } if (m_iTail == m_iHead) { m_bFull = true; } return true; } } bool CCircleBuf::ReadData(unsigned char* buf, int size) { if (m_iHead == m_iTail && !m_bFull) { return false; } else { int iAvail = 0; int iAvailTail = 0; if (m_iHead < m_iTail) { iAvail = m_iTail - m_iHead; if (iAvail < size) { return false; } else { memcpy(buf, m_pucBuf + m_iHead, size); m_iHead += size; } } else { iAvail = BUFSIZE - (m_iHead - m_iTail); if (iAvail < size) { return false; } else { iAvailTail = BUFSIZE - m_iHead; if (iAvailTail < size) { memcpy(buf, m_pucBuf + m_iHead, iAvailTail); memcpy(buf + iAvailTail, m_pucBuf, size - iAvailTail); m_iHead = size - iAvailTail; } else { memcpy(buf, m_pucBuf + m_iHead, size); m_iHead += size; if (m_iHead == BUFSIZE) { m_iHead = 0; } } } } if (m_iHead == m_iTail) { m_bFull = false; } return true; } } bool CCircleBuf::WriteDataEx(const unsigned char* buf, int size) { int iNext = (1 + m_iTail) % BUFSIZE; if (m_iHead == iNext) { return false; } else { int iAvail = 0; int iAvailTail = 0; iAvail = BUFSIZE - 1 - ((m_iTail - m_iHead + BUFSIZE) % BUFSIZE); if (iAvail < size) { return false; } else { if (m_iHead <= m_iTail) { iAvailTail = BUFSIZE - m_iTail; if (iAvailTail < size) { memcpy(m_pucBuf + m_iTail, buf, iAvailTail); memcpy(m_pucBuf, buf + iAvailTail, size - iAvailTail); m_iTail = size - iAvailTail; } else { memcpy(m_pucBuf + m_iTail, buf, size); m_iTail += size; } } else { memcpy(m_pucBuf + m_iTail, buf, size); m_iTail += size; } return true; } } } bool CCircleBuf::ReadDataEx(unsigned char* buf, int size) { if (m_iHead == m_iTail) { return false; } else { int iAvail = 0; int iAvailTail = 0; iAvail = (m_iTail - m_iHead + BUFSIZE) % BUFSIZE; if (iAvail < size) { return false; } else { if (m_iHead < m_iTail) { memcpy(buf, m_pucBuf + m_iHead, size); m_iHead += size; } else { iAvailTail = BUFSIZE - m_iHead; if (iAvailTail < size) { memcpy(buf, m_pucBuf + m_iHead, iAvailTail); memcpy(buf + iAvailTail, m_pucBuf, size - iAvailTail); m_iHead = size - iAvailTail; } else { memcpy(buf, m_pucBuf + m_iHead, size); m_iHead += size; } } return true; } } }