一个简单的序列化实现

以下是一个带有入侵性的序列化实现方法,尚还未加入支持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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值