diff --git a/Src/Common/FSecure/CppTools/ByteConverter/ByteConverter.h b/Src/Common/FSecure/CppTools/ByteConverter/ByteConverter.h index 562e4ea..db1ad50 100644 --- a/Src/Common/FSecure/CppTools/ByteConverter/ByteConverter.h +++ b/Src/Common/FSecure/CppTools/ByteConverter/ByteConverter.h @@ -389,4 +389,68 @@ namespace FSecure return ByteVector::Size(ByteConverter::Convert(obj)); } }; + + /// @brief Class providing simple way of generating ByteConverter listing only necessary members once. + /// ByteConverter can use this functionality by inheriting from PointerTupleConverter and providing + /// public static std::tuple MemberPointers() method. + /// Use std::make_tuple to create return value out of member list. + /// ByteVector can declare its own versions of To/From/Size methods if it needs dedicated logic to serialize type. + /// @tparam T Type for serialization. + template + struct PointerTupleConverter : TupleConverter + { + private: + /// @brief Class applying pointers to members to object. + /// Compatible with std::apply. + /// Creates TupleConverter::ConvertType object. + class ReferenceMembers + { + T const& m_Obj; + public: + ReferenceMembers(T const& obj) : m_Obj{ obj } {} + + template + auto operator () (Ts T::*...ts) const + { + return Utils::MakeConversionTuple(m_Obj.*ts ...); + } + }; + + /// @brief Function assigning object members with tuple of values using tuple member pointers. + /// @tparam PtrTpl Tuple of pointers to members type. + /// @tparam ValueTpl Tuple of values type. + /// @tparam Is Index sequence used to match tuples one to one. + /// @param obj Object to be assigned. + /// @param ptrTpl Tuple of pointers to members. + /// @param valueTpl Tuple of values. + template + static void AssignToMembers(T& obj, PtrTpl const& ptrTpl, ValueTpl valueTpl, std::index_sequence) + { + ((obj.*(std::get(ptrTpl)) = std::move(std::get(valueTpl))), ...); + } + + public: + /// @brief Default implementation of Convert method used by TupleConverter for serialization. + /// Function uses ByteConverter::MemberPointers() to reference T object members. + /// @param obj object to be serialized. + /// @return TupleConverter::ConvertType values to be serialized. + static auto Convert(T const& obj) + { + auto ptrTpl = ByteConverter::MemberPointers(); + return std::apply(ReferenceMembers{ obj }, ptrTpl); + } + + /// @brief Shadowed TupleConverter::From initalizing only selected members, skipped ones will be default initialized. + /// @note T must have default constructor. + /// @param bv. Buffer with serialized data. + /// @return constructed type. + static T From(ByteView& bv) + { + auto ret = T{}; + auto ptrTpl = ByteConverter::MemberPointers(); + auto valueTpl = TupleConverter::Convert(bv); + AssignToMembers(ret, ptrTpl, std::move(valueTpl), std::make_index_sequence::value>{}); + return ret; + } + }; } diff --git a/Src/Common/FSecure/WinTools/HostInfo.h b/Src/Common/FSecure/WinTools/HostInfo.h index 6c9ce35..887ec60 100644 --- a/Src/Common/FSecure/WinTools/HostInfo.h +++ b/Src/Common/FSecure/WinTools/HostInfo.h @@ -36,43 +36,24 @@ namespace FSecure /// overload ByteConverter for RTL_OSVERSIONINFOEXW. szCSDVersion and wSuiteMask are omitted. template<> - struct ByteConverter : TupleConverter + struct ByteConverter : PointerTupleConverter { /// Serialization of RTL_OSVERSIONINFOEXW type to/from ByteVector. /// @param obj. Object to be serialized. - static auto Convert(RTL_OSVERSIONINFOEXW const& obj) + static auto MemberPointers() { - return Utils::MakeConversionTuple( - obj.dwOSVersionInfoSize, - obj.dwMajorVersion, - obj.dwMinorVersion, - obj.dwBuildNumber, - obj.dwPlatformId, - obj.wServicePackMajor, - obj.wServicePackMinor, - obj.wProductType + using T = RTL_OSVERSIONINFOEXW; + return std::make_tuple( + &T::dwOSVersionInfoSize, + &T::dwMajorVersion, + &T::dwMinorVersion, + &T::dwBuildNumber, + &T::dwPlatformId, + &T::wServicePackMajor, + &T::wServicePackMinor, + &T::wProductType ); } - - /// Deserialize from ByteView. - /// Special version of From must be provided, because some of not important members are omitted at serialization. - /// @param bv. Buffer with serialized data. - /// @return RTL_OSVERSIONINFOEXW. - static RTL_OSVERSIONINFOEXW From(ByteView& bv) - { - RTL_OSVERSIONINFOEXW obj = {0,}; - ByteReader{ bv }.Read( - obj.dwOSVersionInfoSize, - obj.dwMajorVersion, - obj.dwMinorVersion, - obj.dwBuildNumber, - obj.dwPlatformId, - obj.wServicePackMajor, - obj.wServicePackMinor, - obj.wProductType - ); - return obj; - } }; /// overload ByteConverter for HostInfo