110152Satgutier@umich.edu/****************************************************************************/
210152Satgutier@umich.edu/*! \mainpage XMLParser library
310152Satgutier@umich.edu * \section intro_sec Introduction
410152Satgutier@umich.edu *
510152Satgutier@umich.edu * This is a basic XML parser written in ANSI C++ for portability.
610152Satgutier@umich.edu * It works by using recursion and a node tree for breaking
710152Satgutier@umich.edu * down the elements of an XML document.
810152Satgutier@umich.edu *
910152Satgutier@umich.edu * @version     V2.41
1010152Satgutier@umich.edu * @author      Frank Vanden Berghen
1110152Satgutier@umich.edu *
1210152Satgutier@umich.edu * The following license terms for the "XMLParser library from Business-Insight" apply to projects
1310152Satgutier@umich.edu * that are in some way related to
1410152Satgutier@umich.edu * the "mcpat project", including applications
1510152Satgutier@umich.edu * using "mcpat project" and tools developed
1610152Satgutier@umich.edu * for enhancing "mcpat project". All other projects
1710152Satgutier@umich.edu * (not related to "mcpat project") have to use the "XMLParser library from Business-Insight"
1810152Satgutier@umich.edu * code under the Aladdin Free Public License (AFPL)
1910152Satgutier@umich.edu * See the file "AFPL-license.txt" for more informations about the AFPL license.
2010152Satgutier@umich.edu * (see http://www.artifex.com/downloads/doc/Public.htm for detailed AFPL terms)
2110152Satgutier@umich.edu *
2210152Satgutier@umich.edu * Redistribution and use of the "XMLParser library from Business-Insight" in source and binary forms, with or without
2310152Satgutier@umich.edu * modification, are permitted provided that the following conditions are met:
2410152Satgutier@umich.edu *     * Redistributions of source code must retain the above copyright
2510152Satgutier@umich.edu *       notice, this list of conditions and the following disclaimer.
2610152Satgutier@umich.edu *     * Redistributions in binary form must reproduce the above copyright
2710152Satgutier@umich.edu *       notice, this list of conditions and the following disclaimer in the
2810152Satgutier@umich.edu *       documentation and/or other materials provided with the distribution.
2910152Satgutier@umich.edu *     * Neither the name of Frank Vanden Berghen nor the
3010152Satgutier@umich.edu *       names of its contributors may be used to endorse or promote products
3110152Satgutier@umich.edu *       derived from this software without specific prior written permission.
3210152Satgutier@umich.edu *
3310152Satgutier@umich.edu * THIS SOFTWARE IS PROVIDED BY Business-Insight ``AS IS'' AND ANY
3410152Satgutier@umich.edu * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3510152Satgutier@umich.edu * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3610152Satgutier@umich.edu * DISCLAIMED. IN NO EVENT SHALL Business-Insight BE LIABLE FOR ANY
3710152Satgutier@umich.edu * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3810152Satgutier@umich.edu * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3910152Satgutier@umich.edu * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
4010152Satgutier@umich.edu * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
4110152Satgutier@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4210152Satgutier@umich.edu * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4310152Satgutier@umich.edu *
4410152Satgutier@umich.edu * Copyright (c) 2002, Business-Insight
4510234Syasuko.eckert@amd.com * Copyright (c) 2010-2013 Advanced Micro Devices, Inc.
4610152Satgutier@umich.edu * <a href="http://www.Business-Insight.com">Business-Insight</a>
4710152Satgutier@umich.edu * All rights reserved.
4810152Satgutier@umich.edu *
4910152Satgutier@umich.edu * \section tutorial First Tutorial
5010152Satgutier@umich.edu * You can follow a simple <a href="../../xmlParser.html">Tutorial</a> to know the basics...
5110152Satgutier@umich.edu *
5210152Satgutier@umich.edu * \section usage General usage: How to include the XMLParser library inside your project.
5310152Satgutier@umich.edu *
5410152Satgutier@umich.edu * The library is composed of two files: <a href="../../xmlParser.cpp">xmlParser.cpp</a> and
5510152Satgutier@umich.edu * <a href="../../xmlParser.h">xmlParser.h</a>. These are the ONLY 2 files that you need when
5610152Satgutier@umich.edu * using the library inside your own projects.
5710152Satgutier@umich.edu *
5810152Satgutier@umich.edu * All the functions of the library are documented inside the comments of the file
5910152Satgutier@umich.edu * <a href="../../xmlParser.h">xmlParser.h</a>. These comments can be transformed in
6010152Satgutier@umich.edu * full-fledged HTML documentation using the DOXYGEN software: simply type: "doxygen doxy.cfg"
6110152Satgutier@umich.edu *
6210152Satgutier@umich.edu * By default, the XMLParser library uses (char*) for string representation.To use the (wchar_t*)
6310152Satgutier@umich.edu * version of the library, you need to define the "_UNICODE" preprocessor definition variable
6410152Satgutier@umich.edu * (this is usually done inside your project definition file) (This is done automatically for you
6510152Satgutier@umich.edu * when using Visual Studio).
6610152Satgutier@umich.edu *
6710152Satgutier@umich.edu * \section example Advanced Tutorial and Many Examples of usage.
6810152Satgutier@umich.edu *
6910152Satgutier@umich.edu * Some very small introductory examples are described inside the Tutorial file
7010152Satgutier@umich.edu * <a href="../../xmlParser.html">xmlParser.html</a>
7110152Satgutier@umich.edu *
7210152Satgutier@umich.edu * Some additional small examples are also inside the file <a href="../../xmlTest.cpp">xmlTest.cpp</a>
7310152Satgutier@umich.edu * (for the "char*" version of the library) and inside the file
7410152Satgutier@umich.edu * <a href="../../xmlTestUnicode.cpp">xmlTestUnicode.cpp</a> (for the "wchar_t*"
7510152Satgutier@umich.edu * version of the library). If you have a question, please review these additionnal examples
7610152Satgutier@umich.edu * before sending an e-mail to the author.
7710152Satgutier@umich.edu *
7810152Satgutier@umich.edu * To build the examples:
7910152Satgutier@umich.edu * - linux/unix: type "make"
8010152Satgutier@umich.edu * - solaris: type "make -f makefile.solaris"
8110152Satgutier@umich.edu * - windows: Visual Studio: double-click on xmlParser.dsw
8210152Satgutier@umich.edu *   (under Visual Studio .NET, the .dsp and .dsw files will be automatically converted to .vcproj and .sln files)
8310152Satgutier@umich.edu *
8410152Satgutier@umich.edu * In order to build the examples you need some additional files:
8510152Satgutier@umich.edu * - linux/unix: makefile
8610152Satgutier@umich.edu * - solaris: makefile.solaris
8710152Satgutier@umich.edu * - windows: Visual Studio: *.dsp, xmlParser.dsw and also xmlParser.lib and xmlParser.dll
8810152Satgutier@umich.edu *
8910152Satgutier@umich.edu * \section debugging Debugging with the XMLParser library
9010152Satgutier@umich.edu *
9110152Satgutier@umich.edu * \subsection debugwin Debugging under WINDOWS
9210152Satgutier@umich.edu *
9310152Satgutier@umich.edu * 	Inside Visual C++, the "debug versions" of the memory allocation functions are
9410152Satgutier@umich.edu * 	very slow: Do not forget to compile in "release mode" to get maximum speed.
9510152Satgutier@umich.edu * 	When I had to debug a software that was using the XMLParser Library, it was usually
9610152Satgutier@umich.edu * 	a nightmare because the library was sooOOOoooo slow in debug mode (because of the
9710152Satgutier@umich.edu *  slow memory allocations in Debug mode). To solve this
9810152Satgutier@umich.edu * 	problem, during all the debugging session, I am now using a very fast DLL version of the
9910152Satgutier@umich.edu * 	XMLParser Library (the DLL is compiled in release mode). Using the DLL version of
10010152Satgutier@umich.edu * 	the XMLParser Library allows me to have lightening XML parsing speed even in debug!
10110152Satgutier@umich.edu * 	Other than that, the DLL version is useless: In the release version of my tool,
10210152Satgutier@umich.edu * 	I always use the normal, ".cpp"-based, XMLParser Library (I simply include the
10310152Satgutier@umich.edu * <a href="../../xmlParser.cpp">xmlParser.cpp</a> and
10410152Satgutier@umich.edu * <a href="../../xmlParser.h">xmlParser.h</a> files into the project).
10510152Satgutier@umich.edu *
10610152Satgutier@umich.edu * 	The file <a href="../../XMLNodeAutoexp.txt">XMLNodeAutoexp.txt</a> contains some
10710152Satgutier@umich.edu * "tweaks" that improve substancially the display of the content of the XMLNode objects
10810152Satgutier@umich.edu * inside the Visual Studio Debugger. Believe me, once you have seen inside the debugger
10910152Satgutier@umich.edu * the "smooth" display of the XMLNode objects, you cannot live without it anymore!
11010152Satgutier@umich.edu *
11110152Satgutier@umich.edu * \subsection debuglinux Debugging under LINUX/UNIX
11210152Satgutier@umich.edu *
11310152Satgutier@umich.edu * 	The speed of the debug version of the XMLParser library is tolerable so no extra
11410152Satgutier@umich.edu * work.has been done.
11510152Satgutier@umich.edu *
11610152Satgutier@umich.edu ****************************************************************************/
11710152Satgutier@umich.edu
11810152Satgutier@umich.edu#ifndef __INCLUDE_XML_NODE__
11910152Satgutier@umich.edu#define __INCLUDE_XML_NODE__
12010152Satgutier@umich.edu
12110152Satgutier@umich.edu#include <stdlib.h>
12210152Satgutier@umich.edu
12310152Satgutier@umich.edu#ifdef _UNICODE
12410152Satgutier@umich.edu// If you comment the next "define" line then the library will never "switch to" _UNICODE (wchar_t*) mode (16/32 bits per characters).
12510152Satgutier@umich.edu// This is useful when you get error messages like:
12610152Satgutier@umich.edu//    'XMLNode::openFileHelper' : cannot convert parameter 2 from 'const char [5]' to 'const wchar_t *'
12710152Satgutier@umich.edu// The _XMLWIDECHAR preprocessor variable force the XMLParser library into either utf16/32-mode (the proprocessor variable
12810152Satgutier@umich.edu// must be defined) or utf8-mode(the pre-processor variable must be undefined).
12910152Satgutier@umich.edu#define _XMLWIDECHAR
13010152Satgutier@umich.edu#endif
13110152Satgutier@umich.edu
13210152Satgutier@umich.edu#if defined(WIN32) || defined(UNDER_CE) || defined(_WIN32) || defined(WIN64) || defined(__BORLANDC__)
13310152Satgutier@umich.edu// comment the next line if you are under windows and the compiler is not Microsoft Visual Studio (6.0 or .NET) or Borland
13410152Satgutier@umich.edu#define _XMLWINDOWS
13510152Satgutier@umich.edu#endif
13610152Satgutier@umich.edu
13710152Satgutier@umich.edu#ifdef XMLDLLENTRY
13810152Satgutier@umich.edu#undef XMLDLLENTRY
13910152Satgutier@umich.edu#endif
14010152Satgutier@umich.edu#ifdef _USE_XMLPARSER_DLL
14110152Satgutier@umich.edu#ifdef _DLL_EXPORTS_
14210152Satgutier@umich.edu#define XMLDLLENTRY __declspec(dllexport)
14310152Satgutier@umich.edu#else
14410152Satgutier@umich.edu#define XMLDLLENTRY __declspec(dllimport)
14510152Satgutier@umich.edu#endif
14610152Satgutier@umich.edu#else
14710152Satgutier@umich.edu#define XMLDLLENTRY
14810152Satgutier@umich.edu#endif
14910152Satgutier@umich.edu
15010152Satgutier@umich.edu// 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)
15110152Satgutier@umich.edu//#define XML_NO_WIDE_CHAR
15210152Satgutier@umich.edu
15310152Satgutier@umich.edu#ifdef XML_NO_WIDE_CHAR
15410152Satgutier@umich.edu#undef _XMLWINDOWS
15510152Satgutier@umich.edu#undef _XMLWIDECHAR
15610152Satgutier@umich.edu#endif
15710152Satgutier@umich.edu
15810152Satgutier@umich.edu#ifdef _XMLWINDOWS
15910152Satgutier@umich.edu#include <tchar.h>
16010152Satgutier@umich.edu#else
16110152Satgutier@umich.edu#define XMLDLLENTRY
16210152Satgutier@umich.edu#ifndef XML_NO_WIDE_CHAR
16310152Satgutier@umich.edu#include <wchar.h> // to have 'wcsrtombs' for ANSI version
16410234Syasuko.eckert@amd.com// to have 'mbsrtowcs' for WIDECHAR version
16510152Satgutier@umich.edu#endif
16610152Satgutier@umich.edu#endif
16710152Satgutier@umich.edu
16810152Satgutier@umich.edu// Some common types for char set portable code
16910152Satgutier@umich.edu#ifdef _XMLWIDECHAR
17010234Syasuko.eckert@amd.com#define _CXML(c) L ## c
17110234Syasuko.eckert@amd.com#define XMLCSTR const wchar_t *
17210234Syasuko.eckert@amd.com#define XMLSTR  wchar_t *
17310234Syasuko.eckert@amd.com#define XMLCHAR wchar_t
17410152Satgutier@umich.edu#else
17510234Syasuko.eckert@amd.com#define _CXML(c) c
17610234Syasuko.eckert@amd.com#define XMLCSTR const char *
17710234Syasuko.eckert@amd.com#define XMLSTR  char *
17810234Syasuko.eckert@amd.com#define XMLCHAR char
17910152Satgutier@umich.edu#endif
18010152Satgutier@umich.edu#ifndef FALSE
18110234Syasuko.eckert@amd.com#define FALSE 0
18210152Satgutier@umich.edu#endif /* FALSE */
18310152Satgutier@umich.edu#ifndef TRUE
18410234Syasuko.eckert@amd.com#define TRUE 1
18510152Satgutier@umich.edu#endif /* TRUE */
18610152Satgutier@umich.edu
18710152Satgutier@umich.edu
18810152Satgutier@umich.edu/// Enumeration for XML parse errors.
18910234Syasuko.eckert@amd.comtypedef enum XMLError {
19010152Satgutier@umich.edu    eXMLErrorNone = 0,
19110152Satgutier@umich.edu    eXMLErrorMissingEndTag,
19210152Satgutier@umich.edu    eXMLErrorNoXMLTagFound,
19310152Satgutier@umich.edu    eXMLErrorEmpty,
19410152Satgutier@umich.edu    eXMLErrorMissingTagName,
19510152Satgutier@umich.edu    eXMLErrorMissingEndTagName,
19610152Satgutier@umich.edu    eXMLErrorUnmatchedEndTag,
19710152Satgutier@umich.edu    eXMLErrorUnmatchedEndClearTag,
19810152Satgutier@umich.edu    eXMLErrorUnexpectedToken,
19910152Satgutier@umich.edu    eXMLErrorNoElements,
20010152Satgutier@umich.edu    eXMLErrorFileNotFound,
20110152Satgutier@umich.edu    eXMLErrorFirstTagNotFound,
20210152Satgutier@umich.edu    eXMLErrorUnknownCharacterEntity,
20310152Satgutier@umich.edu    eXMLErrorCharacterCodeAbove255,
20410152Satgutier@umich.edu    eXMLErrorCharConversionError,
20510152Satgutier@umich.edu    eXMLErrorCannotOpenWriteFile,
20610152Satgutier@umich.edu    eXMLErrorCannotWriteFile,
20710152Satgutier@umich.edu
20810152Satgutier@umich.edu    eXMLErrorBase64DataSizeIsNotMultipleOf4,
20910152Satgutier@umich.edu    eXMLErrorBase64DecodeIllegalCharacter,
21010152Satgutier@umich.edu    eXMLErrorBase64DecodeTruncatedData,
21110152Satgutier@umich.edu    eXMLErrorBase64DecodeBufferTooSmall
21210152Satgutier@umich.edu} XMLError;
21310152Satgutier@umich.edu
21410152Satgutier@umich.edu
21510152Satgutier@umich.edu/// Enumeration used to manage type of data. Use in conjunction with structure XMLNodeContents
21610234Syasuko.eckert@amd.comtypedef enum XMLElementType {
21710234Syasuko.eckert@amd.com    eNodeChild = 0,
21810234Syasuko.eckert@amd.com    eNodeAttribute = 1,
21910234Syasuko.eckert@amd.com    eNodeText = 2,
22010234Syasuko.eckert@amd.com    eNodeClear = 3,
22110234Syasuko.eckert@amd.com    eNodeNULL = 4
22210152Satgutier@umich.edu} XMLElementType;
22310152Satgutier@umich.edu
22410152Satgutier@umich.edu/// Structure used to obtain error details if the parse fails.
22510234Syasuko.eckert@amd.comtypedef struct XMLResults {
22610152Satgutier@umich.edu    enum XMLError error;
22710234Syasuko.eckert@amd.com    int nLine;
22810234Syasuko.eckert@amd.com    int nColumn;
22910152Satgutier@umich.edu} XMLResults;
23010152Satgutier@umich.edu
23110152Satgutier@umich.edu/// Structure for XML clear (unformatted) node (usually comments)
23210152Satgutier@umich.edutypedef struct XMLClear {
23310234Syasuko.eckert@amd.com    XMLCSTR lpszValue;
23410234Syasuko.eckert@amd.com    XMLCSTR lpszOpenTag;
23510234Syasuko.eckert@amd.com    XMLCSTR lpszCloseTag;
23610152Satgutier@umich.edu} XMLClear;
23710152Satgutier@umich.edu
23810152Satgutier@umich.edu/// Structure for XML attribute.
23910152Satgutier@umich.edutypedef struct XMLAttribute {
24010234Syasuko.eckert@amd.com    XMLCSTR lpszName;
24110234Syasuko.eckert@amd.com    XMLCSTR lpszValue;
24210152Satgutier@umich.edu} XMLAttribute;
24310152Satgutier@umich.edu
24410152Satgutier@umich.edu/// XMLElementPosition are not interchangeable with simple indexes
24510152Satgutier@umich.edutypedef int XMLElementPosition;
24610152Satgutier@umich.edu
24710152Satgutier@umich.edustruct XMLNodeContents;
24810152Satgutier@umich.edu
24910152Satgutier@umich.edu/** @defgroup XMLParserGeneral The XML parser */
25010152Satgutier@umich.edu
25110152Satgutier@umich.edu/// Main Class representing a XML node
25210152Satgutier@umich.edu/**
25310152Satgutier@umich.edu * All operations are performed using this class.
25410152Satgutier@umich.edu * \note The constructors of the XMLNode class are protected, so use instead one of these four methods to get your first instance of XMLNode:
25510152Satgutier@umich.edu * <ul>
25610152Satgutier@umich.edu *    <li> XMLNode::parseString </li>
25710152Satgutier@umich.edu *    <li> XMLNode::parseFile </li>
25810152Satgutier@umich.edu *    <li> XMLNode::openFileHelper </li>
25910152Satgutier@umich.edu *    <li> XMLNode::createXMLTopNode (or XMLNode::createXMLTopNode_WOSD)</li>
26010152Satgutier@umich.edu * </ul> */
26110234Syasuko.eckert@amd.comtypedef struct XMLDLLENTRY XMLNode {
26210234Syasuko.eckert@amd.comprivate:
26310152Satgutier@umich.edu
26410152Satgutier@umich.edu    struct XMLNodeDataTag;
26510152Satgutier@umich.edu
26610152Satgutier@umich.edu    /// Constructors are protected, so use instead one of: XMLNode::parseString, XMLNode::parseFile, XMLNode::openFileHelper, XMLNode::createXMLTopNode
26710152Satgutier@umich.edu    XMLNode(struct XMLNodeDataTag *pParent, XMLSTR lpszName, char isDeclaration);
26810152Satgutier@umich.edu    /// Constructors are protected, so use instead one of: XMLNode::parseString, XMLNode::parseFile, XMLNode::openFileHelper, XMLNode::createXMLTopNode
26910152Satgutier@umich.edu    XMLNode(struct XMLNodeDataTag *p);
27010152Satgutier@umich.edu
27110234Syasuko.eckert@amd.compublic:
27210152Satgutier@umich.edu    static XMLCSTR getVersion();///< Return the XMLParser library version number
27310152Satgutier@umich.edu
27410152Satgutier@umich.edu    /** @defgroup conversions Parsing XML files/strings to an XMLNode structure and Rendering XMLNode's to files/string.
27510152Satgutier@umich.edu     * @ingroup XMLParserGeneral
27610152Satgutier@umich.edu     * @{ */
27710152Satgutier@umich.edu
27810152Satgutier@umich.edu    /// Parse an XML string and return the root of a XMLNode tree representing the string.
27910234Syasuko.eckert@amd.com    static XMLNode parseString(XMLCSTR lpXMLString, XMLCSTR tag = NULL,
28010234Syasuko.eckert@amd.com                               XMLResults *pResults = NULL);
28110152Satgutier@umich.edu    /**< The "parseString" function parse an XML string and return the root of a XMLNode tree. The "opposite" of this function is
28210152Satgutier@umich.edu     * the function "createXMLString" that re-creates an XML string from an XMLNode tree. If the XML document is corrupted, the
28310152Satgutier@umich.edu     * "parseString" method will initialize the "pResults" variable with some information that can be used to trace the error.
28410152Satgutier@umich.edu     * If you still want to parse the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the
28510152Satgutier@umich.edu     * beginning of the "xmlParser.cpp" file.
28610152Satgutier@umich.edu     *
28710152Satgutier@umich.edu     * @param lpXMLString the XML string to parse
28810152Satgutier@umich.edu     * @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 (<? ... ?>).
28910152Satgutier@umich.edu     * @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.
29010152Satgutier@umich.edu     */
29110152Satgutier@umich.edu
29210152Satgutier@umich.edu    /// Parse an XML file and return the root of a XMLNode tree representing the file.
29310234Syasuko.eckert@amd.com    static XMLNode parseFile(XMLCSTR filename, XMLCSTR tag = NULL,
29410234Syasuko.eckert@amd.com                             XMLResults *pResults = NULL);
29510152Satgutier@umich.edu    /**< The "parseFile" function parse an XML file and return the root of a XMLNode tree. The "opposite" of this function is
29610152Satgutier@umich.edu     * the function "writeToFile" that re-creates an XML file from an XMLNode tree. If the XML document is corrupted, the
29710152Satgutier@umich.edu     * "parseFile" method will initialize the "pResults" variable with some information that can be used to trace the error.
29810152Satgutier@umich.edu     * If you still want to parse the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the
29910152Satgutier@umich.edu     * beginning of the "xmlParser.cpp" file.
30010152Satgutier@umich.edu     *
30110152Satgutier@umich.edu     * @param filename the path to the XML file to parse
30210152Satgutier@umich.edu     * @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 (<? ... ?>).
30310152Satgutier@umich.edu     * @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.
30410152Satgutier@umich.edu     */
30510152Satgutier@umich.edu
30610152Satgutier@umich.edu    /// 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.
30710234Syasuko.eckert@amd.com    static XMLNode openFileHelper(XMLCSTR filename, XMLCSTR tag = NULL);
30810152Satgutier@umich.edu    /**< The "openFileHelper" function reports to the screen all the warnings and errors that occurred during parsing of the XML file.
30910152Satgutier@umich.edu     * 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
31010152Satgutier@umich.edu     * application has its own way to report and deal with errors, you should rather use the "parseFile" function to parse XML files
31110152Satgutier@umich.edu     * and program yourself thereafter an "error reporting" tailored for your needs (instead of using the very crude "error reporting"
31210152Satgutier@umich.edu     * mechanism included inside the "openFileHelper" function).
31310152Satgutier@umich.edu     *
31410152Satgutier@umich.edu     * If the XML document is corrupted, the "openFileHelper" method will:
31510152Satgutier@umich.edu     *         - display an error message on the console (or inside a messageBox for windows).
31610152Satgutier@umich.edu     *         - stop execution (exit).
31710152Satgutier@umich.edu     *
31810152Satgutier@umich.edu     * I strongly suggest that you write your own "openFileHelper" method tailored to your needs. If you still want to parse
31910152Satgutier@umich.edu     * the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the beginning of the "xmlParser.cpp" file.
32010152Satgutier@umich.edu     *
32110152Satgutier@umich.edu     * @param filename the path of the XML file to parse.
32210152Satgutier@umich.edu     * @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 (<? ... ?>).
32310152Satgutier@umich.edu     */
32410152Satgutier@umich.edu
32510152Satgutier@umich.edu    static XMLCSTR getError(XMLError error); ///< this gives you a user-friendly explanation of the parsing error
32610152Satgutier@umich.edu
32710152Satgutier@umich.edu    /// Create an XML string starting from the current XMLNode.
32810234Syasuko.eckert@amd.com    XMLSTR createXMLString(int nFormat = 1, int *pnSize = NULL) const;
32910152Satgutier@umich.edu    /**< The returned string should be free'd using the "freeXMLString" function.
33010152Satgutier@umich.edu     *
33110152Satgutier@umich.edu     *   If nFormat==0, no formatting is required otherwise this returns an user friendly XML string from a given element
33210152Satgutier@umich.edu     *   with appropriate white spaces and carriage returns. if pnSize is given it returns the size in character of the string. */
33310152Satgutier@umich.edu
33410152Satgutier@umich.edu    /// Save the content of an xmlNode inside a file
33510152Satgutier@umich.edu    XMLError writeToFile(XMLCSTR filename,
33610234Syasuko.eckert@amd.com                         const char *encoding = NULL,
33710234Syasuko.eckert@amd.com                         char nFormat = 1) const;
33810152Satgutier@umich.edu    /**< 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.
33910152Satgutier@umich.edu     * If the global parameter "characterEncoding==encoding_UTF8", then the "encoding" parameter is ignored and always set to "utf-8".
34010152Satgutier@umich.edu     * If the global parameter "characterEncoding==encoding_ShiftJIS", then the "encoding" parameter is ignored and always set to "SHIFT-JIS".
34110152Satgutier@umich.edu     * If "_XMLWIDECHAR=1", then the "encoding" parameter is ignored and always set to "utf-16".
34210152Satgutier@umich.edu     * If no "encoding" parameter is given the "ISO-8859-1" encoding is used. */
34310152Satgutier@umich.edu    /** @} */
34410152Satgutier@umich.edu
34510152Satgutier@umich.edu    /** @defgroup navigate Navigate the XMLNode structure
34610152Satgutier@umich.edu     * @ingroup XMLParserGeneral
34710152Satgutier@umich.edu     * @{ */
34810152Satgutier@umich.edu    XMLCSTR getName() const;                                       ///< name of the node
34910152Satgutier@umich.edu    XMLCSTR getText(int i=0) const;                                ///< return ith text field
35010152Satgutier@umich.edu    int nText() const;                                             ///< nbr of text field
35110152Satgutier@umich.edu    XMLNode getParentNode() const;                                 ///< return the parent node
35210152Satgutier@umich.edu    XMLNode getChildNode(int i=0) const;                           ///< return ith child node
35310152Satgutier@umich.edu    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.
35410152Satgutier@umich.edu    XMLNode getChildNode(XMLCSTR name, int *i=NULL) const;         ///< return next child node with specific name (return an empty node if failing)
35510234Syasuko.eckert@amd.com    XMLNode* getChildNodePtr(XMLCSTR name, int *j) const;
35610152Satgutier@umich.edu    XMLNode getChildNodeWithAttribute(XMLCSTR tagName,
35710152Satgutier@umich.edu                                      XMLCSTR attributeName,
35810152Satgutier@umich.edu                                      XMLCSTR attributeValue=NULL,
35910152Satgutier@umich.edu                                      int *i=NULL)  const;         ///< return child node with specific name/attribute (return an empty node if failing)
36010152Satgutier@umich.edu    XMLNode getChildNodeByPath(XMLCSTR path, char createNodeIfMissing=0, XMLCHAR sep='/');
36110234Syasuko.eckert@amd.com    ///< return the first child node with specific path
36210152Satgutier@umich.edu    XMLNode getChildNodeByPathNonConst(XMLSTR  path, char createNodeIfMissing=0, XMLCHAR sep='/');
36310234Syasuko.eckert@amd.com    ///< return the first child node with specific path.
36410152Satgutier@umich.edu
36510152Satgutier@umich.edu    int nChildNode(XMLCSTR name) const;                            ///< return the number of child node with specific name
36610152Satgutier@umich.edu    int nChildNode() const;                                        ///< nbr of child node
36710152Satgutier@umich.edu    XMLAttribute getAttribute(int i=0) const;                      ///< return ith attribute
36810152Satgutier@umich.edu    XMLCSTR      getAttributeName(int i=0) const;                  ///< return ith attribute name
36910152Satgutier@umich.edu    XMLCSTR      getAttributeValue(int i=0) const;                 ///< return ith attribute value
37010152Satgutier@umich.edu    char  isAttributeSet(XMLCSTR name) const;                      ///< test if an attribute with a specific name is given
37110152Satgutier@umich.edu    XMLCSTR getAttribute(XMLCSTR name, int i) const;               ///< return ith attribute content with specific name (return a NULL if failing)
37210152Satgutier@umich.edu    XMLCSTR getAttribute(XMLCSTR name, int *i=NULL) const;         ///< return next attribute content with specific name (return a NULL if failing)
37310152Satgutier@umich.edu    int nAttribute() const;                                        ///< nbr of attribute
37410152Satgutier@umich.edu    XMLClear getClear(int i=0) const;                              ///< return ith clear field (comments)
37510152Satgutier@umich.edu    int nClear() const;                                            ///< nbr of clear field
37610152Satgutier@umich.edu    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();
37710152Satgutier@umich.edu    int nElement() const;                                          ///< nbr of different contents for current node
37810152Satgutier@umich.edu    char isEmpty() const;                                          ///< is this node Empty?
37910152Satgutier@umich.edu    char isDeclaration() const;                                    ///< is this node a declaration <? .... ?>
38010152Satgutier@umich.edu    XMLNode deepCopy() const;                                      ///< deep copy (duplicate/clone) a XMLNode
38110152Satgutier@umich.edu    static XMLNode emptyNode();                                    ///< return XMLNode::emptyXMLNode;
38210152Satgutier@umich.edu    /** @} */
38310152Satgutier@umich.edu
38410152Satgutier@umich.edu    ~XMLNode();
38510152Satgutier@umich.edu    XMLNode(const XMLNode &A);                                     ///< to allow shallow/fast copy:
38610152Satgutier@umich.edu    XMLNode& operator=( const XMLNode& A );                        ///< to allow shallow/fast copy:
38710152Satgutier@umich.edu
38810152Satgutier@umich.edu    XMLNode(): d(NULL){};
38910152Satgutier@umich.edu    static XMLNode emptyXMLNode;
39010152Satgutier@umich.edu    static XMLClear emptyXMLClear;
39110152Satgutier@umich.edu    static XMLAttribute emptyXMLAttribute;
39210152Satgutier@umich.edu
39310152Satgutier@umich.edu    /** @defgroup xmlModify Create or Update the XMLNode structure
39410152Satgutier@umich.edu     * @ingroup XMLParserGeneral
39510152Satgutier@umich.edu     *  The functions in this group allows you to create from scratch (or update) a XMLNode structure. Start by creating your top
39610152Satgutier@umich.edu     *  node with the "createXMLTopNode" function and then add new nodes with the "addChild" function. The parameter 'pos' gives
39710152Satgutier@umich.edu     *  the position where the childNode, the text or the XMLClearTag will be inserted. The default value (pos=-1) inserts at the
39810152Satgutier@umich.edu     *  end. The value (pos=0) insert at the beginning (Insertion at the beginning is slower than at the end). <br>
39910152Satgutier@umich.edu     *
40010152Satgutier@umich.edu     *  REMARK: 0 <= pos < nChild()+nText()+nClear() <br>
40110152Satgutier@umich.edu     */
40210152Satgutier@umich.edu
40310152Satgutier@umich.edu    /** @defgroup creation Creating from scratch a XMLNode structure
40410152Satgutier@umich.edu     * @ingroup xmlModify
40510152Satgutier@umich.edu     * @{ */
40610152Satgutier@umich.edu    static XMLNode createXMLTopNode(XMLCSTR lpszName, char isDeclaration=FALSE);                    ///< Create the top node of an XMLNode structure
40710152Satgutier@umich.edu    XMLNode        addChild(XMLCSTR lpszName, char isDeclaration=FALSE, XMLElementPosition pos=-1); ///< Add a new child node
40810152Satgutier@umich.edu    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
40910152Satgutier@umich.edu    XMLAttribute  *addAttribute(XMLCSTR lpszName, XMLCSTR lpszValuev);                              ///< Add a new attribute
41010152Satgutier@umich.edu    XMLCSTR        addText(XMLCSTR lpszValue, XMLElementPosition pos=-1);                           ///< Add a new text content
41110152Satgutier@umich.edu    XMLClear      *addClear(XMLCSTR lpszValue, XMLCSTR lpszOpen=NULL, XMLCSTR lpszClose=NULL, XMLElementPosition pos=-1);
41210152Satgutier@umich.edu    /**< Add a new clear tag
41310152Satgutier@umich.edu     * @param lpszOpen default value "<![CDATA["
41410152Satgutier@umich.edu     * @param lpszClose default value "]]>"
41510152Satgutier@umich.edu     */
41610152Satgutier@umich.edu    /** @} */
41710152Satgutier@umich.edu
41810152Satgutier@umich.edu    /** @defgroup xmlUpdate Updating Nodes
41910152Satgutier@umich.edu     * @ingroup xmlModify
42010152Satgutier@umich.edu     * Some update functions:
42110152Satgutier@umich.edu     * @{
42210152Satgutier@umich.edu     */
42310152Satgutier@umich.edu    XMLCSTR       updateName(XMLCSTR lpszName);                                                  ///< change node's name
42410152Satgutier@umich.edu    XMLAttribute *updateAttribute(XMLAttribute *newAttribute, XMLAttribute *oldAttribute);       ///< if the attribute to update is missing, a new one will be added
42510234Syasuko.eckert@amd.com    XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName=NULL, int i=0);     ///< if the attribute to update is missing, a new one will be added
42610234Syasuko.eckert@amd.com    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
42710152Satgutier@umich.edu    XMLCSTR       updateText(XMLCSTR lpszNewValue, int i=0);                                     ///< if the text to update is missing, a new one will be added
42810152Satgutier@umich.edu    XMLCSTR       updateText(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue);                        ///< if the text to update is missing, a new one will be added
42910152Satgutier@umich.edu    XMLClear     *updateClear(XMLCSTR lpszNewContent, int i=0);                                  ///< if the clearTag to update is missing, a new one will be added
43010234Syasuko.eckert@amd.com    XMLClear     *updateClear(XMLClear *newP, XMLClear *oldP);                                   ///< if the clearTag to update is missing, a new one will be added
43110152Satgutier@umich.edu    XMLClear     *updateClear(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue);                       ///< if the clearTag to update is missing, a new one will be added
43210152Satgutier@umich.edu    /** @} */
43310152Satgutier@umich.edu
43410152Satgutier@umich.edu    /** @defgroup xmlDelete Deleting Nodes or Attributes
43510152Satgutier@umich.edu     * @ingroup xmlModify
43610152Satgutier@umich.edu     * Some deletion functions:
43710152Satgutier@umich.edu     * @{
43810152Satgutier@umich.edu     */
43910152Satgutier@umich.edu    /// The "deleteNodeContent" function forces the deletion of the content of this XMLNode and the subtree.
44010152Satgutier@umich.edu    void deleteNodeContent();
44110152Satgutier@umich.edu    /**< \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. */
44210152Satgutier@umich.edu    void deleteAttribute(int i=0);                   ///< Delete the ith attribute of the current XMLNode
44310152Satgutier@umich.edu    void deleteAttribute(XMLCSTR lpszName);          ///< Delete the attribute with the given name (the "strcmp" function is used to find the right attribute)
44410152Satgutier@umich.edu    void deleteAttribute(XMLAttribute *anAttribute); ///< Delete the attribute with the name "anAttribute->lpszName" (the "strcmp" function is used to find the right attribute)
44510152Satgutier@umich.edu    void deleteText(int i=0);                        ///< Delete the Ith text content of the current XMLNode
44610152Satgutier@umich.edu    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)
44710152Satgutier@umich.edu    void deleteClear(int i=0);                       ///< Delete the Ith clear tag inside the current XMLNode
44810152Satgutier@umich.edu    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)
44910152Satgutier@umich.edu    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)
45010152Satgutier@umich.edu    /** @} */
45110152Satgutier@umich.edu
45210152Satgutier@umich.edu    /** @defgroup xmlWOSD ???_WOSD functions.
45310152Satgutier@umich.edu     * @ingroup xmlModify
45410152Satgutier@umich.edu     *  The strings given as parameters for the "add" and "update" methods that have a name with
45510152Satgutier@umich.edu     *  the postfix "_WOSD" (that means "WithOut String Duplication")(for example "addText_WOSD")
45610152Satgutier@umich.edu     *  will be free'd by the XMLNode class. For example, it means that this is incorrect:
45710152Satgutier@umich.edu     *  \code
45810152Satgutier@umich.edu     *     xNode.addText_WOSD("foo");
45910152Satgutier@umich.edu     *     xNode.updateAttribute_WOSD("#newcolor" ,NULL,"color");
46010152Satgutier@umich.edu     *  \endcode
46110152Satgutier@umich.edu     *  In opposition, this is correct:
46210152Satgutier@umich.edu     *  \code
46310152Satgutier@umich.edu     *     xNode.addText("foo");
46410152Satgutier@umich.edu     *     xNode.addText_WOSD(stringDup("foo"));
46510152Satgutier@umich.edu     *     xNode.updateAttribute("#newcolor" ,NULL,"color");
46610152Satgutier@umich.edu     *     xNode.updateAttribute_WOSD(stringDup("#newcolor"),NULL,"color");
46710152Satgutier@umich.edu     *  \endcode
46810152Satgutier@umich.edu     *  Typically, you will never do:
46910152Satgutier@umich.edu     *  \code
47010152Satgutier@umich.edu     *     char *b=(char*)malloc(...);
47110152Satgutier@umich.edu     *     xNode.addText(b);
47210152Satgutier@umich.edu     *     free(b);
47310152Satgutier@umich.edu     *  \endcode
47410152Satgutier@umich.edu     *  ... but rather:
47510152Satgutier@umich.edu     *  \code
47610152Satgutier@umich.edu     *     char *b=(char*)malloc(...);
47710152Satgutier@umich.edu     *     xNode.addText_WOSD(b);
47810152Satgutier@umich.edu     *  \endcode
47910152Satgutier@umich.edu     *  ('free(b)' is performed by the XMLNode class)
48010152Satgutier@umich.edu     * @{ */
48110152Satgutier@umich.edu    static XMLNode createXMLTopNode_WOSD(XMLSTR lpszName, char isDeclaration=FALSE);                     ///< Create the top node of an XMLNode structure
48210152Satgutier@umich.edu    XMLNode        addChild_WOSD(XMLSTR lpszName, char isDeclaration=FALSE, XMLElementPosition pos=-1);  ///< Add a new child node
48310152Satgutier@umich.edu    XMLAttribute  *addAttribute_WOSD(XMLSTR lpszName, XMLSTR lpszValue);                                 ///< Add a new attribute
48410152Satgutier@umich.edu    XMLCSTR        addText_WOSD(XMLSTR lpszValue, XMLElementPosition pos=-1);                            ///< Add a new text content
48510152Satgutier@umich.edu    XMLClear      *addClear_WOSD(XMLSTR lpszValue, XMLCSTR lpszOpen=NULL, XMLCSTR lpszClose=NULL, XMLElementPosition pos=-1); ///< Add a new clear Tag
48610152Satgutier@umich.edu
48710152Satgutier@umich.edu    XMLCSTR        updateName_WOSD(XMLSTR lpszName);                                                  ///< change node's name
48810152Satgutier@umich.edu    XMLAttribute  *updateAttribute_WOSD(XMLAttribute *newAttribute, XMLAttribute *oldAttribute);      ///< if the attribute to update is missing, a new one will be added
48910234Syasuko.eckert@amd.com    XMLAttribute  *updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName=NULL, int i=0);       ///< if the attribute to update is missing, a new one will be added
49010234Syasuko.eckert@amd.com    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
49110152Satgutier@umich.edu    XMLCSTR        updateText_WOSD(XMLSTR lpszNewValue, int i=0);                                     ///< if the text to update is missing, a new one will be added
49210152Satgutier@umich.edu    XMLCSTR        updateText_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue);                        ///< if the text to update is missing, a new one will be added
49310152Satgutier@umich.edu    XMLClear      *updateClear_WOSD(XMLSTR lpszNewContent, int i=0);                                  ///< if the clearTag to update is missing, a new one will be added
49410234Syasuko.eckert@amd.com    XMLClear      *updateClear_WOSD(XMLClear *newP, XMLClear *oldP);                                  ///< if the clearTag to update is missing, a new one will be added
49510152Satgutier@umich.edu    XMLClear      *updateClear_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue);                       ///< if the clearTag to update is missing, a new one will be added
49610152Satgutier@umich.edu    /** @} */
49710152Satgutier@umich.edu
49810152Satgutier@umich.edu    /** @defgroup xmlPosition Position helper functions (use in conjunction with the update&add functions
49910152Satgutier@umich.edu     * @ingroup xmlModify
50010152Satgutier@umich.edu     * These are some useful functions when you want to insert a childNode, a text or a XMLClearTag in the
50110152Satgutier@umich.edu     * middle (at a specified position) of a XMLNode tree already constructed. The value returned by these
50210152Satgutier@umich.edu     * methods is to be used as last parameter (parameter 'pos') of addChild, addText or addClear.
50310152Satgutier@umich.edu     * @{ */
50410152Satgutier@umich.edu    XMLElementPosition positionOfText(int i=0) const;
50510152Satgutier@umich.edu    XMLElementPosition positionOfText(XMLCSTR lpszValue) const;
50610152Satgutier@umich.edu    XMLElementPosition positionOfClear(int i=0) const;
50710152Satgutier@umich.edu    XMLElementPosition positionOfClear(XMLCSTR lpszValue) const;
50810152Satgutier@umich.edu    XMLElementPosition positionOfClear(XMLClear *a) const;
50910152Satgutier@umich.edu    XMLElementPosition positionOfChildNode(int i=0) const;
51010152Satgutier@umich.edu    XMLElementPosition positionOfChildNode(XMLNode x) const;
51110152Satgutier@umich.edu    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
51210152Satgutier@umich.edu    /** @} */
51310152Satgutier@umich.edu
51410152Satgutier@umich.edu    /// Enumeration for XML character encoding.
51510234Syasuko.eckert@amd.com    typedef enum XMLCharEncoding {
51610234Syasuko.eckert@amd.com        char_encoding_error = 0,
51710234Syasuko.eckert@amd.com        char_encoding_UTF8 = 1,
51810234Syasuko.eckert@amd.com        char_encoding_legacy = 2,
51910234Syasuko.eckert@amd.com        char_encoding_ShiftJIS = 3,
52010234Syasuko.eckert@amd.com        char_encoding_GB2312 = 4,
52110234Syasuko.eckert@amd.com        char_encoding_Big5 = 5,
52210234Syasuko.eckert@amd.com        char_encoding_GBK = 6   // this is actually the same as Big5
52310152Satgutier@umich.edu    } XMLCharEncoding;
52410152Satgutier@umich.edu
52510152Satgutier@umich.edu    /** \addtogroup conversions
52610152Satgutier@umich.edu     * @{ */
52710152Satgutier@umich.edu
52810152Satgutier@umich.edu    /// Sets the global options for the conversions
52910152Satgutier@umich.edu    static char setGlobalOptions(XMLCharEncoding characterEncoding=XMLNode::char_encoding_UTF8, char guessWideCharChars=1,
53010152Satgutier@umich.edu                                 char dropWhiteSpace=1, char removeCommentsInMiddleOfText=1);
53110152Satgutier@umich.edu    /**< The "setGlobalOptions" function allows you to change four global parameters that affect string & file
53210152Satgutier@umich.edu     * parsing. First of all, you most-probably will never have to change these 3 global parameters.
53310152Satgutier@umich.edu     *
53410152Satgutier@umich.edu     * @param guessWideCharChars If "guessWideCharChars"=1 and if this library is compiled in WideChar mode, then the
53510152Satgutier@umich.edu     *     XMLNode::parseFile and XMLNode::openFileHelper functions will test if the file contains ASCII
53610152Satgutier@umich.edu     *     characters. If this is the case, then the file will be loaded and converted in memory to
53710152Satgutier@umich.edu     *     WideChar before being parsed. If 0, no conversion will be performed.
53810152Satgutier@umich.edu     *
53910152Satgutier@umich.edu     * @param guessWideCharChars If "guessWideCharChars"=1 and if this library is compiled in ASCII/UTF8/char* mode, then the
54010152Satgutier@umich.edu     *     XMLNode::parseFile and XMLNode::openFileHelper functions will test if the file contains WideChar
54110152Satgutier@umich.edu     *     characters. If this is the case, then the file will be loaded and converted in memory to
54210152Satgutier@umich.edu     *     ASCII/UTF8/char* before being parsed. If 0, no conversion will be performed.
54310152Satgutier@umich.edu     *
54410152Satgutier@umich.edu     * @param characterEncoding This parameter is only meaningful when compiling in char* mode (multibyte character mode).
54510152Satgutier@umich.edu     *     In wchar_t* (wide char mode), this parameter is ignored. This parameter should be one of the
54610152Satgutier@umich.edu     *     three currently recognized encodings: XMLNode::encoding_UTF8, XMLNode::encoding_ascii,
54710152Satgutier@umich.edu     *     XMLNode::encoding_ShiftJIS.
54810152Satgutier@umich.edu     *
54910152Satgutier@umich.edu     * @param dropWhiteSpace In most situations, text fields containing only white spaces (and carriage returns)
55010152Satgutier@umich.edu     *     are useless. Even more, these "empty" text fields are annoying because they increase the
55110152Satgutier@umich.edu     *     complexity of the user's code for parsing. So, 99% of the time, it's better to drop
55210152Satgutier@umich.edu     *     the "empty" text fields. However The XML specification indicates that no white spaces
55310152Satgutier@umich.edu     *     should be lost when parsing the file. So to be perfectly XML-compliant, you should set
55410152Satgutier@umich.edu     *     dropWhiteSpace=0. A note of caution: if you set "dropWhiteSpace=0", the parser will be
55510152Satgutier@umich.edu     *     slower and your code will be more complex.
55610152Satgutier@umich.edu     *
55710152Satgutier@umich.edu     * @param removeCommentsInMiddleOfText To explain this parameter, let's consider this code:
55810152Satgutier@umich.edu     * \code
55910152Satgutier@umich.edu     *        XMLNode x=XMLNode::parseString("<a>foo<!-- hello -->bar<!DOCTYPE world >chu</a>","a");
56010152Satgutier@umich.edu     * \endcode
56110152Satgutier@umich.edu     *     If removeCommentsInMiddleOfText=0, then we will have:
56210152Satgutier@umich.edu     * \code
56310152Satgutier@umich.edu     *        x.getText(0) -> "foo"
56410152Satgutier@umich.edu     *        x.getText(1) -> "bar"
56510152Satgutier@umich.edu     *        x.getText(2) -> "chu"
56610152Satgutier@umich.edu     *        x.getClear(0) --> "<!-- hello -->"
56710152Satgutier@umich.edu     *        x.getClear(1) --> "<!DOCTYPE world >"
56810152Satgutier@umich.edu     * \endcode
56910152Satgutier@umich.edu     *     If removeCommentsInMiddleOfText=1, then we will have:
57010152Satgutier@umich.edu     * \code
57110152Satgutier@umich.edu     *        x.getText(0) -> "foobar"
57210152Satgutier@umich.edu     *        x.getText(1) -> "chu"
57310152Satgutier@umich.edu     *        x.getClear(0) --> "<!DOCTYPE world >"
57410152Satgutier@umich.edu     * \endcode
57510152Satgutier@umich.edu     *
57610152Satgutier@umich.edu     * \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.
57710152Satgutier@umich.edu     *
57810152Satgutier@umich.edu     * \note Sometime, it's useful to set "guessWideCharChars=0" to disable any conversion
57910152Satgutier@umich.edu     * because the test to detect the file-type (ASCII/UTF8/char* or WideChar) may fail (rarely). */
58010152Satgutier@umich.edu
58110152Satgutier@umich.edu    /// Guess the character encoding of the string (ascii, utf8 or shift-JIS)
58210152Satgutier@umich.edu    static XMLCharEncoding guessCharEncoding(void *buffer, int bufLen, char useXMLEncodingAttribute=1);
58310152Satgutier@umich.edu    /**< The "guessCharEncoding" function try to guess the character encoding. You most-probably will never
58410152Satgutier@umich.edu     * have to use this function. It then returns the appropriate value of the global parameter
58510152Satgutier@umich.edu     * "characterEncoding" described in the XMLNode::setGlobalOptions. The guess is based on the content of a buffer of length
58610152Satgutier@umich.edu     * "bufLen" bytes that contains the first bytes (minimum 25 bytes; 200 bytes is a good value) of the
58710152Satgutier@umich.edu     * file to be parsed. The XMLNode::openFileHelper function is using this function to automatically compute
58810152Satgutier@umich.edu     * the value of the "characterEncoding" global parameter. There are several heuristics used to do the
58910152Satgutier@umich.edu     * guess. One of the heuristic is based on the "encoding" attribute. The original XML specifications
59010152Satgutier@umich.edu     * forbids to use this attribute to do the guess but you can still use it if you set
59110152Satgutier@umich.edu     * "useXMLEncodingAttribute" to 1 (this is the default behavior and the behavior of most parsers).
59210152Satgutier@umich.edu     * If an inconsistency in the encoding is detected, then the return value is "0". */
59310152Satgutier@umich.edu    /** @} */
59410152Satgutier@umich.edu
59510234Syasuko.eckert@amd.comprivate:
59610234Syasuko.eckert@amd.com    // these are functions and structures used internally by the XMLNode class (don't bother about them):
59710152Satgutier@umich.edu
59810234Syasuko.eckert@amd.com    typedef struct XMLNodeDataTag { // to allow shallow copy and "intelligent/smart" pointers (automatic delete):
59910234Syasuko.eckert@amd.com        XMLCSTR                lpszName;        // Element name (=NULL if root)
60010234Syasuko.eckert@amd.com        int                    nChild,          // Number of child nodes
60110234Syasuko.eckert@amd.com        nText,           // Number of text fields
60210234Syasuko.eckert@amd.com        nClear,          // Number of Clear fields (comments)
60310234Syasuko.eckert@amd.com        nAttribute;      // Number of attributes
60410234Syasuko.eckert@amd.com        char                   isDeclaration;   // Whether node is an XML declaration - '<?xml ?>'
60510234Syasuko.eckert@amd.com        struct XMLNodeDataTag  *pParent;        // Pointer to parent element (=NULL if root)
60610234Syasuko.eckert@amd.com        XMLNode                *pChild;         // Array of child nodes
60710234Syasuko.eckert@amd.com        XMLCSTR                *pText;          // Array of text fields
60810234Syasuko.eckert@amd.com        XMLClear               *pClear;         // Array of clear fields
60910234Syasuko.eckert@amd.com        XMLAttribute           *pAttribute;     // Array of attributes
61010234Syasuko.eckert@amd.com        int                    *pOrder;         // order of the child_nodes,text_fields,clear_fields
61110234Syasuko.eckert@amd.com        int                    ref_count;       // for garbage collection (smart pointers)
61210234Syasuko.eckert@amd.com    } XMLNodeData;
61310234Syasuko.eckert@amd.com    XMLNodeData *d;
61410152Satgutier@umich.edu
61510234Syasuko.eckert@amd.com    char parseClearTag(void *px, void *pa);
61610234Syasuko.eckert@amd.com    char maybeAddTxT(void *pa, XMLCSTR tokenPStr);
61710234Syasuko.eckert@amd.com    int ParseXMLElement(void *pXML);
61810234Syasuko.eckert@amd.com    void *addToOrder(int memInc, int *_pos, int nc, void *p, int size, XMLElementType xtype);
61910234Syasuko.eckert@amd.com    int indexText(XMLCSTR lpszValue) const;
62010234Syasuko.eckert@amd.com    int indexClear(XMLCSTR lpszValue) const;
62110234Syasuko.eckert@amd.com    XMLNode addChild_priv(int, XMLSTR, char, int);
62210234Syasuko.eckert@amd.com    XMLAttribute *addAttribute_priv(int, XMLSTR, XMLSTR);
62310234Syasuko.eckert@amd.com    XMLCSTR addText_priv(int, XMLSTR, int);
62410234Syasuko.eckert@amd.com    XMLClear *addClear_priv(int, XMLSTR, XMLCSTR, XMLCSTR, int);
62510234Syasuko.eckert@amd.com    void emptyTheNode(char force);
62610234Syasuko.eckert@amd.com    static inline XMLElementPosition findPosition(XMLNodeData *d, int index, XMLElementType xtype);
62710234Syasuko.eckert@amd.com    static int CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, int nFormat);
62810234Syasuko.eckert@amd.com    static int removeOrderElement(XMLNodeData *d, XMLElementType t, int index);
62910234Syasuko.eckert@amd.com    static void exactMemory(XMLNodeData *d);
63010234Syasuko.eckert@amd.com    static int detachFromParent(XMLNodeData *d);
63110152Satgutier@umich.edu} XMLNode;
63210152Satgutier@umich.edu
63310152Satgutier@umich.edu/// This structure is given by the function XMLNode::enumContents.
63410234Syasuko.eckert@amd.comtypedef struct XMLNodeContents {
63510152Satgutier@umich.edu    /// This dictates what's the content of the XMLNodeContent
63610152Satgutier@umich.edu    enum XMLElementType etype;
63710152Satgutier@umich.edu    /**< should be an union to access the appropriate data. Compiler does not allow union of object with constructor... too bad. */
63810152Satgutier@umich.edu    XMLNode child;
63910152Satgutier@umich.edu    XMLAttribute attrib;
64010152Satgutier@umich.edu    XMLCSTR text;
64110152Satgutier@umich.edu    XMLClear clear;
64210152Satgutier@umich.edu
64310152Satgutier@umich.edu} XMLNodeContents;
64410152Satgutier@umich.edu
64510152Satgutier@umich.edu/** @defgroup StringAlloc String Allocation/Free functions
64610152Satgutier@umich.edu * @ingroup xmlModify
64710152Satgutier@umich.edu * @{ */
64810152Satgutier@umich.edu/// Duplicate (copy in a new allocated buffer) the source string.
64910152Satgutier@umich.eduXMLDLLENTRY XMLSTR stringDup(XMLCSTR source, int cbData=-1);
65010152Satgutier@umich.edu/**< This is
65110152Satgutier@umich.edu * a very handy function when used with all the "XMLNode::*_WOSD" functions (\link xmlWOSD \endlink).
65210152Satgutier@umich.edu * @param cbData If !=0 then cbData is the number of chars to duplicate. New strings allocated with
65310152Satgutier@umich.edu * this function should be free'd using the "freeXMLString" function. */
65410152Satgutier@umich.edu
65510152Satgutier@umich.edu/// to free the string allocated inside the "stringDup" function or the "createXMLString" function.
65610152Satgutier@umich.eduXMLDLLENTRY void freeXMLString(XMLSTR t); // {free(t);}
65710152Satgutier@umich.edu/** @} */
65810152Satgutier@umich.edu
65910152Satgutier@umich.edu/** @defgroup atoX ato? like functions
66010152Satgutier@umich.edu * @ingroup XMLParserGeneral
66110152Satgutier@umich.edu * The "xmlto?" functions are equivalents to the atoi, atol, atof functions.
66210152Satgutier@umich.edu * The only difference is: If the variable "xmlString" is NULL, than the return value
66310152Satgutier@umich.edu * is "defautValue". These 6 functions are only here as "convenience" functions for the
66410152Satgutier@umich.edu * user (they are not used inside the XMLparser). If you don't need them, you can
66510152Satgutier@umich.edu * delete them without any trouble.
66610152Satgutier@umich.edu *
66710152Satgutier@umich.edu * @{ */
66810234Syasuko.eckert@amd.comXMLDLLENTRY char    xmltob(XMLCSTR xmlString, char   defautValue=0);
66910234Syasuko.eckert@amd.comXMLDLLENTRY int     xmltoi(XMLCSTR xmlString, int    defautValue=0);
67010234Syasuko.eckert@amd.comXMLDLLENTRY long    xmltol(XMLCSTR xmlString, long   defautValue=0);
67110234Syasuko.eckert@amd.comXMLDLLENTRY double  xmltof(XMLCSTR xmlString, double defautValue=.0);
67210234Syasuko.eckert@amd.comXMLDLLENTRY XMLCSTR xmltoa(XMLCSTR xmlString, XMLCSTR defautValue=_CXML(""));
67310234Syasuko.eckert@amd.comXMLDLLENTRY XMLCHAR xmltoc(XMLCSTR xmlString, XMLCHAR defautValue=_CXML('\0'));
67410152Satgutier@umich.edu/** @} */
67510152Satgutier@umich.edu
67610152Satgutier@umich.edu/** @defgroup ToXMLStringTool Helper class to create XML files using "printf", "fprintf", "cout",... functions.
67710152Satgutier@umich.edu * @ingroup XMLParserGeneral
67810152Satgutier@umich.edu * @{ */
67910152Satgutier@umich.edu/// Helper class to create XML files using "printf", "fprintf", "cout",... functions.
68010152Satgutier@umich.edu/** The ToXMLStringTool class helps you creating XML files using "printf", "fprintf", "cout",... functions.
68110152Satgutier@umich.edu * The "ToXMLStringTool" class is processing strings so that all the characters
68210152Satgutier@umich.edu * &,",',<,> are replaced by their XML equivalent:
68310152Satgutier@umich.edu * \verbatim &amp;, &quot;, &apos;, &lt;, &gt; \endverbatim
68410152Satgutier@umich.edu * Using the "ToXMLStringTool class" and the "fprintf function" is THE most efficient
68510152Satgutier@umich.edu * way to produce VERY large XML documents VERY fast.
68610152Satgutier@umich.edu * \note If you are creating from scratch an XML file using the provided XMLNode class
68710152Satgutier@umich.edu * you must not use the "ToXMLStringTool" class (because the "XMLNode" class does the
68810152Satgutier@umich.edu * processing job for you during rendering).*/
68910234Syasuko.eckert@amd.comtypedef struct XMLDLLENTRY ToXMLStringTool {
69010152Satgutier@umich.edupublic:
69110234Syasuko.eckert@amd.com    ToXMLStringTool(): buf(NULL), buflen(0){}
69210152Satgutier@umich.edu    ~ToXMLStringTool();
69310152Satgutier@umich.edu    void freeBuffer();///<call this function when you have finished using this object to release memory used by the internal buffer.
69410152Satgutier@umich.edu
69510152Satgutier@umich.edu    XMLSTR toXML(XMLCSTR source);///< returns a pointer to an internal buffer that contains a XML-encoded string based on the "source" parameter.
69610152Satgutier@umich.edu
69710152Satgutier@umich.edu    /** The "toXMLUnSafe" function is deprecated because there is a possibility of
69810152Satgutier@umich.edu     * "destination-buffer-overflow". It converts the string
69910152Satgutier@umich.edu     * "source" to the string "dest". */
70010152Satgutier@umich.edu    static XMLSTR toXMLUnSafe(XMLSTR dest,XMLCSTR source); ///< deprecated: use "toXML" instead
70110152Satgutier@umich.edu    static int lengthXMLString(XMLCSTR source);            ///< deprecated: use "toXML" instead
70210152Satgutier@umich.edu
70310152Satgutier@umich.eduprivate:
70410152Satgutier@umich.edu    XMLSTR buf;
70510152Satgutier@umich.edu    int buflen;
70610152Satgutier@umich.edu} ToXMLStringTool;
70710152Satgutier@umich.edu/** @} */
70810152Satgutier@umich.edu
70910152Satgutier@umich.edu/** @defgroup XMLParserBase64Tool Helper class to include binary data inside XML strings using "Base64 encoding".
71010152Satgutier@umich.edu * @ingroup XMLParserGeneral
71110152Satgutier@umich.edu * @{ */
71210152Satgutier@umich.edu/// Helper class to include binary data inside XML strings using "Base64 encoding".
71310152Satgutier@umich.edu/** The "XMLParserBase64Tool" class allows you to include any binary data (images, sounds,...)
71410152Satgutier@umich.edu * into an XML document using "Base64 encoding". This class is completely
71510152Satgutier@umich.edu * separated from the rest of the xmlParser library and can be removed without any problem.
71610152Satgutier@umich.edu * To include some binary data into an XML file, you must convert the binary data into
71710152Satgutier@umich.edu * standard text (using "encode"). To retrieve the original binary data from the
71810152Satgutier@umich.edu * b64-encoded text included inside the XML file, use "decode". Alternatively, these
71910152Satgutier@umich.edu * functions can also be used to "encrypt/decrypt" some critical data contained inside
72010152Satgutier@umich.edu * the XML (it's not a strong encryption at all, but sometimes it can be useful). */
72110234Syasuko.eckert@amd.comtypedef struct XMLDLLENTRY XMLParserBase64Tool {
72210152Satgutier@umich.edupublic:
72310234Syasuko.eckert@amd.com    XMLParserBase64Tool(): buf(NULL), buflen(0){}
72410152Satgutier@umich.edu    ~XMLParserBase64Tool();
72510152Satgutier@umich.edu    void freeBuffer();///< Call this function when you have finished using this object to release memory used by the internal buffer.
72610152Satgutier@umich.edu
72710152Satgutier@umich.edu    /**
72810152Satgutier@umich.edu     * @param formatted If "formatted"=true, some space will be reserved for a carriage-return every 72 chars. */
72910152Satgutier@umich.edu    static int encodeLength(int inBufLen, char formatted=0); ///< return the length of the base64 string that encodes a data buffer of size inBufLen bytes.
73010152Satgutier@umich.edu
73110152Satgutier@umich.edu    /**
73210152Satgutier@umich.edu     * The "base64Encode" function returns a string containing the base64 encoding of "inByteLen" bytes
73310152Satgutier@umich.edu     * from "inByteBuf". If "formatted" parameter is true, then there will be a carriage-return every 72 chars.
73410152Satgutier@umich.edu     * The string will be free'd when the XMLParserBase64Tool object is deleted.
73510152Satgutier@umich.edu     * All returned strings are sharing the same memory space. */
73610152Satgutier@umich.edu    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"
73710152Satgutier@umich.edu
73810152Satgutier@umich.edu    /// returns the number of bytes which will be decoded from "inString".
73910152Satgutier@umich.edu    static unsigned int decodeSize(XMLCSTR inString, XMLError *xe=NULL);
74010152Satgutier@umich.edu
74110152Satgutier@umich.edu    /**
74210152Satgutier@umich.edu     * The "decode" function returns a pointer to a buffer containing the binary data decoded from "inString"
74310152Satgutier@umich.edu     * The output buffer will be free'd when the XMLParserBase64Tool object is deleted.
74410152Satgutier@umich.edu     * All output buffer are sharing the same memory space.
74510152Satgutier@umich.edu     * @param inString If "instring" is malformed, NULL will be returned */
74610152Satgutier@umich.edu    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"
74710152Satgutier@umich.edu
74810152Satgutier@umich.edu    /**
74910152Satgutier@umich.edu     * decodes data from "inString" to "outByteBuf". You need to provide the size (in byte) of "outByteBuf"
75010152Satgutier@umich.edu     * in "inMaxByteOutBuflen". If "outByteBuf" is not large enough or if data is malformed, then "FALSE"
75110152Satgutier@umich.edu     * will be returned; otherwise "TRUE". */
75210152Satgutier@umich.edu    static unsigned char decode(XMLCSTR inString, unsigned char *outByteBuf, int inMaxByteOutBuflen, XMLError *xe=NULL); ///< deprecated.
75310152Satgutier@umich.edu
75410152Satgutier@umich.eduprivate:
75510152Satgutier@umich.edu    void *buf;
75610152Satgutier@umich.edu    int buflen;
75710152Satgutier@umich.edu    void alloc(int newsize);
75810152Satgutier@umich.edu}XMLParserBase64Tool;
75910152Satgutier@umich.edu/** @} */
76010152Satgutier@umich.edu
76110152Satgutier@umich.edu#undef XMLDLLENTRY
76210152Satgutier@umich.edu
76310152Satgutier@umich.edu#endif
764