Path Tracer
XmlParser.h
1 /*
2 Open Asset Import Library (assimp)
3 ----------------------------------------------------------------------
4 
5 Copyright (c) 2006-2020, assimp team
6 
7 All rights reserved.
8 
9 Redistribution and use of this software in source and binary forms,
10 with or without modification, are permitted provided that the
11 following conditions are met:
12 
13 * Redistributions of source code must retain the above
14 copyright notice, this list of conditions and the
15 following disclaimer.
16 
17 * Redistributions in binary form must reproduce the above
18 copyright notice, this list of conditions and the
19 following disclaimer in the documentation and/or other
20 materials provided with the distribution.
21 
22 * Neither the name of the assimp team, nor the names of its
23 contributors may be used to endorse or promote products
24 derived from this software without specific prior
25 written permission of the assimp team.
26 
27 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 
39 ----------------------------------------------------------------------
40 */
41 
42 #ifndef INCLUDED_AI_IRRXML_WRAPPER
43 #define INCLUDED_AI_IRRXML_WRAPPER
44 
45 #include <assimp/DefaultLogger.hpp>
46 #include "BaseImporter.h"
47 #include "IOStream.hpp"
48 #include <pugixml.hpp>
49 #include <vector>
50 
51 namespace Assimp {
52 
54  std::string mName;
55  find_node_by_name_predicate(const std::string &name) :
56  mName(name) {
57  // empty
58  }
59 
60  bool operator()(pugi::xml_node node) const {
61  return node.name() == mName;
62  }
63 };
64 
65 template <class TNodeType>
66 struct NodeConverter {
67 public:
68  static int to_int(TNodeType &node, const char *attribName) {
69  ai_assert(nullptr != attribName);
70  return node.attribute(attribName).to_int();
71  }
72 };
73 
74 using XmlNode = pugi::xml_node;
75 using XmlAttribute = pugi::xml_attribute;
76 
77 template <class TNodeType>
78 class TXmlParser {
79 public:
80  TXmlParser() :
81  mDoc(nullptr),
82  mData() {
83  // empty
84  }
85 
86  ~TXmlParser() {
87  clear();
88  }
89 
90  void clear() {
91  mData.resize(0);
92  delete mDoc;
93  mDoc = nullptr;
94  }
95 
96  TNodeType *findNode(const std::string &name) {
97  if (name.empty()) {
98  return nullptr;
99  }
100 
101  if (nullptr == mDoc) {
102  return nullptr;
103  }
104 
105  find_node_by_name_predicate predicate(name);
106  mCurrent = mDoc->find_node(predicate);
107  if (mCurrent.empty()) {
108  return nullptr;
109  }
110 
111  return &mCurrent;
112  }
113 
114  bool hasNode(const std::string &name) {
115  return nullptr != findNode(name);
116  }
117 
118  bool parse(IOStream *stream) {
119  if (nullptr == stream) {
120  ASSIMP_LOG_DEBUG("Stream is nullptr.");
121  return false;
122  }
123 
124  bool result = false;
125  const size_t len = stream->FileSize();
126  mData.resize(len + 1);
127  memset(&mData[0], '\0', len + 1);
128  stream->Read(&mData[0], 1, len);
129 
130  mDoc = new pugi::xml_document();
131  pugi::xml_parse_result parse_result = mDoc->load_string(&mData[0], pugi::parse_full);
132  if (parse_result.status == pugi::status_ok) {
133  ASSIMP_LOG_DEBUG("Error while parse xml.");
134  result = true;
135  }
136 
137  return result;
138  }
139 
140  pugi::xml_document *getDocument() const {
141  return mDoc;
142  }
143 
144  const TNodeType getRootNode() const {
145  return mDoc->root();
146  }
147 
148  TNodeType getRootNode() {
149  return mDoc->root();
150  }
151 
152  static inline bool hasNode(XmlNode &node, const char *name) {
153  pugi::xml_node child = node.find_child(find_node_by_name_predicate(name));
154  return !child.empty();
155  }
156 
157  static inline bool hasAttribute(XmlNode &xmlNode, const char *name) {
158  pugi::xml_attribute attr = xmlNode.attribute(name);
159  return !attr.empty();
160  }
161 
162  static inline bool getUIntAttribute(XmlNode &xmlNode, const char *name, unsigned int &val) {
163  pugi::xml_attribute attr = xmlNode.attribute(name);
164  if (attr.empty()) {
165  return false;
166  }
167 
168  val = attr.as_uint();
169  return true;
170  }
171 
172  static inline bool getIntAttribute(XmlNode &xmlNode, const char *name, int &val ) {
173  pugi::xml_attribute attr = xmlNode.attribute(name);
174  if (attr.empty()) {
175  return false;
176  }
177 
178  val = attr.as_int();
179  return true;
180  }
181 
182  static inline bool getFloatAttribute(XmlNode &xmlNode, const char *name, float &val ) {
183  pugi::xml_attribute attr = xmlNode.attribute(name);
184  if (attr.empty()) {
185  return false;
186  }
187 
188  val = attr.as_float();
189  return true;
190 
191  }
192 
193  static inline bool getDoubleAttribute( XmlNode &xmlNode, const char *name, double &val ) {
194  pugi::xml_attribute attr = xmlNode.attribute(name);
195  if (attr.empty()) {
196  return false;
197  }
198 
199  val = attr.as_double();
200  return true;
201  }
202 
203  static inline bool getStdStrAttribute(XmlNode &xmlNode, const char *name, std::string &val) {
204  pugi::xml_attribute attr = xmlNode.attribute(name);
205  if (attr.empty()) {
206  return false;
207  }
208 
209  val = attr.as_string();
210  return true;
211  }
212 
213  static inline bool getBoolAttribute( XmlNode &xmlNode, const char *name, bool &val ) {
214  pugi::xml_attribute attr = xmlNode.attribute(name);
215  if (attr.empty()) {
216  return false;
217  }
218 
219  val = attr.as_bool();
220  return true;
221 
222  }
223 
224  static inline bool getValueAsString( XmlNode &node, std::string &text ) {
225  text = "";
226  if (node.empty()) {
227  return false;
228  }
229 
230  text = node.text().as_string();
231 
232  return true;
233  }
234 
235  static inline bool getValueAsFloat( XmlNode &node, ai_real &v ) {
236  if (node.empty()) {
237  return false;
238  }
239 
240  v = node.text().as_float();
241 
242  return true;
243 
244  }
245 
246  private:
247  pugi::xml_document *mDoc;
248  TNodeType mCurrent;
249  std::vector<char> mData;
250 };
251 
253 
255 public:
256  XmlNodeIterator(XmlNode &parent) :
257  mParent(parent),
258  mNodes(),
259  mIndex(0) {
260  // empty
261  }
262 
263  void collectChildrenPreOrder( XmlNode &node ) {
264 
265  if (node != mParent && node.type() == pugi::node_element) {
266  mNodes.push_back(node);
267  }
268  for (XmlNode currentNode : node.children()) {
269  collectChildrenPreOrder(currentNode);
270  }
271  }
272 
273  void collectChildrenPostOrder(XmlNode &node) {
274  for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
275  collectChildrenPostOrder(currentNode);
276  }
277  if (node != mParent) {
278  mNodes.push_back(node);
279  }
280  }
281 
282  bool getNext(XmlNode &next) {
283  if (mIndex == mNodes.size()) {
284  return false;
285  }
286 
287  next = mNodes[mIndex];
288  ++mIndex;
289 
290  return true;
291  }
292 
293  size_t size() const {
294  return mNodes.size();
295  }
296 
297  bool isEmpty() const {
298  return mNodes.empty();
299  }
300 
301  void clear() {
302  if (mNodes.empty()) {
303  return;
304  }
305 
306  mNodes.clear();
307  mIndex = 0;
308  }
309 
310 private:
311  XmlNode &mParent;
312  std::vector<XmlNode> mNodes;
313  size_t mIndex;
314 };
315 
316 } // namespace Assimp
317 
318 #endif // !! INCLUDED_AI_IRRXML_WRAPPER
Assimp::IOStream::FileSize
virtual size_t FileSize() const =0
Returns filesize Returns the filesize.
Assimp::XmlNodeIterator
Definition: XmlParser.h:254
Assimp::TXmlParser
Definition: XmlParser.h:78
Assimp::find_node_by_name_predicate
Definition: XmlParser.h:53
Assimp::IOStream::Read
virtual size_t Read(void *pvBuffer, size_t pSize, size_t pCount)=0
Read from the file.
Assimp::NodeConverter
Definition: XmlParser.h:66
IOStream.hpp
File I/O wrappers for C++.
Assimp
Definition: ai_assert.h:50
Assimp::IOStream
CPP-API: Class to handle file I/O for C++.
Definition: IOStream.hpp:75
DefaultLogger.hpp