Blame ACM/tinyxml/tinyxml.h

Packit 47f805
/*
Packit 47f805
Copyright (c) 2000 Lee Thomason (www.grinninglizard.com)
Packit 47f805
Packit 47f805
This software is provided 'as-is', without any express or implied 
Packit 47f805
warranty. In no event will the authors be held liable for any 
Packit 47f805
damages arising from the use of this software.
Packit 47f805
Packit 47f805
Permission is granted to anyone to use this software for any 
Packit 47f805
purpose, including commercial applications, and to alter it and 
Packit 47f805
redistribute it freely, subject to the following restrictions:
Packit 47f805
Packit 47f805
1. The origin of this software must not be misrepresented; you must 
Packit 47f805
not claim that you wrote the original software. If you use this 
Packit 47f805
software in a product, an acknowledgment in the product documentation 
Packit 47f805
would be appreciated but is not required.
Packit 47f805
Packit 47f805
2. Altered source versions must be plainly marked as such, and
Packit 47f805
must not be misrepresented as being the original software.
Packit 47f805
Packit 47f805
3. This notice may not be removed or altered from any source 
Packit 47f805
distribution.
Packit 47f805
*/
Packit 47f805
Packit 47f805
Packit 47f805
#ifndef TINYXML_INCLUDED
Packit 47f805
#define TINYXML_INCLUDED
Packit 47f805
Packit 47f805
#pragma warning( disable : 4530 )
Packit 47f805
#pragma warning( disable : 4786 )
Packit 47f805
Packit 47f805
#include <string>
Packit 47f805
#include <stdio.h>
Packit 47f805
#include <assert.h>
Packit 47f805
Packit 47f805
class TiXmlDocument;
Packit 47f805
class TiXmlElement;
Packit 47f805
class TiXmlComment;
Packit 47f805
class TiXmlUnknown;
Packit 47f805
class TiXmlAttribute;
Packit 47f805
class TiXmlText;
Packit 47f805
class TiXmlDeclaration;
Packit 47f805
Packit 47f805
Packit 47f805
// Help out windows:
Packit 47f805
#if defined( _DEBUG ) && !defined( DEBUG )
Packit 47f805
	#define DEBUG
Packit 47f805
#endif
Packit 47f805
Packit 47f805
#if defined( DEBUG ) && defined( _MSC_VER )
Packit 47f805
	#include <windows.h>
Packit 47f805
	#define TIXML_LOG OutputDebugString
Packit 47f805
#else
Packit 47f805
	#define TIXML_LOG printf
Packit 47f805
#endif 
Packit 47f805
Packit 47f805
Packit 47f805
/** TiXmlBase is a base class for every class in TinyXml.
Packit 47f805
	It does little except to establish that TinyXml classes
Packit 47f805
	can be printed and provide some utility functions.
Packit 47f805
Packit 47f805
	In XML, the document and elements can contain
Packit 47f805
	other elements and other types of nodes.
Packit 47f805
Packit 47f805
	@verbatim
Packit 47f805
	A Document can contain:	Element	(container or leaf)
Packit 47f805
							Comment (leaf)
Packit 47f805
							Unknown (leaf)
Packit 47f805
							Declaration( leaf )
Packit 47f805
Packit 47f805
	An Element can contain:	Element (container or leaf)
Packit 47f805
							Text	(leaf)
Packit 47f805
							Attributes (not on tree)
Packit 47f805
							Comment (leaf)
Packit 47f805
							Unknown (leaf)
Packit 47f805
Packit 47f805
	A Decleration contains: Attributes (not on tree)
Packit 47f805
	@endverbatim
Packit 47f805
*/
Packit 47f805
class TiXmlBase
Packit 47f805
{
Packit 47f805
	friend class TiXmlNode;
Packit 47f805
	friend class TiXmlElement;
Packit 47f805
	friend class TiXmlDocument;
Packit 47f805
 
Packit 47f805
  public:
Packit 47f805
	TiXmlBase()								{}	
Packit 47f805
	virtual ~TiXmlBase()					{}
Packit 47f805
	
Packit 47f805
	/**	All TinyXml classes can print themselves to a filestream.
Packit 47f805
		This is a formatted print, and will insert tabs and newlines.
Packit 47f805
		
Packit 47f805
		(For an unformatted stream, use the << operator.)
Packit 47f805
	*/
Packit 47f805
 	virtual void Print( FILE* cfile, int depth ) const = 0;
Packit 47f805
Packit 47f805
	// [internal] Underlying implementation of the operator <<
Packit 47f805
	virtual void StreamOut ( std::ostream* out ) const = 0;
Packit 47f805
Packit 47f805
	/**	The world does not agree on whether white space should be kept or
Packit 47f805
		not. In order to make everyone happy, these global, static functions
Packit 47f805
		are provided to set whether or not TinyXml will condense all white space
Packit 47f805
		into a single space or not. The default is to condense. Note changing these
Packit 47f805
		values is not thread safe.
Packit 47f805
	*/
Packit 47f805
	static void SetCondenseWhiteSpace( bool condense )		{ condenseWhiteSpace = condense; }
Packit 47f805
Packit 47f805
	/// Return the current white space setting.
Packit 47f805
	static bool IsWhiteSpaceCondensed()						{ return condenseWhiteSpace; }
Packit 47f805
Packit 47f805
  protected:
Packit 47f805
	static const char* SkipWhiteSpace( const char* );
Packit 47f805
	static bool StreamWhiteSpace( std::istream* in, std::string* tag );
Packit 47f805
	static bool IsWhiteSpace( int c )		{ return ( isspace( c ) || c == '\n' || c == '\r' ); }
Packit 47f805
Packit 47f805
	/*	Read to the specified character.
Packit 47f805
		Returns true if the character found and no error.
Packit 47f805
	*/
Packit 47f805
	static bool StreamTo( std::istream* in, int character, std::string* tag );
Packit 47f805
Packit 47f805
	/*	Reads an XML name into the string provided. Returns
Packit 47f805
		a pointer just past the last character of the name, 
Packit 47f805
		or 0 if the function has an error.
Packit 47f805
	*/
Packit 47f805
	static const char* ReadName( const char*, std::string* name );
Packit 47f805
Packit 47f805
	/*	Reads text. Returns a pointer past the given end tag.
Packit 47f805
		Wickedly complex options, but it keeps the (sensitive) code in one place.
Packit 47f805
	*/
Packit 47f805
	static const char* ReadText(	const char* in,				// where to start
Packit 47f805
									std::string* text,			// the string read
Packit 47f805
									bool ignoreWhiteSpace,		// whether to keep the white space
Packit 47f805
									const char* endTag,			// what ends this text
Packit 47f805
									bool ignoreCase );			// whether to ignore case in the end tag
Packit 47f805
Packit 47f805
	virtual const char* Parse( const char* p ) = 0;
Packit 47f805
Packit 47f805
	// If an entity has been found, transform it into a character.
Packit 47f805
	static const char* GetEntity( const char* in, char* value );
Packit 47f805
Packit 47f805
	// Get a character, while interpreting entities.
Packit 47f805
	inline static const char* GetChar( const char* p, char* value )		
Packit 47f805
											{		
Packit 47f805
												assert( p );
Packit 47f805
												if ( *p == '&' ) 
Packit 47f805
												{
Packit 47f805
													return GetEntity( p, value );
Packit 47f805
												}
Packit 47f805
												else 
Packit 47f805
												{
Packit 47f805
													*value = *p;
Packit 47f805
													return p+1;
Packit 47f805
												}
Packit 47f805
											}
Packit 47f805
Packit 47f805
	// Puts a string to a stream, expanding entities as it goes.
Packit 47f805
	// Note this should not contian the '<', '>', etc, or they will be transformed into entities!
Packit 47f805
	static void PutString( const std::string& str, std::ostream* stream );
Packit 47f805
Packit 47f805
	// Return true if the next characters in the stream are any of the endTag sequences.
Packit 47f805
	bool static StringEqual(	const char* p, 
Packit 47f805
								const char* endTag, 
Packit 47f805
								bool ignoreCase );
Packit 47f805
													
Packit 47f805
Packit 47f805
	enum
Packit 47f805
	{
Packit 47f805
		TIXML_NO_ERROR = 0,
Packit 47f805
		TIXML_ERROR,
Packit 47f805
		TIXML_ERROR_OPENING_FILE,
Packit 47f805
		TIXML_ERROR_OUT_OF_MEMORY,
Packit 47f805
		TIXML_ERROR_PARSING_ELEMENT,
Packit 47f805
		TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
Packit 47f805
		TIXML_ERROR_READING_ELEMENT_VALUE,
Packit 47f805
		TIXML_ERROR_READING_ATTRIBUTES,
Packit 47f805
		TIXML_ERROR_PARSING_EMPTY,
Packit 47f805
		TIXML_ERROR_READING_END_TAG,
Packit 47f805
		TIXML_ERROR_PARSING_UNKNOWN,
Packit 47f805
		TIXML_ERROR_PARSING_COMMENT,
Packit 47f805
		TIXML_ERROR_PARSING_DECLARATION,
Packit 47f805
		TIXML_ERROR_DOCUMENT_EMPTY,
Packit 47f805
Packit 47f805
		TIXML_ERROR_STRING_COUNT
Packit 47f805
	};
Packit 47f805
	static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
Packit 47f805
Packit 47f805
  private:
Packit 47f805
	struct Entity
Packit 47f805
	{
Packit 47f805
		const char*     str;
Packit 47f805
		unsigned int	strLength;
Packit 47f805
		int			    chr;
Packit 47f805
	};
Packit 47f805
	enum
Packit 47f805
	{
Packit 47f805
		NUM_ENTITY = 5,
Packit 47f805
		MAX_ENTITY_LENGTH = 6
Packit 47f805
Packit 47f805
	};
Packit 47f805
	static Entity entity[ NUM_ENTITY ];
Packit 47f805
	static bool condenseWhiteSpace;
Packit 47f805
};
Packit 47f805
Packit 47f805
Packit 47f805
/** The parent class for everything in the Document Object Model.
Packit 47f805
	(Except for attributes, which are contained in elements.)
Packit 47f805
	Nodes have siblings, a parent, and children. A node can be
Packit 47f805
	in a document, or stand on its own. The type of a TiXmlNode
Packit 47f805
	can be queried, and it can be cast to its more defined type.
Packit 47f805
*/
Packit 47f805
class TiXmlNode : public TiXmlBase
Packit 47f805
{
Packit 47f805
  public:
Packit 47f805
Packit 47f805
	/** An output stream operator, for every class. Note that this outputs
Packit 47f805
		without any newlines or formatting, as opposed to Print(), which
Packit 47f805
		includes tabs and new lines.
Packit 47f805
Packit 47f805
		The operator<< and operator>> are not completely symmetric. Writing
Packit 47f805
		a node to a stream is very well defined. You'll get a nice stream
Packit 47f805
		of output, without any extra whitespace or newlines. 
Packit 47f805
		
Packit 47f805
		But reading is not as well defined. (As it always is.) If you create
Packit 47f805
		a TiXmlElement (for example) and read that from an input stream,
Packit 47f805
		the text needs to define an element or junk will result. This is
Packit 47f805
		true of all input streams, but it's worth keeping in mind.
Packit 47f805
Packit 47f805
		A TiXmlDocument will read nodes until it reads a root element.
Packit 47f805
	*/
Packit 47f805
	friend std::ostream& operator<< ( std::ostream& out, const TiXmlNode& base )
Packit 47f805
	{
Packit 47f805
		base.StreamOut( &out );
Packit 47f805
		return out;
Packit 47f805
	}
Packit 47f805
Packit 47f805
	/** An input stream operator, for every class. Tolerant of newlines and
Packit 47f805
		formatting, but doesn't expect them.
Packit 47f805
	*/
Packit 47f805
	friend std::istream& operator>> ( std::istream& in, TiXmlNode& base )
Packit 47f805
	{
Packit 47f805
		std::string tag;
Packit 47f805
		tag.reserve( 8 * 1000 );
Packit 47f805
		base.StreamIn( &in, &tag );
Packit 47f805
		
Packit 47f805
		base.Parse( tag.c_str() );
Packit 47f805
		return in;
Packit 47f805
	}
Packit 47f805
Packit 47f805
	/** The types of XML nodes supported by TinyXml. (All the
Packit 47f805
		unsupported types are picked up by UNKNOWN.)
Packit 47f805
	*/
Packit 47f805
	enum NodeType 
Packit 47f805
	{
Packit 47f805
		DOCUMENT, 
Packit 47f805
		ELEMENT, 
Packit 47f805
		COMMENT, 
Packit 47f805
		UNKNOWN, 
Packit 47f805
		TEXT, 
Packit 47f805
		DECLARATION, 
Packit 47f805
		TYPECOUNT
Packit 47f805
	};
Packit 47f805
Packit 47f805
	virtual ~TiXmlNode();
Packit 47f805
Packit 47f805
	/** The meaning of 'value' changes for the specific type of
Packit 47f805
		TiXmlNode.
Packit 47f805
		@verbatim
Packit 47f805
		Document:	filename of the xml file
Packit 47f805
		Element:	name of the element
Packit 47f805
		Comment:	the comment text
Packit 47f805
		Unknown:	the tag contents
Packit 47f805
		Text:		the text string
Packit 47f805
		@endverbatim
Packit 47f805
Packit 47f805
		The subclasses will wrap this function.
Packit 47f805
	*/
Packit 47f805
	const std::string& Value()	const			{ return value; }
Packit 47f805
Packit 47f805
	/** Changes the value of the node. Defined as:
Packit 47f805
		@verbatim
Packit 47f805
		Document:	filename of the xml file
Packit 47f805
		Element:	name of the element
Packit 47f805
		Comment:	the comment text
Packit 47f805
		Unknown:	the tag contents
Packit 47f805
		Text:		the text string
Packit 47f805
		@endverbatim
Packit 47f805
	*/
Packit 47f805
	void SetValue( const std::string& _value )		{ value = _value; }
Packit 47f805
Packit 47f805
	/// Delete all the children of this node. Does not affect 'this'.
Packit 47f805
	void Clear();
Packit 47f805
Packit 47f805
	/// One step up the DOM.
Packit 47f805
	TiXmlNode* Parent() const					{ return parent; }
Packit 47f805
Packit 47f805
	TiXmlNode* FirstChild()	const	{ return firstChild; }		///< The first child of this node. Will be null if there are no children.
Packit 47f805
	TiXmlNode* FirstChild( const std::string& value ) const;	///< The first child of this node with the matching 'value'. Will be null if none found.
Packit 47f805
	
Packit 47f805
	TiXmlNode* LastChild() const	{ return lastChild; }		/// The last child of this node. Will be null if there are no children.
Packit 47f805
	TiXmlNode* LastChild( const std::string& value ) const;		/// The last child of this node matching 'value'. Will be null if there are no children.
Packit 47f805
Packit 47f805
	/** An alternate way to walk the children of a node.
Packit 47f805
		One way to iterate over nodes is:
Packit 47f805
		@verbatim
Packit 47f805
			for( child = parent->FirstChild(); child; child = child->NextSibling() )
Packit 47f805
		@endverbatim
Packit 47f805
Packit 47f805
		IterateChildren does the same thing with the syntax:
Packit 47f805
		@verbatim
Packit 47f805
			child = 0;
Packit 47f805
			while( child = parent->IterateChildren( child ) )
Packit 47f805
		@endverbatim
Packit 47f805
Packit 47f805
		IterateChildren takes the previous child as input and finds
Packit 47f805
		the next one. If the previous child is null, it returns the
Packit 47f805
		first. IterateChildren will return null when done.
Packit 47f805
	*/
Packit 47f805
	TiXmlNode* IterateChildren( TiXmlNode* previous ) const;
Packit 47f805
Packit 47f805
	/// This flavor of IterateChildren searches for children with a particular 'value'
Packit 47f805
	TiXmlNode* IterateChildren( const std::string& value, TiXmlNode* previous ) const;
Packit 47f805
		
Packit 47f805
	/** Add a new node related to this. Adds a child past the LastChild.
Packit 47f805
		Returns a pointer to the new object or NULL if an error occured.
Packit 47f805
	*/
Packit 47f805
	TiXmlNode* InsertEndChild( const TiXmlNode& addThis );					
Packit 47f805
Packit 47f805
	/** Add a new node related to this. Adds a child before the specified child.
Packit 47f805
		Returns a pointer to the new object or NULL if an error occured.
Packit 47f805
	*/
Packit 47f805
	TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
Packit 47f805
Packit 47f805
	/** Add a new node related to this. Adds a child after the specified child.
Packit 47f805
		Returns a pointer to the new object or NULL if an error occured.
Packit 47f805
	*/
Packit 47f805
	TiXmlNode* InsertAfterChild(  TiXmlNode* afterThis, const TiXmlNode& addThis );
Packit 47f805
	
Packit 47f805
	/** Replace a child of this node.
Packit 47f805
		Returns a pointer to the new object or NULL if an error occured.
Packit 47f805
	*/
Packit 47f805
	TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
Packit 47f805
	
Packit 47f805
	/// Delete a child of this node.
Packit 47f805
	bool RemoveChild( TiXmlNode* removeThis );
Packit 47f805
Packit 47f805
	/// Navigate to a sibling node.
Packit 47f805
	TiXmlNode* PreviousSibling() const			{ return prev; }
Packit 47f805
Packit 47f805
	/// Navigate to a sibling node.
Packit 47f805
	TiXmlNode* PreviousSibling( const std::string& ) const;
Packit 47f805
	
Packit 47f805
	/// Navigate to a sibling node.
Packit 47f805
	TiXmlNode* NextSibling() const				{ return next; }
Packit 47f805
Packit 47f805
	/// Navigate to a sibling node with the given 'value'.
Packit 47f805
	TiXmlNode* NextSibling( const std::string& ) const;
Packit 47f805
Packit 47f805
	/** Convenience function to get through elements. 
Packit 47f805
		Calls NextSibling and ToElement. Will skip all non-Element
Packit 47f805
		nodes. Returns 0 if there is not another element.
Packit 47f805
	*/
Packit 47f805
	TiXmlElement* NextSiblingElement() const;
Packit 47f805
Packit 47f805
	/** Convenience function to get through elements. 
Packit 47f805
		Calls NextSibling and ToElement. Will skip all non-Element
Packit 47f805
		nodes. Returns 0 if there is not another element.
Packit 47f805
	*/
Packit 47f805
	TiXmlElement* NextSiblingElement( const std::string& ) const;
Packit 47f805
Packit 47f805
	/// Convenience function to get through elements.
Packit 47f805
	TiXmlElement* FirstChildElement()	const;
Packit 47f805
	
Packit 47f805
	/// Convenience function to get through elements.
Packit 47f805
	TiXmlElement* FirstChildElement( const std::string& value ) const;
Packit 47f805
Packit 47f805
	/// Query the type (as an enumerated value, above) of this node.
Packit 47f805
	virtual int Type() const	{ return type; }
Packit 47f805
Packit 47f805
	/** Return a pointer to the Document this node lives in. 
Packit 47f805
		Returns null if not in a document.
Packit 47f805
	*/
Packit 47f805
	TiXmlDocument* GetDocument() const;
Packit 47f805
Packit 47f805
	/// Returns true if this node has no children.
Packit 47f805
	bool NoChildren() const						{ return !firstChild; }
Packit 47f805
Packit 47f805
	TiXmlDocument* ToDocument()	const		{ return ( this && type == DOCUMENT ) ? (TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
Packit 47f805
	TiXmlElement*  ToElement() const		{ return ( this && type == ELEMENT  ) ? (TiXmlElement*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
Packit 47f805
	TiXmlComment*  ToComment() const		{ return ( this && type == COMMENT  ) ? (TiXmlComment*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
Packit 47f805
	TiXmlUnknown*  ToUnknown() const		{ return ( this && type == UNKNOWN  ) ? (TiXmlUnknown*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
Packit 47f805
	TiXmlText*	   ToText()    const		{ return ( this && type == TEXT     ) ? (TiXmlText*)     this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
Packit 47f805
	TiXmlDeclaration* ToDeclaration() const	{ return ( this && type == DECLARATION ) ? (TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
Packit 47f805
Packit 47f805
	virtual TiXmlNode* Clone() const = 0;
Packit 47f805
Packit 47f805
	// The real work of the input operator.
Packit 47f805
	virtual void StreamIn( std::istream* in, std::string* tag ) = 0;
Packit 47f805
Packit 47f805
  protected:
Packit 47f805
	TiXmlNode( NodeType type );
Packit 47f805
Packit 47f805
	// The node is passed in by ownership. This object will delete it.
Packit 47f805
	TiXmlNode* LinkEndChild( TiXmlNode* addThis );
Packit 47f805
Packit 47f805
	// Figure out what is at *p, and parse it. Returns null if it is not an xml node.
Packit 47f805
	TiXmlNode* Identify( const char* start );
Packit 47f805
Packit 47f805
	void CopyToClone( TiXmlNode* target ) const	{ target->value = value; }
Packit 47f805
Packit 47f805
	TiXmlNode*		parent;		
Packit 47f805
	NodeType		type;
Packit 47f805
	
Packit 47f805
	TiXmlNode*		firstChild;
Packit 47f805
	TiXmlNode*		lastChild;
Packit 47f805
Packit 47f805
	std::string		value;
Packit 47f805
	
Packit 47f805
	TiXmlNode*		prev;
Packit 47f805
	TiXmlNode*		next;
Packit 47f805
};
Packit 47f805
Packit 47f805
Packit 47f805
/** An attribute is a name-value pair. Elements have an arbitrary
Packit 47f805
	number of attributes, each with a unique name.
Packit 47f805
Packit 47f805
	@note The attributes are not TiXmlNodes, since they are not
Packit 47f805
		  part of the tinyXML document object model. There are other
Packit 47f805
		  suggested ways to look at this problem.
Packit 47f805
Packit 47f805
	@note Attributes have a parent
Packit 47f805
*/
Packit 47f805
class TiXmlAttribute : public TiXmlBase
Packit 47f805
{
Packit 47f805
	friend class TiXmlAttributeSet;
Packit 47f805
Packit 47f805
  public:
Packit 47f805
	/// Construct an empty attribute.
Packit 47f805
	TiXmlAttribute() : prev( 0 ), next( 0 )	{}
Packit 47f805
Packit 47f805
	/// Construct an attribute with a name and value.
Packit 47f805
	TiXmlAttribute( const std::string& _name, const std::string& _value )	: name( _name ), value( _value ), prev( 0 ), next( 0 ) {}
Packit 47f805
Packit 47f805
	const std::string& Name()  const { return name; }		///< Return the name of this attribute.
Packit 47f805
Packit 47f805
	const std::string& Value() const { return value; }		///< Return the value of this attribute.
Packit 47f805
	const int          IntValue() const;					///< Return the value of this attribute, converted to an integer.
Packit 47f805
	const double	   DoubleValue() const;					///< Return the value of this attribute, converted to a double.
Packit 47f805
Packit 47f805
	void SetName( const std::string& _name )	{ name = _name; }		///< Set the name of this attribute.
Packit 47f805
	void SetValue( const std::string& _value )	{ value = _value; }		///< Set the value.
Packit 47f805
	void SetIntValue( int value );										///< Set the value from an integer.
Packit 47f805
	void SetDoubleValue( double value );								///< Set the value from a double.
Packit 47f805
Packit 47f805
	/// Get the next sibling attribute in the DOM. Returns null at end.
Packit 47f805
	TiXmlAttribute* Next() const;
Packit 47f805
	/// Get the previous sibling attribute in the DOM. Returns null at beginning.
Packit 47f805
	TiXmlAttribute* Previous() const;
Packit 47f805
Packit 47f805
	bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
Packit 47f805
	bool operator<( const TiXmlAttribute& rhs )	 const { return name < rhs.name; }
Packit 47f805
	bool operator>( const TiXmlAttribute& rhs )  const { return name > rhs.name; }
Packit 47f805
Packit 47f805
	/*	[internal use] 
Packit 47f805
		Attribtue parsing starts: first letter of the name
Packit 47f805
						 returns: the next char after the value end quote
Packit 47f805
	*/	
Packit 47f805
	virtual const char* Parse( const char* p );
Packit 47f805
Packit 47f805
	// [internal use] 
Packit 47f805
 	virtual void Print( FILE* cfile, int depth ) const;
Packit 47f805
Packit 47f805
	// [internal use] 
Packit 47f805
	virtual void StreamOut( std::ostream* out ) const;
Packit 47f805
Packit 47f805
	// [internal use]
Packit 47f805
	// Set the document pointer so the attribute can report errors.
Packit 47f805
	void SetDocument( TiXmlDocument* doc )	{ document = doc; }
Packit 47f805
Packit 47f805
  private:
Packit 47f805
	TiXmlDocument*	document;	// A pointer back to a document, for error reporting.
Packit 47f805
	std::string		name;
Packit 47f805
	std::string		value;
Packit 47f805
Packit 47f805
	TiXmlAttribute*	prev;
Packit 47f805
	TiXmlAttribute*	next;
Packit 47f805
};
Packit 47f805
Packit 47f805
Packit 47f805
/*	A class used to manage a group of attributes.
Packit 47f805
	It is only used internally, both by the ELEMENT and the DECLARATION.
Packit 47f805
	
Packit 47f805
	The set can be changed transparent to the Element and Declaration
Packit 47f805
	classes that use it, but NOT transparent to the Attribute 
Packit 47f805
	which has to implement a next() and previous() method. Which makes
Packit 47f805
	it a bit problematic and prevents the use of STL.
Packit 47f805
Packit 47f805
	This version is implemented with circular lists because:
Packit 47f805
		- I like circular lists
Packit 47f805
		- it demonstrates some independence from the (typical) doubly linked list.
Packit 47f805
*/
Packit 47f805
class TiXmlAttributeSet
Packit 47f805
{
Packit 47f805
  public:
Packit 47f805
	TiXmlAttributeSet();
Packit 47f805
	~TiXmlAttributeSet();
Packit 47f805
Packit 47f805
	void Add( TiXmlAttribute* attribute );
Packit 47f805
	void Remove( TiXmlAttribute* attribute );
Packit 47f805
Packit 47f805
	TiXmlAttribute* First() const	{ return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
Packit 47f805
	TiXmlAttribute* Last()  const	{ return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
Packit 47f805
	
Packit 47f805
	TiXmlAttribute*	Find( const std::string& name ) const;
Packit 47f805
Packit 47f805
  private:
Packit 47f805
	TiXmlAttribute sentinel;
Packit 47f805
};
Packit 47f805
Packit 47f805
Packit 47f805
/** The element is a container class. It has a value, the element name,
Packit 47f805
	and can contain other elements, text, comments, and unknowns.
Packit 47f805
	Elements also contain an arbitrary number of attributes.
Packit 47f805
*/
Packit 47f805
class TiXmlElement : public TiXmlNode
Packit 47f805
{
Packit 47f805
  public:
Packit 47f805
	/// Construct an element.
Packit 47f805
	TiXmlElement( const std::string& value );
Packit 47f805
Packit 47f805
	virtual ~TiXmlElement();
Packit 47f805
Packit 47f805
	/** Given an attribute name, attribute returns the value
Packit 47f805
		for the attribute of that name, or null if none exists.
Packit 47f805
	*/
Packit 47f805
	const std::string* Attribute( const std::string& name ) const;
Packit 47f805
Packit 47f805
	/** Given an attribute name, attribute returns the value
Packit 47f805
		for the attribute of that name, or null if none exists.
Packit 47f805
	*/
Packit 47f805
	const std::string* Attribute( const std::string& name, int* i ) const;
Packit 47f805
Packit 47f805
	/** Sets an attribute of name to a given value. The attribute
Packit 47f805
		will be created if it does not exist, or changed if it does.
Packit 47f805
	*/
Packit 47f805
	void SetAttribute( const std::string& name, 
Packit 47f805
					   const std::string& value );
Packit 47f805
Packit 47f805
	/** Sets an attribute of name to a given value. The attribute
Packit 47f805
		will be created if it does not exist, or changed if it does.
Packit 47f805
	*/
Packit 47f805
	void SetAttribute( const std::string& name, 
Packit 47f805
					   int value );
Packit 47f805
Packit 47f805
	/** Deletes an attribute with the given name.
Packit 47f805
	*/
Packit 47f805
	void RemoveAttribute( const std::string& name );
Packit 47f805
Packit 47f805
	TiXmlAttribute* FirstAttribute() const	{ return attributeSet.First(); }		///< Access the first attribute in this element.
Packit 47f805
	TiXmlAttribute* LastAttribute()	const 	{ return attributeSet.Last(); }		///< Access the last attribute in this element.
Packit 47f805
Packit 47f805
	// [internal use] Creates a new Element and returs it.
Packit 47f805
	virtual TiXmlNode* Clone() const;
Packit 47f805
	// [internal use] 
Packit 47f805
 	virtual void Print( FILE* cfile, int depth ) const;
Packit 47f805
	// [internal use] 
Packit 47f805
	virtual void StreamOut ( std::ostream* out ) const;
Packit 47f805
	// [internal use] 
Packit 47f805
	virtual void StreamIn( std::istream* in, std::string* tag );
Packit 47f805
Packit 47f805
  protected:
Packit 47f805
	/*	[internal use] 
Packit 47f805
		Attribtue parsing starts: next char past '<'
Packit 47f805
						 returns: next char past '>'
Packit 47f805
	*/	
Packit 47f805
	virtual const char* Parse( const char* p );
Packit 47f805
Packit 47f805
	/*	[internal use]
Packit 47f805
		Reads the "value" of the element -- another element, or text.
Packit 47f805
		This should terminate with the current end tag.
Packit 47f805
	*/
Packit 47f805
	const char* ReadValue( const char* in );
Packit 47f805
	bool ReadValue( std::istream* in );
Packit 47f805
Packit 47f805
  private:
Packit 47f805
	TiXmlAttributeSet attributeSet;
Packit 47f805
};
Packit 47f805
Packit 47f805
Packit 47f805
/**	An XML comment.
Packit 47f805
*/
Packit 47f805
class TiXmlComment : public TiXmlNode
Packit 47f805
{
Packit 47f805
  public:
Packit 47f805
	/// Constructs an empty comment.
Packit 47f805
	TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {}
Packit 47f805
	virtual ~TiXmlComment()	{}
Packit 47f805
Packit 47f805
	// [internal use] Creates a new Element and returs it.
Packit 47f805
	virtual TiXmlNode* Clone() const;
Packit 47f805
	// [internal use] 
Packit 47f805
 	virtual void Print( FILE* cfile, int depth ) const;
Packit 47f805
	// [internal use] 
Packit 47f805
	virtual void StreamOut ( std::ostream* out ) const;
Packit 47f805
	// [internal use] 
Packit 47f805
	virtual void StreamIn( std::istream* in, std::string* tag );
Packit 47f805
Packit 47f805
  protected:
Packit 47f805
	/*	[internal use] 
Packit 47f805
		Attribtue parsing starts: at the ! of the !--
Packit 47f805
						 returns: next char past '>'
Packit 47f805
	*/	
Packit 47f805
	virtual const char* Parse( const char* p );
Packit 47f805
};
Packit 47f805
Packit 47f805
Packit 47f805
/** XML text. Contained in an element.
Packit 47f805
*/
Packit 47f805
class TiXmlText : public TiXmlNode
Packit 47f805
{
Packit 47f805
  public:
Packit 47f805
	TiXmlText( const std::string& initValue )  : TiXmlNode( TiXmlNode::TEXT ) { SetValue( initValue ); }
Packit 47f805
	virtual ~TiXmlText() {}
Packit 47f805
Packit 47f805
Packit 47f805
	// [internal use] Creates a new Element and returns it.
Packit 47f805
	virtual TiXmlNode* Clone() const;
Packit 47f805
	// [internal use] 
Packit 47f805
 	virtual void Print( FILE* cfile, int depth ) const;
Packit 47f805
	// [internal use] 
Packit 47f805
	virtual void StreamOut ( std::ostream* out ) const;
Packit 47f805
	// [internal use] 	
Packit 47f805
	bool Blank() const;	// returns true if all white space and new lines
Packit 47f805
	/*	[internal use] 
Packit 47f805
		Attribtue parsing starts: First char of the text
Packit 47f805
						 returns: next char past '>'
Packit 47f805
	*/	
Packit 47f805
	virtual const char* Parse( const char* p );
Packit 47f805
	// [internal use]
Packit 47f805
	virtual void StreamIn( std::istream* in, std::string* tag );
Packit 47f805
};
Packit 47f805
Packit 47f805
Packit 47f805
/** In correct XML the declaration is the first entry in the file.
Packit 47f805
	@verbatim
Packit 47f805
		
Packit 47f805
	@endverbatim
Packit 47f805
Packit 47f805
	TinyXml will happily read or write files without a declaration,
Packit 47f805
	however. There are 3 possible attributes to the declaration: 
Packit 47f805
	version, encoding, and standalone.
Packit 47f805
Packit 47f805
	Note: In this version of the code, the attributes are
Packit 47f805
	handled as special cases, not generic attributes, simply
Packit 47f805
	because there can only be at most 3 and they are always the same.
Packit 47f805
*/
Packit 47f805
class TiXmlDeclaration : public TiXmlNode
Packit 47f805
{
Packit 47f805
  public:
Packit 47f805
	/// Construct an empty declaration.
Packit 47f805
	TiXmlDeclaration()   : TiXmlNode( TiXmlNode::DECLARATION ) {}
Packit 47f805
Packit 47f805
	/// Construct.
Packit 47f805
	TiXmlDeclaration( const std::string& version, 
Packit 47f805
					  const std::string& encoding,
Packit 47f805
					  const std::string& standalone );
Packit 47f805
Packit 47f805
	virtual ~TiXmlDeclaration()	{}
Packit 47f805
Packit 47f805
	/// Version. Will return empty if none was found.
Packit 47f805
	const std::string& Version() const		{ return version; }
Packit 47f805
	/// Encoding. Will return empty if none was found.
Packit 47f805
	const std::string& Encoding() const		{ return encoding; }
Packit 47f805
	/// Is this a standalone document? 
Packit 47f805
	const std::string& Standalone() const		{ return standalone; }
Packit 47f805
Packit 47f805
	// [internal use] Creates a new Element and returs it.
Packit 47f805
	virtual TiXmlNode* Clone() const;
Packit 47f805
	// [internal use] 
Packit 47f805
 	virtual void Print( FILE* cfile, int depth ) const;
Packit 47f805
	// [internal use] 
Packit 47f805
	virtual void StreamOut ( std::ostream* out ) const;
Packit 47f805
	// [internal use] 
Packit 47f805
	virtual void StreamIn( std::istream* in, std::string* tag );
Packit 47f805
Packit 47f805
  protected:
Packit 47f805
	//	[internal use] 
Packit 47f805
	//	Attribtue parsing starts: next char past '<'
Packit 47f805
	//					 returns: next char past '>'
Packit 47f805
	
Packit 47f805
	virtual const char* Parse( const char* p );
Packit 47f805
Packit 47f805
  private:
Packit 47f805
	std::string version;
Packit 47f805
	std::string encoding;
Packit 47f805
	std::string standalone;
Packit 47f805
};
Packit 47f805
Packit 47f805
Packit 47f805
/** Any tag that tinyXml doesn't recognize is save as an 
Packit 47f805
	unknown. It is a tag of text, but should not be modified.
Packit 47f805
	It will be written back to the XML, unchanged, when the file 
Packit 47f805
	is saved.
Packit 47f805
*/
Packit 47f805
class TiXmlUnknown : public TiXmlNode
Packit 47f805
{
Packit 47f805
  public:
Packit 47f805
	TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {}
Packit 47f805
	virtual ~TiXmlUnknown() {}
Packit 47f805
Packit 47f805
	// [internal use] 	
Packit 47f805
	virtual TiXmlNode* Clone() const;
Packit 47f805
	// [internal use] 
Packit 47f805
 	virtual void Print( FILE* cfile, int depth ) const;
Packit 47f805
	// [internal use] 
Packit 47f805
	virtual void StreamOut ( std::ostream* out ) const;
Packit 47f805
	// [internal use] 
Packit 47f805
	virtual void StreamIn( std::istream* in, std::string* tag );
Packit 47f805
Packit 47f805
  protected:
Packit 47f805
	/*	[internal use] 
Packit 47f805
		Attribute parsing starts: First char of the text
Packit 47f805
						 returns: next char past '>'
Packit 47f805
	*/	
Packit 47f805
	virtual const char* Parse( const char* p );
Packit 47f805
};
Packit 47f805
Packit 47f805
Packit 47f805
/** Always the top level node. A document binds together all the
Packit 47f805
	XML pieces. It can be saved, loaded, and printed to the screen.
Packit 47f805
	The 'value' of a document node is the xml file name.
Packit 47f805
*/
Packit 47f805
class TiXmlDocument : public TiXmlNode
Packit 47f805
{
Packit 47f805
  public:
Packit 47f805
	/// Create an empty document, that has no name.
Packit 47f805
	TiXmlDocument();
Packit 47f805
	/// Create a document with a name. The name of the document is also the filename of the xml.
Packit 47f805
	TiXmlDocument( const std::string& documentName );
Packit 47f805
	
Packit 47f805
	virtual ~TiXmlDocument() {}
Packit 47f805
Packit 47f805
	/** Load a file using the current document value. 
Packit 47f805
		Returns true if successful. Will delete any existing
Packit 47f805
		document data before loading.
Packit 47f805
	*/
Packit 47f805
	bool LoadFile();
Packit 47f805
	/// Save a file using the current document value. Returns true if successful.
Packit 47f805
	bool SaveFile() const;
Packit 47f805
	/// Load a file using the given filename. Returns true if successful.
Packit 47f805
	bool LoadFile( const std::string& filename );
Packit 47f805
	/// Save a file using the given filename. Returns true if successful.
Packit 47f805
	bool SaveFile( const std::string& filename ) const;
Packit 47f805
Packit 47f805
	/// Parse the given null terminated block of xml data.
Packit 47f805
	virtual const char* Parse( const char* p );
Packit 47f805
Packit 47f805
	/** Get the root element -- the only top level element -- of the document.
Packit 47f805
		In well formed XML, there should only be one. TinyXml is tolerant of
Packit 47f805
		multiple elements at the document level.
Packit 47f805
	*/
Packit 47f805
	TiXmlElement* RootElement() const		{ return FirstChildElement(); }
Packit 47f805
	
Packit 47f805
	/// If, during parsing, a error occurs, Error will be set to true.
Packit 47f805
	bool Error() const						{ return error; }
Packit 47f805
Packit 47f805
	/// Contains a textual (english) description of the error if one occurs.
Packit 47f805
	const std::string& ErrorDesc() const	{ return errorDesc; }
Packit 47f805
Packit 47f805
	/** Generally, you probably want the error string ( ErrorDesc() ). But if you
Packit 47f805
		prefer the ErrorId, this function will fetch it.
Packit 47f805
	*/
Packit 47f805
	const int ErrorId()	const				{ return errorId; }
Packit 47f805
Packit 47f805
	/// If you have handled the error, it can be reset with this call.
Packit 47f805
	void ClearError()						{ error = false; errorId = 0; errorDesc = ""; }
Packit 47f805
  
Packit 47f805
	/** Dump the document to standard out. */
Packit 47f805
	void Print() const								{ Print( stdout, 0 ); }
Packit 47f805
Packit 47f805
	// [internal use] 
Packit 47f805
 	virtual void Print( FILE* cfile, int depth = 0 ) const;
Packit 47f805
	// [internal use] 
Packit 47f805
	virtual void StreamOut ( std::ostream* out ) const;
Packit 47f805
	// [internal use] 	
Packit 47f805
	virtual TiXmlNode* Clone() const;
Packit 47f805
	// [internal use] 	
Packit 47f805
	void SetError( int err ) {		assert( err > 0 && err < TIXML_ERROR_STRING_COUNT );
Packit 47f805
									error   = true; 
Packit 47f805
									errorId = err;
Packit 47f805
									errorDesc = errorString[ errorId ]; }
Packit 47f805
	// [internal use] 
Packit 47f805
	virtual void StreamIn( std::istream* in, std::string* tag );
Packit 47f805
Packit 47f805
  protected:
Packit 47f805
Packit 47f805
  private:
Packit 47f805
	bool error;
Packit 47f805
	int  errorId;	
Packit 47f805
	std::string errorDesc;
Packit 47f805
};
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
#endif
Packit 47f805