utils: add serialzation capability 87/151087/3
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Tue, 19 Sep 2017 10:26:56 +0000 (13:26 +0300)
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>
Wed, 20 Sep 2017 14:29:43 +0000 (17:29 +0300)
Change-Id: I6c2fe597a4cde4bda834e7a99dda598c042fe33b
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
src/utils/serializer/for_each_in_tuple.h [new file with mode: 0644]
src/utils/serializer/serialization.h [new file with mode: 0644]

diff --git a/src/utils/serializer/for_each_in_tuple.h b/src/utils/serializer/for_each_in_tuple.h
new file mode 100644 (file)
index 0000000..aecb8a9
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef FOR_EACH_IN_TUPLE_H
+#define FOR_EACH_IN_TUPLE_H
+
+
+#include <tuple>
+
+
+namespace detail
+{
+    template<int... Is>
+    struct seq { };
+
+    template<int N, int... Is>
+    struct gen_seq : gen_seq<N - 1, N - 1, Is...> { };
+
+    template<int... Is>
+    struct gen_seq<0, Is...> : seq<Is...> { };
+
+    template<typename T, typename F, int... Is>
+    void for_each(T&& t, F &f, seq<Is...>)
+    {
+        auto l = { (f(std::get<Is>(t)), 0)... };
+        (void)l;
+    }
+}
+
+template<typename... Ts, typename F>
+void for_each_in_tuple(std::tuple<Ts...> &t, F &f)
+{
+    detail::for_each(t, f, detail::gen_seq<sizeof...(Ts)>());
+}
+
+template<typename... Ts, typename F>
+void for_each_in_tuple(const std::tuple<Ts...> &t, F &f)
+{
+    detail::for_each(t, f, detail::gen_seq<sizeof...(Ts)>());
+}
+
+
+#endif // FOR_EACH_IN_TUPLE_H
diff --git a/src/utils/serializer/serialization.h b/src/utils/serializer/serialization.h
new file mode 100644 (file)
index 0000000..7aec146
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *      Vyacheslav Cherkashin <v.cherkashin@samsung.com>
+ *
+ * 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.
+ *
+ * Contributors:
+ * - Samsung RnD Institute Russia
+ *
+ */
+
+#ifndef SERIALIZATION_H
+#define SERIALIZATION_H
+
+
+#include <tuple>
+#include "for_each_in_tuple.h"
+
+
+namespace Serialization {
+namespace priv {
+
+struct FunctorSerialize
+{
+    FunctorSerialize(std::string &data) :
+        data_(data)
+    {
+        data_.resize(0);
+    }
+
+    template<typename T>
+    void operator () (const T& t)
+    {
+        static_assert(std::is_pod<T>::value, "Type is not support");
+
+        const char* ptr = reinterpret_cast<const char *>(&t);
+        std::copy(ptr, ptr + sizeof(T), std::back_inserter(data_));
+    }
+
+    void operator () (const std::string &str)
+    {
+        // pack size
+        size_t size = str.size();
+        operator () (size);
+
+        // pack data
+        std::copy(str.begin(), str.end(), std::back_inserter(data_));
+    }
+
+private:
+    std::string &data_;
+};
+
+
+struct FunctorDeserialize
+{
+    FunctorDeserialize(const std::string &data) :
+        data_(data) {}
+
+    template<typename T>
+    void operator () (T& t)
+    {
+        static_assert(std::is_pod<T>::value, "Type is not support");
+
+        if (data_.size() - pos_ < sizeof(T))
+            throw std::runtime_error("Cannot deserialize");
+
+        char* ptr = reinterpret_cast<char *>(&t);
+        std::copy(&data_[pos_], &data_[pos_ + sizeof(T)], ptr);
+        pos_ += sizeof(T);
+    }
+
+    void operator () (std::string &str)
+    {
+        // unpack size
+        size_t size;
+        operator () (size);
+
+        // unpack data
+        if (data_.size() - pos_ < size)
+            throw std::runtime_error("Cannot deserialize string");
+
+        str.resize(size);
+        std::copy(&data_[pos_], &data_[pos_ + size], &str[0]);
+        pos_ += size;
+    }
+
+    bool is_end()
+    {
+        return data_.size() == pos_;
+    }
+
+private:
+    size_t pos_ = 0;
+    const std::string &data_;
+};
+
+} // namespace priv
+
+
+
+/*
+ * Note:
+ *      We use std::string like binary array
+ */
+
+template<typename... Ts>
+void tuple_to_string(const std::tuple<Ts...> &tup, std::string &out)
+{
+    priv::FunctorSerialize f_serialize(out);
+    for_each_in_tuple(tup, f_serialize);
+}
+
+template<typename... Ts>
+void tuple_from_string(std::tuple<Ts...> &tup, const std::string &in)
+{
+    priv::FunctorDeserialize f_deserialize(in);
+    for_each_in_tuple(tup, f_deserialize);
+
+    if (!f_deserialize.is_end())
+        throw std::runtime_error("Not expected data exist");
+}
+
+} // namespace Serialization
+
+
+#endif // SERIALIZATION_H