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 //#define TIXML_USE_STL
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; i<*length && p[i]; ++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 occurred.
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 occurred.
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 occurred.
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 occurred.
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 	const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) override;
869 
870 	// Prints this Attribute to a FILE stream.
Print(FILE * cfile,int depth)871 	void Print( FILE* cfile, int depth ) const override
872     {
873 		Print( cfile, depth, 0 );
874 	}
875 	void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
876 
877 	// [internal use]
878 	// Set the document pointer so the attribute can report errors.
SetDocument(TiXmlDocument * doc)879 	void SetDocument( TiXmlDocument* doc )	{ document = doc; }
880 
881 private:
882 	TiXmlAttribute( const TiXmlAttribute& );				// not implemented.
883 	void operator=( const TiXmlAttribute& base );	// not allowed.
884 
885 	TiXmlDocument*	document;	// A pointer back to a document, for error reporting.
886 	TIXML_STRING name;
887 	TIXML_STRING value;
888 	TiXmlAttribute*	prev;
889 	TiXmlAttribute*	next;
890 };
891 
892 
893 /*	A class used to manage a group of attributes.
894 	It is only used internally, both by the ELEMENT and the DECLARATION.
895 
896 	The set can be changed transparent to the Element and Declaration
897 	classes that use it, but NOT transparent to the Attribute
898 	which has to implement a next() and previous() method. Which makes
899 	it a bit problematic and prevents the use of STL.
900 
901 	This version is implemented with circular lists because:
902 		- I like circular lists
903 		- it demonstrates some independence from the (typical) doubly linked list.
904 */
905 class TiXmlAttributeSet
906 {
907 public:
908 	TiXmlAttributeSet();
909 	~TiXmlAttributeSet();
910 
911 	void Add( TiXmlAttribute* attribute );
912 	void Remove( TiXmlAttribute* attribute );
913 
First()914 	const TiXmlAttribute* First()	const	{ return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
First()915 	TiXmlAttribute* First()					{ return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
Last()916 	const TiXmlAttribute* Last() const		{ return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
Last()917 	TiXmlAttribute* Last()					{ return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
918 
919 	const TiXmlAttribute*	Find( const char* _name ) const;
Find(const char * _name)920 	TiXmlAttribute*	Find( const char* _name ) {
921 		return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) );
922 	}
923 	#ifdef TIXML_USE_STL
924 	const TiXmlAttribute*	Find( const std::string& _name ) const;
Find(const std::string & _name)925 	TiXmlAttribute*	Find( const std::string& _name ) {
926 		return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) );
927 	}
928 
929 	#endif
930 
931 private:
932 	//*ME:	Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),
933 	//*ME:	this class must be also use a hidden/disabled copy-constructor !!!
934 	TiXmlAttributeSet( const TiXmlAttributeSet& );	// not allowed
935 	void operator=( const TiXmlAttributeSet& );	// not allowed (as TiXmlAttribute)
936 
937 	TiXmlAttribute sentinel;
938 };
939 
940 
941 /** The element is a container class. It has a value, the element name,
942 	and can contain other elements, text, comments, and unknowns.
943 	Elements also contain an arbitrary number of attributes.
944 */
945 class TiXmlElement : public TiXmlNode
946 {
947 public:
948 	/// Construct an element.
949 	TiXmlElement (const char * in_value);
950 
951 	#ifdef TIXML_USE_STL
952 	/// std::string constructor.
953 	TiXmlElement( const std::string& _value );
954 	#endif
955 
956 	TiXmlElement( const TiXmlElement& );
957 
958 	void operator=( const TiXmlElement& base );
959 
960 	virtual ~TiXmlElement();
961 
962 	/** Given an attribute name, Attribute() returns the value
963 		for the attribute of that name, or null if none exists.
964 	*/
965 	const char* Attribute( const char* name ) const;
966 
967 	/** Given an attribute name, Attribute() returns the value
968 		for the attribute of that name, or null if none exists.
969 		If the attribute exists and can be converted to an integer,
970 		the integer value will be put in the return 'i', if 'i'
971 		is non-null.
972 	*/
973 	const char* Attribute( const char* name, int* i ) const;
974 
975 	/** Given an attribute name, Attribute() returns the value
976 		for the attribute of that name, or null if none exists.
977 		If the attribute exists and can be converted to an double,
978 		the double value will be put in the return 'd', if 'd'
979 		is non-null.
980 	*/
981 	const char* Attribute( const char* name, double* d ) const;
982 
983 	/** QueryIntAttribute examines the attribute - it is an alternative to the
984 		Attribute() method with richer error checking.
985 		If the attribute is an integer, it is stored in 'value' and
986 		the call returns TIXML_SUCCESS. If it is not
987 		an integer, it returns TIXML_WRONG_TYPE. If the attribute
988 		does not exist, then TIXML_NO_ATTRIBUTE is returned.
989 	*/
990 	int QueryIntAttribute( const char* name, int* _value ) const;
991 	/// QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
992 	int QueryDoubleAttribute( const char* name, double* _value ) const;
993 	/// QueryFloatAttribute examines the attribute - see QueryIntAttribute().
QueryFloatAttribute(const char * name,float * _value)994 	int QueryFloatAttribute( const char* name, float* _value ) const {
995 		double d;
996 		int result = QueryDoubleAttribute( name, &d );
997 		if ( result == TIXML_SUCCESS ) {
998 			*_value = (float)d;
999 		}
1000 		return result;
1001 	}
1002 
1003 	#ifdef TIXML_USE_STL
1004 	/** Template form of the attribute query which will try to read the
1005 		attribute into the specified type. Very easy, very powerful, but
1006 		be careful to make sure to call this with the correct type.
1007 
1008 		NOTE: This method doesn't work correctly for 'string' types.
1009 
1010 		@return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE
1011 	*/
QueryValueAttribute(const std::string & name,T * outValue)1012 	template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const
1013 	{
1014 		const TiXmlAttribute* node = attributeSet.Find( name );
1015 		if ( !node )
1016 			return TIXML_NO_ATTRIBUTE;
1017 
1018 		std::stringstream sstream( node->ValueStr() );
1019 		sstream >> *outValue;
1020 		if ( !sstream.fail() )
1021 			return TIXML_SUCCESS;
1022 		return TIXML_WRONG_TYPE;
1023 	}
1024 	/*
1025 	 This is - in theory - a bug fix for "QueryValueAtribute returns truncated std::string"
1026 	 but template specialization is hard to get working cross-compiler. Leaving the bug for now.
1027 
1028 	// The above will fail for std::string because the space character is used as a seperator.
1029 	// Specialize for strings. Bug [ 1695429 ] QueryValueAtribute returns truncated std::string
1030 	template<> int QueryValueAttribute( const std::string& name, std::string* outValue ) const
1031 	{
1032 		const TiXmlAttribute* node = attributeSet.Find( name );
1033 		if ( !node )
1034 			return TIXML_NO_ATTRIBUTE;
1035 		*outValue = node->ValueStr();
1036 		return TIXML_SUCCESS;
1037 	}
1038 	*/
1039 	#endif
1040 
1041 	/** Sets an attribute of name to a given value. The attribute
1042 		will be created if it does not exist, or changed if it does.
1043 	*/
1044 	void SetAttribute( const char* name, const char * _value );
1045 
1046 	#ifdef TIXML_USE_STL
1047 	const std::string* Attribute( const std::string& name ) const;
1048 	const std::string* Attribute( const std::string& name, int* i ) const;
1049 	const std::string* Attribute( const std::string& name, double* d ) const;
1050 	int QueryIntAttribute( const std::string& name, int* _value ) const;
1051 	int QueryDoubleAttribute( const std::string& name, double* _value ) const;
1052 
1053 	/// STL std::string form.
1054 	void SetAttribute( const std::string& name, const std::string& _value );
1055 	///< STL std::string form.
1056 	void SetAttribute( const std::string& name, int _value );
1057 	#endif
1058 
1059 	/** Sets an attribute of name to a given value. The attribute
1060 		will be created if it does not exist, or changed if it does.
1061 	*/
1062 	void SetAttribute( const char * name, int value );
1063 
1064 	/** Sets an attribute of name to a given value. The attribute
1065 		will be created if it does not exist, or changed if it does.
1066 	*/
1067 	void SetDoubleAttribute( const char * name, double value );
1068 
1069 	/** Deletes an attribute with the given name.
1070 	*/
1071 	void RemoveAttribute( const char * name );
1072 	#ifdef TIXML_USE_STL
RemoveAttribute(const std::string & name)1073 	void RemoveAttribute( const std::string& name )	{	RemoveAttribute (name.c_str ());	}	///< STL std::string form.
1074 	#endif
1075 
FirstAttribute()1076 	const TiXmlAttribute* FirstAttribute() const	{ return attributeSet.First(); }		///< Access the first attribute in this element.
FirstAttribute()1077 	TiXmlAttribute* FirstAttribute() 				{ return attributeSet.First(); }
LastAttribute()1078 	const TiXmlAttribute* LastAttribute()	const 	{ return attributeSet.Last(); }		///< Access the last attribute in this element.
LastAttribute()1079 	TiXmlAttribute* LastAttribute()					{ return attributeSet.Last(); }
1080 
1081 	/** Convenience function for easy access to the text inside an element. Although easy
1082 		and concise, GetText() is limited compared to getting the TiXmlText child
1083 		and accessing it directly.
1084 
1085 		If the first child of 'this' is a TiXmlText, the GetText()
1086 		returns the character string of the Text node, else null is returned.
1087 
1088 		This is a convenient method for getting the text of simple contained text:
1089 		@verbatim
1090 		<foo>This is text</foo>
1091 		const char* str = fooElement->GetText();
1092 		@endverbatim
1093 
1094 		'str' will be a pointer to "This is text".
1095 
1096 		Note that this function can be misleading. If the element foo was created from
1097 		this XML:
1098 		@verbatim
1099 		<foo><b>This is text</b></foo>
1100 		@endverbatim
1101 
1102 		then the value of str would be null. The first child node isn't a text node, it is
1103 		another element. From this XML:
1104 		@verbatim
1105 		<foo>This is <b>text</b></foo>
1106 		@endverbatim
1107 		GetText() will return "This is ".
1108 
1109 		WARNING: GetText() accesses a child node - don't become confused with the
1110 				 similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are
1111 				 safe type casts on the referenced node.
1112 	*/
1113 	const char* GetText() const;
1114 
1115 	/// Creates a new Element and returns it - the returned element is a copy.
1116 	TiXmlNode* Clone() const override;
1117 	// Print the Element to a FILE stream.
1118 	void Print( FILE* cfile, int depth ) const override;
1119 
1120 	/*	Attribtue parsing starts: next char past '<'
1121 						 returns: next char past '>'
1122 	*/
1123 	const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) override;
1124 
ToElement()1125 	const TiXmlElement*	 ToElement() const override { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
ToElement()1126 	TiXmlElement* ToElement() override { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1127 
1128 	/** Walk the XML tree visiting this node and all of its children.
1129 	*/
1130 	bool Accept( TiXmlVisitor* visitor ) const override;
1131 
1132 protected:
1133 
1134 	void CopyTo( TiXmlElement* target ) const;
1135 	void ClearThis();	// like clear, but initializes 'this' object as well
1136 
1137 	// Used to be public [internal use]
1138 	#ifdef TIXML_USE_STL
1139 	virtual void StreamIn( std::istream * in, TIXML_STRING * tag ) override;
1140 	#endif
1141 	/*	[internal use]
1142 		Reads the "value" of the element -- another element, or text.
1143 		This should terminate with the current end tag.
1144 	*/
1145 	const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
1146 
1147 private:
1148 
1149 	TiXmlAttributeSet attributeSet;
1150 };
1151 
1152 
1153 /**	An XML comment.
1154 */
1155 class TiXmlComment : public TiXmlNode
1156 {
1157 public:
1158 	/// Constructs an empty comment.
TiXmlComment()1159 	TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {}
1160 	/// Construct a comment from text.
TiXmlComment(const char * _value)1161 	TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::COMMENT ) {
1162 		SetValue( _value );
1163 	}
1164 	TiXmlComment( const TiXmlComment& );
1165 	void operator=( const TiXmlComment& base );
1166 
~TiXmlComment()1167 	virtual ~TiXmlComment()	{}
1168 
1169 	/// Returns a copy of this Comment.
1170 	TiXmlNode* Clone() const override;
1171 	// Write this Comment to a FILE stream.
1172 	void Print( FILE* cfile, int depth ) const override;
1173 
1174 	/*	Attribtue parsing starts: at the ! of the !--
1175 						 returns: next char past '>'
1176 	*/
1177 	const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) override;
1178 
ToComment()1179 	const TiXmlComment* ToComment() const override { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
ToComment()1180 	TiXmlComment* ToComment() override { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1181 
1182 	/** Walk the XML tree visiting this node and all of its children.
1183 	*/
1184 	bool Accept( TiXmlVisitor* visitor ) const override;
1185 
1186 protected:
1187 	void CopyTo( TiXmlComment* target ) const;
1188 
1189 	// used to be public
1190 	#ifdef TIXML_USE_STL
1191 	virtual void StreamIn( std::istream * in, TIXML_STRING * tag ) override;
1192 	#endif
1193 //	virtual void StreamOut( TIXML_OSTREAM * out ) const;
1194 
1195 private:
1196 
1197 };
1198 
1199 
1200 /** XML text. A text node can have 2 ways to output the next. "normal" output
1201 	and CDATA. It will default to the mode it was parsed from the XML file and
1202 	you generally want to leave it alone, but you can change the output mode with
1203 	SetCDATA() and query it with CDATA().
1204 */
1205 class TiXmlText : public TiXmlNode
1206 {
1207 	friend class TiXmlElement;
1208 public:
1209 	/** Constructor for text element. By default, it is treated as
1210 		normal, encoded text. If you want it be output as a CDATA text
1211 		element, set the parameter _cdata to 'true'
1212 	*/
TiXmlText(const char * initValue)1213 	TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TEXT)
1214 	{
1215 		SetValue( initValue );
1216 		cdata = false;
1217 	}
~TiXmlText()1218 	virtual ~TiXmlText() {}
1219 
1220 	#ifdef TIXML_USE_STL
1221 	/// Constructor.
TiXmlText(const std::string & initValue)1222 	TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT)
1223 	{
1224 		SetValue( initValue );
1225 		cdata = false;
1226 	}
1227 	#endif
1228 
TiXmlText(const TiXmlText & copy)1229 	TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT )	{ copy.CopyTo( this ); }
1230 	void operator=( const TiXmlText& base )							 	{ base.CopyTo( this ); }
1231 
1232 	// Write this text object to a FILE stream.
1233 	void Print( FILE* cfile, int depth ) const override;
1234 
1235 	/// Queries whether this represents text using a CDATA section.
CDATA()1236 	bool CDATA() const				{ return cdata; }
1237 	/// Turns on or off a CDATA representation of text.
SetCDATA(bool _cdata)1238 	void SetCDATA( bool _cdata )	{ cdata = _cdata; }
1239 
1240 	const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) override;
1241 
ToText()1242 	const TiXmlText* ToText() const override { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
ToText()1243 	TiXmlText* ToText() override { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1244 
1245 	/** Walk the XML tree visiting this node and all of its children.
1246 	*/
1247 	bool Accept( TiXmlVisitor* content ) const override;
1248 
1249 protected :
1250 	///  [internal use] Creates a new Element and returns it.
1251 	TiXmlNode* Clone() const override;
1252 	void CopyTo( TiXmlText* target ) const;
1253 
1254 	bool Blank() const;	// returns true if all white space and new lines
1255 	// [internal use]
1256 	#ifdef TIXML_USE_STL
1257 	virtual void StreamIn( std::istream * in, TIXML_STRING * tag ) override;
1258 	#endif
1259 
1260 private:
1261 	bool cdata;			// true if this should be input and output as a CDATA style text element
1262 };
1263 
1264 
1265 /** In correct XML the declaration is the first entry in the file.
1266 	@verbatim
1267 		<?xml version="1.0" standalone="yes"?>
1268 	@endverbatim
1269 
1270 	TinyXml will happily read or write files without a declaration,
1271 	however. There are 3 possible attributes to the declaration:
1272 	version, encoding, and standalone.
1273 
1274 	Note: In this version of the code, the attributes are
1275 	handled as special cases, not generic attributes, simply
1276 	because there can only be at most 3 and they are always the same.
1277 */
1278 class TiXmlDeclaration : public TiXmlNode
1279 {
1280 public:
1281 	/// Construct an empty declaration.
TiXmlDeclaration()1282 	TiXmlDeclaration()   : TiXmlNode( TiXmlNode::DECLARATION ) {}
1283 
1284 #ifdef TIXML_USE_STL
1285 	/// Constructor.
1286 	TiXmlDeclaration(	const std::string& _version,
1287 						const std::string& _encoding,
1288 						const std::string& _standalone );
1289 #endif
1290 
1291 	/// Construct.
1292 	TiXmlDeclaration(	const char* _version,
1293 						const char* _encoding,
1294 						const char* _standalone );
1295 
1296 	TiXmlDeclaration( const TiXmlDeclaration& copy );
1297 	void operator=( const TiXmlDeclaration& copy );
1298 
~TiXmlDeclaration()1299 	virtual ~TiXmlDeclaration()	{}
1300 
1301 	/// Version. Will return an empty string if none was found.
Version()1302 	const char *Version() const			{ return version.c_str (); }
1303 	/// Encoding. Will return an empty string if none was found.
Encoding()1304 	const char *Encoding() const		{ return encoding.c_str (); }
1305 	/// Is this a standalone document?
Standalone()1306 	const char *Standalone() const		{ return standalone.c_str (); }
1307 
1308 	/// Creates a copy of this Declaration and returns it.
1309 	TiXmlNode* Clone() const override;
1310 	// Print this declaration to a FILE stream.
1311 	virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
Print(FILE * cfile,int depth)1312 	void Print( FILE* cfile, int depth ) const override
1313     {
1314 		Print( cfile, depth, 0 );
1315 	}
1316 
1317 	const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) override;
1318 
ToDeclaration()1319 	const TiXmlDeclaration* ToDeclaration() const override { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
ToDeclaration()1320 	TiXmlDeclaration* ToDeclaration()override { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1321 
1322 	/** Walk the XML tree visiting this node and all of its children.
1323 	*/
1324 	bool Accept( TiXmlVisitor* visitor ) const override;
1325 
1326 protected:
1327 	void CopyTo( TiXmlDeclaration* target ) const;
1328 	// used to be public
1329 	#ifdef TIXML_USE_STL
1330 	virtual void StreamIn( std::istream * in, TIXML_STRING * tag ) override;
1331 	#endif
1332 
1333 private:
1334 
1335 	TIXML_STRING version;
1336 	TIXML_STRING encoding;
1337 	TIXML_STRING standalone;
1338 };
1339 
1340 
1341 /** Any tag that tinyXml doesn't recognize is saved as an
1342 	unknown. It is a tag of text, but should not be modified.
1343 	It will be written back to the XML, unchanged, when the file
1344 	is saved.
1345 
1346 	DTD tags get thrown into TiXmlUnknowns.
1347 */
1348 class TiXmlUnknown : public TiXmlNode
1349 {
1350 public:
TiXmlUnknown()1351 	TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN )	{}
~TiXmlUnknown()1352 	virtual ~TiXmlUnknown() {}
1353 
TiXmlUnknown(const TiXmlUnknown & copy)1354 	TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN )		{ copy.CopyTo( this ); }
1355 	void operator=( const TiXmlUnknown& copy )										{ copy.CopyTo( this ); }
1356 
1357 	/// Creates a copy of this Unknown and returns it.
1358 	TiXmlNode* Clone() const override;
1359 	// Print this Unknown to a FILE stream.
1360 	void Print( FILE* cfile, int depth ) const override;
1361 
1362 	const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) override;
1363 
ToUnknown()1364 	const TiXmlUnknown*	 ToUnknown() const override { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
ToUnknown()1365 	TiXmlUnknown* ToUnknown()override { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1366 
1367 	/** Walk the XML tree visiting this node and all of its children.
1368 	*/
1369 	bool Accept( TiXmlVisitor* content ) const override;
1370 
1371 protected:
1372 	void CopyTo( TiXmlUnknown* target ) const;
1373 
1374 	#ifdef TIXML_USE_STL
1375 	virtual void StreamIn( std::istream * in, TIXML_STRING * tag ) override;
1376 	#endif
1377 
1378 private:
1379 
1380 };
1381 
1382 
1383 /** Always the top level node. A document binds together all the
1384 	XML pieces. It can be saved, loaded, and printed to the screen.
1385 	The 'value' of a document node is the xml file name.
1386 */
1387 class TiXmlDocument : public TiXmlNode
1388 {
1389 public:
1390 	/// Create an empty document, that has no name.
1391 	TiXmlDocument();
1392 	/// Create a document with a name. The name of the document is also the filename of the xml.
1393 	TiXmlDocument( const char * documentName );
1394 
1395 	#ifdef TIXML_USE_STL
1396 	/// Constructor.
1397 	TiXmlDocument( const std::string& documentName );
1398 	#endif
1399 
1400 	TiXmlDocument( const TiXmlDocument& copy );
1401 	void operator=( const TiXmlDocument& copy );
1402 
~TiXmlDocument()1403 	virtual ~TiXmlDocument() {}
1404 
1405 	/** Load a file using the current document value.
1406 		Returns true if successful. Will delete any existing
1407 		document data before loading.
1408 	*/
1409 	bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1410 	/// Save a file using the current document value. Returns true if successful.
1411 	bool SaveFile() const;
1412 	/// Load a file using the given filename. Returns true if successful.
1413 	bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1414 	/// Save a file using the given filename. Returns true if successful.
1415 	bool SaveFile( const char * filename ) const;
1416 	/** Load a file using the given FILE*. Returns true if successful. Note that this method
1417 		doesn't stream - the entire object pointed at by the FILE*
1418 		will be interpreted as an XML file. TinyXML doesn't stream in XML from the current
1419 		file location. Streaming may be added in the future.
1420 	*/
1421 	bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
1422 	/// Save a file using the given FILE*. Returns true if successful.
1423 	bool SaveFile( FILE* ) const;
1424 
1425 	#ifdef TIXML_USE_STL
1426 	bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING )			///< STL std::string version.
1427 	{
1428 //		StringToBuffer f( filename );
1429 //		return ( f.buffer && LoadFile( f.buffer, encoding ));
1430 		return LoadFile( filename.c_str(), encoding );
1431 	}
SaveFile(const std::string & filename)1432 	bool SaveFile( const std::string& filename ) const		///< STL std::string version.
1433 	{
1434 //		StringToBuffer f( filename );
1435 //		return ( f.buffer && SaveFile( f.buffer ));
1436 		return SaveFile( filename.c_str() );
1437 	}
1438 	#endif
1439 
1440 	/** Parse the given null terminated block of xml data. Passing in an encoding to this
1441 		method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml
1442 		to use that encoding, regardless of what TinyXml might otherwise try to detect.
1443 	*/
1444 	const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) override;
1445 
1446 	/** Get the root element -- the only top level element -- of the document.
1447 		In well formed XML, there should only be one. TinyXml is tolerant of
1448 		multiple elements at the document level.
1449 	*/
RootElement()1450 	const TiXmlElement* RootElement() const		{ return FirstChildElement(); }
RootElement()1451 	TiXmlElement* RootElement()					{ return FirstChildElement(); }
1452 
1453 	/** If an error occurs, Error will be set to true. Also,
1454 		- The ErrorId() will contain the integer identifier of the error (not generally useful)
1455 		- The ErrorDesc() method will return the name of the error. (very useful)
1456 		- The ErrorRow() and ErrorCol() will return the location of the error (if known)
1457 	*/
Error()1458 	bool Error() const						{ return error; }
1459 
1460 	/// Contains a textual (english) description of the error if one occurs.
ErrorDesc()1461 	const char * ErrorDesc() const	{ return errorDesc.c_str (); }
1462 
1463 	/** Generally, you probably want the error string ( ErrorDesc() ). But if you
1464 		prefer the ErrorId, this function will fetch it.
1465 	*/
ErrorId()1466 	int ErrorId()	const				{ return errorId; }
1467 
1468 	/** Returns the location (if known) of the error. The first column is column 1,
1469 		and the first row is row 1. A value of 0 means the row and column wasn't applicable
1470 		(memory errors, for example, have no row/column) or the parser lost the error. (An
1471 		error in the error reporting, in that case.)
1472 
1473 		@sa SetTabSize, Row, Column
1474 	*/
ErrorRow()1475 	int ErrorRow() const	{ return errorLocation.row+1; }
ErrorCol()1476 	int ErrorCol() const	{ return errorLocation.col+1; }	///< The column where the error occurred. See ErrorRow()
1477 
1478 	/** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol())
1479 		to report the correct values for row and column. It does not change the output
1480 		or input in any way.
1481 
1482 		By calling this method, with a tab size
1483 		greater than 0, the row and column of each node and attribute is stored
1484 		when the file is loaded. Very useful for tracking the DOM back in to
1485 		the source file.
1486 
1487 		The tab size is required for calculating the location of nodes. If not
1488 		set, the default of 4 is used. The tabsize is set per document. Setting
1489 		the tabsize to 0 disables row/column tracking.
1490 
1491 		Note that row and column tracking is not supported when using operator>>.
1492 
1493 		The tab size needs to be enabled before the parse or load. Correct usage:
1494 		@verbatim
1495 		TiXmlDocument doc;
1496 		doc.SetTabSize( 8 );
1497 		doc.Load( "myfile.xml" );
1498 		@endverbatim
1499 
1500 		@sa Row, Column
1501 	*/
SetTabSize(int _tabsize)1502 	void SetTabSize( int _tabsize )		{ tabsize = _tabsize; }
1503 
TabSize()1504 	int TabSize() const	{ return tabsize; }
1505 
1506 	/** If you have handled the error, it can be reset with this call. The error
1507 		state is automatically cleared if you Parse a new XML block.
1508 	*/
ClearError()1509 	void ClearError()						{	error = false;
1510 												errorId = 0;
1511 												errorDesc = "";
1512 												errorLocation.row = errorLocation.col = 0;
1513 												//errorLocation.last = 0;
1514 											}
1515 
1516 	/** Write the document to standard out using formatted printing ("pretty print"). */
Print()1517 	void Print() const						{ Print( stdout, 0 ); }
1518 
1519 	/* Write the document to a string using formatted printing ("pretty print"). This
1520 		will allocate a character array (new char[]) and return it as a pointer. The
1521 		calling code pust call delete[] on the return char* to avoid a memory leak.
1522 	*/
1523 	//char* PrintToMemory() const;
1524 
1525 	/// Print this Document to a FILE stream.
1526 	void Print( FILE* cfile, int depth = 0 ) const override;
1527 	// [internal use]
1528 	void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
1529 
ToDocument()1530 	const TiXmlDocument* ToDocument() const override { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
ToDocument()1531 	TiXmlDocument*	ToDocument() override { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
1532 
1533 	/** Walk the XML tree visiting this node and all of its children.
1534 	*/
1535 	bool Accept( TiXmlVisitor* content ) const override;
1536 
1537 protected :
1538 	// [internal use]
1539 	TiXmlNode* Clone() const override;
1540 	#ifdef TIXML_USE_STL
1541 	virtual void StreamIn( std::istream * in, TIXML_STRING * tag ) override;
1542 	#endif
1543 
1544 private:
1545 	void CopyTo( TiXmlDocument* target ) const;
1546 
1547 	bool error;
1548 	int  errorId;
1549 	TIXML_STRING errorDesc;
1550 	int tabsize;
1551 	TiXmlCursor errorLocation;
1552 	bool useMicrosoftBOM;		// the UTF-8 BOM were found when read. Note this, and try to write.
1553 };
1554 
1555 
1556 /**
1557 	A TiXmlHandle is a class that wraps a node pointer with null checks; this is
1558 	an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml
1559 	DOM structure. It is a separate utility class.
1560 
1561 	Take an example:
1562 	@verbatim
1563 	<Document>
1564 		<Element attributeA = "valueA">
1565 			<Child attributeB = "value1" />
1566 			<Child attributeB = "value2" />
1567 		</Element>
1568 	<Document>
1569 	@endverbatim
1570 
1571 	Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very
1572 	easy to write a *lot* of code that looks like:
1573 
1574 	@verbatim
1575 	TiXmlElement* root = document.FirstChildElement( "Document" );
1576 	if ( root )
1577 	{
1578 		TiXmlElement* element = root->FirstChildElement( "Element" );
1579 		if ( element )
1580 		{
1581 			TiXmlElement* child = element->FirstChildElement( "Child" );
1582 			if ( child )
1583 			{
1584 				TiXmlElement* child2 = child->NextSiblingElement( "Child" );
1585 				if ( child2 )
1586 				{
1587 					// Finally do something useful.
1588 	@endverbatim
1589 
1590 	And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity
1591 	of such code. A TiXmlHandle checks for null	pointers so it is perfectly safe
1592 	and correct to use:
1593 
1594 	@verbatim
1595 	TiXmlHandle docHandle( &document );
1596 	TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement();
1597 	if ( child2 )
1598 	{
1599 		// do something useful
1600 	@endverbatim
1601 
1602 	Which is MUCH more concise and useful.
1603 
1604 	It is also safe to copy handles - internally they are nothing more than node pointers.
1605 	@verbatim
1606 	TiXmlHandle handleCopy = handle;
1607 	@endverbatim
1608 
1609 	What they should not be used for is iteration:
1610 
1611 	@verbatim
1612 	int i=0;
1613 	while ( true )
1614 	{
1615 		TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement();
1616 		if ( !child )
1617 			break;
1618 		// do something
1619 		++i;
1620 	}
1621 	@endverbatim
1622 
1623 	It seems reasonable, but it is in fact two embedded while loops. The Child method is
1624 	a linear walk to find the element, so this code would iterate much more than it needs
1625 	to. Instead, prefer:
1626 
1627 	@verbatim
1628 	TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement();
1629 
1630 	for( child; child; child=child->NextSiblingElement() )
1631 	{
1632 		// do something
1633 	}
1634 	@endverbatim
1635 */
1636 class TiXmlHandle
1637 {
1638 public:
1639 	/// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
TiXmlHandle(TiXmlNode * _node)1640 	TiXmlHandle( TiXmlNode* _node )					{ this->node = _node; }
1641 	/// Copy constructor
TiXmlHandle(const TiXmlHandle & ref)1642 	TiXmlHandle( const TiXmlHandle& ref )			{ this->node = ref.node; }
1643 	TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; }
1644 
1645 	/// Return a handle to the first child node.
1646 	TiXmlHandle FirstChild() const;
1647 	/// Return a handle to the first child node with the given name.
1648 	TiXmlHandle FirstChild( const char * value ) const;
1649 	/// Return a handle to the first child element.
1650 	TiXmlHandle FirstChildElement() const;
1651 	/// Return a handle to the first child element with the given name.
1652 	TiXmlHandle FirstChildElement( const char * value ) const;
1653 
1654 	/** Return a handle to the "index" child with the given name.
1655 		The first child is 0, the second 1, etc.
1656 	*/
1657 	TiXmlHandle Child( const char* value, int index ) const;
1658 	/** Return a handle to the "index" child.
1659 		The first child is 0, the second 1, etc.
1660 	*/
1661 	TiXmlHandle Child( int index ) const;
1662 	/** Return a handle to the "index" child element with the given name.
1663 		The first child element is 0, the second 1, etc. Note that only TiXmlElements
1664 		are indexed: other types are not counted.
1665 	*/
1666 	TiXmlHandle ChildElement( const char* value, int index ) const;
1667 	/** Return a handle to the "index" child element.
1668 		The first child element is 0, the second 1, etc. Note that only TiXmlElements
1669 		are indexed: other types are not counted.
1670 	*/
1671 	TiXmlHandle ChildElement( int index ) const;
1672 
1673 	#ifdef TIXML_USE_STL
FirstChild(const std::string & _value)1674 	TiXmlHandle FirstChild( const std::string& _value ) const				{ return FirstChild( _value.c_str() ); }
FirstChildElement(const std::string & _value)1675 	TiXmlHandle FirstChildElement( const std::string& _value ) const		{ return FirstChildElement( _value.c_str() ); }
1676 
Child(const std::string & _value,int index)1677 	TiXmlHandle Child( const std::string& _value, int index ) const			{ return Child( _value.c_str(), index ); }
ChildElement(const std::string & _value,int index)1678 	TiXmlHandle ChildElement( const std::string& _value, int index ) const	{ return ChildElement( _value.c_str(), index ); }
1679 	#endif
1680 
1681 	/** Return the handle as a TiXmlNode. This may return null.
1682 	*/
ToNode()1683 	TiXmlNode* ToNode() const			{ return node; }
1684 	/** Return the handle as a TiXmlElement. This may return null.
1685 	*/
ToElement()1686 	TiXmlElement* ToElement() const		{ return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
1687 	/**	Return the handle as a TiXmlText. This may return null.
1688 	*/
ToText()1689 	TiXmlText* ToText() const			{ return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
1690 	/** Return the handle as a TiXmlUnknown. This may return null.
1691 	*/
ToUnknown()1692 	TiXmlUnknown* ToUnknown() const		{ return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
1693 
1694 	/** @deprecated use ToNode.
1695 		Return the handle as a TiXmlNode. This may return null.
1696 	*/
Node()1697 	TiXmlNode* Node() const			{ return ToNode(); }
1698 	/** @deprecated use ToElement.
1699 		Return the handle as a TiXmlElement. This may return null.
1700 	*/
Element()1701 	TiXmlElement* Element() const	{ return ToElement(); }
1702 	/**	@deprecated use ToText()
1703 		Return the handle as a TiXmlText. This may return null.
1704 	*/
Text()1705 	TiXmlText* Text() const			{ return ToText(); }
1706 	/** @deprecated use ToUnknown()
1707 		Return the handle as a TiXmlUnknown. This may return null.
1708 	*/
Unknown()1709 	TiXmlUnknown* Unknown() const	{ return ToUnknown(); }
1710 
1711 private:
1712 	TiXmlNode* node;
1713 };
1714 
1715 
1716 /** Print to memory functionality. The TiXmlPrinter is useful when you need to:
1717 
1718 	-# Print to memory (especially in non-STL mode)
1719 	-# Control formatting (line endings, etc.)
1720 
1721 	When constructed, the TiXmlPrinter is in its default "pretty printing" mode.
1722 	Before calling Accept() you can call methods to control the printing
1723 	of the XML document. After TiXmlNode::Accept() is called, the printed document can
1724 	be accessed via the CStr(), Str(), and Size() methods.
1725 
1726 	TiXmlPrinter uses the Visitor API.
1727 	@verbatim
1728 	TiXmlPrinter printer;
1729 	printer.SetIndent( "\t" );
1730 
1731 	doc.Accept( &printer );
1732 	fprintf( stdout, "%s", printer.CStr() );
1733 	@endverbatim
1734 */
1735 class TiXmlPrinter : public TiXmlVisitor
1736 {
1737 public:
TiXmlPrinter()1738 	TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ),
1739 					 buffer(), indent( "	" ), lineBreak( "\n" ) {}
1740 
1741 	bool VisitEnter( const TiXmlDocument& doc ) override;
1742 	bool VisitExit( const TiXmlDocument& doc ) override;
1743 
1744 	bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ) override;
1745 	bool VisitExit( const TiXmlElement& element ) override;
1746 
1747 	bool Visit( const TiXmlDeclaration& declaration ) override;
1748 	bool Visit( const TiXmlText& text ) override;
1749 	bool Visit( const TiXmlComment& comment ) override;
1750 	bool Visit( const TiXmlUnknown& unknown ) override;
1751 
1752 	/** Set the indent characters for printing. By default 4 spaces
1753 		but tab (\t) is also useful, or null/empty string for no indentation.
1754 	*/
SetIndent(const char * _indent)1755 	void SetIndent( const char* _indent )			{ indent = _indent ? _indent : "" ; }
1756 	/// Query the indention string.
Indent()1757 	const char* Indent()							{ return indent.c_str(); }
1758 	/** Set the line breaking string. By default set to newline (\n).
1759 		Some operating systems prefer other characters, or can be
1760 		set to the null/empty string for no indenation.
1761 	*/
SetLineBreak(const char * _lineBreak)1762 	void SetLineBreak( const char* _lineBreak )		{ lineBreak = _lineBreak ? _lineBreak : ""; }
1763 	/// Query the current line breaking string.
LineBreak()1764 	const char* LineBreak()							{ return lineBreak.c_str(); }
1765 
1766 	/** Switch over to "stream printing" which is the most dense formatting without
1767 		linebreaks. Common when the XML is needed for network transmission.
1768 	*/
SetStreamPrinting()1769 	void SetStreamPrinting()						{ indent = "";
1770 													  lineBreak = "";
1771 													}
1772 	/// Return the result.
CStr()1773 	const char* CStr()								{ return buffer.c_str(); }
1774 	/// Return the length of the result string.
Size()1775 	size_t Size()									{ return buffer.size(); }
1776 
1777 	#ifdef TIXML_USE_STL
1778 	/// Return the result.
Str()1779 	const std::string& Str()						{ return buffer; }
1780 	#endif
1781 
1782 private:
DoIndent()1783 	void DoIndent()	{
1784 		for( int i=0; i<depth; ++i )
1785 			buffer += indent;
1786 	}
DoLineBreak()1787 	void DoLineBreak() {
1788 		buffer += lineBreak;
1789 	}
1790 
1791 	int depth;
1792 	bool simpleTextPrint;
1793 	TIXML_STRING buffer;
1794 	TIXML_STRING indent;
1795 	TIXML_STRING lineBreak;
1796 };
1797 
1798 
1799 #ifdef _MSC_VER
1800 #pragma warning( pop )
1801 #endif
1802 
1803 #endif
1804 
1805