/*
www.sourceforge.net/projects/tinyxml
Original code by Lee Thomason (www.grinninglizard.com)
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#ifndef TINYXML_INCLUDED
#define TINYXML_INCLUDED
#ifdef _MSC_VER
#pragma warning( push )
#pragma warning( disable : 4530 )
#pragma warning( disable : 4786 )
#endif
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
// Help out windows:
#if defined( _DEBUG ) && !defined( DEBUG )
#define DEBUG
#endif
#ifdef TIXML_USE_STL
#include <string>
#include <iostream>
#include <sstream>
#define TIXML_STRING std::string
#else
#include "tinystr.h"
#define TIXML_STRING TiXmlString
#endif
// Deprecated library function hell. Compilers want to use the
// new safe versions. This probably doesn't fully address the problem,
// but it gets closer. There are too many compilers for me to fully
// test. If you get compilation troubles, undefine TIXML_SAFE
#define TIXML_SAFE
#ifdef TIXML_SAFE
#if defined(_MSC_VER) && (_MSC_VER >= 1400 )
// Microsoft visual studio, version 2005 and higher.
#define TIXML_SNPRINTF _snprintf_s
#define TIXML_SSCANF sscanf_s
#elif defined(_MSC_VER) && (_MSC_VER >= 1200 )
// Microsoft visual studio, version 6 and higher.
//#pragma message( "Using _sn* functions." )
#define TIXML_SNPRINTF _snprintf
#define TIXML_SSCANF sscanf
#elif defined(__GNUC__) && (__GNUC__ >= 3 )
// GCC version 3 and higher.s
//#warning( "Using sn* functions." )
#define TIXML_SNPRINTF snprintf
#define TIXML_SSCANF sscanf
#else
#define TIXML_SNPRINTF snprintf
#define TIXML_SSCANF sscanf
#endif
#endif
class TiXmlDocument;
class TiXmlElement;
class TiXmlComment;
class TiXmlUnknown;
class TiXmlAttribute;
class TiXmlText;
class TiXmlDeclaration;
class TiXmlParsingData;
const int TIXML_MAJOR_VERSION = 2;
const int TIXML_MINOR_VERSION = 6;
const int TIXML_PATCH_VERSION = 2;
/* Internal structure for tracking location of items
in the XML file.
*/
struct TiXmlCursor
{
TiXmlCursor() { Clear(); }
void Clear() { row = col = -1; }
int row; // 0 based.
int col; // 0 based.
};
/**
Implements the interface to the "Visitor pattern" (see the Accept() method.)
If you call the Accept() method, it requires being passed a TiXmlVisitor
class to handle callbacks. For nodes that contain other nodes (Document, Element)
you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves
are simply called with Visit().
If you return 'true' from a Visit method, recursive parsing will continue. If you return
false, <b>no children of this node or its sibilings</b> will be Visited.
All flavors of Visit methods have a default implementation that returns 'true' (continue
visiting). You need to only override methods that are interesting to you.
Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting.
You should never change the document from a callback.
@sa TiXmlNode::Accept()
*/
class TiXmlVisitor
{
public:
virtual ~TiXmlVisitor() {}
/// Visit a document.
virtual bool VisitEnter( const TiXmlDocument& /*doc*/ ) { return true; }
/// Visit a document.
virtual bool VisitExit( const TiXmlDocument& /*doc*/ ) { return true; }
/// Visit an element.
virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ ) { return true; }
/// Visit an element.
virtual bool VisitExit( const TiXmlElement& /*element*/ ) { return true; }
/// Visit a declaration
virtual bool Visit( const TiXmlDeclaration& /*declaration*/ ) { return true; }
/// Visit a text node
virtual bool Visit( const TiXmlText& /*text*/ ) { return true; }
/// Visit a comment node
virtual bool Visit( const TiXmlComment& /*comment*/ ) { return true; }
/// Visit an unknown node
virtual bool Visit( const TiXmlUnknown& /*unknown*/ ) { return true; }
};
// Only used by Attribute::Query functions
enum
{
TIXML_SUCCESS,
TIXML_NO_ATTRIBUTE,
TIXML_WRONG_TYPE
};
// Used by the parsing routines.
enum TiXmlEncoding
{
TIXML_ENCODING_UNKNOWN,
TIXML_ENCODING_UTF8,
TIXML_ENCODING_LEGACY
};
const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
/** TiXmlBase is a base class for every class in TinyXml.
It does little except to establish that TinyXml classes
can be printed and provide some utility functions.
In XML, the document and elements can contain
other elements and other types of nodes.
@verbatim
A Document can contain: Element (container or leaf)
Comment (leaf)
Unknown (leaf)
Declaration( leaf )
An Element can contain: Element (container or leaf)
Text (leaf)
Attributes (not on tree)
Comment (leaf)
Unknown (leaf)
A Decleration contains: Attributes (not on tree)
@endverbatim
*/
class TiXmlBase
{
friend class TiXmlNode;
friend class TiXmlElement;
friend class TiXmlDocument;
public:
TiXmlBase() : userData(0) {}
virtual ~TiXmlBase() {}
/** All TinyXml classes can print themselves to a filestream
or the string class (TiXmlString in non-STL mode, std::string
in STL mode.) Either or both cfile and str can be null.
This is a formatted print, and will insert
tabs and newlines.
(For an unformatted stream, use the << operator.)
*/
virtual void Print( FILE* cfile, int depth ) const = 0;
/** The world does not agree on whether white space should be kept or
not. In order to make everyone happy, these global, static functions
are provided to set whether or not TinyXml will condense all white space
into a single space or not. The default is to condense. Note changing this
value is not thread safe.
*/
static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; }
/// Return the current white space setting.
static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; }
/** Return the position, in the original source file, of this node or attribute.
The row and column are 1-based. (That is the first row and first column is
1,1). If the returns values are 0 or less, then the parser does not have
a row and column value.
Generally, the row and column value will be set when the TiXmlDocument::Load(),
TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set
when the DOM was created from operator>>.
The values reflect the initial load. Once the DOM is modified programmatically
(by adding or changing nodes and attributes) the new values will NOT update to
reflect changes in the document.
There is a minor performance cost to computing the row and column. Computation
can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value.
@sa TiXmlDocument::SetTabSize()
*/
int Row() const { return location.row + 1; }
int Column() const { return location.col + 1; } ///< See Row()
void SetUserData( void* user ) { userData = user; } ///< Set a pointer to arbitrary user data.
void* GetUserData() { return userData; } ///< Get a pointer to arbitrary user data.
const void* GetUserData() const { return userData; } ///< Get a pointer to arbitrary user data.
// Table that returs, for a given lead byte, the total number of bytes
//