summaryrefslogtreecommitdiff
path: root/src/mesh/assimp-master/include/assimp/XmlParser.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesh/assimp-master/include/assimp/XmlParser.h')
-rw-r--r--src/mesh/assimp-master/include/assimp/XmlParser.h493
1 files changed, 493 insertions, 0 deletions
diff --git a/src/mesh/assimp-master/include/assimp/XmlParser.h b/src/mesh/assimp-master/include/assimp/XmlParser.h
new file mode 100644
index 0000000..28f2be8
--- /dev/null
+++ b/src/mesh/assimp-master/include/assimp/XmlParser.h
@@ -0,0 +1,493 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2022, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+
+#ifndef INCLUDED_AI_IRRXML_WRAPPER
+#define INCLUDED_AI_IRRXML_WRAPPER
+
+#include <assimp/ai_assert.h>
+#include <assimp/DefaultLogger.hpp>
+
+#include "BaseImporter.h"
+#include "IOStream.hpp"
+
+#include <pugixml.hpp>
+#include <vector>
+
+namespace Assimp {
+
+/// @brief Will find a node by its name.
+struct find_node_by_name_predicate {
+ std::string mName;
+ find_node_by_name_predicate(const std::string &name) :
+ mName(name) {
+ // empty
+ }
+
+ bool operator()(pugi::xml_node node) const {
+ return node.name() == mName;
+ }
+};
+
+/// @brief Will convert an attribute to its int value.
+/// @tparam TNodeType The node type.
+template <class TNodeType>
+struct NodeConverter {
+public:
+ static int to_int(TNodeType &node, const char *attribName) {
+ ai_assert(nullptr != attribName);
+ return node.attribute(attribName).to_int();
+ }
+};
+
+using XmlNode = pugi::xml_node;
+using XmlAttribute = pugi::xml_attribute;
+
+/// @brief The Xml-Parser class.
+///
+/// Use this parser if you have to import any kind of xml-format.
+///
+/// An example:
+/// @code
+/// TXmlParser<XmlNode> theParser;
+/// if (theParser.parse(fileStream)) {
+/// auto node = theParser.getRootNode();
+/// for ( auto currentNode : node.children()) {
+/// // Will loop over all children
+/// }
+/// }
+/// @endcode
+/// @tparam TNodeType
+template <class TNodeType>
+class TXmlParser {
+public:
+ /// @brief The default class constructor.
+ TXmlParser() :
+ mDoc(nullptr),
+ mData() {
+ // empty
+ }
+
+ /// @brief The class destructor.
+ ~TXmlParser() {
+ clear();
+ }
+
+ /// @brief Will clear the parsed xml-file.
+ void clear() {
+ if (mData.empty()) {
+ mDoc = nullptr;
+ return;
+ }
+ mData.clear();
+ delete mDoc;
+ mDoc = nullptr;
+ }
+
+ /// @brief Will search for a child-node by its name
+ /// @param name [in] The name of the child-node.
+ /// @return The node instance or nullptr, if nothing was found.
+ TNodeType *findNode(const std::string &name) {
+ if (name.empty()) {
+ return nullptr;
+ }
+
+ if (nullptr == mDoc) {
+ return nullptr;
+ }
+
+ find_node_by_name_predicate predicate(name);
+ mCurrent = mDoc->find_node(predicate);
+ if (mCurrent.empty()) {
+ return nullptr;
+ }
+
+ return &mCurrent;
+ }
+
+ /// @brief Will return true, if the node is a child-node.
+ /// @param name [in] The name of the child node to look for.
+ /// @return true, if the node is a child-node or false if not.
+ bool hasNode(const std::string &name) {
+ return nullptr != findNode(name);
+ }
+
+ /// @brief Will parse an xml-file from a given stream.
+ /// @param stream The input stream.
+ /// @return true, if the parsing was successful, false if not.
+ bool parse(IOStream *stream) {
+ if (nullptr == stream) {
+ ASSIMP_LOG_DEBUG("Stream is nullptr.");
+ return false;
+ }
+
+ const size_t len = stream->FileSize();
+ mData.resize(len + 1);
+ memset(&mData[0], '\0', len + 1);
+ stream->Read(&mData[0], 1, len);
+
+ mDoc = new pugi::xml_document();
+ pugi::xml_parse_result parse_result = mDoc->load_string(&mData[0], pugi::parse_full);
+ if (parse_result.status == pugi::status_ok) {
+ return true;
+ }
+
+ ASSIMP_LOG_DEBUG("Error while parse xml.", std::string(parse_result.description()), " @ ", parse_result.offset);
+
+ return false;
+ }
+
+ /// @brief Will return truem if a root node is there.
+ /// @return true in case of an existing root.
+ bool hasRoot() const {
+ return nullptr != mDoc;
+ }
+ /// @brief Will return the document pointer, is nullptr if no xml-file was parsed.
+ /// @return The pointer showing to the document.
+ pugi::xml_document *getDocument() const {
+ return mDoc;
+ }
+
+ /// @brief Will return the root node, const version.
+ /// @return The root node.
+ const TNodeType getRootNode() const {
+ static pugi::xml_node none;
+ if (nullptr == mDoc) {
+ return none;
+ }
+ return mDoc->root();
+ }
+
+ /// @brief Will return the root node, non-const version.
+ /// @return The root node.
+ TNodeType getRootNode() {
+ static pugi::xml_node none;
+ if (nullptr == mDoc) {
+ return none;
+ }
+ return mDoc->root();
+ }
+
+ /// @brief Will check if a node with the given name is in.
+ /// @param node [in] The node to look in.
+ /// @param name [in] The name of the child-node.
+ /// @return true, if node was found, false if not.
+ static inline bool hasNode(XmlNode &node, const char *name) {
+ pugi::xml_node child = node.find_child(find_node_by_name_predicate(name));
+ return !child.empty();
+ }
+
+ /// @brief Will check if an attribute is part of the XmlNode.
+ /// @param xmlNode [in] The node to search in.
+ /// @param name [in} The attribute name to look for.
+ /// @return true, if the was found, false if not.
+ static inline bool hasAttribute(XmlNode &xmlNode, const char *name) {
+ pugi::xml_attribute attr = xmlNode.attribute(name);
+ return !attr.empty();
+ }
+
+ /// @brief Will try to get an unsigned int attribute value.
+ /// @param xmlNode [in] The node to search in.
+ /// @param name [in] The attribute name to look for.
+ /// @param val [out] The unsigned int value from the attribute.
+ /// @return true, if the node contains an attribute with the given name and if the value is an unsigned int.
+ static inline bool getUIntAttribute(XmlNode &xmlNode, const char *name, unsigned int &val) {
+ pugi::xml_attribute attr = xmlNode.attribute(name);
+ if (attr.empty()) {
+ return false;
+ }
+
+ val = attr.as_uint();
+ return true;
+ }
+
+ /// @brief Will try to get an int attribute value.
+ /// @param xmlNode [in] The node to search in.
+ /// @param name [in] The attribute name to look for.
+ /// @param val [out] The int value from the attribute.
+ /// @return true, if the node contains an attribute with the given name and if the value is an int.
+ static inline bool getIntAttribute(XmlNode &xmlNode, const char *name, int &val) {
+ pugi::xml_attribute attr = xmlNode.attribute(name);
+ if (attr.empty()) {
+ return false;
+ }
+
+ val = attr.as_int();
+ return true;
+ }
+
+ /// @brief Will try to get a real attribute value.
+ /// @param xmlNode [in] The node to search in.
+ /// @param name [in] The attribute name to look for.
+ /// @param val [out] The real value from the attribute.
+ /// @return true, if the node contains an attribute with the given name and if the value is a real.
+ static inline bool getRealAttribute(XmlNode &xmlNode, const char *name, ai_real &val) {
+ pugi::xml_attribute attr = xmlNode.attribute(name);
+ if (attr.empty()) {
+ return false;
+ }
+#ifdef ASSIMP_DOUBLE_PRECISION
+ val = attr.as_double();
+#else
+ val = attr.as_float();
+#endif
+ return true;
+ }
+
+ /// @brief Will try to get a float attribute value.
+ /// @param xmlNode [in] The node to search in.
+ /// @param name [in] The attribute name to look for.
+ /// @param val [out] The float value from the attribute.
+ /// @return true, if the node contains an attribute with the given name and if the value is a float.
+ static inline bool getFloatAttribute(XmlNode &xmlNode, const char *name, float &val) {
+ pugi::xml_attribute attr = xmlNode.attribute(name);
+ if (attr.empty()) {
+ return false;
+ }
+
+ val = attr.as_float();
+ return true;
+ }
+
+ /// @brief Will try to get a double attribute value.
+ /// @param xmlNode [in] The node to search in.
+ /// @param name [in] The attribute name to look for.
+ /// @param val [out] The double value from the attribute.
+ /// @return true, if the node contains an attribute with the given name and if the value is a double.
+ static inline bool getDoubleAttribute(XmlNode &xmlNode, const char *name, double &val) {
+ pugi::xml_attribute attr = xmlNode.attribute(name);
+ if (attr.empty()) {
+ return false;
+ }
+
+ val = attr.as_double();
+ return true;
+ }
+
+ /// @brief Will try to get a std::string attribute value.
+ /// @param xmlNode [in] The node to search in.
+ /// @param name [in] The attribute name to look for.
+ /// @param val [out] The std::string value from the attribute.
+ /// @return true, if the node contains an attribute with the given name and if the value is a std::string.
+ static inline bool getStdStrAttribute(XmlNode &xmlNode, const char *name, std::string &val) {
+ pugi::xml_attribute attr = xmlNode.attribute(name);
+ if (attr.empty()) {
+ return false;
+ }
+
+ val = attr.as_string();
+ return true;
+ }
+
+ /// @brief Will try to get a bool attribute value.
+ /// @param xmlNode [in] The node to search in.
+ /// @param name [in] The attribute name to look for.
+ /// @param val [out] The bool value from the attribute.
+ /// @return true, if the node contains an attribute with the given name and if the value is a bool.
+ static inline bool getBoolAttribute(XmlNode &xmlNode, const char *name, bool &val) {
+ pugi::xml_attribute attr = xmlNode.attribute(name);
+ if (attr.empty()) {
+ return false;
+ }
+
+ val = attr.as_bool();
+ return true;
+ }
+
+ /// @brief Will try to get the value of the node as a string.
+ /// @param node [in] The node to search in.
+ /// @param text [out] The value as a text.
+ /// @return true, if the value can be read out.
+ static inline bool getValueAsString(XmlNode &node, std::string &text) {
+ text = std::string();
+ if (node.empty()) {
+ return false;
+ }
+
+ text = node.text().as_string();
+
+ return true;
+ }
+
+ /// @brief Will try to get the value of the node as a float.
+ /// @param node [in] The node to search in.
+ /// @param text [out] The value as a float.
+ /// @return true, if the value can be read out.
+ static inline bool getValueAsFloat(XmlNode &node, ai_real &v) {
+ if (node.empty()) {
+ return false;
+ }
+
+ v = node.text().as_float();
+
+ return true;
+ }
+
+ /// @brief Will try to get the value of the node as an integer.
+ /// @param node [in] The node to search in.
+ /// @param text [out] The value as a int.
+ /// @return true, if the value can be read out.
+ static inline bool getValueAsInt(XmlNode &node, int &v) {
+ if (node.empty()) {
+ return false;
+ }
+
+ v = node.text().as_int();
+
+ return true;
+ }
+
+ /// @brief Will try to get the value of the node as an bool.
+ /// @param node [in] The node to search in.
+ /// @param text [out] The value as a bool.
+ /// @return true, if the value can be read out.
+ static inline bool getValueAsBool(XmlNode& node, bool& v)
+ {
+ if (node.empty()) {
+ return false;
+ }
+
+ v = node.text().as_bool();
+
+ return true;
+ }
+
+private:
+ pugi::xml_document *mDoc;
+ TNodeType mCurrent;
+ std::vector<char> mData;
+};
+
+using XmlParser = TXmlParser<pugi::xml_node>;
+
+/// @brief This class declares an iterator to loop through all children of the root node.
+class XmlNodeIterator {
+public:
+ /// @brief The iteration mode.
+ enum IterationMode {
+ PreOrderMode, ///< Pre-ordering, get the values, continue the iteration.
+ PostOrderMode ///< Post-ordering, continue the iteration, get the values.
+ };
+ /// @brief The class constructor
+ /// @param parent [in] The xml parent to to iterate through.
+ /// @param mode [in] The iteration mode.
+ explicit XmlNodeIterator(XmlNode &parent, IterationMode mode) :
+ mParent(parent),
+ mNodes(),
+ mIndex(0) {
+ if (mode == PreOrderMode) {
+ collectChildrenPreOrder(parent);
+ } else {
+ collectChildrenPostOrder(parent);
+ }
+ }
+
+ /// @brief The class destructor.
+ ~XmlNodeIterator() {
+ // empty
+ }
+
+ /// @brief Will iterate through all children in pre-order iteration.
+ /// @param node [in] The nod to iterate through.
+ void collectChildrenPreOrder(XmlNode &node) {
+ if (node != mParent && node.type() == pugi::node_element) {
+ mNodes.push_back(node);
+ }
+ for (XmlNode currentNode : node.children()) {
+ collectChildrenPreOrder(currentNode);
+ }
+ }
+
+ /// @brief Will iterate through all children in post-order iteration.
+ /// @param node [in] The nod to iterate through.
+ void collectChildrenPostOrder(XmlNode &node) {
+ for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
+ collectChildrenPostOrder(currentNode);
+ }
+ if (node != mParent) {
+ mNodes.push_back(node);
+ }
+ }
+
+ /// @brief Will iterate through all collected nodes.
+ /// @param next The next node, if there is any.
+ /// @return true, if there is a node left.
+ bool getNext(XmlNode &next) {
+ if (mIndex == mNodes.size()) {
+ return false;
+ }
+
+ next = mNodes[mIndex];
+ ++mIndex;
+
+ return true;
+ }
+
+ /// @brief Will return the number of collected nodes.
+ /// @return The number of collected nodes.
+ size_t size() const {
+ return mNodes.size();
+ }
+
+ /// @brief Returns true, if the node is empty.
+ /// @return true, if the node is empty, false if not.
+ bool isEmpty() const {
+ return mNodes.empty();
+ }
+
+ /// @brief Will clear all collected nodes.
+ void clear() {
+ if (mNodes.empty()) {
+ return;
+ }
+
+ mNodes.clear();
+ mIndex = 0;
+ }
+
+private:
+ XmlNode &mParent;
+ std::vector<XmlNode> mNodes;
+ size_t mIndex;
+};
+
+} // namespace Assimp
+
+#endif // !! INCLUDED_AI_IRRXML_WRAPPER