ScummVM API documentation
xmlparser.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef XML_PARSER_H
23 #define XML_PARSER_H
24 
25 #include "common/scummsys.h"
26 #include "common/types.h"
27 
28 #include "common/fs.h"
29 #include "common/list.h"
30 #include "common/hashmap.h"
31 #include "common/hash-str.h"
32 #include "common/stack.h"
33 #include "common/memorypool.h"
34 
35 
36 namespace Common {
37 
47 class SeekableReadStream;
48 
49 #define MAX_XML_DEPTH 8
50 
51 #define XML_KEY(keyName) {\
52  lay = new CustomXMLKeyLayout;\
53  lay->callback = (&kLocalParserName::parserCallback_##keyName);\
54  layout.top()->children[#keyName] = lay;\
55  layout.push(lay); \
56  _layoutList.push_back(lay);
57 
58 #define XML_KEY_RECURSIVE(keyName) {\
59  layout.top()->children[#keyName] = layout.top();\
60  layout.push(layout.top());\
61  }
62 
63 #define KEY_END() layout.pop(); }
64 
65 #define XML_PROP(propName, req) {\
66  prop.name = #propName; \
67  prop.required = req; \
68  layout.top()->properties.push_back(prop); }
69 
70 
71 
72 #define CUSTOM_XML_PARSER(parserName) \
73  protected: \
74  typedef parserName kLocalParserName; \
75  bool keyCallback(ParserNode *node) override {return node->layout->doCallback(this, node); }\
76  struct CustomXMLKeyLayout : public XMLKeyLayout {\
77  typedef bool (parserName::*ParserCallback)(ParserNode *node);\
78  ParserCallback callback;\
79  bool doCallback(XMLParser *parent, ParserNode *node) {return ((kLocalParserName *)parent->*callback)(node);} };\
80  void buildLayout() override { \
81  Common::Stack<XMLKeyLayout *> layout; \
82  CustomXMLKeyLayout *lay = 0; \
83  XMLKeyLayout::XMLKeyProperty prop; \
84  _XMLkeys = new CustomXMLKeyLayout; \
85  layout.push(_XMLkeys);
86 
87 #define PARSER_END() layout.clear(); }
88 
98 class XMLParser {
99 public:
103  XMLParser() : _XMLkeys(nullptr), _stream(nullptr), _allowText(false), _char(0) {}
104 
105  virtual ~XMLParser();
106 
108  enum ParserState {
109  kParserNeedHeader,
110  kParserNeedKey,
111  kParserNeedKeyName,
112 
113  kParserNeedPropertyName,
114  kParserNeedPropertyOperator,
115  kParserNeedPropertyValue,
116 
117  kParserError
118  };
119 
120  struct XMLKeyLayout;
121  struct ParserNode;
122 
124 
126  struct XMLKeyLayout {
127  struct XMLKeyProperty {
128  String name;
129  bool required;
130  };
131 
132  List<XMLKeyProperty> properties;
133  ChildMap children;
134 
135  virtual bool doCallback(XMLParser *parent, ParserNode *node) = 0;
136 
137  virtual ~XMLKeyLayout() {
138  properties.clear();
139  }
140  };
141 
142  XMLKeyLayout *_XMLkeys;
143 
145  struct ParserNode {
146  String name;
147  StringMap values;
148  bool ignore;
149  bool header;
150  int depth;
151  XMLKeyLayout *layout;
152  };
153 
155 
156  ParserNode *allocNode() {
157  return new (_nodePool) ParserNode;
158  }
159 
160  void freeNode(ParserNode *node) {
161  _nodePool.deleteChunk(node);
162  }
163 
171  bool loadFile(const Path &filename);
172 
173  bool loadFile(const FSNode &node);
174 
186  bool loadBuffer(const byte *buffer, uint32 size, DisposeAfterUse::Flag disposable = DisposeAfterUse::NO);
187 
188  bool loadStream(SeekableReadStream *stream);
189 
190  void close();
191 
196  bool parse();
197 
203  if (!_activeKey.empty())
204  return _activeKey.top();
205 
206  return nullptr;
207  }
208 
213  return child->depth > 0 ? _activeKey[child->depth - 1] : 0;
214  }
215 
223  void setAllowText() {
224  _allowText = true;
225  }
226 
227 protected:
228 
236  virtual void buildLayout() = 0;
237 
256  virtual bool keyCallback(ParserNode *node) = 0;
257 
271  virtual bool closedKeyCallback(ParserNode *node) {
272  return true;
273  }
274 
280  virtual bool textCallback(const String &val) {
281  return true;
282  }
283 
288  bool closeKey();
289 
293  bool parseKeyValue(String keyName);
294 
299  bool parseActiveKey(bool closed);
300 
306  bool parserError(const String &errStr);
307 
312  bool skipSpaces();
313 
318  bool skipComments();
319 
325  virtual inline bool isValidNameChar(char c) {
326  return isAlnum(c) || c == '_';
327  }
328 
332  bool parseToken();
333 
352  bool parseIntegerKey(const char *key, int count, ...);
353  bool parseIntegerKey(const String &keyStr, int count, ...);
354  bool vparseIntegerKey(const char *key, int count, va_list args);
355 
356  bool parseXMLHeader(ParserNode *node);
357 
363  virtual void cleanup() {}
364 
372  virtual bool handleUnknownKey(ParserNode *node) { return false; }
373 
374  List<XMLKeyLayout *> _layoutList;
375 
376 private:
377  char _char;
378  bool _allowText;
379  SeekableReadStream *_stream;
380  Path _fileName;
381 
382  ParserState _state;
384  String _error;
385  String _token;
387  Stack<ParserNode *> _activeKey;
388 };
389 
392 } // End of namespace Common
393 
394 #endif
bool parseActiveKey(bool closed)
Definition: xmlparser.h:126
Definition: str.h:59
bool loadFile(const Path &filename)
virtual bool closedKeyCallback(ParserNode *node)
Definition: xmlparser.h:271
virtual bool handleUnknownKey(ParserNode *node)
Definition: xmlparser.h:372
void setAllowText()
Definition: xmlparser.h:223
Definition: list.h:44
ParserNode * getActiveNode()
Definition: xmlparser.h:202
Definition: path.h:52
Definition: stream.h:745
Definition: xmlparser.h:145
bool parserError(const String &errStr)
bool loadBuffer(const byte *buffer, uint32 size, DisposeAfterUse::Flag disposable=DisposeAfterUse::NO)
virtual bool keyCallback(ParserNode *node)=0
Definition: xmlparser.h:98
void deleteChunk(T *ptr)
Definition: memorypool.h:145
Definition: algorithm.h:29
Definition: fs.h:69
Definition: memorypool.h:139
void clear()
Definition: list.h:206
virtual void buildLayout()=0
XMLParser()
Definition: xmlparser.h:103
ParserState
Definition: xmlparser.h:108
virtual bool isValidNameChar(char c)
Definition: xmlparser.h:325
ParserNode * getParentNode(ParserNode *child)
Definition: xmlparser.h:212
virtual bool textCallback(const String &val)
Definition: xmlparser.h:280
Definition: stack.h:102
bool isAlnum(int c)
virtual void cleanup()
Definition: xmlparser.h:363
bool parseKeyValue(String keyName)
bool parseIntegerKey(const char *key, int count,...)