欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C++环形缓冲区

程序员文章站 2024-03-25 15:31:28
...

https://blog.csdn.net/weiyu00/article/details/84750560

#pragma once

template <class T> 
class CRingBuffer
{
public:
	CRingBuffer()
	{
		m_pBuffer = NULL;
		m_nSize = 0;
		m_nUnreadSize = 0;
		m_nWritePos = 0;
		m_nReadPos = 0;
	}

	virtual ~CRingBuffer()
	{
		m_cs.Lock();
		if (m_pBuffer != NULL)
		{
			delete [] m_pBuffer;
			m_pBuffer = NULL;
			m_nSize = 0;
			m_nUnreadSize = 0;
			m_nWritePos = 0;
			m_nReadPos = 0;
		}
		m_cs.Unlock();
	}

	//清空环形缓冲区
	void Clear()
	{
		m_cs.Lock();
		m_nUnreadSize = 0;
		m_nWritePos = 0;
		m_nReadPos = 0;
		m_cs.Unlock();
	}

	//设置环形缓冲区
	//nSize:缓冲区大小
	void SetBuffer(int nSize)
	{
		m_cs.Lock();
		if (m_pBuffer != NULL)
		{
			delete [] m_pBuffer;
			m_pBuffer = NULL;
			m_nSize = 0;
			m_nUnreadSize = 0;
			m_nWritePos = 0;
			m_nReadPos = 0;
		}

		m_pBuffer = new T[nSize];
		if (m_pBuffer != NULL)
		{
			memset(m_pBuffer, 0x00, nSize*sizeof(T));
			m_nSize = nSize;
			m_nUnreadSize = 0;
			m_nWritePos = 0;
			m_nReadPos = 0;
		}
		m_cs.Unlock();
	}
	//写入数据到环形缓冲区
	//返回值:写入的数据大小
	int WriteData(const T* pT, int nSize = 1)
	{
		m_cs.Lock();
		if (nSize > m_nSize - m_nUnreadSize)//缓冲区大小不足时,仅写入最前面的数据
			nSize = m_nSize - m_nUnreadSize;

		if (nSize > 0)
		{
			if (m_nWritePos + nSize <= m_nSize)
			{
				memcpy(&m_pBuffer[m_nWritePos], pT, nSize*sizeof(T));
			}
			else
			{
				memcpy(&m_pBuffer[m_nWritePos], pT, (m_nSize - m_nWritePos)*sizeof(T));
				if (nSize - (m_nSize - m_nWritePos) > 0)
					memcpy(m_pBuffer, &pT[m_nSize - m_nWritePos], (nSize - (m_nSize - m_nWritePos))*sizeof(T));
			}

			m_nUnreadSize += nSize;
			m_nWritePos += nSize;
			if (m_nWritePos >= m_nSize)
				m_nWritePos %= m_nSize;
		}

		m_cs.Unlock();
		return nSize;
	}
	//从环形缓冲区读取数据
	//nSize:缓冲区大小
	//返回值:读取的数据大小
	int ReadData(T* pT, int nSize = 1)
	{
		m_cs.Lock();
		if (nSize > m_nUnreadSize || m_nUnreadSize == 0)
			nSize = m_nUnreadSize;

		if (nSize > 0)
		{
			if (m_nReadPos + nSize <= m_nSize)
			{
				memcpy(pT, &m_pBuffer[m_nReadPos], nSize*sizeof(T));
			}
			else
			{
				memcpy(pT, &m_pBuffer[m_nReadPos], (m_nSize - m_nReadPos)*sizeof(T));
				if (nSize - (m_nSize - m_nReadPos) > 0)
					memcpy(&pT[m_nSize - m_nReadPos], m_pBuffer, (nSize - (m_nSize - m_nReadPos))*sizeof(T));
			}

			m_nUnreadSize -= nSize;
			m_nReadPos += nSize;
			if (m_nReadPos >= m_nSize)
				m_nReadPos %= m_nSize;
		}

		m_cs.Unlock();
		return nSize;
	}
private:
	T* m_pBuffer;	//缓冲区
	int m_nSize;	//缓冲区大小

	int m_nUnreadSize;	//未读取的数据大小

	int m_nWritePos;		//写入下标
	int m_nReadPos;			//读取下标

	CComAutoCriticalSection m_cs;//线程锁
};

相关标签: 环形缓冲区