Fission FSN
Loading...
Searching...
No Matches
fsCXml.h
Go to the documentation of this file.
1/********************************************************************
2*
3* Created: 16/5/2012 16:59
4*
5* File: fsCXml.h
6*
7* Author: Mick Waites
8*
9* Purpose: Xml parsing. Sourced from IwGame.
10*
11*********************************************************************/
12
13#ifndef fsCXmlhdr
14#define fsCXmlhdr
15
16#include <cstring>
17
20
21#include "fsStr.h"
22#include "fsCXmlFileReader.h"
23
24#include <list>
25
26class fsCResourceName;
27
28struct fsXmlAttribute;
29struct fsXmlNode;
30
31//
32//
33//
34// Type definitions provided for ease of code reading
35//
36//
37//
38typedef std::list<fsXmlAttribute*> fsXmlAttributeList;
39typedef std::list<fsXmlNode*> fsXmlNodeList;
40typedef std::list<fsStr*> fsXmlStringList;
41typedef std::list<int> fsXmlIntList;
42typedef std::list<float> fsXmlFloatList;
43typedef std::list<bool> fsXmlBoolList;
44
45//
46//
47//
48// General tools used by all CIwGameXml classes
49//
50//
51//
53{
54public:
55 static int GetFirstWhitespaceIndex(char* pMem, int len);
56};
57
58//
59//
60//
61// An Xml attribute, e.g. <Something attribute="some value" />
62//
63//
64//
66{
67public:
68 bool Managed; // Managed attributes are managed by the pools system and should not be deleted
69 fsStr Name; // Attributes name
70 fsStr Value; // Attributes value
71
72public:
74 {
75 }
76
78 {
79 }
80
81 void Clear()
82 {
83 Name = "";
84 Value = "";
85 }
86
87 void setName(const char* pName)
88 {
89 Name.copy(pName, 0, std::strlen(pName));
90 }
91
92 void setName(char* pName, int len)
93 {
94 Name.copy(pName, 0, len);
95 }
96
97 fsStr& getName() { return Name; }
98
99 void setValue(const char* pValue)
100 {
101 Value.copy(pValue, 0, std::strlen(pValue));
102 Value.hTMLCodesReplace();
103 }
104
105 void setValue(char* pValue, int len)
106 {
107 Value.copy(pValue, 0, len);
108 Value.hTMLCodesReplace();
109 }
110
111 // Single attribute element getters
112 fsStr& GetValue() { return Value; }
113 int GetValueAsInt() const;
114 // float GetValueAsFloat() const;
115 // bool GetValueAsBool() const;
116 // bool GetValueAsPoint(fsPoint &point);
117 // bool GetValueAsPoint3(CIwFVec3 &point);
118 // bool GetValueAsPoint4(CIwFVec4 &point);
119 // bool GetValueAsColour(CIwColour &colour);
120 // bool GetValueAsRect(CIwRect &rect);
121
122 // List attribute element getters (generates a list from comma separated attribute data
124};
125
126//
127//
128//
129// An Xml node, e.g. <XmlNode></XmlNode>
130//
131//
132//
134{
135public:
136 typedef std::list<fsXmlNode*>::iterator _Iterator;
137 typedef std::list<fsXmlAttribute*>::iterator _AttribIterator;
138 _Iterator begin() { return Children.begin(); }
139 _Iterator end() { return Children.end(); }
142
143public:
144 bool Managed; // Managec nodes are managed by the pools system and should not be deleted
145 fsStr Name; // Node name
146 fsStr Value; // Node value
147 bool HasValue; // Determines if value is valid
148 fsXmlAttributeList Attributes; // List of attributes associated with this node
149 fsXmlNode* Parent; // Parent node
150 fsXmlNodeList Children; // List of children nodes
151
152public:
153 fsXmlNode() : Managed(true), HasValue(false), Parent(nullptr)
154 {
155 }
156
157 ~fsXmlNode();
158
159 void Clear()
160 {
161 Name = "";
162 Value = "";
163 Attributes.clear();
164 Parent = nullptr;
165 Children.clear();
166 HasValue = false;
167 }
168
169 void AddChild(fsXmlNode* node)
170 {
171 node->Parent = this;
172 Children.push_back(node);
173 }
174
175 void AddAttribute(fsXmlAttribute* attribute);
176 void AddAttribute(fsStr& name, fsStr& value);
177 void AddAttribute(fsStr& name, const char* value);
178 void UpdateAttribute(fsStr& name, const char* value);
179
180 void SetName(const char* name)
181 {
182 Name.copy((char*)name, 0, std::strlen(name));
183 }
184
185 void SetName(const char* name, int len)
186 {
187 Name.copy((char*)name, 0, len);
188 }
189
190 void SetValue(const char* value)
191 {
192 Value.copy((char*)value, 0, std::strlen(value));
193 Value.hTMLCodesReplace();
194 HasValue = true;
195 }
196
197 void SetValue(const char* value, int len)
198 {
199 Value.copy((char*)value, 0, len);
200 Value.hTMLCodesReplace();
201 HasValue = true;
202 }
203
204 const fsStr& GetName() const { return Name; }
205
206 // Single value getters (data between tags)
207 const fsStr& GetValue() const { return Value; }
208 int GetValueAsInt() const;
209 // float GetValueAsFloat() const;
210 // bool GetValueAsBool() const;
211
212 // Print attributes / tree (DEBUG)
213 void PrintAttributes();
214 void PrintTree(int level = 0);
215
216 // Get first child node
218 // Get first occurrence of a node in this node and all children
219 fsXmlNode* GetFirstNamedNode(const char* pNodeName, unsigned int pNameHash);
220 // Get all occurrences of a node in this node and all children
221 void GetNamedNodes(const char* pNodeName, unsigned int pNameHash, fsXmlNodeList* pNodes);
222
223 // Gets attribute count
224 int GetAttributeCount() const { return Attributes.size(); }
225 // Gets the named attribute
226 fsXmlAttribute* GetAttribute(const char* name);
227 // Gets the Nth attribute
228 fsXmlAttribute* GetAttribute(int index);
229
230 // Save XML file
231 // int SaveAttributes(std::shared_ptr<fsIFile> file);
232 // int SaveTree(std::shared_ptr<fsIFile> file, int level = 0);
233 // int Save(const char* filename);
234
235 // Tag / attribute case chnage (does not change the case of attribute values)
236 void ToLower(bool recursive);
237 void ToUpper(bool recursive);
238
239 // Tree cloning
240 void Copy(fsXmlNode* copy);
241 fsXmlNode* Clone(fsXmlNode* parent);
242 fsXmlNode* CloneTree(fsXmlNode* parent);
243};
244
261
263{
264 int Start;
266
267 void Clear()
268 {
269 Start = 0;
270 Length = 0;
271 }
272};
273
274//
275//
276//
277// The Xml parser
278//
279//
280//
282{
283public:
284
285private:
286 fsStr m_Encoding; // Encoding type
287 fsStr m_Version; // XML version
288 fsCXmlFileReader* m_pDataInput; // Input stream
289 fsXmlNode* m_pRoot; // Root node
290 fsXmlTagMarker* Marker;
291 int MarkerCount;
292
293 std::list<fsXmlNode*>::iterator RemoveNodeFromList(std::list<fsXmlNode*>& list,
294 const std::list<fsXmlNode*>::iterator& it);
295public:
296 fsXmlParser() : m_pDataInput(nullptr), m_pRoot(nullptr), Marker(nullptr), MarkerCount(0)
297 {
298 }
299
300 virtual ~fsXmlParser()
301 {
302 if (m_pDataInput != nullptr)
303 delete m_pDataInput;
304 }
305
306 void SetEncoding(const char* encoding) { m_Encoding = encoding; }
307 const fsStr& GetEncoding() const { return m_Encoding; }
308 void SetVersion(const char* version) { m_Version = version; }
309 const fsStr& GetVersion() const { return m_Version; }
310
312 {
313 if (NodePool == nullptr)
314 return new fsXmlNode();
316 {
317 fsAssert(false, "Error: Ran out of nodes, allocate more");
318 return nullptr;
319 }
321 node->Clear();
322
323 return node;
324 }
325
327 {
328 if (TagPool == nullptr)
329 return new fsXmlTagMarker();
331 {
332 fsAssert(false, "Error: Ran out of tag markers, allocate more");
333 return nullptr;
334 }
336 tag->Clear();
337
338 return tag;
339 }
340
342 {
343 if (AttributePool == nullptr)
344 return new fsXmlAttribute();
346 {
347 fsAssert(false, "Error: Ran out of attributes, allocate more");
348 return nullptr;
349 }
351 attribute->Clear();
352
353 return attribute;
354 }
355
356 // Parse the supplied file
357 eVpXmlParserError Parse(const fsCResourceName& pFilename);
358
359 // Parse the supplied memory buffer
360 eVpXmlParserError Parse(fsCXmlFileReader* pData); // This class becomes owner of CDataInput object
361
362 // Return XML error string
363 const char* GetErrorString(eVpXmlParserError error) const;
364
365 // Get root node (note that root node is '.' and not the first XML tag)
367 {
368 return m_pRoot;
369 }
370
371 // Get first occurrence of a node in this node and all children
372 fsXmlNode* GetFirstNamedNode(fsXmlNode* parent, const char* node_name)
373 {
374 if (parent == nullptr)
375 parent = GetRoot();
376
377 int hash = fsCUniqueId::idCalculate(node_name);
378 if (parent != nullptr)
379 return parent->GetFirstNamedNode(node_name, hash);
380 if (m_pRoot != nullptr)
381 return m_pRoot->GetFirstNamedNode(node_name, hash);
382
383 return nullptr;
384 }
385
386 // Get all occurrences of a node in this node and all children (caller is responsible for cleaning up list)
387 // Pass NULL as pNodeName to return all nodes
388 fsXmlNodeList* GetNamedNodes(fsXmlNode* parent, const char* node_name)
389 {
390 if (parent == nullptr)
391 parent = GetRoot();
392
393 int hash = fsCUniqueId::idCalculate(node_name);
394 fsXmlNodeList* pNodes = new fsXmlNodeList;
395 if (parent != nullptr)
396 parent->GetNamedNodes(node_name, hash, pNodes);
397 else if (m_pRoot != nullptr)
398 m_pRoot->GetNamedNodes(node_name, hash, pNodes);
399
400 return pNodes;
401 }
402
403private:
404 eVpXmlParserError ParseXMLHeader();
405 eVpXmlParserError ParseAttributes(const char* data, int count, fsXmlNode* node);
406 bool PreParse();
408
409 eVpXmlParserError ParseAttributes(fsXmlNode* node);
410 eVpXmlParserError Parse(fsXmlNode* pParent, int range, int& num_tags_found);
411 const char* GetCloseTagName(fsXmlNode* node) const;
412 void ShowError(eVpXmlParserError error, int pos) const;
413
414 int GetNextWord(const char* data, int& offset);
415 int GetNextQuotedWord(const char* data, int& offset);
416
417 // Tag and node pooling
418public:
419 static fsXmlTagMarker* TagPool; // Used to separate tags from the raw XML file
421 static int MaxPoolTags;
422 static fsXmlNode* NodePool; // Xml nodes pool
423 static int NextFreePoolNodeIndex; // Bext free node index in nodes pool
424 static int MaxPoolNodes; // Maximum available nodes in the nodes pool
425 static fsXmlAttribute* AttributePool; // Xml attribute pool
426 static int NextFreePoolAttributeIndex; // Bext free attribute index in nodes pool
427 static int MaxPoolAttributes; // Maximum available attributes in the attributes pool
428public:
429 static void PoolsInit(int node_pool_size = 2048, int tag_pool_size = 2048, int attribute_pool_size = 4096)
430 {
431 NodePool = new fsXmlNode[node_pool_size]();
432 MaxPoolNodes = node_pool_size;
434 TagPool = new fsXmlTagMarker[tag_pool_size]();
435 MaxPoolTags = tag_pool_size;
437 AttributePool = new fsXmlAttribute[attribute_pool_size]();
438 MaxPoolAttributes = attribute_pool_size;
440 mPoolsSize = node_pool_size;
441 }
442
443 static void PoolsDestroy()
444 {
445 if (TagPool != nullptr)
446 {
447 delete []TagPool;
448 TagPool = nullptr;
449 }
450 if (NodePool != nullptr)
451 {
452 delete []NodePool;
453 NodePool = nullptr;
454 }
455 if (AttributePool != nullptr)
456 {
457 delete []AttributePool;
458 AttributePool = nullptr;
459 }
460 }
461
462 static void PoolsReset()
463 {
467 }
468
470 {
471 return mPoolsSize;
472 }
473
475};
476
477#endif
Definition fsCResourceName.h:32
static fsU32 idCalculate(const fsStr &pString)
Definition fsCUniqueId.cpp:9
Definition fsCXmlFileReader.h:33
Definition fsStr.h:23
static void PoolsInit(int node_pool_size=2048, int tag_pool_size=2048, int attribute_pool_size=4096)
Definition fsCXml.h:429
static int NextFreePoolTagIndex
Definition fsCXml.h:420
static int NextFreePoolAttributeIndex
Definition fsCXml.h:426
static fsXmlNode * NodePool
Definition fsCXml.h:422
static int MaxPoolNodes
Definition fsCXml.h:424
static fsXmlTagMarker * TagPool
Definition fsCXml.h:419
const char * GetErrorString(eVpXmlParserError error) const
Definition fsCXml.cpp:627
fsXmlNode * GetFirstNamedNode(fsXmlNode *parent, const char *node_name)
Definition fsCXml.h:372
static fsXmlTagMarker * AllocTag()
Definition fsCXml.h:326
static fsS32 PoolsSizeGet()
Definition fsCXml.h:469
const fsStr & GetVersion() const
Definition fsCXml.h:309
void SetVersion(const char *version)
Definition fsCXml.h:308
static fsS32 mPoolsSize
Definition fsCXml.h:474
eVpXmlParserError Parse(const fsCResourceName &pFilename)
Definition fsCXml.cpp:713
void SetEncoding(const char *encoding)
Definition fsCXml.h:306
const fsStr & GetEncoding() const
Definition fsCXml.h:307
fsXmlParser()
Definition fsCXml.h:296
static int MaxPoolTags
Definition fsCXml.h:421
static fsXmlAttribute * AttributePool
Definition fsCXml.h:425
fsXmlNode * GetRoot()
Definition fsCXml.h:366
static void PoolsDestroy()
Definition fsCXml.h:443
static void PoolsReset()
Definition fsCXml.h:462
static fsXmlNode * AllocNode()
Definition fsCXml.h:311
static int MaxPoolAttributes
Definition fsCXml.h:427
virtual ~fsXmlParser()
Definition fsCXml.h:300
fsXmlNodeList * GetNamedNodes(fsXmlNode *parent, const char *node_name)
Definition fsCXml.h:388
static int NextFreePoolNodeIndex
Definition fsCXml.h:423
static fsXmlAttribute * AllocAttribute()
Definition fsCXml.h:341
Definition fsCXml.h:53
static int GetFirstWhitespaceIndex(char *pMem, int len)
Definition fsCXml.cpp:1087
#define fsAssert(pStatement, pFmtString,...)
Definition fsAssert.h:23
std::list< fsXmlNode * > fsXmlNodeList
Definition fsCXml.h:39
eVpXmlParserError
Definition fsCXml.h:246
@ eVpXmlParserError_NoTagFound
Definition fsCXml.h:248
@ eVpXmlParserError_None
Definition fsCXml.h:247
@ eVpXmlParserError_InvalidPools
Definition fsCXml.h:259
@ eVpXmlParserError_MissingValue
Definition fsCXml.h:254
@ eVpXmlParserError_FileError
Definition fsCXml.h:249
@ eVpXmlParserError_MissingEndTag
Definition fsCXml.h:250
@ eVpXmlParserError_InvalidComment
Definition fsCXml.h:257
@ eVpXmlParserError_MissingClosingQuote
Definition fsCXml.h:255
@ eVpXmlParserError_MissingEquals
Definition fsCXml.h:253
@ eVpXmlParserError_InvalidTag
Definition fsCXml.h:256
@ eVpXmlParserError_MismatchedEndTag
Definition fsCXml.h:252
@ eVpXmlParserError_MissingEndComment
Definition fsCXml.h:251
@ eVpXmlParserError_PreParseError
Definition fsCXml.h:258
std::list< float > fsXmlFloatList
Definition fsCXml.h:42
std::list< int > fsXmlIntList
Definition fsCXml.h:41
std::list< fsStr * > fsXmlStringList
Definition fsCXml.h:40
std::list< fsXmlAttribute * > fsXmlAttributeList
Definition fsCXml.h:38
std::list< bool > fsXmlBoolList
Definition fsCXml.h:43
int fsS32
Definition fsBaseTypes.h:20
Definition fsCXml.h:66
~fsXmlAttribute()
Definition fsCXml.h:77
fsStr Name
Definition fsCXml.h:69
void Clear()
Definition fsCXml.h:81
bool Managed
Definition fsCXml.h:68
fsXmlStringList * GetValueAsList()
Definition fsCXml.cpp:137
void setName(const char *pName)
Definition fsCXml.h:87
fsStr & getName()
Definition fsCXml.h:97
fsStr Value
Definition fsCXml.h:70
void setName(char *pName, int len)
Definition fsCXml.h:92
fsXmlAttribute()
Definition fsCXml.h:73
fsStr & GetValue()
Definition fsCXml.h:112
void setValue(const char *pValue)
Definition fsCXml.h:99
void setValue(char *pValue, int len)
Definition fsCXml.h:105
int GetValueAsInt() const
Definition fsCXml.cpp:54
Definition fsCXml.h:134
bool HasValue
Definition fsCXml.h:147
void Copy(fsXmlNode *copy)
Definition fsCXml.cpp:445
void Clear()
Definition fsCXml.h:159
void GetNamedNodes(const char *pNodeName, unsigned int pNameHash, fsXmlNodeList *pNodes)
Definition fsCXml.cpp:568
void UpdateAttribute(fsStr &name, const char *value)
Definition fsCXml.cpp:246
fsXmlNodeList Children
Definition fsCXml.h:150
bool Managed
Definition fsCXml.h:144
void AddAttribute(fsXmlAttribute *attribute)
Definition fsCXml.cpp:207
_AttribIterator attribs_end()
Definition fsCXml.h:141
void PrintTree(int level=0)
Definition fsCXml.cpp:294
const fsStr & GetValue() const
Definition fsCXml.h:207
fsXmlNode * Parent
Definition fsCXml.h:149
std::list< fsXmlNode * >::iterator _Iterator
Definition fsCXml.h:136
fsStr Value
Definition fsCXml.h:146
_Iterator begin()
Definition fsCXml.h:138
void SetName(const char *name, int len)
Definition fsCXml.h:185
void ToLower(bool recursive)
Definition fsCXml.cpp:330
int GetValueAsInt() const
Definition fsCXml.cpp:266
int GetAttributeCount() const
Definition fsCXml.h:224
void AddChild(fsXmlNode *node)
Definition fsCXml.h:169
fsXmlNode * Clone(fsXmlNode *parent)
Definition fsCXml.cpp:480
~fsXmlNode()
Definition fsCXml.cpp:188
fsXmlNode()
Definition fsCXml.h:153
void SetName(const char *name)
Definition fsCXml.h:180
fsXmlNode * GetFirstNamedNode(const char *pNodeName, unsigned int pNameHash)
Definition fsCXml.cpp:550
fsStr Name
Definition fsCXml.h:145
const fsStr & GetName() const
Definition fsCXml.h:204
fsXmlAttribute * GetAttribute(const char *name)
Definition fsCXml.cpp:591
fsXmlNode * CloneTree(fsXmlNode *parent)
Definition fsCXml.cpp:503
void SetValue(const char *value, int len)
Definition fsCXml.h:197
_Iterator end()
Definition fsCXml.h:139
fsXmlNode * GetFirstNode()
Definition fsCXml.cpp:542
fsXmlAttributeList Attributes
Definition fsCXml.h:148
void PrintAttributes()
Definition fsCXml.cpp:282
void SetValue(const char *value)
Definition fsCXml.h:190
_AttribIterator attribs_begin()
Definition fsCXml.h:140
std::list< fsXmlAttribute * >::iterator _AttribIterator
Definition fsCXml.h:137
void ToUpper(bool recursive)
Definition fsCXml.cpp:346
Definition fsCXml.h:263
int Length
Definition fsCXml.h:265
int Start
Definition fsCXml.h:264
void Clear()
Definition fsCXml.h:267