循环buffer的c++实现

实现一个循环buffer, 新数据会覆盖旧数据
RingBuffer.h

#pragma once
#include <stdio.h>
#include <string.h>
class RingBuffer
{
public:
	RingBuffer()
	{
		size = 0;
	}
	~RingBuffer()
	{
		if (buffer)
		{
			delete buffer;
			buffer = 0;
		}
	}

	void setSize(int t_size)
	{
		if (t_size != size)
		{
			if (buffer)
			{
				delete buffer;
				buffer = 0;
			}
			size = t_size;
			mSize = t_size + 1;
			buffer = new short[mSize];

			
			pEnd = mSize - 1; // 
			pRead = 0;
			pWrite = 0;

			offset = 0;

		}
	}
	bool push(short * pData, int nSample)
	{
		if (nSample > size)
		{
			printf("len is too large ... \n");
			return false;
		}
		int freeSize = size - GetSampleSize();

		int dis = pWrite - pRead;


		if (freeSize >= nSample) // 够用
		{
			if (dis >= 0) /// pWrite 在右侧
			{
				if (pEnd - pWrite + 1 >= nSample) // 不需要折返拷贝
				{
					memcpy(&buffer[pWrite], pData, nSample * sizeof(short));
					//pWrite += nSample;
					pWrite = add(pWrite, nSample);
					

				}
				else // 需要折返拷贝
				{
					//右边空间多少
					int rightFreeSize = pEnd - pWrite + 1;
					// 左边需要拷贝的大小
					int leftSize = nSample - rightFreeSize;

					memcpy(&buffer[pWrite], pData, rightFreeSize * sizeof(short));

					memcpy(&buffer[0], pData + rightFreeSize, leftSize * sizeof(short));

					//pWrite = leftSize;

					pWrite = add(pWrite, nSample);

				}

			}
			else/// pWrite 在左侧
			{
				//
				memcpy(&buffer[pWrite], pData, nSample * sizeof(short));
				//pWrite += nSample;
				pWrite = add(pWrite, nSample);
			}	

		}
		else // 不够用,覆盖, 需要更新pRead
		{
			printf("差几个 %d ... \n", nSample - freeSize);
			if (dis > 0) /// pWrite 在右侧, 
			{


				//右边空间多少
				int rightFreeSize = pEnd - pWrite + 1;
				// 左边需要拷贝的大小
				int leftSize = nSample - rightFreeSize;

				memcpy(&buffer[pWrite], pData, rightFreeSize * sizeof(short));

				memcpy(&buffer[0], pData + rightFreeSize, leftSize * sizeof(short));

				//pWrite = leftSize;
				//pRead = pWrite + 1;

				pWrite = add(pWrite, nSample);
				pRead = add(pWrite, 1);
				pRead = add(pRead, offset);




			}
			else if (dis < 0) /// pWrite 在左侧
			{
				if (pEnd - pWrite + 1 >= nSample) // 不需要折返拷贝
				{
					memcpy(&buffer[pWrite], pData, nSample * sizeof(short));
					//pWrite += nSample;
					//pRead = pWrite + 1;

					pWrite = add(pWrite, nSample);
					pRead = add(pWrite, 1);
					pRead = add(pRead, offset);

				}
				else // 需要折返拷贝
				{
					//右边空间多少
					int rightFreeSize = pEnd - pWrite + 1;
					// 左边需要拷贝的大小
					int leftSize = nSample - rightFreeSize;

					memcpy(&buffer[pWrite], pData, rightFreeSize * sizeof(short));

					memcpy(&buffer[0], pData + rightFreeSize, leftSize * sizeof(short));

					//pWrite = leftSize;
					//pRead = pWrite + 1;

					pWrite = add(pWrite, nSample);
					pRead = add(pWrite, 1);
					pRead = add(pRead, offset);

				}

			}
			else // 不存在这种情况
			{

			}
		}
		return true;
		
	}
	// 外部开空间
	bool pop(short * pData, int nSamples)
	{
		int curSampleSize = GetSampleSize();
		if (curSampleSize < nSamples)
		{
			return false;
		}

		int dis = pWrite - pRead;

		if (dis > 0) /// pWrite 在右侧
		{

			memcpy(pData, &buffer[pRead], nSamples * sizeof(short));
			//pRead += nSamples;
			pRead = add(pRead, nSamples);
			
		}
		else // dis < 0
		{
			if (pEnd - pRead + 1 >= nSamples) // 不需要折返拷贝
			{
				memcpy(pData, &buffer[pRead], nSamples * sizeof(short));
				//pRead += nSamples;

				pRead = add(pRead, nSamples);

			}
			else // 需要折返拷贝
			{
				//右边空间多少
				int rightFreeSize = pEnd - pRead + 1;
				// 左边需要拷贝的大小
				int leftSize = nSamples - rightFreeSize;

				memcpy(pData, &buffer[pRead], rightFreeSize * sizeof(short));

				memcpy(pData + rightFreeSize, &buffer[0], leftSize * sizeof(short));

				//pRead = leftSize;
				pRead = add(pRead, nSamples);

			}

		}
		return true;

	}

	int GetSampleSize()
	{
		return (pWrite - pRead + mSize) % mSize;
	}
	int add(int pos, int t)
	{
		return (pos + t) % mSize;
	}


private:

	int mSize; // 申请空间比容量大1
	int size; // 循环buffer 的容量
	short * buffer; 

	int offset;
	int pEnd;
	int pRead;
	int pWrite;

};


main.cpp

#include <stdio.h>
#include "RingBuffer.h"

int main()
{

	RingBuffer mRingBuffer;
	int mMaxSize = 5;
	mRingBuffer.setSize(mMaxSize * 2);
	int mGetSize = 3;



	short * pShort = new short[mMaxSize];
	for (int i = 0; i < mMaxSize; i++)
	{
		pShort[i] = i;
	}
	short * pGet = new short[mGetSize];


	for (int i = 0; i < 10; i++)
	{
		printf("################ %d ....\n", i);
		mRingBuffer.push(pShort, mMaxSize);

		bool isOk = mRingBuffer.pop(pGet, mGetSize);
		if (isOk)
		{
			for (int j = 0; j < mGetSize; j++)
			{
				printf("%d .. \n", pGet[j]);
			}
		}
		
	}

	printf("## ");
	return 0;
}

代码经过初步测试,后续会用模板的方式更新测试

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值