⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 circularbuffer.cpp

📁 循环缓冲区的C++实现
💻 CPP
字号:
#include "circularbufferSSS.h"

/*
// 声明

class CCycleBuffer  
{
public:
	BOOL isFull();
	BOOL isEmpty();
	void Empty();
	int GetLength();
	CCycleBuffer(int size);
	virtual ~CCycleBuffer();
	int Write(char* buf, int count);
	int Read(char* buf, int count);
private:
	BOOL m_bEmpty, m_bFull;
	char * m_pBuf;
	int m_nBufSize;
	int m_nReadPos;
	int m_nWritePos;
};
*/

// 定义

CCycleBuffer::CCycleBuffer(int size)
{
	m_nBufSize = size;
	m_nReadPos = 0;
	m_nWritePos = 0;
	m_pBuf = new char[m_nBufSize];
	m_bEmpty = TRUE;
	m_bFull = FALSE;
}

CCycleBuffer::~CCycleBuffer()
{
	delete[] m_pBuf;
}

/************************************************************************/
/* 向缓冲区写入数据,返回实际写入的字节数                               */
/************************************************************************/
int CCycleBuffer::Write(char* buf, int count)
{
	if(count <= 0) return 0;
	
	m_bEmpty = FALSE;
	
	// 缓冲区已满,不能继续写入
	if(m_bFull) 
	{
		return 0;
	}
	else if(m_nReadPos == m_nWritePos) // 缓冲区为空(全满的情况上面刚已处理)时
	{
  /*                          == 内存模型 ==
             (empty)            m_nReadPos                (empty)                      
  |----------------------------------|-----------------------------------------|
								m_nWritePos									m_nBufSize
  */
		int leftcount = m_nBufSize - m_nWritePos;
		if(leftcount >= count)
		{
			CopyMemory(m_pBuf + m_nWritePos, buf, count);
			m_nWritePos += count;

			if(m_nWritePos == m_nReadPos + m_nBufSize)	// 应该是必须的
					m_nWritePos = m_nReadPos = 0;

			m_bFull = (m_nWritePos == m_nReadPos);	// 

			if( 0 == count)		// 应该是必须的
			{
				m_bFull = FALSE;
				m_bEmpty = TRUE;
			}

			// ASSERT(m_nReadPos <= m_nWritePos);		当且仅当写入字节为0时,m_nReadPos = m_nWritePos
			return count;
		}
		else
		{
			CopyMemory(m_pBuf + m_nWritePos, buf, leftcount);
			m_nWritePos = (m_nReadPos >= count - leftcount) ? count - leftcount : m_nWritePos;
			CopyMemory(m_pBuf, buf + leftcount, m_nWritePos);

			m_bFull = (m_nWritePos == m_nReadPos);

			if( m_nWritePos == m_nBufSize)	// 应该是必须的
			{
				m_bFull = FALSE;
				m_bEmpty = TRUE;
				ASSERT(0 == count);
			}

			ASSERT(m_nReadPos <= m_nBufSize);
			ASSERT(m_nWritePos <= m_nBufSize);
			// ASSERT(m_nWritePos <= m_nReadPos);
			return leftcount + m_nWritePos;
		}
	} 
	else if(m_nReadPos < m_nWritePos) // 有剩余空间可写入
	{
  /*                           == 内存模型 ==
        (empty)                 (data)                     (empty)
  |-------------------|----------------------------|---------------------------|
                m_nReadPos                m_nWritePos       (leftcount)           
  */
  // 剩余缓冲区大小(从写入位置到缓冲区尾)
		int leftcount = m_nBufSize - m_nWritePos;  
		if(leftcount >= count)   // 有足够的剩余空间存放
		{
			CopyMemory(m_pBuf + m_nWritePos, buf, count);
			m_nWritePos += count;
			
			if(m_nWritePos == m_nReadPos + m_nBufSize)	// 应该是必须的
					m_nWritePos = m_nReadPos = 0;

			m_bFull = (m_nReadPos == m_nWritePos);

			ASSERT(m_nReadPos < m_nBufSize);
			ASSERT(m_nWritePos <= m_nBufSize); 
			// ASSERT(m_nReadPos < m_nWritePos);
			return count;
		}
		else	// 剩余空间不足 《 if(leftcount >= count) 》
		{
			// 先填充满剩余空间,再回头找空间存放
			CopyMemory(m_pBuf + m_nWritePos, buf, leftcount);
			/*int*/ m_nWritePos = (m_nReadPos >= count - leftcount) ? count - leftcount : m_nReadPos;
			CopyMemory(m_pBuf, buf + leftcount, m_nWritePos);
			m_bFull = (m_nReadPos == m_nWritePos);   
			ASSERT(m_nReadPos <= m_nBufSize);
			ASSERT(m_nWritePos <= m_nBufSize);
			// ASSERT(m_nWritePos <= m_nReadPos);
			return leftcount + m_nWritePos;
		}
	}
	else	// m_nWritePos < m_nReadPos 的时候 《 m_nReadPos < m_nWritePos 》
	{
  /*                          == 内存模型 ==
        (data)                 (empty)                     (data)
  |-------------------|----------------------------|---------------------------|
                 m_nWritePos    (leftcount)    m_nReadPos                      
  */
		int leftcount = m_nReadPos - m_nWritePos;
		if(leftcount >= count)
		{
			// 有足够的剩余空间存放
			CopyMemory(m_pBuf + m_nWritePos, buf, count);
			m_nWritePos += count;
			m_bFull = (m_nReadPos == m_nWritePos);
			ASSERT(m_nReadPos <= m_nBufSize);
			ASSERT(m_nWritePos <= m_nBufSize);
			// ASSERT(m_nWritePos <= m_nReadPos);
			return count;
		}
		else
		{
			// 剩余空间不足时要丢弃后面的数据
			CopyMemory(m_pBuf + m_nWritePos, buf, leftcount);
			m_nWritePos += leftcount;
			m_bFull = (m_nReadPos == m_nWritePos);	// 一定为TRUE
			ASSERT(m_bFull);
			ASSERT(m_nReadPos <= m_nBufSize);
			ASSERT(m_nWritePos <= m_nBufSize);  
			// ASSERT(m_nWritePos = m_nReadPos);
			return leftcount;
		}
	}
}

/************************************************************************/
/* 从缓冲区读数据,返回实际读取的字节数                                 */
/************************************************************************/
int CCycleBuffer::Read(char* buf, int count)
{
	if(count <= 0) return 0;
	
	m_bFull = FALSE;
	
	if(m_bEmpty)       // 缓冲区空,不能继续读取数据
	{
		return 0;
	}
	else if(m_nReadPos == m_nWritePos)   // 缓冲区满时
	{
  /*                          == 内存模型 ==
     (data)						m_nReadPos                (data)    
  |--------------------------------|--------------------------------------------|
								m_nWritePos								  m_nBufSize
  */
		int leftcount = m_nBufSize - m_nReadPos;
		if(leftcount >= count)
		{
			CopyMemory(buf, m_pBuf + m_nReadPos, count);
			m_nReadPos += count;
			m_bEmpty = (m_nReadPos == m_nWritePos); // 应该是这样吧 m_bEmpty = (m_nReadPos == m_nWritePos + m_nBufSize);
			//ASSERT(m_nWritePos = m_nReadPos);
			return count;
		}
		else
		{
			CopyMemory(buf, m_pBuf + m_nReadPos, leftcount);
			m_nReadPos = (m_nWritePos >= count - leftcount) ? count - leftcount : m_nWritePos;
			CopyMemory(buf + leftcount, m_pBuf, m_nReadPos);
			m_bEmpty = (m_nReadPos == m_nWritePos);
			return leftcount + m_nReadPos;
		}
	}
	else if(m_nReadPos < m_nWritePos)   // 写指针在后(未读数据是连接的)
	{
  /*                          == 内存模型 ==
        (read)                 (unread)                      (read)    
  |-------------------|----------------------------|---------------------------|
                m_nReadPos                m_nWritePos                     m_nBufSize
  */
		int leftcount = m_nWritePos - m_nReadPos;
		int c = (leftcount >= count) ? count : leftcount;
		CopyMemory(buf, m_pBuf + m_nReadPos, c);
		m_nReadPos += c;
		m_bEmpty = (m_nReadPos == m_nWritePos);
		ASSERT(m_nReadPos <= m_nBufSize);
		ASSERT(m_nWritePos <= m_nBufSize);
		return c;
	}
	else          // 读指针在后(未读数据 可能 是不连接的)
	{
  /*                          == 内存模型 ==
         (unread)                (read)                      (unread)
  |-------------------|----------------------------|---------------------------|
                 m_nWritePos                  m_nReadPos                  m_nBufSize
 
  */
		int leftcount = m_nBufSize - m_nReadPos;
		if(leftcount > count)   // 未读缓冲区够大,直接读取数据
		{
			CopyMemory(buf, m_pBuf + m_nReadPos, count);
			m_nReadPos += count;
			m_bEmpty = (m_nReadPos == m_nWritePos); // 应该是这样吧 m_bEmpty = (m_nReadPos == m_nWritePos + m_nBufSize);
			ASSERT(m_nReadPos <= m_nBufSize);
			ASSERT(m_nWritePos <= m_nBufSize);
			return count;
		}
		else       // 未读缓冲区不足,需回到缓冲区头开始读
		{
			CopyMemory(buf, m_pBuf + m_nReadPos, leftcount);
			m_nReadPos = (m_nWritePos >= count - leftcount) ? count - leftcount : m_nWritePos;
			CopyMemory(buf, m_pBuf, m_nReadPos);
			m_bEmpty = (m_nReadPos == m_nWritePos);
			ASSERT(m_nReadPos <= m_nBufSize);
			ASSERT(m_nWritePos <= m_nBufSize);
			return leftcount + m_nReadPos;
		}  
	}
}

/************************************************************************/
/* 获取缓冲区有效数据(即 未读数据)长度                                */
/************************************************************************/
int CCycleBuffer::GetLength()
{
	if(m_bEmpty)
	{
		return 0;
	}
	else if(m_bFull)
	{
		return m_nBufSize;
	}
	else if(m_nReadPos < m_nWritePos)	// 中间为有效数据(字节)段
	{
		return m_nWritePos - m_nReadPos;
	}
	else	// 两头为有效数据(字节)段
	{
		return m_nBufSize - m_nReadPos + m_nWritePos;
	}
}

void CCycleBuffer::Empty()
{
	m_nReadPos = 0;
	m_nWritePos = 0;
	m_bEmpty = TRUE;
	m_bFull = FALSE;
}

bool CCycleBuffer::isEmpty()
{
	return m_bEmpty;
}

bool CCycleBuffer::isFull()
{
	return m_bFull;
}




⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -