#include <string>
#include <vector>
-#include <list>
-#include <map>
-#include <memory>
-#include <tuple>
+#include <utility>
+#include <type_traits>
namespace CKM {
// Abstract data stream buffer
// Serializable interface
class ISerializable {
public:
- /* ISerializable(){};
- * ISerializable(IStream&){}; */
virtual void Serialize(IStream &) const = 0;
+ virtual void Deserialize(IStream &) = 0;
virtual ~ISerializable() {}
};
struct Serialization {
// serialization
- // normal functions
- // ISerializable objects
- static void Serialize(IStream &stream, const ISerializable &object)
- {
- object.Serialize(stream);
- }
-
- static void Serialize(IStream &stream, const ISerializable *const object)
- {
- object->Serialize(stream);
- }
-
- // char
- static void Serialize(IStream &stream, const char value)
- {
- stream.Write(sizeof(value), &value);
- }
- static void Serialize(IStream &stream, const char *const value)
- {
- stream.Write(sizeof(*value), value);
- }
-
- // unsigned char
- static void Serialize(IStream &stream, const unsigned char value)
- {
- stream.Write(sizeof(value), &value);
- }
- static void Serialize(IStream &stream, const unsigned char *const value)
- {
- stream.Write(sizeof(*value), value);
- }
-
- // unsigned int32
- static void Serialize(IStream &stream, const uint32_t value)
- {
- stream.Write(sizeof(value), &value);
- }
- static void Serialize(IStream &stream, const uint32_t *const value)
- {
- stream.Write(sizeof(*value), value);
- }
-
- // int32
- static void Serialize(IStream &stream, const int32_t value)
- {
- stream.Write(sizeof(value), &value);
- }
- static void Serialize(IStream &stream, const int32_t *const value)
- {
- stream.Write(sizeof(*value), value);
- }
-
- // unsigned int64
- static void Serialize(IStream &stream, const uint64_t value)
+ template <typename T, std::enable_if_t<!std::is_base_of_v<ISerializable, T>, bool> = true>
+ static void Serialize(IStream &stream, const T& value)
{
stream.Write(sizeof(value), &value);
}
- static void Serialize(IStream &stream, const uint64_t *const value)
- {
- stream.Write(sizeof(*value), value);
- }
- // int64
- static void Serialize(IStream &stream, const int64_t value)
- {
- stream.Write(sizeof(value), &value);
- }
- static void Serialize(IStream &stream, const int64_t *const value)
- {
- stream.Write(sizeof(*value), value);
- }
-
- // bool
- static void Serialize(IStream &stream, const bool value)
- {
- stream.Write(sizeof(value), &value);
- }
- static void Serialize(IStream &stream, const bool *const value)
+ // ISerializable objects
+ template <typename T, std::enable_if_t<std::is_base_of_v<ISerializable, T>, bool> = true>
+ static void Serialize(IStream &stream, const T &object)
{
- stream.Write(sizeof(*value), value);
+ object.Serialize(stream);
}
// std::string
stream.Write(length * sizeof(T), str.data());
}
- template<typename T, typename R, typename A>
- static void Serialize(IStream &stream,
- const std::basic_string<T, R, A> *const str)
- {
- int length = str->size();
- stream.Write(sizeof(length), &length);
- stream.Write(length * sizeof(T), str->data());
- }
-
// STL templates
- // std::list
- template <typename T>
- static void Serialize(IStream &stream, const std::list<T> &list)
- {
- int length = list.size();
- stream.Write(sizeof(length), &length);
-
- for (typename std::list<T>::const_iterator list_iter = list.begin();
- list_iter != list.end(); list_iter++)
- Serialize(stream, *list_iter);
- }
- template <typename T>
- static void Serialize(IStream &stream, const std::list<T> *const list)
- {
- Serialize(stream, *list);
- }
-
// RawBuffer
template <typename A>
static void Serialize(IStream &stream,
stream.Write(length, vec.data());
}
- template <typename A>
- static void Serialize(IStream &stream,
- const std::vector<unsigned char, A> *const vec)
- {
- Serialize(stream, *vec);
- }
-
// std::vector
template <typename T, typename A>
static void Serialize(IStream &stream, const std::vector<T, A> &vec)
for (const auto &i : vec)
Serialize(stream, i);
}
- template <typename T, typename A>
- static void Serialize(IStream &stream, const std::vector<T, A> *const vec)
- {
- Serialize(stream, *vec);
- }
// std::pair
template <typename A, typename B>
Serialize(stream, p.first);
Serialize(stream, p.second);
}
- template <typename A, typename B>
- static void Serialize(IStream &stream, const std::pair<A, B> *const p)
- {
- Serialize(stream, *p);
- }
-
- // std::tuple non generic!
- template <typename A, typename B, typename C>
- static void Serialize(IStream &stream, const std::tuple<A, B, C> &p)
- {
- Serialize(stream, std::get<0>(p));
- Serialize(stream, std::get<1>(p));
- Serialize(stream, std::get<2>(p));
- }
- template <typename A, typename B, typename C>
- static void Serialize(IStream &stream, const std::tuple<A, B, C> *const p)
- {
- Serialize(stream, *p);
- }
-
- // std::map
- template <typename K, typename T>
- static void Serialize(IStream &stream, const std::map<K, T> &map)
- {
- int length = map.size();
- stream.Write(sizeof(length), &length);
- typename std::map<K, T>::const_iterator it;
-
- for (it = map.begin(); it != map.end(); ++it) {
- Serialize(stream, (*it).first);
- Serialize(stream, (*it).second);
- }
- }
- template <typename K, typename T>
- static void Serialize(IStream &stream, const std::map<K, T> *const map)
- {
- Serialize(stream, *map);
- }
-
- // std::unique_ptr
- template <typename T>
- static void Serialize(IStream &stream, const std::unique_ptr<T> &p)
- {
- Serialize(stream, *p);
- }
}; // struct Serialization
struct Deserialization {
// deserialization
- // normal functions
- // ISerializable objects
- // T instead of ISerializable is needed to call proper constructor
- template <typename T>
- static void Deserialize(IStream &stream, T &object)
- {
- object = T(stream);
- }
- template <typename T>
- static void Deserialize(IStream &stream, T *&object)
- {
- object = new T(stream);
- }
-
- // *& deserialization template to simplify rest of the code
- template <typename T>
- static inline void DeserializePtr(IStream &stream, T *&value)
- {
- T *tmp = new T;
- std::unique_ptr<T> ptr(tmp);
- Deserialize(stream, *tmp);
- ptr.release();
- value = tmp;
- }
-
- // char
- static void Deserialize(IStream &stream, char &value)
- {
- stream.Read(sizeof(value), &value);
- }
- static void Deserialize(IStream &stream, char *&value)
- {
- DeserializePtr(stream, value);
- }
-
- // unsigned char
- static void Deserialize(IStream &stream, unsigned char &value)
- {
- stream.Read(sizeof(value), &value);
- }
- static void Deserialize(IStream &stream, unsigned char *&value)
- {
- DeserializePtr(stream, value);
- }
-
- // unsigned int32
- static void Deserialize(IStream &stream, uint32_t &value)
- {
- stream.Read(sizeof(value), &value);
- }
- static void Deserialize(IStream &stream, uint32_t *&value)
- {
- DeserializePtr(stream, value);
- }
-
- // int32
- static void Deserialize(IStream &stream, int32_t &value)
- {
- stream.Read(sizeof(value), &value);
- }
- static void Deserialize(IStream &stream, int32_t *&value)
- {
- DeserializePtr(stream, value);
- }
-
- // unsigned int64
- static void Deserialize(IStream &stream, uint64_t &value)
- {
- stream.Read(sizeof(value), &value);
- }
- static void Deserialize(IStream &stream, uint64_t *&value)
- {
- DeserializePtr(stream, value);
- }
-
- // int64
- static void Deserialize(IStream &stream, int64_t &value)
+ template <typename T, std::enable_if_t<!std::is_base_of_v<ISerializable, T>, bool> = true>
+ static void Deserialize(IStream &stream, T &value)
{
stream.Read(sizeof(value), &value);
}
- static void Deserialize(IStream &stream, int64_t *&value)
- {
- DeserializePtr(stream, value);
- }
- // bool
- static void Deserialize(IStream &stream, bool &value)
- {
- stream.Read(sizeof(value), &value);
- }
- static void Deserialize(IStream &stream, bool *&value)
+ // ISerializable objects
+ template <typename T, std::enable_if_t<std::is_base_of_v<ISerializable, T>, bool> = true>
+ static void Deserialize(IStream &stream, T &object)
{
- DeserializePtr(stream, value);
+ object.Deserialize(stream);
}
template <typename T, typename R, typename A>
str = std::basic_string<T, R, A>(buf.data(), buf.data() + length);
}
- template <typename T, typename R, typename A>
- static void Deserialize(IStream &stream, std::basic_string<T, R, A> *&str)
- {
- int length;
- stream.Read(sizeof(length), &length);
- std::vector<T> buf(length);
- stream.Read(length * sizeof(T), buf.data());
- str = new std::basic_string<T, R, A>(buf.data(), buf.data() + length);
- }
-
// STL templates
- // std::list
- template <typename T>
- static void Deserialize(IStream &stream, std::list<T> &list)
- {
- int length;
- stream.Read(sizeof(length), &length);
-
- for (int i = 0; i < length; ++i) {
- T obj;
- Deserialize(stream, obj);
- list.push_back(std::move(obj));
- }
- }
- template <typename T>
- static void Deserialize(IStream &stream, std::list<T> *&list)
- {
- DeserializePtr(stream, list);
- }
-
// RawBuffer
template <typename A>
static void Deserialize(IStream &stream, std::vector<unsigned char, A> &vec)
stream.Read(length, vec.data());
}
- template <typename A>
- static void Deserialize(IStream &stream, std::vector<unsigned char, A> *&vec)
- {
- DeserializePtr<std::vector<unsigned char, A>>(stream, vec);
- }
-
// std::vector
template <typename T, typename A>
static void Deserialize(IStream &stream, std::vector<T, A> &vec)
vec.push_back(std::move(obj));
}
}
- template <typename T, typename A>
- static void Deserialize(IStream &stream, std::vector<T, A> *&vec)
- {
- DeserializePtr(stream, vec);
- }
// std::pair
template <typename A, typename B>
Deserialize(stream, p.first);
Deserialize(stream, p.second);
}
- template <typename A, typename B>
- static void Deserialize(IStream &stream, std::pair<A, B> *&p)
- {
- DeserializePtr(stream, p);
- }
-
- // std::tuple non generic!
- template <typename A, typename B, typename C>
- static void Deserialize(IStream &stream, std::tuple<A, B, C> &p)
- {
- Deserialize(stream, std::get<0>(p));
- Deserialize(stream, std::get<1>(p));
- Deserialize(stream, std::get<2>(p));
- }
- template <typename A, typename B, typename C>
- static void Deserialize(IStream &stream, std::tuple<A, B, C> *&p)
- {
- p = new std::tuple<A, B, C>;
- Deserialize(stream, *p);
- }
-
- // std::map
- template <typename K, typename T>
- static void Deserialize(IStream &stream, std::map<K, T> &map)
- {
- int length;
- stream.Read(sizeof(length), &length);
-
- for (int i = 0; i < length; ++i) {
- K key;
- T obj;
- Deserialize(stream, key);
- Deserialize(stream, obj);
- map[key] = std::move(obj);
- }
- }
- template <typename K, typename T>
- static void Deserialize(IStream &stream, std::map<K, T> *&map)
- {
- DeserializePtr(stream, map);
- }
}; // struct Deserialization
// generic serialization
Deserialization::Deserialize(stream, f);
Deserializer<Args...>::Deserialize(stream, args...);
}
-
- static void Deserialize(IStream &stream, First *&f, Args &... args)
- {
- First *tmp = NULL;
- Deserialization::Deserialize(stream, tmp);
- std::unique_ptr<First> ptr(tmp);
- Deserializer<Args...>::Deserialize(stream, args...);
- ptr.release();
- f = tmp;
- }
-
};
// end of recursion