serialize.h 11 KB

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