summaryrefslogtreecommitdiff
path: root/src/include/serialise.hpp
diff options
context:
space:
mode:
authorJohn Hodge (sonata) <tpg@mutabah.net>2015-01-17 10:20:41 +0800
committerJohn Hodge (sonata) <tpg@mutabah.net>2015-01-17 10:20:41 +0800
commitba096985c2d2486592037f03e67c500d74292a83 (patch)
tree7981e81a29a0820ebd6c9afd993fa7d50692c93a /src/include/serialise.hpp
parent80e4060188913eb12ad8a774b07d3b938485a49a (diff)
downloadmrust-ba096985c2d2486592037f03e67c500d74292a83.tar.gz
Adding deserialise, partially working
Diffstat (limited to 'src/include/serialise.hpp')
-rw-r--r--src/include/serialise.hpp122
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