市面开源库序列化二进制库太多、各种功能强大、使用也比较繁琐。实际项目中使用的功能很少。
内存与维护消耗比较重。
极简使用方式。
一、测试代码:
#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);
}