以下是一个带有入侵性的序列化实现方法,尚还未加入支持STL容器。
namespace persistent
{
//bool理论上使用一个bit就可以表示,但是实际还是使用1个字节,因为这是内存操作的最小单位
//这两个值可以是任意值,只要不相同即可,只是用于校验
const long true_pattern = 0xF00DF00D;
const long flase_pattern = 0xBAD0BAD0;
class serializer
{
public:
serializer(std::ostream& os)
: _ostream(os){}
void put_char(char value)
{ return put_basic_t(value); }
void put_wchar(wchar_t value)
{ return put_basic_t(value); }
void put_bool(bool value)
{ return put_basic_t(value); }
void put_short(short value)
{ return put_basic_t(value); }
void put_long(long value)
{ return put_basic_t(value); }
void put_llong(__int64 value)
{ return put_basic_t<__int64>(value); }
void put_double(double value)
{ return put_basic_t(value); }
void put_string(const std::string& value)
{ return put_string_t(value); }
void put_wstring(const std::wstring& value)
{ return put_string_t(value); }
void put_raw(size_t length, const byte* buff)
{
put_long(static_cast(length));
_ostream.write(reinterpret_cast(buff),
static_cast(length));
if (_ostream.bad())
throw std::exception("stream_write");
}
void put_raw(const util::raw_buffer& buff)
{
_ostream.write(reinterpret_cast(buff.operator const byte*()), static_cast(buff.size()));
if (_ostream.bad())
throw std::exception("stream_write");
}
protected:
template
void put_basic_t(T value)
{
_ostream.write(reinterpret_cast(&value), sizeof(T));
if (_ostream.bad())
throw std::exception("stream_write");
}
template<>
void put_basic_t(bool value)
{
long pattern = value ? true_pattern : false_pattern;
put_long(pattern);
}
template
void put_string_t(const T& value)
{
long len = static_cast(value.length() * sizeof(T::value_type));
put_long(len);
_ostream.write(reinterpret_cast(value.data()), len);
if (_ostream.bad())
throw std::exception("stream_write");
}
private:
std::ostream& _ostream;
serializer& operator =(const serializer&);
};
class deserializer
{
public:
deserializer(std::istream& is)
: _istream(is){}
char get_char()
{ return get_basic_t(); }
wchar_t get_wchar()
{ return get_basic_t(); }
bool get_bool()
{ return get_basic_t(); }
short get_short()
{ return get_basic_t(); }
long get_long()
{ return get_basic_t(); }
__int64 get_llong()
{ return get_basic_t<__int64>(); }
double get_double()
{ return get_basic_t(); }
std::string get_string()
{ return get_string_t(); }
std::string get_wstring()
{ return get_string_t(); }
util::raw_buffer get_raw()
{
size_t length = static_cast(get_long());
if (_istream.eof())
throw std::exception("unexpected_eof");
util::raw_buffer value(length);
_istream.read(value.force_to(), static_cast(length));
if (_istream.bad())
throw std::exception("stream_read");
return value;
}
void get_raw(util::raw_buffer& buff)
{
if (_istream.eof())
throw std::exception("unexpected_eof");
_istream.read(buff.force_to(), static_cast(buff.size()));
if (_istream.bad())
throw std::exception("stream_read");
}
protected:
template
T get_basic_t()
{
if (_istream.eof())
throw std::exception("unexpected_eof");
T value;
_istream.read(reinterpret_cast(&value), sizeof(T));
if (_istream.bad())
throw std::exception("stream_read");
return value;
}
template<>
bool get_basic_t()
{
long value = get_long();
if (value == true_pattern)
return true;
else if (value == false_pattern)
return false;
else
throw std::exception("data_corrupt");
}
template
T get_string_t()
{
long len = get_long();
T value;
value.resize(len / sizeof(T::value_type));
if (_istream.eof())
throw std::exception("unexpected_eof");
_istream.read(reinterpret_cast(&value[0]), len);
if (_istream.bad())
throw std::exception("stream_read");
return value;
}
private:
std::istream& _istream;
deserializer& operator =(const deserializer&);
};
//接口
class serializable
{
public:
virtual void serialize(serializer& out) const = 0;
virtual void deserialize(deserializer& in) = 0;
};
}
struct mydata : public serializable
{
char _c;
wchar_t _w;
bool _b;
short _s;
std::string _str;
public:
virtual void serialize(serializer& out) const
{
out.put_char(_c);
out.put_wchar(_w);
out.put_bool(_b);
out.put_short(_s);
out.put_string(_str);
}
virtual void deserialize(deserializer& in)
{
_c = in.get_char();
_w = in.get_wchar();
_b = in.get_bool();
_s = in.get_short();
_str = in.get_string();
}
bool operator ==(const mydata& r)
{
return _c == r._c
&& _w == r._w
&& _b == r._b
&& _s == r._s
&& _str == r._str;
}
};
//测试代码
void test()
{
mydata data;
data._c = 'X';
data._w = L'q';
data._b = false;
data._s = 12;
data._str = "hello";
//序列化
std::stringstream ssm;
serializer s(ssm);
data.serialize(s);
//反序列化
mydata data2;
deserializer ds(ssm);
data2.deserialize(ds);
assert(data == data2);
}