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