Last active
December 10, 2017 08:57
-
-
Save jngbng/94ccda4c5a412917392c49915b23a224 to your computer and use it in GitHub Desktop.
bitcoin serialize code snippet
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// bitcoin core (0d7e0a328) serialize/deserialize. | |
// Stream s; | |
// CBlock block; | |
// s >> block; | |
// internal above code. | |
// Step1: operator overloading | |
// streams.h | |
template<typename Stream> | |
class OverrideStream // CAutoFile, etc ... | |
{ | |
OverrideStream<Stream>& operator<<(const T& obj) | |
{ | |
// Serialize to this stream | |
::Serialize(*this, obj); | |
return (*this); | |
} | |
template<typename T> | |
CDataStream& operator>>(T& obj) | |
{ | |
// Unserialize from this stream | |
::Unserialize(*this, obj); | |
return (*this); | |
} | |
}; | |
// Step2. Serialize function. | |
// serialize.h | |
// primitive types | |
template<typename Stream> inline void Serialize(Stream& s, bool a) { | |
char f=a; | |
ser_writedata8(s, f); | |
// => s.write((char*)&obj, 1); | |
} | |
// container types | |
template<typename Stream, typename T, typename A> | |
inline void Serialize(Stream& os, const std::vector<T, A>& v) | |
{ | |
// T() for method overloading to optimize | |
Serialize_impl(os, v, T()); | |
} | |
template<typename Stream, typename T, typename A, typename V> | |
void Serialize_impl(Stream& os, const std::vector<T, A>& v, const V&) | |
{ | |
WriteCompactSize(os, v.size()); | |
for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi) | |
::Serialize(os, (*vi)); | |
} | |
template<typename Stream, typename T, typename A> | |
void Serialize_impl(Stream& os, const std::vector<T, A>& v, const unsigned char&) | |
{ | |
WriteCompactSize(os, v.size()); | |
if (!v.empty()) | |
os.write((char*)v.data(), v.size() * sizeof(T)); | |
} | |
// user class | |
template<typename Stream, typename T> | |
inline void Serialize(Stream& os, const T& a) | |
{ | |
a.Serialize(os); | |
} | |
// block.h | |
class CBlockHeader | |
{ | |
ADD_SERIALIZE_METHODS; | |
// => | |
// template<typename Stream> | |
// void Serialize(Stream& s) const { | |
// NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize()); | |
// } | |
// template<typename Stream> | |
// void Unserialize(Stream& s) { | |
// SerializationOp(s, CSerActionUnserialize()); | |
// } | |
template <typename Stream, typename Operation> // for duck-typing | |
inline void SerializationOp(Stream& s, Operation ser_action) { | |
READWRITE(this->nVersion); | |
// => ::SerReadWrite(s, this->nVersion, ser_action); | |
if (ser_action.ForRead()) { | |
// for custom operation: vector resize or COMPACTSIZE | |
} | |
} | |
} | |
/** | |
* Support for ADD_SERIALIZE_METHODS and READWRITE macro | |
*/ | |
struct CSerActionSerialize | |
{ | |
constexpr bool ForRead() const { return false; } | |
}; | |
struct CSerActionUnserialize | |
{ | |
constexpr bool ForRead() const { return true; } | |
}; | |
// for read | |
template<typename Stream, typename T> | |
inline void SerReadWrite(Stream& s, const T& obj, CSerActionSerialize ser_action) | |
{ | |
::Serialize(s, obj); | |
} | |
template<typename Stream, typename T> | |
inline void SerReadWrite(Stream& s, T& obj, CSerActionUnserialize ser_action) | |
{ | |
::Unserialize(s, obj); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment