XMLSerializer.h 74 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2013 Alec Jacobson <alecjacobson@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. /* ---------------------------------------------------------------------------
  9. // XMLSerializer.h
  10. // Author: Christian Schüller on 08/05/13.
  11. ------------------------------------------------------------------------------
  12. Small neader library which allows to save and load a serialization of basic c++ data
  13. types like char, char*, std::string, bool, uint, int, float, double to and from a xml file.
  14. Containers like std::vector, std::std::pair, Eigen dense and sparse matrices are supported
  15. as well as combinations of them (like vector<pair<string,bool>> or vector<vector<int>>).
  16. To serialize an arbitary object use the XMLSerializable interface or even simpler the
  17. XMLSerialization class.
  18. The serialized objects are organised in groups in the xml file and have
  19. their own names which must be unique within one group.
  20. You can find examples how to use it in the test case class XMLSerializerTest.
  21. ----------------------------------------------------------------------------*/
  22. #ifndef XML_SERIALIZER_H
  23. #define XML_SERIALIZER_H
  24. #include <igl/igl_inline.h>
  25. #include <igl/xml/XMLSerializable.h>
  26. #include <iostream>
  27. //#include <array>
  28. #include <vector>
  29. #include <set>
  30. #include <map>
  31. #include <Eigen/Dense>
  32. #include <Eigen/Sparse>
  33. #include "tinyxml2.h"
  34. namespace igl
  35. {
  36. namespace
  37. {
  38. // Utility functions
  39. void EncodeXMLElementName(std::string& name);
  40. void DecodeXMLElementName(std::string& name);
  41. void ReplaceSubString(std::string& str, const std::string& search, const std::string& replace);
  42. // Forward declaration
  43. class XMLSerializer;
  44. /**
  45. * class XMLSerializableObject
  46. * internal usage
  47. */
  48. class XMLSerializableObject : public ::igl::XMLSerializable
  49. {
  50. public:
  51. XMLSerializableObject(const std::string& name, const std::string& group);
  52. virtual ~XMLSerializableObject();
  53. // set attribute conversion functions
  54. void SetAttribute(tinyxml2::XMLElement* element, const char* name, char& dest);
  55. void SetAttribute(tinyxml2::XMLElement* element, const char* name, char*& dest);
  56. void SetAttribute(tinyxml2::XMLElement* element, const char* name, std::string& dest);
  57. void SetAttribute(tinyxml2::XMLElement* element, const char* name, bool& dest);
  58. void SetAttribute(tinyxml2::XMLElement* element, const char* name, unsigned int& dest);
  59. void SetAttribute(tinyxml2::XMLElement* element, const char* name, int& dest);
  60. void SetAttribute(tinyxml2::XMLElement* element, const char* name, float& dest);
  61. void SetAttribute(tinyxml2::XMLElement* element, const char* name, double& dest);
  62. // get attribute conversion functions
  63. void GetAttribute(const char* src, char& dest);
  64. void GetAttribute(const char* src, char*& dest);
  65. void GetAttribute(const char* src, std::string& dest);
  66. void GetAttribute(const char* src, bool& dest);
  67. void GetAttribute(const char* src, unsigned int& dest);
  68. void GetAttribute(const char* src, int& dest);
  69. void GetAttribute(const char* src, float& dest);
  70. void GetAttribute(const char* src, double& dest);
  71. // Initialization
  72. // Basic data types
  73. using XMLSerializable::Init;
  74. void Init(char& val);
  75. void Init(char*& val);
  76. void Init(std::string& val);
  77. void Init(bool& val);
  78. void Init(unsigned int& val);
  79. void Init(int& val);
  80. void Init(float& val);
  81. void Init(double& val);
  82. // XMLSerializable*
  83. template<typename T>
  84. void Init(T& obj);
  85. template<typename T>
  86. void Init(T*& obj);
  87. // STL containers
  88. /*template<typename T, int S>
  89. void Init(std::array<T,S>& obj);*/
  90. template<typename T0, typename T1>
  91. void Init(std::pair<T0,T1>& obj);
  92. template<typename T>
  93. void Init(std::vector<T>& obj);
  94. template<typename T>
  95. void Init(std::set<T>& obj);
  96. template<typename T0, typename T1>
  97. void Init(std::map<T0,T1>& obj);
  98. // Eigen types
  99. template<typename T, int R, int C>
  100. void Init(Eigen::Matrix<T,R,C>& obj);
  101. template<typename T>
  102. void Init(Eigen::SparseMatrix<T>& obj);
  103. // Serialization
  104. // Basic data types
  105. using XMLSerializable::Serialize;
  106. bool Serialize(char& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  107. bool Serialize(char*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  108. bool Serialize(std::string& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  109. bool Serialize(std::string*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  110. bool Serialize(bool obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  111. bool Serialize(bool*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  112. bool Serialize(unsigned int& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  113. bool Serialize(unsigned int*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  114. bool Serialize(int& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  115. bool Serialize(int*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  116. bool Serialize(float& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  117. bool Serialize(float*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  118. bool Serialize(double& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  119. bool Serialize(double*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  120. // XMLSerializable*
  121. template<typename T>
  122. bool Serialize(T& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  123. template<typename T>
  124. bool Serialize(T*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  125. // STL containers
  126. /*template<typename T, size_t S>
  127. bool Serialize(std::array<T,S>& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  128. template<typename T, size_t S>
  129. bool Serialize(std::array<T,S>*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);*/
  130. template<typename T0, typename T1>
  131. bool Serialize(std::pair<T0,T1>& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  132. template<typename T0, typename T1>
  133. bool Serialize(std::pair<T0,T1>*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  134. template<typename T>
  135. bool Serialize(std::vector<T>& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  136. template<typename T>
  137. bool Serialize(std::vector<T>*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  138. bool Serialize(std::vector<bool>& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  139. bool Serialize(std::vector<bool>*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  140. template<typename T>
  141. bool Serialize(std::set<T>& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  142. template<typename T>
  143. bool Serialize(std::set<T>*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  144. template<typename T0, typename T1>
  145. bool Serialize(std::map<T0,T1>& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  146. template<typename T0, typename T1>
  147. bool Serialize(std::map<T0,T1>*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  148. // Eigen types
  149. template<typename T, int R, int C>
  150. bool Serialize(Eigen::Matrix<T,R,C>& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  151. template<typename T, int R, int C>
  152. bool Serialize(Eigen::Matrix<T,R,C>*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  153. template<typename T>
  154. bool Serialize(Eigen::SparseMatrix<T>& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  155. template<typename T>
  156. bool Serialize(Eigen::SparseMatrix<T>*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  157. // Deserialization
  158. // Basic data types
  159. using XMLSerializable::Deserialize;
  160. bool Deserialize(char& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  161. bool Deserialize(char*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  162. bool Deserialize(std::string& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  163. bool Deserialize(std::string*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  164. bool Deserialize(bool& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  165. bool Deserialize(bool*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  166. bool Deserialize(unsigned int& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  167. bool Deserialize(unsigned int*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  168. bool Deserialize(int& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  169. bool Deserialize(int*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  170. bool Deserialize(float& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  171. bool Deserialize(float*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  172. bool Deserialize(double& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  173. bool Deserialize(double*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  174. // XMLSerializable*
  175. template<typename T>
  176. bool Deserialize(T& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  177. template<typename T>
  178. bool Deserialize(T*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  179. // STL containers
  180. /*template<typename T, size_t S>
  181. bool Deserialize(std::array<T,S>& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  182. template<typename T, size_t S>
  183. bool Deserialize(std::array<T,S>*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);*/
  184. template<typename T0, typename T1>
  185. bool Deserialize(std::pair<T0,T1>& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  186. template<typename T0, typename T1>
  187. bool Deserialize(std::pair<T0,T1>*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  188. template<typename T>
  189. bool Deserialize(std::vector<T>& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  190. template<typename T>
  191. bool Deserialize(std::vector<T>*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  192. bool Deserialize(std::vector<bool>& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  193. bool Deserialize(std::vector<bool>*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  194. template<typename T>
  195. bool Deserialize(std::set<T>& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  196. template<typename T>
  197. bool Deserialize(std::set<T>*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  198. template<typename T0, typename T1>
  199. bool Deserialize(std::map<T0,T1>& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  200. template<typename T0, typename T1>
  201. bool Deserialize(std::map<T0,T1>*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  202. // Eigen types
  203. template<typename T, int R, int C>
  204. bool Deserialize(Eigen::Matrix<T,R,C>& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  205. template<typename T, int R, int C>
  206. bool Deserialize(Eigen::Matrix<T,R,C>*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  207. template<typename T>
  208. bool Deserialize(Eigen::SparseMatrix<T>& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  209. template<typename T>
  210. bool Deserialize(Eigen::SparseMatrix<T>*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  211. private:
  212. template<typename T>
  213. bool setElementAttribute(T& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  214. template<typename T>
  215. bool getElementAttribute(T& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);
  216. };
  217. /**
  218. * class XMLSerializableInstance
  219. * internal usage
  220. */
  221. template<typename T>
  222. class XMLSerializableInstance : public XMLSerializableObject
  223. {
  224. public:
  225. T& Object;
  226. T DefaultValue;
  227. XMLSerializableInstance(T& obj, const std::string& name, const std::string group);
  228. XMLSerializableInstance(T& obj, const std::string& name, const std::string group, T defaultValue);
  229. ~XMLSerializableInstance();
  230. // XMLSerializable interface implementation
  231. void Init();
  232. bool Serialize(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element);
  233. bool Deserialize(tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element);
  234. };
  235. /**
  236. * struct XMLSerializerGroup
  237. * internal usage
  238. */
  239. struct XMLSerializerGroup
  240. {
  241. std::string Name;
  242. std::vector<XMLSerializable*>* Objects;
  243. };
  244. /**
  245. * class XMLSerializer
  246. * This is the core class which takes care of saving and loading of serialization of object structures.
  247. */
  248. class XMLSerializer
  249. {
  250. public:
  251. /**
  252. * Serializes an object to a file
  253. */
  254. template<typename T>
  255. static bool SaveObject(T& object, const char* filename);
  256. template<typename T>
  257. static bool SaveObject(T& object, const std::string& objectName, const std::string& groupName, const char* filename, bool overwrite);
  258. /**
  259. * Loads the serialization of an object from a file.
  260. */
  261. template<typename T>
  262. static bool LoadObject(T& object, const char* filename);
  263. template<typename T>
  264. static bool LoadObject(T& object, const std::string& objectName, const std::string& groupName, const char* filename);
  265. /**
  266. * Constructor which sets the default group
  267. */
  268. XMLSerializer(const std::string& defaultGroup);
  269. ~XMLSerializer();
  270. /**
  271. * Save the serialization of all groups to file.
  272. * Parameter overwrite specifies if file gets overwritten or updated
  273. */
  274. bool Save(const char* filename, bool overwrite);
  275. bool Save(const std::string& groupName, const char* filename, bool overwrite);
  276. bool Save(const std::string& objectName, const std::string& groupName, const char* filename, bool overwrite);
  277. /**
  278. * Save the serialization of all groups to a XMLDocument instance.
  279. */
  280. bool SaveToXMLDoc(tinyxml2::XMLDocument* doc);
  281. bool SaveToXMLDoc(const std::string& groupName, tinyxml2::XMLDocument* doc);
  282. bool SaveToXMLDoc(const std::string& objectName, const std::string& groupName, tinyxml2::XMLDocument* doc);
  283. /**
  284. * Save the serialization of a group with a new provided name to given XMLElement instance.
  285. */
  286. bool SaveGroupToXMLElement(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  287. bool SaveGroupToXMLElement(const std::string& groupName, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);
  288. /**
  289. * Load the serialization from a file.
  290. */
  291. bool Load(const char* filename);
  292. bool Load(const std::string& groupName, const char* filename);
  293. bool Load(const std::string& objectName, const std::string& groupName, const char* filename);
  294. /**
  295. * Load the serialization from an XMLDocument instance.
  296. */
  297. bool LoadFromXMLDoc(tinyxml2::XMLDocument* doc);
  298. bool LoadFromXMLDoc(const std::string& groupName, tinyxml2::XMLDocument* doc);
  299. bool LoadFromXMLDoc(const std::string& objectName, const std::string& groupName, tinyxml2::XMLDocument* doc);
  300. /**
  301. * Load the serialization from a XMLElement instance to given group.
  302. */
  303. bool LoadGroupFromXMLElement(const std::string& groupName, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element);
  304. /**
  305. * Set/Get current group. Every object which is added afterwards will be in this group, except it specifies another group.
  306. */
  307. void SetCurrentGroup(const std::string& group);
  308. std::string GetCurrentGroup();
  309. /**
  310. * Add an object to the serializer. Can be simple types like char, char*, string, unsigned int, int, float, double or containers like std::array, std::pair, std::vector.
  311. * Also Eigen dense or sparse matrices are supported and all objects of type Serializable* and combinations of thoses types like vector<vector>, vector<pair> or even vector<pair<vector,Serializable*>>>.
  312. * Also pointers to those objects can be used (for instance like vector<vector<pair<int,float>*>*>).
  313. * char* is also possible as base type and represents a array of chars, but be carefull that the pointer is not just a copy but a valid instance in the current programm scope.
  314. */
  315. // Basic types
  316. bool Add(char& obj, const std::string& name);
  317. bool Add(char*& obj, const std::string& name);
  318. bool Add(std::string& obj, const std::string& name);
  319. bool Add(bool& obj, const std::string& name);
  320. bool Add(unsigned int& obj, const std::string& name);
  321. bool Add(int& obj, const std::string& name);
  322. bool Add(float& obj, const std::string& name);
  323. bool Add(double& obj, const std::string& name);
  324. bool Add(char& obj, const std::string& name, char defaultValue);
  325. bool Add(char*& obj, const std::string& name, char* defaultValue);
  326. bool Add(std::string& obj, const std::string& name, std::string defaultValue);
  327. bool Add(bool& obj, const std::string& name, bool defaultValue);
  328. bool Add(unsigned int& obj, const std::string& name, unsigned int defaultValue);
  329. bool Add(int& obj, const std::string& name, int defaultValue);
  330. bool Add(float& obj, const std::string& name, float defaultValue);
  331. bool Add(double& obj, const std::string& name, double defaultValue);
  332. // XMLSerializable*
  333. template<typename T>
  334. bool Add(T& object, const std::string& name);
  335. template<typename T>
  336. bool Add(T& object, const std::string& name, T defaultValue);
  337. // STL containers
  338. /*template<typename T, size_t S>
  339. bool Add(std::array<T,S>& obj, const std::string& name);*/
  340. template<typename T0, typename T1>
  341. bool Add(std::pair<T0,T1>& obj, const std::string& name);
  342. template<typename T>
  343. bool Add(std::vector<T>& obj, const std::string& name);
  344. template<typename T>
  345. bool Add(std::set<T>& obj, const std::string& name);
  346. template<typename T0, typename T1>
  347. bool Add(std::map<T0,T1>& obj, const std::string& name);
  348. // Eigen types
  349. template<typename T, int R, int C>
  350. bool Add(Eigen::Matrix<T,R,C>& obj, const std::string& name);
  351. template<typename T>
  352. bool Add(Eigen::SparseMatrix<T>& obj, const std::string& name);
  353. private:
  354. std::map<std::string,XMLSerializerGroup*>::iterator currentGroup;
  355. std::map<std::string,XMLSerializerGroup*> groups;
  356. template<typename T>
  357. bool add(T& object, const std::string& name);
  358. template<typename T>
  359. bool add(T& object, const std::string& name, T defaultValue);
  360. bool addObjectToGroup(XMLSerializable* object, const std::string& group);
  361. bool addObjectToGroup(XMLSerializable* object, std::map<std::string,XMLSerializerGroup*>::iterator it);
  362. std::map<std::string,XMLSerializerGroup*>::iterator setGetGroup(const std::string& group);
  363. tinyxml2::XMLDocument* openDoc(const char* filename);
  364. tinyxml2::XMLElement* findAddGroup(tinyxml2::XMLDocument* doc, const char* groupName);
  365. };
  366. int numForbiddenChars = 8;
  367. char forbiddenChars[] = {' ','/','~','#','&','>','<','='};
  368. void ReplaceSubString(std::string& str, const std::string& search, const std::string& replace)
  369. {
  370. size_t pos = 0;
  371. while ((pos = str.find(search, pos)) != std::string::npos)
  372. {
  373. str.replace(pos, search.length(), replace);
  374. pos += replace.length();
  375. }
  376. }
  377. void EncodeXMLElementName(std::string& name)
  378. {
  379. // must not start with a digit
  380. if(isdigit(*name.begin()))
  381. {
  382. name = ":::" + name;
  383. }
  384. std::stringstream stream;
  385. for(int i=0;i<numForbiddenChars;i++)
  386. {
  387. std::string search;
  388. search = forbiddenChars[i];
  389. std::stringstream replaces;
  390. replaces << ":" << (int)forbiddenChars[i];
  391. std::string replace = replaces.str();
  392. ReplaceSubString(name,search,replace);
  393. }
  394. }
  395. void DecodeXMLElementName(std::string& name)
  396. {
  397. if(name.find("::", 0) == 0)
  398. name.replace(0,3,"");
  399. std::stringstream stream;
  400. for(unsigned int i=0;i<numForbiddenChars;i++)
  401. {
  402. std::stringstream searchs;
  403. searchs << ":" << (int)forbiddenChars[i];
  404. std::string search = searchs.str();
  405. std::string replace;
  406. replace = forbiddenChars[i];
  407. ReplaceSubString(name,search,replace);
  408. }
  409. }
  410. XMLSerializableObject::XMLSerializableObject(const std::string& name, const std::string& group)
  411. {
  412. std::string groupName = group;
  413. std::string objectName = name;
  414. EncodeXMLElementName(groupName);
  415. EncodeXMLElementName(objectName);
  416. Name = objectName;
  417. }
  418. XMLSerializableObject::~XMLSerializableObject()
  419. {
  420. }
  421. // set attribute conversion functions
  422. void XMLSerializableObject::SetAttribute(tinyxml2::XMLElement* element, const char* name, char& dest)
  423. {
  424. element->SetAttribute(name,dest);
  425. }
  426. void XMLSerializableObject::SetAttribute(tinyxml2::XMLElement* element, const char* name, char*& dest)
  427. {
  428. element->SetAttribute(name,const_cast<const char*>(dest));
  429. }
  430. void XMLSerializableObject::SetAttribute(tinyxml2::XMLElement* element, const char* name, std::string& dest)
  431. {
  432. element->SetAttribute(name,dest.c_str());
  433. }
  434. void XMLSerializableObject::SetAttribute(tinyxml2::XMLElement* element, const char* name, bool& dest)
  435. {
  436. element->SetAttribute(name,dest);
  437. }
  438. void XMLSerializableObject::SetAttribute(tinyxml2::XMLElement* element, const char* name, unsigned int& dest)
  439. {
  440. element->SetAttribute(name,dest);
  441. }
  442. void XMLSerializableObject::SetAttribute(tinyxml2::XMLElement* element, const char* name, int& dest)
  443. {
  444. element->SetAttribute(name,dest);
  445. }
  446. void XMLSerializableObject::SetAttribute(tinyxml2::XMLElement* element, const char* name, float& dest)
  447. {
  448. element->SetAttribute(name,dest);
  449. }
  450. void XMLSerializableObject::SetAttribute(tinyxml2::XMLElement* element, const char* name, double& dest)
  451. {
  452. element->SetAttribute(name,dest);
  453. }
  454. // get attribute conversion functions
  455. void XMLSerializableObject::GetAttribute(const char* src, char& dest)
  456. {
  457. dest = (char)atoi(src);
  458. }
  459. void XMLSerializableObject::GetAttribute(const char* src, char*& dest)
  460. {
  461. unsigned int length = strlen(src)+1;
  462. dest = new char[length];
  463. strcpy(dest, src);
  464. }
  465. void XMLSerializableObject::GetAttribute(const char* src, std::string& dest)
  466. {
  467. dest = src;
  468. }
  469. void XMLSerializableObject::GetAttribute(const char* src, bool& dest)
  470. {
  471. tinyxml2::XMLUtil::ToBool(src,&dest);
  472. }
  473. void XMLSerializableObject::GetAttribute(const char* src, unsigned int& dest)
  474. {
  475. tinyxml2::XMLUtil::ToUnsigned(src,&dest);
  476. }
  477. void XMLSerializableObject::GetAttribute(const char* src, int& dest)
  478. {
  479. tinyxml2::XMLUtil::ToInt(src,&dest);
  480. }
  481. void XMLSerializableObject::GetAttribute(const char* src, float& dest)
  482. {
  483. tinyxml2::XMLUtil::ToFloat(src,&dest);
  484. }
  485. void XMLSerializableObject::GetAttribute(const char* src, double& dest)
  486. {
  487. tinyxml2::XMLUtil::ToDouble(src,&dest);
  488. }
  489. // specify default value of types
  490. void XMLSerializableObject::Init(char& val)
  491. {
  492. val = '0';
  493. }
  494. void XMLSerializableObject::Init(char*& val)
  495. {
  496. val = NULL;
  497. }
  498. void XMLSerializableObject::Init(std::string& val)
  499. {
  500. val = "";
  501. }
  502. void XMLSerializableObject::Init(bool& val)
  503. {
  504. val = false;
  505. }
  506. void XMLSerializableObject::Init(unsigned int& val)
  507. {
  508. val = 0;
  509. }
  510. void XMLSerializableObject::Init(int& val)
  511. {
  512. val = 0;
  513. }
  514. void XMLSerializableObject::Init(float& val)
  515. {
  516. val = 0.0f;
  517. }
  518. void XMLSerializableObject::Init(double& val)
  519. {
  520. val = 0.000000000000000;
  521. }
  522. template<typename T>
  523. void XMLSerializableObject::Init(T& obj)
  524. {
  525. XMLSerializable* object = static_cast<XMLSerializable*>(&obj);
  526. object->Init();
  527. }
  528. template<typename T>
  529. void XMLSerializableObject::Init(T*& obj)
  530. {
  531. XMLSerializable* object = static_cast<XMLSerializable*>(obj);
  532. object->Init();
  533. }
  534. /*template<typename T, int S>
  535. void XMLSerializableObject::Init(std::array<T,S>& obj)
  536. {
  537. for(unsigned int i=0;i<obj.size();i++)
  538. Init(obj[i]);
  539. }*/
  540. template<typename T0, typename T1>
  541. void XMLSerializableObject::Init(std::pair<T0,T1>& obj)
  542. {
  543. Init(obj.first);
  544. Init(obj.second);
  545. }
  546. template<typename T>
  547. void XMLSerializableObject::Init(std::vector<T>& obj)
  548. {
  549. obj.clear();
  550. }
  551. template<typename T>
  552. void XMLSerializableObject::Init(std::set<T>& obj)
  553. {
  554. obj.clear();
  555. }
  556. template<typename T0, typename T1>
  557. void XMLSerializableObject::Init(std::map<T0,T1>& obj)
  558. {
  559. obj.clear();
  560. }
  561. template<typename T, int R, int C>
  562. void XMLSerializableObject::Init(Eigen::Matrix<T,R,C>& obj)
  563. {
  564. obj.setZero(obj.rows(),obj.cols());
  565. }
  566. template<typename T>
  567. void XMLSerializableObject::Init(Eigen::SparseMatrix<T>& obj)
  568. {
  569. obj.setZero();
  570. }
  571. bool XMLSerializableObject::Serialize(char& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  572. {
  573. return setElementAttribute(obj,doc,element,name);
  574. }
  575. // overload function for char*, it interpreted as char array and can be used to handle strings
  576. bool XMLSerializableObject::Serialize(char*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  577. {
  578. return setElementAttribute(obj,doc,element,name);
  579. }
  580. bool XMLSerializableObject::Serialize(std::string& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  581. {
  582. return setElementAttribute(obj,doc,element,name);
  583. }
  584. bool XMLSerializableObject::Serialize(std::string*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  585. {
  586. return Serialize(*obj,doc,element,name);
  587. }
  588. bool XMLSerializableObject::Serialize(bool obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  589. {
  590. return setElementAttribute(obj,doc,element,name);
  591. }
  592. bool XMLSerializableObject::Serialize(bool*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  593. {
  594. return Serialize(*obj,doc,element,name);
  595. }
  596. bool XMLSerializableObject::Serialize(unsigned int& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  597. {
  598. return setElementAttribute(obj,doc,element,name);
  599. }
  600. bool XMLSerializableObject::Serialize(unsigned int*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  601. {
  602. return Serialize(*obj,doc,element,name);
  603. }
  604. bool XMLSerializableObject::Serialize(int& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  605. {
  606. return setElementAttribute(obj,doc,element,name);
  607. }
  608. bool XMLSerializableObject::Serialize(int*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  609. {
  610. return Serialize(*obj,doc,element,name);
  611. }
  612. bool XMLSerializableObject::Serialize(float& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  613. {
  614. return setElementAttribute(obj,doc,element,name);
  615. }
  616. bool XMLSerializableObject::Serialize(float*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  617. {
  618. return Serialize(*obj,doc,element,name);
  619. }
  620. bool XMLSerializableObject::Serialize(double& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  621. {
  622. return setElementAttribute(obj,doc,element,name);
  623. }
  624. bool XMLSerializableObject::Serialize(double*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  625. {
  626. return Serialize(*obj,doc,element,name);
  627. }
  628. template<typename T>
  629. bool XMLSerializableObject::Serialize(T& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  630. {
  631. // Serialize object implementing XMLSerializable interface
  632. XMLSerializable* object = static_cast<XMLSerializable*>(&obj);
  633. tinyxml2::XMLElement* child = doc->NewElement(name.c_str());
  634. element->InsertEndChild(child);
  635. return object->Serialize(doc,child);
  636. }
  637. template<typename T>
  638. bool XMLSerializableObject::Serialize(T*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  639. {
  640. // Serialize object implementing XMLSerializable interface
  641. XMLSerializable* object = static_cast<XMLSerializable*>(obj);
  642. tinyxml2::XMLElement* child = doc->NewElement(name.c_str());
  643. element->InsertEndChild(child);
  644. return object->Serialize(doc,child);
  645. }
  646. bool XMLSerializableObject::Deserialize(char& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  647. {
  648. return getElementAttribute(obj,doc,element,name);
  649. }
  650. // template specialisation for char*, it interpreted as char array and can be used to handle strings
  651. bool XMLSerializableObject::Deserialize(char*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  652. {
  653. return getElementAttribute(obj,doc,element,name);
  654. }
  655. bool XMLSerializableObject::Deserialize(std::string& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  656. {
  657. return getElementAttribute(obj,doc,element,name);
  658. }
  659. bool XMLSerializableObject::Deserialize(std::string*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  660. {
  661. return Deserialize(*obj,doc,element,name);
  662. }
  663. bool XMLSerializableObject::Deserialize(bool& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  664. {
  665. return getElementAttribute(obj,doc,element,name);
  666. }
  667. bool XMLSerializableObject::Deserialize(bool*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  668. {
  669. return Deserialize(*obj,doc,element,name);
  670. }
  671. bool XMLSerializableObject::Deserialize(unsigned int& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  672. {
  673. return getElementAttribute(obj,doc,element,name);
  674. }
  675. bool XMLSerializableObject::Deserialize(unsigned int*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  676. {
  677. return Deserialize(*obj,doc,element,name);
  678. }
  679. bool XMLSerializableObject::Deserialize(int& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  680. {
  681. return getElementAttribute(obj,doc,element,name);
  682. }
  683. bool XMLSerializableObject::Deserialize(int*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  684. {
  685. return Deserialize(*obj,doc,element,name);
  686. }
  687. bool XMLSerializableObject::Deserialize(float& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  688. {
  689. return getElementAttribute(obj,doc,element,name);
  690. }
  691. bool XMLSerializableObject::Deserialize(float*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  692. {
  693. return Deserialize(*obj,doc,element,name);
  694. }
  695. bool XMLSerializableObject::Deserialize(double& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  696. {
  697. return getElementAttribute(obj,doc,element,name);
  698. }
  699. bool XMLSerializableObject::Deserialize(double*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  700. {
  701. return Deserialize(*obj,doc,element,name);
  702. }
  703. template<typename T>
  704. bool XMLSerializableObject::Deserialize(T& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  705. {
  706. obj = T();
  707. XMLSerializable* object = static_cast<XMLSerializable*>(&obj);
  708. const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
  709. object->Name = child->FirstChild()->Value();
  710. if(child != NULL)
  711. {
  712. obj.Deserialize(doc,child);
  713. }
  714. else
  715. {
  716. obj.Init();
  717. return false;
  718. }
  719. return true;
  720. }
  721. template<typename T>
  722. bool XMLSerializableObject::Deserialize(T*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  723. {
  724. obj = new T();
  725. XMLSerializable* object = static_cast<XMLSerializable*>(obj);
  726. const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
  727. object->Name = child->FirstChild()->Value();
  728. if(child != NULL)
  729. {
  730. obj->Deserialize(doc,child);
  731. }
  732. else
  733. {
  734. obj->Init();
  735. return false;
  736. }
  737. return true;
  738. }
  739. /*
  740. template<typename T, size_t S>
  741. bool XMLSerializableObject::Serialize(std::array<T,S>& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  742. {
  743. tinyxml2::XMLElement* ar = doc->NewElement(name.c_str());
  744. element->InsertEndChild(ar);
  745. ar->SetAttribute("size",(unsigned int)obj.size());
  746. std::stringstream num;
  747. for(unsigned int i=0;i<obj.size();i++)
  748. {
  749. num.str("");
  750. num << "value" << i;
  751. Serialize(obj[i],doc,ar,num.str());
  752. }
  753. return true;
  754. }
  755. template<typename T, size_t S>
  756. bool XMLSerializableObject::Serialize(std::array<T,S>*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  757. {
  758. return Serialize(*obj,doc,element,name);
  759. }
  760. template<typename T, size_t S>
  761. bool XMLSerializableObject::Deserialize(std::array<T,S>& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  762. {
  763. bool res = true;
  764. const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
  765. if(child != NULL)
  766. {
  767. int size = child->UnsignedAttribute("size");
  768. size = S < size ? S : size;
  769. std::stringstream num;
  770. const tinyxml2::XMLAttribute* attribute = NULL;
  771. for(unsigned int i=0;i<size;i++)
  772. {
  773. num.str("");
  774. num << "value" << i;
  775. res &= Deserialize(obj[i],doc,child,num.str());
  776. }
  777. }
  778. else
  779. return false;
  780. return res;
  781. }
  782. template<typename T, size_t S>
  783. bool XMLSerializableObject::Deserialize(std::array<T,S>*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  784. {
  785. obj = new std::array<T,S>();
  786. return Deserialize(*obj,doc,element,name);
  787. }
  788. */
  789. template<typename T0, typename T1>
  790. bool XMLSerializableObject::Serialize(std::pair<T0,T1>& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  791. {
  792. bool res = true;
  793. tinyxml2::XMLElement* pair = doc->NewElement(name.c_str());
  794. element->InsertEndChild(pair);
  795. res &= Serialize(obj.first,doc,pair,"first");
  796. res &= Serialize(obj.second,doc,pair,"second");
  797. return res;
  798. }
  799. template<typename T0, typename T1>
  800. bool XMLSerializableObject::Serialize(std::pair<T0,T1>*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  801. {
  802. return Serialize(*obj,doc,element,name);
  803. }
  804. template<typename T0, typename T1>
  805. bool XMLSerializableObject::Deserialize(std::pair<T0,T1>& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  806. {
  807. bool res = true;
  808. const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
  809. if(child != NULL)
  810. {
  811. res &= Deserialize(obj.first,doc,child,"first");
  812. res &= Deserialize(obj.second,doc,child,"second");
  813. }
  814. else
  815. {
  816. Init(obj.first);
  817. Init(obj.second);
  818. return false;
  819. }
  820. return res;
  821. }
  822. template<typename T0, typename T1>
  823. bool XMLSerializableObject::Deserialize(std::pair<T0,T1>*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  824. {
  825. obj = new std::pair<T0,T1>();
  826. return Deserialize(*obj,doc,element,name);
  827. }
  828. template<typename T>
  829. bool XMLSerializableObject::Serialize(std::vector<T>& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  830. {
  831. tinyxml2::XMLElement* vector = doc->NewElement(name.c_str());
  832. element->InsertEndChild(vector);
  833. vector->SetAttribute("size",(unsigned int)obj.size());
  834. std::stringstream num;
  835. for(unsigned int i=0;i<obj.size();i++)
  836. {
  837. num.str("");
  838. num << "value" << i;
  839. Serialize(obj[i],doc,vector,num.str());
  840. }
  841. return true;
  842. }
  843. template<typename T>
  844. bool XMLSerializableObject::Serialize(std::vector<T>*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  845. {
  846. return Serialize(*obj,doc,element,name);
  847. }
  848. bool XMLSerializableObject::Serialize(std::vector<bool>& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  849. {
  850. tinyxml2::XMLElement* matrix = doc->NewElement(name.c_str());
  851. element->InsertEndChild(matrix);
  852. const unsigned int size = obj.size();
  853. matrix->SetAttribute("size",size);
  854. std::stringstream ms;
  855. ms << "\n";
  856. for(unsigned int i=0;i<size;i++)
  857. ms << obj[i] << ",";
  858. ms << "\n";
  859. std::string mString = ms.str();
  860. if(mString.size() > 1)
  861. mString[mString.size()-2] = '\0';
  862. matrix->SetAttribute("vector_bool",mString.c_str());
  863. return true;
  864. }
  865. bool XMLSerializableObject::Serialize(std::vector<bool>*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  866. {
  867. return Serialize(*obj,doc,element,name);
  868. }
  869. template<typename T>
  870. bool XMLSerializableObject::Deserialize(std::vector<T>& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  871. {
  872. bool res = true;
  873. obj.clear();
  874. const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
  875. if(child != NULL)
  876. {
  877. unsigned int size = child->UnsignedAttribute("size");
  878. obj.resize(size);
  879. std::stringstream num;
  880. for(unsigned int i=0;i<size;i++)
  881. {
  882. num.str("");
  883. num << "value" << i;
  884. res &= Deserialize(obj[i],doc,child,num.str());
  885. }
  886. }
  887. else
  888. return false;
  889. return res;
  890. }
  891. template<typename T>
  892. bool XMLSerializableObject::Deserialize(std::vector<T>*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  893. {
  894. obj = new std::vector<T>();
  895. return Deserialize(*obj,doc,element,name);
  896. }
  897. bool XMLSerializableObject::Deserialize(std::vector<bool>& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  898. {
  899. const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
  900. if(child != NULL)
  901. {
  902. const unsigned int size = child->UnsignedAttribute("size");
  903. obj.resize(size);
  904. const tinyxml2::XMLAttribute* attribute = child->FindAttribute("vector_bool");
  905. if(attribute == NULL)
  906. {
  907. Init(obj);
  908. return false;
  909. }
  910. char* matTemp;
  911. GetAttribute(attribute->Value(),matTemp);
  912. std::string line, ssize;
  913. std::stringstream mats;
  914. mats.str(matTemp);
  915. int r=0;
  916. std::string val;
  917. // for each line
  918. getline(mats,line); // matrix starts with an empty line
  919. while(getline(mats,line))
  920. {
  921. // get current line
  922. std::stringstream liness(line);
  923. for(unsigned int c=0;c<size-1;c++)
  924. {
  925. // split line
  926. getline(liness, val, ',');
  927. // push pack the data if any
  928. if(!val.empty())
  929. {
  930. bool t;
  931. GetAttribute(val.c_str(),t);
  932. obj[c] = t;
  933. }
  934. }
  935. getline(liness, val);
  936. bool t;
  937. GetAttribute(val.c_str(),t);
  938. obj[size-1] = t;
  939. r++;
  940. }
  941. }
  942. else
  943. {
  944. Init(obj);
  945. return false;
  946. }
  947. return true;
  948. }
  949. bool XMLSerializableObject::Deserialize(std::vector<bool>*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  950. {
  951. obj = new std::vector<bool>();
  952. return Deserialize(*obj,doc,element,name);
  953. }
  954. template<typename T>
  955. bool XMLSerializableObject::Serialize(std::set<T>& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  956. {
  957. tinyxml2::XMLElement* vector = doc->NewElement(name.c_str());
  958. element->InsertEndChild(vector);
  959. vector->SetAttribute("size",(unsigned int)obj.size());
  960. std::stringstream num;
  961. typename std::set<T>::iterator iter = obj.begin();
  962. for(int i=0;iter!=obj.end();iter++,i++)
  963. {
  964. num.str("");
  965. num << "value" << i;
  966. Serialize((T)*iter,doc,vector,num.str());
  967. }
  968. return true;
  969. }
  970. template<typename T>
  971. bool XMLSerializableObject::Serialize(std::set<T>*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  972. {
  973. return Serialize(*obj,doc,element,name);
  974. }
  975. template<typename T>
  976. bool XMLSerializableObject::Deserialize(std::set<T>& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  977. {
  978. bool res = true;
  979. obj.clear();
  980. const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
  981. if(child != NULL)
  982. {
  983. unsigned int size = child->UnsignedAttribute("size");
  984. std::stringstream num;
  985. typename std::set<T>::iterator iter = obj.begin();
  986. for(int i=0;i<size;i++)
  987. {
  988. num.str("");
  989. num << "value" << i;
  990. T val;
  991. res &= Deserialize(val,doc,child,num.str());
  992. obj.insert(val);
  993. }
  994. }
  995. else
  996. return false;
  997. return res;
  998. }
  999. template<typename T>
  1000. bool XMLSerializableObject::Deserialize(std::set<T>*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  1001. {
  1002. obj = new std::set<T>();
  1003. return Deserialize(*obj,doc,element,name);
  1004. }
  1005. template<typename T0, typename T1>
  1006. bool XMLSerializableObject::Serialize(std::map<T0,T1>& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  1007. {
  1008. tinyxml2::XMLElement* vector = doc->NewElement(name.c_str());
  1009. element->InsertEndChild(vector);
  1010. vector->SetAttribute("size",(unsigned int)obj.size());
  1011. std::stringstream num;
  1012. typename std::map<T0,T1>::iterator iter = obj.begin();
  1013. for(int i=0;iter!=obj.end();iter++,i++)
  1014. {
  1015. num.str("");
  1016. num << "value" << i;
  1017. Serialize((std::pair<T0,T1>)*iter,doc,vector,num.str());
  1018. }
  1019. return true;
  1020. }
  1021. template<typename T0, typename T1>
  1022. bool XMLSerializableObject::Serialize(std::map<T0,T1>*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  1023. {
  1024. return Serialize(*obj,doc,element,name);
  1025. }
  1026. template<typename T0, typename T1>
  1027. bool XMLSerializableObject::Deserialize(std::map<T0,T1>& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  1028. {
  1029. bool res = true;
  1030. obj.clear();
  1031. const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
  1032. if(child != NULL)
  1033. {
  1034. unsigned int size = child->UnsignedAttribute("size");
  1035. std::stringstream num;
  1036. typename std::map<T0,T1>::iterator iter = obj.begin();
  1037. for(int i=0;i<size;i++)
  1038. {
  1039. num.str("");
  1040. num << "value" << i;
  1041. std::pair<T0,T1> pair;
  1042. res &= Deserialize(pair,doc,child,num.str());
  1043. obj.insert(pair);
  1044. }
  1045. }
  1046. else
  1047. return false;
  1048. return res;
  1049. }
  1050. template<typename T0, typename T1>
  1051. bool XMLSerializableObject::Deserialize(std::map<T0,T1>*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  1052. {
  1053. obj = new std::map<T0,T1>();
  1054. return Deserialize(*obj,doc,element,name);
  1055. }
  1056. template<typename T, int R, int C>
  1057. bool XMLSerializableObject::Serialize(Eigen::Matrix<T,R,C>& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  1058. {
  1059. tinyxml2::XMLElement* matrix = doc->NewElement(name.c_str());
  1060. element->InsertEndChild(matrix);
  1061. const unsigned int rows = obj.rows();
  1062. const unsigned int cols = obj.cols();
  1063. matrix->SetAttribute("rows",rows);
  1064. matrix->SetAttribute("cols",cols);
  1065. std::stringstream ms;
  1066. ms << "\n";
  1067. for(unsigned int r=0;r<rows;r++)
  1068. {
  1069. for(unsigned int c=0;c<cols;c++)
  1070. {
  1071. ms << obj(r,c) << ",";
  1072. }
  1073. ms << "\n";
  1074. }
  1075. std::string mString = ms.str();
  1076. if(mString.size() > 1)
  1077. mString[mString.size()-2] = '\0';
  1078. matrix->SetAttribute("matrix",mString.c_str());
  1079. return true;
  1080. }
  1081. template<typename T, int R, int C>
  1082. bool XMLSerializableObject::Serialize(Eigen::Matrix<T,R,C>*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  1083. {
  1084. return Serialize(*obj,doc,element,name);
  1085. }
  1086. template<typename T, int R, int C>
  1087. bool XMLSerializableObject::Deserialize(Eigen::Matrix<T,R,C>& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  1088. {
  1089. const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
  1090. if(child != NULL)
  1091. {
  1092. const unsigned int rows = child->UnsignedAttribute("rows");
  1093. const unsigned int cols = child->UnsignedAttribute("cols");
  1094. obj.resize(rows,cols);
  1095. const tinyxml2::XMLAttribute* attribute = child->FindAttribute("matrix");
  1096. if(attribute == NULL)
  1097. {
  1098. Init(obj);
  1099. return false;
  1100. }
  1101. char* matTemp;
  1102. GetAttribute(attribute->Value(),matTemp);
  1103. std::string line, srows, scols;
  1104. std::stringstream mats;
  1105. mats.str(matTemp);
  1106. int r=0;
  1107. std::string val;
  1108. // for each line
  1109. getline(mats,line);
  1110. while(getline(mats,line))
  1111. {
  1112. // get current line
  1113. std::stringstream liness(line);
  1114. for(unsigned int c=0;c<cols-1;c++)
  1115. {
  1116. // split line
  1117. getline(liness, val, ',');
  1118. // push pack the data if any
  1119. if(!val.empty())
  1120. GetAttribute(val.c_str(),obj.coeffRef(r,c));
  1121. }
  1122. getline(liness, val);
  1123. GetAttribute(val.c_str(),obj.coeffRef(r,cols-1));
  1124. r++;
  1125. }
  1126. }
  1127. else
  1128. {
  1129. Init(obj);
  1130. return false;
  1131. }
  1132. return true;
  1133. }
  1134. template<typename T, int R, int C>
  1135. bool XMLSerializableObject::Deserialize(Eigen::Matrix<T,R,C>*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  1136. {
  1137. obj = new Eigen::PlainObjectBase<T>();
  1138. return Deserialize(*obj,doc,element,name);
  1139. }
  1140. template<typename T>
  1141. bool XMLSerializableObject::Serialize(Eigen::SparseMatrix<T>& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  1142. {
  1143. tinyxml2::XMLElement* matrix = doc->NewElement(name.c_str());
  1144. element->InsertEndChild(matrix);
  1145. const unsigned int rows = obj.rows();
  1146. const unsigned int cols = obj.cols();
  1147. matrix->SetAttribute("rows",rows);
  1148. matrix->SetAttribute("cols",cols);
  1149. std::stringstream ms;
  1150. ms << "\n";
  1151. for (int k=0;k<obj.outerSize();++k)
  1152. {
  1153. for (typename Eigen::SparseMatrix<T>::InnerIterator it(obj,k);it;++it)
  1154. {
  1155. ms << it.row() << "," << it.col() << "," << it.value() << "\n";
  1156. }
  1157. }
  1158. std::string mString = ms.str();
  1159. if(mString.size() > 0)
  1160. mString[mString.size()-1] = '\0';
  1161. matrix->SetAttribute("matrix",mString.c_str());
  1162. return true;
  1163. }
  1164. template<typename T>
  1165. bool XMLSerializableObject::Serialize(Eigen::SparseMatrix<T>*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  1166. {
  1167. return Serialize(*obj,doc,element,name);
  1168. }
  1169. template<typename T>
  1170. bool XMLSerializableObject::Deserialize(Eigen::SparseMatrix<T>& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  1171. {
  1172. const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
  1173. if(child != NULL)
  1174. {
  1175. const unsigned int rows = child->UnsignedAttribute("rows");
  1176. const unsigned int cols = child->UnsignedAttribute("cols");
  1177. obj.resize(rows,cols);
  1178. obj.setZero();
  1179. const tinyxml2::XMLAttribute* attribute = child->FindAttribute("matrix");
  1180. if(attribute == NULL)
  1181. {
  1182. Init(obj);
  1183. return false;
  1184. }
  1185. char* matTemp;
  1186. GetAttribute(attribute->Value(),matTemp);
  1187. std::string line, srows, scols;
  1188. std::stringstream mats;
  1189. mats.str(matTemp);
  1190. std::vector<Eigen::Triplet<T> > triplets;
  1191. int r=0;
  1192. std::string val;
  1193. // for each line
  1194. getline(mats,line);
  1195. while(getline(mats,line))
  1196. {
  1197. // get current line
  1198. std::stringstream liness(line);
  1199. // row
  1200. getline(liness, val, ',');
  1201. int row = atoi(val.c_str());
  1202. // col
  1203. getline(liness, val, ',');
  1204. int col = atoi(val.c_str());
  1205. // val
  1206. getline(liness, val);
  1207. T value;
  1208. GetAttribute(val.c_str(),value);
  1209. triplets.push_back(Eigen::Triplet<T>(row,col,value));
  1210. r++;
  1211. }
  1212. obj.setFromTriplets(triplets.begin(),triplets.end());
  1213. }
  1214. else
  1215. {
  1216. Init(obj);
  1217. return false;
  1218. }
  1219. return true;
  1220. }
  1221. template<typename T>
  1222. bool XMLSerializableObject::Deserialize(Eigen::SparseMatrix<T>*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  1223. {
  1224. obj = new Eigen::SparseMatrix<T>();
  1225. return Deserialize(*obj,doc,element,name);
  1226. }
  1227. template<typename T>
  1228. bool XMLSerializableObject::setElementAttribute(T& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  1229. {
  1230. tinyxml2::XMLElement* child = doc->NewElement(name.c_str());
  1231. element->InsertEndChild(child);
  1232. SetAttribute(child,"val",obj);
  1233. return true;
  1234. }
  1235. template<typename T>
  1236. bool XMLSerializableObject::getElementAttribute(T& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name)
  1237. {
  1238. // basic data type
  1239. const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str());
  1240. if(child != NULL)
  1241. {
  1242. XMLSerializableObject::GetAttribute(child->Attribute("val"),obj);
  1243. return true;
  1244. }
  1245. else
  1246. {
  1247. Init(obj);
  1248. return false;
  1249. }
  1250. }
  1251. template<typename T>
  1252. XMLSerializableInstance<T>::XMLSerializableInstance(T& obj, const std::string& name, const std::string group)
  1253. : XMLSerializableObject(name, group), Object(obj)
  1254. {
  1255. XMLSerializableObject::Init(DefaultValue);
  1256. }
  1257. template<typename T>
  1258. XMLSerializableInstance<T>::XMLSerializableInstance(T& obj, const std::string& name, const std::string group, T defaultValue)
  1259. : XMLSerializableObject(name, group), Object(obj), DefaultValue(defaultValue)
  1260. {
  1261. }
  1262. template<typename T>
  1263. XMLSerializableInstance<T>::~XMLSerializableInstance()
  1264. {
  1265. }
  1266. template<typename T>
  1267. void XMLSerializableInstance<T>::Init()
  1268. {
  1269. XMLSerializableObject::Init(DefaultValue);
  1270. }
  1271. template<typename T>
  1272. bool XMLSerializableInstance<T>::Serialize(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element)
  1273. {
  1274. return XMLSerializableObject::Serialize(Object,doc,element,Name);
  1275. }
  1276. template<typename T>
  1277. bool XMLSerializableInstance<T>::Deserialize(tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element)
  1278. {
  1279. return XMLSerializableObject::Deserialize(Object,doc,element,Name);
  1280. }
  1281. template<typename T>
  1282. bool XMLSerializer::SaveObject(T& object, const char* filename)
  1283. {
  1284. return SaveObject(object,"Object","Serialization",filename,true);
  1285. }
  1286. template<typename T>
  1287. bool XMLSerializer::SaveObject(T& object, const std::string& objectName, const std::string& groupName, const char* filename, bool overwrite)
  1288. {
  1289. bool result = true;
  1290. XMLSerializer* serializer = new XMLSerializer(groupName);
  1291. result &= serializer->Add(object,objectName);
  1292. result &= serializer->Save(objectName,groupName,filename,overwrite);
  1293. delete serializer;
  1294. return result;
  1295. }
  1296. template<typename T>
  1297. bool XMLSerializer::LoadObject(T& object, const char* filename)
  1298. {
  1299. return LoadObject(object,"Object","Serialization",filename);
  1300. }
  1301. template<typename T>
  1302. bool XMLSerializer::LoadObject(T& object, const std::string& objectName, const std::string& groupName, const char* filename)
  1303. {
  1304. bool result = true;
  1305. XMLSerializer* serializer = new XMLSerializer(groupName);
  1306. result &= serializer->Add(object,objectName);
  1307. result &= serializer->Load(objectName,groupName,filename);
  1308. delete serializer;
  1309. return result;
  1310. }
  1311. XMLSerializer::XMLSerializer(const std::string& defaultGroup)
  1312. {
  1313. SetCurrentGroup(defaultGroup);
  1314. }
  1315. XMLSerializer::~XMLSerializer()
  1316. {
  1317. std::map<std::string,XMLSerializerGroup*>::iterator it;
  1318. for (it=groups.begin();it!=groups.end();it++)
  1319. {
  1320. delete it->second->Objects;
  1321. delete it->second;
  1322. }
  1323. }
  1324. bool XMLSerializer::Save(const char* filename, bool overwrite)
  1325. {
  1326. tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument();
  1327. if(overwrite == false)
  1328. {
  1329. // Check if file exists
  1330. tinyxml2::XMLError error = doc->LoadFile(filename);
  1331. if(error != tinyxml2::XML_NO_ERROR)
  1332. doc->Clear();
  1333. }
  1334. if(SaveToXMLDoc(doc) == false)
  1335. return false;
  1336. // Save
  1337. tinyxml2::XMLError error = doc->SaveFile(filename);
  1338. if(error != tinyxml2::XML_NO_ERROR)
  1339. {
  1340. doc->PrintError();
  1341. return false;
  1342. }
  1343. delete doc;
  1344. return true;
  1345. }
  1346. bool XMLSerializer::SaveToXMLDoc(tinyxml2::XMLDocument* doc)
  1347. {
  1348. std::map<std::string,XMLSerializerGroup*>::iterator it;
  1349. for (it=groups.begin();it!=groups.end();it++)
  1350. {
  1351. // Update group
  1352. tinyxml2::XMLElement* element = doc->FirstChildElement(it->first.c_str());
  1353. if(element != NULL)
  1354. {
  1355. element->DeleteChildren();
  1356. }
  1357. else
  1358. {
  1359. element = doc->NewElement(it->first.c_str());
  1360. doc->InsertEndChild(element);
  1361. }
  1362. std::vector<XMLSerializable*>* group = it->second->Objects;
  1363. for(unsigned int i=0;i<group->size();i++)
  1364. {
  1365. if((*group)[i]->Serialize(doc,element) == false)
  1366. return false;
  1367. }
  1368. }
  1369. return true;
  1370. }
  1371. bool XMLSerializer::Save(const std::string& groupName, const char* filename, bool overwrite)
  1372. {
  1373. tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument();
  1374. if(overwrite == false)
  1375. {
  1376. // Check if file exists
  1377. tinyxml2::XMLError error = doc->LoadFile(filename);
  1378. if(error != tinyxml2::XML_NO_ERROR)
  1379. doc->Clear();
  1380. }
  1381. if(SaveToXMLDoc(groupName, doc) == false)
  1382. return false;
  1383. // Save
  1384. tinyxml2::XMLError error = doc->SaveFile(filename);
  1385. if(error != tinyxml2::XML_NO_ERROR)
  1386. {
  1387. doc->PrintError();
  1388. return false;
  1389. }
  1390. delete doc;
  1391. return true;
  1392. }
  1393. bool XMLSerializer::SaveToXMLDoc(const std::string& groupName, tinyxml2::XMLDocument* doc)
  1394. {
  1395. std::string gn = groupName;
  1396. EncodeXMLElementName(gn);
  1397. std::map<std::string,XMLSerializerGroup*>::iterator it = groups.find(gn);
  1398. if(it == groups.end())
  1399. return false;
  1400. // Update group
  1401. tinyxml2::XMLElement* element = doc->FirstChildElement(it->first.c_str());
  1402. if(element != NULL)
  1403. {
  1404. element->DeleteChildren();
  1405. }
  1406. else
  1407. {
  1408. element = doc->NewElement(it->first.c_str());
  1409. doc->InsertEndChild(element);
  1410. }
  1411. std::vector<XMLSerializable*>* groups = it->second->Objects;
  1412. for(unsigned int i=0;i<groups->size();i++)
  1413. {
  1414. if((*groups)[i]->Serialize(doc,element) == false)
  1415. return false;
  1416. }
  1417. return true;
  1418. }
  1419. bool XMLSerializer::Save(const std::string& objectName, const std::string& groupName, const char* filename, bool overwrite)
  1420. {
  1421. tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument();
  1422. if(overwrite == false)
  1423. {
  1424. // Check if file exists
  1425. tinyxml2::XMLError error = doc->LoadFile(filename);
  1426. if(error != tinyxml2::XML_NO_ERROR)
  1427. doc->Clear();
  1428. }
  1429. if(SaveToXMLDoc(objectName, groupName, doc) == false)
  1430. return false;
  1431. // Save
  1432. tinyxml2::XMLError error = doc->SaveFile(filename);
  1433. if(error != tinyxml2::XML_NO_ERROR)
  1434. {
  1435. doc->PrintError();
  1436. return false;
  1437. }
  1438. delete doc;
  1439. return true;
  1440. }
  1441. bool XMLSerializer::SaveToXMLDoc(const std::string& objectName, const std::string& groupName, tinyxml2::XMLDocument* doc)
  1442. {
  1443. std::string gn = groupName;
  1444. EncodeXMLElementName(gn);
  1445. std::string on = objectName;
  1446. EncodeXMLElementName(on);
  1447. std::map<std::string,XMLSerializerGroup*>::iterator it = groups.find(gn);
  1448. if(it == groups.end())
  1449. return false;
  1450. // Get/Add group
  1451. tinyxml2::XMLElement* element = findAddGroup(doc, it->first.c_str());
  1452. // Serialize
  1453. std::vector<XMLSerializable*>* groups = it->second->Objects;
  1454. bool found = false;
  1455. for(unsigned int i=0;i<groups->size();i++)
  1456. {
  1457. if((*groups)[i]->Name == on)
  1458. {
  1459. found = true;
  1460. tinyxml2::XMLElement* child = element->FirstChildElement(on.c_str());
  1461. if(child != NULL)
  1462. {
  1463. element->DeleteChild(child);
  1464. }
  1465. if((*groups)[i]->Serialize(doc,element) == false)
  1466. return false;
  1467. }
  1468. }
  1469. return found;
  1470. }
  1471. bool XMLSerializer::SaveGroupToXMLElement(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  1472. {
  1473. return SaveGroupToXMLElement(currentGroup->first,doc,element,name);
  1474. }
  1475. bool XMLSerializer::SaveGroupToXMLElement(const std::string& groupName, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name)
  1476. {
  1477. std::string gn = groupName;
  1478. EncodeXMLElementName(gn);
  1479. std::map<std::string,XMLSerializerGroup*>::iterator it = groups.find(gn);
  1480. if(it == groups.end())
  1481. return false;
  1482. // Add new group
  1483. tinyxml2::XMLElement* group = doc->NewElement(name.c_str());
  1484. element->InsertEndChild(group);
  1485. std::vector<XMLSerializable*>* groups = it->second->Objects;
  1486. for(unsigned int i=0;i<groups->size();i++)
  1487. {
  1488. if((*groups)[i]->Serialize(doc,group) == false)
  1489. return false;
  1490. }
  1491. return true;
  1492. }
  1493. bool XMLSerializer::Load(const char* filename)
  1494. {
  1495. tinyxml2::XMLDocument* doc = openDoc(filename);
  1496. if(doc == NULL)
  1497. return false;
  1498. if(LoadFromXMLDoc(doc) == false)
  1499. return false;
  1500. delete doc;
  1501. return true;
  1502. }
  1503. bool XMLSerializer::LoadFromXMLDoc(tinyxml2::XMLDocument* doc)
  1504. {
  1505. std::map<std::string,XMLSerializerGroup*>::iterator it;
  1506. for (it=groups.begin();it!=groups.end();it++)
  1507. {
  1508. tinyxml2::XMLElement* element = doc->FirstChildElement(it->first.c_str());
  1509. if(element == NULL)
  1510. return false;
  1511. // Deserialize
  1512. std::vector<XMLSerializable*>* group = it->second->Objects;
  1513. for(unsigned int i=0;i<group->size();i++)
  1514. {
  1515. if(element == NULL || (*group)[i]->Deserialize(doc,element) == false)
  1516. (*group)[i]->Init(); // Load default value;
  1517. }
  1518. }
  1519. return true;
  1520. }
  1521. bool XMLSerializer::Load(const std::string& groupName, const char* filename)
  1522. {
  1523. tinyxml2::XMLDocument* doc = openDoc(filename);
  1524. if(doc == NULL)
  1525. return false;
  1526. if(LoadFromXMLDoc(groupName, doc) == false)
  1527. return false;
  1528. delete doc;
  1529. return true;
  1530. }
  1531. bool XMLSerializer::LoadFromXMLDoc(const std::string& groupName, tinyxml2::XMLDocument* doc)
  1532. {
  1533. std::string gn = groupName;
  1534. EncodeXMLElementName(gn);
  1535. std::map<std::string,XMLSerializerGroup*>::iterator it = groups.find(gn);
  1536. if(it == groups.end())
  1537. return false;
  1538. tinyxml2::XMLElement* element = doc->FirstChildElement(it->first.c_str());
  1539. if(element == NULL)
  1540. return false;
  1541. // Deserialize
  1542. std::vector<XMLSerializable*>* groups = it->second->Objects;
  1543. for(unsigned int i=0;i<groups->size();i++)
  1544. {
  1545. if(element == NULL || (*groups)[i]->Deserialize(doc,element) == false)
  1546. (*groups)[i]->Init(); // Load default value;
  1547. }
  1548. return true;
  1549. }
  1550. bool XMLSerializer::Load(const std::string& objectName, const std::string& groupName, const char* filename)
  1551. {
  1552. tinyxml2::XMLDocument* doc = openDoc(filename);
  1553. if(doc == NULL)
  1554. return false;
  1555. if(LoadFromXMLDoc(objectName,groupName,doc) == false)
  1556. return false;
  1557. delete doc;
  1558. return true;
  1559. }
  1560. bool XMLSerializer::LoadFromXMLDoc(const std::string& objectName, const std::string& groupName, tinyxml2::XMLDocument* doc)
  1561. {
  1562. std::string gn = groupName;
  1563. EncodeXMLElementName(gn);
  1564. std::string on = objectName;
  1565. EncodeXMLElementName(on);
  1566. std::map<std::string,XMLSerializerGroup*>::iterator it = groups.find(gn);
  1567. if(it == groups.end())
  1568. return false;
  1569. tinyxml2::XMLElement* element = doc->FirstChildElement(it->first.c_str());
  1570. if(element == NULL)
  1571. return false;
  1572. // Deserialize
  1573. std::vector<XMLSerializable*>* groups = it->second->Objects;
  1574. bool found = false;
  1575. for(unsigned int i=0;i<groups->size();i++)
  1576. {
  1577. if((*groups)[i]->Name == on)
  1578. {
  1579. found = true;
  1580. if(element == NULL || (*groups)[i]->Deserialize(doc,element) == false)
  1581. (*groups)[i]->Init(); // Load default value;
  1582. }
  1583. }
  1584. return found;
  1585. }
  1586. bool XMLSerializer::LoadGroupFromXMLElement(const std::string& groupName, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element)
  1587. {
  1588. std::string gn = groupName;
  1589. EncodeXMLElementName(gn);
  1590. std::map<std::string,XMLSerializerGroup*>::iterator it = groups.find(gn);
  1591. if(it == groups.end())
  1592. return false;
  1593. const tinyxml2::XMLElement* group = element->FirstChildElement(groupName.c_str());
  1594. if(group == NULL)
  1595. return false;
  1596. // Deserialize
  1597. std::vector<XMLSerializable*>* groups = it->second->Objects;
  1598. for(unsigned int i=0;i<groups->size();i++)
  1599. {
  1600. if(element == NULL || (*groups)[i]->Deserialize(doc,group) == false)
  1601. (*groups)[i]->Init(); // Load default value;
  1602. }
  1603. return true;
  1604. }
  1605. void XMLSerializer::SetCurrentGroup(const std::string& group)
  1606. {
  1607. currentGroup = setGetGroup(group);
  1608. }
  1609. std::string XMLSerializer::GetCurrentGroup()
  1610. {
  1611. return currentGroup->first;
  1612. }
  1613. template<typename T>
  1614. bool XMLSerializer::Add(T& obj, const std::string& name)
  1615. {
  1616. XMLSerializable* object = static_cast<XMLSerializable*>(&obj);
  1617. object->Name = name;
  1618. return addObjectToGroup(object,currentGroup);
  1619. }
  1620. bool XMLSerializer::Add(char& obj, const std::string& name)
  1621. {
  1622. return add(obj,name);
  1623. }
  1624. bool XMLSerializer::Add(char*& obj, const std::string& name)
  1625. {
  1626. return add(obj,name);
  1627. }
  1628. bool XMLSerializer::Add(std::string& obj, const std::string& name)
  1629. {
  1630. return add(obj,name);
  1631. }
  1632. bool XMLSerializer::Add(bool& obj, const std::string& name)
  1633. {
  1634. return add(obj,name);
  1635. }
  1636. bool XMLSerializer::Add(unsigned int& obj, const std::string& name)
  1637. {
  1638. return add(obj,name);
  1639. }
  1640. bool XMLSerializer::Add(int& obj, const std::string& name)
  1641. {
  1642. return add(obj,name);
  1643. }
  1644. bool XMLSerializer::Add(float& obj, const std::string& name)
  1645. {
  1646. return add(obj,name);
  1647. }
  1648. bool XMLSerializer::Add(double& obj, const std::string& name)
  1649. {
  1650. return add(obj,name);
  1651. }
  1652. /*template<typename T, size_t S>
  1653. bool XMLSerializer::Add(std::array<T,S>& obj, const std::string& name)
  1654. {
  1655. return add(obj,name);
  1656. }*/
  1657. template<typename T0, typename T1>
  1658. bool XMLSerializer::Add(std::pair<T0,T1>& obj, const std::string& name)
  1659. {
  1660. return add(obj,name);
  1661. }
  1662. template<typename T>
  1663. bool XMLSerializer::Add(std::vector<T>& obj, const std::string& name)
  1664. {
  1665. return add(obj,name);
  1666. }
  1667. template<typename T>
  1668. bool XMLSerializer::Add(std::set<T>& obj, const std::string& name)
  1669. {
  1670. return add(obj,name);
  1671. }
  1672. template<typename T0, typename T1>
  1673. bool XMLSerializer::Add(std::map<T0,T1>& obj, const std::string& name)
  1674. {
  1675. return add(obj,name);
  1676. }
  1677. template<typename T, int R, int C>
  1678. bool XMLSerializer::Add(Eigen::Matrix<T,R,C>& obj, const std::string& name)
  1679. {
  1680. return add(obj,name);
  1681. }
  1682. template<typename T>
  1683. bool XMLSerializer::Add(Eigen::SparseMatrix<T>& obj, const std::string& name)
  1684. {
  1685. return add(obj,name);
  1686. }
  1687. template<typename T>
  1688. bool XMLSerializer::Add(T& object, const std::string& name, T defaultValue)
  1689. {
  1690. return false;
  1691. }
  1692. bool XMLSerializer::Add(char& obj, const std::string& name, char defaultValue)
  1693. {
  1694. return add(obj,name,defaultValue);
  1695. }
  1696. bool XMLSerializer::Add(char*& obj, const std::string& name, char* defaultValue)
  1697. {
  1698. return add(obj,name,defaultValue);
  1699. }
  1700. bool XMLSerializer::Add(std::string& obj, const std::string& name, std::string defaultValue)
  1701. {
  1702. return add(obj,name,defaultValue);
  1703. }
  1704. bool XMLSerializer::Add(bool& obj, const std::string& name, bool defaultValue)
  1705. {
  1706. return add(obj,name,defaultValue);
  1707. }
  1708. bool XMLSerializer::Add(unsigned int& obj, const std::string& name, unsigned int defaultValue)
  1709. {
  1710. return add(obj,name,defaultValue);
  1711. }
  1712. bool XMLSerializer::Add(int& obj, const std::string& name, int defaultValue)
  1713. {
  1714. return add(obj,name,defaultValue);
  1715. }
  1716. bool XMLSerializer::Add(float& obj, const std::string& name, float defaultValue)
  1717. {
  1718. return add(obj,name,defaultValue);
  1719. }
  1720. bool XMLSerializer::Add(double& obj, const std::string& name, double defaultValue)
  1721. {
  1722. return add(obj,name,defaultValue);
  1723. }
  1724. template<typename T>
  1725. bool XMLSerializer::add(T& obj, const std::string& name)
  1726. {
  1727. XMLSerializable* object = new XMLSerializableInstance<T>(obj,name,currentGroup->first);
  1728. return addObjectToGroup(object,currentGroup);
  1729. }
  1730. template<typename T>
  1731. bool XMLSerializer::add(T& obj, const std::string& name, T defaultValue)
  1732. {
  1733. XMLSerializable* object = new XMLSerializableInstance<T>(obj,name,currentGroup->first,defaultValue);
  1734. return addObjectToGroup(object,currentGroup);
  1735. }
  1736. bool XMLSerializer::addObjectToGroup(XMLSerializable* obj, const std::string& group)
  1737. {
  1738. std::map<std::string,XMLSerializerGroup*>::iterator it = setGetGroup(group);
  1739. return addObjectToGroup(obj, it);
  1740. }
  1741. bool XMLSerializer::addObjectToGroup(XMLSerializable* object, std::map<std::string,XMLSerializerGroup*>::iterator it)
  1742. {
  1743. std::vector<XMLSerializable*>* objects = it->second->Objects;
  1744. for(unsigned int i=0;i<objects->size();i++)
  1745. {
  1746. if((*objects)[i]->Name == object->Name)
  1747. return false;
  1748. }
  1749. objects->push_back(object);
  1750. return true;
  1751. }
  1752. std::map<std::string,XMLSerializerGroup*>::iterator XMLSerializer::setGetGroup(const std::string& group)
  1753. {
  1754. std::string groupName = group;
  1755. EncodeXMLElementName(groupName);
  1756. std::map<std::string,XMLSerializerGroup*>::iterator it = groups.find(groupName);
  1757. if(it == groups.end())
  1758. {
  1759. XMLSerializerGroup* newGroup = new XMLSerializerGroup();
  1760. newGroup->Objects = new std::vector<XMLSerializable*>();
  1761. groups[groupName] = newGroup;
  1762. it = groups.find(groupName);
  1763. }
  1764. return it;
  1765. }
  1766. tinyxml2::XMLDocument* XMLSerializer::openDoc(const char* filename)
  1767. {
  1768. tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument();
  1769. tinyxml2::XMLError error = doc->LoadFile(filename);
  1770. if(error != tinyxml2::XML_NO_ERROR)
  1771. {
  1772. doc->PrintError();
  1773. doc = NULL;
  1774. }
  1775. return doc;
  1776. }
  1777. tinyxml2::XMLElement* XMLSerializer::findAddGroup(tinyxml2::XMLDocument* doc, const char* groupName)
  1778. {
  1779. tinyxml2::XMLElement* group = doc->FirstChildElement(groupName);
  1780. if(group == NULL)
  1781. {
  1782. group = doc->NewElement(groupName);
  1783. doc->InsertEndChild(group);
  1784. }
  1785. return group;
  1786. }
  1787. }
  1788. }
  1789. #endif