一个简单的序列化实现

来源:互联网 发布:ps软件源码下载 编辑:程序博客网 时间:2024/06/08 14:57

以下是一个带有入侵性的序列化实现方法,尚还未加入支持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);}
0 0
原创粉丝点击