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