libigl v2.5.0
Loading...
Searching...
No Matches
serialize.h
Go to the documentation of this file.
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// -----------------------------------------------------------------------------
12// Functions to save and load a serialization of fundamental c++ data types to
13// and from a binary file. STL containers, Eigen matrix types and nested data
14// structures are also supported. To serialize a user defined class implement
15// the interface Serializable or SerializableBase.
16//
17// See also: xml/serialize_xml.h
18// -----------------------------------------------------------------------------
19// TODOs:
20// * arbitrary pointer graph structures
21// -----------------------------------------------------------------------------
22
23// Known issues: This is not written in libigl-style so it isn't (easily)
24// "dualized" into the static library.
25//
26
27#include <type_traits>
28#include <iostream>
29#include <fstream>
30#include <cstdint>
31#include <numeric>
32#include <vector>
33#include <set>
34#include <map>
35#include <memory>
36#include <cstdint>
37#include <list>
38
39#include <Eigen/Dense>
40#include <Eigen/Sparse>
41
42#include "igl_inline.h"
43
44// non-intrusive serialization helper macros
45
46#define SERIALIZE_TYPE(Type,Params) \
47namespace igl { namespace serialization { \
48 void _serialization(bool s,Type& obj,std::vector<char>& buffer) {Params} \
49 template<> inline void serialize(const Type& obj,std::vector<char>& buffer) { \
50 _serialization(true,const_cast<Type&>(obj),buffer); \
51 } \
52 template<> inline void deserialize(Type& obj,const std::vector<char>& buffer) { \
53 _serialization(false,obj,const_cast<std::vector<char>&>(buffer)); \
54 } \
55}}
56
57#define SERIALIZE_TYPE_SOURCE(Type,Params) \
58namespace igl { namespace serialization { \
59 void _serialization(bool s,Type& obj,std::vector<char>& buffer) {Params} \
60 void _serialize(const Type& obj,std::vector<char>& buffer) { \
61 _serialization(true,const_cast<Type&>(obj),buffer); \
62 } \
63 void _deserialize(Type& obj,const std::vector<char>& buffer) { \
64 _serialization(false,obj,const_cast<std::vector<char>&>(buffer)); \
65 } \
66}}
67
68#define SERIALIZE_MEMBER(Object) igl::serializer(s,obj.Object,std::string(#Object),buffer);
69#define SERIALIZE_MEMBER_NAME(Object,Name) igl::serializer(s,obj.Object,std::string(Name),buffer);
70
71
72namespace igl
73{
74 struct IndexedPointerBase;
75
76 // Serializes the given object either to a file or to a provided buffer
77 // Templates:
78 // T type of the object to serialize
79 // Inputs:
80 // obj object to serialize
81 // objectName unique object name,used for the identification
82 // overwrite set to true to overwrite an existing file
83 // filename name of the file containing the serialization
84 // Outputs:
85 // buffer binary serialization
86 //
87 template <typename T>
88 inline bool serialize(const T& obj,const std::string& filename);
89 template <typename T>
90 inline bool serialize(const T& obj,const std::string& objectName,const std::string& filename,bool overwrite = false);
91 template <typename T>
92 inline bool serialize(const T& obj,const std::string& objectName,std::vector<char>& buffer);
93 template <typename T>
94 inline bool serialize(const T& obj,const std::string& objectName,std::vector<char>& buffer);
95
96 // Deserializes the given data from a file or buffer back to the provided object
97 //
98 // Templates:
99 // T type of the object to serialize
100 // Inputs:
101 // buffer binary serialization
102 // objectName unique object name, used for the identification
103 // filename name of the file containing the serialization
104 // Outputs:
105 // obj object to load back serialization to
106 //
107 template <typename T>
108 inline bool deserialize(T& obj,const std::string& filename);
109 template <typename T>
110 inline bool deserialize(T& obj,const std::string& objectName,const std::string& filename);
111 template <typename T>
112 inline bool deserialize(T& obj,const std::string& objectName,const std::vector<char>& buffer);
113
114 // Wrapper to expose both, the de- and serialization as one function
115 //
116 template <typename T>
117 inline bool serializer(bool serialize,T& obj,const std::string& filename);
118 template <typename T>
119 inline bool serializer(bool serialize,T& obj,const std::string& objectName,const std::string& filename,bool overwrite = false);
120 template <typename T>
121 inline bool serializer(bool serialize,T& obj,const std::string& objectName,std::vector<char>& buffer);
122
123 // User defined types have to either overload the function igl::serialization::serialize()
124 // and igl::serialization::deserialize() for their type (non-intrusive serialization):
125 //
126 // namespace igl { namespace serialization
127 // {
128 // template<>
129 // inline void serialize(const UserType& obj,std::vector<char>& buffer) {
130 // ::igl::serialize(obj.var,"var",buffer);
131 // }
132 //
133 // template<>
134 // inline void deserialize(UserType& obj,const std::vector<char>& buffer) {
135 // ::igl::deserialize(obj.var,"var",buffer);
136 // }
137 // }}
138 //
139 // or use this macro for convenience:
140 //
141 // SERIALIZE_TYPE(UserType,
142 // SERIALIZE_MEMBER(var)
143 // )
144 //
145 // or to derive from the class Serializable and add their the members
146 // in InitSerialization like the following:
147 //
148 // class UserType : public igl::Serializable {
149 //
150 // int var;
151 //
152 // void InitSerialization() {
153 // this->Add(var,"var");
154 // }
155 // };
156
157 // Base interface for user defined types
159 {
160 virtual ~SerializableBase() = default;
161 virtual void Serialize(std::vector<char>& buffer) const = 0;
162 virtual void Deserialize(const std::vector<char>& buffer) = 0;
163 };
164
165 // Convenient interface for user defined types
167 {
168 private:
169
170 template <typename T>
171 struct SerializationObject : public SerializableBase
172 {
173 bool Binary;
174 std::string Name;
175 std::unique_ptr<T> Object;
176
177 void Serialize(std::vector<char>& buffer) const override {
178 igl::serialize(*Object,Name,buffer);
179 }
180
181 void Deserialize(const std::vector<char>& buffer) override {
182 igl::deserialize(*Object,Name,buffer);
183 }
184 };
185
186 mutable bool initialized;
187 mutable std::vector<SerializableBase*> objects;
188
189 public:
190
191 // You **MUST** Override this function to add your member variables which
192 // should be serialized
193 //
194 // http://stackoverflow.com/a/6634382/148668
195 virtual void InitSerialization() = 0;
196
197 // Following functions can be overridden to handle the specific events.
198 // Return false to prevent the de-/serialization of an object.
199 inline virtual bool PreSerialization() const;
200 inline virtual void PostSerialization() const;
201 inline virtual bool PreDeserialization();
202 inline virtual void PostDeserialization();
203
204 // Default implementation of SerializableBase interface
205 inline void Serialize(std::vector<char>& buffer) const override final;
206 inline void Deserialize(const std::vector<char>& buffer) override final;
207
208 // Default constructor, destructor, assignment and copy constructor
209 inline Serializable();
210 inline Serializable(const Serializable& obj);
211 virtual inline ~Serializable();
212 inline Serializable& operator=(const Serializable& obj);
213
214 // Use this function to add your variables which should be serialized
215 template <typename T>
216 inline void Add(T& obj,std::string name,bool binary = false);
217 };
218
219 // structure for pointer handling
221 {
222 enum { BEGIN,END } Type;
223 size_t Index;
224 };
225 template<typename T>
227 {
228 const T* Object;
229 };
230
231 // internal functions
232 namespace serialization
233 {
234 // compile time type checks
235 template <typename T>
236 struct is_stl_container { static const bool value = false; };
237 template <typename T1,typename T2>
238 struct is_stl_container<std::pair<T1,T2> > { static const bool value = true; };
239 template <typename T1,typename T2>
240 struct is_stl_container<std::vector<T1,T2> > { static const bool value = true; };
241 template <typename T>
242 struct is_stl_container<std::set<T> > { static const bool value = true; };
243 template <typename T1,typename T2>
244 struct is_stl_container<std::map<T1,T2> > { static const bool value = true; };
245 template <typename T>
246 struct is_stl_container<std::list<T> > { static const bool value = true; };
247
248 template <typename T>
249 struct is_eigen_type { static const bool value = false; };
250 template <typename T,int R,int C,int P,int MR,int MC>
251 struct is_eigen_type<Eigen::Matrix<T,R,C,P,MR,MC> > { static const bool value = true; };
252 template <typename T,int R,int C,int P,int MR,int MC>
253 struct is_eigen_type<Eigen::Array<T,R,C,P,MR,MC> > { static const bool value = true; };
254 template <typename T,int P,typename I>
255 struct is_eigen_type<Eigen::SparseMatrix<T,P,I> > { static const bool value = true; };
256
257 template <typename T>
258 struct is_smart_ptr { static const bool value = false; };
259 template <typename T>
260 struct is_smart_ptr<std::shared_ptr<T> > { static const bool value = true; };
261 template <typename T>
262 struct is_smart_ptr<std::unique_ptr<T> > { static const bool value = true; };
263 template <typename T>
264 struct is_smart_ptr<std::weak_ptr<T> > { static const bool value = true; };
265
266 template <typename T>
268 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
270 };
271
272 // non serializable types
273 template <typename T>
274 inline typename std::enable_if<!is_serializable<T>::value,size_t>::type getByteSize(const T& obj);
275 template <typename T>
276 inline typename std::enable_if<!is_serializable<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
277 template <typename T>
278 inline typename std::enable_if<!is_serializable<T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter);
279
280 // fundamental types
281 template <typename T>
282 inline typename std::enable_if<std::is_fundamental<T>::value,size_t>::type getByteSize(const T& obj);
283 template <typename T>
284 inline typename std::enable_if<std::is_fundamental<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
285 template <typename T>
286 inline typename std::enable_if<std::is_fundamental<T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter);
287
288 // std::string
289 inline size_t getByteSize(const std::string& obj);
290 inline void serialize(const std::string& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
291 inline void deserialize(std::string& obj,std::vector<char>::const_iterator& iter);
292
293 // enum types
294 template <typename T>
295 inline typename std::enable_if<std::is_enum<T>::value,size_t>::type getByteSize(const T& obj);
296 template <typename T>
297 inline typename std::enable_if<std::is_enum<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
298 template <typename T>
299 inline typename std::enable_if<std::is_enum<T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter);
300
301 // SerializableBase
302 template <typename T>
303 inline typename std::enable_if<std::is_base_of<SerializableBase,T>::value,size_t>::type getByteSize(const T& obj);
304 template <typename T>
305 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);
306 template <typename T>
307 inline typename std::enable_if<std::is_base_of<SerializableBase,T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter);
308
309 // stl containers
310 // std::pair
311 template <typename T1,typename T2>
312 inline size_t getByteSize(const std::pair<T1,T2>& obj);
313 template <typename T1,typename T2>
314 inline void serialize(const std::pair<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
315 template <typename T1,typename T2>
316 inline void deserialize(std::pair<T1,T2>& obj,std::vector<char>::const_iterator& iter);
317
318 // std::vector
319 template <typename T1,typename T2>
320 inline size_t getByteSize(const std::vector<T1,T2>& obj);
321 template <typename T1,typename T2>
322 inline void serialize(const std::vector<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
323 template <typename T1,typename T2>
324 inline void deserialize(std::vector<T1,T2>& obj,std::vector<char>::const_iterator& iter);
325 template <typename T2>
326 inline void deserialize(std::vector<bool,T2>& obj,std::vector<char>::const_iterator& iter);
327
328 // std::set
329 template <typename T>
330 inline size_t getByteSize(const std::set<T>& obj);
331 template <typename T>
332 inline void serialize(const std::set<T>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
333 template <typename T>
334 inline void deserialize(std::set<T>& obj,std::vector<char>::const_iterator& iter);
335
336 // std::map
337 template <typename T1,typename T2>
338 inline size_t getByteSize(const std::map<T1,T2>& obj);
339 template <typename T1,typename T2>
340 inline void serialize(const std::map<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
341 template <typename T1,typename T2>
342 inline void deserialize(std::map<T1,T2>& obj,std::vector<char>::const_iterator& iter);
343
344 // std::list
345 template <typename T>
346 inline size_t getByteSize(const std::list<T>& obj);
347 template <typename T>
348 inline void serialize(const std::list<T>& obj, std::vector<char>& buffer, std::vector<char>::iterator& iter);
349 template <typename T>
350 inline void deserialize(std::list<T>& obj, std::vector<char>::const_iterator& iter);
351
352 // Eigen types
353 template<typename T,int R,int C,int P,int MR,int MC>
354 inline size_t getByteSize(const Eigen::Matrix<T,R,C,P,MR,MC>& obj);
355 template<typename T,int R,int C,int P,int MR,int MC>
356 inline void serialize(const Eigen::Matrix<T,R,C,P,MR,MC>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
357 template<typename T,int R,int C,int P,int MR,int MC>
358 inline void deserialize(Eigen::Matrix<T,R,C,P,MR,MC>& obj,std::vector<char>::const_iterator& iter);
359
360 template<typename T,int R,int C,int P,int MR,int MC>
361 inline size_t getByteSize(const Eigen::Array<T,R,C,P,MR,MC>& obj);
362 template<typename T,int R,int C,int P,int MR,int MC>
363 inline void serialize(const Eigen::Array<T,R,C,P,MR,MC>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
364 template<typename T,int R,int C,int P,int MR,int MC>
365 inline void deserialize(Eigen::Array<T,R,C,P,MR,MC>& obj,std::vector<char>::const_iterator& iter);
366
367 template<typename T,int P,typename I>
368 inline size_t getByteSize(const Eigen::SparseMatrix<T,P,I>& obj);
369 template<typename T,int P,typename I>
370 inline void serialize(const Eigen::SparseMatrix<T,P,I>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
371 template<typename T,int P,typename I>
372 inline void deserialize(Eigen::SparseMatrix<T,P,I>& obj,std::vector<char>::const_iterator& iter);
373
374 template<typename T,int P>
375 inline size_t getByteSize(const Eigen::Quaternion<T,P>& obj);
376 template<typename T,int P>
377 inline void serialize(const Eigen::Quaternion<T,P>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
378 template<typename T,int P>
379 inline void deserialize(Eigen::Quaternion<T,P>& obj,std::vector<char>::const_iterator& iter);
380
381 // raw pointers
382 template <typename T>
383 inline typename std::enable_if<std::is_pointer<T>::value,size_t>::type getByteSize(const T& obj);
384 template <typename T>
385 inline typename std::enable_if<std::is_pointer<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
386 template <typename T>
387 inline typename std::enable_if<std::is_pointer<T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter);
388
389 // std::shared_ptr and std::unique_ptr
390 template <typename T>
391 inline typename std::enable_if<serialization::is_smart_ptr<T>::value,size_t>::type getByteSize(const T& obj);
392 template <typename T>
393 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);
394 template <template<typename> class T0, typename T1>
395 inline typename std::enable_if<serialization::is_smart_ptr<T0<T1> >::value>::type deserialize(T0<T1>& obj,std::vector<char>::const_iterator& iter);
396
397 // std::weak_ptr
398 template <typename T>
399 inline size_t getByteSize(const std::weak_ptr<T>& obj);
400 template <typename T>
401 inline void serialize(const std::weak_ptr<T>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter);
402 template <typename T>
403 inline void deserialize(std::weak_ptr<T>& obj,std::vector<char>::const_iterator& iter);
404
405 // functions to overload for non-intrusive serialization
406 template <typename T>
407 inline void serialize(const T& obj,std::vector<char>& buffer);
408 template <typename T>
409 inline void deserialize(T& obj,const std::vector<char>& buffer);
410
411 // helper functions
412 template <typename T>
413 inline void updateMemoryMap(T& obj,size_t size);
414 }
415}
416
417// Always include inlines for these functions
418
419// IMPLEMENTATION
420
421namespace igl
422{
423 template <typename T>
424 inline bool serialize(const T& obj,const std::string& filename)
425 {
426 return serialize(obj,"obj",filename,true);
427 }
428
429 template <typename T>
430 inline bool serialize(const T& obj,const std::string& objectName,const std::string& filename,bool overwrite)
431 {
432 bool success = false;
433
434 std::vector<char> buffer;
435
436 std::ios_base::openmode mode = std::ios::out | std::ios::binary;
437
438 if(overwrite)
439 mode |= std::ios::trunc;
440 else
441 mode |= std::ios::app;
442
443 std::ofstream file(filename.c_str(),mode);
444
445 if(file.is_open())
446 {
447 serialize(obj,objectName,buffer);
448
449 file.write(&buffer[0],buffer.size());
450
451 file.close();
452
453 success = true;
454 }
455 else
456 {
457 std::cerr << "serialization: file " << filename << " not found!" << std::endl;
458 }
459
460 return success;
461 }
462
463 template <typename T>
464 inline bool serialize(const T& obj,const std::string& objectName,std::vector<char>& buffer)
465 {
466 // serialize object data
467 size_t size = serialization::getByteSize(obj);
468 std::vector<char> tmp(size);
469 auto it = tmp.begin();
470 serialization::serialize(obj,tmp,it);
471
472 std::string objectType(typeid(obj).name());
473 size_t newObjectSize = tmp.size();
474 size_t newHeaderSize = serialization::getByteSize(objectName) + serialization::getByteSize(objectType) + sizeof(size_t);
475 size_t curSize = buffer.size();
476 size_t newSize = curSize + newHeaderSize + newObjectSize;
477
478 buffer.resize(newSize);
479
480 std::vector<char>::iterator iter = buffer.begin()+curSize;
481
482 // serialize object header (name/type/size)
483 serialization::serialize(objectName,buffer,iter);
484 serialization::serialize(objectType,buffer,iter);
485 serialization::serialize(newObjectSize,buffer,iter);
486
487 // copy serialized data to buffer
488 iter = std::copy(tmp.begin(),tmp.end(),iter);
489
490 return true;
491 }
492
493 template <typename T>
494 inline bool deserialize(T& obj,const std::string& filename)
495 {
496 return deserialize(obj,"obj",filename);
497 }
498
499 template <typename T>
500 inline bool deserialize(T& obj,const std::string& objectName,const std::string& filename)
501 {
502 bool success = false;
503
504 std::ifstream file(filename.c_str(),std::ios::binary);
505
506 if(file.is_open())
507 {
508 file.seekg(0,std::ios::end);
509 std::streamoff size = file.tellg();
510 file.seekg(0,std::ios::beg);
511
512 std::vector<char> buffer(size);
513 file.read(&buffer[0],size);
514
515 success = deserialize(obj, objectName, buffer);
516 file.close();
517 }
518 else
519 {
520 std::cerr << "serialization: file " << filename << " not found!" << std::endl;
521 }
522
523 return success;
524 }
525
526 template <typename T>
527 inline bool deserialize(T& obj,const std::string& objectName,const std::vector<char>& buffer)
528 {
529 bool success = false;
530
531 // find suitable object header
532 auto objectIter = buffer.cend();
533 auto iter = buffer.cbegin();
534 while(iter != buffer.end())
535 {
536 std::string name;
537 std::string type;
538 size_t size;
542
543 if(name == objectName && type == typeid(obj).name())
544 {
545 objectIter = iter;
546 //break; // find first suitable object header
547 }
548
549 iter+=size;
550 }
551
552 if(objectIter != buffer.end())
553 {
554 serialization::deserialize(obj,objectIter);
555 success = true;
556 }
557 else
558 {
559 obj = T();
560 }
561
562 return success;
563 }
564
565 // Wrapper function which combines both, de- and serialization
566 template <typename T>
567 inline bool serializer(bool s,T& obj,const std::string& filename)
568 {
569 return s ? serialize(obj,filename) : deserialize(obj,filename);
570 }
571
572 template <typename T>
573 inline bool serializer(bool s,T& obj,const std::string& objectName,const std::string& filename,bool overwrite)
574 {
575 return s ? serialize(obj,objectName,filename,overwrite) : deserialize(obj,objectName,filename);
576 }
577
578 template <typename T>
579 inline bool serializer(bool s,T& obj,const std::string& objectName,std::vector<char>& buffer)
580 {
581 return s ? serialize(obj,objectName,buffer) : deserialize(obj,objectName,buffer);
582 }
583
585 {
586 return true;
587 }
588
590 {
591 }
592
594 {
595 return true;
596 }
597
599 {
600 }
601
602 inline void Serializable::Serialize(std::vector<char>& buffer) const
603 {
604 if(this->PreSerialization())
605 {
606 if(initialized == false)
607 {
608 objects.clear();
609 (const_cast<Serializable*>(this))->InitSerialization();
610 initialized = true;
611 }
612
613 for(const auto& v : objects)
614 {
615 v->Serialize(buffer);
616 }
617
618 this->PostSerialization();
619 }
620 }
621
622 inline void Serializable::Deserialize(const std::vector<char>& buffer)
623 {
624 if(this->PreDeserialization())
625 {
626 if(initialized == false)
627 {
628 objects.clear();
629 (const_cast<Serializable*>(this))->InitSerialization();
630 initialized = true;
631 }
632
633 for(auto& v : objects)
634 {
635 v->Deserialize(buffer);
636 }
637
638 this->PostDeserialization();
639 }
640 }
641
643 {
644 initialized = false;
645 }
646
648 {
649 initialized = false;
650 objects.clear();
651 }
652
654 {
655 initialized = false;
656 objects.clear();
657 }
658
660 {
661 if(this != &obj)
662 {
663 if(initialized)
664 {
665 initialized = false;
666 objects.clear();
667 }
668 }
669 return *this;
670 }
671
672 template <typename T>
673 inline void Serializable::Add(T& obj,const std::string name,bool binary)
674 {
675 auto object = new SerializationObject<T>();
676 object->Binary = binary;
677 object->Name = name;
678 object->Object = std::unique_ptr<T>(&obj);
679
680 objects.push_back(object);
681 }
682
683 namespace serialization
684 {
685 template <typename T>
686 inline typename std::enable_if<!is_serializable<T>::value,size_t>::type getByteSize(const T& /*obj*/)
687 {
688 return sizeof(std::vector<char>::size_type);
689 }
690
691 template <typename T>
692 inline typename std::enable_if<!is_serializable<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
693 {
694 // data
695 std::vector<char> tmp;
696 serialize<>(obj,tmp);
697
698 // size
699 size_t size = buffer.size();
700 serialization::serialize(tmp.size(),buffer,iter);
701 size_t cur = iter - buffer.begin();
702
703 buffer.resize(size+tmp.size());
704 iter = buffer.begin()+cur;
705 iter = std::copy(tmp.begin(),tmp.end(),iter);
706 }
707
708 template <typename T>
709 inline typename std::enable_if<!is_serializable<T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter)
710 {
711 std::vector<char>::size_type size;
712 serialization::deserialize<>(size,iter);
713
714 std::vector<char> tmp;
715 tmp.resize(size);
716 std::copy(iter,iter+size,tmp.begin());
717
718 deserialize<>(obj,tmp);
719 iter += size;
720 }
721
722 // fundamental types
723
724 template <typename T>
725 inline typename std::enable_if<std::is_fundamental<T>::value,size_t>::type getByteSize(const T& /*obj*/)
726 {
727 return sizeof(T);
728 }
729
730 template <typename T>
731 inline typename std::enable_if<std::is_fundamental<T>::value>::type serialize(const T& obj,std::vector<char>& /*buffer*/,std::vector<char>::iterator& iter)
732 {
733 //serialization::updateMemoryMap(obj,sizeof(T));
734 const uint8_t* ptr = reinterpret_cast<const uint8_t*>(&obj);
735 iter = std::copy(ptr,ptr+sizeof(T),iter);
736 }
737
738 template <typename T>
739 inline typename std::enable_if<std::is_fundamental<T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter)
740 {
741 uint8_t* ptr = reinterpret_cast<uint8_t*>(&obj);
742 std::copy(iter,iter+sizeof(T),ptr);
743 iter += sizeof(T);
744 }
745
746 // std::string
747
748 inline size_t getByteSize(const std::string& obj)
749 {
750 return getByteSize(obj.length())+obj.length()*sizeof(uint8_t);
751 }
752
753 inline void serialize(const std::string& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
754 {
755 serialization::serialize(obj.length(),buffer,iter);
756 for(const auto& cur : obj)
757 {
758 serialization::serialize(cur,buffer,iter);
759 }
760 }
761
762 inline void deserialize(std::string& obj,std::vector<char>::const_iterator& iter)
763 {
764 size_t size;
766
767 std::string str(size,'\0');
768 for(size_t i=0; i<size; ++i)
769 {
770 serialization::deserialize(str.at(i),iter);
771 }
772
773 obj = str;
774 }
775
776 // enum types
777
778 template <typename T>
779 inline typename std::enable_if<std::is_enum<T>::value,size_t>::type getByteSize(const T& /*obj*/)
780 {
781 return sizeof(T);
782 }
783
784 template <typename T>
785 inline typename std::enable_if<std::is_enum<T>::value>::type serialize(const T& obj,std::vector<char>& /*buffer*/,std::vector<char>::iterator& iter)
786 {
787 const uint8_t* ptr = reinterpret_cast<const uint8_t*>(&obj);
788 iter = std::copy(ptr,ptr+sizeof(T),iter);
789 }
790
791 template <typename T>
792 inline typename std::enable_if<std::is_enum<T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter)
793 {
794 uint8_t* ptr = reinterpret_cast<uint8_t*>(&obj);
795 std::copy(iter,iter+sizeof(T),ptr);
796 iter += sizeof(T);
797 }
798
799 // SerializableBase
800
801 template <typename T>
802 inline typename std::enable_if<std::is_base_of<SerializableBase,T>::value,size_t>::type getByteSize(const T& /*obj*/)
803 {
804 return sizeof(std::vector<char>::size_type);
805 }
806
807 template <typename T>
808 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)
809 {
810 // data
811 std::vector<char> tmp;
812 obj.Serialize(tmp);
813
814 // size
815 size_t size = buffer.size();
816 serialization::serialize(tmp.size(),buffer,iter);
817 size_t cur = iter - buffer.begin();
818
819 buffer.resize(size+tmp.size());
820 iter = buffer.begin()+cur;
821 iter = std::copy(tmp.begin(),tmp.end(),iter);
822 }
823
824 template <typename T>
825 inline typename std::enable_if<std::is_base_of<SerializableBase,T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter)
826 {
827 std::vector<char>::size_type size;
829
830 std::vector<char> tmp;
831 tmp.resize(size);
832 std::copy(iter,iter+size,tmp.begin());
833
834 obj.Deserialize(tmp);
835 iter += size;
836 }
837
838 // STL containers
839
840 // std::pair
841
842 template <typename T1,typename T2>
843 inline size_t getByteSize(const std::pair<T1,T2>& obj)
844 {
845 return getByteSize(obj.first)+getByteSize(obj.second);
846 }
847
848 template <typename T1,typename T2>
849 inline void serialize(const std::pair<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
850 {
851 serialization::serialize(obj.first,buffer,iter);
852 serialization::serialize(obj.second,buffer,iter);
853 }
854
855 template <typename T1,typename T2>
856 inline void deserialize(std::pair<T1,T2>& obj,std::vector<char>::const_iterator& iter)
857 {
858 serialization::deserialize(obj.first,iter);
859 serialization::deserialize(obj.second,iter);
860 }
861
862 // std::vector
863
864 template <typename T1,typename T2>
865 inline size_t getByteSize(const std::vector<T1,T2>& obj)
866 {
867 return std::accumulate(obj.begin(),obj.end(),sizeof(size_t),[](const size_t& acc,const T1& cur) { return acc+getByteSize(cur); });
868 }
869
870 template <typename T1,typename T2>
871 inline void serialize(const std::vector<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
872 {
873 size_t size = obj.size();
874 serialization::serialize(size,buffer,iter);
875 for(const T1& cur : obj)
876 {
877 serialization::serialize(cur,buffer,iter);
878 }
879 }
880
881 template <typename T1,typename T2>
882 inline void deserialize(std::vector<T1,T2>& obj,std::vector<char>::const_iterator& iter)
883 {
884 size_t size;
886
887 obj.resize(size);
888 for(T1& v : obj)
889 {
891 }
892 }
893
894 template <typename T2>
895 inline void deserialize(std::vector<bool,T2>& obj,std::vector<char>::const_iterator& iter)
896 {
897 size_t size;
899
900 obj.resize(size);
901 for(int i=0;i<obj.size();i++)
902 {
903 bool val;
905 obj[i] = val;
906 }
907 }
908
909 //std::set
910
911 template <typename T>
912 inline size_t getByteSize(const std::set<T>& obj)
913 {
914 return std::accumulate(obj.begin(),obj.end(),getByteSize(obj.size()),[](const size_t& acc,const T& cur) { return acc+getByteSize(cur); });
915 }
916
917 template <typename T>
918 inline void serialize(const std::set<T>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
919 {
920 serialization::serialize(obj.size(),buffer,iter);
921 for(const T& cur : obj)
922 {
923 serialization::serialize(cur,buffer,iter);
924 }
925 }
926
927 template <typename T>
928 inline void deserialize(std::set<T>& obj,std::vector<char>::const_iterator& iter)
929 {
930 size_t size;
932
933 obj.clear();
934 for(size_t i=0; i<size; ++i)
935 {
936 T val;
938 obj.insert(val);
939 }
940 }
941
942 // std::map
943
944 template <typename T1,typename T2>
945 inline size_t getByteSize(const std::map<T1,T2>& obj)
946 {
947 return std::accumulate(obj.begin(),obj.end(),sizeof(size_t),[](const size_t& acc,const std::pair<T1,T2>& cur) { return acc+getByteSize(cur); });
948 }
949
950 template <typename T1,typename T2>
951 inline void serialize(const std::map<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
952 {
953 serialization::serialize(obj.size(),buffer,iter);
954 for(const auto& cur : obj)
955 {
956 serialization::serialize(cur,buffer,iter);
957 }
958 }
959
960 template <typename T1,typename T2>
961 inline void deserialize(std::map<T1,T2>& obj,std::vector<char>::const_iterator& iter)
962 {
963 size_t size;
965
966 obj.clear();
967 for(size_t i=0; i<size; ++i)
968 {
969 std::pair<T1,T2> pair;
971 obj.insert(pair);
972 }
973 }
974
975 //std::list
976
977 template <typename T>
978 inline size_t getByteSize(const std::list<T>& obj)
979 {
980 return std::accumulate(obj.begin(), obj.end(), getByteSize(obj.size()), [](const size_t& acc, const T& cur) { return acc + getByteSize(cur); });
981 }
982
983 template <typename T>
984 inline void serialize(const std::list<T>& obj, std::vector<char>& buffer, std::vector<char>::iterator& iter)
985 {
986 serialization::serialize(obj.size(), buffer, iter);
987 for (const T& cur : obj)
988 {
989 serialization::serialize(cur, buffer, iter);
990 }
991 }
992
993 template <typename T>
994 inline void deserialize(std::list<T>& obj, std::vector<char>::const_iterator& iter)
995 {
996 size_t size;
997 serialization::deserialize(size, iter);
998
999 obj.clear();
1000 for (size_t i = 0; i < size; ++i)
1001 {
1002 T val;
1003 serialization::deserialize(val, iter);
1004 obj.emplace_back(val);
1005 }
1006 }
1007
1008
1009 // Eigen types
1010 template<typename T,int R,int C,int P,int MR,int MC>
1011 inline size_t getByteSize(const Eigen::Matrix<T,R,C,P,MR,MC>& obj)
1012 {
1013 // space for numbers of rows,cols and data
1014 return 2*sizeof(typename Eigen::Matrix<T,R,C,P,MR,MC>::Index)+sizeof(T)*obj.rows()*obj.cols();
1015 }
1016
1017 template<typename T,int R,int C,int P,int MR,int MC>
1018 inline void serialize(const Eigen::Matrix<T,R,C,P,MR,MC>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
1019 {
1020 serialization::serialize(obj.rows(),buffer,iter);
1021 serialization::serialize(obj.cols(),buffer,iter);
1022 size_t size = sizeof(T)*obj.rows()*obj.cols();
1023 auto ptr = reinterpret_cast<const uint8_t*>(obj.data());
1024 iter = std::copy(ptr,ptr+size,iter);
1025 }
1026
1027 template<typename T,int R,int C,int P,int MR,int MC>
1028 inline void deserialize(Eigen::Matrix<T,R,C,P,MR,MC>& obj,std::vector<char>::const_iterator& iter)
1029 {
1030 typename Eigen::Matrix<T,R,C,P,MR,MC>::Index rows,cols;
1031 serialization::deserialize(rows,iter);
1032 serialization::deserialize(cols,iter);
1033 size_t size = sizeof(T)*rows*cols;
1034 obj.resize(rows,cols);
1035 auto ptr = reinterpret_cast<uint8_t*>(obj.data());
1036 std::copy(iter,iter+size,ptr);
1037 iter+=size;
1038 }
1039
1040 template<typename T,int R,int C,int P,int MR,int MC>
1041 inline size_t getByteSize(const Eigen::Array<T,R,C,P,MR,MC>& obj)
1042 {
1043 // space for numbers of rows,cols and data
1044 return 2*sizeof(typename Eigen::Array<T,R,C,P,MR,MC>::Index)+sizeof(T)*obj.rows()*obj.cols();
1045 }
1046
1047 template<typename T,int R,int C,int P,int MR,int MC>
1048 inline void serialize(const Eigen::Array<T,R,C,P,MR,MC>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
1049 {
1050 serialization::serialize(obj.rows(),buffer,iter);
1051 serialization::serialize(obj.cols(),buffer,iter);
1052 size_t size = sizeof(T)*obj.rows()*obj.cols();
1053 auto ptr = reinterpret_cast<const uint8_t*>(obj.data());
1054 iter = std::copy(ptr,ptr+size,iter);
1055 }
1056
1057 template<typename T,int R,int C,int P,int MR,int MC>
1058 inline void deserialize(Eigen::Array<T,R,C,P,MR,MC>& obj,std::vector<char>::const_iterator& iter)
1059 {
1060 typename Eigen::Array<T,R,C,P,MR,MC>::Index rows,cols;
1061 serialization::deserialize(rows,iter);
1062 serialization::deserialize(cols,iter);
1063 size_t size = sizeof(T)*rows*cols;
1064 obj.resize(rows,cols);
1065 auto ptr = reinterpret_cast<uint8_t*>(obj.data());
1066 std::copy(iter,iter+size,ptr);
1067 iter+=size;
1068 }
1069
1070 template<typename T,int P,typename I>
1071 inline size_t getByteSize(const Eigen::SparseMatrix<T,P,I>& obj)
1072 {
1073 // space for numbers of rows,cols,nonZeros and tripplets with data (rowIdx,colIdx,value)
1074 size_t size = sizeof(typename Eigen::SparseMatrix<T,P,I>::Index);
1075 return 3*size+(sizeof(T)+2*size)*obj.nonZeros();
1076 }
1077
1078 template<typename T,int P,typename I>
1079 inline void serialize(const Eigen::SparseMatrix<T,P,I>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
1080 {
1081 serialization::serialize(obj.rows(),buffer,iter);
1082 serialization::serialize(obj.cols(),buffer,iter);
1083 serialization::serialize(obj.nonZeros(),buffer,iter);
1084
1085 for(int k=0;k<obj.outerSize();++k)
1086 {
1087 for(typename Eigen::SparseMatrix<T,P,I>::InnerIterator it(obj,k);it;++it)
1088 {
1089 serialization::serialize(it.row(),buffer,iter);
1090 serialization::serialize(it.col(),buffer,iter);
1091 serialization::serialize(it.value(),buffer,iter);
1092 }
1093 }
1094 }
1095
1096 template<typename T,int P,typename I>
1097 inline void deserialize(Eigen::SparseMatrix<T,P,I>& obj,std::vector<char>::const_iterator& iter)
1098 {
1099 typename Eigen::SparseMatrix<T,P,I>::Index rows,cols,nonZeros;
1100 serialization::deserialize(rows,iter);
1101 serialization::deserialize(cols,iter);
1102 serialization::deserialize(nonZeros,iter);
1103
1104 obj.resize(rows,cols);
1105 obj.setZero();
1106
1107 std::vector<Eigen::Triplet<T,I> > triplets;
1108 for(int i=0;i<nonZeros;i++)
1109 {
1110 typename Eigen::SparseMatrix<T,P,I>::Index rowId,colId;
1111 serialization::deserialize(rowId,iter);
1112 serialization::deserialize(colId,iter);
1113 T value;
1114 serialization::deserialize(value,iter);
1115 triplets.push_back(Eigen::Triplet<T,I>(rowId,colId,value));
1116 }
1117 obj.setFromTriplets(triplets.begin(),triplets.end());
1118 }
1119
1120 template<typename T,int P>
1121 inline size_t getByteSize(const Eigen::Quaternion<T,P>& /*obj*/)
1122 {
1123 return sizeof(T)*4;
1124 }
1125
1126 template<typename T,int P>
1127 inline void serialize(const Eigen::Quaternion<T,P>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
1128 {
1129 serialization::serialize(obj.w(),buffer,iter);
1130 serialization::serialize(obj.x(),buffer,iter);
1131 serialization::serialize(obj.y(),buffer,iter);
1132 serialization::serialize(obj.z(),buffer,iter);
1133 }
1134
1135 template<typename T,int P>
1136 inline void deserialize(Eigen::Quaternion<T,P>& obj,std::vector<char>::const_iterator& iter)
1137 {
1138 serialization::deserialize(obj.w(),iter);
1139 serialization::deserialize(obj.x(),iter);
1140 serialization::deserialize(obj.y(),iter);
1141 serialization::deserialize(obj.z(),iter);
1142 }
1143
1144 // pointers
1145
1146 template <typename T>
1147 inline typename std::enable_if<std::is_pointer<T>::value,size_t>::type getByteSize(const T& obj)
1148 {
1149 size_t size = sizeof(bool);
1150
1151 if(obj)
1152 size += getByteSize(*obj);
1153
1154 return size;
1155 }
1156
1157 template <typename T>
1158 inline typename std::enable_if<std::is_pointer<T>::value>::type serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
1159 {
1160 serialization::serialize(obj == nullptr,buffer,iter);
1161
1162 if(obj)
1163 serialization::serialize(*obj,buffer,iter);
1164 }
1165
1166 template <typename T>
1167 inline typename std::enable_if<std::is_pointer<T>::value>::type deserialize(T& obj,std::vector<char>::const_iterator& iter)
1168 {
1169 bool isNullPtr;
1170 serialization::deserialize(isNullPtr,iter);
1171
1172 if(isNullPtr)
1173 {
1174 if(obj)
1175 {
1176 std::cout << "serialization: possible memory leak in serialization for '" << typeid(obj).name() << "'" << std::endl;
1177 obj = nullptr;
1178 }
1179 }
1180 else
1181 {
1182 if(obj)
1183 {
1184 std::cout << "serialization: possible memory corruption in deserialization for '" << typeid(obj).name() << "'" << std::endl;
1185 }
1186 else
1187 {
1188 obj = new typename std::remove_pointer<T>::type();
1189 }
1190 serialization::deserialize(*obj,iter);
1191 }
1192 }
1193
1194 // std::shared_ptr and std::unique_ptr
1195
1196 template <typename T>
1197 inline typename std::enable_if<serialization::is_smart_ptr<T>::value,size_t>::type getByteSize(const T& obj)
1198 {
1199 return getByteSize(obj.get());
1200 }
1201
1202 template <typename T>
1203 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)
1204 {
1205 serialize(obj.get(),buffer,iter);
1206 }
1207
1208 template <template<typename> class T0,typename T1>
1209 inline typename std::enable_if<serialization::is_smart_ptr<T0<T1> >::value>::type deserialize(T0<T1>& obj,std::vector<char>::const_iterator& iter)
1210 {
1211 bool isNullPtr;
1212 serialization::deserialize(isNullPtr,iter);
1213
1214 if(isNullPtr)
1215 {
1216 obj.reset();
1217 }
1218 else
1219 {
1220 obj = T0<T1>(new T1());
1221 serialization::deserialize(*obj,iter);
1222 }
1223 }
1224
1225 // std::weak_ptr
1226
1227 template <typename T>
1228 inline size_t getByteSize(const std::weak_ptr<T>& /*obj*/)
1229 {
1230 return sizeof(size_t);
1231 }
1232
1233 template <typename T>
1234 inline void serialize(const std::weak_ptr<T>& /*obj*/,std::vector<char>& /*buffer*/,std::vector<char>::iterator& /*iter*/)
1235 {
1236
1237 }
1238
1239 template <typename T>
1240 inline void deserialize(std::weak_ptr<T>& /*obj*/,std::vector<char>::const_iterator& /*iter*/)
1241 {
1242
1243 }
1244
1245 // functions to overload for non-intrusive serialization
1246 template <typename T>
1247 inline void serialize(const T& obj,std::vector<char>& /*buffer*/)
1248 {
1249 std::cerr << typeid(obj).name() << " is not serializable: derive from igl::Serializable or specialize the template function igl::serialization::serialize(const T& obj,std::vector<char>& buffer)" << std::endl;
1250 }
1251
1252 template <typename T>
1253 inline void deserialize(T& obj,const std::vector<char>& /*buffer*/)
1254 {
1255 std::cerr << typeid(obj).name() << " is not deserializable: derive from igl::Serializable or specialize the template function igl::serialization::deserialize(T& obj, const std::vector<char>& buffer)" << std::endl;
1256 }
1257
1258 // helper functions
1259
1260 template <typename T>
1261 inline void updateMemoryMap(T& obj,size_t size,std::map<std::uintptr_t,IndexedPointerBase*>& memoryMap)
1262 {
1263 // check if object is already serialized
1264 auto startPtr = new IndexedPointer<T>();
1265 startPtr->Object = &obj;
1266 auto startBasePtr = static_cast<IndexedPointerBase*>(startPtr);
1267 startBasePtr->Type = IndexedPointerBase::BEGIN;
1268 auto startAddress = reinterpret_cast<std::uintptr_t>(&obj);
1269 auto p = std::pair<std::uintptr_t,IndexedPointerBase*>(startAddress,startBasePtr);
1270
1271 auto el = memoryMap.insert(p);
1272 auto iter = ++el.first; // next elememt
1273 if(el.second && (iter == memoryMap.end() || iter->second->Type != IndexedPointerBase::END))
1274 {
1275 // not yet serialized
1276 auto endPtr = new IndexedPointer<T>();
1277 auto endBasePtr = static_cast<IndexedPointerBase*>(endPtr);
1278 endBasePtr->Type = IndexedPointerBase::END;
1279 auto endAddress = reinterpret_cast<std::uintptr_t>(&obj) + size - 1;
1280 auto p = std::pair<std::uintptr_t,IndexedPointerBase*>(endAddress,endBasePtr);
1281
1282 // insert end address
1283 memoryMap.insert(el.first,p);
1284 }
1285 else
1286 {
1287 // already serialized
1288
1289 // remove inserted address
1290 memoryMap.erase(el.first);
1291 }
1292 }
1293 }
1294}
1295
1296#endif
Definition serialize.h:167
void Add(T &obj, std::string name, bool binary=false)
Definition serialize.h:673
virtual void PostSerialization() const
Definition serialize.h:589
Serializable()
Definition serialize.h:642
void Deserialize(const std::vector< char > &buffer) override final
Definition serialize.h:622
virtual bool PreDeserialization()
Definition serialize.h:593
void Serialize(std::vector< char > &buffer) const override final
Definition serialize.h:602
virtual void PostDeserialization()
Definition serialize.h:598
virtual bool PreSerialization() const
Definition serialize.h:584
Serializable & operator=(const Serializable &obj)
Definition serialize.h:659
virtual ~Serializable()
Definition serialize.h:653
virtual void InitSerialization()=0
std::enable_if<!is_serializable< T >::value, size_t >::type getByteSize(const T &obj)
Definition serialize.h:686
void deserialize(igl::opengl::ViewerCore &obj, const std::vector< char > &buffer)
Definition ViewerCore.h:286
void updateMemoryMap(T &obj, size_t size)
void serialize(const igl::opengl::ViewerCore &obj, std::vector< char > &buffer)
Definition ViewerCore.h:280
Definition AABB.h:17
void mode(const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > &X, const int d, Eigen::Matrix< T, Eigen::Dynamic, 1 > &M)
Takes mode of coefficients in a matrix along a given dimension.
bool serialize(const T &obj, const std::string &filename)
Definition serialize.h:424
bool deserialize(T &obj, const std::string &filename)
Definition serialize.h:494
bool serializer(bool serialize, T &obj, const std::string &filename)
Definition serialize.h:567
Definition serialize.h:221
enum igl::IndexedPointerBase::@2 Type
@ END
Definition serialize.h:222
@ BEGIN
Definition serialize.h:222
size_t Index
Definition serialize.h:223
Definition serialize.h:227
const T * Object
Definition serialize.h:228
Definition serialize.h:159
virtual void Serialize(std::vector< char > &buffer) const =0
virtual void Deserialize(const std::vector< char > &buffer)=0
virtual ~SerializableBase()=default
Definition serialize.h:249
static const bool value
Definition serialize.h:249
Definition serialize.h:267
static const bool value
Definition serialize.h:268
Definition serialize.h:258
static const bool value
Definition serialize.h:258
Definition serialize.h:236
static const bool value
Definition serialize.h:236