Xml.cpp 3.2 KB

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