Commit 45fa5f22 authored by Tomáš Jakubec's avatar Tomáš Jakubec
Browse files

rework of console logger

compatibility with MSVC
binary serializers
parent abc73b9a
Loading
Loading
Loading
Loading
+121 −0
Original line number Diff line number Diff line
#ifndef BINARYSERIALIZER_H
#define BINARYSERIALIZER_H
#include <vector>
#include <cstdint>

// TODO možná změnit jméno
/**
 * @brief The BinarySerializer class holds binary array and is able to
 * store binary data as well as serialize and deserialize data
 */
class BinarySerializer {
public:
    using Byte = uint8_t;
    using ByteContainer = std::vector<Byte>;
    using ByteContainerIterator = ByteContainer::const_iterator;


    template<typename T>
    static void addNext(std::vector<Byte>& binaryDataContainer, const T& data);

    template <typename T>
    static void readNext(std::vector<Byte>::const_iterator& binaryDataIterator, T& data);

    template <typename T>
    static T readNext(std::vector<Byte>::const_iterator& binaryDataIterator) {
        T data;
        readNext(binaryDataIterator, data);
        return data;
    }

    template<typename T>
    void maddNext(const T& data) {
        addNext(mData, data);
    }

    template <typename T>
    void mreadNext(T& data) {
        readNext(mDataIterator, data);
    }

    template <typename T>
    T mreadNext() {
        return readNext<T>(mDataIterator);
    }

    void resetIterator() {
        mDataIterator = mData.cbegin();
    }
//private:
    ByteContainer mData;
    ByteContainerIterator mDataIterator;
};

#include "Serializers/SerializeCustom.h"
#include "Serializers/SerializeSimple.h"
#include "Serializers/SerializeIterable.h"
#include "Serializers/SerializeTuple.h"
#include <GTMesh/Utils/ClassSelector.h>

namespace Impl {
template<typename VarType, typename Serializer, typename = void>
struct IsSerializableBy : public std::false_type
{};

template<typename VarType, typename Serializer>
struct IsSerializableBy<VarType,
                        Serializer,
                        decltype(Serializer::serialize(std::declval<std::vector<unsigned char> &>(),
                                                    std::declval<const VarType &>()))>
    : public std::true_type
{};

template<typename VarType, typename Serializer, typename = void>
struct IsDeserializableBy : public std::false_type
{};

template<typename VarType, typename Serializer>
struct IsDeserializableBy<
    VarType,
    Serializer,
    decltype(Serializer::deserialize(std::declval<std::vector<unsigned char>::const_iterator &>(),
                                  std::declval<const VarType &>()))> : public std::true_type
{};

} // Impl namespace

template<typename VarType, typename Serializer>
struct IsSerializableBy: public Impl::IsSerializableBy<VarType, Serializer>
{};

template<typename VarType, typename... Serializers>
using SelectSerializer = ClassSelector<VarType, IsSerializableBy, Serializers...>;

template<typename T>
void BinarySerializer::addNext(std::vector<BinarySerializer::Byte> &binaryDataContainer, const T &data)
{
    SelectSerializer<T, SerializeCustom, SerializeSimple, SerializeIterable, SerializeTuple>::
        SelectedClass::serialize(binaryDataContainer, data);
}

template<typename VarType, typename Serializer>
struct IsDeserializableBy: public Impl::IsDeserializableBy<VarType, Serializer>
{};

template<typename VarType, typename... Serializers>
using SelectDeserializer = ClassSelector<VarType, IsDeserializableBy, Serializers...>;

template<typename T>
void BinarySerializer::readNext(std::vector<Byte>::const_iterator& binaryDataIterator, T& data)
{
    SelectDeserializer<T,
                       SerializeCustom,
                       SerializeSimple,
                       DeserializeAsociativeMap,
                       DeserializeAsociativeSet,
                       SerializeIterable,
                       SerializeTuple>::SelectedClass::deserialize(binaryDataIterator, data);
}

#endif // BINARYSERIALIZER_H
+30 −0
Original line number Diff line number Diff line
#ifndef SERIALIZECUSTOM_H
#define SERIALIZECUSTOM_H
#include "../BinarySerializer.h"
#include <GTMesh/Traits/CustomTypeTraits.h>

struct SerializeCustom {

    template <typename T>
    using IsBitviseSerializable = Impl::void_t<decltype(BinarySerialize(std::declval<BinarySerializer::ByteContainer&>(), std::declval<const T&>()))>;


    template <typename T>
    using IsBitviseDeserializable = Impl::void_t<decltype(BinaryDeserialize(std::declval<BinarySerializer::ByteContainerIterator&>(), std::declval<const T&>()))>;


    template <typename T>
    static
        IsBitviseSerializable<T>
        serialize(BinarySerializer::ByteContainer& dataContainer, const T& data, ...) {
        BinarySerialize(dataContainer, data);
    }

    template <typename T>
    static
        IsBitviseDeserializable<T>
        deserialize(BinarySerializer::ByteContainerIterator& dataIterator, T& data, ...) {
        BinaryDeserialize(dataIterator, data);
    }
};
#endif // SERIALIZECUSTOM_H
+64 −0
Original line number Diff line number Diff line
#ifndef SERIALIZEITERABLE_H
#define SERIALIZEITERABLE_H
#include <GTMesh/Traits/CustomTypeTraits.h>
#include "../BinarySerializer.h"

struct SerializeIterable {
    template <typename T, typename ..., std::enable_if_t<IsIterable<T>::value, bool> = true>
    static void serialize(std::vector<unsigned char>& dataContainer, const T& data){
        BinarySerializer::addNext(dataContainer, data.size());
        for (const auto& val : data) {
            BinarySerializer::addNext(dataContainer, val);
        }
    }



    template <typename T, typename ..., std::enable_if_t<IsIterable<T>::value, bool> = true>
    static void deserialize(std::vector<unsigned char>::const_iterator& dataIterator, T& data){

        decltype(data.size()) size = BinarySerializer::readNext<decltype(data.size())>(dataIterator);

        if (data.size() != size) {
            data.resize(size);
        }

        for (auto & val : data) {
            BinarySerializer::readNext(dataIterator, val);
        }
    }

    // TODO think how to deserialize lists and maps
};

struct DeserializeAsociativeMap {
    template <typename T, typename ..., std::enable_if_t<IsIterable<T>::value, bool> = true>
    static Impl::void_t<typename T::key_type,typename T::mapped_type>
        deserialize(std::vector<unsigned char>::const_iterator& dataIterator, T& data){

        decltype(data.size()) size = BinarySerializer::readNext<decltype(data.size())>(dataIterator);

        for (decltype(data.size()) i = 0; i < size; i ++) {
            std::pair<typename T::key_type,typename T::mapped_type> val;
            BinarySerializer::readNext(dataIterator, val);
            data.insert(val);
        }
    }
};

struct DeserializeAsociativeSet {
    template <typename T, typename ..., std::enable_if_t<IsIterable<T>::value, bool> = true>
    static Impl::void_t<typename T::key_type>
    deserialize(std::vector<unsigned char>::const_iterator& dataIterator, T& data){

        decltype(data.size()) size = BinarySerializer::readNext<decltype(data.size())>(dataIterator);

        for (decltype(data.size()) i = 0; i < size; i ++) {
            typename T::key_type val;
            BinarySerializer::readNext(dataIterator, val);
            data.insert(val);
        }
    }
};

#endif // SERIALIZEITERABLE_H
+50 −0
Original line number Diff line number Diff line
#ifndef SERIALIZESIMPLE_H
#define SERIALIZESIMPLE_H
#include <type_traits>
#include <vector>
#include <stdexcept>

namespace Impl {
template<typename T>
inline constexpr bool IsSimpleSerializable_v = !std::is_class<T>::value;
}

/**
 * @brief The SerializeSimple struct serializes simple types as double or int.
 */
struct SerializeSimple {

    template <typename T, typename ..., std::enable_if_t<Impl::IsSimpleSerializable_v<T>, bool> = true>
    static void serialize(std::vector<unsigned char>& dataContainer, const T& data){
        const unsigned char* pData = reinterpret_cast<const unsigned char*>(&data);
        dataContainer.insert(dataContainer.end(), pData, pData + sizeof (T));
    }

    template <typename T, typename ..., std::enable_if_t<Impl::IsSimpleSerializable_v<T>, bool> = true>
    static void deserialize(std::vector<unsigned char>::const_iterator& dataIterator, T& data){
        unsigned char *const pData = reinterpret_cast<unsigned char*>(&data);
        for (size_t i = 0; i < sizeof (T); i++) {
            pData[i] = *dataIterator;
            dataIterator++;
        }
    }

    static void serialize(std::vector<unsigned char>& dataContainer, const bool data){
        dataContainer.push_back(data ? 1 : 0);
    }

    template <typename T, typename ..., std::enable_if_t<Impl::IsSimpleSerializable_v<T>, bool> = true>
    static void deserialize(std::vector<unsigned char>::const_iterator& dataIterator, bool& data){
        switch (*dataIterator) {
        case 1: data = true;
            break;
        case 0: data = false;
            break;
        default:
            throw std::runtime_error(std::to_string((int)*dataIterator & 0xff) + ": invalid data input for bool 1/0 expected");
        }
    }

};

#endif // SERIALIZESIMPLE_H
+53 −0
Original line number Diff line number Diff line
#ifndef SERIALIZETUPLE_H
#define SERIALIZETUPLE_H
#include "../BinarySerializer.h"
#include <GTMesh/Utils/ConstexprFor.h>
#include <tuple>


struct SerializeTuple {
    /**
     * @brief Python-like print of dictionary pair of key and value.
     */
    template<typename T1, typename T2>
    static void serialize(BinarySerializer::ByteContainer& dataContainer, const std::pair<T1,T2>& data, ...)
    {
        BinarySerializer::addNext(dataContainer, data.first);
        BinarySerializer::addNext(dataContainer, data.second);
    }

    template<typename T1, typename T2>
    static void deserialize(BinarySerializer::ByteContainerIterator& dataIterator, std::pair<T1,T2>& data, ...)
    {
        BinarySerializer::readNext(dataIterator, data.first);
        BinarySerializer::readNext(dataIterator, data.second);
    }


    struct SerializeTupleHelper{
        template <unsigned int Index, typename ... TupleTypes>
        static void exec(BinarySerializer::ByteContainer& dataContainer, const std::tuple<TupleTypes...>& data) {
            BinarySerializer::addNext(dataContainer, std::get<Index>(data));
        }
    };

    template<typename ... TupleTypes>
    static void serialize(BinarySerializer::ByteContainer& dataContainer, const std::tuple<TupleTypes...>& data, ...)
    {
        constexprFor<SerializeTupleHelper, sizeof... (TupleTypes)>(dataContainer, data);
    }

    struct DeserializeTupleHelper{
        template <unsigned int Index, typename ... TupleTypes>
        static void exec(BinarySerializer::ByteContainerIterator& dataIterator, std::tuple<TupleTypes...>& data) {
            BinarySerializer::readNext(dataIterator, std::get<Index>(data));
        }
    };

    template<typename ... TupleTypes>
    static void deserialize(BinarySerializer::ByteContainerIterator& dataIterator, std::tuple<TupleTypes...>& data, ...)
    {
        constexprFor<DeserializeTupleHelper, sizeof... (TupleTypes)>(dataIterator, data);
    }
};
#endif // SERIALIZETUPLE_H
Loading