Реализовать фреймворк для бинарной сериализации и десериализации произвольных структур данных.
Основа фреймворка приведена ниже:
// serialize.h
#pragma once
#include <iostream>
#include <iterator>
#include <algorithm>
template <typename T>
struct serializer {
static void apply(const T &obj, std::ostream &os) {
const uint8_t *ptr = reinterpret_cast<const uint8_t *>(&obj);
std::ostream_iterator<uint8_t> oi(os);
std::copy(ptr, ptr + sizeof(T), oi);
}
};
///////////////////////////////////////////////////////////////////////
template <typename T>
struct deserializer {
static void apply(T &val, std::istream &is) {
uint8_t *ptr = reinterpret_cast<uint8_t*>(&val);
std::istream_iterator<uint8_t> ii(is);
std::copy_n(ii, sizeof(T), ptr);
}
};
///////////////////////////////////////////////////////////////////////
template <typename T>
void serialize(const T &obj, std::ostream &os)
{
serializer<T>::apply(obj, os);
}
template <typename T>
void deserialize(T &obj, std::istream &is)
{
return deserializer<T>::apply(obj, is);
}
Данный код позволяет сериализовывать и десериализовывать любые примитивные объекты, как показано в примере:
// test_serialize.cpp
#include <fstream>
#include <iostream>
#include "serialize.h"
using namespace std;
int main()
{
ofstream ofs("test.ser", ofstream::out | ofstream::binary);
char hello[7] = "hello!";
int boo[3] = { 1, 2, 3 };
serialize(hello, ofs);
serialize(boo, ofs);
char hello2[7];
int boo2[3];
ofs.close();
ifstream ifs("test.ser", ifstream::in | ofstream::binary);
ifs >> noskipws;
deserialize(hello2, ifs);
deserialize(boo2, ifs);
if (equal(hello, hello + 7, hello2))
cout << "Hello OK!" << endl;
if (equal(boo, boo + 3, boo2))
cout << "Boo OK!" << endl;
return 0;
}
Требуется расширить поведение serialize
и deserialize
, чтобы они поддерживали сериализацию и десериализацию стандартных классов и контейнеров:
std::string
.vector<T>
для любого сериализуемого типа T
.map<K, V>
для любых сериализуемых типов K
, V
.