serialize_xml.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. //
  2. // Copyright (C) 2014 Christian Schüller <schuellchr@gmail.com>
  3. //
  4. // This Source Code Form is subject to the terms of the Mozilla Public License
  5. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  6. // obtain one at http://mozilla.org/MPL/2.0/.
  7. // -----------------------------------------------------------------------------
  8. // Functions to save and load a serialization of fundamental c++ data types to
  9. // and from a xml file. STL containers, Eigen matrix types and nested data
  10. // structures are also supported. To serialize a user defined class implement
  11. // the interface XMLSerializable.
  12. //
  13. // See also: serialize.h
  14. // -----------------------------------------------------------------------------
  15. #ifndef IGL_SERIALIZABLE_XML_H
  16. #define IGL_SERIALIZABLE_XML_H
  17. #include <type_traits>
  18. #include <iostream>
  19. #include <vector>
  20. #include <set>
  21. #include <map>
  22. #include <Eigen/Dense>
  23. #include <Eigen/Sparse>
  24. #include <igl/serialize.h>
  25. #include "tinyxml2.h"
  26. //#define SERIALIZE_XML(x) igl::serialize_xml(x,#x,doc,element);
  27. //#define DESERIALIZE_XML(x) igl::deserialize_xml(x,#x,,doc,element);
  28. namespace igl
  29. {
  30. // serializes the given object either to a xml file or to the provided doc data
  31. //
  32. // Templates:
  33. // T type of the object to serialize
  34. // Inputs:
  35. // obj object to serialize
  36. // objectName unique object name,used for the identification
  37. // filename name of the file containing the serialization
  38. // binary set to true to serialize the object in binary format (faster for big data)
  39. // overwrite set to true to update the serialization in an existing xml file
  40. // element tinyxml2 virtual representation of the current xml node
  41. // Outputs:
  42. // doc contains current tinyxml2 virtual representation of the xml data
  43. //
  44. template <typename T>
  45. void serialize_xml(const T& obj,const std::string& filename);
  46. template <typename T>
  47. void serialize_xml(const T& obj,const std::string& objectName,const std::string& filename, bool binary = false,bool overwrite = false);
  48. template <typename T>
  49. void serialize_xml(const T& obj,const std::string& objectName,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,bool binary = false);
  50. // deserializes the given data from a xml file or doc data back to the provided object
  51. //
  52. // Templates:
  53. // T type of the object to serialize
  54. // Inputs:
  55. //
  56. // objectName unique object name,used for the identification
  57. // filename name of the file containing the serialization
  58. // binary set to true to serialize the object in binary format (faster for big data)
  59. // overwrite set to true to update the serialization in an existing xml file
  60. // doc contains current tinyxml2 virtual representation of the xml data
  61. // element tinyxml2 virtual representation of the current xml node
  62. // Outputs:
  63. // obj object to load back serialization to
  64. //
  65. template <typename T>
  66. void deserialize_xml(T& obj,const std::string& filename);
  67. template <typename T>
  68. void deserialize_xml(T& obj,const std::string& objectName,const std::string& filename);
  69. template <typename T>
  70. void deserialize_xml(T& obj,const std::string& objectName,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element);
  71. // interface for user defined types
  72. struct XMLSerializable : public Serializable
  73. {
  74. virtual void Serialize(std::vector<char>& buffer) const = 0;
  75. virtual void Deserialize(const std::vector<char>& buffer) = 0;
  76. virtual void Serialize(tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element) const = 0;
  77. virtual void Deserialize(const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element) = 0;
  78. };
  79. // example:
  80. //
  81. // class Test : public igl::Serializable {
  82. //
  83. // int var;
  84. //
  85. // void Serialize(std::vector<char>& buffer) {
  86. // serialize(var,"var1",buffer);
  87. // }
  88. // void Deserialize(const std::vector<char>& buffer) {
  89. // deserialize(var,"var1",buffer);
  90. // }
  91. // void Serialize(tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element) const {
  92. // serialize_xml(var,"var1",doc,element);
  93. // }
  94. // void Deserialize(const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element) {
  95. // deserialize_xml(var,"var1",doc,element);
  96. // }
  97. // }
  98. // internal functions
  99. namespace detail_xml
  100. {
  101. // fundamental types
  102. template <typename T>
  103. std::enable_if_t<std::is_fundamental<T>::value> serialize(const T& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
  104. template <typename T>
  105. std::enable_if_t<std::is_fundamental<T>::value> deserialize(T& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
  106. // std::string
  107. void serialize(const std::string& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
  108. void deserialize(std::string& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
  109. // Serializable
  110. template <typename T>
  111. std::enable_if_t<std::is_base_of<XMLSerializable,T>::value> serialize(const T& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
  112. template <typename T>
  113. std::enable_if_t<std::is_base_of<XMLSerializable,T>::value> deserialize(T& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
  114. // STL containers
  115. template <typename T1, typename T2>
  116. void serialize(const std::pair<T1,T2>& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
  117. template <typename T1,typename T2>
  118. void deserialize(std::pair<T1,T2>& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
  119. template <typename T1,typename T2>
  120. void serialize(const std::vector<T1,T2>& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
  121. template <typename T1,typename T2>
  122. void deserialize(std::vector<T1,T2>& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
  123. template <typename T>
  124. void serialize(const std::set<T>& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
  125. template <typename T>
  126. void deserialize(std::set<T>& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
  127. template <typename T1,typename T2>
  128. void serialize(const std::map<T1,T2>& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
  129. template <typename T1,typename T2>
  130. void deserialize(std::map<T1,T2>& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
  131. // Eigen types
  132. template<typename T,int R,int C,int P,int MR,int MC>
  133. void serialize(const Eigen::Matrix<T,R,C,P,MR,MC>& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
  134. template<typename T,int R,int C,int P,int MR,int MC>
  135. void deserialize(Eigen::Matrix<T,R,C,P,MR,MC>& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
  136. template<typename T,int P,typename I>
  137. void serialize(const Eigen::SparseMatrix<T,P,I>& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
  138. template<typename T,int P,typename I>
  139. void deserialize(Eigen::SparseMatrix<T,P,I>& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
  140. // pointers
  141. template <typename T>
  142. std::enable_if_t<std::is_pointer<T>::value> serialize(const T& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
  143. template <typename T>
  144. std::enable_if_t<std::is_pointer<T>::value> deserialize(T& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
  145. // helper functions
  146. tinyxml2::XMLElement* getElement(tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
  147. void getAttribute(const char* src,bool& dest);
  148. void getAttribute(const char* scr,char& dest);
  149. void getAttribute(const char* src,std::string& dest);
  150. void getAttribute(const char* src,float& dest);
  151. void getAttribute(const char* src,double& dest);
  152. template<typename T>
  153. std::enable_if_t<std::is_integral<T>::value && std::is_unsigned<T>::value> getAttribute(const char* src,T& dest);
  154. template<typename T>
  155. std::enable_if_t<std::is_integral<T>::value && !std::is_unsigned<T>::value> getAttribute(const char* src,T& dest);
  156. void replaceSubString(std::string& str,const std::string& search,const std::string& replace);
  157. void encodeXMLElementName(std::string& name);
  158. void decodeXMLElementName(std::string& name);
  159. std::string base64_encode(unsigned char const* bytes_to_encode,unsigned int in_len);
  160. std::string base64_decode(std::string const& encoded_string);
  161. // compile time type serializable check
  162. template <typename T>
  163. struct is_stl_container { static const bool value = false; };
  164. template <typename T1,typename T2>
  165. struct is_stl_container<std::pair<T1,T2> > { static const bool value = true; };
  166. template <typename T1,typename T2>
  167. struct is_stl_container<std::vector<T1,T2> > { static const bool value = true; };
  168. template <typename T>
  169. struct is_stl_container<std::set<T> > { static const bool value = true; };
  170. template <typename T1,typename T2>
  171. struct is_stl_container<std::map<T1,T2> > { static const bool value = true; };
  172. template <typename T>
  173. struct is_eigen_type { static const bool value = false; };
  174. template <typename T,int R,int C,int P,int MR,int MC>
  175. struct is_eigen_type<Eigen::Matrix<T,R,C,P,MR,MC> > { static const bool value = true; };
  176. template <typename T,int P,typename I>
  177. struct is_eigen_type<Eigen::SparseMatrix<T,P,I> > { static const bool value = true; };
  178. template <typename T>
  179. struct is_serializable {
  180. using T0 = typename std::remove_pointer<T>::type;
  181. static const bool value = std::is_fundamental<T0>::value || std::is_same<std::string,T0>::value || std::is_base_of<Serializable,T0>::value
  182. || is_stl_container<T0>::value || is_eigen_type<T0>::value;
  183. };
  184. }
  185. }
  186. #include "serialize_xml.cpp";
  187. #endif