AppEasy Core SDK  1.5.0
Cross platform mobile and desktop app and game development SDK - The easy way to make apps
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines
CzXml.h
Go to the documentation of this file.
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_