XMLSerialization.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. /**
  2. * XML Serialization
  3. * Simple and lightweight xml serialization class
  4. *
  5. * Original code by Lothar Perr
  6. *
  7. * This software is provided 'as-is', without any express or implied
  8. * warranty. In no event will the authors be held liable for any
  9. * damages arising from the use of this software.
  10. *
  11. * Permission is granted to anyone to use this software for any
  12. * purpose, including commercial applications, and to alter it and
  13. * redistribute it freely
  14. */
  15. #pragma once
  16. #include "stdafx.h"
  17. #include <algorithm>
  18. #include <string>
  19. #include <iostream>
  20. #include <sstream>
  21. #include "XMLSerialization.h"
  22. /**
  23. XML Serialization namespace
  24. */
  25. namespace xmls
  26. {
  27. /**
  28. Assign a value to the xint member
  29. @return void
  30. */
  31. void xInt::AssignValue(int value)
  32. {
  33. m_sValue =std::to_string(value);
  34. };
  35. /**
  36. Returns the int-value of the xint member
  37. @return current value
  38. */
  39. int xInt::value()
  40. {
  41. int value;
  42. value = std::stoi(m_sValue);
  43. return value;
  44. };
  45. /**
  46. Returns the bool-value of the xbool member
  47. @return current value
  48. */
  49. bool xBool::value()
  50. {
  51. bool value=false;
  52. std::string sHelp = m_sValue;
  53. transform(sHelp.begin(), sHelp.end(), sHelp.begin(), ::toupper);
  54. if (sHelp=="TRUE") return true;
  55. return value;
  56. };
  57. /**
  58. Assign a value to the xTime_t member
  59. @return void
  60. */
  61. void xTime_t::AssignValue(const time_t value)
  62. {
  63. m_sValue = std::to_string(value);
  64. }
  65. time_t xTime_t::value()
  66. {
  67. time_t t;
  68. t = std::stoi(m_sValue);
  69. return t;
  70. }
  71. /**
  72. Assign a value to the xOleDateTime member
  73. @return void
  74. */
  75. void xOleDateTime::AssignValue(const COleDateTime value)
  76. {
  77. const CString MSR_RESULT_INFOR_YMD = _T("%Y-%m-%d %H:%M:%S");
  78. m_sValue = value.Format (MSR_RESULT_INFOR_YMD);
  79. }
  80. COleDateTime xOleDateTime::value()
  81. {
  82. COleDateTime t;
  83. t.ParseDateTime(m_sValue.c_str());
  84. return t;
  85. }
  86. void xOleDateTimeSpan::AssignValue(const COleDateTimeSpan a_TimeSpan)
  87. {
  88. CString strRet;
  89. strRet.Format("%f", a_TimeSpan.m_span);
  90. m_sValue = strRet;
  91. }
  92. COleDateTimeSpan xOleDateTimeSpan::value()
  93. {
  94. COleDateTimeSpan t;
  95. t.m_span = atof(m_sValue.c_str());
  96. return t;
  97. }
  98. /**
  99. Delete all (self created) collection-elements
  100. @return void
  101. */
  102. class Slo;
  103. void CollectionBase::Clear()
  104. {
  105. if (m_vCollection.size()>0)
  106. {
  107. m_vCollection.clear();
  108. }
  109. }
  110. /**
  111. SerializableBase Constructor
  112. */
  113. Slo::Slo()
  114. {
  115. m_sClassName.clear ();
  116. m_sVersion.clear();
  117. m_sXML.clear();
  118. m_AttributeMappings.clear();
  119. m_MemberMappings.clear();
  120. m_MemberCollections.clear();
  121. }
  122. /**
  123. SerializableBase Destructor
  124. Clean Collections, Mappings and Subclass-Mappings
  125. */
  126. Slo::~Slo()
  127. {
  128. if (m_MemberCollections.size()>0)
  129. {
  130. m_MemberCollections.clear();
  131. }
  132. if (m_MemberMappings.size() > 0)
  133. {
  134. m_MemberMappings.clear();
  135. }
  136. if (m_AttributeMappings.size() > 0)
  137. {
  138. m_AttributeMappings.clear();
  139. }
  140. m_sXML.clear();
  141. m_sClassName.clear ();
  142. m_sVersion.clear();
  143. }
  144. /**
  145. Register a member
  146. @MemberName XML-Description/Name for the member
  147. @Member Member to register
  148. @return void
  149. */
  150. void Slo::Register(std::string MemberName, MemberBase *Member, std::string DefaultValue)
  151. {
  152. m_AttributeMappings[MemberName] = Member;
  153. }
  154. /**
  155. Register a member-subclass
  156. @MemberName XML-Description/Name for the member-class
  157. @Member Member-class to register
  158. @return void
  159. */
  160. void Slo::Register(std::string MemberName, ISlo *Member)
  161. {
  162. m_MemberMappings[MemberName] = Member;
  163. }
  164. /**
  165. Register a class-collection
  166. @CollectionName XML-Description/Name for the collection
  167. @SubclassCollection Collection to register
  168. @return void
  169. */
  170. void Slo::Register(std::string CollectionName, CollectionBase *SubclassCollection)
  171. {
  172. SubclassCollection->setCollectionName(CollectionName);
  173. m_MemberCollections[CollectionName] = SubclassCollection;
  174. }
  175. /**
  176. Perform serialization
  177. @classDoc tinyxml Class Document
  178. @rootNode tinyxml Element rootNode
  179. @return void
  180. */
  181. void Slo::toXML(tinyxml2::XMLDocument *classDoc, tinyxml2::XMLElement *rootNode)
  182. {
  183. for (auto it_member = m_AttributeMappings.begin() ; it_member != m_AttributeMappings.end(); ++it_member)
  184. {
  185. rootNode->SetAttribute(it_member->first.c_str(), it_member->second->c_str ());
  186. }
  187. for (auto it_subclass = m_MemberMappings.begin() ; it_subclass != m_MemberMappings.end(); ++it_subclass)
  188. {
  189. ISlo *subMember = it_subclass->second;
  190. tinyxml2::XMLElement *subClassNode = classDoc->NewElement("Member");
  191. subClassNode->SetAttribute("RegName", it_subclass->first.c_str());
  192. rootNode->InsertEndChild(subClassNode);
  193. subMember->Serialize(true,classDoc, subClassNode);
  194. }
  195. for (CollectionIterator it_collection = m_MemberCollections.begin() ; it_collection != m_MemberCollections.end(); ++it_collection)
  196. {
  197. tinyxml2::XMLElement *listNode = classDoc->NewElement("Collection");
  198. listNode->SetAttribute("RegName", (*it_collection).second ->getCollectionName().c_str());
  199. for (size_t c=0;c<(*it_collection).second->size();c++)
  200. {
  201. ISlo *item = (*it_collection).second ->getItem(c);
  202. tinyxml2::XMLElement *elementNode = classDoc->NewElement("Member");
  203. item->Serialize(true,classDoc, elementNode);
  204. listNode->InsertEndChild(elementNode);
  205. }
  206. rootNode->InsertEndChild(listNode);
  207. }
  208. }
  209. /**
  210. Perform deserialization
  211. @classItem destination object
  212. @classDoc tinyxml Class Document
  213. @rootNode tinyxml Element rootNode
  214. @return void
  215. */
  216. void Slo::fromXML( tinyxml2::XMLDocument *classDoc, tinyxml2::XMLElement *rootNode)
  217. {
  218. for (auto it = this->m_AttributeMappings.begin(); it != this->m_AttributeMappings.end(); ++it)
  219. {
  220. if (rootNode->Attribute(it->first.c_str() ))
  221. {
  222. *(it->second->getStringPtr ()) = rootNode->Attribute(it->first.c_str());// *(*it)->getField() = memberNode->GetText();
  223. }
  224. }
  225. tinyxml2::XMLElement *classNode = rootNode->FirstChildElement("Member");
  226. while(classNode!=NULL)
  227. {
  228. std::string className = classNode->Attribute("RegName");
  229. for (auto it_subclass = this->m_MemberMappings.begin(); it_subclass != this->m_MemberMappings.end(); ++it_subclass)
  230. {
  231. if (it_subclass->first == className)
  232. {
  233. it_subclass->second ->Serialize( false,classDoc, classNode);
  234. break;
  235. }
  236. }
  237. classNode = classNode->NextSiblingElement("Member");
  238. }
  239. tinyxml2::XMLElement *collectionNode = rootNode->FirstChildElement("Collection");
  240. while (collectionNode!=NULL)
  241. {
  242. std::string collectionName = collectionNode->Attribute("RegName");
  243. for (CollectionIterator it_collection = this->m_MemberCollections.begin() ; it_collection != this->m_MemberCollections.end(); ++it_collection)
  244. {
  245. if ((*it_collection).second ->getCollectionName()==collectionName)
  246. {
  247. (*it_collection).second ->Clear();
  248. tinyxml2::XMLElement *classNode = collectionNode->FirstChildElement("Member");
  249. while (classNode!=NULL)
  250. {
  251. ISlo *newItem = (*it_collection).second ->newElement();
  252. newItem->Serialize(false,classDoc, classNode);
  253. classNode = classNode->NextSiblingElement("Member");
  254. }
  255. }
  256. }
  257. collectionNode = collectionNode->NextSiblingElement("Collection");
  258. }
  259. }
  260. /**
  261. Get Class-Type of XML-Source
  262. @XMLSource XML-Input
  263. @return class name
  264. */
  265. std::string Slo::IdentifyClass(std::string XMLSource)
  266. {
  267. tinyxml2::XMLDocument doc;
  268. doc.Parse(XMLSource.c_str(), (size_t)XMLSource.length());
  269. tinyxml2::XMLElement* rootNode;
  270. rootNode = doc.FirstChildElement(RootClassName);
  271. if (rootNode)
  272. {
  273. const char* value = rootNode->Attribute("RegName");
  274. if (value) return std::string(value);
  275. }
  276. return Empty_String;
  277. }
  278. /**
  279. Get Class-Version of XML-Source
  280. @XMLSource XML-Input
  281. @return class version
  282. */
  283. std::string Slo::IdentifyClassVersion(std::string XMLSource)
  284. {
  285. tinyxml2::XMLDocument doc;
  286. doc.Parse(XMLSource.c_str(), (size_t)XMLSource.length());
  287. tinyxml2::XMLElement* rootNode;
  288. rootNode = doc.FirstChildElement(RootClassName);
  289. if (rootNode)
  290. {
  291. const char* value = rootNode->Attribute("Version");
  292. if (value) return std::string(value);
  293. }
  294. return Empty_String;
  295. }
  296. /**
  297. Search/Replace in a string
  298. @source source the source string
  299. @searchFor search for
  300. @replaceWith replace with
  301. @return the resulting string
  302. */
  303. std::string Slo::strReplaceAll(std::string source, const std::string searchFor, const std::string replaceWith)
  304. {
  305. if(searchFor.empty())
  306. return source;
  307. size_t start_pos = 0;
  308. while((start_pos = source.find(searchFor, start_pos)) != std::string::npos) {
  309. source.replace(start_pos, searchFor.length(), replaceWith);
  310. start_pos += replaceWith.length();
  311. }
  312. return source;
  313. }
  314. void Slo::Clear()
  315. {
  316. m_AttributeMappings.clear ();
  317. m_MemberMappings.clear ();
  318. m_MemberCollections.clear ();
  319. }
  320. void xDouble::AssignValue(const double value)
  321. {
  322. m_sValue = std::to_string(value);
  323. }
  324. double xDouble::value()
  325. {
  326. double value;
  327. value = std::stod(m_sValue);
  328. return value;
  329. }
  330. void xLong::AssignValue(const long value)
  331. {
  332. m_sValue = std::to_string(value);
  333. }
  334. long xLong::value()
  335. {
  336. long value;
  337. value = std::stol(m_sValue);
  338. return value;
  339. }
  340. void xDWORD::AssignValue(const DWORD value)
  341. {
  342. m_sValue = std::to_string(value);
  343. }
  344. DWORD xDWORD::value()
  345. {
  346. DWORD value;
  347. value = std::stol(m_sValue);
  348. return value;
  349. }
  350. void xRect::AssignValue(const CRect value, int shape)
  351. {// domain text body
  352. CString strDomainTextBody = _T("");
  353. // value 1 -- shape
  354. CString strValue;
  355. // value 2 -- center x
  356. // domain center
  357. strValue.Format("%d", (int)value.CenterPoint().x);
  358. strDomainTextBody += strValue + _T(",");
  359. // value 3 -- center y
  360. strValue.Format("%d", (int)value.CenterPoint().y);
  361. strDomainTextBody += strValue + _T(",");
  362. if (shape==0)
  363. {
  364. // value 4 -- diameter
  365. strValue.Format("%d", (int)value.Width ());
  366. strDomainTextBody += strValue+ _T(",");
  367. // value 5 -- 0
  368. strDomainTextBody += _T("0");
  369. }
  370. else
  371. {
  372. // value 4 -- width
  373. strValue.Format("%d", (int)value.Width());
  374. strDomainTextBody += strValue + _T(",");
  375. // value 5 -- height
  376. strValue.Format("%d", (int)value.Height());
  377. strDomainTextBody += strValue ;
  378. }
  379. // return domain text body
  380. m_sValue= strDomainTextBody;
  381. }
  382. CRect xRect::value()
  383. {//here,we use the rectangle's left,top,right,bottom to memorize these four numbers.Infact they are centreX, centreY , diameter(width),0(height) if the shape is circle.
  384. //so when we get these numbers we must get left,top,right,bottom because they are just four numbers memory here temporarily.
  385. CRect rectangle;
  386. std::vector<std::string> point;
  387. SplitString(m_sValue, point, ",");
  388. rectangle.left = stoi(point[0]);
  389. rectangle.top = stoi(point[1]);
  390. rectangle.right = stoi( point[2]);
  391. rectangle.bottom = stoi(point[3]);
  392. return rectangle;
  393. }
  394. void xPoint::AssignValue(const CPoint value)
  395. {
  396. int X = value.x;
  397. int Y= value.y;
  398. std::string OutString;
  399. std::string sX = std::to_string(X);
  400. std::string sY = std::to_string(Y);
  401. OutString = sX + "," + sY ;
  402. m_sValue = OutString;
  403. }
  404. CPoint xPoint::value()
  405. {
  406. CPoint p;
  407. std::vector<std::string> point;
  408. SplitString(m_sValue, point, ",");
  409. p.x = stoi(point[0], 0, 0);
  410. p.y = stoi(point[1], 0, 0);
  411. return p;
  412. }
  413. void SplitString(const std::string& s, std::vector<std::string>& v, const std::string& c)
  414. {
  415. std::string::size_type pos1, pos2;
  416. pos2 = s.find(c);
  417. pos1 = 0;
  418. while (std::string::npos != pos2)
  419. {
  420. v.push_back(s.substr(pos1, pos2 - pos1));
  421. pos1 = pos2 + c.size();
  422. pos2 = s.find(c, pos1);
  423. }
  424. if (pos1 != s.length())
  425. v.push_back(s.substr(pos1));
  426. }
  427. std::vector<std::string> SplitString(const std::string& s, const std::string& c)
  428. {
  429. std::string::size_type pos1, pos2;
  430. pos2 = s.find(c);
  431. pos1 = 0;
  432. std::vector<std::string> v;
  433. while (std::string::npos != pos2)
  434. {
  435. v.push_back(s.substr(pos1, pos2 - pos1));
  436. pos1 = pos2 + c.size();
  437. pos2 = s.find(c, pos1);
  438. }
  439. if (pos1 != s.length())
  440. v.push_back(s.substr(pos1));
  441. return v;
  442. }
  443. void ReplaceAll(std::string& content, std::string searchFor, std::string replaceWith)
  444. {
  445. if (searchFor.empty())
  446. return ;
  447. size_t start_pos = 0;
  448. while ((start_pos = content.find(searchFor, start_pos)) != std::string::npos) {
  449. content.replace(start_pos, searchFor.length(), replaceWith);
  450. start_pos += replaceWith.length();
  451. }
  452. return ;
  453. /*while (content.find(substr1) > 0)
  454. {
  455. content.replace(content.find(substr1), substr1.size(), substr2);
  456. }*/
  457. }
  458. void ReplaceFirst(std::string& content, std::string searchFor, std::string replaceWith)
  459. {
  460. if (searchFor.empty())
  461. return;
  462. size_t start_pos = 0;
  463. start_pos = content.find(searchFor, start_pos);
  464. if (start_pos != std::string::npos)
  465. {
  466. content.replace(start_pos, searchFor.length(), replaceWith);
  467. //start_pos += replaceWith.length();
  468. }
  469. return;
  470. /*while (content.find(substr1) > 0)
  471. {
  472. content.replace(content.find(substr1), substr1.size(), substr2);
  473. }*/
  474. }
  475. }