serialize.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. //
  2. // Copyright (C) 2014 Christian Schüller <schuellchr@gmail.com>
  3. //
  4. // This Source Code Form is subject to the terms of the Mozilla Public License
  5. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  6. // obtain one at http://mozilla.org/MPL/2.0/.
  7. #include "serialize.h"
  8. namespace igl
  9. {
  10. template <typename T>
  11. void serialize(const T& obj,const std::string& filename)
  12. {
  13. std::ofstream fout(filename.c_str(),std::ios::out | std::ios::binary);
  14. if(fout.is_open())
  15. {
  16. std::vector<char> buffer;
  17. serialize(obj,"obj",buffer);
  18. fout.write(&buffer[0],buffer.size());
  19. fout.close();
  20. }
  21. else
  22. {
  23. std::cerr << "Saving binary serialization failed!" << std::endl;
  24. }
  25. }
  26. template <typename T>
  27. void serialize(const T& obj,const std::string& objectName,std::vector<char>& buffer)
  28. {
  29. static_assert(detail::is_serializable<T>::value,"'igl::serialize': type is not serializable");
  30. // serialize object data
  31. size_t size = detail::getByteSize(obj);
  32. std::vector<char> tmp(size);
  33. detail::serialize(obj,tmp,tmp.begin());
  34. std::string objectType(typeid(obj).name());
  35. size_t curSize = buffer.size();
  36. size_t objSize = tmp.size();
  37. size_t newSize = curSize + detail::getByteSize(objectName) + detail::getByteSize(objectType) + sizeof(size_t)+objSize;
  38. buffer.resize(newSize);
  39. std::vector<char>::iterator iter = buffer.begin()+curSize;
  40. // serialize object header (name/type/size)
  41. detail::serialize(objectName,buffer,iter);
  42. detail::serialize(objectType,buffer,iter);
  43. detail::serialize(objSize,buffer,iter);
  44. // copy serilized data to buffer
  45. iter = std::copy(tmp.begin(),tmp.end(),iter);
  46. }
  47. template <typename T>
  48. void deserialize(T& obj,const std::string& filename)
  49. {
  50. std::ifstream file(filename.c_str(),std::ios::binary);
  51. if(file.is_open())
  52. {
  53. file.seekg(0,std::ios::end);
  54. int size = file.tellg();
  55. file.seekg(0,std::ios::beg);
  56. std::vector<char> buffer(size);
  57. file.read(&buffer[0],size);
  58. deserialize(obj,"obj",buffer);
  59. file.close();
  60. }
  61. else
  62. {
  63. std::cerr << "Loading binary serialization failed!" << std::endl;
  64. }
  65. }
  66. template <typename T>
  67. void deserialize(T& obj,const std::string& objectName,const std::vector<char>& buffer)
  68. {
  69. static_assert(detail::is_serializable<T>::value,"'igl::deserialize': type is not deserializable");
  70. // find suitable object header
  71. std::vector<char>::const_iterator iter = buffer.begin();
  72. while(iter != buffer.end())
  73. {
  74. std::string name;
  75. std::string type;
  76. size_t size;
  77. detail::deserialize(name,iter);
  78. detail::deserialize(type,iter);
  79. detail::deserialize(size,iter);
  80. if(name == objectName && type == typeid(obj).name())
  81. break;
  82. else
  83. iter+=size;
  84. }
  85. if(iter != buffer.end())
  86. detail::deserialize(obj,iter);
  87. else
  88. obj = T();
  89. }
  90. namespace detail
  91. {
  92. // fundamental types
  93. template <typename T>
  94. typename std::enable_if_t<std::is_fundamental<T>::value,size_t> getByteSize(const T& obj)
  95. {
  96. return sizeof(T);
  97. }
  98. template <typename T>
  99. std::enable_if_t<std::is_fundamental<T>::value> serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
  100. {
  101. const uint8_t* ptr = reinterpret_cast<const uint8_t*>(&obj);
  102. iter = std::copy(ptr,ptr+sizeof(T),iter);
  103. }
  104. template <typename T>
  105. std::enable_if_t<std::is_fundamental<T>::value> deserialize(T& obj,std::vector<char>::const_iterator& iter)
  106. {
  107. uint8_t* ptr = reinterpret_cast<uint8_t*>(&obj);
  108. std::copy(iter,iter+sizeof(T),ptr);
  109. iter += sizeof(T);
  110. }
  111. // std::string
  112. size_t getByteSize(const std::string& obj)
  113. {
  114. return getByteSize(obj.length())+obj.length()*sizeof(uint8_t);
  115. }
  116. void serialize(const std::string& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
  117. {
  118. detail::serialize(obj.length(),buffer,iter);
  119. for(const auto& cur : obj) { detail::serialize(cur,buffer,iter); }
  120. }
  121. void deserialize(std::string& obj,std::vector<char>::const_iterator& iter)
  122. {
  123. size_t size;
  124. detail::deserialize(size,iter);
  125. std::string str(size,'\0');
  126. for(size_t i=0; i<size; ++i)
  127. {
  128. detail::deserialize(str.at(i),iter);
  129. }
  130. obj = str;
  131. }
  132. // Serializable
  133. template <typename T>
  134. typename std::enable_if_t<std::is_base_of<Serializable,T>::value,size_t> getByteSize(const T& obj)
  135. {
  136. return sizeof(std::vector<char>::size_type);
  137. }
  138. template <typename T>
  139. std::enable_if_t<std::is_base_of<Serializable,T>::value> serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
  140. {
  141. // data
  142. std::vector<char> tmp;
  143. obj.Serialize(tmp);
  144. // size
  145. size_t size = buffer.size();
  146. detail::serialize(tmp.size(),buffer,iter);
  147. size_t cur = iter - buffer.begin();
  148. buffer.resize(size+tmp.size());
  149. iter = buffer.begin()+cur;
  150. iter = std::copy(tmp.begin(),tmp.end(),iter);
  151. }
  152. template <typename T>
  153. std::enable_if_t<std::is_base_of<Serializable,T>::value> deserialize(T& obj,std::vector<char>::const_iterator& iter)
  154. {
  155. std::vector<char>::size_type size;
  156. detail::deserialize(size,iter);
  157. std::vector<char> tmp;
  158. tmp.resize(size);
  159. std::copy(iter,iter+size,tmp.begin());
  160. obj.Deserialize(tmp);
  161. iter += size;
  162. }
  163. // STL containers
  164. // std::pair
  165. template <typename T1,typename T2>
  166. size_t getByteSize(const std::pair<T1,T2>& obj)
  167. {
  168. return getByteSize(obj.first)+getByteSize(obj.second);
  169. }
  170. template <typename T1,typename T2>
  171. void serialize(const std::pair<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
  172. {
  173. detail::serialize(obj.first,buffer,iter);
  174. detail::serialize(obj.second,buffer,iter);
  175. }
  176. template <typename T1,typename T2>
  177. void deserialize(std::pair<T1,T2>& obj,std::vector<char>::const_iterator& iter)
  178. {
  179. detail::deserialize(obj.first,iter);
  180. detail::deserialize(obj.second,iter);
  181. }
  182. // std::vector
  183. template <typename T1,typename T2>
  184. size_t getByteSize(const std::vector<T1,T2>& obj)
  185. {
  186. return std::accumulate(obj.begin(),obj.end(),sizeof(size_t),[](const size_t& acc,const T1& cur) { return acc+getByteSize(cur); });
  187. }
  188. template <typename T1,typename T2>
  189. void serialize(const std::vector<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
  190. {
  191. size_t size = obj.size();
  192. detail::serialize(size,buffer,iter);
  193. for(const auto& cur : obj)
  194. {
  195. detail::serialize(cur,buffer,iter);
  196. }
  197. }
  198. template <typename T1,typename T2>
  199. void deserialize(std::vector<T1,T2>& obj,std::vector<char>::const_iterator& iter)
  200. {
  201. size_t size;
  202. detail::deserialize(size,iter);
  203. obj.resize(size);
  204. for(size_t i=0; i<size; ++i)
  205. {
  206. detail::deserialize(obj[i],iter);
  207. }
  208. }
  209. //std::set
  210. template <typename T>
  211. size_t getByteSize(const std::set<T>& obj)
  212. {
  213. return std::accumulate(obj.begin(),obj.end(),getByteSize(obj.size()),[](const size_t& acc,const T& cur) { return acc+getByteSize(cur); });
  214. }
  215. template <typename T>
  216. void serialize(const std::set<T>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
  217. {
  218. detail::serialize(obj.size(),buffer,iter);
  219. for(const auto& cur : obj) { detail::serialize(cur,buffer,iter); }
  220. }
  221. template <typename T>
  222. void deserialize(std::set<T>& obj,std::vector<char>::const_iterator& iter)
  223. {
  224. size_t size;
  225. detail::deserialize(size,iter);
  226. obj.clear();
  227. for(size_t i=0; i<size; ++i)
  228. {
  229. T val;
  230. detail::deserialize(val,iter);
  231. obj.insert(val);
  232. }
  233. }
  234. // std::map
  235. template <typename T1,typename T2>
  236. size_t getByteSize(const std::map<T1,T2>& obj)
  237. {
  238. return std::accumulate(obj.begin(),obj.end(),sizeof(size_t),[](const size_t& acc,const std::pair<T1,T2>& cur) { return acc+getByteSize(cur); });
  239. }
  240. template <typename T1,typename T2>
  241. void serialize(const std::map<T1,T2>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
  242. {
  243. detail::serialize(obj.size(),buffer,iter);
  244. for(const auto& cur : obj) { detail::serialize(cur,buffer,iter); }
  245. }
  246. template <typename T1,typename T2>
  247. void deserialize(std::map<T1,T2>& obj,std::vector<char>::const_iterator& iter)
  248. {
  249. size_t size;
  250. detail::deserialize(size,iter);
  251. obj.clear();
  252. for(size_t i=0; i<size; ++i)
  253. {
  254. std::pair<T1,T2> pair;
  255. detail::deserialize(pair,iter);
  256. obj.insert(pair);
  257. }
  258. }
  259. // Eigen types
  260. template<typename T,int R,int C,int P,int MR,int MC>
  261. size_t getByteSize(const Eigen::Matrix<T,R,C,P,MR,MC>& obj)
  262. {
  263. // space for numbers of rows,cols and data
  264. return 2*sizeof(Eigen::Matrix<T,R,C,P,MR,MC>::Index)+sizeof(T)*obj.rows()*obj.cols();
  265. }
  266. template<typename T,int R,int C,int P,int MR,int MC>
  267. void serialize(const Eigen::Matrix<T,R,C,P,MR,MC>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
  268. {
  269. detail::serialize(obj.rows(),buffer,iter);
  270. detail::serialize(obj.cols(),buffer,iter);
  271. size_t size = sizeof(T)*obj.rows()*obj.cols();
  272. const uint8_t* ptr = reinterpret_cast<const uint8_t*>(obj.data());
  273. iter = std::copy(ptr,ptr+size,iter);
  274. }
  275. template<typename T,int R,int C,int P,int MR,int MC>
  276. void deserialize(Eigen::Matrix<T,R,C,P,MR,MC>& obj,std::vector<char>::const_iterator& iter)
  277. {
  278. Eigen::Matrix<T,R,C,P,MR,MC>::Index rows,cols;
  279. detail::deserialize(rows,iter);
  280. detail::deserialize(cols,iter);
  281. size_t size = sizeof(T)*rows*cols;
  282. obj.resize(rows,cols);
  283. uint8_t* ptr = reinterpret_cast<uint8_t*>(obj.data());
  284. std::copy(iter,iter+size,ptr);
  285. iter+=size;
  286. }
  287. template<typename T,int P,typename I>
  288. size_t getByteSize(const Eigen::SparseMatrix<T,P,I>& obj)
  289. {
  290. // space for numbers of rows,cols,nonZeros and tripplets with data (rowIdx,colIdx,value)
  291. size_t size = sizeof(Eigen::SparseMatrix<T,P,I>::Index);
  292. return 3*size+(sizeof(T)+2*size)*obj.nonZeros();
  293. }
  294. template<typename T,int P,typename I>
  295. void serialize(const Eigen::SparseMatrix<T,P,I>& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
  296. {
  297. detail::serialize(obj.rows(),buffer,iter);
  298. detail::serialize(obj.cols(),buffer,iter);
  299. detail::serialize(obj.nonZeros(),buffer,iter);
  300. for(int k=0;k<obj.outerSize();++k)
  301. {
  302. for(typename Eigen::SparseMatrix<T,P,I>::InnerIterator it(obj,k);it;++it)
  303. {
  304. detail::serialize(it.row(),buffer,iter);
  305. detail::serialize(it.col(),buffer,iter);
  306. detail::serialize(it.value(),buffer,iter);
  307. }
  308. }
  309. }
  310. template<typename T,int P,typename I>
  311. void deserialize(Eigen::SparseMatrix<T,P,I>& obj,std::vector<char>::const_iterator& iter)
  312. {
  313. Eigen::SparseMatrix<T,P,I>::Index rows,cols,nonZeros;
  314. detail::deserialize(rows,iter);
  315. detail::deserialize(cols,iter);
  316. detail::deserialize(nonZeros,iter);
  317. obj.resize(rows,cols);
  318. obj.setZero();
  319. std::vector<Eigen::Triplet<T,I> > triplets;
  320. for(int i=0;i<nonZeros;i++)
  321. {
  322. Eigen::SparseMatrix<T,P,I>::Index rowId,colId;
  323. detail::deserialize(rowId,iter);
  324. detail::deserialize(colId,iter);
  325. T value;
  326. detail::deserialize(value,iter);
  327. triplets.push_back(Eigen::Triplet<T,I>(rowId,colId,value));
  328. }
  329. obj.setFromTriplets(triplets.begin(),triplets.end());
  330. }
  331. // pointers
  332. template <typename T>
  333. std::enable_if_t<std::is_pointer<T>::value,size_t> getByteSize(const T& obj)
  334. {
  335. bool isNullPtr = (obj == NULL);
  336. size_t size = sizeof(bool);
  337. if(isNullPtr == false)
  338. size += getByteSize(*obj);
  339. return size;
  340. }
  341. template <typename T>
  342. std::enable_if_t<std::is_pointer<T>::value> serialize(const T& obj,std::vector<char>& buffer,std::vector<char>::iterator& iter)
  343. {
  344. bool isNullPtr = (obj == NULL);
  345. detail::serialize(isNullPtr,buffer,iter);
  346. if(isNullPtr == false)
  347. detail::serialize(*obj,buffer,iter);
  348. }
  349. template <typename T>
  350. std::enable_if_t<std::is_pointer<T>::value> deserialize(T& obj,std::vector<char>::const_iterator& iter)
  351. {
  352. bool isNullPtr;
  353. detail::deserialize(isNullPtr,iter);
  354. if(isNullPtr)
  355. {
  356. if(obj != NULL)
  357. {
  358. std::cout << "deserialization: possible memory leak for '" << typeid(obj).name() << "'" << std::endl;
  359. obj = NULL;
  360. }
  361. }
  362. else
  363. {
  364. if(obj != NULL)
  365. std::cout << "deserialization: possible memory leak for '" << typeid(obj).name() << "'" << std::endl;
  366. obj = new std::remove_pointer<T>::type();
  367. detail::deserialize(*obj,iter);
  368. }
  369. }
  370. }
  371. }