AppEasy Core SDK
1.5.0
Cross platform mobile and desktop app and game development SDK - The easy way to make apps
|
00001 // 00002 // 00003 // AppEasy SDK - Cross Platform Multi-purpose Game and App Engine 00004 // 00005 // Developed by Matthew Hopwood of Pocketeers Limited - www.pocketeers.co.uk 00006 // 00007 // For updates, tutorials and more details check out www.appeasymobile.com 00008 // 00009 // This code is provided free of charge and without any warranty whatsoever. You must ensure that this whole notice is present in all files and derivatives, so the reader knows its origin. 00010 // If you use this SDK in your product then please ensure that you credit AppEasy's usage appropriately. Please see www.appeasymobile.com for licensing details and support 00011 // 00012 // 00013 00014 // Warnings 00015 // * Before parsing ensure that the XKL data pools have been set up by calling CzXmlParser::PoolsInit() 00016 // * CzXmlParser::PoolsReset() to reset pool data and prevent running out of pool memory (do not call whilst parsing an XML file) 00017 00018 00019 #if !defined(_CZ_XML_H_) 00020 #define _CZ_XML_H_ 00021 00022 00023 #include "CzUtil.h" 00024 #include "CzDataIO.h" 00025 00026 class CzXmlParser; 00027 class CzFile; 00028 struct CzXmlAttribute; 00029 struct CzXmlNode; 00030 00031 #define CZ_INT_LIST_POOL_SIZE 256 00032 #define CZ_FLOAT_LIST_POOL_SIZE 8192 00033 #define CZ_BOOL_LIST_POOL_SIZE 256 00034 00035 /** 00036 @addtogroup Core 00037 @{ 00038 */ 00039 00040 // 00041 // 00042 // 00043 // Type definitions provided for ease of code reading 00044 // 00045 // 00046 // 00047 00048 /** 00049 @typedef CzList<CzXmlAttribute*> CzXmlAttributeList 00050 00051 @brief A list of CzXmlAttribute's 00052 */ 00053 typedef CzList<CzXmlAttribute*> CzXmlAttributeList; 00054 00055 /** 00056 @typedef CzList<CzXmlNode*> CzXmlNodeList 00057 00058 @brief A list of CzXmlNode's 00059 */ 00060 typedef CzList<CzXmlNode*> CzXmlNodeList; 00061 00062 /** 00063 @class CzXmlTools 00064 00065 @brief General tools used by all CzXml classes. 00066 00067 */ 00068 class CzXmlTools 00069 { 00070 public: 00071 static int GetFirstWhitespaceIndex(char* pMem, int len); //< Returns index of the first white space 00072 static int IntListPool[CZ_INT_LIST_POOL_SIZE]; //< Int pool used by XML system 00073 static float FloatListPool[CZ_FLOAT_LIST_POOL_SIZE]; //< Float pool used by XML system 00074 static bool BoolListPool[CZ_BOOL_LIST_POOL_SIZE]; //< Bool pool used by XML system 00075 }; 00076 00077 /** 00078 @struct CzXmlAttribute 00079 00080 @brief An Xml attribute, e.g. <Something attribute="some value" /> 00081 00082 */ 00083 00084 struct CzXmlAttribute 00085 { 00086 public: 00087 bool Managed; ///< Managec attributes are managed by the pools system and should not be deleted 00088 CzString Name; ///< Attributes name 00089 CzString Value; ///< Attributes value 00090 00091 public: 00092 CzXmlAttribute() : Managed(false) {} 00093 virtual ~CzXmlAttribute() {} 00094 00095 void Clear() ///< Clears the attributes name and value 00096 { 00097 Name = ""; 00098 Value = ""; 00099 // Name.reset(); 00100 // Value.reset(); 00101 } 00102 00103 void setName(const char* pName) ///< Sets the name of the attribute 00104 { 00105 Name.Copy(pName, 0, strlen(pName)); 00106 } 00107 void setName(char* pName, int len) ///< Sets the name of the attribute 00108 { 00109 Name.Copy(pName, 0, len); 00110 } 00111 CzString& getName() { return Name; } ///< Gets the name of the attribute 00112 void setValue(const char* pValue) ///< Sets the value of the attribute 00113 { 00114 Value.Copy(pValue, 0, strlen(pValue)); 00115 Value.ReplaceHTMLCodes(); 00116 } 00117 void setValue(char* pValue, int len) ///< Sets the value of the attribute 00118 { 00119 Value.Copy(pValue, 0, len); 00120 Value.ReplaceHTMLCodes(); 00121 } 00122 00123 // Single attribute element getters 00124 CzString& getValue() { return Value; } ///< Gets the value of the attribute 00125 int getValueAsInt() const; ///< Gets the value of the attribute as an integer 00126 float getValueAsFloat() const; ///< Gets the value of the attribute as a floating point number 00127 bool getValueAsBool() const; ///< Gets the value of the attribute as a boolean 00128 bool getValueAsPoint(CzVec2 &point); ///< Gets the value of the attribute as a vec2 00129 bool getValueAsPoint3(CzVec3 &point, float default_y = 0, float default_z = 0); ///< Gets the value of the attribute as a vec3 (if less than 3 values are found then rest will be assigned 0) 00130 bool getValueAsPoint3Copy(CzVec3 &point); ///< Gets the value of the attribute as a vec3 (if less than 3 values are found then rest will be assigned the first value) 00131 bool getValueAsPoint4(CzVec4 &point); ///< Gets the value of the attribute as a vec4 00132 bool getValueAsColour(CzColour &colour); ///< Gets the value of the attribute as a colour 00133 bool getValueAsRect(CzIRect &rect); ///< Gets the value of the attribute as a rect 00134 00135 // List attribute element getters (generates a list from comma separated attribute data 00136 CzStringList* getValueAsList(); ///< Gets the value of the attribute as a list of strings 00137 }; 00138 00139 /** 00140 @struct CzXmlNode 00141 00142 @brief An Xml node, e.g. <XmlNode></XmlNode> 00143 00144 */ 00145 00146 struct CzXmlNode 00147 { 00148 public: 00149 typedef CzXmlNodeList::iterator _Iterator; 00150 typedef CzXmlAttributeList::iterator _AttribIterator; 00151 _Iterator begin() { return Children.begin(); } 00152 _Iterator end() { return Children.end(); } 00153 _AttribIterator attribs_begin() { return Attributes.begin(); } 00154 _AttribIterator attribs_end() { return Attributes.end(); } 00155 00156 public: 00157 bool Managed; ///< Managec nodes are managed by the pools system and should not be deleted 00158 bool HasValue; ///< Determines if value is valid 00159 uint16 Line; ///< File line 00160 CzString Name; ///< Node name 00161 CzString Value; ///< Node value 00162 CzXmlAttributeList Attributes; ///< List of attributes associated with this node 00163 CzXmlNode* Parent; ///< Parent node 00164 CzXmlNodeList Children; ///< List of children nodes 00165 CzXmlParser* Parser; ///< Parser that created this node 00166 00167 public: 00168 CzXmlNode() : Parent(NULL), HasValue(false), Managed(false), Parser(NULL), Line(0) {} 00169 virtual ~CzXmlNode(); 00170 void Clear() ///< Clears the node 00171 { 00172 Name = ""; 00173 Value = ""; 00174 Attributes.clear(); 00175 Parent = NULL; 00176 Children.clear(); 00177 HasValue = false; 00178 } 00179 00180 void AddChild(CzXmlNode* node) ///< Adds a child node to the tree 00181 { 00182 node->Parent = this; 00183 Children.push_back(node); 00184 } 00185 00186 void RemoveChild(CzXmlNode* node) ///< Remove a child node from the tree (does not destroy it) 00187 { 00188 Children.remove(node); 00189 } 00190 00191 void AddAttribute(CzXmlAttribute *attribute); ///< Adds an attribute to this node 00192 void AddAttribute(const CzString& name, const CzString& value, CzXmlParser* parser); ///< Adds an attribute to this node 00193 void AddAttribute(const CzString& name, const char* value, CzXmlParser* parser); ///< Adds an attribute to this node 00194 void UpdateAttribute(const CzString& name, const char* value, CzXmlParser* parser); ///< Updates an existing named attribute in this node 00195 00196 void SetName(const char* name) ///< Sets the nodes name 00197 { 00198 Name.Copy((char*)name, 0, strlen(name)); 00199 } 00200 void SetName(const char* name, int len) ///< Sets the nodes name 00201 { 00202 Name.Copy((char*)name, 0, len); 00203 } 00204 void SetValue(const char* value) ///< Sets the nodes value 00205 { 00206 Value.Copy((char*)value, 0, strlen(value)); 00207 Value.ReplaceHTMLCodes(); 00208 HasValue = true; 00209 } 00210 void SetValue(const char* value, int len) ///< Sets the nodes value 00211 { 00212 Value.Copy((char*)value, 0, len); 00213 Value.ReplaceHTMLCodes(); 00214 HasValue = true; 00215 } 00216 const CzString& GetName() const { return Name; } ///< Gets the nodes name 00217 00218 // Single value getters (data between tags) 00219 const CzString& getValue() const { return Value; } ///< Gets the nodes value 00220 int getValueAsInt() const; ///< Gets the nodes value as an integer 00221 float getValueAsFloat() const; ///< Gets the nodes value as a floating point number 00222 bool getValueAsBool() const; ///< Gets the nodes value as a boolean 00223 00224 CzXmlParser* getParser() { return Parser; } ///< Returns the parser that created this node 00225 void setParser(CzXmlParser* parser) { Parser = parser; } ///< Sets the parser that created this node 00226 00227 // Print attributes / tree (DEBUG) 00228 void PrintAttributes(CzString& out); ///< Print node attributes to a string 00229 void PrintTree(CzString& out, int level = 0); ///< Print entire tree to a string 00230 00231 CzXmlNode* getFirstNode(); ///< Get first child node 00232 CzXmlNode* getFirstNamedNode(unsigned int name_hash); ///< Get first occurrence of a node in this node and all children 00233 void getNamedNodes(unsigned int name_hash, CzXmlNodeList* nodes); ///< Get all occurrences of a node in this node and all children 00234 00235 // Gets attribute count 00236 int getAttributeCount() const { return Attributes.size(); } ///< Returns number of attributes that the node contains 00237 // Gets the named attribute 00238 CzXmlAttribute* getAttribute(const char* name); ///< Returns named attribute 00239 CzXmlAttribute* getAttribute(unsigned int hash); ///< Returns named attribute 00240 // Gets the Nth attribute 00241 CzXmlAttribute* getAttributeAtInex(int index); ///< Returns attribute at the specified index 00242 00243 // Save XML file 00244 int SaveAttributes(CzFile* file); ///< Saves the attributes to a file 00245 int SaveTree(CzFile* file, int level = 0); ///< Saves entire node tree to a file 00246 int Save(const char* filename); ///< Saves entire node tree to a file with the specified filename 00247 const char* getParserFileName() const; ///< Returns the name of the file that is being parsed 00248 00249 // Tag / attribute case chnage (does not change the case of attribute values) 00250 void ToLower(bool recursive); ///< Changes tags and attributes names to lower case, does not affect values 00251 void ToUpper(bool recursive); ///< Changes tags and attributes names to upper case, does not affect values 00252 00253 // Tree cloning 00254 CzXmlNode* Clone(CzXmlNode* parent); ///< Clones this node 00255 CzXmlNode* CloneTree(CzXmlNode* parent); ///< Clones the entire tree 00256 00257 }; 00258 00259 /** 00260 @enum eCzXmlParseError 00261 00262 @brief XML parser errors. 00263 */ 00264 00265 enum eCzXmlParseError 00266 { 00267 XmlErrorNone, 00268 XmlErrorNoTagFound, 00269 XmlErrorFileError, 00270 XmlErrorMissingEndTag, 00271 XmlErrorMissingEndComment, 00272 XmlErrorMismatchedEndTag, 00273 XmlErrorMissingEquals, 00274 XmlErrorMissingValue, 00275 XmlErrorMissingClosingQuote, 00276 XmlErrorInvalidTag, 00277 XmlErrorInvalidComment, 00278 XmlErrorPreParseError, 00279 XmlErrorInvalidPools, 00280 }; 00281 00282 /** 00283 @struct CzXmlTagMarker 00284 00285 @brief XML tag marker. 00286 00287 Tag markers are used to speed up XML parsing 00288 00289 */ 00290 00291 struct CzXmlTagMarker 00292 { 00293 int Start; 00294 int Length; 00295 int Line; 00296 00297 void Clear() 00298 { 00299 Start = 0; 00300 Length = 0; 00301 Line = 0; 00302 } 00303 }; 00304 00305 /** 00306 @class CzXmlParser 00307 00308 @brief The Xml parser. 00309 00310 <h1>Introduction</h1> 00311 00312 AppEasy comes with a basic XML parser that has the following features: 00313 - Load and save XML files 00314 - Very small code footprint 00315 - Very quick parser 00316 - Uses memory pooling for tags, attributes and values, reducing memory fragmentation 00317 - Error output, including line numbers 00318 00319 CzXmlParser does however have limitations such as no support for XML schemas and will allow you to do some things that normal XML parsers will not allow you to do. 00320 00321 The XML engine is split into the following classes: 00322 - CzXmlAttribute - A nodes named attributes and values 00323 - CzXmlNode - A named node containing a collection of attributes 00324 - CzXmlParser - The main parser object that loads and parsers the XML file 00325 00326 <h1>Loading an XML file</h1> 00327 00328 To load an XML file, create an instance of CzXmlParser and call Parse() to parse the data, like shown below: 00329 00330 @code 00331 // Load the xml file 00332 CzXmlParser* xml = new CzXmlParser(); 00333 if (xml->Parse("./Scene1.xml") == eXMLParserError_None) 00334 { 00335 // Save the xml file back out 00336 xml->getRoot()->Save("test1.xml"); 00337 } 00338 @endcode 00339 00340 In this example we create an instance of the XML parser object then call Parse() passing in the name of the XML file. If there was no parsing errors then we save the file back out to 00341 check that it worked. 00342 00343 Three versions of Parse() are available: 00344 - Parse(const char* filename); 00345 - Parse(CzFile *file); 00346 - Parse(CzDataInput* data); 00347 00348 These allowing parsing of a named file, an AppEasy file and a data input stream. 00349 00350 <h1>Working with Nodes</h1> 00351 00352 The parser provides a number of useful methods that you can use to get nodes from the parsed data: 00353 - getRoot() - Returns the root node of the loaded XML data 00354 - getFirstNamedNode() - Searches the complete XML node structure from the specified parent node and returns the first node who's name matches the supplied node name 00355 - gettNamedNodes() - Searches the complete XML node structure from the specified node and returns all nodes who's names match the supplied node name 00356 00357 Once you have a node you can begin querying the nodes value and attributes. To get the nodes value you can use the following methods: 00358 - getValue() - Returns the nodes value as a string 00359 - getValueAsInt() - Returns the nodes value as an integer 00360 - getValueAsFloat() - Returns the nodes value as a floating point number 00361 - getValueAsBool() - Returns the nodes value as a boolean 00362 00363 For debug purposes you can also print the nodes attributes and complete hierarchy using the following methods: 00364 - PrintAttributes() - Prints the nodes attributes to a string 00365 - PrintTree() - Prints the entier XML node structure to a string 00366 00367 You can search a nodes child nodes using the following methods: 00368 - getFirstNode() - Returns the first node 00369 - getFirstNamedNode(unsigned int name_hash) - Returns the first named mode 00370 - getNamedNodes(unsigned int name_hash, CzXmlNodeList *nodes) - Returns all nodes that match the supplied name 00371 00372 Note that these methods take a hashed string value as node names instead of a string for faster searching. 00373 00374 CzXmlNode also provides methods for saving its structure to a file: 00375 - SaveAttributes(CzFile* file) - Saves a group of mode attributes to a file 00376 - SaveTree(CzFile* file) - Saves a complete mode tree to a file 00377 - Save(const char* filename) - Saves a complete mode tree to a file with specified filename 00378 00379 Querying attributes can be done using the following methods: 00380 - GetAttributeCount() - Returns number of attributes that the node contains 00381 - GetAttribute(const char* name) - Gets the named attribute 00382 - GetAttribute(int index) - Gets the attribute at the specified index 00383 00384 And finally methods have been provided for building nodes: 00385 - SetName(const char* name, int len) - Sets the nodes name 00386 - SetValue(const char* value, int len) - Sets the nodes value 00387 - AddChild(CzXmlNode* node) - Adds a new node as a child 00388 - AddAttribute(CzXmlAttribute *attribute) - Adds a new attribute to the node 00389 - AddAttribute(CzString& name, CzString& value) - Adds a new attribute to the node 00390 - AddAttribute(CzString& name, const char* value) - Adds a new attribute to the node 00391 - UpdateAttribute(const CzString& name, const char* value, CzXmlParser* parser) - Updates an existing named attribute in the node 00392 00393 <h1>Node and Attribute Iteration</h1> 00394 00395 CzXmlNode provides iterator based access to both child nodes and attributes: 00396 00397 @code 00398 typedef CIwList<CzXmlNode*>::iterator _Iterator; 00399 typedef CIwList<CzXmlAttribute*>::iterator _AttribIterator; 00400 _Iterator begin() 00401 _Iterator end() 00402 _AttribIterator attribs_begin() 00403 _AttribIterator attribs_end() 00404 @endcode 00405 00406 These types and methods allow you to easily walk the nodes child nodes and attributes. Below is an example showing how to walk a nodes child nodes and each nodes attributes: 00407 00408 @code 00409 // Walk the child nodes 00410 for (CzXmlNode::_Iterator nodes = node->begin(); nodes != node->end(); ++nodes) 00411 { 00412 // Walk the nodes attrobutes 00413 for (CzXmlNode::_AttribIterator attribs = (*nodes)->attribs_begin(); attribs != (*nodes)->attribs_end(); ++attribs) 00414 { 00415 } 00416 } 00417 @endcode 00418 00419 <h1>Attribute Query</h1> 00420 00421 CzXmlAttribute provides an extensive set of methods for querying attribute values and converting the data to different formats. Below is a list of all methods: 00422 00423 @code 00424 CzString& getValue() { return Value; } 00425 int getValueAsInt() const; 00426 float getValueAsFloat() const; 00427 bool getValueAsBool() const; 00428 bool getValueAsPoint(CIwFVec2 &point); 00429 bool getValueAsPoint3(CIwFVec3 &point); 00430 bool getValueAsPoint4(CIwFVec4 &point); 00431 bool getValueAsColour(CIwColour &colour); 00432 bool getValueAsRect(CIwRect &rect); 00433 00434 CzXmlStringList* getValueAsList(); 00435 int getValueAsListOfInt(); 00436 int getValueAsListOfFloat(); 00437 int getValueAsListOfBool(); 00438 @endcode 00439 00440 The list value retrieval methods uses a pooled memory system to reduce constant allocation and deallocation of memory, so please ensure that you store off the values 00441 retrieved from the pool buffers before calling the list methods again or data will be written over. To see how the list pool buffers are used lets take a quick look 00442 at at GetValueAsRect(): 00443 00444 @code 00445 bool CzXmlAttribute::getValueAsRect(CzIRect& rect) 00446 { 00447 if (Value.getAsListOfInt(CzXmlTools::IntListPool) != 4) 00448 { 00449 return false; 00450 } 00451 rect.x = CzXmlTools::IntListPool[0]; 00452 rect.y = CzXmlTools::IntListPool[1]; 00453 rect.w = CzXmlTools::IntListPool[2]; 00454 rect.h = CzXmlTools::IntListPool[3]; 00455 00456 return true; 00457 } 00458 @endcode 00459 00460 As you can see, when we call GetAsListOfInt() a global buffer called CzXmlTools::IntListPool is filled with the values that are returned. 00461 00462 <h1>Creating an XML file</h1> 00463 00464 XML is very useful when it comes to representing data in a platform independent manner. It's also very useful when it comes to serialising game state and other data to 00465 storage as it can be saved in a good structured format. 00466 00467 To create an XML file you need to create a root XML node then add further named child nodes that contain values and attributes that contain your data. Below shows a 00468 quick example: 00469 00470 @code 00471 // Create root XML node 00472 CzXmlNode* root = new CzXmlNode(); 00473 root->SetName("xml"); 00474 00475 // Create and add a settings child node to the root 00476 CzXmlNode* settings_node = new CzXmlNode(); 00477 settings_node->SetName("Settings"); 00478 root->AddChild(settings_node); 00479 00480 // Create and add a FullVersion node to the settings node 00481 CzXmlNode* value_node = new CzXmlNode(); 00482 value_node->SetName("FullVersion"); 00483 value_node->SetValue("true"); 00484 settings_node->AddChild(value_node); 00485 00486 // Save the XML file 00487 settings_node->Save("./Settings.xml"); 00488 00489 // Cleanup xml data 00490 delete root; 00491 @endcode 00492 00493 The above code will generate the following XML file: 00494 00495 @code 00496 <?xml version="1.0"?> 00497 <Settings> 00498 <FullVersion>true</FullVersion> 00499 </Settings> 00500 @endcode 00501 00502 */ 00503 00504 class CzXmlParser 00505 { 00506 public: 00507 00508 private: 00509 CzString Filename; ///< Name of file being parsed 00510 CzString m_Encoding; ///< Encoding type 00511 CzString m_Version; ///< XML version 00512 CzDataInput* m_pDataInput; ///< Input stream 00513 CzXmlNode* m_pRoot; ///< Root node 00514 CzXmlTagMarker* Marker; ///< Tag markers buffer 00515 int MarkerCount; ///< Total tag markers in the buffer 00516 00517 CzXmlNodeList::iterator RemoveNodeFromList(CzXmlNodeList& list, const CzXmlNodeList::iterator& it); 00518 public: 00519 CzXmlParser() : m_pDataInput(NULL), m_pRoot(NULL) 00520 { 00521 TagPool = NULL; 00522 NextFreePoolTagIndex = 0; 00523 MaxPoolTags = 0; 00524 NodePool = NULL; 00525 NextFreePoolNodeIndex = 0; 00526 MaxPoolNodes = 0; 00527 AttributePool = NULL; 00528 NextFreePoolAttributeIndex = 0; 00529 MaxPoolAttributes = 0; 00530 // m_Encoding.setString("utf-8"); 00531 // m_Version.setString("1.0"); 00532 } 00533 virtual ~CzXmlParser() 00534 { 00535 // if (m_pRoot != NULL) 00536 // delete m_pRoot; 00537 SAFE_DELETE_ARRAY(TagPool); 00538 SAFE_DELETE_ARRAY(NodePool); 00539 SAFE_DELETE_ARRAY(AttributePool); 00540 SAFE_DELETE(m_pDataInput); 00541 } 00542 00543 void setEncoding(const char* enocding) { m_Encoding.setString(enocding); } 00544 const CzString& getEncoding() const { return m_Encoding; } 00545 void setVersion(const char* version) { m_Version.setString(version); } 00546 const CzString& getVersion() const { return m_Version; } 00547 const CzString& getFilename() const { return Filename; } 00548 00549 CzXmlNode* AllocNode() ///< Allocates space for a new node 00550 { 00551 if (NodePool == NULL) 00552 return new CzXmlNode(); 00553 if (NextFreePoolNodeIndex >= MaxPoolNodes) 00554 { 00555 return new CzXmlNode(); 00556 // CzDebug::Log(CZ_DEBUG_CHANNEL_ERROR, "Ran out of nodes, allocate more"); 00557 // return NULL; 00558 } 00559 CzXmlNode* node = NodePool + NextFreePoolNodeIndex++; 00560 node->Clear(); 00561 node->setParser(this); 00562 node->Managed = true; 00563 00564 return node; 00565 } 00566 CzXmlTagMarker* AllocTag() ///< Allocates space for a new tag marker 00567 { 00568 if (TagPool == NULL) 00569 return new CzXmlTagMarker(); 00570 if (NextFreePoolTagIndex >= MaxPoolTags) 00571 { 00572 return new CzXmlTagMarker(); 00573 // CzDebug::Log(CZ_DEBUG_CHANNEL_ERROR, "Ran out of tag markers, allocate more"); 00574 // return NULL; 00575 } 00576 CzXmlTagMarker* tag = TagPool + NextFreePoolTagIndex++; 00577 tag->Clear(); 00578 00579 return tag; 00580 } 00581 00582 CzXmlAttribute* AllocAttribute() ///< Allocates space for a new attribute 00583 { 00584 if (AttributePool == NULL) 00585 return new CzXmlAttribute(); 00586 if (NextFreePoolAttributeIndex >= MaxPoolAttributes) 00587 { 00588 return new CzXmlAttribute(); 00589 // CzDebug::Log(CZ_DEBUG_CHANNEL_ERROR, "Ran out of attributes, allocate more"); 00590 // return NULL; 00591 } 00592 CzXmlAttribute* attribute = AttributePool + NextFreePoolAttributeIndex++; 00593 attribute->Clear(); 00594 attribute->Managed = true; 00595 00596 return attribute; 00597 } 00598 00599 // Parse the supplied file 00600 eCzXmlParseError Parse(const char* pFilename); ///< Parses the supplied file 00601 eCzXmlParseError Parse(CzFile *file); ///< Parses the supplied file 00602 eCzXmlParseError Parse(CzDataInput* pData); ///< Parses the supplied memory buffer 00603 int Save(const char* filename); ///< Saves entire node tree to a file with the specified filename 00604 const char* getErrorString(eCzXmlParseError error) const; ///< Returns the string repesentation of the supplied error 00605 CzXmlNode* getRoot() ///< Get root node (note that root node is '.' and not the first XML tag) 00606 { 00607 return m_pRoot; 00608 } 00609 CzXmlNode* getFirstNamedNode(CzXmlNode *parent, const char* node_name) ///< Get first occurrence of a node in this node and all children 00610 { 00611 if (parent == NULL) 00612 parent = getRoot(); 00613 00614 int hash = CzString::CalculateHash(node_name); 00615 if (parent != NULL) 00616 return parent->getFirstNamedNode(hash); 00617 if (m_pRoot != NULL) 00618 return m_pRoot->getFirstNamedNode(hash); 00619 00620 return NULL; 00621 } 00622 CzXmlNodeList* getNamedNodes(CzXmlNode *parent, const char* node_name)///</ Get all occurrences of a node in this node and all children (caller is responsible for cleaning up list). Pass NULL as bode_name to return all nodes 00623 { 00624 if (parent == NULL) 00625 parent = getRoot(); 00626 00627 int hash = CzString::CalculateHash(node_name); 00628 CzXmlNodeList* pNodes = new CzXmlNodeList; 00629 if (parent != NULL) 00630 parent->getNamedNodes(hash, pNodes); 00631 else 00632 if (m_pRoot != NULL) 00633 m_pRoot->getNamedNodes(hash, pNodes); 00634 00635 return pNodes; 00636 } 00637 00638 private: 00639 eCzXmlParseError ParseXMLHeader(); 00640 eCzXmlParseError ParseAttributes(const char* data, int count, CzXmlNode* node); 00641 bool PreParse(); 00642 eCzXmlParseError Parse(CzXmlNode* parent); 00643 00644 eCzXmlParseError ParseAttributes(CzXmlNode* node); 00645 eCzXmlParseError Parse(CzXmlNode* pParent, int range, int &num_tags_found); 00646 const char* getCloseTagName(CzXmlNode *node) const; 00647 void ShowError(eCzXmlParseError error, int pos) const; 00648 00649 int getNextWord(const char* data, int &offset); 00650 int getNextQuotedWord(const char* data, int &offset); 00651 00652 // friend CzXmlNode; 00653 // friend CzXmlAttribute; 00654 00655 // Tag and node pooling 00656 CzXmlTagMarker* TagPool; ///< Used to separate tags from the raw XML file 00657 int NextFreePoolTagIndex; ///< Next free pool tag index 00658 int MaxPoolTags; ///< Maxmimum available pooled tags 00659 CzXmlNode* NodePool; ///< Xml nodes pool 00660 int NextFreePoolNodeIndex; ///< Bext free node index in nodes pool 00661 int MaxPoolNodes; ///< Maximum available nodes in the nodes pool 00662 CzXmlAttribute* AttributePool; ///< Xml attribute pool 00663 int NextFreePoolAttributeIndex; ///< Bext free attribute index in nodes pool 00664 int MaxPoolAttributes; ///< Maximum available attributes in the attributes pool 00665 public: 00666 00667 }; 00668 00669 /// @} 00670 00671 #endif // _CZ_XML_H_