summaryrefslogtreecommitdiff
path: root/src/common/serialization.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/serialization.h')
-rw-r--r--src/common/serialization.h610
1 files changed, 610 insertions, 0 deletions
diff --git a/src/common/serialization.h b/src/common/serialization.h
new file mode 100644
index 0000000..7f0ee84
--- /dev/null
+++ b/src/common/serialization.h
@@ -0,0 +1,610 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @file serialization.h
+ * @author Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version 1.0
+ * @brief Interfaces and templates used for data serialization.
+ */
+#pragma once
+
+#include <stdint.h>
+#include <time.h>
+
+#include <string>
+#include <vector>
+#include <list>
+#include <map>
+#include <unordered_map>
+#include <set>
+#include <memory>
+
+namespace CCHECKER {
+
+namespace Common {
+
+// Abstract data stream buffer
+class IStream {
+public:
+ virtual void read(size_t num, void *bytes) = 0;
+ virtual void write(size_t num, const void *bytes) = 0;
+ virtual ~IStream() {}
+};
+
+// Serializable interface
+class ISerializable {
+public:
+ ISerializable() {}
+ ISerializable(IStream &) {}
+ virtual void Serialize(IStream &) const = 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)
+ {
+ 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);
+ }
+
+ static void Serialize(IStream &stream, const time_t value)
+ {
+ stream.write(sizeof(value), &value);
+ }
+ static void Serialize(IStream &stream, const time_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)
+ {
+ stream.write(sizeof(*value), value);
+ }
+
+ // std::string
+ template <typename T, typename R, typename A>
+ static void Serialize(IStream &stream, const std::basic_string<T, R, A> &str)
+ {
+ int length = str.size();
+ stream.write(sizeof(length), &length);
+ 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)
+ {
+ size_t length = list.size();
+ stream.write(sizeof(length), &length);
+
+ for (const auto &item : list)
+ Serialize(stream, item);
+ }
+ template <typename T>
+ static void Serialize(IStream &stream, const std::list<T> *const list)
+ {
+ Serialize(stream, *list);
+ }
+
+ template <typename T>
+ static void Serialize(IStream &stream, const std::set<T> &set)
+ {
+ auto len = set.size();
+ stream.write(sizeof(len), &len);
+
+ for (const auto &item : set)
+ Serialize(stream, item);
+ }
+ template <typename T>
+ static void Serialize(IStream &stream, const std::set<T> *const set)
+ {
+ Serialize(stream, *set);
+ }
+
+ // RawBuffer
+ template <typename A>
+ static void Serialize(IStream &stream, const std::vector<unsigned char, A> &vec)
+ {
+ int length = vec.size();
+ stream.write(sizeof(length), &length);
+ 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)
+ {
+ int length = vec.size();
+ stream.write(sizeof(length), &length);
+
+ 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>
+ static void Serialize(IStream &stream, const std::pair<A, B> &p)
+ {
+ 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::map
+ template <typename K, typename T>
+ static void Serialize(IStream &stream, const std::map<K, T> &map)
+ {
+ size_t length = map.size();
+ stream.write(sizeof(length), &length);
+
+ for (const auto &item : map) {
+ Serialize(stream, item.first);
+ Serialize(stream, item.second);
+ }
+ }
+ template <typename K, typename T>
+ static void Serialize(IStream &stream, const std::map<K, T> *const map)
+ {
+ Serialize(stream, *map);
+ }
+
+ // std::unordered_map
+ template <typename K, typename T>
+ static void Serialize(IStream &stream, const std::unordered_map<K, T> &map)
+ {
+ size_t length = map.size();
+ stream.write(sizeof(length), &length);
+
+ for (const auto &item : map) {
+ Serialize(stream, item.first);
+ Serialize(stream, item.second);
+ }
+ }
+ template <typename K, typename T>
+ static void Serialize(IStream &stream,
+ const std::unordered_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);
+ }
+
+ // std::shared_ptr
+ template <typename T>
+ static void Serialize(IStream &stream, const std::shared_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);
+ }
+
+ template <typename T>
+ static void Deserialize(IStream &stream, std::shared_ptr<T> &object)
+ {
+ object.reset(new T(stream));
+ }
+
+ // char
+ static void Deserialize(IStream &stream, char &value)
+ {
+ stream.read(sizeof(value), &value);
+ }
+ static void Deserialize(IStream &stream, char *&value)
+ {
+ value = new char;
+ stream.read(sizeof(*value), value);
+ }
+
+ // unsigned char
+ static void Deserialize(IStream &stream, unsigned char &value)
+ {
+ stream.read(sizeof(value), &value);
+ }
+ static void Deserialize(IStream &stream, unsigned char *&value)
+ {
+ value = new unsigned char;
+ stream.read(sizeof(*value), value);
+ }
+
+ // unsigned int32
+ static void Deserialize(IStream &stream, uint32_t &value)
+ {
+ stream.read(sizeof(value), &value);
+ }
+ static void Deserialize(IStream &stream, uint32_t *&value)
+ {
+ value = new uint32_t;
+ stream.read(sizeof(*value), value);
+ }
+
+ // int32
+ static void Deserialize(IStream &stream, int32_t &value)
+ {
+ stream.read(sizeof(value), &value);
+ }
+ static void Deserialize(IStream &stream, int32_t *&value)
+ {
+ value = new int32_t;
+ stream.read(sizeof(*value), value);
+ }
+
+ // unsigned int64
+ static void Deserialize(IStream &stream, uint64_t &value)
+ {
+ stream.read(sizeof(value), &value);
+ }
+ static void Deserialize(IStream &stream, uint64_t *&value)
+ {
+ value = new uint64_t;
+ stream.read(sizeof(*value), value);
+ }
+
+ // int64
+ static void Deserialize(IStream &stream, int64_t &value)
+ {
+ stream.read(sizeof(value), &value);
+ }
+ static void Deserialize(IStream &stream, int64_t *&value)
+ {
+ value = new int64_t;
+ stream.read(sizeof(*value), value);
+ }
+
+ static void Deserialize(IStream &stream, time_t &value)
+ {
+ stream.read(sizeof(value), &value);
+ }
+ static void Deserialize(IStream &stream, time_t *&value)
+ {
+ value = new time_t;
+ stream.read(sizeof(*value), value);
+ }
+
+ // bool
+ static void Deserialize(IStream &stream, bool &value)
+ {
+ stream.read(sizeof(value), &value);
+ }
+ static void Deserialize(IStream &stream, bool *&value)
+ {
+ value = new bool;
+ stream.read(sizeof(*value), value);
+ }
+
+ 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 = 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)
+ {
+ list = new std::list<T>;
+ Deserialize(stream, *list);
+ }
+
+ template <typename T>
+ static void Deserialize(IStream &stream, std::set<T> &set)
+ {
+ size_t len;
+ stream.read(sizeof(len), &len);
+
+ for (size_t i = 0; i < len; ++i) {
+ T obj;
+ Deserialize(stream, obj);
+ set.insert(std::move(obj));
+ }
+ }
+ template <typename T>
+ static void Deserialize(IStream &stream, std::set<T> *&set)
+ {
+ set = new std::set<T>;
+ Deserialize(stream, *set);
+ }
+
+ // RawBuffer
+ template <typename A>
+ static void Deserialize(IStream &stream, std::vector<unsigned char, A> &vec)
+ {
+ int length;
+ stream.read(sizeof(length), &length);
+ vec.resize(length);
+ stream.read(length, vec.data());
+ }
+
+ template <typename A>
+ static void Deserialize(IStream &stream, std::vector<unsigned char, A> *&vec)
+ {
+ vec = new std::vector<unsigned char, A>;
+ Deserialize(stream, *vec);
+ }
+
+ // std::vector
+ template <typename T, typename A>
+ static void Deserialize(IStream &stream, std::vector<T, A> &vec)
+ {
+ int length;
+ stream.read(sizeof(length), &length);
+
+ for (int i = 0; i < length; ++i) {
+ T obj;
+ Deserialize(stream, obj);
+ vec.push_back(std::move(obj));
+ }
+ }
+ template <typename T, typename A>
+ static void Deserialize(IStream &stream, std::vector<T, A> *&vec)
+ {
+ vec = new std::vector<T, A>;
+ Deserialize(stream, *vec);
+ }
+
+ // std::pair
+ template <typename A, typename B>
+ static void Deserialize(IStream &stream, std::pair<A, B> &p)
+ {
+ Deserialize(stream, p.first);
+ Deserialize(stream, p.second);
+ }
+ template <typename A, typename B>
+ static void Deserialize(IStream &stream, std::pair<A, B> *&p)
+ {
+ p = new std::pair<A, B>;
+ 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)
+ {
+ map = new std::map<K, T>;
+ Deserialize(stream, *map);
+ }
+
+ // std::unordered_map
+ template <typename K, typename T>
+ static void Deserialize(IStream &stream, std::unordered_map<K, T> &map)
+ {
+ size_t length;
+ stream.read(sizeof(length), &length);
+
+ for (size_t 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::unordered_map<K, T> *&map)
+ {
+ map = new std::map<K, T>;
+ Deserialize(stream, *map);
+ }
+}; // struct Deserialization
+
+// generic serialization
+template <typename... Args>
+struct Serializer;
+
+template <typename First, typename... Args>
+struct Serializer<First, Args...> : public Serializer<Args...> {
+ static void Serialize(IStream &stream, const First &f, const Args &... args)
+ {
+ Serialization::Serialize(stream, f);
+ Serializer<Args...>::Serialize(stream, args...);
+ }
+};
+
+// end of recursion
+template <>
+struct Serializer<> {
+ static void Serialize(IStream &)
+ {
+ return;
+ }
+};
+
+// generic deserialization
+template <typename... Args>
+struct Deserializer;
+
+template <typename First, typename... Args>
+struct Deserializer<First, Args...> : public Deserializer<Args...> {
+ static void Deserialize(IStream &stream, First &f, Args &... args)
+ {
+ Deserialization::Deserialize(stream, f);
+ Deserializer<Args...>::Deserialize(stream, args...);
+ }
+};
+
+// end of recursion
+template <>
+struct Deserializer<> {
+ static void Deserialize(IStream &)
+ {
+ return;
+ }
+};
+
+} // namespace Common
+} // namespace CCHECKER