Unify function names in TupleConverter

master
Pawel Kurowski 2020-07-18 23:34:11 +02:00
parent 2e28901b32
commit 8aaa98cb6e
3 changed files with 56 additions and 53 deletions

View File

@ -285,9 +285,9 @@ namespace FSecure
/// @brief Class providing simple way of generating ByteConverter of custom types by treating them as tuple. /// @brief Class providing simple way of generating ByteConverter of custom types by treating them as tuple.
/// ByteConverter can use this functionality by inheriting from TupleConverter and providing /// ByteConverter can use this functionality by inheriting from TupleConverter and providing
/// public static std::tuple<...> TupleTransform(T const&) method. /// public static std::tuple<...> Convert(T const&) method.
/// Use Utils::MakeConversionTuple to create efficient tuple of value or references to members. /// Use Utils::MakeConversionTuple to create efficient tuple of value or references to members.
/// ByteVector can declare its own versions of To/Size/From methods if it needs dedicated logic to serialize type. /// ByteVector can declare its own versions of To/From/Size methods if it needs dedicated logic to serialize type.
/// @tparam T Type for serialization. /// @tparam T Type for serialization.
template <typename T> template <typename T>
struct TupleConverter struct TupleConverter
@ -314,65 +314,32 @@ namespace FSecure
}; };
public: public:
/// @brief Type of helper tuple returned by ByteConverter<C>::TupleTransform. /// @brief Type returned by ByteConverter<C>::Convert.
/// @note This type will be deduced late in instantiation procedure. /// @note This type will be deduced late in instantiation procedure.
/// @tparam C Type To be serialized. /// @tparam C Type To be serialized.
template <typename C> template <typename C>
using TupleTransformType = decltype(ByteConverter<C>::TupleTransform(std::declval<C>())); using ConvertType = decltype(ByteConverter<C>::Convert(std::declval<C>()));
// MSVC is using late deduction of default template parameter type, and only if they are used. /// @brief Use it to convert raw data into tuple.
// This allows definition of constexpr version of Size function using SFINAE. /// Allows splitting deserialization into two phases.
// There are proposals implement same delay in clang, but it is not available yet, or possibly will never be. /// 1. Retrieve data as tuple. ByteView internal pointer will be correctly moved in the process.
#if defined (__clang__) /// 2. Create dedicated logic of transforming tuple into desired type.
/// @brief Default implementation of Size method. /// @param bv. Buffer with serialized data.
/// @param obj Object for serialization. /// @return tuple of retrieved data for type construction.
/// @return size_t. Number of bytes used after serialization. static auto Convert(ByteView& bv)
static size_t Size([[maybe_unused]] T const& obj)
{ {
if constexpr (Utils::Apply<IsSizeConstexpr, TupleTransformType<T>>::value) return bv.Read<ConvertType<T>>();
{
return Utils::Apply<GetConstexprSize, TupleTransformType<T>>::value;
}
else
{
return ByteVector::Size(ByteConverter<T>::TupleTransform(obj));
}
}
#else
/// @brief Default implementation of Size method with compile time evaluation.
/// @return size_t. Number of bytes used after serialization.
template <typename C = TupleTransformType<T>, std::enable_if_t<Utils::Apply<IsSizeConstexpr, C>::value, int> = 0>
static constexpr size_t Size()
{
return Utils::Apply<GetConstexprSize, C>::value;
} }
/// @brief Default implementation of Size method. // From this point forward will be implemented ByteConverter standard interface methods.
/// @param obj Object for serialization.
/// @return size_t. Number of bytes used after serialization.
template <typename C = TupleTransformType<T>, std::enable_if_t<!Utils::Apply<IsSizeConstexpr, C>::value, int> = 0>
static size_t Size(T const& obj)
{
return ByteVector::Size(ByteConverter<T>::TupleTransform(obj));
}
#endif
/// @brief Default implementation of To method. /// @brief Default implementation of To method.
/// Serializes data treating it as tuple generated by TupleTransform. /// Serializes data treating it as tuple generated by Convert.
/// @param obj Object for serialization. /// @param obj Object for serialization.
/// @param bv output ByteVector with already allocated memory for data. /// @param bv output ByteVector with already allocated memory for data.
static void To(T const& obj, ByteVector& bv) static void To(T const& obj, ByteVector& bv)
{ {
bv.Store(ByteConverter<T>::TupleTransform(obj)); bv.Store(ByteConverter<T>::Convert(obj));
}
/// @brief Use it to read from ByteView to tuple of types deduced from TupleTransform.
/// This is a helper method used to create dedicated logic of type reading after all data was retrieved form view as tuple.
/// @param bv. Buffer with serialized data.
/// @return tuple of retrieved data for type construction.
static auto ReadTuple(ByteView& bv)
{
return bv.Read<TupleTransformType<T>>();
} }
/// @brief Default implementation of From method. /// @brief Default implementation of From method.
@ -383,8 +350,44 @@ namespace FSecure
/// @return constructed type. /// @return constructed type.
static T From(ByteView& bv) static T From(ByteView& bv)
{ {
auto tpl = ReadTuple(bv); return std::apply(Utils::Construction::Braces<T>{}, Convert(bv));
return std::apply(Utils::Construction::Braces<T>{}, std::move(tpl));
} }
// MSVC is using late deduction of default template parameter type, and only if they are used.
// This allows definition of constexpr version of Size function using SFINAE.
// There are proposals to implement same delay in clang, but it is not available yet, or possibly will never be.
#if defined (__clang__)
/// @brief Default implementation of Size method.
/// @param obj Object for serialization.
/// @return size_t. Number of bytes used after serialization.
static size_t Size([[maybe_unused]] T const& obj)
{
if constexpr (Utils::Apply<IsSizeConstexpr, ConvertType<T>>::value)
{
return Utils::Apply<GetConstexprSize, ConvertType<T>>::value;
}
else
{
return ByteVector::Size(ByteConverter<T>::Convert(obj));
}
}
#else
/// @brief Default implementation of Size method with compile time evaluation.
/// @return size_t. Number of bytes used after serialization.
template <typename C = ConvertType<T>, std::enable_if_t<Utils::Apply<IsSizeConstexpr, C>::value, int> = 0>
static constexpr size_t Size()
{
return Utils::Apply<GetConstexprSize, C>::value;
}
/// @brief Default implementation of Size method.
/// @param obj Object for serialization.
/// @return size_t. Number of bytes used after serialization.
template <typename C = ConvertType<T>, std::enable_if_t<!Utils::Apply<IsSizeConstexpr, C>::value, int> = 0>
static size_t Size(T const& obj)
{
return ByteVector::Size(ByteConverter<T>::Convert(obj));
}
#endif
}; };
} }

View File

@ -40,7 +40,7 @@ namespace FSecure
{ {
/// Serialization of RTL_OSVERSIONINFOEXW type to/from ByteVector. /// Serialization of RTL_OSVERSIONINFOEXW type to/from ByteVector.
/// @param obj. Object to be serialized. /// @param obj. Object to be serialized.
static auto TupleTransform(RTL_OSVERSIONINFOEXW const& obj) static auto Convert(RTL_OSVERSIONINFOEXW const& obj)
{ {
return Utils::MakeConversionTuple( return Utils::MakeConversionTuple(
obj.dwOSVersionInfoSize, obj.dwOSVersionInfoSize,
@ -81,7 +81,7 @@ namespace FSecure
{ {
/// Serialization of HostInfo type to/from ByteVector. /// Serialization of HostInfo type to/from ByteVector.
/// @param obj. Object to be serialized. /// @param obj. Object to be serialized.
static auto TupleTransform(HostInfo const& obj) static auto Convert(HostInfo const& obj)
{ {
return Utils::MakeConversionTuple(obj.m_ComputerName, obj.m_UserName, obj.m_Domain, obj.m_OsVersionInfo, obj.m_ProcessId, obj.m_IsElevated); return Utils::MakeConversionTuple(obj.m_ComputerName, obj.m_UserName, obj.m_Domain, obj.m_OsVersionInfo, obj.m_ProcessId, obj.m_IsElevated);
} }

View File

@ -80,7 +80,7 @@ namespace FSecure
template <> template <>
struct ByteConverter<C3::RouteId> : TupleConverter<C3::RouteId> struct ByteConverter<C3::RouteId> : TupleConverter<C3::RouteId>
{ {
static auto TupleTransform(C3::RouteId const& obj) static auto Convert(C3::RouteId const& obj)
{ {
return Utils::MakeConversionTuple(obj.GetAgentId(), obj.GetInterfaceId()); return Utils::MakeConversionTuple(obj.GetAgentId(), obj.GetInterfaceId());
} }