xref: /third_party/lame/ACM/tinyxml/tinyxml.h (revision 159b3361)
1/*
2Copyright (c) 2000 Lee Thomason (www.grinninglizard.com)
3
4This software is provided 'as-is', without any express or implied
5warranty. In no event will the authors be held liable for any
6damages arising from the use of this software.
7
8Permission is granted to anyone to use this software for any
9purpose, including commercial applications, and to alter it and
10redistribute it freely, subject to the following restrictions:
11
121. The origin of this software must not be misrepresented; you must
13not claim that you wrote the original software. If you use this
14software in a product, an acknowledgment in the product documentation
15would be appreciated but is not required.
16
172. Altered source versions must be plainly marked as such, and
18must not be misrepresented as being the original software.
19
203. This notice may not be removed or altered from any source
21distribution.
22*/
23
24
25#ifndef TINYXML_INCLUDED
26#define TINYXML_INCLUDED
27
28#pragma warning( disable : 4530 )
29#pragma warning( disable : 4786 )
30
31#include <string>
32#include <stdio.h>
33#include <assert.h>
34
35class TiXmlDocument;
36class TiXmlElement;
37class TiXmlComment;
38class TiXmlUnknown;
39class TiXmlAttribute;
40class TiXmlText;
41class TiXmlDeclaration;
42
43
44// Help out windows:
45#if defined( _DEBUG ) && !defined( DEBUG )
46	#define DEBUG
47#endif
48
49#if defined( DEBUG ) && defined( _MSC_VER )
50	#include <windows.h>
51	#define TIXML_LOG OutputDebugString
52#else
53	#define TIXML_LOG printf
54#endif
55
56
57/** TiXmlBase is a base class for every class in TinyXml.
58	It does little except to establish that TinyXml classes
59	can be printed and provide some utility functions.
60
61	In XML, the document and elements can contain
62	other elements and other types of nodes.
63
64	@verbatim
65	A Document can contain:	Element	(container or leaf)
66							Comment (leaf)
67							Unknown (leaf)
68							Declaration( leaf )
69
70	An Element can contain:	Element (container or leaf)
71							Text	(leaf)
72							Attributes (not on tree)
73							Comment (leaf)
74							Unknown (leaf)
75
76	A Decleration contains: Attributes (not on tree)
77	@endverbatim
78*/
79class TiXmlBase
80{
81	friend class TiXmlNode;
82	friend class TiXmlElement;
83	friend class TiXmlDocument;
84
85  public:
86	TiXmlBase()								{}
87	virtual ~TiXmlBase()					{}
88
89	/**	All TinyXml classes can print themselves to a filestream.
90		This is a formatted print, and will insert tabs and newlines.
91
92		(For an unformatted stream, use the << operator.)
93	*/
94 	virtual void Print( FILE* cfile, int depth ) const = 0;
95
96	// [internal] Underlying implementation of the operator <<
97	virtual void StreamOut ( std::ostream* out ) const = 0;
98
99	/**	The world does not agree on whether white space should be kept or
100		not. In order to make everyone happy, these global, static functions
101		are provided to set whether or not TinyXml will condense all white space
102		into a single space or not. The default is to condense. Note changing these
103		values is not thread safe.
104	*/
105	static void SetCondenseWhiteSpace( bool condense )		{ condenseWhiteSpace = condense; }
106
107	/// Return the current white space setting.
108	static bool IsWhiteSpaceCondensed()						{ return condenseWhiteSpace; }
109
110  protected:
111	static const char* SkipWhiteSpace( const char* );
112	static bool StreamWhiteSpace( std::istream* in, std::string* tag );
113	static bool IsWhiteSpace( int c )		{ return ( isspace( c ) || c == '\n' || c == '\r' ); }
114
115	/*	Read to the specified character.
116		Returns true if the character found and no error.
117	*/
118	static bool StreamTo( std::istream* in, int character, std::string* tag );
119
120	/*	Reads an XML name into the string provided. Returns
121		a pointer just past the last character of the name,
122		or 0 if the function has an error.
123	*/
124	static const char* ReadName( const char*, std::string* name );
125
126	/*	Reads text. Returns a pointer past the given end tag.
127		Wickedly complex options, but it keeps the (sensitive) code in one place.
128	*/
129	static const char* ReadText(	const char* in,				// where to start
130									std::string* text,			// the string read
131									bool ignoreWhiteSpace,		// whether to keep the white space
132									const char* endTag,			// what ends this text
133									bool ignoreCase );			// whether to ignore case in the end tag
134
135	virtual const char* Parse( const char* p ) = 0;
136
137	// If an entity has been found, transform it into a character.
138	static const char* GetEntity( const char* in, char* value );
139
140	// Get a character, while interpreting entities.
141	inline static const char* GetChar( const char* p, char* value )
142											{
143												assert( p );
144												if ( *p == '&' )
145												{
146													return GetEntity( p, value );
147												}
148												else
149												{
150													*value = *p;
151													return p+1;
152												}
153											}
154
155	// Puts a string to a stream, expanding entities as it goes.
156	// Note this should not contian the '<', '>', etc, or they will be transformed into entities!
157	static void PutString( const std::string& str, std::ostream* stream );
158
159	// Return true if the next characters in the stream are any of the endTag sequences.
160	bool static StringEqual(	const char* p,
161								const char* endTag,
162								bool ignoreCase );
163
164
165	enum
166	{
167		TIXML_NO_ERROR = 0,
168		TIXML_ERROR,
169		TIXML_ERROR_OPENING_FILE,
170		TIXML_ERROR_OUT_OF_MEMORY,
171		TIXML_ERROR_PARSING_ELEMENT,
172		TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
173		TIXML_ERROR_READING_ELEMENT_VALUE,
174		TIXML_ERROR_READING_ATTRIBUTES,
175		TIXML_ERROR_PARSING_EMPTY,
176		TIXML_ERROR_READING_END_TAG,
177		TIXML_ERROR_PARSING_UNKNOWN,
178		TIXML_ERROR_PARSING_COMMENT,
179		TIXML_ERROR_PARSING_DECLARATION,
180		TIXML_ERROR_DOCUMENT_EMPTY,
181
182		TIXML_ERROR_STRING_COUNT
183	};
184	static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
185
186  private:
187	struct Entity
188	{
189		const char*     str;
190		unsigned int	strLength;
191		int			    chr;
192	};
193	enum
194	{
195		NUM_ENTITY = 5,
196		MAX_ENTITY_LENGTH = 6
197
198	};
199	static Entity entity[ NUM_ENTITY ];
200	static bool condenseWhiteSpace;
201};
202
203
204/** The parent class for everything in the Document Object Model.
205	(Except for attributes, which are contained in elements.)
206	Nodes have siblings, a parent, and children. A node can be
207	in a document, or stand on its own. The type of a TiXmlNode
208	can be queried, and it can be cast to its more defined type.
209*/
210class TiXmlNode : public TiXmlBase
211{
212  public:
213
214	/** An output stream operator, for every class. Note that this outputs
215		without any newlines or formatting, as opposed to Print(), which
216		includes tabs and new lines.
217
218		The operator<< and operator>> are not completely symmetric. Writing
219		a node to a stream is very well defined. You'll get a nice stream
220		of output, without any extra whitespace or newlines.
221
222		But reading is not as well defined. (As it always is.) If you create
223		a TiXmlElement (for example) and read that from an input stream,
224		the text needs to define an element or junk will result. This is
225		true of all input streams, but it's worth keeping in mind.
226
227		A TiXmlDocument will read nodes until it reads a root element.
228	*/
229	friend std::ostream& operator<< ( std::ostream& out, const TiXmlNode& base )
230	{
231		base.StreamOut( &out );
232		return out;
233	}
234
235	/** An input stream operator, for every class. Tolerant of newlines and
236		formatting, but doesn't expect them.
237	*/
238	friend std::istream& operator>> ( std::istream& in, TiXmlNode& base )
239	{
240		std::string tag;
241		tag.reserve( 8 * 1000 );
242		base.StreamIn( &in, &tag );
243
244		base.Parse( tag.c_str() );
245		return in;
246	}
247
248	/** The types of XML nodes supported by TinyXml. (All the
249		unsupported types are picked up by UNKNOWN.)
250	*/
251	enum NodeType
252	{
253		DOCUMENT,
254		ELEMENT,
255		COMMENT,
256		UNKNOWN,
257		TEXT,
258		DECLARATION,
259		TYPECOUNT
260	};
261
262	virtual ~TiXmlNode();
263
264	/** The meaning of 'value' changes for the specific type of
265		TiXmlNode.
266		@verbatim
267		Document:	filename of the xml file
268		Element:	name of the element
269		Comment:	the comment text
270		Unknown:	the tag contents
271		Text:		the text string
272		@endverbatim
273
274		The subclasses will wrap this function.
275	*/
276	const std::string& Value()	const			{ return value; }
277
278	/** Changes the value of the node. Defined as:
279		@verbatim
280		Document:	filename of the xml file
281		Element:	name of the element
282		Comment:	the comment text
283		Unknown:	the tag contents
284		Text:		the text string
285		@endverbatim
286	*/
287	void SetValue( const std::string& _value )		{ value = _value; }
288
289	/// Delete all the children of this node. Does not affect 'this'.
290	void Clear();
291
292	/// One step up the DOM.
293	TiXmlNode* Parent() const					{ return parent; }
294
295	TiXmlNode* FirstChild()	const	{ return firstChild; }		///< The first child of this node. Will be null if there are no children.
296	TiXmlNode* FirstChild( const std::string& value ) const;	///< The first child of this node with the matching 'value'. Will be null if none found.
297
298	TiXmlNode* LastChild() const	{ return lastChild; }		/// The last child of this node. Will be null if there are no children.
299	TiXmlNode* LastChild( const std::string& value ) const;		/// The last child of this node matching 'value'. Will be null if there are no children.
300
301	/** An alternate way to walk the children of a node.
302		One way to iterate over nodes is:
303		@verbatim
304			for( child = parent->FirstChild(); child; child = child->NextSibling() )
305		@endverbatim
306
307		IterateChildren does the same thing with the syntax:
308		@verbatim
309			child = 0;
310			while( child = parent->IterateChildren( child ) )
311		@endverbatim
312
313		IterateChildren takes the previous child as input and finds
314		the next one. If the previous child is null, it returns the
315		first. IterateChildren will return null when done.
316	*/
317	TiXmlNode* IterateChildren( TiXmlNode* previous ) const;
318
319	/// This flavor of IterateChildren searches for children with a particular 'value'
320	TiXmlNode* IterateChildren( const std::string& value, TiXmlNode* previous ) const;
321
322	/** Add a new node related to this. Adds a child past the LastChild.
323		Returns a pointer to the new object or NULL if an error occured.
324	*/
325	TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
326
327	/** Add a new node related to this. Adds a child before the specified child.
328		Returns a pointer to the new object or NULL if an error occured.
329	*/
330	TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
331
332	/** Add a new node related to this. Adds a child after the specified child.
333		Returns a pointer to the new object or NULL if an error occured.
334	*/
335	TiXmlNode* InsertAfterChild(  TiXmlNode* afterThis, const TiXmlNode& addThis );
336
337	/** Replace a child of this node.
338		Returns a pointer to the new object or NULL if an error occured.
339	*/
340	TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
341
342	/// Delete a child of this node.
343	bool RemoveChild( TiXmlNode* removeThis );
344
345	/// Navigate to a sibling node.
346	TiXmlNode* PreviousSibling() const			{ return prev; }
347
348	/// Navigate to a sibling node.
349	TiXmlNode* PreviousSibling( const std::string& ) const;
350
351	/// Navigate to a sibling node.
352	TiXmlNode* NextSibling() const				{ return next; }
353
354	/// Navigate to a sibling node with the given 'value'.
355	TiXmlNode* NextSibling( const std::string& ) const;
356
357	/** Convenience function to get through elements.
358		Calls NextSibling and ToElement. Will skip all non-Element
359		nodes. Returns 0 if there is not another element.
360	*/
361	TiXmlElement* NextSiblingElement() const;
362
363	/** Convenience function to get through elements.
364		Calls NextSibling and ToElement. Will skip all non-Element
365		nodes. Returns 0 if there is not another element.
366	*/
367	TiXmlElement* NextSiblingElement( const std::string& ) const;
368
369	/// Convenience function to get through elements.
370	TiXmlElement* FirstChildElement()	const;
371
372	/// Convenience function to get through elements.
373	TiXmlElement* FirstChildElement( const std::string& value ) const;
374
375	/// Query the type (as an enumerated value, above) of this node.
376	virtual int Type() const	{ return type; }
377
378	/** Return a pointer to the Document this node lives in.
379		Returns null if not in a document.
380	*/
381	TiXmlDocument* GetDocument() const;
382
383	/// Returns true if this node has no children.
384	bool NoChildren() const						{ return !firstChild; }
385
386	TiXmlDocument* ToDocument()	const		{ return ( this && type == DOCUMENT ) ? (TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
387	TiXmlElement*  ToElement() const		{ return ( this && type == ELEMENT  ) ? (TiXmlElement*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
388	TiXmlComment*  ToComment() const		{ return ( this && type == COMMENT  ) ? (TiXmlComment*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
389	TiXmlUnknown*  ToUnknown() const		{ return ( this && type == UNKNOWN  ) ? (TiXmlUnknown*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
390	TiXmlText*	   ToText()    const		{ return ( this && type == TEXT     ) ? (TiXmlText*)     this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
391	TiXmlDeclaration* ToDeclaration() const	{ return ( this && type == DECLARATION ) ? (TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
392
393	virtual TiXmlNode* Clone() const = 0;
394
395	// The real work of the input operator.
396	virtual void StreamIn( std::istream* in, std::string* tag ) = 0;
397
398  protected:
399	TiXmlNode( NodeType type );
400
401	// The node is passed in by ownership. This object will delete it.
402	TiXmlNode* LinkEndChild( TiXmlNode* addThis );
403
404	// Figure out what is at *p, and parse it. Returns null if it is not an xml node.
405	TiXmlNode* Identify( const char* start );
406
407	void CopyToClone( TiXmlNode* target ) const	{ target->value = value; }
408
409	TiXmlNode*		parent;
410	NodeType		type;
411
412	TiXmlNode*		firstChild;
413	TiXmlNode*		lastChild;
414
415	std::string		value;
416
417	TiXmlNode*		prev;
418	TiXmlNode*		next;
419};
420
421
422/** An attribute is a name-value pair. Elements have an arbitrary
423	number of attributes, each with a unique name.
424
425	@note The attributes are not TiXmlNodes, since they are not
426		  part of the tinyXML document object model. There are other
427		  suggested ways to look at this problem.
428
429	@note Attributes have a parent
430*/
431class TiXmlAttribute : public TiXmlBase
432{
433	friend class TiXmlAttributeSet;
434
435  public:
436	/// Construct an empty attribute.
437	TiXmlAttribute() : prev( 0 ), next( 0 )	{}
438
439	/// Construct an attribute with a name and value.
440	TiXmlAttribute( const std::string& _name, const std::string& _value )	: name( _name ), value( _value ), prev( 0 ), next( 0 ) {}
441
442	const std::string& Name()  const { return name; }		///< Return the name of this attribute.
443
444	const std::string& Value() const { return value; }		///< Return the value of this attribute.
445	const int          IntValue() const;					///< Return the value of this attribute, converted to an integer.
446	const double	   DoubleValue() const;					///< Return the value of this attribute, converted to a double.
447
448	void SetName( const std::string& _name )	{ name = _name; }		///< Set the name of this attribute.
449	void SetValue( const std::string& _value )	{ value = _value; }		///< Set the value.
450	void SetIntValue( int value );										///< Set the value from an integer.
451	void SetDoubleValue( double value );								///< Set the value from a double.
452
453	/// Get the next sibling attribute in the DOM. Returns null at end.
454	TiXmlAttribute* Next() const;
455	/// Get the previous sibling attribute in the DOM. Returns null at beginning.
456	TiXmlAttribute* Previous() const;
457
458	bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
459	bool operator<( const TiXmlAttribute& rhs )	 const { return name < rhs.name; }
460	bool operator>( const TiXmlAttribute& rhs )  const { return name > rhs.name; }
461
462	/*	[internal use]
463		Attribtue parsing starts: first letter of the name
464						 returns: the next char after the value end quote
465	*/
466	virtual const char* Parse( const char* p );
467
468	// [internal use]
469 	virtual void Print( FILE* cfile, int depth ) const;
470
471	// [internal use]
472	virtual void StreamOut( std::ostream* out ) const;
473
474	// [internal use]
475	// Set the document pointer so the attribute can report errors.
476	void SetDocument( TiXmlDocument* doc )	{ document = doc; }
477
478  private:
479	TiXmlDocument*	document;	// A pointer back to a document, for error reporting.
480	std::string		name;
481	std::string		value;
482
483	TiXmlAttribute*	prev;
484	TiXmlAttribute*	next;
485};
486
487
488/*	A class used to manage a group of attributes.
489	It is only used internally, both by the ELEMENT and the DECLARATION.
490
491	The set can be changed transparent to the Element and Declaration
492	classes that use it, but NOT transparent to the Attribute
493	which has to implement a next() and previous() method. Which makes
494	it a bit problematic and prevents the use of STL.
495
496	This version is implemented with circular lists because:
497		- I like circular lists
498		- it demonstrates some independence from the (typical) doubly linked list.
499*/
500class TiXmlAttributeSet
501{
502  public:
503	TiXmlAttributeSet();
504	~TiXmlAttributeSet();
505
506	void Add( TiXmlAttribute* attribute );
507	void Remove( TiXmlAttribute* attribute );
508
509	TiXmlAttribute* First() const	{ return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
510	TiXmlAttribute* Last()  const	{ return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
511
512	TiXmlAttribute*	Find( const std::string& name ) const;
513
514  private:
515	TiXmlAttribute sentinel;
516};
517
518
519/** The element is a container class. It has a value, the element name,
520	and can contain other elements, text, comments, and unknowns.
521	Elements also contain an arbitrary number of attributes.
522*/
523class TiXmlElement : public TiXmlNode
524{
525  public:
526	/// Construct an element.
527	TiXmlElement( const std::string& value );
528
529	virtual ~TiXmlElement();
530
531	/** Given an attribute name, attribute returns the value
532		for the attribute of that name, or null if none exists.
533	*/
534	const std::string* Attribute( const std::string& name ) const;
535
536	/** Given an attribute name, attribute returns the value
537		for the attribute of that name, or null if none exists.
538	*/
539	const std::string* Attribute( const std::string& name, int* i ) const;
540
541	/** Sets an attribute of name to a given value. The attribute
542		will be created if it does not exist, or changed if it does.
543	*/
544	void SetAttribute( const std::string& name,
545					   const std::string& value );
546
547	/** Sets an attribute of name to a given value. The attribute
548		will be created if it does not exist, or changed if it does.
549	*/
550	void SetAttribute( const std::string& name,
551					   int value );
552
553	/** Deletes an attribute with the given name.
554	*/
555	void RemoveAttribute( const std::string& name );
556
557	TiXmlAttribute* FirstAttribute() const	{ return attributeSet.First(); }		///< Access the first attribute in this element.
558	TiXmlAttribute* LastAttribute()	const 	{ return attributeSet.Last(); }		///< Access the last attribute in this element.
559
560	// [internal use] Creates a new Element and returs it.
561	virtual TiXmlNode* Clone() const;
562	// [internal use]
563 	virtual void Print( FILE* cfile, int depth ) const;
564	// [internal use]
565	virtual void StreamOut ( std::ostream* out ) const;
566	// [internal use]
567	virtual void StreamIn( std::istream* in, std::string* tag );
568
569  protected:
570	/*	[internal use]
571		Attribtue parsing starts: next char past '<'
572						 returns: next char past '>'
573	*/
574	virtual const char* Parse( const char* p );
575
576	/*	[internal use]
577		Reads the "value" of the element -- another element, or text.
578		This should terminate with the current end tag.
579	*/
580	const char* ReadValue( const char* in );
581	bool ReadValue( std::istream* in );
582
583  private:
584	TiXmlAttributeSet attributeSet;
585};
586
587
588/**	An XML comment.
589*/
590class TiXmlComment : public TiXmlNode
591{
592  public:
593	/// Constructs an empty comment.
594	TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {}
595	virtual ~TiXmlComment()	{}
596
597	// [internal use] Creates a new Element and returs it.
598	virtual TiXmlNode* Clone() const;
599	// [internal use]
600 	virtual void Print( FILE* cfile, int depth ) const;
601	// [internal use]
602	virtual void StreamOut ( std::ostream* out ) const;
603	// [internal use]
604	virtual void StreamIn( std::istream* in, std::string* tag );
605
606  protected:
607	/*	[internal use]
608		Attribtue parsing starts: at the ! of the !--
609						 returns: next char past '>'
610	*/
611	virtual const char* Parse( const char* p );
612};
613
614
615/** XML text. Contained in an element.
616*/
617class TiXmlText : public TiXmlNode
618{
619  public:
620	TiXmlText( const std::string& initValue )  : TiXmlNode( TiXmlNode::TEXT ) { SetValue( initValue ); }
621	virtual ~TiXmlText() {}
622
623
624	// [internal use] Creates a new Element and returns it.
625	virtual TiXmlNode* Clone() const;
626	// [internal use]
627 	virtual void Print( FILE* cfile, int depth ) const;
628	// [internal use]
629	virtual void StreamOut ( std::ostream* out ) const;
630	// [internal use]
631	bool Blank() const;	// returns true if all white space and new lines
632	/*	[internal use]
633		Attribtue parsing starts: First char of the text
634						 returns: next char past '>'
635	*/
636	virtual const char* Parse( const char* p );
637	// [internal use]
638	virtual void StreamIn( std::istream* in, std::string* tag );
639};
640
641
642/** In correct XML the declaration is the first entry in the file.
643	@verbatim
644		<?xml version="1.0" standalone="yes"?>
645	@endverbatim
646
647	TinyXml will happily read or write files without a declaration,
648	however. There are 3 possible attributes to the declaration:
649	version, encoding, and standalone.
650
651	Note: In this version of the code, the attributes are
652	handled as special cases, not generic attributes, simply
653	because there can only be at most 3 and they are always the same.
654*/
655class TiXmlDeclaration : public TiXmlNode
656{
657  public:
658	/// Construct an empty declaration.
659	TiXmlDeclaration()   : TiXmlNode( TiXmlNode::DECLARATION ) {}
660
661	/// Construct.
662	TiXmlDeclaration( const std::string& version,
663					  const std::string& encoding,
664					  const std::string& standalone );
665
666	virtual ~TiXmlDeclaration()	{}
667
668	/// Version. Will return empty if none was found.
669	const std::string& Version() const		{ return version; }
670	/// Encoding. Will return empty if none was found.
671	const std::string& Encoding() const		{ return encoding; }
672	/// Is this a standalone document?
673	const std::string& Standalone() const		{ return standalone; }
674
675	// [internal use] Creates a new Element and returs it.
676	virtual TiXmlNode* Clone() const;
677	// [internal use]
678 	virtual void Print( FILE* cfile, int depth ) const;
679	// [internal use]
680	virtual void StreamOut ( std::ostream* out ) const;
681	// [internal use]
682	virtual void StreamIn( std::istream* in, std::string* tag );
683
684  protected:
685	//	[internal use]
686	//	Attribtue parsing starts: next char past '<'
687	//					 returns: next char past '>'
688
689	virtual const char* Parse( const char* p );
690
691  private:
692	std::string version;
693	std::string encoding;
694	std::string standalone;
695};
696
697
698/** Any tag that tinyXml doesn't recognize is save as an
699	unknown. It is a tag of text, but should not be modified.
700	It will be written back to the XML, unchanged, when the file
701	is saved.
702*/
703class TiXmlUnknown : public TiXmlNode
704{
705  public:
706	TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {}
707	virtual ~TiXmlUnknown() {}
708
709	// [internal use]
710	virtual TiXmlNode* Clone() const;
711	// [internal use]
712 	virtual void Print( FILE* cfile, int depth ) const;
713	// [internal use]
714	virtual void StreamOut ( std::ostream* out ) const;
715	// [internal use]
716	virtual void StreamIn( std::istream* in, std::string* tag );
717
718  protected:
719	/*	[internal use]
720		Attribute parsing starts: First char of the text
721						 returns: next char past '>'
722	*/
723	virtual const char* Parse( const char* p );
724};
725
726
727/** Always the top level node. A document binds together all the
728	XML pieces. It can be saved, loaded, and printed to the screen.
729	The 'value' of a document node is the xml file name.
730*/
731class TiXmlDocument : public TiXmlNode
732{
733  public:
734	/// Create an empty document, that has no name.
735	TiXmlDocument();
736	/// Create a document with a name. The name of the document is also the filename of the xml.
737	TiXmlDocument( const std::string& documentName );
738
739	virtual ~TiXmlDocument() {}
740
741	/** Load a file using the current document value.
742		Returns true if successful. Will delete any existing
743		document data before loading.
744	*/
745	bool LoadFile();
746	/// Save a file using the current document value. Returns true if successful.
747	bool SaveFile() const;
748	/// Load a file using the given filename. Returns true if successful.
749	bool LoadFile( const std::string& filename );
750	/// Save a file using the given filename. Returns true if successful.
751	bool SaveFile( const std::string& filename ) const;
752
753	/// Parse the given null terminated block of xml data.
754	virtual const char* Parse( const char* p );
755
756	/** Get the root element -- the only top level element -- of the document.
757		In well formed XML, there should only be one. TinyXml is tolerant of
758		multiple elements at the document level.
759	*/
760	TiXmlElement* RootElement() const		{ return FirstChildElement(); }
761
762	/// If, during parsing, a error occurs, Error will be set to true.
763	bool Error() const						{ return error; }
764
765	/// Contains a textual (english) description of the error if one occurs.
766	const std::string& ErrorDesc() const	{ return errorDesc; }
767
768	/** Generally, you probably want the error string ( ErrorDesc() ). But if you
769		prefer the ErrorId, this function will fetch it.
770	*/
771	const int ErrorId()	const				{ return errorId; }
772
773	/// If you have handled the error, it can be reset with this call.
774	void ClearError()						{ error = false; errorId = 0; errorDesc = ""; }
775
776	/** Dump the document to standard out. */
777	void Print() const								{ Print( stdout, 0 ); }
778
779	// [internal use]
780 	virtual void Print( FILE* cfile, int depth = 0 ) const;
781	// [internal use]
782	virtual void StreamOut ( std::ostream* out ) const;
783	// [internal use]
784	virtual TiXmlNode* Clone() const;
785	// [internal use]
786	void SetError( int err ) {		assert( err > 0 && err < TIXML_ERROR_STRING_COUNT );
787									error   = true;
788									errorId = err;
789									errorDesc = errorString[ errorId ]; }
790	// [internal use]
791	virtual void StreamIn( std::istream* in, std::string* tag );
792
793  protected:
794
795  private:
796	bool error;
797	int  errorId;
798	std::string errorDesc;
799};
800
801
802
803#endif
804
805