Home | History | Annotate | Download | only in tinyxml
      1 /*
      2 www.sourceforge.net/projects/tinyxml
      3 Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
      4 
      5 This software is provided 'as-is', without any express or implied
      6 warranty. In no event will the authors be held liable for any
      7 damages arising from the use of this software.
      8 
      9 Permission is granted to anyone to use this software for any
     10 purpose, including commercial applications, and to alter it and
     11 redistribute it freely, subject to the following restrictions:
     12 
     13 1. The origin of this software must not be misrepresented; you must
     14 not claim that you wrote the original software. If you use this
     15 software in a product, an acknowledgment in the product documentation
     16 would be appreciated but is not required.
     17 
     18 2. Altered source versions must be plainly marked as such, and
     19 must not be misrepresented as being the original software.
     20 
     21 3. This notice may not be removed or altered from any source
     22 distribution.
     23 */
     24 
     25 
     26 #ifndef TINYXML_INCLUDED
     27 #define TINYXML_INCLUDED
     28 
     29 #ifdef _MSC_VER
     30 #pragma warning( push )
     31 #pragma warning( disable : 4530 )
     32 #pragma warning( disable : 4786 )
     33 #endif
     34 
     35 #include <ctype.h>
     36 #include <stdio.h>
     37 #include <stdlib.h>
     38 #include <string.h>
     39 #include <assert.h>
     40 
     41 // Help out windows:
     42 #if defined( _DEBUG ) && !defined( DEBUG )
     43 #define DEBUG
     44 #endif
     45 
     46 #if defined( DEBUG ) && defined( _MSC_VER )
     47 #include <windows.h>
     48 #define TIXML_LOG OutputDebugString
     49 #else
     50 #define TIXML_LOG printf
     51 #endif
     52 
     53 #ifdef TIXML_USE_STL
     54 	#include <string>
     55  	#include <iostream>
     56 	#define TIXML_STRING	std::string
     57 	#define TIXML_ISTREAM	std::istream
     58 	#define TIXML_OSTREAM	std::ostream
     59 #else
     60 	#include "tinystr.h"
     61 	#define TIXML_STRING	TiXmlString
     62 	#define TIXML_OSTREAM	TiXmlOutStream
     63 #endif
     64 
     65 // Deprecated library function hell. Compilers want to use the
     66 // new safe versions. This probably doesn't fully address the problem,
     67 // but it gets closer. There are too many compilers for me to fully
     68 // test. If you get compilation troubles, undefine TIXML_SAFE
     69 
     70 #define TIXML_SAFE		// TinyXml isn't fully buffer overrun protected, safe code. This is work in progress.
     71 #ifdef TIXML_SAFE
     72 	#if defined(_MSC_VER) && (_MSC_VER >= 1200 )
     73 		// Microsoft visual studio, version 6 and higher.
     74 		//#pragma message( "Using _sn* functions." )
     75 		#define TIXML_SNPRINTF _snprintf
     76 		#define TIXML_SNSCANF  _snscanf
     77 	#elif defined(__GNUC__) && (__GNUC__ >= 3 )
     78 		// GCC version 3 and higher.s
     79 		//#warning( "Using sn* functions." )
     80 		#define TIXML_SNPRINTF snprintf
     81 		#define TIXML_SNSCANF  snscanf
     82 	#endif
     83 #endif
     84 
     85 class TiXmlDocument;
     86 class TiXmlElement;
     87 class TiXmlComment;
     88 class TiXmlUnknown;
     89 class TiXmlAttribute;
     90 class TiXmlText;
     91 class TiXmlDeclaration;
     92 class TiXmlParsingData;
     93 
     94 const int TIXML_MAJOR_VERSION = 2;
     95 const int TIXML_MINOR_VERSION = 4;
     96 const int TIXML_PATCH_VERSION = 0;
     97 
     98 /*	Internal structure for tracking location of items
     99 	in the XML file.
    100 */
    101 struct TiXmlCursor
    102 {
    103 	TiXmlCursor()		{ Clear(); }
    104 	void Clear()		{ row = col = -1; }
    105 
    106 	int row;	// 0 based.
    107 	int col;	// 0 based.
    108 };
    109 
    110 
    111 // Only used by Attribute::Query functions
    112 enum
    113 {
    114 	TIXML_SUCCESS,
    115 	TIXML_NO_ATTRIBUTE,
    116 	TIXML_WRONG_TYPE
    117 };
    118 
    119 
    120 // Used by the parsing routines.
    121 enum TiXmlEncoding
    122 {
    123 	TIXML_ENCODING_UNKNOWN,
    124 	TIXML_ENCODING_UTF8,
    125 	TIXML_ENCODING_LEGACY
    126 };
    127 
    128 const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
    129 
    130 /** TiXmlBase is a base class for every class in TinyXml.
    131 	It does little except to establish that TinyXml classes
    132 	can be printed and provide some utility functions.
    133 
    134 	In XML, the document and elements can contain
    135 	other elements and other types of nodes.
    136 
    137 	@verbatim
    138 	A Document can contain:	Element	(container or leaf)
    139 							Comment (leaf)
    140 							Unknown (leaf)
    141 							Declaration( leaf )
    142 
    143 	An Element can contain:	Element (container or leaf)
    144 							Text	(leaf)
    145 							Attributes (not on tree)
    146 							Comment (leaf)
    147 							Unknown (leaf)
    148 
    149 	A Decleration contains: Attributes (not on tree)
    150 	@endverbatim
    151 */
    152 class TiXmlBase
    153 {
    154 	friend class TiXmlNode;
    155 	friend class TiXmlElement;
    156 	friend class TiXmlDocument;
    157 
    158 public:
    159 	TiXmlBase()	:	userData(0) {}
    160 	virtual ~TiXmlBase()					{}
    161 
    162 	/**	All TinyXml classes can print themselves to a filestream.
    163 		This is a formatted print, and will insert tabs and newlines.
    164 
    165 		(For an unformatted stream, use the << operator.)
    166 	*/
    167 	virtual void Print( FILE* cfile, int depth ) const = 0;
    168 
    169 	/**	The world does not agree on whether white space should be kept or
    170 		not. In order to make everyone happy, these global, static functions
    171 		are provided to set whether or not TinyXml will condense all white space
    172 		into a single space or not. The default is to condense. Note changing this
    173 		values is not thread safe.
    174 	*/
    175 	static void SetCondenseWhiteSpace( bool condense )		{ condenseWhiteSpace = condense; }
    176 
    177 	/// Return the current white space setting.
    178 	static bool IsWhiteSpaceCondensed()						{ return condenseWhiteSpace; }
    179 
    180 	/** Return the position, in the original source file, of this node or attribute.
    181 		The row and column are 1-based. (That is the first row and first column is
    182 		1,1). If the returns values are 0 or less, then the parser does not have
    183 		a row and column value.
    184 
    185 		Generally, the row and column value will be set when the TiXmlDocument::Load(),
    186 		TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set
    187 		when the DOM was created from operator>>.
    188 
    189 		The values reflect the initial load. Once the DOM is modified programmatically
    190 		(by adding or changing nodes and attributes) the new values will NOT update to
    191 		reflect changes in the document.
    192 
    193 		There is a minor performance cost to computing the row and column. Computation
    194 		can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value.
    195 
    196 		@sa TiXmlDocument::SetTabSize()
    197 	*/
    198 	int Row() const			{ return location.row + 1; }
    199 	int Column() const		{ return location.col + 1; }	///< See Row()
    200 
    201 	void  SetUserData( void* user )			{ userData = user; }
    202 	void* GetUserData()						{ return userData; }
    203 
    204 	// Table that returs, for a given lead byte, the total number of bytes
    205 	// in the UTF-8 sequence.
    206 	static const int utf8ByteTable[256];
    207 
    208 	virtual const char* Parse(	const char* p,
    209 								TiXmlParsingData* data,
    210 								TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
    211 
    212 	enum
    213 	{
    214 		TIXML_NO_ERROR = 0,
    215 		TIXML_ERROR,
    216 		TIXML_ERROR_OPENING_FILE,
    217 		TIXML_ERROR_OUT_OF_MEMORY,
    218 		TIXML_ERROR_PARSING_ELEMENT,
    219 		TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
    220 		TIXML_ERROR_READING_ELEMENT_VALUE,
    221 		TIXML_ERROR_READING_ATTRIBUTES,
    222 		TIXML_ERROR_PARSING_EMPTY,
    223 		TIXML_ERROR_READING_END_TAG,
    224 		TIXML_ERROR_PARSING_UNKNOWN,
    225 		TIXML_ERROR_PARSING_COMMENT,
    226 		TIXML_ERROR_PARSING_DECLARATION,
    227 		TIXML_ERROR_DOCUMENT_EMPTY,
    228 		TIXML_ERROR_EMBEDDED_NULL,
    229 		TIXML_ERROR_PARSING_CDATA,
    230 
    231 		TIXML_ERROR_STRING_COUNT
    232 	};
    233 
    234 protected:
    235 
    236 	// See STL_STRING_BUG
    237 	// Utility class to overcome a bug.
    238 	class StringToBuffer
    239 	{
    240 	  public:
    241 		StringToBuffer( const TIXML_STRING& str );
    242 		~StringToBuffer();
    243 		char* buffer;
    244 	};
    245 
    246 	static const char*	SkipWhiteSpace( const char*, TiXmlEncoding encoding );
    247 	inline static bool	IsWhiteSpace( char c )
    248 	{
    249 		return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' );
    250 	}
    251 
    252 	virtual void StreamOut (TIXML_OSTREAM *) const = 0;
    253 
    254 	#ifdef TIXML_USE_STL
    255 	    static bool	StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag );
    256 	    static bool StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag );
    257 	#endif
    258 
    259 	/*	Reads an XML name into the string provided. Returns
    260 		a pointer just past the last character of the name,
    261 		or 0 if the function has an error.
    262 	*/
    263 	static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding );
    264 
    265 	/*	Reads text. Returns a pointer past the given end tag.
    266 		Wickedly complex options, but it keeps the (sensitive) code in one place.
    267 	*/
    268 	static const char* ReadText(	const char* in,				// where to start
    269 									TIXML_STRING* text,			// the string read
    270 									bool ignoreWhiteSpace,		// whether to keep the white space
    271 									const char* endTag,			// what ends this text
    272 									bool ignoreCase,			// whether to ignore case in the end tag
    273 									TiXmlEncoding encoding );	// the current encoding
    274 
    275 	// If an entity has been found, transform it into a character.
    276 	static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding );
    277 
    278 	// Get a character, while interpreting entities.
    279 	// The length can be from 0 to 4 bytes.
    280 	inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding )
    281 	{
    282 		assert( p );
    283 		if ( encoding == TIXML_ENCODING_UTF8 )
    284 		{
    285 			*length = utf8ByteTable[ *((unsigned char*)p) ];
    286 			assert( *length >= 0 && *length < 5 );
    287 		}
    288 		else
    289 		{
    290 			*length = 1;
    291 		}
    292 
    293 		if ( *length == 1 )
    294 		{
    295 			if ( *p == '&' )
    296 				return GetEntity( p, _value, length, encoding );
    297 			*_value = *p;
    298 			return p+1;
    299 		}
    300 		else if ( *length )
    301 		{
    302 			//strncpy( _value, p, *length );	// lots of compilers don't like this function (unsafe),
    303 												// and the null terminator isn't needed
    304 			for( int i=0; p[i] && i<*length; ++i ) {
    305 				_value[i] = p[i];
    306 			}
    307 			return p + (*length);
    308 		}
    309 		else
    310 		{
    311 			// Not valid text.
    312 			return 0;
    313 		}
    314 	}
    315 
    316 	// Puts a string to a stream, expanding entities as it goes.
    317 	// Note this should not contian the '<', '>', etc, or they will be transformed into entities!
    318 	static void PutString( const TIXML_STRING& str, TIXML_OSTREAM* out );
    319 
    320 	static void PutString( const TIXML_STRING& str, TIXML_STRING* out );
    321 
    322 	// Return true if the next characters in the stream are any of the endTag sequences.
    323 	// Ignore case only works for english, and should only be relied on when comparing
    324 	// to English words: StringEqual( p, "version", true ) is fine.
    325 	static bool StringEqual(	const char* p,
    326 								const char* endTag,
    327 								bool ignoreCase,
    328 								TiXmlEncoding encoding );
    329 
    330 	static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
    331 
    332 	TiXmlCursor location;
    333 
    334     /// Field containing a generic user pointer
    335 	void*			userData;
    336 
    337 	// None of these methods are reliable for any language except English.
    338 	// Good for approximation, not great for accuracy.
    339 	static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding );
    340 	static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding );
    341 	inline static int ToLower( int v, TiXmlEncoding encoding )
    342 	{
    343 		if ( encoding == TIXML_ENCODING_UTF8 )
    344 		{
    345 			if ( v < 128 ) return tolower( v );
    346 			return v;
    347 		}
    348 		else
    349 		{
    350 			return tolower( v );
    351 		}
    352 	}
    353 	static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
    354 
    355 private:
    356 	TiXmlBase( const TiXmlBase& );				// not implemented.
    357 	void operator=( const TiXmlBase& base );	// not allowed.
    358 
    359 	struct Entity
    360 	{
    361 		const char*     str;
    362 		unsigned int	strLength;
    363 		char		    chr;
    364 	};
    365 	enum
    366 	{
    367 		NUM_ENTITY = 5,
    368 		MAX_ENTITY_LENGTH = 6
    369 
    370 	};
    371 	static Entity entity[ NUM_ENTITY ];
    372 	static bool condenseWhiteSpace;
    373 };
    374 
    375 
    376 /** The parent class for everything in the Document Object Model.
    377 	(Except for attributes).
    378 	Nodes have siblings, a parent, and children. A node can be
    379 	in a document, or stand on its own. The type of a TiXmlNode
    380 	can be queried, and it can be cast to its more defined type.
    381 */
    382 class TiXmlNode : public TiXmlBase
    383 {
    384 	friend class TiXmlDocument;
    385 	friend class TiXmlElement;
    386 
    387 public:
    388 	#ifdef TIXML_USE_STL
    389 
    390 	    /** An input stream operator, for every class. Tolerant of newlines and
    391 		    formatting, but doesn't expect them.
    392 	    */
    393 	    friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
    394 
    395 	    /** An output stream operator, for every class. Note that this outputs
    396 		    without any newlines or formatting, as opposed to Print(), which
    397 		    includes tabs and new lines.
    398 
    399 		    The operator<< and operator>> are not completely symmetric. Writing
    400 		    a node to a stream is very well defined. You'll get a nice stream
    401 		    of output, without any extra whitespace or newlines.
    402 
    403 		    But reading is not as well defined. (As it always is.) If you create
    404 		    a TiXmlElement (for example) and read that from an input stream,
    405 		    the text needs to define an element or junk will result. This is
    406 		    true of all input streams, but it's worth keeping in mind.
    407 
    408 		    A TiXmlDocument will read nodes until it reads a root element, and
    409 			all the children of that root element.
    410 	    */
    411 	    friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
    412 
    413 		/// Appends the XML node or attribute to a std::string.
    414 		friend std::string& operator<< (std::string& out, const TiXmlNode& base );
    415 
    416 	#else
    417 	    // Used internally, not part of the public API.
    418 	    friend TIXML_OSTREAM& operator<< (TIXML_OSTREAM& out, const TiXmlNode& base);
    419 	#endif
    420 
    421 	/** The types of XML nodes supported by TinyXml. (All the
    422 			unsupported types are picked up by UNKNOWN.)
    423 	*/
    424 	enum NodeType
    425 	{
    426 		DOCUMENT,
    427 		ELEMENT,
    428 		COMMENT,
    429 		UNKNOWN,
    430 		TEXT,
    431 		DECLARATION,
    432 		TYPECOUNT
    433 	};
    434 
    435 	virtual ~TiXmlNode();
    436 
    437 	/** The meaning of 'value' changes for the specific type of
    438 		TiXmlNode.
    439 		@verbatim
    440 		Document:	filename of the xml file
    441 		Element:	name of the element
    442 		Comment:	the comment text
    443 		Unknown:	the tag contents
    444 		Text:		the text string
    445 		@endverbatim
    446 
    447 		The subclasses will wrap this function.
    448 	*/
    449 	const char *Value() const { return value.c_str (); }
    450 
    451     #ifdef TIXML_USE_STL
    452 	/** Return Value() as a std::string. If you only use STL,
    453 	    this is more efficient than calling Value().
    454 		Only available in STL mode.
    455 	*/
    456 	const std::string& ValueStr() const { return value; }
    457 	#endif
    458 
    459 	/** Changes the value of the node. Defined as:
    460 		@verbatim
    461 		Document:	filename of the xml file
    462 		Element:	name of the element
    463 		Comment:	the comment text
    464 		Unknown:	the tag contents
    465 		Text:		the text string
    466 		@endverbatim
    467 	*/
    468 	void SetValue(const char * _value) { value = _value;}
    469 
    470     #ifdef TIXML_USE_STL
    471 	/// STL std::string form.
    472 	void SetValue( const std::string& _value )
    473 	{
    474 		StringToBuffer buf( _value );
    475 		SetValue( buf.buffer ? buf.buffer : "" );
    476 	}
    477 	#endif
    478 
    479 	/// Delete all the children of this node. Does not affect 'this'.
    480 	void Clear();
    481 
    482 	/// One step up the DOM.
    483 	TiXmlNode* Parent()							{ return parent; }
    484 	const TiXmlNode* Parent() const				{ return parent; }
    485 
    486 	const TiXmlNode* FirstChild()	const	{ return firstChild; }		///< The first child of this node. Will be null if there are no children.
    487 	TiXmlNode* FirstChild()					{ return firstChild; }
    488 	const TiXmlNode* FirstChild( const char * value ) const;			///< The first child of this node with the matching 'value'. Will be null if none found.
    489 	TiXmlNode* FirstChild( const char * value );						///< The first child of this node with the matching 'value'. Will be null if none found.
    490 
    491 	const TiXmlNode* LastChild() const	{ return lastChild; }		/// The last child of this node. Will be null if there are no children.
    492 	TiXmlNode* LastChild()	{ return lastChild; }
    493 	const TiXmlNode* LastChild( const char * value ) const;			/// The last child of this node matching 'value'. Will be null if there are no children.
    494 	TiXmlNode* LastChild( const char * value );
    495 
    496     #ifdef TIXML_USE_STL
    497 	const TiXmlNode* FirstChild( const std::string& _value ) const	{	return FirstChild (_value.c_str ());	}	///< STL std::string form.
    498 	TiXmlNode* FirstChild( const std::string& _value )				{	return FirstChild (_value.c_str ());	}	///< STL std::string form.
    499 	const TiXmlNode* LastChild( const std::string& _value ) const	{	return LastChild (_value.c_str ());	}	///< STL std::string form.
    500 	TiXmlNode* LastChild( const std::string& _value )				{	return LastChild (_value.c_str ());	}	///< STL std::string form.
    501 	#endif
    502 
    503 	/** An alternate way to walk the children of a node.
    504 		One way to iterate over nodes is:
    505 		@verbatim
    506 			for( child = parent->FirstChild(); child; child = child->NextSibling() )
    507 		@endverbatim
    508 
    509 		IterateChildren does the same thing with the syntax:
    510 		@verbatim
    511 			child = 0;
    512 			while( child = parent->IterateChildren( child ) )
    513 		@endverbatim
    514 
    515 		IterateChildren takes the previous child as input and finds
    516 		the next one. If the previous child is null, it returns the
    517 		first. IterateChildren will return null when done.
    518 	*/
    519 	const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const;
    520 	TiXmlNode* IterateChildren( TiXmlNode* previous );
    521 
    522 	/// This flavor of IterateChildren searches for children with a particular 'value'
    523 	const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const;
    524 	TiXmlNode* IterateChildren( const char * value, TiXmlNode* previous );
    525 
    526     #ifdef TIXML_USE_STL
    527 	const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const	{	return IterateChildren (_value.c_str (), previous);	}	///< STL std::string form.
    528 	TiXmlNode* IterateChildren( const std::string& _value, TiXmlNode* previous ) {	return IterateChildren (_value.c_str (), previous);	}	///< STL std::string form.
    529 	#endif
    530 
    531 	/** Add a new node related to this. Adds a child past the LastChild.
    532 		Returns a pointer to the new object or NULL if an error occured.
    533 	*/
    534 	TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
    535 
    536 
    537 	/** Add a new node related to this. Adds a child past the LastChild.
    538 
    539 		NOTE: the node to be added is passed by pointer, and will be
    540 		henceforth owned (and deleted) by tinyXml. This method is efficient
    541 		and avoids an extra copy, but should be used with care as it
    542 		uses a different memory model than the other insert functions.
    543 
    544 		@sa InsertEndChild
    545 	*/
    546 	TiXmlNode* LinkEndChild( TiXmlNode* addThis );
    547 
    548 	/** Add a new node related to this. Adds a child before the specified child.
    549 		Returns a pointer to the new object or NULL if an error occured.
    550 	*/
    551 	TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
    552 
    553 	/** Add a new node related to this. Adds a child after the specified child.
    554 		Returns a pointer to the new object or NULL if an error occured.
    555 	*/
    556 	TiXmlNode* InsertAfterChild(  TiXmlNode* afterThis, const TiXmlNode& addThis );
    557 
    558 	/** Replace a child of this node.
    559 		Returns a pointer to the new object or NULL if an error occured.
    560 	*/
    561 	TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
    562 
    563 	/// Delete a child of this node.
    564 	bool RemoveChild( TiXmlNode* removeThis );
    565 
    566 	/// Navigate to a sibling node.
    567 	const TiXmlNode* PreviousSibling() const			{ return prev; }
    568 	TiXmlNode* PreviousSibling()						{ return prev; }
    569 
    570 	/// Navigate to a sibling node.
    571 	const TiXmlNode* PreviousSibling( const char * ) const;
    572 	TiXmlNode* PreviousSibling( const char * );
    573 
    574     #ifdef TIXML_USE_STL
    575 	const TiXmlNode* PreviousSibling( const std::string& _value ) const	{	return PreviousSibling (_value.c_str ());	}	///< STL std::string form.
    576 	TiXmlNode* PreviousSibling( const std::string& _value ) 			{	return PreviousSibling (_value.c_str ());	}	///< STL std::string form.
    577 	const TiXmlNode* NextSibling( const std::string& _value) const		{	return NextSibling (_value.c_str ());	}	///< STL std::string form.
    578 	TiXmlNode* NextSibling( const std::string& _value) 					{	return NextSibling (_value.c_str ());	}	///< STL std::string form.
    579 	#endif
    580 
    581 	/// Navigate to a sibling node.
    582 	const TiXmlNode* NextSibling() const				{ return next; }
    583 	TiXmlNode* NextSibling()							{ return next; }
    584 
    585 	/// Navigate to a sibling node with the given 'value'.
    586 	const TiXmlNode* NextSibling( const char * ) const;
    587 	TiXmlNode* NextSibling( const char * );
    588 
    589 	/** Convenience function to get through elements.
    590 		Calls NextSibling and ToElement. Will skip all non-Element
    591 		nodes. Returns 0 if there is not another element.
    592 	*/
    593 	const TiXmlElement* NextSiblingElement() const;
    594 	TiXmlElement* NextSiblingElement();
    595 
    596 	/** Convenience function to get through elements.
    597 		Calls NextSibling and ToElement. Will skip all non-Element
    598 		nodes. Returns 0 if there is not another element.
    599 	*/
    600 	const TiXmlElement* NextSiblingElement( const char * ) const;
    601 	TiXmlElement* NextSiblingElement( const char * );
    602 
    603     #ifdef TIXML_USE_STL
    604 	const TiXmlElement* NextSiblingElement( const std::string& _value) const	{	return NextSiblingElement (_value.c_str ());	}	///< STL std::string form.
    605 	TiXmlElement* NextSiblingElement( const std::string& _value)				{	return NextSiblingElement (_value.c_str ());	}	///< STL std::string form.
    606 	#endif
    607 
    608 	/// Convenience function to get through elements.
    609 	const TiXmlElement* FirstChildElement()	const;
    610 	TiXmlElement* FirstChildElement();
    611 
    612 	/// Convenience function to get through elements.
    613 	const TiXmlElement* FirstChildElement( const char * value ) const;
    614 	TiXmlElement* FirstChildElement( const char * value );
    615 
    616     #ifdef TIXML_USE_STL
    617 	const TiXmlElement* FirstChildElement( const std::string& _value ) const	{	return FirstChildElement (_value.c_str ());	}	///< STL std::string form.
    618 	TiXmlElement* FirstChildElement( const std::string& _value )				{	return FirstChildElement (_value.c_str ());	}	///< STL std::string form.
    619 	#endif
    620 
    621 	/** Query the type (as an enumerated value, above) of this node.
    622 		The possible types are: DOCUMENT, ELEMENT, COMMENT,
    623 								UNKNOWN, TEXT, and DECLARATION.
    624 	*/
    625 	virtual int Type() const	{ return type; }
    626 
    627 	/** Return a pointer to the Document this node lives in.
    628 		Returns null if not in a document.
    629 	*/
    630 	const TiXmlDocument* GetDocument() const;
    631 	TiXmlDocument* GetDocument();
    632 
    633 	/// Returns true if this node has no children.
    634 	bool NoChildren() const						{ return !firstChild; }
    635 
    636 	const TiXmlDocument* ToDocument()	const		{ return ( this && type == DOCUMENT ) ? (const TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
    637 	const TiXmlElement*  ToElement() const			{ return ( this && type == ELEMENT  ) ? (const TiXmlElement*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
    638 	const TiXmlComment*  ToComment() const			{ return ( this && type == COMMENT  ) ? (const TiXmlComment*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
    639 	const TiXmlUnknown*  ToUnknown() const			{ return ( this && type == UNKNOWN  ) ? (const TiXmlUnknown*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
    640 	const TiXmlText*	   ToText()    const		{ return ( this && type == TEXT     ) ? (const TiXmlText*)     this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
    641 	const TiXmlDeclaration* ToDeclaration() const	{ return ( this && type == DECLARATION ) ? (const TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
    642 
    643 	TiXmlDocument* ToDocument()			{ return ( this && type == DOCUMENT ) ? (TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
    644 	TiXmlElement*  ToElement()			{ return ( this && type == ELEMENT  ) ? (TiXmlElement*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
    645 	TiXmlComment*  ToComment()			{ return ( this && type == COMMENT  ) ? (TiXmlComment*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
    646 	TiXmlUnknown*  ToUnknown()			{ return ( this && type == UNKNOWN  ) ? (TiXmlUnknown*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
    647 	TiXmlText*	   ToText()   			{ return ( this && type == TEXT     ) ? (TiXmlText*)     this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
    648 	TiXmlDeclaration* ToDeclaration()	{ return ( this && type == DECLARATION ) ? (TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
    649 
    650 	/** Create an exact duplicate of this node and return it. The memory must be deleted
    651 		by the caller.
    652 	*/
    653 	virtual TiXmlNode* Clone() const = 0;
    654 
    655 protected:
    656 	TiXmlNode( NodeType _type );
    657 
    658 	// Copy to the allocated object. Shared functionality between Clone, Copy constructor,
    659 	// and the assignment operator.
    660 	void CopyTo( TiXmlNode* target ) const;
    661 
    662 	#ifdef TIXML_USE_STL
    663 	    // The real work of the input operator.
    664 	    virtual void StreamIn( TIXML_ISTREAM* in, TIXML_STRING* tag ) = 0;
    665 	#endif
    666 
    667 	// Figure out what is at *p, and parse it. Returns null if it is not an xml node.
    668 	TiXmlNode* Identify( const char* start, TiXmlEncoding encoding );
    669 
    670 	TiXmlNode*		parent;
    671 	NodeType		type;
    672 
    673 	TiXmlNode*		firstChild;
    674 	TiXmlNode*		lastChild;
    675 
    676 	TIXML_STRING	value;
    677 
    678 	TiXmlNode*		prev;
    679 	TiXmlNode*		next;
    680 
    681 private:
    682 	TiXmlNode( const TiXmlNode& );				// not implemented.
    683 	void operator=( const TiXmlNode& base );	// not allowed.
    684 };
    685 
    686 
    687 /** An attribute is a name-value pair. Elements have an arbitrary
    688 	number of attributes, each with a unique name.
    689 
    690 	@note The attributes are not TiXmlNodes, since they are not
    691 		  part of the tinyXML document object model. There are other
    692 		  suggested ways to look at this problem.
    693 */
    694 class TiXmlAttribute : public TiXmlBase
    695 {
    696 	friend class TiXmlAttributeSet;
    697 
    698 public:
    699 	/// Construct an empty attribute.
    700 	TiXmlAttribute() : TiXmlBase()
    701 	{
    702 		document = 0;
    703 		prev = next = 0;
    704 	}
    705 
    706 	#ifdef TIXML_USE_STL
    707 	/// std::string constructor.
    708 	TiXmlAttribute( const std::string& _name, const std::string& _value )
    709 	{
    710 		name = _name;
    711 		value = _value;
    712 		document = 0;
    713 		prev = next = 0;
    714 	}
    715 	#endif
    716 
    717 	/// Construct an attribute with a name and value.
    718 	TiXmlAttribute( const char * _name, const char * _value )
    719 	{
    720 		name = _name;
    721 		value = _value;
    722 		document = 0;
    723 		prev = next = 0;
    724 	}
    725 
    726 	const char*		Name()  const		{ return name.c_str (); }		///< Return the name of this attribute.
    727 	const char*		Value() const		{ return value.c_str (); }		///< Return the value of this attribute.
    728 	int				IntValue() const;									///< Return the value of this attribute, converted to an integer.
    729 	double			DoubleValue() const;								///< Return the value of this attribute, converted to a double.
    730 
    731 	/** QueryIntValue examines the value string. It is an alternative to the
    732 		IntValue() method with richer error checking.
    733 		If the value is an integer, it is stored in 'value' and
    734 		the call returns TIXML_SUCCESS. If it is not
    735 		an integer, it returns TIXML_WRONG_TYPE.
    736 
    737 		A specialized but useful call. Note that for success it returns 0,
    738 		which is the opposite of almost all other TinyXml calls.
    739 	*/
    740 	int QueryIntValue( int* _value ) const;
    741 	/// QueryDoubleValue examines the value string. See QueryIntValue().
    742 	int QueryDoubleValue( double* _value ) const;
    743 
    744 	void SetName( const char* _name )	{ name = _name; }				///< Set the name of this attribute.
    745 	void SetValue( const char* _value )	{ value = _value; }				///< Set the value.
    746 
    747 	void SetIntValue( int _value );										///< Set the value from an integer.
    748 	void SetDoubleValue( double _value );								///< Set the value from a double.
    749 
    750     #ifdef TIXML_USE_STL
    751 	/// STL std::string form.
    752 	void SetName( const std::string& _name )
    753 	{
    754 		StringToBuffer buf( _name );
    755 		SetName ( buf.buffer ? buf.buffer : "error" );
    756 	}
    757 	/// STL std::string form.
    758 	void SetValue( const std::string& _value )
    759 	{
    760 		StringToBuffer buf( _value );
    761 		SetValue( buf.buffer ? buf.buffer : "error" );
    762 	}
    763 	#endif
    764 
    765 	/// Get the next sibling attribute in the DOM. Returns null at end.
    766 	const TiXmlAttribute* Next() const;
    767 	TiXmlAttribute* Next();
    768 	/// Get the previous sibling attribute in the DOM. Returns null at beginning.
    769 	const TiXmlAttribute* Previous() const;
    770 	TiXmlAttribute* Previous();
    771 
    772 	bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
    773 	bool operator<( const TiXmlAttribute& rhs )	 const { return name < rhs.name; }
    774 	bool operator>( const TiXmlAttribute& rhs )  const { return name > rhs.name; }
    775 
    776 	/*	Attribute parsing starts: first letter of the name
    777 						 returns: the next char after the value end quote
    778 	*/
    779 	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
    780 
    781 	// Prints this Attribute to a FILE stream.
    782 	virtual void Print( FILE* cfile, int depth ) const;
    783 
    784 	virtual void StreamOut( TIXML_OSTREAM * out ) const;
    785 	// [internal use]
    786 	// Set the document pointer so the attribute can report errors.
    787 	void SetDocument( TiXmlDocument* doc )	{ document = doc; }
    788 
    789 private:
    790 	TiXmlAttribute( const TiXmlAttribute& );				// not implemented.
    791 	void operator=( const TiXmlAttribute& base );	// not allowed.
    792 
    793 	TiXmlDocument*	document;	// A pointer back to a document, for error reporting.
    794 	TIXML_STRING name;
    795 	TIXML_STRING value;
    796 	TiXmlAttribute*	prev;
    797 	TiXmlAttribute*	next;
    798 };
    799 
    800 
    801 /*	A class used to manage a group of attributes.
    802 	It is only used internally, both by the ELEMENT and the DECLARATION.
    803 
    804 	The set can be changed transparent to the Element and Declaration
    805 	classes that use it, but NOT transparent to the Attribute
    806 	which has to implement a next() and previous() method. Which makes
    807 	it a bit problematic and prevents the use of STL.
    808 
    809 	This version is implemented with circular lists because:
    810 		- I like circular lists
    811 		- it demonstrates some independence from the (typical) doubly linked list.
    812 */
    813 class TiXmlAttributeSet
    814 {
    815 public:
    816 	TiXmlAttributeSet();
    817 	~TiXmlAttributeSet();
    818 
    819 	void Add( TiXmlAttribute* attribute );
    820 	void Remove( TiXmlAttribute* attribute );
    821 
    822 	const TiXmlAttribute* First()	const	{ return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
    823 	TiXmlAttribute* First()					{ return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
    824 	const TiXmlAttribute* Last() const		{ return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
    825 	TiXmlAttribute* Last()					{ return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
    826 
    827 	const TiXmlAttribute*	Find( const char * name ) const;
    828 	TiXmlAttribute*	Find( const char * name );
    829 
    830 private:
    831 	//*ME:	Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),
    832 	//*ME:	this class must be also use a hidden/disabled copy-constructor !!!
    833 	TiXmlAttributeSet( const TiXmlAttributeSet& );	// not allowed
    834 	void operator=( const TiXmlAttributeSet& );	// not allowed (as TiXmlAttribute)
    835 
    836 	TiXmlAttribute sentinel;
    837 };
    838 
    839 
    840 /** The element is a container class. It has a value, the element name,
    841 	and can contain other elements, text, comments, and unknowns.
    842 	Elements also contain an arbitrary number of attributes.
    843 */
    844 class TiXmlElement : public TiXmlNode
    845 {
    846 public:
    847 	/// Construct an element.
    848 	TiXmlElement (const char * in_value);
    849 
    850 	#ifdef TIXML_USE_STL
    851 	/// std::string constructor.
    852 	TiXmlElement( const std::string& _value );
    853 	#endif
    854 
    855 	TiXmlElement( const TiXmlElement& );
    856 
    857 	void operator=( const TiXmlElement& base );
    858 
    859 	virtual ~TiXmlElement();
    860 
    861 	/** Given an attribute name, Attribute() returns the value
    862 		for the attribute of that name, or null if none exists.
    863 	*/
    864 	const char* Attribute( const char* name ) const;
    865 
    866 	/** Given an attribute name, Attribute() returns the value
    867 		for the attribute of that name, or null if none exists.
    868 		If the attribute exists and can be converted to an integer,
    869 		the integer value will be put in the return 'i', if 'i'
    870 		is non-null.
    871 	*/
    872 	const char* Attribute( const char* name, int* i ) const;
    873 
    874 	/** Given an attribute name, Attribute() returns the value
    875 		for the attribute of that name, or null if none exists.
    876 		If the attribute exists and can be converted to an double,
    877 		the double value will be put in the return 'd', if 'd'
    878 		is non-null.
    879 	*/
    880 	const char* Attribute( const char* name, double* d ) const;
    881 
    882 	/** QueryIntAttribute examines the attribute - it is an alternative to the
    883 		Attribute() method with richer error checking.
    884 		If the attribute is an integer, it is stored in 'value' and
    885 		the call returns TIXML_SUCCESS. If it is not
    886 		an integer, it returns TIXML_WRONG_TYPE. If the attribute
    887 		does not exist, then TIXML_NO_ATTRIBUTE is returned.
    888 	*/
    889 	int QueryIntAttribute( const char* name, int* _value ) const;
    890 	/// QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
    891 	int QueryDoubleAttribute( const char* name, double* _value ) const;
    892 	/// QueryFloatAttribute examines the attribute - see QueryIntAttribute().
    893 	int QueryFloatAttribute( const char* name, float* _value ) const {
    894 		double d;
    895 		int result = QueryDoubleAttribute( name, &d );
    896 		if ( result == TIXML_SUCCESS ) {
    897 			*_value = (float)d;
    898 		}
    899 		return result;
    900 	}
    901 
    902 	/** Sets an attribute of name to a given value. The attribute
    903 		will be created if it does not exist, or changed if it does.
    904 	*/
    905 	void SetAttribute( const char* name, const char * _value );
    906 
    907     #ifdef TIXML_USE_STL
    908 	const char* Attribute( const std::string& name ) const				{ return Attribute( name.c_str() ); }
    909 	const char* Attribute( const std::string& name, int* i ) const		{ return Attribute( name.c_str(), i ); }
    910 	const char* Attribute( const std::string& name, double* d ) const	{ return Attribute( name.c_str(), d ); }
    911 	int QueryIntAttribute( const std::string& name, int* _value ) const	{ return QueryIntAttribute( name.c_str(), _value ); }
    912 	int QueryDoubleAttribute( const std::string& name, double* _value ) const { return QueryDoubleAttribute( name.c_str(), _value ); }
    913 
    914 	/// STL std::string form.
    915 	void SetAttribute( const std::string& name, const std::string& _value )
    916 	{
    917 		StringToBuffer n( name );
    918 		StringToBuffer v( _value );
    919 		if ( n.buffer && v.buffer )
    920 			SetAttribute (n.buffer, v.buffer );
    921 	}
    922 	///< STL std::string form.
    923 	void SetAttribute( const std::string& name, int _value )
    924 	{
    925 		StringToBuffer n( name );
    926 		if ( n.buffer )
    927 			SetAttribute (n.buffer, _value);
    928 	}
    929 	#endif
    930 
    931 	/** Sets an attribute of name to a given value. The attribute
    932 		will be created if it does not exist, or changed if it does.
    933 	*/
    934 	void SetAttribute( const char * name, int value );
    935 
    936 	/** Sets an attribute of name to a given value. The attribute
    937 		will be created if it does not exist, or changed if it does.
    938 	*/
    939 	void SetDoubleAttribute( const char * name, double value );
    940 
    941 	/** Deletes an attribute with the given name.
    942 	*/
    943 	void RemoveAttribute( const char * name );
    944     #ifdef TIXML_USE_STL
    945 	void RemoveAttribute( const std::string& name )	{	RemoveAttribute (name.c_str ());	}	///< STL std::string form.
    946 	#endif
    947 
    948 	const TiXmlAttribute* FirstAttribute() const	{ return attributeSet.First(); }		///< Access the first attribute in this element.
    949 	TiXmlAttribute* FirstAttribute() 				{ return attributeSet.First(); }
    950 	const TiXmlAttribute* LastAttribute()	const 	{ return attributeSet.Last(); }		///< Access the last attribute in this element.
    951 	TiXmlAttribute* LastAttribute()					{ return attributeSet.Last(); }
    952 
    953 	/** Convenience function for easy access to the text inside an element. Although easy
    954 		and concise, GetText() is limited compared to getting the TiXmlText child
    955 		and accessing it directly.
    956 
    957 		If the first child of 'this' is a TiXmlText, the GetText()
    958 		returs the character string of the Text node, else null is returned.
    959 
    960 		This is a convenient method for getting the text of simple contained text:
    961 		@verbatim
    962 		<foo>This is text</foo>
    963 		const char* str = fooElement->GetText();
    964 		@endverbatim
    965 
    966 		'str' will be a pointer to "This is text".
    967 
    968 		Note that this function can be misleading. If the element foo was created from
    969 		this XML:
    970 		@verbatim
    971 		<foo><b>This is text</b></foo>
    972 		@endverbatim
    973 
    974 		then the value of str would be null. The first child node isn't a text node, it is
    975 		another element. From this XML:
    976 		@verbatim
    977 		<foo>This is <b>text</b></foo>
    978 		@endverbatim
    979 		GetText() will return "This is ".
    980 
    981 		WARNING: GetText() accesses a child node - don't become confused with the
    982 				 similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are
    983 				 safe type casts on the referenced node.
    984 	*/
    985 	const char* GetText() const;
    986 
    987 	/// Creates a new Element and returns it - the returned element is a copy.
    988 	virtual TiXmlNode* Clone() const;
    989 	// Print the Element to a FILE stream.
    990 	virtual void Print( FILE* cfile, int depth ) const;
    991 
    992 	/*	Attribtue parsing starts: next char past '<'
    993 						 returns: next char past '>'
    994 	*/
    995 	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
    996 
    997 protected:
    998 
    999 	void CopyTo( TiXmlElement* target ) const;
   1000 	void ClearThis();	// like clear, but initializes 'this' object as well
   1001 
   1002 	// Used to be public [internal use]
   1003 	#ifdef TIXML_USE_STL
   1004 	    virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
   1005 	#endif
   1006 	virtual void StreamOut( TIXML_OSTREAM * out ) const;
   1007 
   1008 	/*	[internal use]
   1009 		Reads the "value" of the element -- another element, or text.
   1010 		This should terminate with the current end tag.
   1011 	*/
   1012 	const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
   1013 
   1014 private:
   1015 
   1016 	TiXmlAttributeSet attributeSet;
   1017 };
   1018 
   1019 
   1020 /**	An XML comment.
   1021 */
   1022 class TiXmlComment : public TiXmlNode
   1023 {
   1024 public:
   1025 	/// Constructs an empty comment.
   1026 	TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {}
   1027 	TiXmlComment( const TiXmlComment& );
   1028 	void operator=( const TiXmlComment& base );
   1029 
   1030 	virtual ~TiXmlComment()	{}
   1031 
   1032 	/// Returns a copy of this Comment.
   1033 	virtual TiXmlNode* Clone() const;
   1034 	/// Write this Comment to a FILE stream.
   1035 	virtual void Print( FILE* cfile, int depth ) const;
   1036 
   1037 	/*	Attribtue parsing starts: at the ! of the !--
   1038 						 returns: next char past '>'
   1039 	*/
   1040 	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
   1041 
   1042 protected:
   1043 	void CopyTo( TiXmlComment* target ) const;
   1044 
   1045 	// used to be public
   1046 	#ifdef TIXML_USE_STL
   1047 	    virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
   1048 	#endif
   1049 	virtual void StreamOut( TIXML_OSTREAM * out ) const;
   1050 
   1051 private:
   1052 
   1053 };
   1054 
   1055 
   1056 /** XML text. A text node can have 2 ways to output the next. "normal" output
   1057 	and CDATA. It will default to the mode it was parsed from the XML file and
   1058 	you generally want to leave it alone, but you can change the output mode with
   1059 	SetCDATA() and query it with CDATA().
   1060 */
   1061 class TiXmlText : public TiXmlNode
   1062 {
   1063 	friend class TiXmlElement;
   1064 public:
   1065 	/** Constructor for text element. By default, it is treated as
   1066 		normal, encoded text. If you want it be output as a CDATA text
   1067 		element, set the parameter _cdata to 'true'
   1068 	*/
   1069 	TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TEXT)
   1070 	{
   1071 		SetValue( initValue );
   1072 		cdata = false;
   1073 	}
   1074 	virtual ~TiXmlText() {}
   1075 
   1076 	#ifdef TIXML_USE_STL
   1077 	/// Constructor.
   1078 	TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT)
   1079 	{
   1080 		SetValue( initValue );
   1081 		cdata = false;
   1082 	}
   1083 	#endif
   1084 
   1085 	TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT )	{ copy.CopyTo( this ); }
   1086 	void operator=( const TiXmlText& base )							 	{ base.CopyTo( this ); }
   1087 
   1088 	/// Write this text object to a FILE stream.
   1089 	virtual void Print( FILE* cfile, int depth ) const;
   1090 
   1091 	/// Queries whether this represents text using a CDATA section.
   1092 	bool CDATA()					{ return cdata; }
   1093 	/// Turns on or off a CDATA representation of text.
   1094 	void SetCDATA( bool _cdata )	{ cdata = _cdata; }
   1095 
   1096 	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
   1097 
   1098 protected :
   1099 	///  [internal use] Creates a new Element and returns it.
   1100 	virtual TiXmlNode* Clone() const;
   1101 	void CopyTo( TiXmlText* target ) const;
   1102 
   1103 	virtual void StreamOut ( TIXML_OSTREAM * out ) const;
   1104 	bool Blank() const;	// returns true if all white space and new lines
   1105 	// [internal use]
   1106 	#ifdef TIXML_USE_STL
   1107 	    virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
   1108 	#endif
   1109 
   1110 private:
   1111 	bool cdata;			// true if this should be input and output as a CDATA style text element
   1112 };
   1113 
   1114 
   1115 /** In correct XML the declaration is the first entry in the file.
   1116 	@verbatim
   1117 		<?xml version="1.0" standalone="yes"?>
   1118 	@endverbatim
   1119 
   1120 	TinyXml will happily read or write files without a declaration,
   1121 	however. There are 3 possible attributes to the declaration:
   1122 	version, encoding, and standalone.
   1123 
   1124 	Note: In this version of the code, the attributes are
   1125 	handled as special cases, not generic attributes, simply
   1126 	because there can only be at most 3 and they are always the same.
   1127 */
   1128 class TiXmlDeclaration : public TiXmlNode
   1129 {
   1130 public:
   1131 	/// Construct an empty declaration.
   1132 	TiXmlDeclaration()   : TiXmlNode( TiXmlNode::DECLARATION ) {}
   1133 
   1134 #ifdef TIXML_USE_STL
   1135 	/// Constructor.
   1136 	TiXmlDeclaration(	const std::string& _version,
   1137 						const std::string& _encoding,
   1138 						const std::string& _standalone );
   1139 #endif
   1140 
   1141 	/// Construct.
   1142 	TiXmlDeclaration(	const char* _version,
   1143 						const char* _encoding,
   1144 						const char* _standalone );
   1145 
   1146 	TiXmlDeclaration( const TiXmlDeclaration& copy );
   1147 	void operator=( const TiXmlDeclaration& copy );
   1148 
   1149 	virtual ~TiXmlDeclaration()	{}
   1150 
   1151 	/// Version. Will return an empty string if none was found.
   1152 	const char *Version() const			{ return version.c_str (); }
   1153 	/// Encoding. Will return an empty string if none was found.
   1154 	const char *Encoding() const		{ return encoding.c_str (); }
   1155 	/// Is this a standalone document?
   1156 	const char *Standalone() const		{ return standalone.c_str (); }
   1157 
   1158 	/// Creates a copy of this Declaration and returns it.
   1159 	virtual TiXmlNode* Clone() const;
   1160 	/// Print this declaration to a FILE stream.
   1161 	virtual void Print( FILE* cfile, int depth ) const;
   1162 
   1163 	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
   1164 
   1165 protected:
   1166 	void CopyTo( TiXmlDeclaration* target ) const;
   1167 	// used to be public
   1168 	#ifdef TIXML_USE_STL
   1169 	    virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
   1170 	#endif
   1171 	virtual void StreamOut ( TIXML_OSTREAM * out) const;
   1172 
   1173 private:
   1174 
   1175 	TIXML_STRING version;
   1176 	TIXML_STRING encoding;
   1177 	TIXML_STRING standalone;
   1178 };
   1179 
   1180 
   1181 /** Any tag that tinyXml doesn't recognize is saved as an
   1182 	unknown. It is a tag of text, but should not be modified.
   1183 	It will be written back to the XML, unchanged, when the file
   1184 	is saved.
   1185 
   1186 	DTD tags get thrown into TiXmlUnknowns.
   1187 */
   1188 class TiXmlUnknown : public TiXmlNode
   1189 {
   1190 public:
   1191 	TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN )	{}
   1192 	virtual ~TiXmlUnknown() {}
   1193 
   1194 	TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN )		{ copy.CopyTo( this ); }
   1195 	void operator=( const TiXmlUnknown& copy )										{ copy.CopyTo( this ); }
   1196 
   1197 	/// Creates a copy of this Unknown and returns it.
   1198 	virtual TiXmlNode* Clone() const;
   1199 	/// Print this Unknown to a FILE stream.
   1200 	virtual void Print( FILE* cfile, int depth ) const;
   1201 
   1202 	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
   1203 
   1204 protected:
   1205 	void CopyTo( TiXmlUnknown* target ) const;
   1206 
   1207 	#ifdef TIXML_USE_STL
   1208 	    virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
   1209 	#endif
   1210 	virtual void StreamOut ( TIXML_OSTREAM * out ) const;
   1211 
   1212 private:
   1213 
   1214 };
   1215 
   1216 
   1217 /** Always the top level node. A document binds together all the
   1218 	XML pieces. It can be saved, loaded, and printed to the screen.
   1219 	The 'value' of a document node is the xml file name.
   1220 */
   1221 class TiXmlDocument : public TiXmlNode
   1222 {
   1223 public:
   1224 	/// Create an empty document, that has no name.
   1225 	TiXmlDocument();
   1226 	/// Create a document with a name. The name of the document is also the filename of the xml.
   1227 	TiXmlDocument( const char * documentName );
   1228 
   1229 	#ifdef TIXML_USE_STL
   1230 	/// Constructor.
   1231 	TiXmlDocument( const std::string& documentName );
   1232 	#endif
   1233 
   1234 	TiXmlDocument( const TiXmlDocument& copy );
   1235 	void operator=( const TiXmlDocument& copy );
   1236 
   1237 	virtual ~TiXmlDocument() {}
   1238 
   1239 	/** Load a file using the current document value.
   1240 		Returns true if successful. Will delete any existing
   1241 		document data before loading.
   1242 	*/
   1243 	bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
   1244 	/// Save a file using the current document value. Returns true if successful.
   1245 	bool SaveFile() const;
   1246 	/// Load a file using the given filename. Returns true if successful.
   1247 	bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
   1248 	/// Save a file using the given filename. Returns true if successful.
   1249 	bool SaveFile( const char * filename ) const;
   1250 
   1251 	#ifdef TIXML_USE_STL
   1252 	bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING )			///< STL std::string version.
   1253 	{
   1254 		StringToBuffer f( filename );
   1255 		return ( f.buffer && LoadFile( f.buffer, encoding ));
   1256 	}
   1257 	bool SaveFile( const std::string& filename ) const		///< STL std::string version.
   1258 	{
   1259 		StringToBuffer f( filename );
   1260 		return ( f.buffer && SaveFile( f.buffer ));
   1261 	}
   1262 	#endif
   1263 
   1264 	/** Parse the given null terminated block of xml data. Passing in an encoding to this
   1265 		method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml
   1266 		to use that encoding, regardless of what TinyXml might otherwise try to detect.
   1267 	*/
   1268 	virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
   1269 
   1270 	/** Get the root element -- the only top level element -- of the document.
   1271 		In well formed XML, there should only be one. TinyXml is tolerant of
   1272 		multiple elements at the document level.
   1273 	*/
   1274 	const TiXmlElement* RootElement() const		{ return FirstChildElement(); }
   1275 	TiXmlElement* RootElement()					{ return FirstChildElement(); }
   1276 
   1277 	/** If an error occurs, Error will be set to true. Also,
   1278 		- The ErrorId() will contain the integer identifier of the error (not generally useful)
   1279 		- The ErrorDesc() method will return the name of the error. (very useful)
   1280 		- The ErrorRow() and ErrorCol() will return the location of the error (if known)
   1281 	*/
   1282 	bool Error() const						{ return error; }
   1283 
   1284 	/// Contains a textual (english) description of the error if one occurs.
   1285 	const char * ErrorDesc() const	{ return errorDesc.c_str (); }
   1286 
   1287 	/** Generally, you probably want the error string ( ErrorDesc() ). But if you
   1288 		prefer the ErrorId, this function will fetch it.
   1289 	*/
   1290 	int ErrorId()	const				{ return errorId; }
   1291 
   1292 	/** Returns the location (if known) of the error. The first column is column 1,
   1293 		and the first row is row 1. A value of 0 means the row and column wasn't applicable
   1294 		(memory errors, for example, have no row/column) or the parser lost the error. (An
   1295 		error in the error reporting, in that case.)
   1296 
   1297 		@sa SetTabSize, Row, Column
   1298 	*/
   1299 	int ErrorRow()	{ return errorLocation.row+1; }
   1300 	int ErrorCol()	{ return errorLocation.col+1; }	///< The column where the error occured. See ErrorRow()
   1301 
   1302 	/** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol())
   1303 		to report the correct values for row and column. It does not change the output
   1304 		or input in any way.
   1305 
   1306 		By calling this method, with a tab size
   1307 		greater than 0, the row and column of each node and attribute is stored
   1308 		when the file is loaded. Very useful for tracking the DOM back in to
   1309 		the source file.
   1310 
   1311 		The tab size is required for calculating the location of nodes. If not
   1312 		set, the default of 4 is used. The tabsize is set per document. Setting
   1313 		the tabsize to 0 disables row/column tracking.
   1314 
   1315 		Note that row and column tracking is not supported when using operator>>.
   1316 
   1317 		The tab size needs to be enabled before the parse or load. Correct usage:
   1318 		@verbatim
   1319 		TiXmlDocument doc;
   1320 		doc.SetTabSize( 8 );
   1321 		doc.Load( "myfile.xml" );
   1322 		@endverbatim
   1323 
   1324 		@sa Row, Column
   1325 	*/
   1326 	void SetTabSize( int _tabsize )		{ tabsize = _tabsize; }
   1327 
   1328 	int TabSize() const	{ return tabsize; }
   1329 
   1330 	/** If you have handled the error, it can be reset with this call. The error
   1331 		state is automatically cleared if you Parse a new XML block.
   1332 	*/
   1333 	void ClearError()						{	error = false;
   1334 												errorId = 0;
   1335 												errorDesc = "";
   1336 												errorLocation.row = errorLocation.col = 0;
   1337 												//errorLocation.last = 0;
   1338 											}
   1339 
   1340 	/** Dump the document to standard out. */
   1341 	void Print() const						{ Print( stdout, 0 ); }
   1342 
   1343 	/// Print this Document to a FILE stream.
   1344 	virtual void Print( FILE* cfile, int depth = 0 ) const;
   1345 	// [internal use]
   1346 	void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
   1347 
   1348 protected :
   1349 	virtual void StreamOut ( TIXML_OSTREAM * out) const;
   1350 	// [internal use]
   1351 	virtual TiXmlNode* Clone() const;
   1352 	#ifdef TIXML_USE_STL
   1353 	    virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
   1354 	#endif
   1355 
   1356 private:
   1357 	void CopyTo( TiXmlDocument* target ) const;
   1358 
   1359 	bool error;
   1360 	int  errorId;
   1361 	TIXML_STRING errorDesc;
   1362 	int tabsize;
   1363 	TiXmlCursor errorLocation;
   1364 	bool useMicrosoftBOM;		// the UTF-8 BOM were found when read. Note this, and try to write.
   1365 };
   1366 
   1367 
   1368 /**
   1369 	A TiXmlHandle is a class that wraps a node pointer with null checks; this is
   1370 	an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml
   1371 	DOM structure. It is a separate utility class.
   1372 
   1373 	Take an example:
   1374 	@verbatim
   1375 	<Document>
   1376 		<Element attributeA = "valueA">
   1377 			<Child attributeB = "value1" />
   1378 			<Child attributeB = "value2" />
   1379 		</Element>
   1380 	<Document>
   1381 	@endverbatim
   1382 
   1383 	Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very
   1384 	easy to write a *lot* of code that looks like:
   1385 
   1386 	@verbatim
   1387 	TiXmlElement* root = document.FirstChildElement( "Document" );
   1388 	if ( root )
   1389 	{
   1390 		TiXmlElement* element = root->FirstChildElement( "Element" );
   1391 		if ( element )
   1392 		{
   1393 			TiXmlElement* child = element->FirstChildElement( "Child" );
   1394 			if ( child )
   1395 			{
   1396 				TiXmlElement* child2 = child->NextSiblingElement( "Child" );
   1397 				if ( child2 )
   1398 				{
   1399 					// Finally do something useful.
   1400 	@endverbatim
   1401 
   1402 	And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity
   1403 	of such code. A TiXmlHandle checks for null	pointers so it is perfectly safe
   1404 	and correct to use:
   1405 
   1406 	@verbatim
   1407 	TiXmlHandle docHandle( &document );
   1408 	TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).Element();
   1409 	if ( child2 )
   1410 	{
   1411 		// do something useful
   1412 	@endverbatim
   1413 
   1414 	Which is MUCH more concise and useful.
   1415 
   1416 	It is also safe to copy handles - internally they are nothing more than node pointers.
   1417 	@verbatim
   1418 	TiXmlHandle handleCopy = handle;
   1419 	@endverbatim
   1420 
   1421 	What they should not be used for is iteration:
   1422 
   1423 	@verbatim
   1424 	int i=0;
   1425 	while ( true )
   1426 	{
   1427 		TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).Element();
   1428 		if ( !child )
   1429 			break;
   1430 		// do something
   1431 		++i;
   1432 	}
   1433 	@endverbatim
   1434 
   1435 	It seems reasonable, but it is in fact two embedded while loops. The Child method is
   1436 	a linear walk to find the element, so this code would iterate much more than it needs
   1437 	to. Instead, prefer:
   1438 
   1439 	@verbatim
   1440 	TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).Element();
   1441 
   1442 	for( child; child; child=child->NextSiblingElement() )
   1443 	{
   1444 		// do something
   1445 	}
   1446 	@endverbatim
   1447 */
   1448 class TiXmlHandle
   1449 {
   1450 public:
   1451 	/// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
   1452 	TiXmlHandle( TiXmlNode* _node )					{ this->node = _node; }
   1453 	/// Copy constructor
   1454 	TiXmlHandle( const TiXmlHandle& ref )			{ this->node = ref.node; }
   1455 	TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; }
   1456 
   1457 	/// Return a handle to the first child node.
   1458 	TiXmlHandle FirstChild() const;
   1459 	/// Return a handle to the first child node with the given name.
   1460 	TiXmlHandle FirstChild( const char * value ) const;
   1461 	/// Return a handle to the first child element.
   1462 	TiXmlHandle FirstChildElement() const;
   1463 	/// Return a handle to the first child element with the given name.
   1464 	TiXmlHandle FirstChildElement( const char * value ) const;
   1465 
   1466 	/** Return a handle to the "index" child with the given name.
   1467 		The first child is 0, the second 1, etc.
   1468 	*/
   1469 	TiXmlHandle Child( const char* value, int index ) const;
   1470 	/** Return a handle to the "index" child.
   1471 		The first child is 0, the second 1, etc.
   1472 	*/
   1473 	TiXmlHandle Child( int index ) const;
   1474 	/** Return a handle to the "index" child element with the given name.
   1475 		The first child element is 0, the second 1, etc. Note that only TiXmlElements
   1476 		are indexed: other types are not counted.
   1477 	*/
   1478 	TiXmlHandle ChildElement( const char* value, int index ) const;
   1479 	/** Return a handle to the "index" child element.
   1480 		The first child element is 0, the second 1, etc. Note that only TiXmlElements
   1481 		are indexed: other types are not counted.
   1482 	*/
   1483 	TiXmlHandle ChildElement( int index ) const;
   1484 
   1485 	#ifdef TIXML_USE_STL
   1486 	TiXmlHandle FirstChild( const std::string& _value ) const				{ return FirstChild( _value.c_str() ); }
   1487 	TiXmlHandle FirstChildElement( const std::string& _value ) const		{ return FirstChildElement( _value.c_str() ); }
   1488 
   1489 	TiXmlHandle Child( const std::string& _value, int index ) const			{ return Child( _value.c_str(), index ); }
   1490 	TiXmlHandle ChildElement( const std::string& _value, int index ) const	{ return ChildElement( _value.c_str(), index ); }
   1491 	#endif
   1492 
   1493 	/// Return the handle as a TiXmlNode. This may return null.
   1494 	TiXmlNode* Node() const			{ return node; }
   1495 	/// Return the handle as a TiXmlElement. This may return null.
   1496 	TiXmlElement* Element() const	{ return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
   1497 	/// Return the handle as a TiXmlText. This may return null.
   1498 	TiXmlText* Text() const			{ return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
   1499 	/// Return the handle as a TiXmlUnknown. This may return null;
   1500 	TiXmlUnknown* Unknown() const			{ return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
   1501 
   1502 private:
   1503 	TiXmlNode* node;
   1504 };
   1505 
   1506 #ifdef _MSC_VER
   1507 #pragma warning( pop )
   1508 #endif
   1509 
   1510 #endif
   1511 
   1512