serialize.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  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.
  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 "igl_inline.h"
  22. #include <type_traits>
  23. #include <iostream>
  24. #include <numeric>
  25. #include <vector>
  26. #include <set>
  27. #include <map>
  28. #include <fstream>
  29. #include <Eigen/Dense>
  30. #include <Eigen/Sparse>
  31. //#define SERIALIZE(x) igl::serialize(x,#x,buffer);
  32. //#define DESERIALIZE(x) igl::deserialize(x,#x,buffer);
  33. namespace igl
  34. {
  35. // serializes the given object either to a file or to a provided buffer
  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. // Outputs:
  43. // buffer binary serialization
  44. //
  45. template <typename T>
  46. IGL_INLINE void serialize(const T& obj,const std::string& filename);
  47. template <typename T>
  48. IGL_INLINE void serialize(const T& obj,const std::string& objectName,std::vector<char>& buffer);
  49. // deserializes the given data from a file or buffer back to the provided object
  50. //
  51. // Templates:
  52. // T type of the object to serialize
  53. // Inputs:
  54. // buffer binary serialization
  55. // objectName unique object name, used for the identification
  56. // filename name of the file containing the serialization
  57. // Outputs:
  58. // obj object to load back serialization to
  59. //
  60. template <typename T>
  61. IGL_INLINE void deserialize(T& obj,const std::string& filename);
  62. template <typename T>
  63. IGL_INLINE void deserialize(T& obj,const std::string& objectName,const std::vector<char>& buffer);
  64. // interface for user defined types
  65. struct Serializable
  66. {
  67. virtual void Serialize(std::vector<char>& buffer) const = 0;
  68. virtual void Deserialize(const std::vector<char>& buffer) = 0;
  69. };
  70. // example:
  71. //
  72. // class Test : public igl::Serializable {
  73. //
  74. // int var;
  75. //
  76. // void Serialize(std::vector<char>& buffer) {
  77. // serialize(var,"var1",buffer);
  78. // }
  79. // void Deserialize(const std::vector<char>& buffer) {
  80. // deserialize(var,"var1",buffer);
  81. // }
  82. // }
  83. // internal functions
  84. namespace detail
  85. {
  86. // fundamental types
  87. template <typename T>
  88. IGL_INLINE typename std::enable_if<std::is_fundamental<T>::value,size_t>::type getByteSize(const T& obj);
  89. template <typename T>
  90. 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);
  91. template <typename T>
  92. IGL_INLINE typename std::enable_if<std::is_fundamental<T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter);
  93. // std::string
  94. IGL_INLINE size_t getByteSize(const std::string& obj);
  95. IGL_INLINE void serialize(const std::string& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
  96. IGL_INLINE void deserialize(std::string& obj,std::vector<char>::const_iterator& iter);
  97. // Serializable
  98. template <typename T>
  99. IGL_INLINE typename std::enable_if<std::is_base_of<Serializable,T>::value,size_t>::type getByteSize(const T& obj);
  100. template <typename T>
  101. IGL_INLINE typename std::enable_if<std::is_base_of<Serializable,T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
  102. template <typename T>
  103. IGL_INLINE typename std::enable_if<std::is_base_of<Serializable,T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter);
  104. // stl containers
  105. // std::pair
  106. template <typename T1,typename T2>
  107. IGL_INLINE size_t getByteSize(const std::pair<T1,T2>& obj);
  108. template <typename T1,typename T2>
  109. IGL_INLINE void serialize(const std::pair<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
  110. template <typename T1,typename T2>
  111. IGL_INLINE void deserialize(std::pair<T1,T2>& obj,std::vector<char>::const_iterator& iter);
  112. // std::vector
  113. template <typename T1,typename T2>
  114. IGL_INLINE size_t getByteSize(const std::vector<T1,T2>& obj);
  115. template <typename T1,typename T2>
  116. IGL_INLINE void serialize(const std::vector<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
  117. template <typename T1,typename T2>
  118. IGL_INLINE void deserialize(std::vector<T1,T2>& obj,std::vector<char>::const_iterator& iter);
  119. // std::set
  120. template <typename T>
  121. IGL_INLINE size_t getByteSize(const std::set<T>& obj);
  122. template <typename T>
  123. IGL_INLINE void serialize(const std::set<T>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
  124. template <typename T>
  125. IGL_INLINE void deserialize(std::set<T>& obj,std::vector<char>::const_iterator& iter);
  126. // std::map
  127. template <typename T1,typename T2>
  128. IGL_INLINE size_t getByteSize(const std::map<T1,T2>& obj);
  129. template <typename T1,typename T2>
  130. IGL_INLINE void serialize(const std::map<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
  131. template <typename T1,typename T2>
  132. IGL_INLINE void deserialize(std::map<T1,T2>& obj,std::vector<char>::const_iterator& iter);
  133. // Eigen types
  134. template<typename T,int R,int C,int P,int MR,int MC>
  135. IGL_INLINE size_t getByteSize(const Eigen::Matrix<T,R,C,P,MR,MC>& obj);
  136. template<typename T,int R,int C,int P,int MR,int MC>
  137. IGL_INLINE void serialize(const Eigen::Matrix<T,R,C,P,MR,MC>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
  138. template<typename T,int R,int C,int P,int MR,int MC>
  139. IGL_INLINE void deserialize(Eigen::Matrix<T,R,C,P,MR,MC>& obj,std::vector<char>::const_iterator& iter);
  140. template<typename T,int P,typename I>
  141. IGL_INLINE size_t getByteSize(const Eigen::SparseMatrix<T,P,I>& obj);
  142. template<typename T,int P,typename I>
  143. IGL_INLINE void serialize(const Eigen::SparseMatrix<T,P,I>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
  144. template<typename T,int P,typename I>
  145. IGL_INLINE void deserialize(Eigen::SparseMatrix<T,P,I>& obj,std::vector<char>::const_iterator& iter);
  146. // pointers
  147. template <typename T>
  148. IGL_INLINE typename std::enable_if<std::is_pointer<T>::value,size_t>::type getByteSize(const T& obj);
  149. template <typename T>
  150. 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);
  151. template <typename T>
  152. IGL_INLINE typename std::enable_if<std::is_pointer<T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter);
  153. // compile time type serializable check
  154. template <typename T>
  155. struct is_stl_container { static const bool value = false; };
  156. template <typename T1,typename T2>
  157. struct is_stl_container<std::pair<T1,T2> > { static const bool value = true; };
  158. template <typename T1,typename T2>
  159. struct is_stl_container<std::vector<T1,T2> > { static const bool value = true; };
  160. template <typename T>
  161. struct is_stl_container<std::set<T> > { static const bool value = true; };
  162. template <typename T1,typename T2>
  163. struct is_stl_container<std::map<T1,T2> > { static const bool value = true; };
  164. template <typename T>
  165. struct is_eigen_type { static const bool value = false; };
  166. template <typename T,int R,int C,int P,int MR,int MC>
  167. struct is_eigen_type<Eigen::Matrix<T,R,C,P,MR,MC> > { static const bool value = true; };
  168. template <typename T,int P,typename I>
  169. struct is_eigen_type<Eigen::SparseMatrix<T,P,I> > { static const bool value = true; };
  170. template <typename T>
  171. struct is_serializable {
  172. using T0 = typename std::remove_pointer<T>::type;
  173. static const bool value = std::is_fundamental<T0>::value || std::is_same<std::string,T0>::value || std::is_base_of<Serializable,T0>::value
  174. || is_stl_container<T0>::value || is_eigen_type<T0>::value;
  175. };
  176. }
  177. }
  178. #ifndef IGL_STATIC_LIBRARY
  179. #include "serialize.cpp"
  180. #endif
  181. #endif