Xml.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. // Copyright (C) 2009-2022, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <AnKi/Util/DynamicArray.h>
  7. #include <AnKi/Util/String.h>
  8. #include <TinyXml2/include/tinyxml2.h>
  9. #if !ANKI_TINYXML2
  10. # error "Wrong tinyxml2 included"
  11. #endif
  12. namespace anki {
  13. /// @addtogroup util_file
  14. /// @{
  15. /// XML element.
  16. class XmlElement
  17. {
  18. friend class XmlDocument;
  19. public:
  20. XmlElement()
  21. : m_el(nullptr)
  22. {
  23. }
  24. XmlElement(const XmlElement& b)
  25. : m_el(b.m_el)
  26. , m_alloc(b.m_alloc)
  27. {
  28. }
  29. /// If element has something return true
  30. explicit operator Bool() const
  31. {
  32. return m_el != nullptr;
  33. }
  34. /// Copy
  35. XmlElement& operator=(const XmlElement& b)
  36. {
  37. m_el = b.m_el;
  38. m_alloc = b.m_alloc;
  39. return *this;
  40. }
  41. /// Return the text inside a tag. May return empty string.
  42. Error getText(CString& out) const;
  43. /// Return the text inside as a number.
  44. template<typename T>
  45. Error getNumber(T& out) const;
  46. /// Get a number of numbers.
  47. template<typename T>
  48. Error getNumbers(DynamicArrayAuto<T>& out) const;
  49. /// Get a fixed number of numbers.
  50. /// @tparam TArray A type that should have operator[] and getSize() methods implemented.
  51. template<typename TArray>
  52. Error getNumbers(TArray& out) const;
  53. /// Get a child element quietly
  54. Error getChildElementOptional(CString name, XmlElement& out) const;
  55. /// Get a child element and print error if not found
  56. Error getChildElement(CString name, XmlElement& out) const;
  57. /// Get the next element with the same name. Returns empty XmlElement if it reached the end of the list.
  58. Error getNextSiblingElement(CString name, XmlElement& out) const;
  59. /// Get the number of sibling elements of this node.
  60. /// @note The sibling elements share the same name.
  61. Error getSiblingElementsCount(U32& out) const;
  62. /// @name Get attributes optional
  63. /// @{
  64. /// Get value of a string attribute. May return empty string.
  65. /// @param name The name of the attribute.
  66. /// @param out The value of the attribute.
  67. /// @param attribPresent True if the attribute exists. If it doesn't the @a out is undefined.
  68. Error getAttributeTextOptional(CString name, CString& out, Bool& attribPresent) const;
  69. /// Get the attribute's value as a series of numbers.
  70. /// @param name The name of the attribute.
  71. /// @param out The value of the attribute.
  72. /// @param attribPresent True if the attribute exists. If it doesn't the @a out is undefined.
  73. template<typename T>
  74. Error getAttributeNumbersOptional(CString name, DynamicArrayAuto<T>& out, Bool& attribPresent) const;
  75. /// Get the attribute's value as a series of numbers.
  76. /// @tparam TArray A type that should have operator[] and getSize() methods implemented.
  77. /// @param name The name of the attribute.
  78. /// @param out The value of the attribute.
  79. /// @param attribPresent True if the attribute exists. If it doesn't the @a out is undefined.
  80. template<typename TArray>
  81. Error getAttributeNumbersOptional(CString name, TArray& out, Bool& attribPresent) const;
  82. /// Get the attribute's value as a number.
  83. /// @param name The name of the attribute.
  84. /// @param out The value of the attribute.
  85. /// @param attribPresent True if the attribute exists. If it doesn't the @a out is undefined.
  86. template<typename T>
  87. Error getAttributeNumberOptional(CString name, T& out, Bool& attribPresent) const;
  88. /// @}
  89. /// @name Get attributes
  90. /// @{
  91. /// Get value of a string attribute. May return empty string.
  92. /// @param name The name of the attribute.
  93. /// @param out The value of the attribute.
  94. Error getAttributeText(CString name, CString& out) const
  95. {
  96. Bool found;
  97. ANKI_CHECK(getAttributeTextOptional(name, out, found));
  98. return throwAttribNotFoundError(name, found);
  99. }
  100. /// Get the attribute's value as a series of numbers.
  101. /// @param name The name of the attribute.
  102. /// @param out The value of the attribute.
  103. template<typename T>
  104. Error getAttributeNumbers(CString name, DynamicArrayAuto<T>& out) const
  105. {
  106. Bool found;
  107. ANKI_CHECK(getAttributeNumbersOptional(name, out, found));
  108. return throwAttribNotFoundError(name, found);
  109. }
  110. /// Get the attribute's value as a series of numbers.
  111. /// @tparam TArray A type that should have operator[] and getSize() methods implemented.
  112. /// @param name The name of the attribute.
  113. /// @param out The value of the attribute.
  114. template<typename TArray>
  115. Error getAttributeNumbers(CString name, TArray& out) const
  116. {
  117. Bool found;
  118. ANKI_CHECK(getAttributeNumbersOptional(name, out, found));
  119. return throwAttribNotFoundError(name, found);
  120. }
  121. /// Get the attribute's value as a number.
  122. /// @param name The name of the attribute.
  123. /// @param out The value of the attribute.
  124. template<typename T>
  125. Error getAttributeNumber(CString name, T& out) const
  126. {
  127. Bool found;
  128. ANKI_CHECK(getAttributeNumberOptional(name, out, found));
  129. return throwAttribNotFoundError(name, found);
  130. }
  131. /// @}
  132. private:
  133. const tinyxml2::XMLElement* m_el;
  134. GenericMemoryPoolAllocator<U8> m_alloc;
  135. XmlElement(const tinyxml2::XMLElement* el, GenericMemoryPoolAllocator<U8> alloc)
  136. : m_el(el)
  137. , m_alloc(alloc)
  138. {
  139. }
  140. Error check() const;
  141. template<typename T>
  142. Error parseNumbers(CString txt, DynamicArrayAuto<T>& out) const;
  143. template<typename TArray>
  144. Error parseNumbers(CString txt, TArray& out) const;
  145. Error throwAttribNotFoundError(CString attrib, Bool found) const
  146. {
  147. if(!found)
  148. {
  149. ANKI_UTIL_LOGE("Attribute not found \"%s\"", &attrib[0]);
  150. return Error::USER_DATA;
  151. }
  152. else
  153. {
  154. return Error::NONE;
  155. }
  156. }
  157. };
  158. /// XML document.
  159. class XmlDocument
  160. {
  161. public:
  162. static CString XML_HEADER;
  163. /// Parse from a file.
  164. Error loadFile(CString filename, GenericMemoryPoolAllocator<U8> alloc);
  165. /// Parse from a CString.
  166. Error parse(CString xmlText, GenericMemoryPoolAllocator<U8> alloc);
  167. Error getChildElement(CString name, XmlElement& out) const;
  168. Error getChildElementOptional(CString name, XmlElement& out) const;
  169. private:
  170. tinyxml2::XMLDocument m_doc;
  171. GenericMemoryPoolAllocator<U8> m_alloc;
  172. };
  173. /// @}
  174. } // end namespace anki
  175. #include <AnKi/Util/Xml.inl.h>