serialize.h 41 KB

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