对多个字节组装成一个帧后发送封装

2013年6月29日 由 Creater 留言 »

很多时候,我们需要填充一个帧结构然后通过网络或者串口发送出去,另外可能一个帧需要在多个地方进行填充后才发送。我利用下边的封装类完成,使用块进行复制,相对来说速度更快点!
头文件CQueueBuf.h

using namespace std;
class CQueueBuf
{
public:
public:
	CQueueBuf(size_t size);
	~CQueueBuf();

	bool Write(const char *p,size_t l);

	bool Read(char *dest,size_t l);


	bool Remove(size_t l);


	std::string ReadString(size_t l);


	size_t GetLength();

	const char *GetStart();

	size_t GetL();

	size_t Space();

	unsigned long ByteCounter(bool clear = false);

private:
	CQueueBuf(const CQueueBuf& s) {}
	CQueueBuf& operator=(const CQueueBuf& ) { return *this; }
	char *buf;
	size_t maxSizeBytes;
	size_t queueBytes;
	size_t readIndex;
	size_t writeIndex;
	unsigned long bytesCount;
};

其中:
maxSizeBytes为循环缓冲区的大小;
queueBytes为当前在循环缓冲区队列中的字节数;
readIndex为读索引;
writeIndex为写索引;
bytesCount为总的字节计数。

源文件为:

#include "CQueueBuf.h"
#include <string>

CQueueBuf::CQueueBuf(size_t size)
:buf(new char[/*2 * */size])
,maxSizeBytes(size)
,queueBytes(0)
,readIndex(0)
,writeIndex(0)
,bytesCount(0)
{
}

CQueueBuf::~CQueueBuf()
{
	delete[] buf;
}


bool CQueueBuf::Write(const char *s,size_t l)
{
	if (queueBytes + l > maxSizeBytes)
	{
		return false;
	}
	bytesCount += (unsigned long)l;
	if (writeIndex + l > maxSizeBytes)
	{
		size_t l1 = maxSizeBytes - writeIndex;
		memcpy(buf + writeIndex, s, l1);
		memcpy(buf, s + l1, l - l1);
		writeIndex = l - l1;
		queueBytes += l;
	}
	else
	{
		memcpy(buf + writeIndex, s, l);
		memcpy(buf + maxSizeBytes + writeIndex, s, l);
		writeIndex += l;
		if (writeIndex >= maxSizeBytes)
			writeIndex -= maxSizeBytes;
		queueBytes += l;
	}
	return true;
}


bool CQueueBuf::Read(char *s,size_t l)
{
	if (l > queueBytes)
	{
		return false; 
	}
	if (readIndex + l > maxSizeBytes) 
	{
		size_t l1 = maxSizeBytes - readIndex;
		if (s)
		{
			memcpy(s, buf + readIndex, l1);
			memcpy(s + l1, buf, l - l1);
		}
		readIndex = l - l1;
		queueBytes -= l;
	}
	else
	{
		if (s)
		{
			memcpy(s, buf + readIndex, l);
		}
		readIndex += l;
		if (readIndex >= maxSizeBytes)
			readIndex -= maxSizeBytes;
		queueBytes -= l;
	}
	if (!queueBytes)
	{
		readIndex = writeIndex = 0;
	}
	return true;
}


bool CQueueBuf::Remove(size_t l)
{
	return Read(NULL, l);
}


size_t CQueueBuf::GetLength()
{
	return queueBytes;
}


const char *CQueueBuf::GetStart()
{
	return buf + readIndex;
}


size_t CQueueBuf::GetL()
{
	return (readIndex + queueBytes > maxSizeBytes) ? maxSizeBytes - readIndex : queueBytes;
}


size_t CQueueBuf::Space()
{
	return maxSizeBytes - queueBytes;
}


unsigned long  CQueueBuf::ByteCounter(bool clear)
{
	if (clear)
	{
		unsigned long x = bytesCount;
		bytesCount = 0;
		return x;
	}
	return bytesCount;
}


std::string  CQueueBuf::ReadString(size_t l)
{
	char *sz = new char[l + 1];
	if (!Read(sz, l)) 
	{
		delete[] sz;
		return "";
	}
	sz[l] = 0;
	std::string tmp = sz;
	delete[] sz;
	return tmp;
}

Write:为向缓冲区中写bytes数组;
Read:为从缓冲区中读长度为l的字节数,如果不够读则返回false。
Remove:为移除缓冲区中的l字节,内部实现为读l字节;
GetLength:当需要查询一个帧是否组装完成或者需要获取缓冲区中的字节数时非要有用喔!
GetStart:返回读索引

广告位

发表评论

你必须 登陆 方可发表评论.