XMLSerializer.cpp 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878
  1. #include "XMLSerializer.h"
  2. namespace igl
  3. {
  4. int numForbiddenChars = 8;
  5. char forbiddenChars[] = {' ','/','~','#','&','>','<','='};
  6. }
  7. void igl::ReplaceSubString(std::string& str, const std::string& search, const std::string& replace)
  8. {
  9. size_t pos = 0;
  10. while ((pos = str.find(search, pos)) != std::string::npos)
  11. {
  12. str.replace(pos, search.length(), replace);
  13. pos += replace.length();
  14. }
  15. }
  16. void igl::EncodeXMLElementName(std::string& name)
  17. {
  18. // must not start with a digit
  19. if(isdigit(*name.begin()))
  20. {
  21. name = ":::" + name;
  22. }
  23. std::stringstream stream;
  24. for(int i=0;i<numForbiddenChars;i++)
  25. {
  26. std::string search;
  27. search = forbiddenChars[i];
  28. std::stringstream replaces;
  29. replaces << ":" << (int)forbiddenChars[i];
  30. std::string replace = replaces.str();
  31. ReplaceSubString(name,search,replace);
  32. }
  33. }
  34. /*void igl::DecodeXMLElementName(std::string& name)
  35. {
  36. if(name.find("::", 0) == 0)
  37. name.replace(0,3,"");
  38. std::stringstream stream;
  39. for(int i=0;i<numForbiddenChars;i++)
  40. {
  41. std::stringstream searchs;
  42. searchs << ":" << (int)forbiddenChars[i];
  43. std::string search = searchs.str();
  44. std::string replace;
  45. replace = forbiddenChars[i];
  46. ReplaceSubString(name,search,replace);
  47. }
  48. }*/
  49. void igl::XMLSerialization::Init()
  50. {
  51. }
  52. bool igl::XMLSerialization::Serialize(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element)
  53. {
  54. bool serialized;
  55. if(BeforeSerialization())
  56. {
  57. serialized = xmlSerializer->SaveGroupToXMLElement(doc,element,Name);
  58. AfterSerialization();
  59. }
  60. return serialized;
  61. }
  62. bool igl::XMLSerialization::Deserialize(tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element)
  63. {
  64. bool serialized;
  65. if(BeforeDeserialization())
  66. {
  67. serialized = xmlSerializer->LoadGroupFromXMLElement(Name,doc,element);
  68. AfterDeserialization();
  69. }
  70. return serialized;
  71. }
  72. igl::XMLSerialization::XMLSerialization(const std::string& name)
  73. {
  74. Name = name;
  75. xmlSerializer = new igl::XMLSerializer(name);
  76. }
  77. igl::XMLSerialization::~XMLSerialization()
  78. {
  79. delete xmlSerializer;
  80. }
  81. bool igl::XMLSerialization::BeforeSerialization()
  82. {
  83. return true;
  84. }
  85. void igl::XMLSerialization::AfterSerialization()
  86. {
  87. }
  88. bool igl::XMLSerialization::BeforeDeserialization()
  89. {
  90. return true;
  91. }
  92. void igl::XMLSerialization::AfterDeserialization()
  93. {
  94. }
  95. igl::XMLSerializableObject::XMLSerializableObject(const std::string& name, const std::string& group)
  96. {
  97. std::string groupName = group;
  98. std::string objectName = name;
  99. igl::EncodeXMLElementName(groupName);
  100. igl::EncodeXMLElementName(objectName);
  101. Name = objectName;
  102. }
  103. igl::XMLSerializableObject::~XMLSerializableObject()
  104. {
  105. }
  106. // set attribute conversion functions
  107. void igl::XMLSerializableObject::SetAttribute(tinyxml2::XMLElement* element, const char* name, char& dest)
  108. {
  109. element->SetAttribute(name,dest);
  110. }
  111. void igl::XMLSerializableObject::SetAttribute(tinyxml2::XMLElement* element, const char* name, char*& dest)
  112. {
  113. element->SetAttribute(name,const_cast<const char*>(dest));
  114. }
  115. void igl::XMLSerializableObject::SetAttribute(tinyxml2::XMLElement* element, const char* name, std::string& dest)
  116. {
  117. element->SetAttribute(name,dest.c_str());
  118. }
  119. void igl::XMLSerializableObject::SetAttribute(tinyxml2::XMLElement* element, const char* name, bool& dest)
  120. {
  121. element->SetAttribute(name,dest);
  122. }
  123. void igl::XMLSerializableObject::SetAttribute(tinyxml2::XMLElement* element, const char* name, unsigned int& dest)
  124. {
  125. element->SetAttribute(name,dest);
  126. }
  127. void igl::XMLSerializableObject::SetAttribute(tinyxml2::XMLElement* element, const char* name, int& dest)
  128. {
  129. element->SetAttribute(name,dest);
  130. }
  131. void igl::XMLSerializableObject::SetAttribute(tinyxml2::XMLElement* element, const char* name, float& dest)
  132. {
  133. element->SetAttribute(name,dest);
  134. }
  135. void igl::XMLSerializableObject::SetAttribute(tinyxml2::XMLElement* element, const char* name, double& dest)
  136. {
  137. element->SetAttribute(name,dest);
  138. }
  139. // get attribute conversion functions
  140. void igl::XMLSerializableObject::GetAttribute(const char* src, char& dest)
  141. {
  142. dest = (char)atoi(src);
  143. }
  144. void igl::XMLSerializableObject::GetAttribute(const char* src, char*& dest)
  145. {
  146. unsigned int length = strlen(src)+1;
  147. dest = new char[length];
  148. strcpy(dest, src);
  149. }
  150. void igl::XMLSerializableObject::GetAttribute(const char* src, std::string& dest)
  151. {
  152. dest = src;
  153. }
  154. void igl::XMLSerializableObject::GetAttribute(const char* src, bool& dest)
  155. {
  156. tinyxml2::XMLUtil::ToBool(src,&dest);
  157. }
  158. void igl::XMLSerializableObject::GetAttribute(const char* src, unsigned int& dest)
  159. {
  160. tinyxml2::XMLUtil::ToUnsigned(src,&dest);
  161. }
  162. void igl::XMLSerializableObject::GetAttribute(const char* src, int& dest)
  163. {
  164. tinyxml2::XMLUtil::ToInt(src,&dest);
  165. }
  166. void igl::XMLSerializableObject::GetAttribute(const char* src, float& dest)
  167. {
  168. tinyxml2::XMLUtil::ToFloat(src,&dest);
  169. }
  170. void igl::XMLSerializableObject::GetAttribute(const char* src, double& dest)
  171. {
  172. tinyxml2::XMLUtil::ToDouble(src,&dest);
  173. }
  174. // specify default value of types
  175. template<typename T>
  176. void igl::XMLSerializableObject::Init(T*& obj)
  177. {
  178. igl::XMLSerializable* object = static_cast<igl::XMLSerializable*>(obj);
  179. object->Init();
  180. }
  181. template<>
  182. void igl::XMLSerializableObject::Init(char& val)
  183. {
  184. val = '0';
  185. }
  186. template<>
  187. void igl::XMLSerializableObject::Init(char*& val)
  188. {
  189. val = NULL;
  190. }
  191. template<>
  192. void igl::XMLSerializableObject::Init(std::string& val)
  193. {
  194. val = "";
  195. }
  196. template<>
  197. void igl::XMLSerializableObject::Init(bool& val)
  198. {
  199. val = false;
  200. }
  201. template<>
  202. void igl::XMLSerializableObject::Init(unsigned int& val)
  203. {
  204. val = 0;
  205. }
  206. template<>
  207. void igl::XMLSerializableObject::Init(int& val)
  208. {
  209. val = 0;
  210. }
  211. template<>
  212. void igl::XMLSerializableObject::Init(float& val)
  213. {
  214. val = 0.0f;
  215. }
  216. template<>
  217. void igl::XMLSerializableObject::Init(double& val)
  218. {
  219. val = 0.000000000000000;
  220. }
  221. template<typename T, int S>
  222. void igl::XMLSerializableObject::Init(std::array<T,S>& obj)
  223. {
  224. for(int i=0;i<obj.size();i++)
  225. Init(obj[i]);
  226. }
  227. template<typename T0, typename T1>
  228. void igl::XMLSerializableObject::Init(std::pair<T0,T1>& obj)
  229. {
  230. Init(obj.first);
  231. Init(obj.second);
  232. }
  233. template<typename T>
  234. void igl::XMLSerializableObject::Init(std::vector<T>& obj)
  235. {
  236. obj.clear();
  237. }
  238. template<typename T, int R, int C>
  239. void igl::XMLSerializableObject::Init(Eigen::Matrix<T,R,C>& obj)
  240. {
  241. obj.setZero(obj.rows(),obj.cols());
  242. }
  243. template<typename T>
  244. void igl::XMLSerializableObject::Init(Eigen::SparseMatrix<T>& obj)
  245. {
  246. obj.setZero();
  247. }
  248. template<typename T>
  249. bool igl::XMLSerializableObject::Serialize(T& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  250. {
  251. return false;
  252. }
  253. template<typename T>
  254. bool igl::XMLSerializableObject::Serialize(T*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  255. {
  256. // Serialize object implementing XMLSerializable interface
  257. igl::XMLSerializable* object = static_cast<igl::XMLSerializable*>(obj);
  258. tinyxml2::XMLElement* child = doc->NewElement(name.c_str());
  259. element->InsertEndChild(child);
  260. return object->Serialize(doc,child);
  261. }
  262. template<>
  263. bool igl::XMLSerializableObject::Serialize(char& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  264. {
  265. return setElementAttribute(obj,doc,element,name);
  266. }
  267. // template specialisation for char*, it interpreted as char array and can be used to handle strings
  268. template<>
  269. bool igl::XMLSerializableObject::Serialize(char*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  270. {
  271. return setElementAttribute(obj,doc,element,name);
  272. }
  273. template<>
  274. bool igl::XMLSerializableObject::Serialize(std::string& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  275. {
  276. return setElementAttribute(obj,doc,element,name);
  277. }
  278. template<>
  279. bool igl::XMLSerializableObject::Serialize(std::string*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  280. {
  281. return Serialize(*obj,doc,element,name);
  282. }
  283. template<>
  284. bool igl::XMLSerializableObject::Serialize(bool& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  285. {
  286. return setElementAttribute(obj,doc,element,name);
  287. }
  288. template<>
  289. bool igl::XMLSerializableObject::Serialize(bool*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  290. {
  291. return Serialize(*obj,doc,element,name);
  292. }
  293. template<>
  294. bool igl::XMLSerializableObject::Serialize(unsigned int& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  295. {
  296. return setElementAttribute(obj,doc,element,name);
  297. }
  298. template<>
  299. bool igl::XMLSerializableObject::Serialize(unsigned int*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  300. {
  301. return Serialize(*obj,doc,element,name);
  302. }
  303. template<>
  304. bool igl::XMLSerializableObject::Serialize(int& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  305. {
  306. return setElementAttribute(obj,doc,element,name);
  307. }
  308. template<>
  309. bool igl::XMLSerializableObject::Serialize(int*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  310. {
  311. return Serialize(*obj,doc,element,name);
  312. }
  313. template<>
  314. bool igl::XMLSerializableObject::Serialize(float& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  315. {
  316. return setElementAttribute(obj,doc,element,name);
  317. }
  318. template<>
  319. bool igl::XMLSerializableObject::Serialize(float*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  320. {
  321. return Serialize(*obj,doc,element,name);
  322. }
  323. template<>
  324. bool igl::XMLSerializableObject::Serialize(double& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  325. {
  326. return setElementAttribute(obj,doc,element,name);
  327. }
  328. template<>
  329. bool igl::XMLSerializableObject::Serialize(double*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  330. {
  331. return Serialize(*obj,doc,element,name);
  332. }
  333. template<typename T>
  334. bool igl::XMLSerializableObject::Deserialize(T& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  335. {
  336. return false;
  337. }
  338. template<typename T>
  339. bool igl::XMLSerializableObject::Deserialize(T*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  340. {
  341. obj = new T();
  342. igl::XMLSerializable* object = static_cast<igl::XMLSerializable*>(obj);
  343. const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
  344. object->Name = child->FirstChild()->Value();
  345. if(child != NULL)
  346. {
  347. obj->Deserialize(doc,child);
  348. }
  349. else
  350. {
  351. obj->Init();
  352. return false;
  353. }
  354. }
  355. template<>
  356. bool igl::XMLSerializableObject::Deserialize(char& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  357. {
  358. return getElementAttribute(obj,doc,element,name);
  359. }
  360. // template specialisation for char*, it interpreted as char array and can be used to handle strings
  361. template<>
  362. bool igl::XMLSerializableObject::Deserialize(char*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  363. {
  364. return getElementAttribute(obj,doc,element,name);
  365. }
  366. template<>
  367. bool igl::XMLSerializableObject::Deserialize(std::string& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  368. {
  369. return getElementAttribute(obj,doc,element,name);
  370. }
  371. template<>
  372. bool igl::XMLSerializableObject::Deserialize(std::string*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  373. {
  374. return Deserialize(*obj,doc,element,name);
  375. }
  376. template<>
  377. bool igl::XMLSerializableObject::Deserialize(bool& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  378. {
  379. return getElementAttribute(obj,doc,element,name);
  380. }
  381. template<>
  382. bool igl::XMLSerializableObject::Deserialize(bool*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  383. {
  384. return Deserialize(*obj,doc,element,name);
  385. }
  386. template<>
  387. bool igl::XMLSerializableObject::Deserialize(unsigned int& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  388. {
  389. return getElementAttribute(obj,doc,element,name);
  390. }
  391. template<>
  392. bool igl::XMLSerializableObject::Deserialize(unsigned int*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  393. {
  394. return Deserialize(*obj,doc,element,name);
  395. }
  396. template<>
  397. bool igl::XMLSerializableObject::Deserialize(int& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  398. {
  399. return getElementAttribute(obj,doc,element,name);
  400. }
  401. template<>
  402. bool igl::XMLSerializableObject::Deserialize(int*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  403. {
  404. return Deserialize(*obj,doc,element,name);
  405. }
  406. template<>
  407. bool igl::XMLSerializableObject::Deserialize(float& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  408. {
  409. return getElementAttribute(obj,doc,element,name);
  410. }
  411. template<>
  412. bool igl::XMLSerializableObject::Deserialize(float*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  413. {
  414. return Deserialize(*obj,doc,element,name);
  415. }
  416. template<>
  417. bool igl::XMLSerializableObject::Deserialize(double& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  418. {
  419. return getElementAttribute(obj,doc,element,name);
  420. }
  421. template<>
  422. bool igl::XMLSerializableObject::Deserialize(double*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  423. {
  424. return Deserialize(*obj,doc,element,name);
  425. }
  426. template<typename T, int S>
  427. bool igl::XMLSerializableObject::Serialize(std::array<T,S>& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  428. {
  429. tinyxml2::XMLElement* ar = doc->NewElement(name.c_str());
  430. element->InsertEndChild(ar);
  431. ar->SetAttribute("size",obj.size());
  432. std::stringstream num;
  433. for(int i=0;i<obj.size();i++)
  434. {
  435. num.str("");
  436. num << "value" << i;
  437. Serialize(obj[i],doc,ar,num.str());
  438. }
  439. return true;
  440. }
  441. template<typename T, int S>
  442. bool igl::XMLSerializableObject::Serialize(std::array<T,S>*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  443. {
  444. return Serialize(*obj,doc,element,name);
  445. }
  446. template<typename T, int S>
  447. bool igl::XMLSerializableObject::Deserialize(std::array<T,S>& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  448. {
  449. bool res = true;
  450. const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
  451. if(child != NULL)
  452. {
  453. int size = child->UnsignedAttribute("size");
  454. size = std::min(S,size);
  455. std::stringstream num;
  456. const tinyxml2::XMLAttribute* attribute = NULL;
  457. for(int i=0;i<size;i++)
  458. {
  459. num.str("");
  460. num << "value" << i;
  461. res &= Deserialize(obj[i],doc,child,num.str());
  462. }
  463. }
  464. else
  465. return false;
  466. return res;
  467. }
  468. template<typename T, int S>
  469. bool igl::XMLSerializableObject::Deserialize(std::array<T,S>*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  470. {
  471. obj = new std::array<T,S>();
  472. return Deserialize(*obj,doc,element,name);
  473. }
  474. template<typename T0, typename T1>
  475. bool igl::XMLSerializableObject::Serialize(std::pair<T0,T1>& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  476. {
  477. bool res = true;
  478. tinyxml2::XMLElement* pair = doc->NewElement(name.c_str());
  479. element->InsertEndChild(pair);
  480. res &= Serialize(obj.first,doc,pair,"first");
  481. res &= Serialize(obj.second,doc,pair,"second");
  482. return res;
  483. }
  484. template<typename T0, typename T1>
  485. bool igl::XMLSerializableObject::Serialize(std::pair<T0,T1>*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  486. {
  487. return Serialize(*obj,doc,element,name);
  488. }
  489. template<typename T0, typename T1>
  490. bool igl::XMLSerializableObject::Deserialize(std::pair<T0,T1>& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  491. {
  492. bool res = true;
  493. const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
  494. if(child != NULL)
  495. {
  496. res &= Deserialize(obj.first,doc,child,"first");
  497. res &= Deserialize(obj.second,doc,child,"second");
  498. }
  499. else
  500. {
  501. Init(obj.first);
  502. Init(obj.second);
  503. return false;
  504. }
  505. return res;
  506. }
  507. template<typename T0, typename T1>
  508. bool igl::XMLSerializableObject::Deserialize(std::pair<T0,T1>*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  509. {
  510. obj = new std::pair<T0,T1>();
  511. return Deserialize(*obj,doc,element,name);
  512. }
  513. template<typename T>
  514. bool igl::XMLSerializableObject::Serialize(std::vector<T>& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  515. {
  516. tinyxml2::XMLElement* vector = doc->NewElement(name.c_str());
  517. element->InsertEndChild(vector);
  518. vector->SetAttribute("size",obj.size());
  519. std::stringstream num;
  520. for(int i=0;i<obj.size();i++)
  521. {
  522. num.str("");
  523. num << "value" << i;
  524. Serialize(obj[i],doc,vector,num.str());
  525. }
  526. return true;
  527. }
  528. template<typename T>
  529. bool igl::XMLSerializableObject::Deserialize(std::vector<T>& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  530. {
  531. bool res = true;
  532. obj.clear();
  533. const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
  534. if(child != NULL)
  535. {
  536. int size = child->UnsignedAttribute("size");
  537. obj.resize(size);
  538. std::stringstream num;
  539. const tinyxml2::XMLAttribute* attribute = NULL;
  540. for(int i=0;i<size;i++)
  541. {
  542. num.str("");
  543. num << "value" << i;
  544. res &= Deserialize(obj[i],doc,child,num.str());
  545. }
  546. }
  547. else
  548. return false;
  549. return res;
  550. }
  551. template<typename T>
  552. bool igl::XMLSerializableObject::Serialize(std::vector<T>*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  553. {
  554. return Serialize(*obj,doc,element,name);
  555. }
  556. template<typename T>
  557. bool igl::XMLSerializableObject::Deserialize(std::vector<T>*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  558. {
  559. obj = new vector<T>();
  560. return Deserialize(*obj,doc,element,name);
  561. }
  562. template<typename T, int R, int C>
  563. bool igl::XMLSerializableObject::Serialize(Eigen::Matrix<T,R,C>& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  564. {
  565. tinyxml2::XMLElement* matrix = doc->NewElement(name.c_str());
  566. element->InsertEndChild(matrix);
  567. const int rows = obj.rows();
  568. const int cols = obj.cols();
  569. matrix->SetAttribute("rows",rows);
  570. matrix->SetAttribute("cols",cols);
  571. std::stringstream ms;
  572. ms << "\n";
  573. for(int r=0;r<rows;r++)
  574. {
  575. for(int c=0;c<cols;c++)
  576. {
  577. ms << obj(r,c) << ",";
  578. }
  579. ms << "\n";
  580. }
  581. std::string mString = ms.str();
  582. if(mString.size() > 1)
  583. mString[mString.size()-2] = '\0';
  584. matrix->SetAttribute("matrix",mString.c_str());
  585. return true;
  586. }
  587. template<typename T, int R, int C>
  588. bool igl::XMLSerializableObject::Serialize(Eigen::Matrix<T,R,C>*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  589. {
  590. return Serialize(*obj,doc,element,name);
  591. }
  592. template<typename T, int R, int C>
  593. bool igl::XMLSerializableObject::Deserialize(Eigen::Matrix<T,R,C>& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  594. {
  595. const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
  596. if(child != NULL)
  597. {
  598. const int rows = child->UnsignedAttribute("rows");
  599. const int cols = child->UnsignedAttribute("cols");
  600. obj.resize(rows,cols);
  601. const tinyxml2::XMLAttribute* attribute = child->FindAttribute("matrix");
  602. if(attribute == NULL)
  603. {
  604. Init(obj);
  605. return false;
  606. }
  607. char* matTemp;
  608. GetAttribute(attribute->Value(),matTemp);
  609. std::string line, srows, scols;
  610. std::stringstream mats;
  611. mats.str(matTemp);
  612. int r=0;
  613. std::string val;
  614. // for each line
  615. getline(mats,line);
  616. while(getline(mats,line))
  617. {
  618. // get current line
  619. std::stringstream liness(line);
  620. for(int c=0;c<cols-1;c++)
  621. {
  622. // split line
  623. getline(liness, val, ',');
  624. // push pack the data if any
  625. if(!val.empty())
  626. GetAttribute(val.c_str(),obj.coeffRef(r,c));
  627. }
  628. getline(liness, val);
  629. GetAttribute(val.c_str(),obj.coeffRef(r,cols-1));
  630. r++;
  631. }
  632. }
  633. else
  634. {
  635. Init(obj);
  636. return false;
  637. }
  638. return true;
  639. }
  640. template<typename T, int R, int C>
  641. bool igl::XMLSerializableObject::Deserialize(Eigen::Matrix<T,R,C>*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  642. {
  643. obj = new Eigen::PlainObjectBase<T>();
  644. return Deserialize(*obj,doc,element,name);
  645. }
  646. template<typename T>
  647. bool igl::XMLSerializableObject::Serialize(Eigen::SparseMatrix<T>& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  648. {
  649. tinyxml2::XMLElement* matrix = doc->NewElement(name.c_str());
  650. element->InsertEndChild(matrix);
  651. const int rows = obj.rows();
  652. const int cols = obj.cols();
  653. matrix->SetAttribute("rows",rows);
  654. matrix->SetAttribute("cols",cols);
  655. std::stringstream ms;
  656. ms << "\n";
  657. for (int k=0;k<obj.outerSize();++k)
  658. {
  659. for (Eigen::SparseMatrix<T>::InnerIterator it(obj,k);it;++it)
  660. {
  661. ms << it.row() << "," << it.col() << "," << it.value() << "\n";
  662. }
  663. }
  664. std::string mString = ms.str();
  665. if(mString.size() > 0)
  666. mString[mString.size()-1] = '\0';
  667. matrix->SetAttribute("matrix",mString.c_str());
  668. return true;
  669. }
  670. template<typename T>
  671. bool igl::XMLSerializableObject::Serialize(Eigen::SparseMatrix<T>*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  672. {
  673. return Serialize(*obj,doc,element,name);
  674. }
  675. template<typename T>
  676. bool igl::XMLSerializableObject::Deserialize(Eigen::SparseMatrix<T>& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  677. {
  678. const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
  679. if(child != NULL)
  680. {
  681. const int rows = child->UnsignedAttribute("rows");
  682. const int cols = child->UnsignedAttribute("cols");
  683. obj.resize(rows,cols);
  684. obj.setZero();
  685. const tinyxml2::XMLAttribute* attribute = child->FindAttribute("matrix");
  686. if(attribute == NULL)
  687. {
  688. Init(obj);
  689. return false;
  690. }
  691. char* matTemp;
  692. GetAttribute(attribute->Value(),matTemp);
  693. std::string line, srows, scols;
  694. std::stringstream mats;
  695. mats.str(matTemp);
  696. std::vector<Eigen::Triplet<T>> triplets;
  697. int r=0;
  698. std::string val;
  699. // for each line
  700. getline(mats,line);
  701. while(getline(mats,line))
  702. {
  703. // get current line
  704. std::stringstream liness(line);
  705. // row
  706. getline(liness, val, ',');
  707. int row = atoi(val.c_str());
  708. // col
  709. getline(liness, val, ',');
  710. int col = atoi(val.c_str());
  711. // val
  712. getline(liness, val);
  713. T value;
  714. GetAttribute(val.c_str(),value);
  715. triplets.push_back(Eigen::Triplet<T>(row,col,value));
  716. r++;
  717. }
  718. obj.setFromTriplets(triplets.begin(),triplets.end());
  719. }
  720. else
  721. {
  722. Init(obj);
  723. return false;
  724. }
  725. return true;
  726. }
  727. template<typename T>
  728. bool igl::XMLSerializableObject::Deserialize(Eigen::SparseMatrix<T>*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  729. {
  730. obj = new Eigen::SparseMatrix<T>();
  731. return Deserialize(*obj,doc,element,name);
  732. }
  733. template<typename T>
  734. bool igl::XMLSerializableObject::setElementAttribute(T& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  735. {
  736. tinyxml2::XMLElement* child = doc->NewElement(name.c_str());
  737. element->InsertEndChild(child);
  738. SetAttribute(child,"val",obj);
  739. return true;
  740. }
  741. template<typename T>
  742. bool igl::XMLSerializableObject::getElementAttribute(T& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  743. {
  744. // basic data type
  745. const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
  746. if(child != NULL)
  747. {
  748. igl::XMLSerializableObject::GetAttribute(child->Attribute("val"),obj);
  749. return true;
  750. }
  751. else
  752. {
  753. Init(obj);
  754. return false;
  755. }
  756. }
  757. template<typename T>
  758. igl::XMLSerializableInstance<T>::XMLSerializableInstance(T& obj, const std::string& name, const std::string group)
  759. : XMLSerializableObject(name, group), Object(obj)
  760. {
  761. igl::XMLSerializableObject::Init(DefaultValue);
  762. }
  763. template<typename T>
  764. igl::XMLSerializableInstance<T>::XMLSerializableInstance(T& obj, const std::string& name, const std::string group, T defaultValue)
  765. : XMLSerializableObject(name, group), Object(obj), DefaultValue(defaultValue)
  766. {
  767. }
  768. template<typename T>
  769. igl::XMLSerializableInstance<T>::~XMLSerializableInstance()
  770. {
  771. }
  772. template<typename T>
  773. void igl::XMLSerializableInstance<T>::Init()
  774. {
  775. igl::XMLSerializableObject::Init(DefaultValue);
  776. }
  777. template<typename T>
  778. bool igl::XMLSerializableInstance<T>::Serialize(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element)
  779. {
  780. return igl::XMLSerializableObject::Serialize(Object,doc,element,Name);
  781. }
  782. template<typename T>
  783. bool igl::XMLSerializableInstance<T>::Deserialize(tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element)
  784. {
  785. return igl::XMLSerializableObject::Deserialize(Object,doc,element,Name);
  786. }
  787. template<typename T>
  788. static bool igl::XMLSerializer::SaveObject(T& object, const char* filename)
  789. {
  790. return SaveObject(object,"Object","Serialization",filename,true);
  791. }
  792. template<typename T>
  793. static bool igl::XMLSerializer::SaveObject(T& object, const std::string& objectName, const std::string& groupName, const char* filename, bool overwrite)
  794. {
  795. bool result = true;
  796. XMLSerializer* serializer = new XMLSerializer(groupName);
  797. result &= serializer->Add(object,objectName);
  798. result &= serializer->Save(objectName,groupName,filename,overwrite);
  799. delete serializer;
  800. return result;
  801. }
  802. template<typename T>
  803. static bool igl::XMLSerializer::LoadObject(T& object, const char* filename)
  804. {
  805. return LoadObject(object,"Object","Serialization",filename);
  806. }
  807. template<typename T>
  808. static bool igl::XMLSerializer::LoadObject(T& object, const std::string& objectName, const std::string& groupName, const char* filename)
  809. {
  810. bool result = true;
  811. XMLSerializer* serializer = new XMLSerializer(groupName);
  812. result &= serializer->Add(object,objectName);
  813. result &= serializer->Load(objectName,groupName,filename);
  814. delete serializer;
  815. return result;
  816. }
  817. igl::XMLSerializer::XMLSerializer(const std::string& defaultGroup)
  818. {
  819. SetCurrentGroup(defaultGroup);
  820. }
  821. igl::XMLSerializer::~XMLSerializer()
  822. {
  823. std::map<std::string,XMLSerializerGroup*>::iterator it;
  824. for (it=groups.begin();it!=groups.end();it++)
  825. {
  826. delete it->second->Objects;
  827. delete it->second;
  828. }
  829. }
  830. bool igl::XMLSerializer::Save(const char* filename, bool overwrite)
  831. {
  832. tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument();
  833. if(overwrite == false)
  834. {
  835. // Check if file exists
  836. tinyxml2::XMLError error = doc->LoadFile(filename);
  837. if(error != tinyxml2::XML_NO_ERROR)
  838. doc->Clear();
  839. }
  840. if(SaveToXMLDoc(doc) == false)
  841. return false;
  842. // Save
  843. tinyxml2::XMLError error = doc->SaveFile(filename);
  844. if(error != tinyxml2::XML_NO_ERROR)
  845. {
  846. doc->PrintError();
  847. return false;
  848. }
  849. delete doc;
  850. return true;
  851. }
  852. bool igl::XMLSerializer::SaveToXMLDoc(tinyxml2::XMLDocument* doc)
  853. {
  854. std::map<std::string,XMLSerializerGroup*>::iterator it;
  855. for (it=groups.begin();it!=groups.end();it++)
  856. {
  857. // Update group
  858. tinyxml2::XMLElement* element = doc->FirstChildElement(it->first.c_str());
  859. if(element != NULL)
  860. {
  861. element->DeleteChildren();
  862. }
  863. else
  864. {
  865. element = doc->NewElement(it->first.c_str());
  866. doc->InsertEndChild(element);
  867. }
  868. std::vector<XMLSerializable*>* group = it->second->Objects;
  869. for(int i=0;i<group->size();i++)
  870. {
  871. if((*group)[i]->Serialize(doc,element) == false)
  872. return false;
  873. }
  874. }
  875. return true;
  876. }
  877. bool igl::XMLSerializer::Save(const std::string& groupName, const char* filename, bool overwrite)
  878. {
  879. tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument();
  880. if(overwrite == false)
  881. {
  882. // Check if file exists
  883. tinyxml2::XMLError error = doc->LoadFile(filename);
  884. if(error != tinyxml2::XML_NO_ERROR)
  885. doc->Clear();
  886. }
  887. if(SaveToXMLDoc(groupName, doc) == false)
  888. return false;
  889. // Save
  890. tinyxml2::XMLError error = doc->SaveFile(filename);
  891. if(error != tinyxml2::XML_NO_ERROR)
  892. {
  893. doc->PrintError();
  894. return false;
  895. }
  896. delete doc;
  897. return true;
  898. }
  899. bool igl::XMLSerializer::SaveToXMLDoc(const std::string& groupName, tinyxml2::XMLDocument* doc)
  900. {
  901. std::string gn = groupName;
  902. EncodeXMLElementName(gn);
  903. std::map<std::string,XMLSerializerGroup*>::iterator it = groups.find(gn);
  904. if(it == groups.end())
  905. return false;
  906. // Update group
  907. tinyxml2::XMLElement* element = doc->FirstChildElement(it->first.c_str());
  908. if(element != NULL)
  909. {
  910. element->DeleteChildren();
  911. }
  912. else
  913. {
  914. element = doc->NewElement(it->first.c_str());
  915. doc->InsertEndChild(element);
  916. }
  917. std::vector<XMLSerializable*>* groups = it->second->Objects;
  918. for(int i=0;i<groups->size();i++)
  919. {
  920. if((*groups)[i]->Serialize(doc,element) == false)
  921. return false;
  922. }
  923. return true;
  924. }
  925. bool igl::XMLSerializer::Save(const std::string& objectName, const std::string& groupName, const char* filename, bool overwrite)
  926. {
  927. tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument();
  928. if(overwrite == false)
  929. {
  930. // Check if file exists
  931. tinyxml2::XMLError error = doc->LoadFile(filename);
  932. if(error != tinyxml2::XML_NO_ERROR)
  933. doc->Clear();
  934. }
  935. if(SaveToXMLDoc(objectName, groupName, doc) == false)
  936. return false;
  937. // Save
  938. tinyxml2::XMLError error = doc->SaveFile(filename);
  939. if(error != tinyxml2::XML_NO_ERROR)
  940. {
  941. doc->PrintError();
  942. return false;
  943. }
  944. delete doc;
  945. return true;
  946. }
  947. bool igl::XMLSerializer::SaveToXMLDoc(const std::string& objectName, const std::string& groupName, tinyxml2::XMLDocument* doc)
  948. {
  949. std::string gn = groupName;
  950. EncodeXMLElementName(gn);
  951. std::string on = objectName;
  952. EncodeXMLElementName(on);
  953. std::map<std::string,XMLSerializerGroup*>::iterator it = groups.find(gn);
  954. if(it == groups.end())
  955. return false;
  956. // Get/Add group
  957. tinyxml2::XMLElement* element = findAddGroup(doc, it->first.c_str());
  958. // Serialize
  959. std::vector<XMLSerializable*>* groups = it->second->Objects;
  960. bool found = false;
  961. for(int i=0;i<groups->size();i++)
  962. {
  963. if((*groups)[i]->Name == on)
  964. {
  965. found = true;
  966. tinyxml2::XMLElement* child = element->FirstChildElement(on.c_str());
  967. if(child != NULL)
  968. {
  969. element->DeleteChild(child);
  970. }
  971. if((*groups)[i]->Serialize(doc,element) == false)
  972. return false;
  973. }
  974. }
  975. return found;
  976. }
  977. bool igl::XMLSerializer::SaveGroupToXMLElement(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  978. {
  979. return SaveGroupToXMLElement(currentGroup->first,doc,element,name);
  980. }
  981. bool igl::XMLSerializer::SaveGroupToXMLElement(const std::string& groupName, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  982. {
  983. std::string gn = groupName;
  984. EncodeXMLElementName(gn);
  985. std::map<std::string,XMLSerializerGroup*>::iterator it = groups.find(gn);
  986. if(it == groups.end())
  987. return false;
  988. // Add new group
  989. tinyxml2::XMLElement* group = doc->NewElement(name.c_str());
  990. element->InsertEndChild(group);
  991. std::vector<XMLSerializable*>* groups = it->second->Objects;
  992. for(int i=0;i<groups->size();i++)
  993. {
  994. if((*groups)[i]->Serialize(doc,group) == false)
  995. return false;
  996. }
  997. return true;
  998. }
  999. bool igl::XMLSerializer::Load(const char* filename)
  1000. {
  1001. tinyxml2::XMLDocument* doc = openDoc(filename);
  1002. if(doc == NULL)
  1003. return false;
  1004. if(LoadFromXMLDoc(doc) == false)
  1005. return false;
  1006. delete doc;
  1007. return true;
  1008. }
  1009. bool igl::XMLSerializer::LoadFromXMLDoc(tinyxml2::XMLDocument* doc)
  1010. {
  1011. std::map<std::string,XMLSerializerGroup*>::iterator it;
  1012. for (it=groups.begin();it!=groups.end();it++)
  1013. {
  1014. tinyxml2::XMLElement* element = doc->FirstChildElement(it->first.c_str());
  1015. if(element == NULL)
  1016. return false;
  1017. // Deserialize
  1018. std::vector<XMLSerializable*>* group = it->second->Objects;
  1019. for(int i=0;i<group->size();i++)
  1020. {
  1021. if(element == NULL || (*group)[i]->Deserialize(doc,element) == false)
  1022. (*group)[i]->Init(); // Load default value;
  1023. }
  1024. }
  1025. return true;
  1026. }
  1027. bool igl::XMLSerializer::Load(const std::string& groupName, const char* filename)
  1028. {
  1029. tinyxml2::XMLDocument* doc = openDoc(filename);
  1030. if(doc == NULL)
  1031. return false;
  1032. if(LoadFromXMLDoc(groupName, doc) == false)
  1033. return false;
  1034. delete doc;
  1035. return true;
  1036. }
  1037. bool igl::XMLSerializer::LoadFromXMLDoc(const std::string& groupName, tinyxml2::XMLDocument* doc)
  1038. {
  1039. std::string gn = groupName;
  1040. EncodeXMLElementName(gn);
  1041. std::map<std::string,XMLSerializerGroup*>::iterator it = groups.find(gn);
  1042. if(it == groups.end())
  1043. return false;
  1044. tinyxml2::XMLElement* element = doc->FirstChildElement(it->first.c_str());
  1045. if(element == NULL)
  1046. return false;
  1047. // Deserialize
  1048. std::vector<XMLSerializable*>* groups = it->second->Objects;
  1049. for(int i=0;i<groups->size();i++)
  1050. {
  1051. if(element == NULL || (*groups)[i]->Deserialize(doc,element) == false)
  1052. (*groups)[i]->Init(); // Load default value;
  1053. }
  1054. return true;
  1055. }
  1056. bool igl::XMLSerializer::Load(const std::string& objectName, const std::string& groupName, const char* filename)
  1057. {
  1058. tinyxml2::XMLDocument* doc = openDoc(filename);
  1059. if(doc == NULL)
  1060. return false;
  1061. if(LoadFromXMLDoc(objectName,groupName,doc) == false)
  1062. return false;
  1063. delete doc;
  1064. return true;
  1065. }
  1066. bool igl::XMLSerializer::LoadFromXMLDoc(const std::string& objectName, const std::string& groupName, tinyxml2::XMLDocument* doc)
  1067. {
  1068. std::string gn = groupName;
  1069. EncodeXMLElementName(gn);
  1070. std::string on = objectName;
  1071. EncodeXMLElementName(on);
  1072. std::map<std::string,XMLSerializerGroup*>::iterator it = groups.find(gn);
  1073. if(it == groups.end())
  1074. return false;
  1075. tinyxml2::XMLElement* element = doc->FirstChildElement(it->first.c_str());
  1076. if(element == NULL)
  1077. return false;
  1078. // Deserialize
  1079. std::vector<XMLSerializable*>* groups = it->second->Objects;
  1080. bool found = false;
  1081. for(int i=0;i<groups->size();i++)
  1082. {
  1083. if((*groups)[i]->Name == on)
  1084. {
  1085. found = true;
  1086. if(element == NULL || (*groups)[i]->Deserialize(doc,element) == false)
  1087. (*groups)[i]->Init(); // Load default value;
  1088. }
  1089. }
  1090. return found;
  1091. }
  1092. bool igl::XMLSerializer::LoadGroupFromXMLElement(const std::string& groupName, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element)
  1093. {
  1094. std::string gn = groupName;
  1095. EncodeXMLElementName(gn);
  1096. std::map<std::string,XMLSerializerGroup*>::iterator it = groups.find(gn);
  1097. if(it == groups.end())
  1098. return false;
  1099. const tinyxml2::XMLElement* group = element->FirstChildElement(groupName.c_str());
  1100. if(group == NULL)
  1101. return false;
  1102. // Deserialize
  1103. std::vector<XMLSerializable*>* groups = it->second->Objects;
  1104. for(int i=0;i<groups->size();i++)
  1105. {
  1106. if(element == NULL || (*groups)[i]->Deserialize(doc,group) == false)
  1107. (*groups)[i]->Init(); // Load default value;
  1108. }
  1109. return true;
  1110. }
  1111. void igl::XMLSerializer::SetCurrentGroup(const std::string& group)
  1112. {
  1113. currentGroup = setGetGroup(group);
  1114. }
  1115. std::string igl::XMLSerializer::GetCurrentGroup()
  1116. {
  1117. return currentGroup->first;
  1118. }
  1119. template<typename T>
  1120. bool igl::XMLSerializer::Add(T& obj, const std::string& name)
  1121. {
  1122. igl::XMLSerializable* object = static_cast<igl::XMLSerializable*>(obj);
  1123. object->Name = name;
  1124. return addObjectToGroup(object,currentGroup);
  1125. }
  1126. template<>
  1127. bool igl::XMLSerializer::Add(char& obj, const std::string& name)
  1128. {
  1129. return add(obj,name);
  1130. }
  1131. template<>
  1132. bool igl::XMLSerializer::Add(char*& obj, const std::string& name)
  1133. {
  1134. return add(obj,name);
  1135. }
  1136. template<>
  1137. bool igl::XMLSerializer::Add(std::string& obj, const std::string& name)
  1138. {
  1139. return add(obj,name);
  1140. }
  1141. template<>
  1142. bool igl::XMLSerializer::Add(bool& obj, const std::string& name)
  1143. {
  1144. return add(obj,name);
  1145. }
  1146. template<>
  1147. bool igl::XMLSerializer::Add(unsigned int& obj, const std::string& name)
  1148. {
  1149. return add(obj,name);
  1150. }
  1151. template<>
  1152. bool igl::XMLSerializer::Add(int& obj, const std::string& name)
  1153. {
  1154. return add(obj,name);
  1155. }
  1156. template<>
  1157. bool igl::XMLSerializer::Add(float& obj, const std::string& name)
  1158. {
  1159. return add(obj,name);
  1160. }
  1161. template<>
  1162. bool igl::XMLSerializer::Add(double& obj, const std::string& name)
  1163. {
  1164. return add(obj,name);
  1165. }
  1166. template<typename T, int S>
  1167. bool igl::XMLSerializer::Add(std::array<T,S>& obj, const std::string& name)
  1168. {
  1169. return add(obj,name);
  1170. }
  1171. template<typename T0, typename T1>
  1172. bool igl::XMLSerializer::Add(std::pair<T0,T1>& obj, const std::string& name)
  1173. {
  1174. return add(obj,name);
  1175. }
  1176. template<typename T>
  1177. bool igl::XMLSerializer::Add(std::vector<T>& obj, const std::string& name)
  1178. {
  1179. return add(obj,name);
  1180. }
  1181. template<typename T, int R, int C>
  1182. bool igl::XMLSerializer::Add(Eigen::Matrix<T,R,C>& obj, const std::string& name)
  1183. {
  1184. return add(obj,name);
  1185. }
  1186. template<typename T>
  1187. bool igl::XMLSerializer::Add(Eigen::SparseMatrix<T>& obj, const std::string& name)
  1188. {
  1189. return add(obj,name);
  1190. }
  1191. template<typename T>
  1192. bool igl::XMLSerializer::Add(T& object, const std::string& name, T defaultValue)
  1193. {
  1194. }
  1195. template<>
  1196. bool igl::XMLSerializer::Add(char& obj, const std::string& name, char defaultValue)
  1197. {
  1198. return add(obj,name,defaultValue);
  1199. }
  1200. template<>
  1201. bool igl::XMLSerializer::Add(char*& obj, const std::string& name, char* defaultValue)
  1202. {
  1203. return add(obj,name,defaultValue);
  1204. }
  1205. template<>
  1206. bool igl::XMLSerializer::Add(std::string& obj, const std::string& name, std::string defaultValue)
  1207. {
  1208. return add(obj,name,defaultValue);
  1209. }
  1210. template<>
  1211. bool igl::XMLSerializer::Add(bool& obj, const std::string& name, bool defaultValue)
  1212. {
  1213. return add(obj,name,defaultValue);
  1214. }
  1215. template<>
  1216. bool igl::XMLSerializer::Add(unsigned int& obj, const std::string& name, unsigned int defaultValue)
  1217. {
  1218. return add(obj,name,defaultValue);
  1219. }
  1220. template<>
  1221. bool igl::XMLSerializer::Add(int& obj, const std::string& name, int defaultValue)
  1222. {
  1223. return add(obj,name,defaultValue);
  1224. }
  1225. template<>
  1226. bool igl::XMLSerializer::Add(float& obj, const std::string& name, float defaultValue)
  1227. {
  1228. return add(obj,name,defaultValue);
  1229. }
  1230. template<>
  1231. bool igl::XMLSerializer::Add(double& obj, const std::string& name, double defaultValue)
  1232. {
  1233. return add(obj,name,defaultValue);
  1234. }
  1235. template<typename T>
  1236. bool igl::XMLSerializer::add(T& obj, const std::string& name)
  1237. {
  1238. XMLSerializable* object = new igl::XMLSerializableInstance<T>(obj,name,currentGroup->first);
  1239. return addObjectToGroup(object,currentGroup);
  1240. }
  1241. template<typename T>
  1242. bool igl::XMLSerializer::add(T& obj, const std::string& name, T defaultValue)
  1243. {
  1244. igl::XMLSerializable* object = new igl::XMLSerializableInstance<T>(obj,name,currentGroup->first,defaultValue);
  1245. return addObjectToGroup(object,currentGroup);
  1246. }
  1247. bool igl::XMLSerializer::addObjectToGroup(XMLSerializable* obj, const std::string& group)
  1248. {
  1249. std::map<std::string,XMLSerializerGroup*>::iterator it = setGetGroup(group);
  1250. return addObjectToGroup(obj, it);
  1251. }
  1252. bool igl::XMLSerializer::addObjectToGroup(XMLSerializable* object, std::map<std::string,XMLSerializerGroup*>::iterator it)
  1253. {
  1254. std::vector<XMLSerializable*>* objects = it->second->Objects;
  1255. for(int i=0;i<objects->size();i++)
  1256. {
  1257. if((*objects)[i]->Name == object->Name)
  1258. return false;
  1259. }
  1260. objects->push_back(object);
  1261. return true;
  1262. }
  1263. std::map<std::string,igl::XMLSerializerGroup*>::iterator igl::XMLSerializer::setGetGroup(const std::string& group)
  1264. {
  1265. std::string groupName = group;
  1266. EncodeXMLElementName(groupName);
  1267. std::map<std::string,XMLSerializerGroup*>::iterator it = groups.find(groupName);
  1268. if(it == groups.end())
  1269. {
  1270. XMLSerializerGroup* newGroup = new XMLSerializerGroup();
  1271. newGroup->Objects = new std::vector<XMLSerializable*>();
  1272. groups[groupName] = newGroup;
  1273. it = groups.find(groupName);
  1274. }
  1275. return it;
  1276. }
  1277. tinyxml2::XMLDocument* igl::XMLSerializer::openDoc(const char* filename)
  1278. {
  1279. tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument();
  1280. tinyxml2::XMLError error = doc->LoadFile(filename);
  1281. if(error != tinyxml2::XML_NO_ERROR)
  1282. {
  1283. doc->PrintError();
  1284. doc = NULL;
  1285. }
  1286. return doc;
  1287. }
  1288. tinyxml2::XMLElement* igl::XMLSerializer::findAddGroup(tinyxml2::XMLDocument* doc, const char* groupName)
  1289. {
  1290. tinyxml2::XMLElement* group = doc->FirstChildElement(groupName);
  1291. if(group == NULL)
  1292. {
  1293. group = doc->NewElement(groupName);
  1294. doc->InsertEndChild(group);
  1295. }
  1296. return group;
  1297. }
  1298. igl::XMLSerializerTest::XMLSerializerTest()
  1299. : XMLSerialization("testObject")
  1300. {
  1301. xmlSerializer->Add(testInt,"testInt");
  1302. xmlSerializer->Add(testVector,"testVector");
  1303. testInt = 10;
  1304. testVector.push_back(1.0001f);
  1305. testVector.push_back(2.0001f);
  1306. testVector.push_back(3.0001f);
  1307. }
  1308. bool igl::XMLSerializerTest::Test()
  1309. {
  1310. // test vars 0
  1311. char testChar0 = 'a';
  1312. char* testCharArray0 = "testCharArray0";
  1313. std::string testString0 = "testString0";
  1314. bool testBool0 = true;
  1315. unsigned int testUnsigned0 = 13;
  1316. int testInt0 = 1000;
  1317. float testFloat0 = 0.00001f;
  1318. double testDouble0 = 0.01000000005;
  1319. std::array<float,2> testArray0 = {0.001f,1.001f};
  1320. std::pair<int,bool> testPair0;
  1321. testPair0.first = 5;
  1322. testPair0.second = true;
  1323. std::vector<int> testVector0;
  1324. testVector0.push_back(1);
  1325. testVector0.push_back(2);
  1326. testVector0.push_back(3);
  1327. Eigen::MatrixXi testDenseMatrix0;
  1328. testDenseMatrix0 = Eigen::Matrix3i::Identity();
  1329. Eigen::SparseMatrix<double> testSparseMatrix0(3,3);
  1330. std::vector<Eigen::Triplet<double>> triplets;
  1331. triplets.push_back(Eigen::Triplet<double>(0,0,1));
  1332. triplets.push_back(Eigen::Triplet<double>(1,1,2));
  1333. triplets.push_back(Eigen::Triplet<double>(2,2,3));
  1334. testSparseMatrix0.setFromTriplets(triplets.begin(),triplets.end());
  1335. igl::XMLSerializerTest* testObject0 = new igl::XMLSerializerTest();
  1336. std::vector<std::pair<int,bool>*> testComplex10;
  1337. testComplex10.push_back(&testPair0);
  1338. testComplex10.push_back(&testPair0);
  1339. std::vector<igl::XMLSerializerTest*> testComplex20;
  1340. testComplex20.push_back(testObject0);
  1341. testComplex20.push_back(testObject0);
  1342. // test vars 1
  1343. char testChar1 = 'b';
  1344. char* testCharArray1 = "testCharArray1";
  1345. std::string testString1 = "testString1";
  1346. bool testBool1 = false;
  1347. unsigned int testUnsigned1 = 12;
  1348. int testInt1 = -1000;
  1349. float testFloat1 = -0.00001f;
  1350. double testDouble1 = -0.000000000001;
  1351. std::array<float,2> testArray1 = {-0.001f,-1.001f};
  1352. std::pair<int,bool> testPair1;
  1353. testPair1.first = -5;
  1354. testPair1.second = false;
  1355. std::vector<int> testVector1;
  1356. testVector1.push_back(-1);
  1357. testVector1.push_back(-2);
  1358. testVector1.push_back(-3);
  1359. Eigen::MatrixXi testDenseMatrix1;
  1360. testDenseMatrix1 = Eigen::Matrix3i::Identity();
  1361. testDenseMatrix1 *= 2;
  1362. Eigen::SparseMatrix<double> testSparseMatrix1(3,3);
  1363. triplets.clear();
  1364. triplets.push_back(Eigen::Triplet<double>(0,0,-1));
  1365. triplets.push_back(Eigen::Triplet<double>(1,1,-2));
  1366. triplets.push_back(Eigen::Triplet<double>(2,2,-3));
  1367. testSparseMatrix1.setFromTriplets(triplets.begin(),triplets.end());
  1368. igl::XMLSerializerTest* testObject1 = new igl::XMLSerializerTest();
  1369. testObject1->testInt = 3;
  1370. testObject1->testVector.clear();
  1371. std::vector<std::pair<int,bool>*> testComplex11;
  1372. testComplex11.push_back(&testPair1);
  1373. testComplex11.push_back(&testPair1);
  1374. std::vector<igl::XMLSerializerTest*> testComplex21;
  1375. testComplex21.push_back(testObject1);
  1376. testComplex21.push_back(testObject1);
  1377. // test Serializer
  1378. bool testResult = true;
  1379. // test static functions
  1380. // check static updating
  1381. int testInt = 5;
  1382. testResult &= igl::XMLSerializer::SaveObject(testInt0,"test.xml");
  1383. testResult &= igl::XMLSerializer::SaveObject(testChar0,"testChar","test","test.xml",false);
  1384. testResult &= igl::XMLSerializer::LoadObject(testInt,"test.xml");
  1385. testResult &= testInt0 == testInt;
  1386. // check static overwriting
  1387. testInt = 3;
  1388. testResult &= igl::XMLSerializer::SaveObject(testInt0,"test.xml");
  1389. testResult &= igl::XMLSerializer::SaveObject(testChar0,"testChar","test","test.xml",true);
  1390. testResult &= igl::XMLSerializer::LoadObject(testInt,"test.xml") == false;
  1391. testResult &= testInt0 != testInt;
  1392. // check static based type saving
  1393. testResult &= igl::XMLSerializer::SaveObject(testChar0,"testChar","test0","test.xml",true);
  1394. testResult &= igl::XMLSerializer::SaveObject(testCharArray0,"testCharArray","test0","test.xml",false);
  1395. testResult &= igl::XMLSerializer::SaveObject(testString0,"testString","test0","test.xml",false);
  1396. testResult &= igl::XMLSerializer::SaveObject(testBool0,"testBool","test0","test.xml",false);
  1397. testResult &= igl::XMLSerializer::SaveObject(testUnsigned0,"testUnsigned","test0","test.xml",false);
  1398. testResult &= igl::XMLSerializer::SaveObject(testInt0,"testInt","test0","test.xml",false);
  1399. testResult &= igl::XMLSerializer::SaveObject(testFloat0,"testFloat","test0","test.xml",false);
  1400. testResult &= igl::XMLSerializer::SaveObject(testDouble0,"testDouble","test0","test.xml",false);
  1401. testResult &= igl::XMLSerializer::SaveObject(testArray0,"testArray","test1","test.xml",false);
  1402. testResult &= igl::XMLSerializer::SaveObject(testPair0,"testPair","test1","test.xml",false);
  1403. testResult &= igl::XMLSerializer::SaveObject(testVector0,"testVector","test1","test.xml",false);
  1404. testResult &= igl::XMLSerializer::SaveObject(testDenseMatrix0,"testDense","test1","test.xml",false);
  1405. testResult &= igl::XMLSerializer::SaveObject(testSparseMatrix0,"testSparse","test1","test.xml",false);
  1406. testResult &= igl::XMLSerializer::SaveObject(testObject0,"testObject","test1","test.xml",false);
  1407. testResult &= igl::XMLSerializer::SaveObject(testComplex10,"testComplex1","test1","test.xml",false);
  1408. testResult &= igl::XMLSerializer::SaveObject(testComplex20,"testComplex2","test1","test.xml",false);
  1409. testResult &= igl::XMLSerializer::LoadObject(testChar1,"testChar","test0","test.xml");
  1410. testResult &= igl::XMLSerializer::LoadObject(testCharArray1,"testCharArray","test0","test.xml");
  1411. testResult &= igl::XMLSerializer::LoadObject(testString1,"testString","test0","test.xml");
  1412. testResult &= igl::XMLSerializer::LoadObject(testBool1,"testBool","test0","test.xml");
  1413. testResult &= igl::XMLSerializer::LoadObject(testUnsigned1,"testUnsigned","test0","test.xml");
  1414. testResult &= igl::XMLSerializer::LoadObject(testInt1,"testInt","test0","test.xml");
  1415. testResult &= igl::XMLSerializer::LoadObject(testFloat1,"testFloat","test0","test.xml");
  1416. testResult &= igl::XMLSerializer::LoadObject(testDouble1,"testDouble","test0","test.xml");
  1417. testResult &= igl::XMLSerializer::LoadObject(testArray1,"testArray","test1","test.xml");
  1418. testResult &= igl::XMLSerializer::LoadObject(testPair1,"testPair","test1","test.xml");
  1419. testResult &= igl::XMLSerializer::LoadObject(testVector1,"testVector","test1","test.xml");
  1420. testResult &= igl::XMLSerializer::LoadObject(testDenseMatrix1,"testDense","test1","test.xml");
  1421. testResult &= igl::XMLSerializer::LoadObject(testSparseMatrix1,"testSparse","test1","test.xml");
  1422. testResult &= igl::XMLSerializer::LoadObject(testObject1,"testObject","test1","test.xml");
  1423. testResult &= igl::XMLSerializer::LoadObject(testComplex11,"testComplex1","test1","test.xml");
  1424. testResult &= igl::XMLSerializer::LoadObject(testComplex21,"testComplex2","test1","test.xml");
  1425. testResult &= testChar0 == testChar1;
  1426. testResult &= strcmp(testCharArray0,testCharArray1) == 0;
  1427. testResult &= testString0 == testString1;
  1428. testResult &= testBool0 == testBool1;
  1429. testResult &= testUnsigned0 == testUnsigned1;
  1430. testResult &= testInt0 == testInt1;
  1431. testResult &= testFloat0 == testFloat1;
  1432. testResult &= testDouble0 == testDouble1;
  1433. for(int i=0;i<testArray0.size();i++)
  1434. testResult &= testArray0[i] == testArray1[i];
  1435. testResult &= testPair0.first == testPair1.first;
  1436. testResult &= testPair0.second == testPair1.second;
  1437. testResult &= testVector0.size() == testVector1.size();
  1438. for(int i=0;i<testVector0.size();i++)
  1439. testResult &= testVector0[i] == testVector1[i];
  1440. testResult &= (testDenseMatrix0-testDenseMatrix1).sum() == 0;
  1441. testResult &= (testSparseMatrix0-testSparseMatrix1).norm() == 0;
  1442. testResult &= testObject0->testInt == testObject1->testInt;
  1443. testResult &= testObject0->testVector.size() == testObject1->testVector.size();
  1444. for(int i=0;i<testObject0->testVector.size();i++)
  1445. testResult &= testObject0->testVector[i] == testObject1->testVector[i];
  1446. testResult &= testComplex10.size() == testComplex11.size();
  1447. for(int i=0;i<testComplex10.size();i++)
  1448. {
  1449. testResult &= testComplex10[i]->first == testComplex11[0]->first;
  1450. testResult &= testComplex10[i]->second == testComplex11[0]->second;
  1451. }
  1452. testResult &= testComplex20.size() == testComplex21.size();
  1453. for(int i=0;i<testComplex20.size();i++)
  1454. {
  1455. testResult &= ((XMLSerializerTest*)testComplex20[i])->testInt == ((XMLSerializerTest*)testComplex21[i])->testInt;
  1456. testResult &= ((XMLSerializerTest*)testComplex20[i])->testVector.size() == ((XMLSerializerTest*)testComplex21[i])->testVector.size();
  1457. for(int j=0;j<((XMLSerializerTest*)testComplex20[i])->testVector.size();j++)
  1458. testResult &= ((XMLSerializerTest*)testComplex20[i])->testVector[j] == ((XMLSerializerTest*)testComplex21[i])->testVector[j];
  1459. }
  1460. igl::XMLSerializer* s = new igl::XMLSerializer("test0");
  1461. // clear file
  1462. testResult &= s->Save("test.xml",true);
  1463. testResult &= s->Add(testChar0,"testChar");
  1464. testResult &= s->Add(testCharArray0,"testCharArray");
  1465. testResult &= s->Add(testString0,"testString");
  1466. testResult &= s->Add(testBool0,"testBool");
  1467. testResult &= s->Add(testUnsigned0,"testUnsigned");
  1468. testResult &= s->Add(testInt0,"testInt");
  1469. testResult &= s->Add(testFloat0,"testFloat");
  1470. testResult &= s->Add(testDouble0,"testDouble");
  1471. s->SetCurrentGroup("test1");
  1472. testResult &= s->Add(testArray0,"testArray");
  1473. testResult &= s->Add(testPair0,"testPair");
  1474. testResult &= s->Add(testVector0,"testVector");
  1475. testResult &= s->Add(testDenseMatrix0,"testDenseMatrix");
  1476. testResult &= s->Add(testSparseMatrix0,"testSparseMatrix");
  1477. testResult &= s->Add(testObject0,"testObject");
  1478. testResult &= s->Add(testComplex10,"testComplex1");
  1479. testResult &= s->Add(testComplex20,"testComplex2");
  1480. // Test single attribute save load
  1481. testResult &= s->Save("testComplex2","test1","test.xml",true);
  1482. testResult &= s->Load("testComplex2","test1","test.xml");
  1483. testResult &= testComplex20.size() == testComplex21.size();
  1484. for(int i=0;i<testComplex20.size();i++)
  1485. {
  1486. testResult &= ((XMLSerializerTest*)testComplex20[i])->testInt == ((XMLSerializerTest*)testComplex21[i])->testInt;
  1487. testResult &= ((XMLSerializerTest*)testComplex20[i])->testVector.size() == ((XMLSerializerTest*)testComplex21[i])->testVector.size();
  1488. for(int j=0;j<((XMLSerializerTest*)testComplex20[i])->testVector.size();j++)
  1489. testResult &= ((XMLSerializerTest*)testComplex20[i])->testVector[j] == ((XMLSerializerTest*)testComplex21[i])->testVector[j];
  1490. }
  1491. // Test group save load without overriding
  1492. testResult &= s->Save("test0","test.xml",false);
  1493. testResult &= s->Load("test0","test.xml");
  1494. testResult &= s->Load("testComplex2","test1","test.xml");
  1495. testResult &= testChar0 == testChar1;
  1496. testResult &= strcmp(testCharArray0,testCharArray1) == 0;
  1497. testResult &= testString0 == testString1;
  1498. testResult &= testBool0 == testBool1;
  1499. testResult &= testUnsigned0 == testUnsigned1;
  1500. testResult &= testInt0 == testInt1;
  1501. testResult &= testFloat0 == testFloat1;
  1502. testResult &= testDouble0 == testDouble1;
  1503. // Test full serialization save load
  1504. testResult &= s->Save("test.xml",true);
  1505. testResult &= s->Load("test.xml");
  1506. testResult &= testChar0 == testChar1;
  1507. testResult &= strcmp(testCharArray0,testCharArray1) == 0;
  1508. testResult &= testString0 == testString1;
  1509. testResult &= testBool0 == testBool1;
  1510. testResult &= testUnsigned0 == testUnsigned1;
  1511. testResult &= testInt0 == testInt1;
  1512. testResult &= testFloat0 == testFloat1;
  1513. testResult &= testDouble0 == testDouble1;
  1514. for(int i=0;i<testArray0.size();i++)
  1515. testResult &= testArray0[i] == testArray1[i];
  1516. testResult &= testPair0.first == testPair1.first;
  1517. testResult &= testPair0.second == testPair1.second;
  1518. testResult &= testVector0.size() == testVector1.size();
  1519. for(int i=0;i<testVector0.size();i++)
  1520. testResult &= testVector0[i] == testVector1[i];
  1521. testResult &= (testDenseMatrix0-testDenseMatrix1).sum() == 0;
  1522. testResult &= (testSparseMatrix0-testSparseMatrix1).norm() == 0;
  1523. testResult &= testObject0->testInt == testObject1->testInt;
  1524. testResult &= testObject0->testVector.size() == testObject1->testVector.size();
  1525. for(int i=0;i<testObject0->testVector.size();i++)
  1526. testResult &= testObject0->testVector[i] == testObject1->testVector[i];
  1527. testResult &= testComplex10.size() == testComplex11.size();
  1528. for(int i=0;i<testComplex10.size();i++)
  1529. {
  1530. testResult &= testComplex10[i]->first == testComplex11[0]->first;
  1531. testResult &= testComplex10[i]->second == testComplex11[0]->second;
  1532. }
  1533. testResult &= testComplex20.size() == testComplex21.size();
  1534. for(int i=0;i<testComplex20.size();i++)
  1535. {
  1536. testResult &= ((XMLSerializerTest*)testComplex20[i])->testInt == ((XMLSerializerTest*)testComplex21[i])->testInt;
  1537. testResult &= ((XMLSerializerTest*)testComplex20[i])->testVector.size() == ((XMLSerializerTest*)testComplex21[i])->testVector.size();
  1538. for(int j=0;j<((XMLSerializerTest*)testComplex20[i])->testVector.size();j++)
  1539. testResult &= ((XMLSerializerTest*)testComplex20[i])->testVector[j] == ((XMLSerializerTest*)testComplex21[i])->testVector[j];
  1540. }
  1541. delete s;
  1542. return testResult;
  1543. }
  1544. #ifndef IGL_HEADER_ONLY
  1545. // Explicit template specialization
  1546. #endif