/****************************************************************************/
/*! \mainpage XMLParser library
 * \section intro_sec Introduction
 *
 * This is a basic XML parser written in ANSI C++ for portability.
 * It works by using recursion and a node tree for breaking
 * down the elements of an XML document.
 *
 * @version     V2.41
 * @author      Frank Vanden Berghen
 *
 * The following license terms for the "XMLParser library from Business-Insight" apply to projects
 * that are in some way related to
 * the "mcpat project", including applications
 * using "mcpat project" and tools developed
 * for enhancing "mcpat project". All other projects
 * (not related to "mcpat project") have to use the "XMLParser library from Business-Insight"
 * code under the Aladdin Free Public License (AFPL)
 * See the file "AFPL-license.txt" for more informations about the AFPL license.
 * (see http://www.artifex.com/downloads/doc/Public.htm for detailed AFPL terms)
 *
 * Redistribution and use of the "XMLParser library from Business-Insight" in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Frank Vanden Berghen nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Business-Insight ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Business-Insight BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Copyright (c) 2002, Business-Insight
 * Copyright (c) 2010-2013 Advanced Micro Devices, Inc.
 * <a href="http://www.Business-Insight.com">Business-Insight</a>
 * All rights reserved.
 *
 * \section tutorial First Tutorial
 * You can follow a simple <a href="../../xmlParser.html">Tutorial</a> to know the basics...
 *
 * \section usage General usage: How to include the XMLParser library inside your project.
 *
 * The library is composed of two files: <a href="../../xmlParser.cpp">xmlParser.cpp</a> and
 * <a href="../../xmlParser.h">xmlParser.h</a>. These are the ONLY 2 files that you need when
 * using the library inside your own projects.
 *
 * All the functions of the library are documented inside the comments of the file
 * <a href="../../xmlParser.h">xmlParser.h</a>. These comments can be transformed in
 * full-fledged HTML documentation using the DOXYGEN software: simply type: "doxygen doxy.cfg"
 *
 * By default, the XMLParser library uses (char*) for string representation.To use the (wchar_t*)
 * version of the library, you need to define the "_UNICODE" preprocessor definition variable
 * (this is usually done inside your project definition file) (This is done automatically for you
 * when using Visual Studio).
 *
 * \section example Advanced Tutorial and Many Examples of usage.
 *
 * Some very small introductory examples are described inside the Tutorial file
 * <a href="../../xmlParser.html">xmlParser.html</a>
 *
 * Some additional small examples are also inside the file <a href="../../xmlTest.cpp">xmlTest.cpp</a>
 * (for the "char*" version of the library) and inside the file
 * <a href="../../xmlTestUnicode.cpp">xmlTestUnicode.cpp</a> (for the "wchar_t*"
 * version of the library). If you have a question, please review these additionnal examples
 * before sending an e-mail to the author.
 *
 * To build the examples:
 * - linux/unix: type "make"
 * - solaris: type "make -f makefile.solaris"
 * - windows: Visual Studio: double-click on xmlParser.dsw
 *   (under Visual Studio .NET, the .dsp and .dsw files will be automatically converted to .vcproj and .sln files)
 *
 * In order to build the examples you need some additional files:
 * - linux/unix: makefile
 * - solaris: makefile.solaris
 * - windows: Visual Studio: *.dsp, xmlParser.dsw and also xmlParser.lib and xmlParser.dll
 *
 * \section debugging Debugging with the XMLParser library
 *
 * \subsection debugwin Debugging under WINDOWS
 *
 * 	Inside Visual C++, the "debug versions" of the memory allocation functions are
 * 	very slow: Do not forget to compile in "release mode" to get maximum speed.
 * 	When I had to debug a software that was using the XMLParser Library, it was usually
 * 	a nightmare because the library was sooOOOoooo slow in debug mode (because of the
 *  slow memory allocations in Debug mode). To solve this
 * 	problem, during all the debugging session, I am now using a very fast DLL version of the
 * 	XMLParser Library (the DLL is compiled in release mode). Using the DLL version of
 * 	the XMLParser Library allows me to have lightening XML parsing speed even in debug!
 * 	Other than that, the DLL version is useless: In the release version of my tool,
 * 	I always use the normal, ".cpp"-based, XMLParser Library (I simply include the
 * <a href="../../xmlParser.cpp">xmlParser.cpp</a> and
 * <a href="../../xmlParser.h">xmlParser.h</a> files into the project).
 *
 * 	The file <a href="../../XMLNodeAutoexp.txt">XMLNodeAutoexp.txt</a> contains some
 * "tweaks" that improve substancially the display of the content of the XMLNode objects
 * inside the Visual Studio Debugger. Believe me, once you have seen inside the debugger
 * the "smooth" display of the XMLNode objects, you cannot live without it anymore!
 *
 * \subsection debuglinux Debugging under LINUX/UNIX
 *
 * 	The speed of the debug version of the XMLParser library is tolerable so no extra
 * work.has been done.
 *
 ****************************************************************************/

#ifndef __INCLUDE_XML_NODE__
#define __INCLUDE_XML_NODE__

#include <stdlib.h>

#ifdef _UNICODE
// If you comment the next "define" line then the library will never "switch to" _UNICODE (wchar_t*) mode (16/32 bits per characters).
// This is useful when you get error messages like:
//    'XMLNode::openFileHelper' : cannot convert parameter 2 from 'const char [5]' to 'const wchar_t *'
// The _XMLWIDECHAR preprocessor variable force the XMLParser library into either utf16/32-mode (the proprocessor variable
// must be defined) or utf8-mode(the pre-processor variable must be undefined).
#define _XMLWIDECHAR
#endif

#if defined(WIN32) || defined(UNDER_CE) || defined(_WIN32) || defined(WIN64) || defined(__BORLANDC__)
// comment the next line if you are under windows and the compiler is not Microsoft Visual Studio (6.0 or .NET) or Borland
#define _XMLWINDOWS
#endif

#ifdef XMLDLLENTRY
#undef XMLDLLENTRY
#endif
#ifdef _USE_XMLPARSER_DLL
#ifdef _DLL_EXPORTS_
#define XMLDLLENTRY __declspec(dllexport)
#else
#define XMLDLLENTRY __declspec(dllimport)
#endif
#else
#define XMLDLLENTRY
#endif

// 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)
//#define XML_NO_WIDE_CHAR

#ifdef XML_NO_WIDE_CHAR
#undef _XMLWINDOWS
#undef _XMLWIDECHAR
#endif

#ifdef _XMLWINDOWS
#include <tchar.h>
#else
#define XMLDLLENTRY
#ifndef XML_NO_WIDE_CHAR
#include <wchar.h> // to have 'wcsrtombs' for ANSI version
// to have 'mbsrtowcs' for WIDECHAR version
#endif
#endif

// Some common types for char set portable code
#ifdef _XMLWIDECHAR
#define _CXML(c) L ## c
#define XMLCSTR const wchar_t *
#define XMLSTR  wchar_t *
#define XMLCHAR wchar_t
#else
#define _CXML(c) c
#define XMLCSTR const char *
#define XMLSTR  char *
#define XMLCHAR char
#endif
#ifndef FALSE
#define FALSE 0
#endif /* FALSE */
#ifndef TRUE
#define TRUE 1
#endif /* TRUE */


/// Enumeration for XML parse errors.
typedef enum XMLError {
    eXMLErrorNone = 0,
    eXMLErrorMissingEndTag,
    eXMLErrorNoXMLTagFound,
    eXMLErrorEmpty,
    eXMLErrorMissingTagName,
    eXMLErrorMissingEndTagName,
    eXMLErrorUnmatchedEndTag,
    eXMLErrorUnmatchedEndClearTag,
    eXMLErrorUnexpectedToken,
    eXMLErrorNoElements,
    eXMLErrorFileNotFound,
    eXMLErrorFirstTagNotFound,
    eXMLErrorUnknownCharacterEntity,
    eXMLErrorCharacterCodeAbove255,
    eXMLErrorCharConversionError,
    eXMLErrorCannotOpenWriteFile,
    eXMLErrorCannotWriteFile,

    eXMLErrorBase64DataSizeIsNotMultipleOf4,
    eXMLErrorBase64DecodeIllegalCharacter,
    eXMLErrorBase64DecodeTruncatedData,
    eXMLErrorBase64DecodeBufferTooSmall
} XMLError;


/// Enumeration used to manage type of data. Use in conjunction with structure XMLNodeContents
typedef enum XMLElementType {
    eNodeChild = 0,
    eNodeAttribute = 1,
    eNodeText = 2,
    eNodeClear = 3,
    eNodeNULL = 4
} XMLElementType;

/// Structure used to obtain error details if the parse fails.
typedef struct XMLResults {
    enum XMLError error;
    int nLine;
    int nColumn;
} XMLResults;

/// Structure for XML clear (unformatted) node (usually comments)
typedef struct XMLClear {
    XMLCSTR lpszValue;
    XMLCSTR lpszOpenTag;
    XMLCSTR lpszCloseTag;
} XMLClear;

/// Structure for XML attribute.
typedef struct XMLAttribute {
    XMLCSTR lpszName;
    XMLCSTR lpszValue;
} XMLAttribute;

/// XMLElementPosition are not interchangeable with simple indexes
typedef int XMLElementPosition;

struct XMLNodeContents;

/** @defgroup XMLParserGeneral The XML parser */

/// Main Class representing a XML node
/**
 * All operations are performed using this class.
 * \note The constructors of the XMLNode class are protected, so use instead one of these four methods to get your first instance of XMLNode:
 * <ul>
 *    <li> XMLNode::parseString </li>
 *    <li> XMLNode::parseFile </li>
 *    <li> XMLNode::openFileHelper </li>
 *    <li> XMLNode::createXMLTopNode (or XMLNode::createXMLTopNode_WOSD)</li>
 * </ul> */
typedef struct XMLDLLENTRY XMLNode {
private:

    struct XMLNodeDataTag;

    /// Constructors are protected, so use instead one of: XMLNode::parseString, XMLNode::parseFile, XMLNode::openFileHelper, XMLNode::createXMLTopNode
    XMLNode(struct XMLNodeDataTag *pParent, XMLSTR lpszName, char isDeclaration);
    /// Constructors are protected, so use instead one of: XMLNode::parseString, XMLNode::parseFile, XMLNode::openFileHelper, XMLNode::createXMLTopNode
    XMLNode(struct XMLNodeDataTag *p);

public:
    static XMLCSTR getVersion();///< Return the XMLParser library version number

    /** @defgroup conversions Parsing XML files/strings to an XMLNode structure and Rendering XMLNode's to files/string.
     * @ingroup XMLParserGeneral
     * @{ */

    /// Parse an XML string and return the root of a XMLNode tree representing the string.
    static XMLNode parseString(XMLCSTR lpXMLString, XMLCSTR tag = NULL,
                               XMLResults *pResults = NULL);
    /**< The "parseString" function parse an XML string and return the root of a XMLNode tree. The "opposite" of this function is
     * the function "createXMLString" that re-creates an XML string from an XMLNode tree. If the XML document is corrupted, the
     * "parseString" method will initialize the "pResults" variable with some information that can be used to trace the error.
     * If you still want to parse the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the
     * beginning of the "xmlParser.cpp" file.
     *
     * @param lpXMLString the XML string to parse
     * @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 (<? ... ?>).
     * @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.
     */

    /// Parse an XML file and return the root of a XMLNode tree representing the file.
    static XMLNode parseFile(XMLCSTR filename, XMLCSTR tag = NULL,
                             XMLResults *pResults = NULL);
    /**< The "parseFile" function parse an XML file and return the root of a XMLNode tree. The "opposite" of this function is
     * the function "writeToFile" that re-creates an XML file from an XMLNode tree. If the XML document is corrupted, the
     * "parseFile" method will initialize the "pResults" variable with some information that can be used to trace the error.
     * If you still want to parse the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the
     * beginning of the "xmlParser.cpp" file.
     *
     * @param filename the path to the XML file to parse
     * @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 (<? ... ?>).
     * @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.
     */

    /// 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.
    static XMLNode openFileHelper(XMLCSTR filename, XMLCSTR tag = NULL);
    /**< The "openFileHelper" function reports to the screen all the warnings and errors that occurred during parsing of the XML file.
     * 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
     * application has its own way to report and deal with errors, you should rather use the "parseFile" function to parse XML files
     * and program yourself thereafter an "error reporting" tailored for your needs (instead of using the very crude "error reporting"
     * mechanism included inside the "openFileHelper" function).
     *
     * If the XML document is corrupted, the "openFileHelper" method will:
     *         - display an error message on the console (or inside a messageBox for windows).
     *         - stop execution (exit).
     *
     * I strongly suggest that you write your own "openFileHelper" method tailored to your needs. If you still want to parse
     * the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the beginning of the "xmlParser.cpp" file.
     *
     * @param filename the path of the XML file to parse.
     * @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 (<? ... ?>).
     */

    static XMLCSTR getError(XMLError error); ///< this gives you a user-friendly explanation of the parsing error

    /// Create an XML string starting from the current XMLNode.
    XMLSTR createXMLString(int nFormat = 1, int *pnSize = NULL) const;
    /**< The returned string should be free'd using the "freeXMLString" function.
     *
     *   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. if pnSize is given it returns the size in character of the string. */

    /// Save the content of an xmlNode inside a file
    XMLError writeToFile(XMLCSTR filename,
                         const char *encoding = NULL,
                         char nFormat = 1) const;
    /**< 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.
     * If the global parameter "characterEncoding==encoding_UTF8", then the "encoding" parameter is ignored and always set to "utf-8".
     * If the global parameter "characterEncoding==encoding_ShiftJIS", then the "encoding" parameter is ignored and always set to "SHIFT-JIS".
     * If "_XMLWIDECHAR=1", then the "encoding" parameter is ignored and always set to "utf-16".
     * If no "encoding" parameter is given the "ISO-8859-1" encoding is used. */
    /** @} */

    /** @defgroup navigate Navigate the XMLNode structure
     * @ingroup XMLParserGeneral
     * @{ */
    XMLCSTR getName() const;                                       ///< name of the node
    XMLCSTR getText(int i=0) const;                                ///< return ith text field
    int nText() const;                                             ///< nbr of text field
    XMLNode getParentNode() const;                                 ///< return the parent node
    XMLNode getChildNode(int i=0) const;                           ///< return ith child node
    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.
    XMLNode getChildNode(XMLCSTR name, int *i=NULL) const;         ///< return next child node with specific name (return an empty node if failing)
    XMLNode* getChildNodePtr(XMLCSTR name, int *j) const;
    XMLNode getChildNodeWithAttribute(XMLCSTR tagName,
                                      XMLCSTR attributeName,
                                      XMLCSTR attributeValue=NULL,
                                      int *i=NULL)  const;         ///< return child node with specific name/attribute (return an empty node if failing)
    XMLNode getChildNodeByPath(XMLCSTR path, char createNodeIfMissing=0, XMLCHAR sep='/');
    ///< return the first child node with specific path
    XMLNode getChildNodeByPathNonConst(XMLSTR  path, char createNodeIfMissing=0, XMLCHAR sep='/');
    ///< return the first child node with specific path.

    int nChildNode(XMLCSTR name) const;                            ///< return the number of child node with specific name
    int nChildNode() const;                                        ///< nbr of child node
    XMLAttribute getAttribute(int i=0) const;                      ///< return ith attribute
    XMLCSTR      getAttributeName(int i=0) const;                  ///< return ith attribute name
    XMLCSTR      getAttributeValue(int i=0) const;                 ///< return ith attribute value
    char  isAttributeSet(XMLCSTR name) const;                      ///< test if an attribute with a specific name is given
    XMLCSTR getAttribute(XMLCSTR name, int i) const;               ///< return ith attribute content with specific name (return a NULL if failing)
    XMLCSTR getAttribute(XMLCSTR name, int *i=NULL) const;         ///< return next attribute content with specific name (return a NULL if failing)
    int nAttribute() const;                                        ///< nbr of attribute
    XMLClear getClear(int i=0) const;                              ///< return ith clear field (comments)
    int nClear() const;                                            ///< nbr of clear field
    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();
    int nElement() const;                                          ///< nbr of different contents for current node
    char isEmpty() const;                                          ///< is this node Empty?
    char isDeclaration() const;                                    ///< is this node a declaration <? .... ?>
    XMLNode deepCopy() const;                                      ///< deep copy (duplicate/clone) a XMLNode
    static XMLNode emptyNode();                                    ///< return XMLNode::emptyXMLNode;
    /** @} */

    ~XMLNode();
    XMLNode(const XMLNode &A);                                     ///< to allow shallow/fast copy:
    XMLNode& operator=( const XMLNode& A );                        ///< to allow shallow/fast copy:

    XMLNode(): d(NULL){};
    static XMLNode emptyXMLNode;
    static XMLClear emptyXMLClear;
    static XMLAttribute emptyXMLAttribute;

    /** @defgroup xmlModify Create or Update the XMLNode structure
     * @ingroup XMLParserGeneral
     *  The functions in this group allows you to create from scratch (or update) a XMLNode structure. Start by creating your top
     *  node with the "createXMLTopNode" function and then add new nodes with the "addChild" function. The parameter 'pos' gives
     *  the position where the childNode, the text or the XMLClearTag will be inserted. The default value (pos=-1) inserts at the
     *  end. The value (pos=0) insert at the beginning (Insertion at the beginning is slower than at the end). <br>
     *
     *  REMARK: 0 <= pos < nChild()+nText()+nClear() <br>
     */

    /** @defgroup creation Creating from scratch a XMLNode structure
     * @ingroup xmlModify
     * @{ */
    static XMLNode createXMLTopNode(XMLCSTR lpszName, char isDeclaration=FALSE);                    ///< Create the top node of an XMLNode structure
    XMLNode        addChild(XMLCSTR lpszName, char isDeclaration=FALSE, XMLElementPosition pos=-1); ///< Add a new child node
    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
    XMLAttribute  *addAttribute(XMLCSTR lpszName, XMLCSTR lpszValuev);                              ///< Add a new attribute
    XMLCSTR        addText(XMLCSTR lpszValue, XMLElementPosition pos=-1);                           ///< Add a new text content
    XMLClear      *addClear(XMLCSTR lpszValue, XMLCSTR lpszOpen=NULL, XMLCSTR lpszClose=NULL, XMLElementPosition pos=-1);
    /**< Add a new clear tag
     * @param lpszOpen default value "<![CDATA["
     * @param lpszClose default value "]]>"
     */
    /** @} */

    /** @defgroup xmlUpdate Updating Nodes
     * @ingroup xmlModify
     * Some update functions:
     * @{
     */
    XMLCSTR       updateName(XMLCSTR lpszName);                                                  ///< change node's name
    XMLAttribute *updateAttribute(XMLAttribute *newAttribute, XMLAttribute *oldAttribute);       ///< if the attribute to update is missing, a new one will be added
    XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName=NULL, int i=0);     ///< if the attribute to update is missing, a new one will be added
    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
    XMLCSTR       updateText(XMLCSTR lpszNewValue, int i=0);                                     ///< if the text to update is missing, a new one will be added
    XMLCSTR       updateText(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue);                        ///< if the text to update is missing, a new one will be added
    XMLClear     *updateClear(XMLCSTR lpszNewContent, int i=0);                                  ///< if the clearTag to update is missing, a new one will be added
    XMLClear     *updateClear(XMLClear *newP, XMLClear *oldP);                                   ///< if the clearTag to update is missing, a new one will be added
    XMLClear     *updateClear(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue);                       ///< if the clearTag to update is missing, a new one will be added
    /** @} */

    /** @defgroup xmlDelete Deleting Nodes or Attributes
     * @ingroup xmlModify
     * Some deletion functions:
     * @{
     */
    /// The "deleteNodeContent" function forces the deletion of the content of this XMLNode and the subtree.
    void deleteNodeContent();
    /**< \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. */
    void deleteAttribute(int i=0);                   ///< Delete the ith attribute of the current XMLNode
    void deleteAttribute(XMLCSTR lpszName);          ///< Delete the attribute with the given name (the "strcmp" function is used to find the right attribute)
    void deleteAttribute(XMLAttribute *anAttribute); ///< Delete the attribute with the name "anAttribute->lpszName" (the "strcmp" function is used to find the right attribute)
    void deleteText(int i=0);                        ///< Delete the Ith text content of the current XMLNode
    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)
    void deleteClear(int i=0);                       ///< Delete the Ith clear tag inside the current XMLNode
    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)
    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)
    /** @} */

    /** @defgroup xmlWOSD ???_WOSD functions.
     * @ingroup xmlModify
     *  The strings given as parameters for the "add" and "update" methods that have a name with
     *  the postfix "_WOSD" (that means "WithOut String Duplication")(for example "addText_WOSD")
     *  will be free'd by the XMLNode class. For example, it means that this is incorrect:
     *  \code
     *     xNode.addText_WOSD("foo");
     *     xNode.updateAttribute_WOSD("#newcolor" ,NULL,"color");
     *  \endcode
     *  In opposition, this is correct:
     *  \code
     *     xNode.addText("foo");
     *     xNode.addText_WOSD(stringDup("foo"));
     *     xNode.updateAttribute("#newcolor" ,NULL,"color");
     *     xNode.updateAttribute_WOSD(stringDup("#newcolor"),NULL,"color");
     *  \endcode
     *  Typically, you will never do:
     *  \code
     *     char *b=(char*)malloc(...);
     *     xNode.addText(b);
     *     free(b);
     *  \endcode
     *  ... but rather:
     *  \code
     *     char *b=(char*)malloc(...);
     *     xNode.addText_WOSD(b);
     *  \endcode
     *  ('free(b)' is performed by the XMLNode class)
     * @{ */
    static XMLNode createXMLTopNode_WOSD(XMLSTR lpszName, char isDeclaration=FALSE);                     ///< Create the top node of an XMLNode structure
    XMLNode        addChild_WOSD(XMLSTR lpszName, char isDeclaration=FALSE, XMLElementPosition pos=-1);  ///< Add a new child node
    XMLAttribute  *addAttribute_WOSD(XMLSTR lpszName, XMLSTR lpszValue);                                 ///< Add a new attribute
    XMLCSTR        addText_WOSD(XMLSTR lpszValue, XMLElementPosition pos=-1);                            ///< Add a new text content
    XMLClear      *addClear_WOSD(XMLSTR lpszValue, XMLCSTR lpszOpen=NULL, XMLCSTR lpszClose=NULL, XMLElementPosition pos=-1); ///< Add a new clear Tag

    XMLCSTR        updateName_WOSD(XMLSTR lpszName);                                                  ///< change node's name
    XMLAttribute  *updateAttribute_WOSD(XMLAttribute *newAttribute, XMLAttribute *oldAttribute);      ///< if the attribute to update is missing, a new one will be added
    XMLAttribute  *updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName=NULL, int i=0);       ///< if the attribute to update is missing, a new one will be added
    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
    XMLCSTR        updateText_WOSD(XMLSTR lpszNewValue, int i=0);                                     ///< if the text to update is missing, a new one will be added
    XMLCSTR        updateText_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue);                        ///< if the text to update is missing, a new one will be added
    XMLClear      *updateClear_WOSD(XMLSTR lpszNewContent, int i=0);                                  ///< if the clearTag to update is missing, a new one will be added
    XMLClear      *updateClear_WOSD(XMLClear *newP, XMLClear *oldP);                                  ///< if the clearTag to update is missing, a new one will be added
    XMLClear      *updateClear_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue);                       ///< if the clearTag to update is missing, a new one will be added
    /** @} */

    /** @defgroup xmlPosition Position helper functions (use in conjunction with the update&add functions
     * @ingroup xmlModify
     * These are some useful functions when you want to insert a childNode, a text or a XMLClearTag in the
     * middle (at a specified position) of a XMLNode tree already constructed. The value returned by these
     * methods is to be used as last parameter (parameter 'pos') of addChild, addText or addClear.
     * @{ */
    XMLElementPosition positionOfText(int i=0) const;
    XMLElementPosition positionOfText(XMLCSTR lpszValue) const;
    XMLElementPosition positionOfClear(int i=0) const;
    XMLElementPosition positionOfClear(XMLCSTR lpszValue) const;
    XMLElementPosition positionOfClear(XMLClear *a) const;
    XMLElementPosition positionOfChildNode(int i=0) const;
    XMLElementPosition positionOfChildNode(XMLNode x) const;
    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
    /** @} */

    /// Enumeration for XML character encoding.
    typedef enum XMLCharEncoding {
        char_encoding_error = 0,
        char_encoding_UTF8 = 1,
        char_encoding_legacy = 2,
        char_encoding_ShiftJIS = 3,
        char_encoding_GB2312 = 4,
        char_encoding_Big5 = 5,
        char_encoding_GBK = 6   // this is actually the same as Big5
    } XMLCharEncoding;

    /** \addtogroup conversions
     * @{ */

    /// Sets the global options for the conversions
    static char setGlobalOptions(XMLCharEncoding characterEncoding=XMLNode::char_encoding_UTF8, char guessWideCharChars=1,
                                 char dropWhiteSpace=1, char removeCommentsInMiddleOfText=1);
    /**< The "setGlobalOptions" function allows you to change four global parameters that affect string & file
     * parsing. First of all, you most-probably will never have to change these 3 global parameters.
     *
     * @param guessWideCharChars If "guessWideCharChars"=1 and if this library is compiled in WideChar mode, then the
     *     XMLNode::parseFile and XMLNode::openFileHelper functions will test if the file contains ASCII
     *     characters. If this is the case, then the file will be loaded and converted in memory to
     *     WideChar before being parsed. If 0, no conversion will be performed.
     *
     * @param guessWideCharChars If "guessWideCharChars"=1 and if this library is compiled in ASCII/UTF8/char* mode, then the
     *     XMLNode::parseFile and XMLNode::openFileHelper functions will test if the file contains WideChar
     *     characters. If this is the case, then the file will be loaded and converted in memory to
     *     ASCII/UTF8/char* before being parsed. If 0, no conversion will be performed.
     *
     * @param characterEncoding This parameter is only meaningful when compiling in char* mode (multibyte character mode).
     *     In wchar_t* (wide char mode), this parameter is ignored. This parameter should be one of the
     *     three currently recognized encodings: XMLNode::encoding_UTF8, XMLNode::encoding_ascii,
     *     XMLNode::encoding_ShiftJIS.
     *
     * @param dropWhiteSpace In most situations, text fields containing only white spaces (and carriage returns)
     *     are useless. Even more, these "empty" text fields are annoying because they increase the
     *     complexity of the user's code for parsing. So, 99% of the time, it's better to drop
     *     the "empty" text fields. However The XML specification indicates that no white spaces
     *     should be lost when parsing the file. So to be perfectly XML-compliant, you should set
     *     dropWhiteSpace=0. A note of caution: if you set "dropWhiteSpace=0", the parser will be
     *     slower and your code will be more complex.
     *
     * @param removeCommentsInMiddleOfText To explain this parameter, let's consider this code:
     * \code
     *        XMLNode x=XMLNode::parseString("<a>foo<!-- hello -->bar<!DOCTYPE world >chu</a>","a");
     * \endcode
     *     If removeCommentsInMiddleOfText=0, then we will have:
     * \code
     *        x.getText(0) -> "foo"
     *        x.getText(1) -> "bar"
     *        x.getText(2) -> "chu"
     *        x.getClear(0) --> "<!-- hello -->"
     *        x.getClear(1) --> "<!DOCTYPE world >"
     * \endcode
     *     If removeCommentsInMiddleOfText=1, then we will have:
     * \code
     *        x.getText(0) -> "foobar"
     *        x.getText(1) -> "chu"
     *        x.getClear(0) --> "<!DOCTYPE world >"
     * \endcode
     *
     * \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.
     *
     * \note Sometime, it's useful to set "guessWideCharChars=0" to disable any conversion
     * because the test to detect the file-type (ASCII/UTF8/char* or WideChar) may fail (rarely). */

    /// Guess the character encoding of the string (ascii, utf8 or shift-JIS)
    static XMLCharEncoding guessCharEncoding(void *buffer, int bufLen, char useXMLEncodingAttribute=1);
    /**< The "guessCharEncoding" function try to guess the character encoding. You most-probably will never
     * have to use this function. It then returns the appropriate value of the global parameter
     * "characterEncoding" described in the XMLNode::setGlobalOptions. The guess is based on the content of a buffer of length
     * "bufLen" bytes that contains the first bytes (minimum 25 bytes; 200 bytes is a good value) of the
     * file to be parsed. The XMLNode::openFileHelper function is using this function to automatically compute
     * the value of the "characterEncoding" global parameter. There are several heuristics used to do the
     * guess. One of the heuristic is based on the "encoding" attribute. The original XML specifications
     * forbids to use this attribute to do the guess but you can still use it if you set
     * "useXMLEncodingAttribute" to 1 (this is the default behavior and the behavior of most parsers).
     * If an inconsistency in the encoding is detected, then the return value is "0". */
    /** @} */

private:
    // these are functions and structures used internally by the XMLNode class (don't bother about them):

    typedef struct XMLNodeDataTag { // to allow shallow copy and "intelligent/smart" pointers (automatic delete):
        XMLCSTR                lpszName;        // Element name (=NULL if root)
        int                    nChild,          // Number of child nodes
        nText,           // Number of text fields
        nClear,          // Number of Clear fields (comments)
        nAttribute;      // Number of attributes
        char                   isDeclaration;   // Whether node is an XML declaration - '<?xml ?>'
        struct XMLNodeDataTag  *pParent;        // Pointer to parent element (=NULL if root)
        XMLNode                *pChild;         // Array of child nodes
        XMLCSTR                *pText;          // Array of text fields
        XMLClear               *pClear;         // Array of clear fields
        XMLAttribute           *pAttribute;     // Array of attributes
        int                    *pOrder;         // order of the child_nodes,text_fields,clear_fields
        int                    ref_count;       // for garbage collection (smart pointers)
    } XMLNodeData;
    XMLNodeData *d;

    char parseClearTag(void *px, void *pa);
    char maybeAddTxT(void *pa, XMLCSTR tokenPStr);
    int ParseXMLElement(void *pXML);
    void *addToOrder(int memInc, int *_pos, int nc, void *p, int size, XMLElementType xtype);
    int indexText(XMLCSTR lpszValue) const;
    int indexClear(XMLCSTR lpszValue) const;
    XMLNode addChild_priv(int, XMLSTR, char, int);
    XMLAttribute *addAttribute_priv(int, XMLSTR, XMLSTR);
    XMLCSTR addText_priv(int, XMLSTR, int);
    XMLClear *addClear_priv(int, XMLSTR, XMLCSTR, XMLCSTR, int);
    void emptyTheNode(char force);
    static inline XMLElementPosition findPosition(XMLNodeData *d, int index, XMLElementType xtype);
    static int CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, int nFormat);
    static int removeOrderElement(XMLNodeData *d, XMLElementType t, int index);
    static void exactMemory(XMLNodeData *d);
    static int detachFromParent(XMLNodeData *d);
} XMLNode;

/// This structure is given by the function XMLNode::enumContents.
typedef struct XMLNodeContents {
    /// This dictates what's the content of the XMLNodeContent
    enum XMLElementType etype;
    /**< should be an union to access the appropriate data. Compiler does not allow union of object with constructor... too bad. */
    XMLNode child;
    XMLAttribute attrib;
    XMLCSTR text;
    XMLClear clear;

} XMLNodeContents;

/** @defgroup StringAlloc String Allocation/Free functions
 * @ingroup xmlModify
 * @{ */
/// Duplicate (copy in a new allocated buffer) the source string.
XMLDLLENTRY XMLSTR stringDup(XMLCSTR source, int cbData=-1);
/**< This is
 * a very handy function when used with all the "XMLNode::*_WOSD" functions (\link xmlWOSD \endlink).
 * @param cbData If !=0 then cbData is the number of chars to duplicate. New strings allocated with
 * this function should be free'd using the "freeXMLString" function. */

/// to free the string allocated inside the "stringDup" function or the "createXMLString" function.
XMLDLLENTRY void freeXMLString(XMLSTR t); // {free(t);}
/** @} */

/** @defgroup atoX ato? like functions
 * @ingroup XMLParserGeneral
 * The "xmlto?" functions are equivalents to the atoi, atol, atof functions.
 * The only difference is: If the variable "xmlString" is NULL, than the return value
 * is "defautValue". These 6 functions are only here as "convenience" functions for the
 * user (they are not used inside the XMLparser). If you don't need them, you can
 * delete them without any trouble.
 *
 * @{ */
XMLDLLENTRY char    xmltob(XMLCSTR xmlString, char   defautValue=0);
XMLDLLENTRY int     xmltoi(XMLCSTR xmlString, int    defautValue=0);
XMLDLLENTRY long    xmltol(XMLCSTR xmlString, long   defautValue=0);
XMLDLLENTRY double  xmltof(XMLCSTR xmlString, double defautValue=.0);
XMLDLLENTRY XMLCSTR xmltoa(XMLCSTR xmlString, XMLCSTR defautValue=_CXML(""));
XMLDLLENTRY XMLCHAR xmltoc(XMLCSTR xmlString, XMLCHAR defautValue=_CXML('\0'));
/** @} */

/** @defgroup ToXMLStringTool Helper class to create XML files using "printf", "fprintf", "cout",... functions.
 * @ingroup XMLParserGeneral
 * @{ */
/// Helper class to create XML files using "printf", "fprintf", "cout",... functions.
/** The ToXMLStringTool class helps you creating XML files using "printf", "fprintf", "cout",... functions.
 * The "ToXMLStringTool" class is processing strings so that all the characters
 * &,",',<,> are replaced by their XML equivalent:
 * \verbatim &amp;, &quot;, &apos;, &lt;, &gt; \endverbatim
 * Using the "ToXMLStringTool class" and the "fprintf function" is THE most efficient
 * way to produce VERY large XML documents VERY fast.
 * \note If you are creating from scratch an XML file using the provided XMLNode class
 * you must not use the "ToXMLStringTool" class (because the "XMLNode" class does the
 * processing job for you during rendering).*/
typedef struct XMLDLLENTRY ToXMLStringTool {
public:
    ToXMLStringTool(): buf(NULL), buflen(0){}
    ~ToXMLStringTool();
    void freeBuffer();///<call this function when you have finished using this object to release memory used by the internal buffer.

    XMLSTR toXML(XMLCSTR source);///< returns a pointer to an internal buffer that contains a XML-encoded string based on the "source" parameter.

    /** The "toXMLUnSafe" function is deprecated because there is a possibility of
     * "destination-buffer-overflow". It converts the string
     * "source" to the string "dest". */
    static XMLSTR toXMLUnSafe(XMLSTR dest,XMLCSTR source); ///< deprecated: use "toXML" instead
    static int lengthXMLString(XMLCSTR source);            ///< deprecated: use "toXML" instead

private:
    XMLSTR buf;
    int buflen;
} ToXMLStringTool;
/** @} */

/** @defgroup XMLParserBase64Tool Helper class to include binary data inside XML strings using "Base64 encoding".
 * @ingroup XMLParserGeneral
 * @{ */
/// Helper class to include binary data inside XML strings using "Base64 encoding".
/** The "XMLParserBase64Tool" class allows you to include any binary data (images, sounds,...)
 * into an XML document using "Base64 encoding". This class is completely
 * separated from the rest of the xmlParser library and can be removed without any problem.
 * To include some binary data into an XML file, you must convert the binary data into
 * standard text (using "encode"). To retrieve the original binary data from the
 * b64-encoded text included inside the XML file, use "decode". Alternatively, these
 * functions can also be used to "encrypt/decrypt" some critical data contained inside
 * the XML (it's not a strong encryption at all, but sometimes it can be useful). */
typedef struct XMLDLLENTRY XMLParserBase64Tool {
public:
    XMLParserBase64Tool(): buf(NULL), buflen(0){}
    ~XMLParserBase64Tool();
    void freeBuffer();///< Call this function when you have finished using this object to release memory used by the internal buffer.

    /**
     * @param formatted If "formatted"=true, some space will be reserved for a carriage-return every 72 chars. */
    static int encodeLength(int inBufLen, char formatted=0); ///< return the length of the base64 string that encodes a data buffer of size inBufLen bytes.

    /**
     * The "base64Encode" function returns a string containing the base64 encoding of "inByteLen" bytes
     * from "inByteBuf". If "formatted" parameter is true, then there will be a carriage-return every 72 chars.
     * The string will be free'd when the XMLParserBase64Tool object is deleted.
     * All returned strings are sharing the same memory space. */
    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"

    /// returns the number of bytes which will be decoded from "inString".
    static unsigned int decodeSize(XMLCSTR inString, XMLError *xe=NULL);

    /**
     * The "decode" function returns a pointer to a buffer containing the binary data decoded from "inString"
     * The output buffer will be free'd when the XMLParserBase64Tool object is deleted.
     * All output buffer are sharing the same memory space.
     * @param inString If "instring" is malformed, NULL will be returned */
    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"

    /**
     * decodes data from "inString" to "outByteBuf". You need to provide the size (in byte) of "outByteBuf"
     * in "inMaxByteOutBuflen". If "outByteBuf" is not large enough or if data is malformed, then "FALSE"
     * will be returned; otherwise "TRUE". */
    static unsigned char decode(XMLCSTR inString, unsigned char *outByteBuf, int inMaxByteOutBuflen, XMLError *xe=NULL); ///< deprecated.

private:
    void *buf;
    int buflen;
    void alloc(int newsize);
}XMLParserBase64Tool;
/** @} */

#undef XMLDLLENTRY

#endif
