Xml.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. // Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <AnKi/Util/Xml.h>
  6. #include <AnKi/Util/File.h>
  7. #include <AnKi/Util/Logger.h>
  8. namespace anki {
  9. Error XmlElement::check() const
  10. {
  11. Error err = Error::NONE;
  12. if(m_el == nullptr)
  13. {
  14. ANKI_UTIL_LOGE("Empty element");
  15. err = Error::USER_DATA;
  16. }
  17. return err;
  18. }
  19. Error XmlElement::getText(CString& out) const
  20. {
  21. ANKI_CHECK(check());
  22. out = (m_el->GetText()) ? CString(m_el->GetText()) : CString();
  23. return Error::NONE;
  24. }
  25. Error XmlElement::getChildElementOptional(CString name, XmlElement& out) const
  26. {
  27. const Error err = check();
  28. if(!err)
  29. {
  30. out = XmlElement(m_el->FirstChildElement(&name[0]), m_alloc);
  31. }
  32. else
  33. {
  34. out = XmlElement();
  35. }
  36. return err;
  37. }
  38. Error XmlElement::getChildElement(CString name, XmlElement& out) const
  39. {
  40. Error err = check();
  41. if(err)
  42. {
  43. out = XmlElement();
  44. return err;
  45. }
  46. err = getChildElementOptional(name, out);
  47. if(err)
  48. {
  49. return err;
  50. }
  51. if(!out)
  52. {
  53. ANKI_UTIL_LOGE("Cannot find tag: %s", &name[0]);
  54. err = Error::USER_DATA;
  55. }
  56. return err;
  57. }
  58. Error XmlElement::getNextSiblingElement(CString name, XmlElement& out) const
  59. {
  60. const Error err = check();
  61. if(!err)
  62. {
  63. out = XmlElement(m_el->NextSiblingElement(&name[0]), m_alloc);
  64. }
  65. else
  66. {
  67. out = XmlElement();
  68. }
  69. return err;
  70. }
  71. Error XmlElement::getSiblingElementsCount(U32& out) const
  72. {
  73. ANKI_CHECK(check());
  74. const tinyxml2::XMLElement* el = m_el;
  75. out = 0;
  76. do
  77. {
  78. el = el->NextSiblingElement(m_el->Name());
  79. ++out;
  80. } while(el);
  81. out -= 1;
  82. return Error::NONE;
  83. }
  84. Error XmlElement::getAttributeTextOptional(CString name, CString& out, Bool& attribPresent) const
  85. {
  86. ANKI_CHECK(check());
  87. const tinyxml2::XMLAttribute* attrib = m_el->FindAttribute(&name[0]);
  88. if(!attrib)
  89. {
  90. attribPresent = false;
  91. return Error::NONE;
  92. }
  93. attribPresent = true;
  94. const char* value = attrib->Value();
  95. if(value)
  96. {
  97. out = value;
  98. }
  99. else
  100. {
  101. out = CString();
  102. }
  103. return Error::NONE;
  104. }
  105. CString XmlDocument::XML_HEADER = R"(<?xml version="1.0" encoding="UTF-8" ?>)";
  106. Error XmlDocument::loadFile(CString filename, GenericMemoryPoolAllocator<U8> alloc)
  107. {
  108. File file;
  109. ANKI_CHECK(file.open(filename, FileOpenFlag::READ));
  110. StringAuto text(alloc);
  111. ANKI_CHECK(file.readAllText(text));
  112. ANKI_CHECK(parse(text.toCString(), alloc));
  113. return Error::NONE;
  114. }
  115. Error XmlDocument::parse(CString xmlText, GenericMemoryPoolAllocator<U8> alloc)
  116. {
  117. m_alloc = alloc;
  118. if(m_doc.Parse(&xmlText[0]))
  119. {
  120. ANKI_UTIL_LOGE("Cannot parse file. Reason: %s",
  121. ((m_doc.GetErrorStr1() == nullptr) ? "unknown" : m_doc.GetErrorStr1()));
  122. return Error::USER_DATA;
  123. }
  124. return Error::NONE;
  125. }
  126. ANKI_USE_RESULT Error XmlDocument::getChildElementOptional(CString name, XmlElement& out) const
  127. {
  128. out = XmlElement(m_doc.FirstChildElement(&name[0]), m_alloc);
  129. return Error::NONE;
  130. }
  131. ANKI_USE_RESULT Error XmlDocument::getChildElement(CString name, XmlElement& out) const
  132. {
  133. ANKI_CHECK(getChildElementOptional(name, out));
  134. if(!out)
  135. {
  136. ANKI_UTIL_LOGE("Cannot find tag \"%s\"", &name[0]);
  137. return Error::USER_DATA;
  138. }
  139. return Error::NONE;
  140. }
  141. } // end namespace anki