serialize.h 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2014 Christian Schüller <schuellchr@gmail.com>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #ifndef IGL_SERIALIZE_H
  9. #define IGL_SERIALIZE_H
  10. // -----------------------------------------------------------------------------
  11. // Functions to save and load a serialization of fundamental c++ data types to
  12. // and from a binary file. STL containers, Eigen matrix types and nested data
  13. // structures are also supported. To serialize a user defined class implement
  14. // the interface Serializable or SerializableBase.
  15. //
  16. // See also: xml/serialize_xml.h
  17. // -----------------------------------------------------------------------------
  18. // TODOs:
  19. // * non-intrusive serialization example
  20. // * arbitrary pointer graph structures
  21. // * cross-platform compatibility (big-, little-endian)
  22. // -----------------------------------------------------------------------------
  23. // Known issues: This is not written in libigl-style so it isn't (easily)
  24. // "dualized" into the static library.
  25. //
  26. #include <type_traits>
  27. #include <iostream>
  28. #include <fstream>
  29. #include <cstdint>
  30. #include <numeric>
  31. #include <vector>
  32. #include <set>
  33. #include <map>
  34. #include <memory>
  35. #include <cstdint>
  36. #include <Eigen/Dense>
  37. #include <Eigen/Sparse>
  38. #include "igl_inline.h"
  39. // non-intrusive serialization helper macros
  40. #define SERIALIZE_TYPE(Type,Params) \
  41. namespace igl { namespace serialization { \
  42. void _serialization(bool s,Type& obj,std::vector<char>& buffer) {Params} \
  43. void serialize(const Type& obj,std::vector<char>& buffer) { \
  44. _serialization(true,const_cast<Type&>(obj),buffer); \
  45. } \
  46. void deserialize(Type& obj,const std::vector<char>& buffer) { \
  47. _serialization(false,obj,const_cast<std::vector<char>&>(buffer)); \
  48. } \
  49. }}
  50. #define SERIALIZE_MEMBER(Object) ::igl::serializer(s,obj.##Object,std::string(#Object),buffer);
  51. #define SERIALIZE_MEMBER_NAME(Object,Name) ::igl::serializer(s,obj.##Object,std::string(Name),buffer);
  52. namespace igl
  53. {
  54. struct IndexedPointerBase;
  55. // Serializes the given object either to a file or to a provided buffer
  56. // Templates:
  57. // T type of the object to serialize
  58. // Inputs:
  59. // obj object to serialize
  60. // objectName unique object name,used for the identification
  61. // overwrite set to true to overwrite an existing file
  62. // filename name of the file containing the serialization
  63. // Outputs:
  64. // buffer binary serialization
  65. //
  66. template <typename T>
  67. inline bool serialize(const T& obj,const std::string& filename);
  68. template <typename T>
  69. inline bool serialize(const T& obj,const std::string& objectName,const std::string& filename,bool overwrite = false);
  70. template <typename T>
  71. inline bool serialize(const T& obj,const std::string& objectName,std::vector<char>& buffer);
  72. template <typename T>
  73. inline bool serialize(const T& obj,const std::string& objectName,std::vector<char>& buffer);
  74. // Deserializes the given data from a file or buffer back to the provided object
  75. //
  76. // Templates:
  77. // T type of the object to serialize
  78. // Inputs:
  79. // buffer binary serialization
  80. // objectName unique object name, used for the identification
  81. // filename name of the file containing the serialization
  82. // Outputs:
  83. // obj object to load back serialization to
  84. //
  85. template <typename T>
  86. inline bool deserialize(T& obj,const std::string& filename);
  87. template <typename T>
  88. inline bool deserialize(T& obj,const std::string& objectName,const std::string& filename);
  89. template <typename T>
  90. inline bool deserialize(T& obj,const std::string& objectName,const std::vector<char>& buffer);
  91. // Wrapper to expose both, the de- and serialization as one function
  92. //
  93. template <typename T>
  94. inline bool serializer(bool serialize,T& obj,std::string& filename);
  95. template <typename T>
  96. inline bool serializer(bool serialize,T& obj,std::string& objectName,const std::string& filename,bool overwrite = false);
  97. template <typename T>
  98. inline bool serializer(bool serialize,T& obj,std::string& objectName,std::vector<char>& buffer);
  99. // User defined types have to either overload the function igl::serialization::serialize()
  100. // and igl::serialization::deserialize() for their type (non-intrusive serialization):
  101. //
  102. // namespace igl { namespace serialization
  103. // {
  104. // inline void serialize(const UserType& obj,std::vector<char>& buffer) {
  105. // ::igl::serialize(obj.var,"var",buffer);
  106. // }
  107. //
  108. // inline void deserialize(UserType& obj,const std::vector<char>& buffer) {
  109. // ::igl::deserialize(obj.var,"var",buffer);
  110. // }
  111. // }}
  112. //
  113. // or use this macro for convenience:
  114. //
  115. // SERIALIZE_TYPE(UserType,
  116. // SERIALIZE_MEMBER(var)
  117. // )
  118. //
  119. // or to derive from the class Serializable and add their the members
  120. // in InitSerialization like the following:
  121. //
  122. // class UserType : public igl::Serializable {
  123. //
  124. // int var;
  125. //
  126. // void InitSerialization() {
  127. // this->Add(var,"var");
  128. // }
  129. // };
  130. // Base interface for user defined types
  131. struct SerializableBase
  132. {
  133. virtual void Serialize(std::vector<char>& buffer) const = 0;
  134. virtual void Deserialize(const std::vector<char>& buffer) = 0;
  135. };
  136. // Convenient interface for user defined types
  137. class Serializable: public SerializableBase
  138. {
  139. private:
  140. template <typename T>
  141. struct SerializationObject : public SerializableBase
  142. {
  143. bool Binary;
  144. std::string Name;
  145. std::unique_ptr<T> Object;
  146. void Serialize(std::vector<char>& buffer) const override {
  147. igl::serialize(*Object,Name,buffer);
  148. }
  149. void Deserialize(const std::vector<char>& buffer) override {
  150. igl::deserialize(*Object,Name,buffer);
  151. }
  152. };
  153. mutable bool initialized;
  154. mutable std::vector<SerializableBase*> objects;
  155. public:
  156. // Override this function to add your member variables which should be serialized
  157. inline virtual void InitSerialization() = 0;
  158. // Following functions can be overridden to handle the specific events.
  159. // Return false to prevent the de-/serialization of an object.
  160. inline virtual bool PreSerialization() const;
  161. inline virtual void PostSerialization() const;
  162. inline virtual bool PreDeserialization();
  163. inline virtual void PostDeserialization();
  164. // Default implementation of SerializableBase interface
  165. inline void Serialize(std::vector<char>& buffer) const override final;
  166. inline void Deserialize(const std::vector<char>& buffer) override final;
  167. // Default constructor, destructor, assignment and copy constructor
  168. inline Serializable();
  169. inline Serializable(const Serializable& obj);
  170. inline ~Serializable();
  171. inline Serializable& operator=(const Serializable& obj);
  172. // Use this function to add your variables which should be serialized
  173. template <typename T>
  174. inline void Add(T& obj,std::string name,bool binary = false);
  175. };
  176. // structure for pointer handling
  177. struct IndexedPointerBase
  178. {
  179. enum { BEGIN,END } Type;
  180. size_t Index;
  181. };
  182. template<typename T>
  183. struct IndexedPointer: public IndexedPointerBase
  184. {
  185. const T* Object;
  186. };
  187. // internal functions
  188. namespace serialization
  189. {
  190. // compile time type checks
  191. template <typename T>
  192. struct is_stl_container { static const bool value = false; };
  193. template <typename T1,typename T2>
  194. struct is_stl_container<std::pair<T1,T2> > { static const bool value = true; };
  195. template <typename T1,typename T2>
  196. struct is_stl_container<std::vector<T1,T2> > { static const bool value = true; };
  197. template <typename T>
  198. struct is_stl_container<std::set<T> > { static const bool value = true; };
  199. template <typename T1,typename T2>
  200. struct is_stl_container<std::map<T1,T2> > { static const bool value = true; };
  201. template <typename T>
  202. struct is_eigen_type { static const bool value = false; };
  203. template <typename T,int R,int C,int P,int MR,int MC>
  204. struct is_eigen_type<Eigen::Matrix<T,R,C,P,MR,MC> > { static const bool value = true; };
  205. template <typename T,int P,typename I>
  206. struct is_eigen_type<Eigen::SparseMatrix<T,P,I> > { static const bool value = true; };
  207. template <typename T>
  208. struct is_smart_ptr { static const bool value = false; };
  209. template <typename T>
  210. struct is_smart_ptr<std::shared_ptr<T> > { static const bool value = true; };
  211. template <typename T>
  212. struct is_smart_ptr<std::unique_ptr<T> > { static const bool value = true; };
  213. template <typename T>
  214. struct is_smart_ptr<std::weak_ptr<T> > { static const bool value = true; };
  215. template <typename T>
  216. struct is_serializable {
  217. static const bool value = std::is_fundamental<T>::value || std::is_same<std::string,T>::value || std::is_base_of<SerializableBase,T>::value
  218. || is_stl_container<T>::value || is_eigen_type<T>::value || std::is_pointer<T>::value || serialization::is_smart_ptr<T>::value;
  219. };
  220. // non serializable types
  221. template <typename T>
  222. inline typename std::enable_if<!is_serializable<T>::value,size_t>::type getByteSize(const T& obj);
  223. template <typename T>
  224. inline typename std::enable_if<!is_serializable<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
  225. template <typename T>
  226. inline typename std::enable_if<!is_serializable<T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter);
  227. // fundamental types
  228. template <typename T>
  229. inline typename std::enable_if<std::is_fundamental<T>::value,size_t>::type getByteSize(const T& obj);
  230. template <typename T>
  231. inline typename std::enable_if<std::is_fundamental<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
  232. template <typename T>
  233. inline typename std::enable_if<std::is_fundamental<T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter);
  234. // std::string
  235. inline size_t getByteSize(const std::string& obj);
  236. inline void serialize(const std::string& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
  237. inline void deserialize(std::string& obj,std::vector<char>::const_iterator& iter);
  238. // SerializableBase
  239. template <typename T>
  240. inline typename std::enable_if<std::is_base_of<SerializableBase,T>::value,size_t>::type getByteSize(const T& obj);
  241. template <typename T>
  242. 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);
  243. template <typename T>
  244. inline typename std::enable_if<std::is_base_of<SerializableBase,T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter);
  245. // stl containers
  246. // std::pair
  247. template <typename T1,typename T2>
  248. inline size_t getByteSize(const std::pair<T1,T2>& obj);
  249. template <typename T1,typename T2>
  250. inline void serialize(const std::pair<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
  251. template <typename T1,typename T2>
  252. inline void deserialize(std::pair<T1,T2>& obj,std::vector<char>::const_iterator& iter);
  253. // std::vector
  254. template <typename T1,typename T2>
  255. inline size_t getByteSize(const std::vector<T1,T2>& obj);
  256. template <typename T1,typename T2>
  257. inline void serialize(const std::vector<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
  258. template <typename T1,typename T2>
  259. inline void deserialize(std::vector<T1,T2>& obj,std::vector<char>::const_iterator& iter);
  260. template <typename T2>
  261. inline void deserialize(std::vector<bool,T2>& obj,std::vector<char>::const_iterator& iter);
  262. // std::set
  263. template <typename T>
  264. inline size_t getByteSize(const std::set<T>& obj);
  265. template <typename T>
  266. inline void serialize(const std::set<T>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
  267. template <typename T>
  268. inline void deserialize(std::set<T>& obj,std::vector<char>::const_iterator& iter);
  269. // std::map
  270. template <typename T1,typename T2>
  271. inline size_t getByteSize(const std::map<T1,T2>& obj);
  272. template <typename T1,typename T2>
  273. inline void serialize(const std::map<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
  274. template <typename T1,typename T2>
  275. inline void deserialize(std::map<T1,T2>& obj,std::vector<char>::const_iterator& iter);
  276. // Eigen types
  277. template<typename T,int R,int C,int P,int MR,int MC>
  278. inline size_t getByteSize(const Eigen::Matrix<T,R,C,P,MR,MC>& obj);
  279. template<typename T,int R,int C,int P,int MR,int MC>
  280. inline void serialize(const Eigen::Matrix<T,R,C,P,MR,MC>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
  281. template<typename T,int R,int C,int P,int MR,int MC>
  282. inline void deserialize(Eigen::Matrix<T,R,C,P,MR,MC>& obj,std::vector<char>::const_iterator& iter);
  283. template<typename T,int P,typename I>
  284. inline size_t getByteSize(const Eigen::SparseMatrix<T,P,I>& obj);
  285. template<typename T,int P,typename I>
  286. inline void serialize(const Eigen::SparseMatrix<T,P,I>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
  287. template<typename T,int P,typename I>
  288. inline void deserialize(Eigen::SparseMatrix<T,P,I>& obj,std::vector<char>::const_iterator& iter);
  289. // raw pointers
  290. template <typename T>
  291. inline typename std::enable_if<std::is_pointer<T>::value,size_t>::type getByteSize(const T& obj);
  292. template <typename T>
  293. inline typename std::enable_if<std::is_pointer<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
  294. template <typename T>
  295. inline typename std::enable_if<std::is_pointer<T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter);
  296. // std::shared_ptr and std::unique_ptr
  297. template <typename T>
  298. inline typename std::enable_if<serialization::is_smart_ptr<T>::value,size_t>::type getByteSize(const T& obj);
  299. template <typename T>
  300. inline typename std::enable_if<serialization::is_smart_ptr<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
  301. template <template<typename> class T0, typename T1>
  302. inline typename std::enable_if<serialization::is_smart_ptr<T0<T1> >::value>::type deserialize(T0<T1>& obj,std::vector<char>::const_iterator& iter);
  303. // std::weak_ptr
  304. template <typename T>
  305. inline size_t getByteSize(const std::weak_ptr<T>& obj);
  306. template <typename T>
  307. inline void serialize(const std::weak_ptr<T>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
  308. template <typename T>
  309. inline void deserialize(std::weak_ptr<T>& obj,std::vector<char>::const_iterator& iter);
  310. // functions to overload for non-intrusive serialization
  311. template <typename T>
  312. inline void serialize(const T& obj,std::vector<char>& buffer);
  313. template <typename T>
  314. inline void deserialize(T& obj,const std::vector<char>& buffer);
  315. // helper functions
  316. template <typename T>
  317. inline void updateMemoryMap(T& obj,size_t size);
  318. }
  319. }
  320. // Always include inlines for these functions
  321. // IMPLEMENTATION
  322. namespace igl
  323. {
  324. template <typename T>
  325. inline bool serialize(const T& obj,const std::string& filename)
  326. {
  327. return serialize(obj,"obj",filename,true);
  328. }
  329. template <typename T>
  330. inline bool serialize(const T& obj,const std::string& objectName,const std::string& filename,bool overwrite)
  331. {
  332. bool success = false;
  333. std::vector<char> buffer;
  334. std::ios_base::openmode mode = std::ios::out | std::ios::binary;
  335. if(overwrite)
  336. mode |= std::ios::trunc;
  337. else
  338. mode |= std::ios::app;
  339. std::ofstream file(filename.c_str(),mode);
  340. if(file.is_open())
  341. {
  342. serialize(obj,objectName,buffer);
  343. file.write(&buffer[0],buffer.size());
  344. file.close();
  345. success = true;
  346. }
  347. else
  348. {
  349. std::cerr << "serialization: file " << filename << " not found!" << std::endl;
  350. }
  351. return success;
  352. }
  353. template <typename T>
  354. inline bool serialize(const T& obj,const std::string& objectName,std::vector<char>& buffer)
  355. {
  356. // serialize object data
  357. size_t size = serialization::getByteSize(obj);
  358. std::vector<char> tmp(size);
  359. auto it = tmp.begin();
  360. serialization::serialize(obj,tmp,it);
  361. std::string objectType(typeid(obj).name());
  362. size_t newObjectSize = tmp.size();
  363. size_t newHeaderSize = serialization::getByteSize(objectName) + serialization::getByteSize(objectType) + sizeof(size_t);
  364. size_t curSize = buffer.size();
  365. size_t newSize = curSize + newHeaderSize + newObjectSize;
  366. buffer.resize(newSize);
  367. std::vector<char>::iterator iter = buffer.begin()+curSize;
  368. // serialize object header (name/type/size)
  369. serialization::serialize(objectName,buffer,iter);
  370. serialization::serialize(objectType,buffer,iter);
  371. serialization::serialize(newObjectSize,buffer,iter);
  372. // copy serialized data to buffer
  373. iter = std::copy(tmp.begin(),tmp.end(),iter);
  374. return true;
  375. }
  376. template <typename T>
  377. inline bool deserialize(T& obj,const std::string& filename)
  378. {
  379. return deserialize(obj,"obj",filename);
  380. }
  381. template <typename T>
  382. inline bool deserialize(T& obj,const std::string& objectName,const std::string& filename)
  383. {
  384. bool success = false;
  385. std::ifstream file(filename.c_str(),std::ios::binary);
  386. if(file.is_open())
  387. {
  388. file.seekg(0,std::ios::end);
  389. std::streamoff size = file.tellg();
  390. file.seekg(0,std::ios::beg);
  391. std::vector<char> buffer(size);
  392. file.read(&buffer[0],size);
  393. deserialize(obj,objectName,buffer);
  394. file.close();
  395. success = true;
  396. }
  397. else
  398. {
  399. std::cerr << "serialization: file " << filename << " not found!" << std::endl;
  400. }
  401. return success;
  402. }
  403. template <typename T>
  404. inline bool deserialize(T& obj,const std::string& objectName,const std::vector<char>& buffer)
  405. {
  406. bool success = false;
  407. // find suitable object header
  408. auto objectIter = buffer.cend();
  409. auto iter = buffer.cbegin();
  410. while(iter != buffer.end())
  411. {
  412. std::string name;
  413. std::string type;
  414. size_t size;
  415. serialization::deserialize(name,iter);
  416. serialization::deserialize(type,iter);
  417. serialization::deserialize(size,iter);
  418. if(name == objectName && type == typeid(obj).name())
  419. {
  420. objectIter = iter;
  421. //break; // find first suitable object header
  422. }
  423. iter+=size;
  424. }
  425. if(objectIter != buffer.end())
  426. {
  427. serialization::deserialize(obj,objectIter);
  428. success = true;
  429. }
  430. else
  431. {
  432. obj = T();
  433. }
  434. return success;
  435. }
  436. // Wrapper function which combines both, de- and serialization
  437. template <typename T>
  438. inline bool serializer(bool s,T& obj,std::string& filename)
  439. {
  440. return s ? serialize(obj,filename) : deserialize(obj,filename);
  441. }
  442. template <typename T>
  443. inline bool serializer(bool s,T& obj,std::string& objectName,const std::string& filename,bool overwrite)
  444. {
  445. return s ? serialize(obj,objectName,filename,overwrite) : deserialize(obj,objectName,filename);
  446. }
  447. template <typename T>
  448. inline bool serializer(bool s,T& obj,std::string& objectName,std::vector<char>& buffer)
  449. {
  450. return s ? serialize(obj,objectName,buffer) : deserialize(obj,objectName,buffer);
  451. }
  452. inline bool Serializable::PreSerialization() const
  453. {
  454. return true;
  455. }
  456. inline void Serializable::PostSerialization() const
  457. {
  458. }
  459. inline bool Serializable::PreDeserialization()
  460. {
  461. return true;
  462. }
  463. inline void Serializable::PostDeserialization()
  464. {
  465. }
  466. inline void Serializable::Serialize(std::vector<char>& buffer) const
  467. {
  468. if(this->PreSerialization())
  469. {
  470. if(initialized == false)
  471. {
  472. objects.clear();
  473. (const_cast<Serializable*>(this))->InitSerialization();
  474. initialized = true;
  475. }
  476. for(const auto& v : objects)
  477. {
  478. v->Serialize(buffer);
  479. }
  480. this->PostSerialization();
  481. }
  482. }
  483. inline void Serializable::Deserialize(const std::vector<char>& buffer)
  484. {
  485. if(this->PreDeserialization())
  486. {
  487. if(initialized == false)
  488. {
  489. objects.clear();
  490. (const_cast<Serializable*>(this))->InitSerialization();
  491. initialized = true;
  492. }
  493. for(auto& v : objects)
  494. {
  495. v->Deserialize(buffer);
  496. }
  497. this->PostDeserialization();
  498. }
  499. }
  500. inline Serializable::Serializable()
  501. {
  502. initialized = false;
  503. }
  504. inline Serializable::Serializable(const Serializable& obj)
  505. {
  506. initialized = false;
  507. objects.clear();
  508. }
  509. inline Serializable::~Serializable()
  510. {
  511. initialized = false;
  512. objects.clear();
  513. }
  514. inline Serializable& Serializable::operator=(const Serializable& obj)
  515. {
  516. if(this != &obj)
  517. {
  518. if(initialized)
  519. {
  520. initialized = false;
  521. objects.clear();
  522. }
  523. }
  524. return *this;
  525. }
  526. template <typename T>
  527. inline void Serializable::Add(T& obj,std::string name,bool binary)
  528. {
  529. auto object = new SerializationObject<T>();
  530. object->Binary = binary;
  531. object->Name = name;
  532. object->Object = std::unique_ptr<T>(&obj);
  533. objects.push_back(object);
  534. }
  535. namespace serialization
  536. {
  537. // not serializable
  538. template <typename T>
  539. inline typename std::enable_if<!is_serializable<T>::value,size_t>::type getByteSize(const T& obj)
  540. {
  541. return sizeof(std::vector<char>::size_type);
  542. }
  543. template <typename T>
  544. inline typename std::enable_if<!is_serializable<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
  545. {
  546. // data
  547. std::vector<char> tmp;
  548. serialize(obj,tmp);
  549. // size
  550. size_t size = buffer.size();
  551. serialization::serialize(tmp.size(),buffer,iter);
  552. size_t cur = iter - buffer.begin();
  553. buffer.resize(size+tmp.size());
  554. iter = buffer.begin()+cur;
  555. iter = std::copy(tmp.begin(),tmp.end(),iter);
  556. }
  557. template <typename T>
  558. inline typename std::enable_if<!is_serializable<T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter)
  559. {
  560. std::vector<char>::size_type size;
  561. serialization::deserialize(size,iter);
  562. std::vector<char> tmp;
  563. tmp.resize(size);
  564. std::copy(iter,iter+size,tmp.begin());
  565. deserialize(obj,tmp);
  566. iter += size;
  567. }
  568. // fundamental types
  569. template <typename T>
  570. inline typename std::enable_if<std::is_fundamental<T>::value,size_t>::type getByteSize(const T& obj)
  571. {
  572. return sizeof(T);
  573. }
  574. template <typename T>
  575. inline typename std::enable_if<std::is_fundamental<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
  576. {
  577. //serialization::updateMemoryMap(obj,sizeof(T));
  578. const uint8_t* ptr = reinterpret_cast<const uint8_t*>(&obj);
  579. iter = std::copy(ptr,ptr+sizeof(T),iter);
  580. }
  581. template <typename T>
  582. inline typename std::enable_if<std::is_fundamental<T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter)
  583. {
  584. uint8_t* ptr = reinterpret_cast<uint8_t*>(&obj);
  585. std::copy(iter,iter+sizeof(T),ptr);
  586. iter += sizeof(T);
  587. }
  588. // std::string
  589. inline size_t getByteSize(const std::string& obj)
  590. {
  591. return getByteSize(obj.length())+obj.length()*sizeof(uint8_t);
  592. }
  593. inline void serialize(const std::string& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
  594. {
  595. serialization::serialize(obj.length(),buffer,iter);
  596. for(const auto& cur : obj)
  597. {
  598. serialization::serialize(cur,buffer,iter);
  599. }
  600. }
  601. inline void deserialize(std::string& obj,std::vector<char>::const_iterator& iter)
  602. {
  603. size_t size;
  604. serialization::deserialize(size,iter);
  605. std::string str(size,'\0');
  606. for(size_t i=0; i<size; ++i)
  607. {
  608. serialization::deserialize(str.at(i),iter);
  609. }
  610. obj = str;
  611. }
  612. // SerializableBase
  613. template <typename T>
  614. inline typename std::enable_if<std::is_base_of<SerializableBase,T>::value,size_t>::type getByteSize(const T& obj)
  615. {
  616. return sizeof(std::vector<char>::size_type);
  617. }
  618. template <typename T>
  619. 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)
  620. {
  621. // data
  622. std::vector<char> tmp;
  623. obj.Serialize(tmp);
  624. // size
  625. size_t size = buffer.size();
  626. serialization::serialize(tmp.size(),buffer,iter);
  627. size_t cur = iter - buffer.begin();
  628. buffer.resize(size+tmp.size());
  629. iter = buffer.begin()+cur;
  630. iter = std::copy(tmp.begin(),tmp.end(),iter);
  631. }
  632. template <typename T>
  633. inline typename std::enable_if<std::is_base_of<SerializableBase,T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter)
  634. {
  635. std::vector<char>::size_type size;
  636. serialization::deserialize(size,iter);
  637. std::vector<char> tmp;
  638. tmp.resize(size);
  639. std::copy(iter,iter+size,tmp.begin());
  640. obj.Deserialize(tmp);
  641. iter += size;
  642. }
  643. // STL containers
  644. // std::pair
  645. template <typename T1,typename T2>
  646. inline size_t getByteSize(const std::pair<T1,T2>& obj)
  647. {
  648. return getByteSize(obj.first)+getByteSize(obj.second);
  649. }
  650. template <typename T1,typename T2>
  651. inline void serialize(const std::pair<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
  652. {
  653. serialization::serialize(obj.first,buffer,iter);
  654. serialization::serialize(obj.second,buffer,iter);
  655. }
  656. template <typename T1,typename T2>
  657. inline void deserialize(std::pair<T1,T2>& obj,std::vector<char>::const_iterator& iter)
  658. {
  659. serialization::deserialize(obj.first,iter);
  660. serialization::deserialize(obj.second,iter);
  661. }
  662. // std::vector
  663. template <typename T1,typename T2>
  664. inline size_t getByteSize(const std::vector<T1,T2>& obj)
  665. {
  666. return std::accumulate(obj.begin(),obj.end(),sizeof(size_t),[](const size_t& acc,const T1& cur) { return acc+getByteSize(cur); });
  667. }
  668. template <typename T1,typename T2>
  669. inline void serialize(const std::vector<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
  670. {
  671. size_t size = obj.size();
  672. serialization::serialize(size,buffer,iter);
  673. for(const T1& cur : obj)
  674. {
  675. serialization::serialize(cur,buffer,iter);
  676. }
  677. }
  678. template <typename T1,typename T2>
  679. inline void deserialize(std::vector<T1,T2>& obj,std::vector<char>::const_iterator& iter)
  680. {
  681. size_t size;
  682. serialization::deserialize(size,iter);
  683. obj.resize(size);
  684. for(T1& v : obj)
  685. {
  686. serialization::deserialize(v,iter);
  687. }
  688. }
  689. template <typename T2>
  690. inline void deserialize(std::vector<bool,T2>& obj,std::vector<char>::const_iterator& iter)
  691. {
  692. size_t size;
  693. serialization::deserialize(size,iter);
  694. obj.resize(size);
  695. for(int i=0;i<obj.size();i++)
  696. {
  697. bool val;
  698. serialization::deserialize(val,iter);
  699. obj[i] = val;
  700. }
  701. }
  702. //std::set
  703. template <typename T>
  704. inline size_t getByteSize(const std::set<T>& obj)
  705. {
  706. return std::accumulate(obj.begin(),obj.end(),getByteSize(obj.size()),[](const size_t& acc,const T& cur) { return acc+getByteSize(cur); });
  707. }
  708. template <typename T>
  709. inline void serialize(const std::set<T>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
  710. {
  711. serialization::serialize(obj.size(),buffer,iter);
  712. for(const T& cur : obj)
  713. {
  714. serialization::serialize(cur,buffer,iter);
  715. }
  716. }
  717. template <typename T>
  718. inline void deserialize(std::set<T>& obj,std::vector<char>::const_iterator& iter)
  719. {
  720. size_t size;
  721. serialization::deserialize(size,iter);
  722. obj.clear();
  723. for(size_t i=0; i<size; ++i)
  724. {
  725. T val;
  726. serialization::deserialize(val,iter);
  727. obj.insert(val);
  728. }
  729. }
  730. // std::map
  731. template <typename T1,typename T2>
  732. inline size_t getByteSize(const std::map<T1,T2>& obj)
  733. {
  734. return std::accumulate(obj.begin(),obj.end(),sizeof(size_t),[](const size_t& acc,const std::pair<T1,T2>& cur) { return acc+getByteSize(cur); });
  735. }
  736. template <typename T1,typename T2>
  737. inline void serialize(const std::map<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
  738. {
  739. serialization::serialize(obj.size(),buffer,iter);
  740. for(const auto& cur : obj)
  741. {
  742. serialization::serialize(cur,buffer,iter);
  743. }
  744. }
  745. template <typename T1,typename T2>
  746. inline void deserialize(std::map<T1,T2>& obj,std::vector<char>::const_iterator& iter)
  747. {
  748. size_t size;
  749. serialization::deserialize(size,iter);
  750. obj.clear();
  751. for(size_t i=0; i<size; ++i)
  752. {
  753. std::pair<T1,T2> pair;
  754. serialization::deserialize(pair,iter);
  755. obj.insert(pair);
  756. }
  757. }
  758. // Eigen types
  759. template<typename T,int R,int C,int P,int MR,int MC>
  760. inline size_t getByteSize(const Eigen::Matrix<T,R,C,P,MR,MC>& obj)
  761. {
  762. // space for numbers of rows,cols and data
  763. return 2*sizeof(typename Eigen::Matrix<T,R,C,P,MR,MC>::Index)+sizeof(T)*obj.rows()*obj.cols();
  764. }
  765. template<typename T,int R,int C,int P,int MR,int MC>
  766. inline void serialize(const Eigen::Matrix<T,R,C,P,MR,MC>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
  767. {
  768. serialization::serialize(obj.rows(),buffer,iter);
  769. serialization::serialize(obj.cols(),buffer,iter);
  770. size_t size = sizeof(T)*obj.rows()*obj.cols();
  771. auto ptr = reinterpret_cast<const uint8_t*>(obj.data());
  772. iter = std::copy(ptr,ptr+size,iter);
  773. }
  774. template<typename T,int R,int C,int P,int MR,int MC>
  775. inline void deserialize(Eigen::Matrix<T,R,C,P,MR,MC>& obj,std::vector<char>::const_iterator& iter)
  776. {
  777. typename Eigen::Matrix<T,R,C,P,MR,MC>::Index rows,cols;
  778. serialization::deserialize(rows,iter);
  779. serialization::deserialize(cols,iter);
  780. size_t size = sizeof(T)*rows*cols;
  781. obj.resize(rows,cols);
  782. auto ptr = reinterpret_cast<uint8_t*>(obj.data());
  783. std::copy(iter,iter+size,ptr);
  784. iter+=size;
  785. }
  786. template<typename T,int P,typename I>
  787. inline size_t getByteSize(const Eigen::SparseMatrix<T,P,I>& obj)
  788. {
  789. // space for numbers of rows,cols,nonZeros and tripplets with data (rowIdx,colIdx,value)
  790. size_t size = sizeof(typename Eigen::SparseMatrix<T,P,I>::Index);
  791. return 3*size+(sizeof(T)+2*size)*obj.nonZeros();
  792. }
  793. template<typename T,int P,typename I>
  794. inline void serialize(const Eigen::SparseMatrix<T,P,I>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
  795. {
  796. serialization::serialize(obj.rows(),buffer,iter);
  797. serialization::serialize(obj.cols(),buffer,iter);
  798. serialization::serialize(obj.nonZeros(),buffer,iter);
  799. for(int k=0;k<obj.outerSize();++k)
  800. {
  801. for(typename Eigen::SparseMatrix<T,P,I>::InnerIterator it(obj,k);it;++it)
  802. {
  803. serialization::serialize(it.row(),buffer,iter);
  804. serialization::serialize(it.col(),buffer,iter);
  805. serialization::serialize(it.value(),buffer,iter);
  806. }
  807. }
  808. }
  809. template<typename T,int P,typename I>
  810. inline void deserialize(Eigen::SparseMatrix<T,P,I>& obj,std::vector<char>::const_iterator& iter)
  811. {
  812. typename Eigen::SparseMatrix<T,P,I>::Index rows,cols,nonZeros;
  813. serialization::deserialize(rows,iter);
  814. serialization::deserialize(cols,iter);
  815. serialization::deserialize(nonZeros,iter);
  816. obj.resize(rows,cols);
  817. obj.setZero();
  818. std::vector<Eigen::Triplet<T,I> > triplets;
  819. for(int i=0;i<nonZeros;i++)
  820. {
  821. typename Eigen::SparseMatrix<T,P,I>::Index rowId,colId;
  822. serialization::deserialize(rowId,iter);
  823. serialization::deserialize(colId,iter);
  824. T value;
  825. serialization::deserialize(value,iter);
  826. triplets.push_back(Eigen::Triplet<T,I>(rowId,colId,value));
  827. }
  828. obj.setFromTriplets(triplets.begin(),triplets.end());
  829. }
  830. // pointers
  831. template <typename T>
  832. inline typename std::enable_if<std::is_pointer<T>::value,size_t>::type getByteSize(const T& obj)
  833. {
  834. size_t size = sizeof(bool);
  835. if(obj)
  836. size += getByteSize(*obj);
  837. return size;
  838. }
  839. template <typename T>
  840. inline typename std::enable_if<std::is_pointer<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
  841. {
  842. serialization::serialize(obj == nullptr,buffer,iter);
  843. if(obj)
  844. serialization::serialize(*obj,buffer,iter);
  845. }
  846. template <typename T>
  847. inline typename std::enable_if<std::is_pointer<T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter)
  848. {
  849. bool isNullPtr;
  850. serialization::deserialize(isNullPtr,iter);
  851. if(isNullPtr)
  852. {
  853. if(obj)
  854. {
  855. std::cout << "serialization: possible memory leak in serialization for '" << typeid(obj).name() << "'" << std::endl;
  856. obj = nullptr;
  857. }
  858. }
  859. else
  860. {
  861. if(obj)
  862. {
  863. std::cout << "serialization: possible memory corruption in deserialization for '" << typeid(obj).name() << "'" << std::endl;
  864. }
  865. else
  866. {
  867. obj = new typename std::remove_pointer<T>::type();
  868. }
  869. serialization::deserialize(*obj,iter);
  870. }
  871. }
  872. // std::shared_ptr and std::unique_ptr
  873. template <typename T>
  874. inline typename std::enable_if<serialization::is_smart_ptr<T>::value,size_t>::type getByteSize(const T& obj)
  875. {
  876. return getByteSize(obj.get());
  877. }
  878. template <typename T>
  879. inline typename std::enable_if<serialization::is_smart_ptr<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
  880. {
  881. serialize(obj.get(),buffer,iter);
  882. }
  883. template <template<typename> class T0,typename T1>
  884. inline typename std::enable_if<serialization::is_smart_ptr<T0<T1> >::value>::type deserialize(T0<T1>& obj,std::vector<char>::const_iterator& iter)
  885. {
  886. bool isNullPtr;
  887. serialization::deserialize(isNullPtr,iter);
  888. if(isNullPtr)
  889. {
  890. obj.reset();
  891. }
  892. else
  893. {
  894. obj = T0<T1>(new T1());
  895. serialization::deserialize(*obj,iter);
  896. }
  897. }
  898. // std::weak_ptr
  899. template <typename T>
  900. inline size_t getByteSize(const std::weak_ptr<T>& obj)
  901. {
  902. return sizeof(size_t);
  903. }
  904. template <typename T>
  905. inline void serialize(const std::weak_ptr<T>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
  906. {
  907. }
  908. template <typename T>
  909. inline void deserialize(std::weak_ptr<T>& obj,std::vector<char>::const_iterator& iter)
  910. {
  911. }
  912. // functions to overload for non-intrusive serialization
  913. template <typename T>
  914. inline void serialize(const T& obj,std::vector<char>& buffer)
  915. {
  916. std::cerr << typeid(obj).name() << " is not serializable: derive from igl::Serializable or overload the function igl::serialization::serialize(const T& obj,std::vector<char>& buffer)" << std::endl;
  917. }
  918. template <typename T>
  919. inline void deserialize(T& obj,const std::vector<char>& buffer)
  920. {
  921. std::cerr << typeid(obj).name() << " is not deserializable: derive from igl::Serializable or overload the function igl::serialization::deserialize(T& obj, const std::vector<char>& buffer)" << std::endl;
  922. }
  923. // helper functions
  924. template <typename T>
  925. inline void updateMemoryMap(T& obj,size_t size,std::map<std::uintptr_t,IndexedPointerBase*>& memoryMap)
  926. {
  927. // check if object is already serialized
  928. auto startPtr = new IndexedPointer<T>();
  929. startPtr->Object = &obj;
  930. auto startBasePtr = static_cast<IndexedPointerBase*>(startPtr);
  931. startBasePtr->Type = IndexedPointerBase::BEGIN;
  932. auto startAddress = reinterpret_cast<std::uintptr_t>(&obj);
  933. auto p = std::pair<std::uintptr_t,IndexedPointerBase*>(startAddress,startBasePtr);
  934. auto el = memoryMap.insert(p);
  935. auto iter = ++el.first; // next elememt
  936. if(el.second && (iter == memoryMap.end() || iter->second->Type != IndexedPointerBase::END))
  937. {
  938. // not yet serialized
  939. auto endPtr = new IndexedPointer<T>();
  940. auto endBasePtr = static_cast<IndexedPointerBase*>(endPtr);
  941. endBasePtr->Type = IndexedPointerBase::END;
  942. auto endAddress = reinterpret_cast<std::uintptr_t>(&obj) + size - 1;
  943. auto p = std::pair<std::uintptr_t,IndexedPointerBase*>(endAddress,endBasePtr);
  944. // insert end address
  945. memoryMap.insert(el.first,p);
  946. }
  947. else
  948. {
  949. // already serialized
  950. // remove inserted address
  951. memoryMap.erase(el.first);
  952. }
  953. }
  954. }
  955. }
  956. #endif