C++版的循环缓冲区类(实际测试可用!)

/*

 * CCycleBuffer.h

 *

 *  Created on: 2013-5-27

 *      Author: shiguang

 */



#ifndef __test__CCycleBuffer__

#define __test__CCycleBuffer__

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <assert.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;



public:

	int GetReadPos()

	{

		return m_nReadPos;

	}

	int GetWritePos()

	{

		return m_nWritePos;

	}

};

#endif /* defined(__test__CCycleBuffer__) */


 

/*

 * CCycleBuffer.cpp

 *

 *  Created on: 2013-5-27

 *      Author: shiguang

 */



#include "CCycleBuffer.h"

// 定义

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)

		{

			memcpy(m_pBuf + m_nWritePos, buf, count);

			m_nWritePos += count;

			m_bFull = (m_nWritePos == m_nReadPos);

			return count;

		}

		else

		{

			memcpy(m_pBuf + m_nWritePos, buf, leftcount);

			m_nWritePos =

					(m_nReadPos > count - leftcount) ?

							count - leftcount : m_nReadPos; // 计算未写入数据大小

			memcpy(m_pBuf, buf + leftcount, m_nWritePos);

			m_bFull = (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)   // 有足够的剩余空间存放

		{

			memcpy(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);

			return count;

		}

		else       // 剩余空间不足

		{

			// 先填充满剩余空间,再回头找空间存放

			memcpy(m_pBuf + m_nWritePos, buf, leftcount);

			m_nWritePos =

					(m_nReadPos >= count - leftcount) ?

							count - leftcount : m_nReadPos;

			memcpy(m_pBuf, buf + leftcount, m_nWritePos);

			m_bFull = (m_nReadPos == m_nWritePos);

			assert(m_nReadPos <= m_nBufSize);

			assert(m_nWritePos <= m_nBufSize);

			return leftcount + m_nWritePos;

		}

	}

	else

	{

		/*                          == 内存模型 ==

		 (unread)                 (read)                     (unread)

		 |-------------------|----------------------------|---------------------------|

		 m_nWritePos    (leftcount)    m_nReadPos

		 */

		int leftcount = m_nReadPos - m_nWritePos;

		if (leftcount > count)

		{

			// 有足够的剩余空间存放

			memcpy(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);

			return count;

		}

		else

		{

			// 剩余空间不足时要丢弃后面的数据

			memcpy(m_pBuf + m_nWritePos, buf, leftcount);

			m_nWritePos += leftcount;

			m_bFull = (m_nReadPos == m_nWritePos);

			assert(m_bFull);

			assert(m_nReadPos <= m_nBufSize);

			assert(m_nWritePos <= m_nBufSize);

			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)

		{

			memcpy(buf, m_pBuf + m_nReadPos, count);

			m_nReadPos += count;

			m_bEmpty = (m_nReadPos == m_nWritePos);

			return count;

		}

		else

		{

			memcpy(buf, m_pBuf + m_nReadPos, leftcount);

			m_nReadPos =

					(m_nWritePos > count - leftcount) ?

							count - leftcount : m_nWritePos;

			memcpy(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;

		memcpy(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)   // 未读缓冲区够大,直接读取数据

		{

			memcpy(buf, m_pBuf + m_nReadPos, count);

			m_nReadPos += count;

			m_bEmpty = (m_nReadPos == m_nWritePos);

			assert(m_nReadPos <= m_nBufSize);

			assert(m_nWritePos <= m_nBufSize);

			return count;

		}

		else       // 未读缓冲区不足,需回到缓冲区头开始读

		{

			memcpy(buf, m_pBuf + m_nReadPos, leftcount);

			m_nReadPos =

					(m_nWritePos >= count - leftcount) ?

							count - leftcount : m_nWritePos;  // 计算剩余未读数据大小

			memcpy(buf + leftcount, 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;

}

 

 


 

/*

 * main.cpp

 *

 *  Created on: 2013-5-27

 *      Author: shiguang

 */



#include "CCycleBuffer.h"



int main()

{

	CCycleBuffer buffer(100);

	char* datachar = new char[40];

	char* reschar = new char[100];



	int res = 0;



	for (int i = 0; i < 40; ++i)

	{

		datachar[i] = i + 1;

	}

	res = buffer.Write(datachar, 40);

	printf("写入数据个数:%d\n", res);

	res = buffer.Write(datachar, 40);

	printf("写入数据个数:%d\n", res);

	res = buffer.Write(datachar, 40);

	printf("写入数据个数:%d\n", res);

	res = buffer.Write(datachar, 40);

	printf("写入数据个数:%d\n", res);



	res = buffer.Read(reschar, 100);

	printf("读取数据个数:%d\n", res);

	for (int i = 0; i < 100; ++i)

	{

		if (i % 10 == 0)

		{

			printf("\n");

		}

		printf("%2d   ", reschar[i]);

	}



	return 0;

}


输出结果:

 

 

写入数据个数:40

写入数据个数:40

写入数据个数:20

写入数据个数:0

读取数据个数:100



 1    2    3    4    5    6    7    8    9   10   

11   12   13   14   15   16   17   18   19   20   

21   22   23   24   25   26   27   28   29   30   

31   32   33   34   35   36   37   38   39   40   

 1    2    3    4    5    6    7    8    9   10   

11   12   13   14   15   16   17   18   19   20   

21   22   23   24   25   26   27   28   29   30   

31   32   33   34   35   36   37   38   39   40   

 1    2    3    4    5    6    7    8    9   10   

11   12   13   14   15   16   17   18   19   20   


源程序来自网络资料!

 

你可能感兴趣的:(C++)