| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
- // All rights reserved.
- // Code licensed under the BSD License.
- // http://www.anki3d.org/LICENSE
- #pragma once
- #include <AnKi/Util/DynamicArray.h>
- #include <AnKi/Util/String.h>
- #include <TinyXml2/tinyxml2.h>
- #if !ANKI_TINYXML2
- # error "Wrong tinyxml2 included"
- #endif
- namespace anki {
- /// @addtogroup util_file
- /// @{
- /// XML element.
- class XmlElement
- {
- template<typename>
- friend class XmlDocument;
- public:
- XmlElement() = default;
- /// Copy.
- XmlElement(const XmlElement& b)
- : m_el(b.m_el)
- , m_pool(b.m_pool)
- {
- }
- /// If element has something return true
- explicit operator Bool() const
- {
- return m_el != nullptr;
- }
- /// Copy
- XmlElement& operator=(const XmlElement& b)
- {
- m_el = b.m_el;
- m_pool = b.m_pool;
- return *this;
- }
- /// Return the text inside a tag. May return empty string.
- Error getText(CString& out) const;
- /// Return the text inside as a number.
- template<typename T>
- Error getNumber(T& out) const;
- /// Get a number of numbers.
- template<typename T, typename TMemoryPool>
- Error getNumbers(DynamicArray<T, TMemoryPool>& out) const;
- /// Get a fixed number of numbers.
- /// @tparam TArray A type that should have operator[] and getSize() methods implemented.
- template<typename TArray>
- Error getNumbers(TArray& out) const;
- /// Get a child element quietly
- Error getChildElementOptional(CString name, XmlElement& out) const;
- /// Get a child element and print error if not found
- Error getChildElement(CString name, XmlElement& out) const;
- /// Get the next element with the same name. Returns empty XmlElement if it reached the end of the list.
- Error getNextSiblingElement(CString name, XmlElement& out) const;
- /// Get the number of sibling elements of this node.
- /// @note The sibling elements share the same name.
- Error getSiblingElementsCount(U32& out) const;
- /// @name Get attributes optional
- /// @{
- /// Get value of a string attribute. May return empty string.
- /// @param name The name of the attribute.
- /// @param out The value of the attribute.
- /// @param attribPresent True if the attribute exists. If it doesn't the @a out is undefined.
- Error getAttributeTextOptional(CString name, CString& out, Bool& attribPresent) const;
- /// Get the attribute's value as a series of numbers.
- /// @param name The name of the attribute.
- /// @param out The value of the attribute.
- /// @param attribPresent True if the attribute exists. If it doesn't the @a out is undefined.
- template<typename T, typename TMemoryPool>
- Error getAttributeNumbersOptional(CString name, DynamicArray<T, TMemoryPool>& out, Bool& attribPresent) const;
- /// Get the attribute's value as a series of numbers.
- /// @tparam TArray A type that should have operator[] and getSize() methods implemented.
- /// @param name The name of the attribute.
- /// @param out The value of the attribute.
- /// @param attribPresent True if the attribute exists. If it doesn't the @a out is undefined.
- template<typename TArray>
- Error getAttributeNumbersOptional(CString name, TArray& out, Bool& attribPresent) const;
- /// Get the attribute's value as a number.
- /// @param name The name of the attribute.
- /// @param out The value of the attribute.
- /// @param attribPresent True if the attribute exists. If it doesn't the @a out is undefined.
- template<typename T>
- Error getAttributeNumberOptional(CString name, T& out, Bool& attribPresent) const;
- /// @}
- /// @name Get attributes
- /// @{
- /// Get value of a string attribute. May return empty string.
- /// @param name The name of the attribute.
- /// @param out The value of the attribute.
- Error getAttributeText(CString name, CString& out) const
- {
- Bool found;
- ANKI_CHECK(getAttributeTextOptional(name, out, found));
- return throwAttribNotFoundError(name, found);
- }
- /// Get the attribute's value as a series of numbers.
- /// @param name The name of the attribute.
- /// @param out The value of the attribute.
- template<typename T, typename TMemoryPool>
- Error getAttributeNumbers(CString name, DynamicArray<T, TMemoryPool>& out) const
- {
- Bool found;
- ANKI_CHECK(getAttributeNumbersOptional(name, out, found));
- return throwAttribNotFoundError(name, found);
- }
- /// Get the attribute's value as a series of numbers.
- /// @tparam TArray A type that should have operator[] and getSize() methods implemented.
- /// @param name The name of the attribute.
- /// @param out The value of the attribute.
- template<typename TArray>
- Error getAttributeNumbers(CString name, TArray& out) const
- {
- Bool found;
- ANKI_CHECK(getAttributeNumbersOptional(name, out, found));
- return throwAttribNotFoundError(name, found);
- }
- /// Get the attribute's value as a number.
- /// @param name The name of the attribute.
- /// @param out The value of the attribute.
- template<typename T>
- Error getAttributeNumber(CString name, T& out) const
- {
- Bool found;
- ANKI_CHECK(getAttributeNumberOptional(name, out, found));
- return throwAttribNotFoundError(name, found);
- }
- /// @}
- private:
- const tinyxml2::XMLElement* m_el = nullptr;
- BaseMemoryPool* m_pool = nullptr;
- XmlElement(const tinyxml2::XMLElement* el, BaseMemoryPool* pool)
- : m_el(el)
- , m_pool(pool)
- {
- }
- Error check() const;
- template<typename T, typename TMemoryPool>
- Error parseNumbers(CString txt, DynamicArray<T, TMemoryPool>& out) const;
- template<typename TArray>
- Error parseNumbers(CString txt, TArray& out) const;
- Error throwAttribNotFoundError(CString attrib, Bool found) const
- {
- if(!found)
- {
- ANKI_UTIL_LOGE("Attribute not found \"%s\"", &attrib[0]);
- return Error::kUserData;
- }
- else
- {
- return Error::kNone;
- }
- }
- };
- /// XML document.
- template<typename TMemoryPool>
- class XmlDocument
- {
- public:
- static constexpr CString kXmlHeader = R"(<?xml version="1.0" encoding="UTF-8" ?>)";
- XmlDocument(const TMemoryPool& pool = TMemoryPool())
- : m_pool(pool)
- {
- }
- /// Parse from a file.
- Error loadFile(CString filename);
- /// Parse from a CString.
- Error parse(CString xmlText);
- Error getChildElement(CString name, XmlElement& out) const;
- Error getChildElementOptional(CString name, XmlElement& out) const;
- private:
- mutable TMemoryPool m_pool;
- tinyxml2::XMLDocument m_doc;
- };
- /// @}
- } // end namespace anki
- #include <AnKi/Util/Xml.inl.h>
|