Changeset 143:5d6130e3f43c in rrlib_rtti


Ignore:
Timestamp:
28.03.2020 21:13:36 (3 months ago)
Author:
Max Reichardt <mreichardt@…>
Branch:
17.03
Children:
144:bd3582809830, 145:ae5a7c09b179
Phase:
public
Message:

Adds additional generic rtti-based XML serialization implemenentations for container types (that use the default rrlib_serialization template functions) - together with unit tests. This results in a significant reduction of binary sizes. Furthemore, adds support for XML deserialization of multi-line strings.

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • detail/tDataTypeInfo.h

    r115 r143  
    7979                  (!(SupportsBitwiseCopy<T>::value && IsDefaultConstructionZeroMemory<T>::value) ? eTLF_BINARY_OPS : 0) | 
    8080                  (serialization::IsBinarySerializable<T>::value ? eTLF_BINARY_SERIALIZATION : 0) | 
    81                   ((serialization::IsXMLSerializable<T>::value || serialization::IsStringSerializable<T>::value) && (!(IsStdPair<T>::value || IsStdTuple<T>::value)) ? eTLF_OTHER_SERIALIZATION : 0)) 
     81                  ((serialization::IsXMLSerializable<T>::value || serialization::IsStringSerializable<T>::value) && (!(IsStdPair<T>::value || IsStdTuple<T>::value || ((IsStdVector<T>::value || IsStdArray<T>::value) && serialization::IsXMLSerializationDefaultImplementation<T>::value && (!std::is_same<T, std::vector<bool>>::value)))) ? eTLF_OTHER_SERIALIZATION : 0)) 
    8282       }; 
    8383}; 
  • tTypedPointer.cpp

    r108 r143  
    3737// Internal includes with "" 
    3838//---------------------------------------------------------------------- 
     39#include "rrlib/rtti/rtti.h" 
    3940 
    4041//---------------------------------------------------------------------- 
     
    6263// Const values 
    6364//---------------------------------------------------------------------- 
     65static tType cSTRING_TYPE = tDataType<std::string>(); 
     66static tType cBOOL_VECTOR_TYPE = tDataType<std::vector<bool>>(); 
    6467 
    6568//---------------------------------------------------------------------- 
     
    101104      } 
    102105    } 
     106    else if (type.GetTypeClassification() == tTypeClassification::LIST && type != cBOOL_VECTOR_TYPE) 
     107    { 
     108      size_t child_count = 0; 
     109      for (auto it = node.ChildrenBegin(); it != node.ChildrenEnd(); ++it) 
     110      { 
     111        child_count++; 
     112      } 
     113      this->ResizeVector(child_count); 
     114      size_t i = 0; 
     115      for (auto it = node.ChildrenBegin(); it != node.ChildrenEnd(); ++it, ++i) 
     116      { 
     117        this->GetVectorElement(i).Deserialize(*it); 
     118      } 
     119    } 
     120    else if (type.GetTypeClassification() == tTypeClassification::ARRAY) 
     121    { 
     122      const size_t array_size = this->GetType().GetArraySize(); 
     123      const size_t element_size = this->GetType().GetSize() / array_size; 
     124      rrlib::rtti::tType element_type = this->GetType().GetElementType(); 
     125      assert(element_type.GetSize() == element_size); 
     126      size_t i = 0; 
     127      for (auto it = node.ChildrenBegin(); it != node.ChildrenEnd() && i < array_size; ++it, ++i) 
     128      { 
     129        tTypedPointer element(static_cast<char*>(this->GetRawDataPointer()) + element_size * i, element_type); 
     130        element.Deserialize(*it); 
     131      } 
     132    } 
     133    else if (type == cSTRING_TYPE) 
     134    { 
     135      *this->Get<std::string>() = node.GetTextContent(); 
     136    } 
    103137    else if (type.GetTypeTraits() & trait_flags::cIS_STRING_SERIALIZABLE) 
    104138    { 
     
    171205      } 
    172206    } 
     207    else if (type.GetTypeClassification() == tTypeClassification::LIST && type != cBOOL_VECTOR_TYPE) 
     208    { 
     209      const size_t size = this->GetVectorSize(); 
     210      for (size_t i = 0; i < size; i++) 
     211      { 
     212        this->GetVectorElement(i).Serialize(node.AddChildNode("element")); 
     213      } 
     214    } 
     215    else if (type.GetTypeClassification() == tTypeClassification::ARRAY) 
     216    { 
     217      const size_t array_size = this->GetType().GetArraySize(); 
     218      const size_t element_size = this->GetType().GetSize() / array_size; 
     219      rrlib::rtti::tType element_type = this->GetType().GetElementType(); 
     220      assert(element_type.GetSize() == element_size); 
     221      for (size_t i = 0; i < array_size; i++) 
     222      { 
     223        tTypedConstPointer element(static_cast<const char*>(this->GetRawDataPointer()) + element_size * i, element_type); 
     224        element.Serialize(node.AddChildNode("element")); 
     225      } 
     226    } 
     227    else if (type == cSTRING_TYPE) 
     228    { 
     229      node.SetContent(*this->Get<std::string>()); 
     230    } 
    173231    else if (type.GetTypeTraits() & trait_flags::cIS_STRING_SERIALIZABLE) 
    174232    { 
  • tests/rtti.cpp

    r139 r143  
    8282static_assert(std::is_same<typename rrlib::rtti::NormalizedType<unsigned long>::type, typename std::conditional<sizeof(unsigned long) == 8, unsigned long long, unsigned int>::type>::value, "Invalid trait implementation"); 
    8383static_assert(IsImplicitlyConvertible<double, bool>::value, "Trait not implemented correctly"); 
     84#ifdef _LIB_RRLIB_XML_PRESENT_ 
     85static_assert(serialization::IsXMLSerializationDefaultImplementation<std::vector<std::string>>::value, "Trait not implemented correctly"); 
     86static_assert(serialization::IsXMLSerializable<std::vector<std::string>>::value, "Trait not implemented correctly"); 
     87static_assert((detail::TableLayoutFlags<std::vector<std::string>>::value & detail::eTLF_OTHER_SERIALIZATION) == 0, "Trait not implemented correctly"); 
     88static_assert((detail::TableLayoutFlags<std::vector<bool>>::value & detail::eTLF_OTHER_SERIALIZATION) != 0, "Trait not implemented correctly"); 
     89static_assert((detail::TableLayoutFlags<std::array<std::string, 3>>::value & detail::eTLF_OTHER_SERIALIZATION) == 0, "Trait not implemented correctly"); 
     90static_assert((detail::TableLayoutFlags<std::array<bool, 3>>::value & detail::eTLF_OTHER_SERIALIZATION) == 0, "Trait not implemented correctly"); 
     91#endif 
    8492 
    8593//---------------------------------------------------------------------- 
     
    184192 
    185193  template <typename T> 
    186   void TestGenericOperations(T& t) 
     194  void TestGenericOperationsBinary(T& t) 
    187195  { 
    188196    static_assert(rrlib::serialization::IsBinarySerializable<T>::value, "Trait not correctly implemented"); 
     
    192200    copy->DeepCopyFrom(wrapper); 
    193201    RRLIB_UNIT_TESTS_EQUALITY_MESSAGE(std::string("Objects must be equal (type: ") + util::Demangle(typeid(T).name()) + ")", copy->Equals(wrapper), true); 
     202  } 
     203 
     204  template <typename T> 
     205  void TestGenericOperations(T& t) 
     206  { 
     207    TestGenericOperationsBinary(t); 
     208 
     209#ifdef _LIB_RRLIB_XML_PRESENT_ 
     210 
     211    // Serialize to XML - and compare dumps 
     212    static_assert(rrlib::serialization::IsXMLSerializable<T>::value, "Trait not correctly implemented"); 
     213    rrlib::xml::tDocument doc1, doc2; 
     214    doc1.AddRootNode("Test") << t; 
     215    tTypedConstPointer generic_t(&t); 
     216    generic_t.Serialize(doc2.AddRootNode("Test")); 
     217    std::string xml_dump = doc1.RootNode().GetXMLDump(); 
     218    assert(xml_dump.length() > 12); 
     219    //std::cout << xml_dump << '\n' << doc2.RootNode().GetXMLDump() << '\n'; 
     220    RRLIB_UNIT_TESTS_EQUALITY(xml_dump, doc2.RootNode().GetXMLDump()); 
     221 
     222    // Deserialize from XML 
     223    std::unique_ptr<tGenericObject> copy(generic_t.GetType().CreateGenericObject()); 
     224    copy->Deserialize(doc1.RootNode()); 
     225    RRLIB_UNIT_TESTS_ASSERT(copy->GetData<T>() == t); 
     226#endif 
    194227  } 
    195228 
     
    209242    std::array<std::vector<bool>, 2> test_vector_bool_array = { test_vector_bool, test_vector_bool }; 
    210243    TestGenericOperations(test_vector_bool_array); 
     244    std::vector<std::string> test_string_vector = { "First String", "2nd String" }; 
     245    TestGenericOperations(test_string_vector); 
     246    using serialization::tDataEncoding; 
     247    std::array<std::tuple<tDataEncoding, uint8_t, std::pair<double, std::string>>, 2> test_tuple_array = { std::make_tuple(tDataEncoding::XML, static_cast<uint8_t>(45), std::make_pair(4., "Txt")), std::make_tuple(tDataEncoding::STRING, static_cast<uint8_t>(141), std::make_pair(-0.1, "www")) }; 
     248    TestGenericOperations(test_tuple_array); 
    211249 
    212250    tBuffer buffer; 
     
    217255    } 
    218256    stream.Close(); 
    219     TestGenericOperations(buffer); 
     257    TestGenericOperationsBinary(buffer); 
    220258  } 
    221259 
Note: See TracChangeset for help on using the changeset viewer.