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