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