diff options
author | John Hodge (sonata) <tpg@mutabah.net> | 2015-01-17 10:20:41 +0800 |
---|---|---|
committer | John Hodge (sonata) <tpg@mutabah.net> | 2015-01-17 10:20:41 +0800 |
commit | ba096985c2d2486592037f03e67c500d74292a83 (patch) | |
tree | 7981e81a29a0820ebd6c9afd993fa7d50692c93a /src/include/serialise.hpp | |
parent | 80e4060188913eb12ad8a774b07d3b938485a49a (diff) | |
download | mrust-ba096985c2d2486592037f03e67c500d74292a83.tar.gz |
Adding deserialise, partially working
Diffstat (limited to 'src/include/serialise.hpp')
-rw-r--r-- | src/include/serialise.hpp | 122 |
1 files changed, 115 insertions, 7 deletions
diff --git a/src/include/serialise.hpp b/src/include/serialise.hpp index be5658a8..000f8141 100644 --- a/src/include/serialise.hpp +++ b/src/include/serialise.hpp @@ -6,21 +6,27 @@ #include <vector> #include <string> #include <map> +#include <memory> class Serialiser; +class Deserialiser; #define SERIALISABLE_PROTOTYPES()\ virtual const char* serialise_tag() const override; \ - virtual void serialise(::Serialiser& s) const override -#define SERIALISE_TYPE(method_prefix, tag_str, body) \ + virtual void serialise(::Serialiser& s) const override; \ + virtual void deserialise(::Deserialiser& s) override +#define SERIALISE_TYPE(method_prefix, tag_str, body, des_body) \ const char* method_prefix serialise_tag() const { return tag_str; } \ - void method_prefix serialise(::Serialiser& s) const { body } + void method_prefix serialise(::Serialiser& s) const { body } \ + void method_prefix deserialise(::Deserialiser& s) { des_body } +#define SERIALISE_TYPE_S(class_, body) SERIALISE_TYPE(class_::, #class_, body, body) class Serialisable { public: virtual const char* serialise_tag() const = 0; virtual void serialise(Serialiser& s) const = 0; + virtual void deserialise(Deserialiser& s) = 0; }; class Serialiser @@ -31,9 +37,15 @@ protected: virtual void start_array(unsigned int size) = 0; virtual void end_array() = 0; public: + template<typename T> + inline void item(T& v) { *this << v; } + virtual Serialiser& operator<<(bool val) = 0; - virtual Serialiser& operator<<(unsigned int val) = 0; - virtual Serialiser& operator<<(const ::std::string& s) = 0; + virtual Serialiser& operator<<(uint64_t val) = 0; + virtual Serialiser& operator<<(const char* s) = 0; + Serialiser& operator<<(const ::std::string& s) { + return *this << s.c_str(); + } Serialiser& operator<<(const Serialisable& subobj); template<typename T> @@ -45,6 +57,22 @@ public: end_array(); return *this; } + template<typename T> + Serialiser& operator<<(const ::std::shared_ptr<T>& v) + { + *this << v.get(); + if(v.get()) + *this << *v; + return *this; + } + template<typename T> + Serialiser& operator<<(const ::std::unique_ptr<T>& v) + { + *this << v.get(); + if(v.get()) + *this << *v; + return *this; + } template<typename T1, typename T2> Serialiser& operator<<(const ::std::pair<T1,T2>& v) { @@ -57,13 +85,93 @@ public: template<typename T1, typename T2> Serialiser& operator<<(const ::std::map<T1,T2>& v) { - start_object("map"); + start_array(v.size()); for(const auto& ent : v) *this << ent; - end_object("map"); + end_array(); return *this; } }; +class Deserialiser +{ +protected: + virtual size_t start_array() = 0; + virtual void end_array() = 0; + + virtual ::std::string read_tag() = 0; +public: + virtual void item(bool& b) = 0; + virtual void item(uint64_t& v) = 0; + virtual void item(::std::string& s) = 0; + + virtual void start_object(const char *tag) = 0; + virtual void end_object(const char *tag) = 0; + ::std::string start_object(); + + void item(Serialisable& v); + + template<typename T> + void item(::std::vector<T>& v) { + size_t size = start_array(); + v.reserve(size); + for(size_t i = 0; i < size; i ++) { + T item; + this->item(item); + v.emplace_back( ::std::move(item) ); + } + end_array(); + } + template<typename T> + void item(::std::shared_ptr<T>& v) + { + bool present; + + item(present); + + if(present) { + v.reset(new T); + item(*v); + } + else { + v.reset(); + } + } + template<typename T> + void item(::std::unique_ptr<T>& v) + { + bool present; + + item(present); + + if(present) { + v.reset( T::from_deserialiser(*this).release() ); + } + else { + v.reset(); + } + } + template<typename T1, typename T2> + void item(::std::pair<T1,T2>& v) + { + if(2 != start_array()) + throw ::std::runtime_error("Invalid array size for pair"); + item(v.first); + item(v.second); + end_array(); + } + template<typename T1, typename T2> + void item(::std::map<T1,T2>& v) + { + size_t count = start_array(); + while(count--) { + ::std::pair<T1,T2> e; + item(e); + v.insert( e ); + } + end_array(); + } +}; + #endif |