• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

sst/core/techModels/libMcPATbeta06/xmlParser.h

00001 /****************************************************************************/
00002 /*! \mainpage XMLParser library
00003  * \section intro_sec Introduction
00004  *
00005  * This is a basic XML parser written in ANSI C++ for portability.
00006  * It works by using recursion and a node tree for breaking
00007  * down the elements of an XML document.
00008  *
00009  * @version     V2.41
00010  * @author      Frank Vanden Berghen
00011  *
00012  * The following license terms for the "XMLParser library from Business-Insight" apply to projects
00013  * that are in some way related to
00014  * the "mcpat project", including applications
00015  * using "mcpat project" and tools developed
00016  * for enhancing "mcpat project". All other projects
00017  * (not related to "mcpat project") have to use the "XMLParser library from Business-Insight"
00018  * code under the Aladdin Free Public License (AFPL)
00019  * See the file "AFPL-license.txt" for more informations about the AFPL license.
00020  * (see http://www.artifex.com/downloads/doc/Public.htm for detailed AFPL terms)
00021  *
00022  * Redistribution and use of the "XMLParser library from Business-Insight" in source and binary forms, with or without
00023  * modification, are permitted provided that the following conditions are met:
00024  *     * Redistributions of source code must retain the above copyright
00025  *       notice, this list of conditions and the following disclaimer.
00026  *     * Redistributions in binary form must reproduce the above copyright
00027  *       notice, this list of conditions and the following disclaimer in the
00028  *       documentation and/or other materials provided with the distribution.
00029  *     * Neither the name of Frank Vanden Berghen nor the
00030  *       names of its contributors may be used to endorse or promote products
00031  *       derived from this software without specific prior written permission.
00032  *
00033  * THIS SOFTWARE IS PROVIDED BY Business-Insight ``AS IS'' AND ANY
00034  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00035  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00036  * DISCLAIMED. IN NO EVENT SHALL Business-Insight BE LIABLE FOR ANY
00037  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00038  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00039  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00040  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00041  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00042  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00043  *
00044  * Copyright (c) 2002, Business-Insight
00045  * <a href="http://www.Business-Insight.com">Business-Insight</a>
00046  * All rights reserved.
00047  *
00048  * \section tutorial First Tutorial
00049  * You can follow a simple <a href="../../xmlParser.html">Tutorial</a> to know the basics...
00050  *
00051  * \section usage General usage: How to include the XMLParser library inside your project.
00052  *
00053  * The library is composed of two files: <a href="../../xmlParser.cpp">xmlParser.cpp</a> and
00054  * <a href="../../xmlParser.h">xmlParser.h</a>. These are the ONLY 2 files that you need when
00055  * using the library inside your own projects.
00056  *
00057  * All the functions of the library are documented inside the comments of the file
00058  * <a href="../../xmlParser.h">xmlParser.h</a>. These comments can be transformed in
00059  * full-fledged HTML documentation using the DOXYGEN software: simply type: "doxygen doxy.cfg"
00060  *
00061  * By default, the XMLParser library uses (char*) for string representation.To use the (wchar_t*)
00062  * version of the library, you need to define the "_UNICODE" preprocessor definition variable
00063  * (this is usually done inside your project definition file) (This is done automatically for you
00064  * when using Visual Studio).
00065  *
00066  * \section example Advanced Tutorial and Many Examples of usage.
00067  *
00068  * Some very small introductory examples are described inside the Tutorial file
00069  * <a href="../../xmlParser.html">xmlParser.html</a>
00070  *
00071  * Some additional small examples are also inside the file <a href="../../xmlTest.cpp">xmlTest.cpp</a>
00072  * (for the "char*" version of the library) and inside the file
00073  * <a href="../../xmlTestUnicode.cpp">xmlTestUnicode.cpp</a> (for the "wchar_t*"
00074  * version of the library). If you have a question, please review these additionnal examples
00075  * before sending an e-mail to the author.
00076  *
00077  * To build the examples:
00078  * - linux/unix: type "make"
00079  * - solaris: type "make -f makefile.solaris"
00080  * - windows: Visual Studio: double-click on xmlParser.dsw
00081  *   (under Visual Studio .NET, the .dsp and .dsw files will be automatically converted to .vcproj and .sln files)
00082  *
00083  * In order to build the examples you need some additional files:
00084  * - linux/unix: makefile
00085  * - solaris: makefile.solaris
00086  * - windows: Visual Studio: *.dsp, xmlParser.dsw and also xmlParser.lib and xmlParser.dll
00087  *
00088  * \section debugging Debugging with the XMLParser library
00089  *
00090  * \subsection debugwin Debugging under WINDOWS
00091  *
00092  *      Inside Visual C++, the "debug versions" of the memory allocation functions are
00093  *      very slow: Do not forget to compile in "release mode" to get maximum speed.
00094  *      When I had to debug a software that was using the XMLParser Library, it was usually
00095  *      a nightmare because the library was sooOOOoooo slow in debug mode (because of the
00096  *  slow memory allocations in Debug mode). To solve this
00097  *      problem, during all the debugging session, I am now using a very fast DLL version of the
00098  *      XMLParser Library (the DLL is compiled in release mode). Using the DLL version of
00099  *      the XMLParser Library allows me to have lightening XML parsing speed even in debug!
00100  *      Other than that, the DLL version is useless: In the release version of my tool,
00101  *      I always use the normal, ".cpp"-based, XMLParser Library (I simply include the
00102  * <a href="../../xmlParser.cpp">xmlParser.cpp</a> and
00103  * <a href="../../xmlParser.h">xmlParser.h</a> files into the project).
00104  *
00105  *      The file <a href="../../XMLNodeAutoexp.txt">XMLNodeAutoexp.txt</a> contains some
00106  * "tweaks" that improve substancially the display of the content of the XMLNode objects
00107  * inside the Visual Studio Debugger. Believe me, once you have seen inside the debugger
00108  * the "smooth" display of the XMLNode objects, you cannot live without it anymore!
00109  *
00110  * \subsection debuglinux Debugging under LINUX/UNIX
00111  *
00112  *      The speed of the debug version of the XMLParser library is tolerable so no extra
00113  * work.has been done.
00114  *
00115  ****************************************************************************/
00116 
00117 #ifndef __INCLUDE_XML_NODE__
00118 #define __INCLUDE_XML_NODE__
00119 
00120 #include <stdlib.h>
00121 
00122 #ifdef _UNICODE
00123 // If you comment the next "define" line then the library will never "switch to" _UNICODE (wchar_t*) mode (16/32 bits per characters).
00124 // This is useful when you get error messages like:
00125 //    'XMLNode::openFileHelper' : cannot convert parameter 2 from 'const char [5]' to 'const wchar_t *'
00126 // The _XMLWIDECHAR preprocessor variable force the XMLParser library into either utf16/32-mode (the proprocessor variable
00127 // must be defined) or utf8-mode(the pre-processor variable must be undefined).
00128 #define _XMLWIDECHAR
00129 #endif
00130 
00131 #if defined(WIN32) || defined(UNDER_CE) || defined(_WIN32) || defined(WIN64) || defined(__BORLANDC__)
00132 // comment the next line if you are under windows and the compiler is not Microsoft Visual Studio (6.0 or .NET) or Borland
00133 #define _XMLWINDOWS
00134 #endif
00135 
00136 #ifdef XMLDLLENTRY
00137 #undef XMLDLLENTRY
00138 #endif
00139 #ifdef _USE_XMLPARSER_DLL
00140 #ifdef _DLL_EXPORTS_
00141 #define XMLDLLENTRY __declspec(dllexport)
00142 #else
00143 #define XMLDLLENTRY __declspec(dllimport)
00144 #endif
00145 #else
00146 #define XMLDLLENTRY
00147 #endif
00148 
00149 // uncomment the next line if you want no support for wchar_t* (no need for the <wchar.h> or <tchar.h> libraries anymore to compile)
00150 //#define XML_NO_WIDE_CHAR
00151 
00152 #ifdef XML_NO_WIDE_CHAR
00153 #undef _XMLWINDOWS
00154 #undef _XMLWIDECHAR
00155 #endif
00156 
00157 #ifdef _XMLWINDOWS
00158 #include <tchar.h>
00159 #else
00160 #define XMLDLLENTRY
00161 #ifndef XML_NO_WIDE_CHAR
00162 #include <wchar.h> // to have 'wcsrtombs' for ANSI version
00163                    // to have 'mbsrtowcs' for WIDECHAR version
00164 #endif
00165 #endif
00166 
00167 // Some common types for char set portable code
00168 #ifdef _XMLWIDECHAR
00169     #define _CXML(c) L ## c
00170     #define XMLCSTR const wchar_t *
00171     #define XMLSTR  wchar_t *
00172     #define XMLCHAR wchar_t
00173 #else
00174     #define _CXML(c) c
00175     #define XMLCSTR const char *
00176     #define XMLSTR  char *
00177     #define XMLCHAR char
00178 #endif
00179 #ifndef FALSE
00180     #define FALSE 0
00181 #endif /* FALSE */
00182 #ifndef TRUE
00183     #define TRUE 1
00184 #endif /* TRUE */
00185 
00186 
00187 /// Enumeration for XML parse errors.
00188 typedef enum XMLError
00189 {
00190     eXMLErrorNone = 0,
00191     eXMLErrorMissingEndTag,
00192     eXMLErrorNoXMLTagFound,
00193     eXMLErrorEmpty,
00194     eXMLErrorMissingTagName,
00195     eXMLErrorMissingEndTagName,
00196     eXMLErrorUnmatchedEndTag,
00197     eXMLErrorUnmatchedEndClearTag,
00198     eXMLErrorUnexpectedToken,
00199     eXMLErrorNoElements,
00200     eXMLErrorFileNotFound,
00201     eXMLErrorFirstTagNotFound,
00202     eXMLErrorUnknownCharacterEntity,
00203     eXMLErrorCharacterCodeAbove255,
00204     eXMLErrorCharConversionError,
00205     eXMLErrorCannotOpenWriteFile,
00206     eXMLErrorCannotWriteFile,
00207 
00208     eXMLErrorBase64DataSizeIsNotMultipleOf4,
00209     eXMLErrorBase64DecodeIllegalCharacter,
00210     eXMLErrorBase64DecodeTruncatedData,
00211     eXMLErrorBase64DecodeBufferTooSmall
00212 } XMLError;
00213 
00214 
00215 /// Enumeration used to manage type of data. Use in conjunction with structure XMLNodeContents
00216 typedef enum XMLElementType
00217 {
00218     eNodeChild=0,
00219     eNodeAttribute=1,
00220     eNodeText=2,
00221     eNodeClear=3,
00222     eNodeNULL=4
00223 } XMLElementType;
00224 
00225 /// Structure used to obtain error details if the parse fails.
00226 typedef struct XMLResults
00227 {
00228     enum XMLError error;
00229     int  nLine,nColumn;
00230 } XMLResults;
00231 
00232 /// Structure for XML clear (unformatted) node (usually comments)
00233 typedef struct XMLClear {
00234     XMLCSTR lpszValue; XMLCSTR lpszOpenTag; XMLCSTR lpszCloseTag;
00235 } XMLClear;
00236 
00237 /// Structure for XML attribute.
00238 typedef struct XMLAttribute {
00239     XMLCSTR lpszName; XMLCSTR lpszValue;
00240 } XMLAttribute;
00241 
00242 /// XMLElementPosition are not interchangeable with simple indexes
00243 typedef int XMLElementPosition;
00244 
00245 struct XMLNodeContents;
00246 
00247 /** @defgroup XMLParserGeneral The XML parser */
00248 
00249 /// Main Class representing a XML node
00250 /**
00251  * All operations are performed using this class.
00252  * \note The constructors of the XMLNode class are protected, so use instead one of these four methods to get your first instance of XMLNode:
00253  * <ul>
00254  *    <li> XMLNode::parseString </li>
00255  *    <li> XMLNode::parseFile </li>
00256  *    <li> XMLNode::openFileHelper </li>
00257  *    <li> XMLNode::createXMLTopNode (or XMLNode::createXMLTopNode_WOSD)</li>
00258  * </ul> */
00259 typedef struct XMLDLLENTRY XMLNode
00260 {
00261   private:
00262 
00263     struct XMLNodeDataTag;
00264 
00265     /// Constructors are protected, so use instead one of: XMLNode::parseString, XMLNode::parseFile, XMLNode::openFileHelper, XMLNode::createXMLTopNode
00266     XMLNode(struct XMLNodeDataTag *pParent, XMLSTR lpszName, char isDeclaration);
00267     /// Constructors are protected, so use instead one of: XMLNode::parseString, XMLNode::parseFile, XMLNode::openFileHelper, XMLNode::createXMLTopNode
00268     XMLNode(struct XMLNodeDataTag *p);
00269 
00270   public:
00271     static XMLCSTR getVersion();///< Return the XMLParser library version number
00272 
00273     /** @defgroup conversions Parsing XML files/strings to an XMLNode structure and Rendering XMLNode's to files/string.
00274      * @ingroup XMLParserGeneral
00275      * @{ */
00276 
00277     /// Parse an XML string and return the root of a XMLNode tree representing the string.
00278     static XMLNode parseString   (XMLCSTR  lpXMLString, XMLCSTR tag=NULL, XMLResults *pResults=NULL);
00279     /**< The "parseString" function parse an XML string and return the root of a XMLNode tree. The "opposite" of this function is
00280      * the function "createXMLString" that re-creates an XML string from an XMLNode tree. If the XML document is corrupted, the
00281      * "parseString" method will initialize the "pResults" variable with some information that can be used to trace the error.
00282      * If you still want to parse the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the
00283      * beginning of the "xmlParser.cpp" file.
00284      *
00285      * @param lpXMLString the XML string to parse
00286      * @param tag  the name of the first tag inside the XML file. If the tag parameter is omitted, this function returns a node that represents the head of the xml document including the declaration term (<? ... ?>).
00287      * @param pResults a pointer to a XMLResults variable that will contain some information that can be used to trace the XML parsing error. You can have a user-friendly explanation of the parsing error with the "getError" function.
00288      */
00289 
00290     /// Parse an XML file and return the root of a XMLNode tree representing the file.
00291     static XMLNode parseFile     (XMLCSTR     filename, XMLCSTR tag=NULL, XMLResults *pResults=NULL);
00292     /**< The "parseFile" function parse an XML file and return the root of a XMLNode tree. The "opposite" of this function is
00293      * the function "writeToFile" that re-creates an XML file from an XMLNode tree. If the XML document is corrupted, the
00294      * "parseFile" method will initialize the "pResults" variable with some information that can be used to trace the error.
00295      * If you still want to parse the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the
00296      * beginning of the "xmlParser.cpp" file.
00297      *
00298      * @param filename the path to the XML file to parse
00299      * @param tag the name of the first tag inside the XML file. If the tag parameter is omitted, this function returns a node that represents the head of the xml document including the declaration term (<? ... ?>).
00300      * @param pResults a pointer to a XMLResults variable that will contain some information that can be used to trace the XML parsing error. You can have a user-friendly explanation of the parsing error with the "getError" function.
00301      */
00302 
00303     /// Parse an XML file and return the root of a XMLNode tree representing the file. A very crude error checking is made. An attempt to guess the Char Encoding used in the file is made.
00304     static XMLNode openFileHelper(XMLCSTR     filename, XMLCSTR tag=NULL);
00305     /**< The "openFileHelper" function reports to the screen all the warnings and errors that occurred during parsing of the XML file.
00306      * This function also tries to guess char Encoding (UTF-8, ASCII or SHIT-JIS) based on the first 200 bytes of the file. Since each
00307      * application has its own way to report and deal with errors, you should rather use the "parseFile" function to parse XML files
00308      * and program yourself thereafter an "error reporting" tailored for your needs (instead of using the very crude "error reporting"
00309      * mechanism included inside the "openFileHelper" function).
00310      *
00311      * If the XML document is corrupted, the "openFileHelper" method will:
00312      *         - display an error message on the console (or inside a messageBox for windows).
00313      *         - stop execution (exit).
00314      *
00315      * I strongly suggest that you write your own "openFileHelper" method tailored to your needs. If you still want to parse
00316      * the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the beginning of the "xmlParser.cpp" file.
00317      *
00318      * @param filename the path of the XML file to parse.
00319      * @param tag the name of the first tag inside the XML file. If the tag parameter is omitted, this function returns a node that represents the head of the xml document including the declaration term (<? ... ?>).
00320      */
00321 
00322     static XMLCSTR getError(XMLError error); ///< this gives you a user-friendly explanation of the parsing error
00323 
00324     /// Create an XML string starting from the current XMLNode.
00325     XMLSTR createXMLString(int nFormat=1, int *pnSize=NULL) const;
00326     /**< The returned string should be free'd using the "freeXMLString" function.
00327      *
00328      *   If nFormat==0, no formatting is required otherwise this returns an user friendly XML string from a given element
00329      *   with appropriate white spaces and carriage returns. if pnSize is given it returns the size in character of the string. */
00330 
00331     /// Save the content of an xmlNode inside a file
00332     XMLError writeToFile(XMLCSTR filename,
00333                          const char *encoding=NULL,
00334                          char nFormat=1) const;
00335     /**< If nFormat==0, no formatting is required otherwise this returns an user friendly XML string from a given element with appropriate white spaces and carriage returns.
00336      * If the global parameter "characterEncoding==encoding_UTF8", then the "encoding" parameter is ignored and always set to "utf-8".
00337      * If the global parameter "characterEncoding==encoding_ShiftJIS", then the "encoding" parameter is ignored and always set to "SHIFT-JIS".
00338      * If "_XMLWIDECHAR=1", then the "encoding" parameter is ignored and always set to "utf-16".
00339      * If no "encoding" parameter is given the "ISO-8859-1" encoding is used. */
00340     /** @} */
00341 
00342     /** @defgroup navigate Navigate the XMLNode structure
00343      * @ingroup XMLParserGeneral
00344      * @{ */
00345     XMLCSTR getName() const;                                       ///< name of the node
00346     XMLCSTR getText(int i=0) const;                                ///< return ith text field
00347     int nText() const;                                             ///< nbr of text field
00348     XMLNode getParentNode() const;                                 ///< return the parent node
00349     XMLNode getChildNode(int i=0) const;                           ///< return ith child node
00350     XMLNode getChildNode(XMLCSTR name, int i)  const;              ///< return ith child node with specific name (return an empty node if failing). If i==-1, this returns the last XMLNode with the given name.
00351     XMLNode getChildNode(XMLCSTR name, int *i=NULL) const;         ///< return next child node with specific name (return an empty node if failing)
00352     XMLNode getChildNodeWithAttribute(XMLCSTR tagName,
00353                                       XMLCSTR attributeName,
00354                                       XMLCSTR attributeValue=NULL,
00355                                       int *i=NULL)  const;         ///< return child node with specific name/attribute (return an empty node if failing)
00356     XMLNode getChildNodeByPath(XMLCSTR path, char createNodeIfMissing=0, XMLCHAR sep='/');
00357                                                                    ///< return the first child node with specific path
00358     XMLNode getChildNodeByPathNonConst(XMLSTR  path, char createNodeIfMissing=0, XMLCHAR sep='/');
00359                                                                    ///< return the first child node with specific path.
00360 
00361     int nChildNode(XMLCSTR name) const;                            ///< return the number of child node with specific name
00362     int nChildNode() const;                                        ///< nbr of child node
00363     XMLAttribute getAttribute(int i=0) const;                      ///< return ith attribute
00364     XMLCSTR      getAttributeName(int i=0) const;                  ///< return ith attribute name
00365     XMLCSTR      getAttributeValue(int i=0) const;                 ///< return ith attribute value
00366     char  isAttributeSet(XMLCSTR name) const;                      ///< test if an attribute with a specific name is given
00367     XMLCSTR getAttribute(XMLCSTR name, int i) const;               ///< return ith attribute content with specific name (return a NULL if failing)
00368     XMLCSTR getAttribute(XMLCSTR name, int *i=NULL) const;         ///< return next attribute content with specific name (return a NULL if failing)
00369     int nAttribute() const;                                        ///< nbr of attribute
00370     XMLClear getClear(int i=0) const;                              ///< return ith clear field (comments)
00371     int nClear() const;                                            ///< nbr of clear field
00372     XMLNodeContents enumContents(XMLElementPosition i) const;      ///< enumerate all the different contents (attribute,child,text, clear) of the current XMLNode. The order is reflecting the order of the original file/string. NOTE: 0 <= i < nElement();
00373     int nElement() const;                                          ///< nbr of different contents for current node
00374     char isEmpty() const;                                          ///< is this node Empty?
00375     char isDeclaration() const;                                    ///< is this node a declaration <? .... ?>
00376     XMLNode deepCopy() const;                                      ///< deep copy (duplicate/clone) a XMLNode
00377     static XMLNode emptyNode();                                    ///< return XMLNode::emptyXMLNode;
00378     /** @} */
00379 
00380     ~XMLNode();
00381     XMLNode(const XMLNode &A);                                     ///< to allow shallow/fast copy:
00382     XMLNode& operator=( const XMLNode& A );                        ///< to allow shallow/fast copy:
00383 
00384     XMLNode(): d(NULL){};
00385     static XMLNode emptyXMLNode;
00386     static XMLClear emptyXMLClear;
00387     static XMLAttribute emptyXMLAttribute;
00388 
00389     /** @defgroup xmlModify Create or Update the XMLNode structure
00390      * @ingroup XMLParserGeneral
00391      *  The functions in this group allows you to create from scratch (or update) a XMLNode structure. Start by creating your top
00392      *  node with the "createXMLTopNode" function and then add new nodes with the "addChild" function. The parameter 'pos' gives
00393      *  the position where the childNode, the text or the XMLClearTag will be inserted. The default value (pos=-1) inserts at the
00394      *  end. The value (pos=0) insert at the beginning (Insertion at the beginning is slower than at the end). <br>
00395      *
00396      *  REMARK: 0 <= pos < nChild()+nText()+nClear() <br>
00397      */
00398 
00399     /** @defgroup creation Creating from scratch a XMLNode structure
00400      * @ingroup xmlModify
00401      * @{ */
00402     static XMLNode createXMLTopNode(XMLCSTR lpszName, char isDeclaration=FALSE);                    ///< Create the top node of an XMLNode structure
00403     XMLNode        addChild(XMLCSTR lpszName, char isDeclaration=FALSE, XMLElementPosition pos=-1); ///< Add a new child node
00404     XMLNode        addChild(XMLNode nodeToAdd, XMLElementPosition pos=-1);                          ///< If the "nodeToAdd" has some parents, it will be detached from it's parents before being attached to the current XMLNode
00405     XMLAttribute  *addAttribute(XMLCSTR lpszName, XMLCSTR lpszValuev);                              ///< Add a new attribute
00406     XMLCSTR        addText(XMLCSTR lpszValue, XMLElementPosition pos=-1);                           ///< Add a new text content
00407     XMLClear      *addClear(XMLCSTR lpszValue, XMLCSTR lpszOpen=NULL, XMLCSTR lpszClose=NULL, XMLElementPosition pos=-1);
00408     /**< Add a new clear tag
00409      * @param lpszOpen default value "<![CDATA["
00410      * @param lpszClose default value "]]>"
00411      */
00412     /** @} */
00413 
00414     /** @defgroup xmlUpdate Updating Nodes
00415      * @ingroup xmlModify
00416      * Some update functions:
00417      * @{
00418      */
00419     XMLCSTR       updateName(XMLCSTR lpszName);                                                  ///< change node's name
00420     XMLAttribute *updateAttribute(XMLAttribute *newAttribute, XMLAttribute *oldAttribute);       ///< if the attribute to update is missing, a new one will be added
00421     XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName=NULL,int i=0);       ///< if the attribute to update is missing, a new one will be added
00422     XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,XMLCSTR lpszOldName);///< set lpszNewName=NULL if you don't want to change the name of the attribute if the attribute to update is missing, a new one will be added
00423     XMLCSTR       updateText(XMLCSTR lpszNewValue, int i=0);                                     ///< if the text to update is missing, a new one will be added
00424     XMLCSTR       updateText(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue);                        ///< if the text to update is missing, a new one will be added
00425     XMLClear     *updateClear(XMLCSTR lpszNewContent, int i=0);                                  ///< if the clearTag to update is missing, a new one will be added
00426     XMLClear     *updateClear(XMLClear *newP,XMLClear *oldP);                                    ///< if the clearTag to update is missing, a new one will be added
00427     XMLClear     *updateClear(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue);                       ///< if the clearTag to update is missing, a new one will be added
00428     /** @} */
00429 
00430     /** @defgroup xmlDelete Deleting Nodes or Attributes
00431      * @ingroup xmlModify
00432      * Some deletion functions:
00433      * @{
00434      */
00435     /// The "deleteNodeContent" function forces the deletion of the content of this XMLNode and the subtree.
00436     void deleteNodeContent();
00437     /**< \note The XMLNode instances that are referring to the part of the subtree that has been deleted CANNOT be used anymore!!. Unexpected results will occur if you continue using them. */
00438     void deleteAttribute(int i=0);                   ///< Delete the ith attribute of the current XMLNode
00439     void deleteAttribute(XMLCSTR lpszName);          ///< Delete the attribute with the given name (the "strcmp" function is used to find the right attribute)
00440     void deleteAttribute(XMLAttribute *anAttribute); ///< Delete the attribute with the name "anAttribute->lpszName" (the "strcmp" function is used to find the right attribute)
00441     void deleteText(int i=0);                        ///< Delete the Ith text content of the current XMLNode
00442     void deleteText(XMLCSTR lpszValue);              ///< Delete the text content "lpszValue" inside the current XMLNode (direct "pointer-to-pointer" comparison is used to find the right text)
00443     void deleteClear(int i=0);                       ///< Delete the Ith clear tag inside the current XMLNode
00444     void deleteClear(XMLCSTR lpszValue);             ///< Delete the clear tag "lpszValue" inside the current XMLNode (direct "pointer-to-pointer" comparison is used to find the clear tag)
00445     void deleteClear(XMLClear *p);                   ///< Delete the clear tag "p" inside the current XMLNode (direct "pointer-to-pointer" comparison on the lpszName of the clear tag is used to find the clear tag)
00446     /** @} */
00447 
00448     /** @defgroup xmlWOSD ???_WOSD functions.
00449      * @ingroup xmlModify
00450      *  The strings given as parameters for the "add" and "update" methods that have a name with
00451      *  the postfix "_WOSD" (that means "WithOut String Duplication")(for example "addText_WOSD")
00452      *  will be free'd by the XMLNode class. For example, it means that this is incorrect:
00453      *  \code
00454      *     xNode.addText_WOSD("foo");
00455      *     xNode.updateAttribute_WOSD("#newcolor" ,NULL,"color");
00456      *  \endcode
00457      *  In opposition, this is correct:
00458      *  \code
00459      *     xNode.addText("foo");
00460      *     xNode.addText_WOSD(stringDup("foo"));
00461      *     xNode.updateAttribute("#newcolor" ,NULL,"color");
00462      *     xNode.updateAttribute_WOSD(stringDup("#newcolor"),NULL,"color");
00463      *  \endcode
00464      *  Typically, you will never do:
00465      *  \code
00466      *     char *b=(char*)malloc(...);
00467      *     xNode.addText(b);
00468      *     free(b);
00469      *  \endcode
00470      *  ... but rather:
00471      *  \code
00472      *     char *b=(char*)malloc(...);
00473      *     xNode.addText_WOSD(b);
00474      *  \endcode
00475      *  ('free(b)' is performed by the XMLNode class)
00476      * @{ */
00477     static XMLNode createXMLTopNode_WOSD(XMLSTR lpszName, char isDeclaration=FALSE);                     ///< Create the top node of an XMLNode structure
00478     XMLNode        addChild_WOSD(XMLSTR lpszName, char isDeclaration=FALSE, XMLElementPosition pos=-1);  ///< Add a new child node
00479     XMLAttribute  *addAttribute_WOSD(XMLSTR lpszName, XMLSTR lpszValue);                                 ///< Add a new attribute
00480     XMLCSTR        addText_WOSD(XMLSTR lpszValue, XMLElementPosition pos=-1);                            ///< Add a new text content
00481     XMLClear      *addClear_WOSD(XMLSTR lpszValue, XMLCSTR lpszOpen=NULL, XMLCSTR lpszClose=NULL, XMLElementPosition pos=-1); ///< Add a new clear Tag
00482 
00483     XMLCSTR        updateName_WOSD(XMLSTR lpszName);                                                  ///< change node's name
00484     XMLAttribute  *updateAttribute_WOSD(XMLAttribute *newAttribute, XMLAttribute *oldAttribute);      ///< if the attribute to update is missing, a new one will be added
00485     XMLAttribute  *updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName=NULL,int i=0);        ///< if the attribute to update is missing, a new one will be added
00486     XMLAttribute  *updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName,XMLCSTR lpszOldName); ///< set lpszNewName=NULL if you don't want to change the name of the attribute if the attribute to update is missing, a new one will be added
00487     XMLCSTR        updateText_WOSD(XMLSTR lpszNewValue, int i=0);                                     ///< if the text to update is missing, a new one will be added
00488     XMLCSTR        updateText_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue);                        ///< if the text to update is missing, a new one will be added
00489     XMLClear      *updateClear_WOSD(XMLSTR lpszNewContent, int i=0);                                  ///< if the clearTag to update is missing, a new one will be added
00490     XMLClear      *updateClear_WOSD(XMLClear *newP,XMLClear *oldP);                                   ///< if the clearTag to update is missing, a new one will be added
00491     XMLClear      *updateClear_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue);                       ///< if the clearTag to update is missing, a new one will be added
00492     /** @} */
00493 
00494     /** @defgroup xmlPosition Position helper functions (use in conjunction with the update&add functions
00495      * @ingroup xmlModify
00496      * These are some useful functions when you want to insert a childNode, a text or a XMLClearTag in the
00497      * middle (at a specified position) of a XMLNode tree already constructed. The value returned by these
00498      * methods is to be used as last parameter (parameter 'pos') of addChild, addText or addClear.
00499      * @{ */
00500     XMLElementPosition positionOfText(int i=0) const;
00501     XMLElementPosition positionOfText(XMLCSTR lpszValue) const;
00502     XMLElementPosition positionOfClear(int i=0) const;
00503     XMLElementPosition positionOfClear(XMLCSTR lpszValue) const;
00504     XMLElementPosition positionOfClear(XMLClear *a) const;
00505     XMLElementPosition positionOfChildNode(int i=0) const;
00506     XMLElementPosition positionOfChildNode(XMLNode x) const;
00507     XMLElementPosition positionOfChildNode(XMLCSTR name, int i=0) const; ///< return the position of the ith childNode with the specified name if (name==NULL) return the position of the ith childNode
00508     /** @} */
00509 
00510     /// Enumeration for XML character encoding.
00511     typedef enum XMLCharEncoding
00512     {
00513         char_encoding_error=0,
00514         char_encoding_UTF8=1,
00515         char_encoding_legacy=2,
00516         char_encoding_ShiftJIS=3,
00517         char_encoding_GB2312=4,
00518         char_encoding_Big5=5,
00519         char_encoding_GBK=6     // this is actually the same as Big5
00520     } XMLCharEncoding;
00521 
00522     /** \addtogroup conversions
00523      * @{ */
00524 
00525     /// Sets the global options for the conversions
00526     static char setGlobalOptions(XMLCharEncoding characterEncoding=XMLNode::char_encoding_UTF8, char guessWideCharChars=1,
00527                                  char dropWhiteSpace=1, char removeCommentsInMiddleOfText=1);
00528     /**< The "setGlobalOptions" function allows you to change four global parameters that affect string & file
00529      * parsing. First of all, you most-probably will never have to change these 3 global parameters.
00530      *
00531      * @param guessWideCharChars If "guessWideCharChars"=1 and if this library is compiled in WideChar mode, then the
00532      *     XMLNode::parseFile and XMLNode::openFileHelper functions will test if the file contains ASCII
00533      *     characters. If this is the case, then the file will be loaded and converted in memory to
00534      *     WideChar before being parsed. If 0, no conversion will be performed.
00535      *
00536      * @param guessWideCharChars If "guessWideCharChars"=1 and if this library is compiled in ASCII/UTF8/char* mode, then the
00537      *     XMLNode::parseFile and XMLNode::openFileHelper functions will test if the file contains WideChar
00538      *     characters. If this is the case, then the file will be loaded and converted in memory to
00539      *     ASCII/UTF8/char* before being parsed. If 0, no conversion will be performed.
00540      *
00541      * @param characterEncoding This parameter is only meaningful when compiling in char* mode (multibyte character mode).
00542      *     In wchar_t* (wide char mode), this parameter is ignored. This parameter should be one of the
00543      *     three currently recognized encodings: XMLNode::encoding_UTF8, XMLNode::encoding_ascii,
00544      *     XMLNode::encoding_ShiftJIS.
00545      *
00546      * @param dropWhiteSpace In most situations, text fields containing only white spaces (and carriage returns)
00547      *     are useless. Even more, these "empty" text fields are annoying because they increase the
00548      *     complexity of the user's code for parsing. So, 99% of the time, it's better to drop
00549      *     the "empty" text fields. However The XML specification indicates that no white spaces
00550      *     should be lost when parsing the file. So to be perfectly XML-compliant, you should set
00551      *     dropWhiteSpace=0. A note of caution: if you set "dropWhiteSpace=0", the parser will be
00552      *     slower and your code will be more complex.
00553      *
00554      * @param removeCommentsInMiddleOfText To explain this parameter, let's consider this code:
00555      * \code
00556      *        XMLNode x=XMLNode::parseString("<a>foo<!-- hello -->bar<!DOCTYPE world >chu</a>","a");
00557      * \endcode
00558      *     If removeCommentsInMiddleOfText=0, then we will have:
00559      * \code
00560      *        x.getText(0) -> "foo"
00561      *        x.getText(1) -> "bar"
00562      *        x.getText(2) -> "chu"
00563      *        x.getClear(0) --> "<!-- hello -->"
00564      *        x.getClear(1) --> "<!DOCTYPE world >"
00565      * \endcode
00566      *     If removeCommentsInMiddleOfText=1, then we will have:
00567      * \code
00568      *        x.getText(0) -> "foobar"
00569      *        x.getText(1) -> "chu"
00570      *        x.getClear(0) --> "<!DOCTYPE world >"
00571      * \endcode
00572      *
00573      * \return "0" when there are no errors. If you try to set an unrecognized encoding then the return value will be "1" to signal an error.
00574      *
00575      * \note Sometime, it's useful to set "guessWideCharChars=0" to disable any conversion
00576      * because the test to detect the file-type (ASCII/UTF8/char* or WideChar) may fail (rarely). */
00577 
00578     /// Guess the character encoding of the string (ascii, utf8 or shift-JIS)
00579     static XMLCharEncoding guessCharEncoding(void *buffer, int bufLen, char useXMLEncodingAttribute=1);
00580     /**< The "guessCharEncoding" function try to guess the character encoding. You most-probably will never
00581      * have to use this function. It then returns the appropriate value of the global parameter
00582      * "characterEncoding" described in the XMLNode::setGlobalOptions. The guess is based on the content of a buffer of length
00583      * "bufLen" bytes that contains the first bytes (minimum 25 bytes; 200 bytes is a good value) of the
00584      * file to be parsed. The XMLNode::openFileHelper function is using this function to automatically compute
00585      * the value of the "characterEncoding" global parameter. There are several heuristics used to do the
00586      * guess. One of the heuristic is based on the "encoding" attribute. The original XML specifications
00587      * forbids to use this attribute to do the guess but you can still use it if you set
00588      * "useXMLEncodingAttribute" to 1 (this is the default behavior and the behavior of most parsers).
00589      * If an inconsistency in the encoding is detected, then the return value is "0". */
00590     /** @} */
00591 
00592   private:
00593       // these are functions and structures used internally by the XMLNode class (don't bother about them):
00594 
00595       typedef struct XMLNodeDataTag // to allow shallow copy and "intelligent/smart" pointers (automatic delete):
00596       {
00597           XMLCSTR                lpszName;        // Element name (=NULL if root)
00598           int                    nChild,          // Number of child nodes
00599                                  nText,           // Number of text fields
00600                                  nClear,          // Number of Clear fields (comments)
00601                                  nAttribute;      // Number of attributes
00602           char                   isDeclaration;   // Whether node is an XML declaration - '<?xml ?>'
00603           struct XMLNodeDataTag  *pParent;        // Pointer to parent element (=NULL if root)
00604           XMLNode                *pChild;         // Array of child nodes
00605           XMLCSTR                *pText;          // Array of text fields
00606           XMLClear               *pClear;         // Array of clear fields
00607           XMLAttribute           *pAttribute;     // Array of attributes
00608           int                    *pOrder;         // order of the child_nodes,text_fields,clear_fields
00609           int                    ref_count;       // for garbage collection (smart pointers)
00610       } XMLNodeData;
00611       XMLNodeData *d;
00612 
00613       char parseClearTag(void *px, void *pa);
00614       char maybeAddTxT(void *pa, XMLCSTR tokenPStr);
00615       int ParseXMLElement(void *pXML);
00616       void *addToOrder(int memInc, int *_pos, int nc, void *p, int size, XMLElementType xtype);
00617       int indexText(XMLCSTR lpszValue) const;
00618       int indexClear(XMLCSTR lpszValue) const;
00619       XMLNode addChild_priv(int,XMLSTR,char,int);
00620       XMLAttribute *addAttribute_priv(int,XMLSTR,XMLSTR);
00621       XMLCSTR addText_priv(int,XMLSTR,int);
00622       XMLClear *addClear_priv(int,XMLSTR,XMLCSTR,XMLCSTR,int);
00623       void emptyTheNode(char force);
00624       static inline XMLElementPosition findPosition(XMLNodeData *d, int index, XMLElementType xtype);
00625       static int CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, int nFormat);
00626       static int removeOrderElement(XMLNodeData *d, XMLElementType t, int index);
00627       static void exactMemory(XMLNodeData *d);
00628       static int detachFromParent(XMLNodeData *d);
00629 } XMLNode;
00630 
00631 /// This structure is given by the function XMLNode::enumContents.
00632 typedef struct XMLNodeContents
00633 {
00634     /// This dictates what's the content of the XMLNodeContent
00635     enum XMLElementType etype;
00636     /**< should be an union to access the appropriate data. Compiler does not allow union of object with constructor... too bad. */
00637     XMLNode child;
00638     XMLAttribute attrib;
00639     XMLCSTR text;
00640     XMLClear clear;
00641 
00642 } XMLNodeContents;
00643 
00644 /** @defgroup StringAlloc String Allocation/Free functions
00645  * @ingroup xmlModify
00646  * @{ */
00647 /// Duplicate (copy in a new allocated buffer) the source string.
00648 XMLDLLENTRY XMLSTR stringDup(XMLCSTR source, int cbData=-1);
00649 /**< This is
00650  * a very handy function when used with all the "XMLNode::*_WOSD" functions (\link xmlWOSD \endlink).
00651  * @param cbData If !=0 then cbData is the number of chars to duplicate. New strings allocated with
00652  * this function should be free'd using the "freeXMLString" function. */
00653 
00654 /// to free the string allocated inside the "stringDup" function or the "createXMLString" function.
00655 XMLDLLENTRY void freeXMLString(XMLSTR t); // {free(t);}
00656 /** @} */
00657 
00658 /** @defgroup atoX ato? like functions
00659  * @ingroup XMLParserGeneral
00660  * The "xmlto?" functions are equivalents to the atoi, atol, atof functions.
00661  * The only difference is: If the variable "xmlString" is NULL, than the return value
00662  * is "defautValue". These 6 functions are only here as "convenience" functions for the
00663  * user (they are not used inside the XMLparser). If you don't need them, you can
00664  * delete them without any trouble.
00665  *
00666  * @{ */
00667 XMLDLLENTRY char    xmltob(XMLCSTR xmlString,char   defautValue=0);
00668 XMLDLLENTRY int     xmltoi(XMLCSTR xmlString,int    defautValue=0);
00669 XMLDLLENTRY long    xmltol(XMLCSTR xmlString,long   defautValue=0);
00670 XMLDLLENTRY double  xmltof(XMLCSTR xmlString,double defautValue=.0);
00671 XMLDLLENTRY XMLCSTR xmltoa(XMLCSTR xmlString,XMLCSTR defautValue=_CXML(""));
00672 XMLDLLENTRY XMLCHAR xmltoc(XMLCSTR xmlString,XMLCHAR defautValue=_CXML('\0'));
00673 /** @} */
00674 
00675 /** @defgroup ToXMLStringTool Helper class to create XML files using "printf", "fprintf", "cout",... functions.
00676  * @ingroup XMLParserGeneral
00677  * @{ */
00678 /// Helper class to create XML files using "printf", "fprintf", "cout",... functions.
00679 /** The ToXMLStringTool class helps you creating XML files using "printf", "fprintf", "cout",... functions.
00680  * The "ToXMLStringTool" class is processing strings so that all the characters
00681  * &,",',<,> are replaced by their XML equivalent:
00682  * \verbatim &amp;, &quot;, &apos;, &lt;, &gt; \endverbatim
00683  * Using the "ToXMLStringTool class" and the "fprintf function" is THE most efficient
00684  * way to produce VERY large XML documents VERY fast.
00685  * \note If you are creating from scratch an XML file using the provided XMLNode class
00686  * you must not use the "ToXMLStringTool" class (because the "XMLNode" class does the
00687  * processing job for you during rendering).*/
00688 typedef struct XMLDLLENTRY ToXMLStringTool
00689 {
00690 public:
00691     ToXMLStringTool(): buf(NULL),buflen(0){}
00692     ~ToXMLStringTool();
00693     void freeBuffer();///<call this function when you have finished using this object to release memory used by the internal buffer.
00694 
00695     XMLSTR toXML(XMLCSTR source);///< returns a pointer to an internal buffer that contains a XML-encoded string based on the "source" parameter.
00696 
00697     /** The "toXMLUnSafe" function is deprecated because there is a possibility of
00698      * "destination-buffer-overflow". It converts the string
00699      * "source" to the string "dest". */
00700     static XMLSTR toXMLUnSafe(XMLSTR dest,XMLCSTR source); ///< deprecated: use "toXML" instead
00701     static int lengthXMLString(XMLCSTR source);            ///< deprecated: use "toXML" instead
00702 
00703 private:
00704     XMLSTR buf;
00705     int buflen;
00706 } ToXMLStringTool;
00707 /** @} */
00708 
00709 /** @defgroup XMLParserBase64Tool Helper class to include binary data inside XML strings using "Base64 encoding".
00710  * @ingroup XMLParserGeneral
00711  * @{ */
00712 /// Helper class to include binary data inside XML strings using "Base64 encoding".
00713 /** The "XMLParserBase64Tool" class allows you to include any binary data (images, sounds,...)
00714  * into an XML document using "Base64 encoding". This class is completely
00715  * separated from the rest of the xmlParser library and can be removed without any problem.
00716  * To include some binary data into an XML file, you must convert the binary data into
00717  * standard text (using "encode"). To retrieve the original binary data from the
00718  * b64-encoded text included inside the XML file, use "decode". Alternatively, these
00719  * functions can also be used to "encrypt/decrypt" some critical data contained inside
00720  * the XML (it's not a strong encryption at all, but sometimes it can be useful). */
00721 typedef struct XMLDLLENTRY XMLParserBase64Tool
00722 {
00723 public:
00724     XMLParserBase64Tool(): buf(NULL),buflen(0){}
00725     ~XMLParserBase64Tool();
00726     void freeBuffer();///< Call this function when you have finished using this object to release memory used by the internal buffer.
00727 
00728     /**
00729      * @param formatted If "formatted"=true, some space will be reserved for a carriage-return every 72 chars. */
00730     static int encodeLength(int inBufLen, char formatted=0); ///< return the length of the base64 string that encodes a data buffer of size inBufLen bytes.
00731 
00732     /**
00733      * The "base64Encode" function returns a string containing the base64 encoding of "inByteLen" bytes
00734      * from "inByteBuf". If "formatted" parameter is true, then there will be a carriage-return every 72 chars.
00735      * The string will be free'd when the XMLParserBase64Tool object is deleted.
00736      * All returned strings are sharing the same memory space. */
00737     XMLSTR encode(unsigned char *inByteBuf, unsigned int inByteLen, char formatted=0); ///< returns a pointer to an internal buffer containing the base64 string containing the binary data encoded from "inByteBuf"
00738 
00739     /// returns the number of bytes which will be decoded from "inString".
00740     static unsigned int decodeSize(XMLCSTR inString, XMLError *xe=NULL);
00741 
00742     /**
00743      * The "decode" function returns a pointer to a buffer containing the binary data decoded from "inString"
00744      * The output buffer will be free'd when the XMLParserBase64Tool object is deleted.
00745      * All output buffer are sharing the same memory space.
00746      * @param inString If "instring" is malformed, NULL will be returned */
00747     unsigned char* decode(XMLCSTR inString, int *outByteLen=NULL, XMLError *xe=NULL); ///< returns a pointer to an internal buffer containing the binary data decoded from "inString"
00748 
00749     /**
00750      * decodes data from "inString" to "outByteBuf". You need to provide the size (in byte) of "outByteBuf"
00751      * in "inMaxByteOutBuflen". If "outByteBuf" is not large enough or if data is malformed, then "FALSE"
00752      * will be returned; otherwise "TRUE". */
00753     static unsigned char decode(XMLCSTR inString, unsigned char *outByteBuf, int inMaxByteOutBuflen, XMLError *xe=NULL); ///< deprecated.
00754 
00755 private:
00756     void *buf;
00757     int buflen;
00758     void alloc(int newsize);
00759 }XMLParserBase64Tool;
00760 /** @} */
00761 
00762 #undef XMLDLLENTRY
00763 
00764 #endif

Generated on Fri Oct 22 2010 11:02:17 for SST by  doxygen 1.7.1