serialize_xml.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  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. #ifndef IGL_XML_SERIALIZABLE_XML_H
  8. #define IGL_XML_SERIALIZABLE_XML_H
  9. // -----------------------------------------------------------------------------
  10. // Functions to save and load a serialization of fundamental c++ data types to
  11. // and from a xml file. STL containers, Eigen matrix types and nested data
  12. // structures are also supported. To serialize a user defined class implement
  13. // the interface XMLSerializable or XMLSerializableBase.
  14. //
  15. // See also: serialize.h
  16. // -----------------------------------------------------------------------------
  17. #include "../igl_inline.h"
  18. #include <type_traits>
  19. #include <iostream>
  20. #include <vector>
  21. #include <set>
  22. #include <map>
  23. #include <memory>
  24. #include <Eigen/Dense>
  25. #include <Eigen/Sparse>
  26. #include <igl/serialize.h>
  27. #include "tinyxml2.h"
  28. //#define SERIALIZE_XML(x) igl::xml::serialize_xml(x,#x,doc,element);
  29. //#define DESERIALIZE_XML(x) igl::xml::deserialize_xml(x,#x,,doc,element);
  30. namespace igl
  31. {
  32. namespace xml
  33. {
  34. // serializes the given object either to a xml file or to the provided doc data
  35. //
  36. // Templates:
  37. // T type of the object to serialize
  38. // Inputs:
  39. // obj object to serialize
  40. // objectName unique object name,used for the identification
  41. // filename name of the file containing the serialization
  42. // binary set to true to serialize the object in binary format (faster for big data)
  43. // overwrite set to true to overwrite an existing xml file
  44. // element tinyxml2 virtual representation of the current xml node
  45. // Outputs:
  46. // doc contains current tinyxml2 virtual representation of the xml data
  47. //
  48. template <typename T>
  49. IGL_INLINE void serialize_xml(const T& obj,const std::string& filename);
  50. template <typename T>
  51. IGL_INLINE void serialize_xml(const T& obj,const std::string& objectName,const std::string& filename, bool binary = false,bool overwrite = false);
  52. template <typename T>
  53. IGL_INLINE void serialize_xml(const T& obj,const std::string& objectName,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,bool binary = false);
  54. // deserializes the given data from a xml file or doc data back to the provided object
  55. //
  56. // Templates:
  57. // T type of the object to serialize
  58. // Inputs:
  59. //
  60. // objectName unique object name,used for the identification
  61. // filename name of the file containing the serialization
  62. // binary set to true to serialize the object in binary format (faster for big data)
  63. // overwrite set to true to overwrite an existing xml file
  64. // doc contains current tinyxml2 virtual representation of the xml data
  65. // element tinyxml2 virtual representation of the current xml node
  66. // Outputs:
  67. // obj object to load back serialization to
  68. //
  69. template <typename T>
  70. IGL_INLINE void deserialize_xml(T& obj,const std::string& filename);
  71. template <typename T>
  72. IGL_INLINE void deserialize_xml(T& obj,const std::string& objectName,const std::string& filename);
  73. template <typename T>
  74. IGL_INLINE void deserialize_xml(T& obj,const std::string& objectName,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element);
  75. // interface for user defined types
  76. struct XMLSerializableBase : public SerializableBase
  77. {
  78. virtual void Serialize(std::vector<char>& buffer) const = 0;
  79. virtual void Deserialize(const std::vector<char>& buffer) = 0;
  80. virtual void Serialize(tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element) const = 0;
  81. virtual void Deserialize(const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element) = 0;
  82. };
  83. // Convenient interface for user defined types
  84. class XMLSerializable: public XMLSerializableBase
  85. {
  86. private:
  87. template <typename T>
  88. struct XMLSerializationObject: public XMLSerializableBase
  89. {
  90. bool Binary;
  91. std::string Name;
  92. T* Object;
  93. void Serialize(std::vector<char>& buffer) const {
  94. serialize(*Object,Name,buffer);
  95. }
  96. void Deserialize(const std::vector<char>& buffer) {
  97. deserialize(*Object,Name,buffer);
  98. }
  99. void Serialize(tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element) const {
  100. serialize_xml(*Object,Name,doc,element,Binary);
  101. }
  102. void Deserialize(const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element) {
  103. deserialize_xml(*Object,Name,doc,element);
  104. }
  105. };
  106. mutable bool initialized;
  107. mutable std::vector<XMLSerializableBase*> objects;
  108. public:
  109. // Override this function to add your member variables which should be serialized
  110. IGL_INLINE virtual void InitSerialization() = 0;
  111. // Following functions can be overridden to handle the specific events.
  112. // Return false to prevent the de-/serialization of an object.
  113. IGL_INLINE virtual bool PreSerialization() const;
  114. IGL_INLINE virtual void PostSerialization() const;
  115. IGL_INLINE virtual bool PreDeserialization();
  116. IGL_INLINE virtual void PostDeserialization();
  117. // Default implementation of XMLSerializableBase interface
  118. IGL_INLINE void Serialize(std::vector<char>& buffer) const;
  119. IGL_INLINE void Deserialize(const std::vector<char>& buffer);
  120. IGL_INLINE void Serialize(tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element) const;
  121. IGL_INLINE void Deserialize(const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element);
  122. // Default constructor, destructor, assignment and copy constructor
  123. IGL_INLINE XMLSerializable();
  124. IGL_INLINE XMLSerializable(const XMLSerializable& obj);
  125. IGL_INLINE ~XMLSerializable();
  126. IGL_INLINE XMLSerializable& operator=(const XMLSerializable& obj);
  127. // Use this function to add your variables which should be serialized
  128. template <typename T>
  129. IGL_INLINE void Add(T& obj,std::string name,bool binary = false);
  130. };
  131. // internal functions
  132. namespace serialization_xml
  133. {
  134. // fundamental types
  135. template <typename T>
  136. IGL_INLINE typename std::enable_if<std::is_fundamental<T>::value>::type serialize(const T& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
  137. template <typename T>
  138. IGL_INLINE typename std::enable_if<std::is_fundamental<T>::value>::type deserialize(T& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
  139. // std::string
  140. IGL_INLINE void serialize(const std::string& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
  141. IGL_INLINE void deserialize(std::string& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
  142. // XMLSerializableBase
  143. template <typename T>
  144. IGL_INLINE typename std::enable_if<std::is_base_of<XMLSerializableBase,T>::value>::type serialize(const T& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
  145. template <typename T>
  146. IGL_INLINE typename std::enable_if<std::is_base_of<XMLSerializableBase,T>::value>::type deserialize(T& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
  147. // STL containers
  148. template <typename T1, typename T2>
  149. IGL_INLINE void serialize(const std::pair<T1,T2>& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
  150. template <typename T1,typename T2>
  151. IGL_INLINE void deserialize(std::pair<T1,T2>& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
  152. template <typename T1,typename T2>
  153. IGL_INLINE void serialize(const std::vector<T1,T2>& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
  154. template <typename T1,typename T2>
  155. IGL_INLINE void deserialize(std::vector<T1,T2>& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
  156. template <typename T>
  157. IGL_INLINE void serialize(const std::set<T>& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
  158. template <typename T>
  159. IGL_INLINE void deserialize(std::set<T>& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
  160. template <typename T1,typename T2>
  161. IGL_INLINE void serialize(const std::map<T1,T2>& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
  162. template <typename T1,typename T2>
  163. IGL_INLINE void deserialize(std::map<T1,T2>& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
  164. // Eigen types
  165. template<typename T,int R,int C,int P,int MR,int MC>
  166. IGL_INLINE void serialize(const Eigen::Matrix<T,R,C,P,MR,MC>& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
  167. template<typename T,int R,int C,int P,int MR,int MC>
  168. IGL_INLINE void deserialize(Eigen::Matrix<T,R,C,P,MR,MC>& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
  169. template<typename T,int P,typename I>
  170. IGL_INLINE void serialize(const Eigen::SparseMatrix<T,P,I>& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
  171. template<typename T,int P,typename I>
  172. IGL_INLINE void deserialize(Eigen::SparseMatrix<T,P,I>& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
  173. // raw pointers
  174. template <typename T>
  175. IGL_INLINE typename std::enable_if<std::is_pointer<T>::value>::type serialize(const T& obj,tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
  176. template <typename T>
  177. IGL_INLINE typename std::enable_if<std::is_pointer<T>::value>::type deserialize(T& obj,const tinyxml2::XMLDocument* doc,const tinyxml2::XMLElement* element,const std::string& name);
  178. // helper functions
  179. tinyxml2::XMLElement* getElement(tinyxml2::XMLDocument* doc,tinyxml2::XMLElement* element,const std::string& name);
  180. IGL_INLINE void getAttribute(const char* src,bool& dest);
  181. IGL_INLINE void getAttribute(const char* scr,char& dest);
  182. IGL_INLINE void getAttribute(const char* src,std::string& dest);
  183. IGL_INLINE void getAttribute(const char* src,float& dest);
  184. IGL_INLINE void getAttribute(const char* src,double& dest);
  185. template<typename T>
  186. IGL_INLINE typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value>::type getAttribute(const char* src,T& dest);
  187. template<typename T>
  188. IGL_INLINE typename std::enable_if<std::is_integral<T>::value && !std::is_unsigned<T>::value>::type getAttribute(const char* src,T& dest);
  189. IGL_INLINE void replaceSubString(std::string& str,const std::string& search,const std::string& replace);
  190. IGL_INLINE void encodeXMLElementName(std::string& name);
  191. IGL_INLINE void decodeXMLElementName(std::string& name);
  192. IGL_INLINE std::string base64_encode(unsigned char const* bytes_to_encode,unsigned int in_len);
  193. IGL_INLINE std::string base64_decode(std::string const& encoded_string);
  194. // compile time type serializable check
  195. template <typename T>
  196. struct is_stl_container { static const bool value = false; };
  197. template <typename T1,typename T2>
  198. struct is_stl_container<std::pair<T1,T2> > { static const bool value = true; };
  199. template <typename T1,typename T2>
  200. struct is_stl_container<std::vector<T1,T2> > { static const bool value = true; };
  201. template <typename T>
  202. struct is_stl_container<std::set<T> > { static const bool value = true; };
  203. template <typename T1,typename T2>
  204. struct is_stl_container<std::map<T1,T2> > { static const bool value = true; };
  205. template <typename T>
  206. struct is_eigen_type { static const bool value = false; };
  207. template <typename T,int R,int C,int P,int MR,int MC>
  208. struct is_eigen_type<Eigen::Matrix<T,R,C,P,MR,MC> > { static const bool value = true; };
  209. template <typename T,int P,typename I>
  210. struct is_eigen_type<Eigen::SparseMatrix<T,P,I> > { static const bool value = true; };
  211. template <typename T>
  212. struct is_serializable {
  213. using T0 = typename std::remove_pointer<T>::type;
  214. static const bool value = std::is_fundamental<T0>::value || std::is_same<std::string,T0>::value || std::is_base_of<XMLSerializableBase,T0>::value
  215. || is_stl_container<T0>::value || is_eigen_type<T0>::value;
  216. };
  217. }
  218. }
  219. }
  220. #ifndef IGL_STATIC_LIBRARY
  221. #include "serialize_xml.cpp"
  222. #endif
  223. #endif