serialize.h 39 KB

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