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