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