极简风格快速处理序列化与反序列化 C++ 11 C++20

市面开源库序列化二进制库太多、各种功能强大、使用也比较繁琐。实际项目中使用的功能很少。

内存与维护消耗比较重。

极简使用方式。

一、测试代码:

#include "Serialize.h"
#include <limits>
#include <iostream>

void main()
{
	unsigned char ucValue = (std::numeric_limits<unsigned char>::max)();
	short sValue = (std::numeric_limits<short>::max)();
	unsigned short usValue = (std::numeric_limits<unsigned short>::max)();
	int iValue = (std::numeric_limits<int>::max)();
	unsigned int uiValue = (std::numeric_limits<unsigned int>::max)();
	long long llValue = (std::numeric_limits<long long>::max)();
	unsigned long long ullValue = (std::numeric_limits<unsigned long long>::max)();
	float fValue = (std::numeric_limits<float>::max)();
	double dValue = (std::numeric_limits<double>::max)();
	bool bValue = (std::numeric_limits<bool>::max)();

	std::string stds = "test Serialize std::string";
	std::string stdsw = "test Serialize std::wstring";

	Serialize ar;
	ar << ucValue << sValue << usValue << iValue << uiValue << llValue 
	   << ullValue << fValue << dValue << bValue << stds << stdsw;

	std::cout << "src:" << ucValue << " " << sValue << " " << usValue << " " << iValue << " " << uiValue << " " << llValue << " "
		<< ullValue << " " << fValue << " " << dValue << "\n\t" << bValue << " " << stds << " " << stdsw << "\n";

	UnSerialize unAr(ar.str());

	unsigned char uc = 0;
	short s;
	unsigned short us;
	int i = 0;
	unsigned int ui = 0;
	long long ll = 0;
	unsigned long long ull = 0;
	float f = 0.0f;
	double d = 0.0f;
	bool b = false;
	std::string s1 = "";
	std::string s2 = "";
	unAr >> uc >> s >> us >> i >> ui >> ll >> ull >> f >> d >> b >> s1 >> s2;

	std::cout << "dst:" << uc << " " << s << " " << us << " " << i << " " << ui << " " << ll << " "
		<< ull << " " << f << " " << d << "\n\t" << b << " " << s1 << " " << s2 << "\n";
}

二、运行结果:

三、Serialize (序列化)

class Serialize final
{
public:
	void ClearBuffer();

	//Serialize& operator<<(char value); C++中大量使用std::string 删除此实现
	Serialize& operator<<(unsigned char value);
	Serialize& operator<<(short value);
	Serialize& operator<<(unsigned short value);
	Serialize& operator<<(int value);
	Serialize& operator<<(unsigned int value);
	Serialize& operator<<(long long value);
	Serialize& operator<<(unsigned long long value);
	Serialize& operator<<(float value);
	Serialize& operator<<(double value);
	Serialize& operator<<(const std::string& value);
	Serialize& operator<<(const std::wstring& value);
	Serialize& operator<<(bool value);

	template <typename T>
	Serialize& Make(T value)
	{
		m_sBuf.sputn((char*)&value, sizeof(T));
		return (*this);
	}

	std::string str();

	int len();

private:
	std::stringbuf m_sBuf;
};

四、UnSerialize (反序列化)

class UnSerialize final
{
public:
	UnSerialize(const std::string& sSrc);

	//UnSerialize& operator>>(char& value); C++中大量使用std::string 删除此实现
	UnSerialize& operator>>(unsigned char& value);
	UnSerialize& operator>>(short& value);
	UnSerialize& operator>>(unsigned short& value);
	UnSerialize& operator>>(int& value);
	UnSerialize& operator>>(unsigned int& value);
	UnSerialize& operator>>(long long& value);
	UnSerialize& operator>>(unsigned long long& value);
	UnSerialize& operator>>(float& value);
	UnSerialize& operator>>(double& value);
	UnSerialize& operator>>(std::string& value);
	UnSerialize& operator>>(std::wstring& value);
	UnSerialize& operator>>(bool& value);

	template <typename T>
	UnSerialize& Get(T& ret)
	{
		if (!bSuccess)
			return (*this);

		auto iRet = m_sBuf.sgetn((char*)&ret, sizeof(T));

		if (iRet != sizeof(T))
			bSuccess = false;

		return (*this);
	}

	bool bSuccess;	//解析数据是否成功
	int iLen;
private:
	std::stringbuf m_sBuf;
};

五、包装模板

template<class T>
class SerializeT
{
public:
	Serialize ar;
public:
	SerializeT() {}
	virtual ~SerializeT() {}

	std::string package()
	{
		serialize();
		return ar.str();
	}

	virtual void serialize() = 0;
};

template<class T>
class UnSerializeT
{
public:
	virtual ~UnSerializeT() {}

	virtual bool unPackage(UnSerialize& ar)
	{
		unSerialize(ar);
		return ar.bSuccess;
	}

protected:
	virtual void unSerialize(UnSerialize& ar) = 0;
};


class Test1 : public UnSerializeT<Test1>
{
private:
	int				iCmd=0x123456;
	int				iMagicNum=6;
public:
	virtual void unSerialize(UnSerialize& ar) override
	{
		ar >> iCmd >> iMagicNum;
	}
};


class Test2 : public SerializeT<Test2>
{
private:
	int				iCmd = 0x654321;
	int				iMagicNum = 6;
public:
	int				iClientHeartbeatId = 0;
	virtual void serialize() override
	{
		ar << iCmd << iMagicNum<< iClientHeartbeatId;
	}
};

六、具体实现


#include "Serialize.h"
#include <string.h>
#include <codecvt>

Serialize& Serialize::operator<<(unsigned char value)
{
	m_sBuf.sputn((char*)&value, sizeof(unsigned char));
	return (*this);
}

Serialize& Serialize::operator<<(short value)
{
	char tmp[2] = { 0 };
	tmp[0] = (char)(((value & 0xff00) >> 8) & 0xff);
	tmp[1] = (char)((value & 0x00ff) & 0xff);
	m_sBuf.sputn((char*)&tmp, 2);
	return (*this);
//	return Make<short>(value);
}

Serialize& Serialize::operator<<(unsigned short value)
{
	char tmp[2] = { 0 };
	tmp[0] = (char)(((value & 0xff00) >> 8) & 0xff);
	tmp[1] = (char)((value & 0x00ff) & 0xff);
	m_sBuf.sputn((char*)&tmp, 2);
	return (*this);
//	return Make<unsigned short>(value);
}

Serialize& Serialize::operator<<(int value)
{
	char tmp[4] = { 0 };
	tmp[0] = (char)(((value & 0xff000000) >> 24) & 0xff);
	tmp[1] = (char)(((value & 0x00ff0000) >> 16) & 0xff);
	tmp[2] = (char)(((value & 0x0000ff00) >> 8) & 0xff);
	tmp[3] = (char)((value & 0x000000ff) & 0xff);
	m_sBuf.sputn((char*)&tmp, 4);
	return (*this);
	//return Make<int>(value);
}

Serialize& Serialize::operator<<(unsigned int value)
{
	char tmp[4] = { 0 };
	tmp[0] = (char)(((value & 0xff000000) >> 24) & 0xff);
	tmp[1] = (char)(((value & 0x00ff0000) >> 16) & 0xff);
	tmp[2] = (char)(((value & 0x0000ff00) >> 8) & 0xff);
	tmp[3] = (char)((value & 0x000000ff) & 0xff);
	m_sBuf.sputn((char*)&tmp, 4);

	return (*this);
//	return Make<unsigned int>(value);
}

Serialize& Serialize::operator<<(long long value)
{
	//return Make<long long>(value);
	char tmp[8] = { 0 };
	tmp[0] = (char)(((value & 0xff00000000000000) >> 56) & 0xff);
	tmp[1] = (char)(((value & 0x00ff000000000000) >> 48) & 0xff);
	tmp[2] = (char)(((value & 0x0000ff0000000000) >> 40) & 0xff);
	tmp[3] = (char)(((value & 0x000000ff00000000) >> 32) & 0xff);

	tmp[4] = (char)(((value & 0x00000000ff000000) >> 24) & 0xff);
	tmp[5] = (char)(((value & 0x0000000000ff0000) >> 16) & 0xff);
	tmp[6] = (char)(((value & 0x000000000000ff00) >> 8) & 0xff);
	tmp[7] = (char)((value & 0x00000000000000ff) & 0xff);
	m_sBuf.sputn((char*)&tmp, 8);

	return (*this);
}

Serialize& Serialize::operator<<(unsigned long long value)
{
//	return Make<unsigned long long>(value);
	char tmp[8] = { 0 };
	tmp[0] = (char)(((value & 0xff00000000000000) >> 56) & 0xff);
	tmp[1] = (char)(((value & 0x00ff000000000000) >> 48) & 0xff);
	tmp[2] = (char)(((value & 0x0000ff0000000000) >> 40) & 0xff);
	tmp[3] = (char)(((value & 0x000000ff00000000) >> 32) & 0xff);

	tmp[4] = (char)(((value & 0x00000000ff000000) >> 24) & 0xff);
	tmp[5] = (char)(((value & 0x0000000000ff0000) >> 16) & 0xff);
	tmp[6] = (char)(((value & 0x000000000000ff00) >> 8) & 0xff);
	tmp[7] = (char)((value & 0x00000000000000ff) & 0xff);
	m_sBuf.sputn((char*)&tmp, 8);

	return (*this);
}

Serialize& Serialize::operator<<(float value)
{
	return Make<float>(value);
}

Serialize& Serialize::operator<<(double value)
{
	return Make<double>(value);
}

Serialize& Serialize::operator<<(const std::string& value)
{
	int len = (int)value.length();
	(*this) << len;
	//int iCount = value.length();
	//m_sBuf.sputn((char*)&iCount, sizeof(int));
	m_sBuf.sputn(value.c_str(), len);

	return (*this);
}

Serialize& Serialize::operator<<(const std::wstring& value)
{
	std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
	auto sData = conv.to_bytes(value);

	int len = (int)sData.length();
	(*this) << len;

	m_sBuf.sputn(sData.c_str(), len);

	return (*this);
}

Serialize& Serialize::operator<<(bool value)
{
	unsigned short usShort = value ? 1 : 0;
	(*this) << usShort;

	return (*this);
	//	return Make<unsigned short>(usShort);
}

std::string Serialize::str()
{
	return m_sBuf.str();
}

int Serialize::len()
{
	return (int)m_sBuf.str().length();
}

void Serialize::ClearBuffer()
{
	m_sBuf.str("");
}

UnSerialize::UnSerialize(const std::string& sSrc)
	:m_sBuf(sSrc, std::ios_base::in)
	, iLen((int)sSrc.length())
{
	bSuccess = true;
}

UnSerialize& UnSerialize::operator >> (unsigned char& value)
{
	if (!bSuccess)
		return (*this);

	auto iRet = m_sBuf.sgetn((char*)&value, 1);
	if (iRet != 1) {
		bSuccess = false;
		return (*this);
	}
	return (*this);
//	return Get<unsigned char>(value);
}

UnSerialize& UnSerialize::operator >> (short& value)
{
	if (!bSuccess)
		return (*this);

	char tmp[2] = { 0 };
	auto iRet = m_sBuf.sgetn((char*)&tmp, 2);
	if (iRet != 2) {
		bSuccess = false;
		return (*this);
	}
	int i1 = (((char)tmp[0]) << 8) & 0xFF00;
	int i2 = ((char)tmp[1]) & 0x00FF;
	int ret = i1 | i2 ;
	value = ret;
	return (*this);
//	return Get<short>(value);
}

UnSerialize& UnSerialize::operator >> (unsigned short& value)
{
	if (!bSuccess)
		return (*this);

	char tmp[2] = { 0 };
	auto iRet = m_sBuf.sgetn((char*)&tmp, 2);
	if (iRet != 2) {
		bSuccess = false;
		return (*this);
	}
	int i1 = (((char)tmp[0]) << 8) & 0xFF00;
	int i2 = ((char)tmp[1]) & 0x00FF;
	int ret = i1 | i2;
	value = ret;
	return (*this);
//	return Get<unsigned short>(value);
}

UnSerialize& UnSerialize::operator >> (int& value)
{
	if (!bSuccess)
		return (*this);

	char tmp[4] = { 0 };
	auto iRet = m_sBuf.sgetn((char*)&tmp, 4); 
	if (iRet != 4) 
	{
		bSuccess = false;
		return (*this);
	}

	int i1 = (((char)tmp[0]) << 24)&0xFF000000;
	int i2 = (((char)tmp[1]) << 16)&0x00FF0000;
	int i3 = (((char)tmp[2]) << 8)& 0x0000FF00;
	int i4 = ((char)tmp[3])& 0x000000FF;
	//int ret = (int)(((byte)tmp[0] << 24 )| ((char)tmp[1] << 16 )| ((char)tmp[2] << 8) | ((char)tmp[3]));
	int ret = i1 | i2 | i3 | i4;
	value = ret;
	return (*this);
	//return Get<int>(value);
}

UnSerialize& UnSerialize::operator >> (unsigned int& value)
{
	if (!bSuccess)
		return (*this);

	char tmp[4] = { 0 };
	auto iRet = m_sBuf.sgetn((char*)&tmp, 4);
	if (iRet != 4) {
		bSuccess = false;
		return (*this);
	}
	int i1 = (((char)tmp[0]) << 24) & 0xFF000000;
	int i2 = (((char)tmp[1]) << 16) & 0x00FF0000;
	int i3 = (((char)tmp[2]) << 8) & 0x0000FF00;
	int i4 = ((char)tmp[3]) & 0x000000FF;
	//int ret = (int)(((byte)tmp[0] << 24 )| ((char)tmp[1] << 16 )| ((char)tmp[2] << 8) | ((char)tmp[3]));
	int ret = i1 | i2 | i3 | i4;
	value = ret;
	return (*this);
//	return Get<unsigned int>(value);
}

UnSerialize& UnSerialize::operator>>(long long& value)
{
	if (!bSuccess)
		return (*this);

	char tmp[8] = { 0 };
	auto iRet = m_sBuf.sgetn((char*)&tmp, 8);
	if (iRet != 8) 
	{
		bSuccess = false;
		return (*this);
	}

	long long i1 = (((long long)tmp[0]) << 56) & 0xFF00000000000000;
	long long i2 = (((long long)tmp[1]) << 48) & 0x00FF000000000000;
	long long i3 = (((long long)tmp[2]) << 40) & 0x0000FF0000000000;
	long long i4 = (((long long)tmp[3]) << 32) & 0x000000FF00000000;

	long long i5 = (((long long)tmp[4]) << 24) & 0x00000000FF000000;
	long long i6 = (((long long)tmp[5]) << 16) & 0x0000000000FF0000;
	long long i7 = (((long long)tmp[6]) << 8) & 0x000000000000FF00;
	long long i8 = ((long long)tmp[7]) & 0x00000000000000FF;
	//int ret = (int)(((byte)tmp[0] << 24 )| ((char)tmp[1] << 16 )| ((char)tmp[2] << 8) | ((char)tmp[3]));
	long long ret = i1 | i2 | i3 | i4 | i5 | i6 | i7 | i8;
	value = ret;
	return (*this);
	//return Get<long long>(value);
}

UnSerialize& UnSerialize::operator>>(unsigned long long& value)
{
	if (!bSuccess)
		return (*this);

	char tmp[8] = { 0 };
	auto iRet = m_sBuf.sgetn((char*)&tmp, 8);
	if (iRet != 8) 
	{
		bSuccess = false;
		return (*this);
	}
	
	unsigned long long i1 = (((unsigned long long)tmp[0]) << 56) & 0xFF00000000000000;
	unsigned long long i2 = (((unsigned long long)tmp[1]) << 48) & 0x00FF000000000000;
	unsigned long long i3 = (((unsigned long long)tmp[2]) << 40) & 0x0000FF0000000000;
	unsigned long long i4 = (((unsigned long long)tmp[3]) << 32) & 0x000000FF00000000;

	unsigned long long i5 = (((unsigned long long)tmp[4]) << 24) & 0x00000000FF000000;
	unsigned long long i6 = (((unsigned long long)tmp[5]) << 16) & 0x0000000000FF0000;
	unsigned long long i7 = (((unsigned long long)tmp[6]) << 8) & 0x000000000000FF00;
	unsigned long long i8 = ((unsigned long long)tmp[7]) & 0x00000000000000FF;
	//int ret = (int)(((byte)tmp[0] << 24 )| ((char)tmp[1] << 16 )| ((char)tmp[2] << 8) | ((char)tmp[3]));
	unsigned long long ret = i1 | i2 | i3 | i4 | i5 | i6 | i7 | i8;
	value = ret;
	return (*this);
	//return Get<unsigned long long>(value);
}

UnSerialize& UnSerialize::operator>>(float& value)
{
	return Get<float>(value);
}

UnSerialize& UnSerialize::operator>>(double& value)
{
	return Get<double>(value);
}

UnSerialize& UnSerialize::operator>>(std::string& value)
{
	int iCount = 0;
	//auto iRet = m_sBuf.sgetn((char*)&iCount, sizeof(int));
	(*this) >> iCount;
	if (iCount > 0)
	{
		char* buff = new char[iCount + 1];
		memset(buff, 0, iCount + 1);
		auto iRet = m_sBuf.sgetn(buff, iCount);
		value.assign(std::move(buff), iCount);
		delete[] buff;

		if (iRet != iCount)
			bSuccess = false;
	}

	return (*this);
}

UnSerialize& UnSerialize::operator>>(std::wstring& value)
{
	int iCount = 0;
	//auto iRet = m_sBuf.sgetn((char*)&iCount, sizeof(int));
	(*this) >> iCount;
	if (iCount > 0)
	{
		std::string sData;
		char* buff = new char[iCount + 1];
		memset(buff, 0, iCount + 1);
		auto iRet = m_sBuf.sgetn(buff, iCount);
		sData.assign(std::move(buff), iCount);
		delete[] buff;

		if (sData.length() > 0)
		{
			std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> con;
			value = std::move(con.from_bytes(sData.data()));
		}

		if (iRet != iCount)
			bSuccess = false;
	}

	return (*this);
}

UnSerialize& UnSerialize::operator>>(bool& value)
{
	unsigned short usValue = 0;
	(*this) >> usValue;
	value = usValue ? true : false;
	return (*this);
}

【免费】极简风格快速处理序列化与反序列化C++11C++20测试及代码实现工程文件资源-CSDN文库

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

优秀会上瘾

缺少的是时间,从来不是金钱.

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值