https://blog.csdn.net/g2com/article/details/64904256
比特币客户端所有的序列化函数均在 seriliaze.h 中实现。其中,CDataStream类是数据序列化的核心结构。
CDataStream 拥有一个字符类容器用来存放序列化之后的数据。它结合一个容器类型和一个流(stream)API 以处理数据。
宏 READDATA() 和 WRITEDATA()
#define WRITEDATA(s, obj) s.write((char*)&(obj), sizeof(obj))
#define READDATA(s, obj) s.read((char*)&(obj), sizeof(obj))
CDataStream 重载了操作符 <<
和 >>
用于序列化和反序列化。
template <typename T>
CDataStream &operator<<(const T &obj) {
// Serialize to this stream
::Serialize(*this, obj, nType, nVersion);
return (*this);
}
template <typename T>
CDataStream &operator>>(T &obj) {
// Unserialize from this stream
::Unserialize(*this, obj, nType, nVersion);
return (*this);
}
头文件serialize.h包含了14个重载后的这两个全局函数给14个原始类型(signed和unsigned版本char,short,int,long和long long,以及char,float,double和bool)以及6个重载版本的6个复合类型(string,vector,pair,map,set和CScript)。因此,对于这些类型,你可以简单地使用以下代码来序列化/反序列化数据:
如果没有任何实现的类型符合第二个参数obj,则以下泛型T全局函数将会被调用。
template<typename Stream, typename T>
inline void Serialize(Stream& os, const T& a, long nType, int nVersion=VERSION)
{
a.Serialize(os, (int)nType, nVersion);
}
对于该泛型版本,类型T应该用于实现一个成员函数和签名T::Serialize(Stream, int, int)。它将通过a.Serialize()被调用。
泛型T需要实现以下三个成员函数进行序列化。
unsigned int GetSerializeSize(int nType = 0, int nVersion = VERSION) const;
void Serialize(Stream &s, int nType = 0, int nVersion = VERSION) const;
void Unserialize(Stream &s, int nType = 0, int nVersion = VERSION);
一个宏IMPLEMENT_SERIALIZE(statements)用于定义任意类型的这三个函数的实现。
宏READWRITE()的定义如下
#define READWRITE(obj) (nSerSize += ::SerReadWrite(s, (obj), nType, nVersion, ser_action))
ser_action是一个对象在三个函数当中均有声明,但为三种不同类型。它在三个函数当中分别为
- CSerActionGetSerializeSize
- CSerActionSerialize
- CSerActionUnserialize
template <typename Stream, typename T>
inline unsigned int SerReadWrite(Stream &s, const T &obj, int nType,
int nVersion,
CSerActionGetSerializeSize ser_action) {
return ::GetSerializeSize(obj, nType, nVersion);
}
template <typename Stream, typename T>
inline unsigned int SerReadWrite(Stream &s, const T &obj, int nType,
int nVersion, CSerActionSerialize ser_action) {
::Serialize(s, obj, nType, nVersion);
return 0;
}
template <typename Stream, typename T>
inline unsigned int SerReadWrite(Stream &s, T &obj, int nType, int nVersion,
CSerActionUnserialize ser_action) {
::Unserialize(s, obj, nType, nVersion);
return 0;
}
如你所见,函数::SerReadWrite()被重载为三种版本。取决于最后一个参数,它将会调分别用全局函数::GetSerialize(),::Serialize()和::Unserialize()。
#include <iostream>
#include "serialize.h"
using namespace std;
class AClass {
public:
AClass(int xin) : x(xin){};
int x;
IMPLEMENT_SERIALIZE(READWRITE(this->x);)
} int main() {
CDataStream astream2;
AClass aObj(200); // 一个 x 为 200 的 AClass 类型对象
cout << "aObj=" << aObj.x >> endl;
asream2 << aObj;
AClass a2(1); // 另一个 x 为 1 的对象
astream2 >> a2 cout << "a2=" << a2.x << endl;
return 0;
}