In any project, when a function is created for serialization, another function is created for unserialization.
Serialization by contract employs a different approach: a contract with a name and data structures is declared, and then serialization and deserialization of the data are automated.
For instance, contract XYZ:
SERIALIZATION_CONTRACT(XYZ, std::vector<std::tuple<int, std::string>>, std::wstring);Then to serialize these data in std::vector<uint8_t> bytes:
std::vector<uint8_t> bytes;
XYZ({{10, "ABC1"}, {11, "ABC2"}}, L"ABC3") >> bytes;And to unserialize from std::vector<uint8_t> bytes:
std::vector<std::tuple<int, std::string>> out1;
std::wstring out2;
XYZ(out1, out2) << bytes;The serialization framework can be used in IPC to serialize and unserialize data by contract.
If only one type of data is sent from a client to a server, then the approach described above can be used.
If different types are sent, then on the server, the types need to be unserialized correspondingly.
On server, to subscribe to the contract: ON_SERIALIZATION_CONTRACT.
For instance:
SERIALIZATION_CONTRACT(ABC, std::variant<float, std::variant<int, std::string>>);
SERIALIZATION_CONTRACT(QAZ, std::string, int>);
ON_SERIALIZATION_CONTRACT(ABC)[&](const std::variant<float, std::variant<int, std::string>>& par)
{
};
ON_SERIALIZATION_CONTRACT(QAZ)[&](const std::string& par1, int par2)
{
};
When bytes are received on the server, PROCESS_SERIALIZATION_CONTRACT(bytes) should be called,
and the unserialized data will be dispatched to one of the callbacks ON_SERIALIZATION_CONTRACT.
SerializationContract.h contains implementation of SERIALIZATION_CONTRACT macro.
SerializationContractData.h contains implementation for serialization, and unserialization for most STL data structures.
Serialization and unserialization of a custom struct Data can be implemented as shown in main.cpp.
The framework can be tested on https://wandbox.org/permlink/s9uWjs37WfZIEVUl