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