Blame ACM/tinyxml/tinyxml.cpp

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
#include <iostream>
Packit 47f805
#include <sstream>
Packit 47f805
#include <fstream>
Packit 47f805
#include "tinyxml.h"
Packit 47f805
using namespace std;
Packit 47f805
Packit 47f805
Packit 47f805
bool TiXmlBase::condenseWhiteSpace = true;
Packit 47f805
Packit 47f805
Packit 47f805
void TiXmlBase::PutString( const std::string& str, std::ostream* stream )
Packit 47f805
{
Packit 47f805
	// Scan for the all important '&'
Packit 47f805
	unsigned int i=0, j=0;
Packit 47f805
Packit 47f805
	while ( i < str.length() )
Packit 47f805
	{
Packit 47f805
		unsigned next = str.find( '&', i );
Packit 47f805
Packit 47f805
		if ( next == string::npos )
Packit 47f805
		{
Packit 47f805
			stream->write( &str.at( i ), str.length() - i );
Packit 47f805
			return;
Packit 47f805
   		}
Packit 47f805
Packit 47f805
		// We found an entity.
Packit 47f805
		if ( next - i > 0 )
Packit 47f805
			stream->write( &str.at( i ), next - i );
Packit 47f805
		i = next;
Packit 47f805
Packit 47f805
		// Check for the special "&#x" entitity
Packit 47f805
		if (    i < str.length() - 2
Packit 47f805
		     && str[i] == '&'
Packit 47f805
			 && str[i+1] == '#'
Packit 47f805
			 && str[i+2] == 'x' )
Packit 47f805
		{
Packit 47f805
			stream->put( str[i] );
Packit 47f805
		}
Packit 47f805
		else
Packit 47f805
		{
Packit 47f805
			for ( j=0; j
Packit 47f805
			{
Packit 47f805
				if ( str[i] == entity[j].chr )
Packit 47f805
				{
Packit 47f805
					stream->write( entity[j].str, entity[j].strLength );
Packit 47f805
					break;
Packit 47f805
				}
Packit 47f805
			}
Packit 47f805
			if ( j == NUM_ENTITY )
Packit 47f805
			{
Packit 47f805
				stream->put( str[i] );
Packit 47f805
			}
Packit 47f805
		}
Packit 47f805
		++i;
Packit 47f805
	}
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlNode::TiXmlNode( NodeType _type )
Packit 47f805
{
Packit 47f805
	parent = 0;
Packit 47f805
	type = _type;
Packit 47f805
	firstChild = 0;
Packit 47f805
	lastChild = 0;
Packit 47f805
	prev = 0;
Packit 47f805
	next = 0;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlNode::~TiXmlNode()
Packit 47f805
{
Packit 47f805
	TiXmlNode* node = firstChild;
Packit 47f805
	TiXmlNode* temp = 0;
Packit 47f805
Packit 47f805
	while ( node )
Packit 47f805
	{
Packit 47f805
		temp = node;
Packit 47f805
		node = node->next;
Packit 47f805
		delete temp;
Packit 47f805
	}	
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
void TiXmlNode::Clear()
Packit 47f805
{
Packit 47f805
	TiXmlNode* node = firstChild;
Packit 47f805
	TiXmlNode* temp = 0;
Packit 47f805
Packit 47f805
	while ( node )
Packit 47f805
	{
Packit 47f805
		temp = node;
Packit 47f805
		node = node->next;
Packit 47f805
		delete temp;
Packit 47f805
	}	
Packit 47f805
Packit 47f805
	firstChild = 0;
Packit 47f805
	lastChild = 0;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node )
Packit 47f805
{
Packit 47f805
	node->parent = this;
Packit 47f805
	
Packit 47f805
	node->prev = lastChild;
Packit 47f805
	node->next = 0;
Packit 47f805
Packit 47f805
	if ( lastChild )
Packit 47f805
		lastChild->next = node;
Packit 47f805
	else
Packit 47f805
		firstChild = node;			// it was an empty list.
Packit 47f805
Packit 47f805
	lastChild = node;
Packit 47f805
	return node;
Packit 47f805
}
Packit 47f805
	
Packit 47f805
Packit 47f805
TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis )
Packit 47f805
{
Packit 47f805
	TiXmlNode* node = addThis.Clone();
Packit 47f805
	if ( !node )
Packit 47f805
		return 0;
Packit 47f805
Packit 47f805
	return LinkEndChild( node );
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis )
Packit 47f805
{
Packit 47f805
	if ( beforeThis->parent != this )
Packit 47f805
		return 0;
Packit 47f805
	
Packit 47f805
	TiXmlNode* node = addThis.Clone();
Packit 47f805
	if ( !node )
Packit 47f805
		return 0;
Packit 47f805
	node->parent = this;
Packit 47f805
	
Packit 47f805
	node->next = beforeThis;
Packit 47f805
	node->prev = beforeThis->prev;
Packit 47f805
	beforeThis->prev->next = node;
Packit 47f805
	beforeThis->prev = node;
Packit 47f805
	return node;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis )
Packit 47f805
{
Packit 47f805
	if ( afterThis->parent != this )
Packit 47f805
		return 0;
Packit 47f805
	
Packit 47f805
	TiXmlNode* node = addThis.Clone();
Packit 47f805
	if ( !node )
Packit 47f805
		return 0;
Packit 47f805
	node->parent = this;
Packit 47f805
	
Packit 47f805
	node->prev = afterThis;
Packit 47f805
	node->next = afterThis->next;
Packit 47f805
	afterThis->next->prev = node;
Packit 47f805
	afterThis->next = node;
Packit 47f805
	return node;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis )
Packit 47f805
{
Packit 47f805
	if ( replaceThis->parent != this )
Packit 47f805
		return 0;
Packit 47f805
	
Packit 47f805
	TiXmlNode* node = withThis.Clone();
Packit 47f805
	if ( !node )
Packit 47f805
		return 0;
Packit 47f805
Packit 47f805
	node->next = replaceThis->next;
Packit 47f805
	node->prev = replaceThis->prev;
Packit 47f805
Packit 47f805
	if ( replaceThis->next )
Packit 47f805
		replaceThis->next->prev = node;
Packit 47f805
	else
Packit 47f805
		lastChild = node;
Packit 47f805
Packit 47f805
	if ( replaceThis->prev )
Packit 47f805
		replaceThis->prev->next = node;
Packit 47f805
	else
Packit 47f805
		firstChild = node;
Packit 47f805
Packit 47f805
	delete replaceThis;
Packit 47f805
	node->parent = this;
Packit 47f805
	return node;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
bool TiXmlNode::RemoveChild( TiXmlNode* removeThis )
Packit 47f805
{
Packit 47f805
	if ( removeThis->parent != this )
Packit 47f805
	{	
Packit 47f805
		assert( 0 );
Packit 47f805
		return false;
Packit 47f805
	}
Packit 47f805
	
Packit 47f805
	if ( removeThis->next )
Packit 47f805
		removeThis->next->prev = removeThis->prev;
Packit 47f805
	else
Packit 47f805
		lastChild = removeThis->prev;
Packit 47f805
Packit 47f805
	if ( removeThis->prev )
Packit 47f805
		removeThis->prev->next = removeThis->next;
Packit 47f805
	else
Packit 47f805
		firstChild = removeThis->next;
Packit 47f805
Packit 47f805
	delete removeThis;
Packit 47f805
	return true;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlNode* TiXmlNode::FirstChild( const std::string& value ) const
Packit 47f805
{
Packit 47f805
	TiXmlNode* node;
Packit 47f805
	for ( node = firstChild; node; node = node->next )
Packit 47f805
	{
Packit 47f805
		if ( node->Value() == value )
Packit 47f805
			return node;
Packit 47f805
	}
Packit 47f805
	return 0;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlNode* TiXmlNode::LastChild( const std::string& value ) const
Packit 47f805
{
Packit 47f805
	TiXmlNode* node;
Packit 47f805
	for ( node = lastChild; node; node = node->prev )
Packit 47f805
	{
Packit 47f805
		if ( node->Value() == value )
Packit 47f805
			return node;
Packit 47f805
	}
Packit 47f805
	return 0;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlNode* TiXmlNode::IterateChildren( TiXmlNode* previous ) const
Packit 47f805
{
Packit 47f805
	if ( !previous )
Packit 47f805
	{
Packit 47f805
		return FirstChild();
Packit 47f805
	}
Packit 47f805
	else
Packit 47f805
	{
Packit 47f805
		assert( previous->parent == this );
Packit 47f805
		return previous->NextSibling();
Packit 47f805
	}
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlNode* TiXmlNode::IterateChildren( const std::string& val, TiXmlNode* previous ) const
Packit 47f805
{
Packit 47f805
	if ( !previous )
Packit 47f805
	{
Packit 47f805
		return FirstChild( val );
Packit 47f805
	}
Packit 47f805
	else
Packit 47f805
	{
Packit 47f805
		assert( previous->parent == this );
Packit 47f805
		return previous->NextSibling( val );
Packit 47f805
	}
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlNode* TiXmlNode::NextSibling( const std::string& value ) const
Packit 47f805
{
Packit 47f805
	TiXmlNode* node;
Packit 47f805
	for ( node = next; node; node = node->next )
Packit 47f805
	{
Packit 47f805
		if ( node->Value() == value )
Packit 47f805
			return node;
Packit 47f805
	}
Packit 47f805
	return 0;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlNode* TiXmlNode::PreviousSibling( const std::string& value ) const
Packit 47f805
{
Packit 47f805
	TiXmlNode* node;
Packit 47f805
	for ( node = prev; node; node = node->prev )
Packit 47f805
	{
Packit 47f805
		if ( node->Value() == value )
Packit 47f805
			return node;
Packit 47f805
	}
Packit 47f805
	return 0;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
void TiXmlElement::RemoveAttribute( const std::string& name )
Packit 47f805
{
Packit 47f805
	TiXmlAttribute* node = attributeSet.Find( name );
Packit 47f805
	if ( node )
Packit 47f805
	{
Packit 47f805
		attributeSet.Remove( node );
Packit 47f805
		delete node;
Packit 47f805
	}
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlElement* TiXmlNode::FirstChildElement() const
Packit 47f805
{
Packit 47f805
	TiXmlNode* node;
Packit 47f805
Packit 47f805
	for (	node = FirstChild();
Packit 47f805
			node;
Packit 47f805
			node = node->NextSibling() )
Packit 47f805
	{
Packit 47f805
		if ( node->ToElement() )
Packit 47f805
			return node->ToElement();
Packit 47f805
	}
Packit 47f805
	return 0;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlElement* TiXmlNode::FirstChildElement( const std::string& value ) const
Packit 47f805
{
Packit 47f805
	TiXmlNode* node;
Packit 47f805
Packit 47f805
	for (	node = FirstChild( value );
Packit 47f805
			node;
Packit 47f805
			node = node->NextSibling( value ) )
Packit 47f805
	{
Packit 47f805
		if ( node->ToElement() )
Packit 47f805
			return node->ToElement();
Packit 47f805
	}
Packit 47f805
	return 0;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlElement* TiXmlNode::NextSiblingElement() const
Packit 47f805
{
Packit 47f805
	TiXmlNode* node;
Packit 47f805
Packit 47f805
	for (	node = NextSibling();
Packit 47f805
			node;
Packit 47f805
			node = node->NextSibling() )
Packit 47f805
	{
Packit 47f805
		if ( node->ToElement() )
Packit 47f805
			return node->ToElement();
Packit 47f805
	}
Packit 47f805
	return 0;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlElement* TiXmlNode::NextSiblingElement( const std::string& value ) const
Packit 47f805
{
Packit 47f805
	TiXmlNode* node;
Packit 47f805
Packit 47f805
	for (	node = NextSibling( value );
Packit 47f805
			node;
Packit 47f805
			node = node->NextSibling( value ) )
Packit 47f805
	{
Packit 47f805
		if ( node->ToElement() )
Packit 47f805
			return node->ToElement();
Packit 47f805
	}
Packit 47f805
	return 0;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlDocument* TiXmlNode::GetDocument() const
Packit 47f805
{
Packit 47f805
	const TiXmlNode* node;
Packit 47f805
Packit 47f805
	for( node = this; node; node = node->parent )
Packit 47f805
	{
Packit 47f805
		if ( node->ToDocument() )
Packit 47f805
			return node->ToDocument();
Packit 47f805
	}
Packit 47f805
	return 0;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
// TiXmlElement::TiXmlElement() 
Packit 47f805
// 	: TiXmlNode( TiXmlNode::ELEMENT )
Packit 47f805
// {
Packit 47f805
// }
Packit 47f805
Packit 47f805
TiXmlElement::TiXmlElement( const std::string& _value ) 
Packit 47f805
	: TiXmlNode( TiXmlNode::ELEMENT )
Packit 47f805
{
Packit 47f805
	firstChild = lastChild = 0;
Packit 47f805
	value = _value;
Packit 47f805
}
Packit 47f805
Packit 47f805
TiXmlElement::~TiXmlElement()
Packit 47f805
{
Packit 47f805
	while( attributeSet.First() )
Packit 47f805
	{
Packit 47f805
		TiXmlAttribute* node = attributeSet.First();
Packit 47f805
		attributeSet.Remove( node );
Packit 47f805
		delete node;
Packit 47f805
	}
Packit 47f805
}
Packit 47f805
Packit 47f805
const std::string* TiXmlElement::Attribute( const std::string& name ) const
Packit 47f805
{
Packit 47f805
	TiXmlAttribute* node = attributeSet.Find( name );
Packit 47f805
Packit 47f805
	if ( node )
Packit 47f805
		return &(node->Value() );
Packit 47f805
Packit 47f805
	return 0;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const
Packit 47f805
{
Packit 47f805
	const std::string* s = Attribute( name );
Packit 47f805
	if ( s )
Packit 47f805
		*i = atoi( s->c_str() );
Packit 47f805
	else
Packit 47f805
		*i = 0;
Packit 47f805
	return s;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
void TiXmlElement::SetAttribute( const std::string& name, int val )
Packit 47f805
{	
Packit 47f805
	char buf[64];
Packit 47f805
	sprintf( buf, "%d", val );
Packit 47f805
Packit 47f805
	std::string v = buf;
Packit 47f805
Packit 47f805
	SetAttribute( name, v );
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
void TiXmlElement::SetAttribute( const std::string& name, const std::string& value )
Packit 47f805
{
Packit 47f805
	TiXmlAttribute* node = attributeSet.Find( name );
Packit 47f805
	if ( node )
Packit 47f805
	{
Packit 47f805
		node->SetValue( value );
Packit 47f805
		return;
Packit 47f805
	}
Packit 47f805
Packit 47f805
	TiXmlAttribute* attrib = new TiXmlAttribute( name, value );
Packit 47f805
	if ( attrib )
Packit 47f805
	{
Packit 47f805
		attributeSet.Add( attrib );
Packit 47f805
	}
Packit 47f805
	else
Packit 47f805
	{
Packit 47f805
		TiXmlDocument* document = GetDocument();
Packit 47f805
		if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY );
Packit 47f805
	}
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
void TiXmlElement::Print( FILE* cfile, int depth ) const
Packit 47f805
{
Packit 47f805
	int i;
Packit 47f805
	for ( i=0; i
Packit 47f805
	{
Packit 47f805
		fprintf( cfile, "    " );
Packit 47f805
	}
Packit 47f805
Packit 47f805
	fprintf( cfile, "<%s", value.c_str() );
Packit 47f805
Packit 47f805
	TiXmlAttribute* attrib;
Packit 47f805
	for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
Packit 47f805
	{
Packit 47f805
		fprintf( cfile, " " );
Packit 47f805
		attrib->Print( cfile, depth );
Packit 47f805
	}
Packit 47f805
Packit 47f805
	// There are 3 different formatting approaches:
Packit 47f805
	// 1) An element without children is printed as a <foo /> node
Packit 47f805
	// 2) An element with only a text child is printed as <foo> text </foo>
Packit 47f805
	// 3) An element with children is printed on multiple lines.
Packit 47f805
	TiXmlNode* node;
Packit 47f805
	if ( !firstChild )
Packit 47f805
	{
Packit 47f805
		fprintf( cfile, " />" );
Packit 47f805
  	}
Packit 47f805
	else if ( firstChild == lastChild && firstChild->ToText() )
Packit 47f805
	{
Packit 47f805
		fprintf( cfile, ">" );
Packit 47f805
		firstChild->Print( cfile, depth + 1 );
Packit 47f805
		fprintf( cfile, "</%s>", value.c_str() );
Packit 47f805
  	}
Packit 47f805
	else
Packit 47f805
	{
Packit 47f805
		fprintf( cfile, ">" );
Packit 47f805
Packit 47f805
		for ( node = firstChild; node; node=node->NextSibling() )
Packit 47f805
		{
Packit 47f805
	 		if ( !node->ToText() )
Packit 47f805
			{
Packit 47f805
				fprintf( cfile, "\n" );
Packit 47f805
			}
Packit 47f805
			node->Print( cfile, depth+1 );
Packit 47f805
		}
Packit 47f805
		fprintf( cfile, "\n" );
Packit 47f805
		for( i=0; i
Packit 47f805
			fprintf( cfile, "    " );
Packit 47f805
		fprintf( cfile, "</%s>", value.c_str() );
Packit 47f805
	}
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
void TiXmlElement::StreamOut( std::ostream* stream ) const
Packit 47f805
{
Packit 47f805
	(*stream) << "<" << value;
Packit 47f805
Packit 47f805
	TiXmlAttribute* attrib;
Packit 47f805
	for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
Packit 47f805
	{	
Packit 47f805
		(*stream) << " ";
Packit 47f805
		attrib->StreamOut( stream );
Packit 47f805
	}
Packit 47f805
Packit 47f805
	// If this node has children, give it a closing tag. Else
Packit 47f805
	// make it an empty tag.
Packit 47f805
	TiXmlNode* node;
Packit 47f805
	if ( firstChild )
Packit 47f805
	{ 		
Packit 47f805
		(*stream) << ">";
Packit 47f805
Packit 47f805
		for ( node = firstChild; node; node=node->NextSibling() )
Packit 47f805
		{
Packit 47f805
			node->StreamOut( stream );
Packit 47f805
		}
Packit 47f805
		(*stream) << "</" << value << ">";
Packit 47f805
	}
Packit 47f805
	else
Packit 47f805
	{
Packit 47f805
		(*stream) << " />";
Packit 47f805
	}
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlNode* TiXmlElement::Clone() const
Packit 47f805
{
Packit 47f805
	TiXmlElement* clone = new TiXmlElement( Value() );
Packit 47f805
Packit 47f805
	if ( !clone )
Packit 47f805
		return 0;
Packit 47f805
	
Packit 47f805
	CopyToClone( clone );
Packit 47f805
Packit 47f805
	// Clone the attributes, then clone the children.
Packit 47f805
	TiXmlAttribute* attribute = 0;
Packit 47f805
	for(	attribute = attributeSet.First(); 
Packit 47f805
			attribute; 
Packit 47f805
			attribute = attribute->Next() )
Packit 47f805
	{
Packit 47f805
		clone->SetAttribute( attribute->Name(), attribute->Value() );
Packit 47f805
	}
Packit 47f805
	
Packit 47f805
	TiXmlNode* node = 0;
Packit 47f805
	for ( node = firstChild; node; node = node->NextSibling() )
Packit 47f805
	{
Packit 47f805
		clone->LinkEndChild( node->Clone() );
Packit 47f805
	}
Packit 47f805
	return clone;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::DOCUMENT )
Packit 47f805
{
Packit 47f805
	error = false;
Packit 47f805
//	ignoreWhiteSpace = true;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::DOCUMENT )
Packit 47f805
{
Packit 47f805
//	ignoreWhiteSpace = true;
Packit 47f805
	value = documentName;
Packit 47f805
	error = false;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
bool TiXmlDocument::LoadFile()
Packit 47f805
{
Packit 47f805
	return LoadFile( value );
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
bool TiXmlDocument::SaveFile() const
Packit 47f805
{
Packit 47f805
 	return SaveFile( value );
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
bool TiXmlDocument::LoadFile( const std::string& filename )
Packit 47f805
{	
Packit 47f805
	// Delete the existing data:
Packit 47f805
	Clear();
Packit 47f805
	value = filename;
Packit 47f805
	
Packit 47f805
	FILE* file = fopen( filename.c_str(), "r" );
Packit 47f805
Packit 47f805
	if ( file )
Packit 47f805
	{
Packit 47f805
		// Get the file size, so we can pre-allocate the string. HUGE speed impact.
Packit 47f805
		long length = 0;
Packit 47f805
		fseek( file, 0, SEEK_END );
Packit 47f805
		length = ftell( file );
Packit 47f805
		fseek( file, 0, SEEK_SET );
Packit 47f805
Packit 47f805
		// If we have a file, assume it is all one big XML file, and read it in.
Packit 47f805
		// The document parser may decide the document ends sooner than the entire file, however.
Packit 47f805
		std::string data;
Packit 47f805
		data.reserve( length );
Packit 47f805
Packit 47f805
		const int BUF_SIZE = 2048;
Packit 47f805
		char buf[BUF_SIZE];
Packit 47f805
Packit 47f805
		while( fgets( buf, BUF_SIZE, file ) )
Packit 47f805
		{
Packit 47f805
			data += buf;
Packit 47f805
		}
Packit 47f805
		fclose( file );
Packit 47f805
Packit 47f805
		Parse( data.c_str() );
Packit 47f805
		if (  !Error() )
Packit 47f805
		{
Packit 47f805
			return true;
Packit 47f805
		}
Packit 47f805
	}
Packit 47f805
	SetError( TIXML_ERROR_OPENING_FILE );
Packit 47f805
	return false;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
bool TiXmlDocument::SaveFile( const std::string& filename ) const
Packit 47f805
{
Packit 47f805
	// The old c stuff lives on...
Packit 47f805
	FILE* fp = fopen( filename.c_str(), "w" );
Packit 47f805
	if ( fp )
Packit 47f805
	{
Packit 47f805
		Print( fp, 0 );
Packit 47f805
		fclose( fp );
Packit 47f805
		return true;
Packit 47f805
	}
Packit 47f805
	return false;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlNode* TiXmlDocument::Clone() const
Packit 47f805
{
Packit 47f805
	TiXmlDocument* clone = new TiXmlDocument();
Packit 47f805
	if ( !clone )
Packit 47f805
		return 0;
Packit 47f805
Packit 47f805
	CopyToClone( clone );
Packit 47f805
	clone->error = error;
Packit 47f805
	clone->errorDesc = errorDesc;
Packit 47f805
Packit 47f805
	TiXmlNode* node = 0;
Packit 47f805
	for ( node = firstChild; node; node = node->NextSibling() )
Packit 47f805
	{
Packit 47f805
		clone->LinkEndChild( node->Clone() );
Packit 47f805
	}
Packit 47f805
	return clone;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
void TiXmlDocument::Print( FILE* cfile, int depth ) const
Packit 47f805
{
Packit 47f805
	TiXmlNode* node;
Packit 47f805
	for ( node=FirstChild(); node; node=node->NextSibling() )
Packit 47f805
	{
Packit 47f805
		node->Print( cfile, depth );
Packit 47f805
		fprintf( cfile, "\n" );
Packit 47f805
	}
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
void TiXmlDocument::StreamOut( std::ostream* out ) const
Packit 47f805
{
Packit 47f805
	TiXmlNode* node;
Packit 47f805
	for ( node=FirstChild(); node; node=node->NextSibling() )
Packit 47f805
	{
Packit 47f805
		node->StreamOut( out );
Packit 47f805
Packit 47f805
		// Special rule for streams: stop after the root element.
Packit 47f805
		// The stream in code will only read one element, so don't 
Packit 47f805
		// write more than one.
Packit 47f805
		if ( node->ToElement() )
Packit 47f805
			break;
Packit 47f805
	}
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlAttribute* TiXmlAttribute::Next() const
Packit 47f805
{
Packit 47f805
	// We are using knowledge of the sentinel. The sentinel
Packit 47f805
	// have a value or name.
Packit 47f805
	if ( next->value.empty() && next->name.empty() )
Packit 47f805
		return 0;
Packit 47f805
	return next;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlAttribute* TiXmlAttribute::Previous() const
Packit 47f805
{
Packit 47f805
	// We are using knowledge of the sentinel. The sentinel
Packit 47f805
	// have a value or name.
Packit 47f805
	if ( prev->value.empty() && prev->name.empty() )
Packit 47f805
		return 0;
Packit 47f805
	return prev;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
void TiXmlAttribute::Print( FILE* cfile, int /*depth*/ ) const
Packit 47f805
{
Packit 47f805
	ostringstream stream( ostringstream::out );
Packit 47f805
	stream.str().reserve( 500 );
Packit 47f805
	
Packit 47f805
	StreamOut( &stream );
Packit 47f805
	fprintf( cfile, "%s", stream.str().c_str() );
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
void TiXmlAttribute::StreamOut( std::ostream* stream ) const
Packit 47f805
{
Packit 47f805
	if ( value.find( '\"' ) != std::string::npos )
Packit 47f805
	{
Packit 47f805
		PutString( name, stream );
Packit 47f805
		(*stream) << "=" << "'";
Packit 47f805
		PutString( value, stream );
Packit 47f805
		(*stream) << "'";
Packit 47f805
	}
Packit 47f805
	else
Packit 47f805
	{
Packit 47f805
		PutString( name, stream );
Packit 47f805
		(*stream) << "=" << "\"";
Packit 47f805
		PutString( value, stream );
Packit 47f805
		(*stream) << "\"";
Packit 47f805
	}
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
void TiXmlAttribute::SetIntValue( int value )
Packit 47f805
{
Packit 47f805
	std::string s;
Packit 47f805
	std::ostringstream stream( s );
Packit 47f805
	stream << value;
Packit 47f805
	SetValue( stream.str() );
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
void TiXmlAttribute::SetDoubleValue( double value )
Packit 47f805
{
Packit 47f805
	std::string s;
Packit 47f805
	std::ostringstream stream( s );
Packit 47f805
	stream << value;
Packit 47f805
	SetValue( stream.str() );
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
const int TiXmlAttribute::IntValue() const
Packit 47f805
{
Packit 47f805
	int v;
Packit 47f805
	std::istringstream string( value );
Packit 47f805
	string >> v;
Packit 47f805
	return v;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
const double  TiXmlAttribute::DoubleValue() const
Packit 47f805
{
Packit 47f805
	double v;
Packit 47f805
	std::istringstream string( value );
Packit 47f805
	string >> v;
Packit 47f805
	return v;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
void TiXmlComment::Print( FILE* cfile, int depth ) const
Packit 47f805
{
Packit 47f805
	ostringstream stream( ostringstream::out );
Packit 47f805
	stream.str().reserve( 1000 );
Packit 47f805
	
Packit 47f805
	for ( int i=0; i
Packit 47f805
	{
Packit 47f805
		fprintf( cfile, "    " );
Packit 47f805
	}
Packit 47f805
	StreamOut( &stream );
Packit 47f805
	fprintf( cfile, "%s", stream.str().c_str() );
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
void TiXmlComment::StreamOut( std::ostream* stream ) const
Packit 47f805
{
Packit 47f805
	(*stream) << "
Packit 47f805
	PutString( value, stream );
Packit 47f805
	(*stream) << "-->";
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlNode* TiXmlComment::Clone() const
Packit 47f805
{
Packit 47f805
	TiXmlComment* clone = new TiXmlComment();
Packit 47f805
Packit 47f805
	if ( !clone )
Packit 47f805
		return 0;
Packit 47f805
Packit 47f805
	CopyToClone( clone );
Packit 47f805
	return clone;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
void TiXmlText::Print( FILE* cfile, int depth ) const
Packit 47f805
{
Packit 47f805
	ostringstream stream( ostringstream::out );
Packit 47f805
	stream.str().reserve( 1000 );
Packit 47f805
	StreamOut( &stream );
Packit 47f805
	fprintf( cfile, "%s", stream.str().c_str() );
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
void TiXmlText::StreamOut( std::ostream* stream ) const
Packit 47f805
{
Packit 47f805
	PutString( value, stream );
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlNode* TiXmlText::Clone() const
Packit 47f805
{	
Packit 47f805
	TiXmlText* clone = 0;
Packit 47f805
	clone = new TiXmlText( "" );
Packit 47f805
	
Packit 47f805
	if ( !clone )
Packit 47f805
		return 0;
Packit 47f805
Packit 47f805
	CopyToClone( clone );
Packit 47f805
	return clone;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlDeclaration::TiXmlDeclaration( const std::string& _version, 
Packit 47f805
									const std::string& _encoding,
Packit 47f805
									const std::string& _standalone )
Packit 47f805
	: TiXmlNode( TiXmlNode::DECLARATION ) 
Packit 47f805
{
Packit 47f805
	version = _version;
Packit 47f805
	encoding = _encoding;
Packit 47f805
	standalone = _standalone;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
void TiXmlDeclaration::Print( FILE* cfile, int depth ) const
Packit 47f805
{
Packit 47f805
	ostringstream stream( ostringstream::out );
Packit 47f805
	stream.str().reserve( 200 );
Packit 47f805
	StreamOut( &stream );
Packit 47f805
	fprintf( cfile, "%s", stream.str().c_str() );
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
void TiXmlDeclaration::StreamOut( std::ostream* stream ) const
Packit 47f805
{
Packit 47f805
	(*stream) << "
Packit 47f805
Packit 47f805
	if ( !version.empty() )
Packit 47f805
	{
Packit 47f805
		(*stream) << "version=\"";
Packit 47f805
		PutString( version, stream );
Packit 47f805
		(*stream) << "\" ";
Packit 47f805
	}
Packit 47f805
	if ( !encoding.empty() )
Packit 47f805
	{
Packit 47f805
		(*stream) << "encoding=\"";
Packit 47f805
		PutString( encoding, stream );
Packit 47f805
		(*stream ) << "\" ";
Packit 47f805
	}
Packit 47f805
	if ( !standalone.empty() )
Packit 47f805
	{
Packit 47f805
		(*stream) << "standalone=\"";
Packit 47f805
		PutString( standalone, stream );
Packit 47f805
		(*stream) << "\" ";
Packit 47f805
	}
Packit 47f805
	(*stream) << "?>";
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlNode* TiXmlDeclaration::Clone() const
Packit 47f805
{	
Packit 47f805
	TiXmlDeclaration* clone = new TiXmlDeclaration();
Packit 47f805
Packit 47f805
	if ( !clone )
Packit 47f805
		return 0;
Packit 47f805
Packit 47f805
	CopyToClone( clone );
Packit 47f805
	clone->version = version;
Packit 47f805
	clone->encoding = encoding;
Packit 47f805
	clone->standalone = standalone;
Packit 47f805
	return clone;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
void TiXmlUnknown::Print( FILE* cfile, int depth ) const
Packit 47f805
{
Packit 47f805
	ostringstream stream( ostringstream::out );
Packit 47f805
	stream.str().reserve( 200 );
Packit 47f805
	StreamOut( &stream );
Packit 47f805
Packit 47f805
	for ( int i=0; i
Packit 47f805
		fprintf( cfile, "    " );
Packit 47f805
	fprintf( cfile, "%s", stream.str().c_str() );
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
void TiXmlUnknown::StreamOut( std::ostream* stream ) const
Packit 47f805
{
Packit 47f805
	(*stream) << "<" << value << ">";		// Don't use entities hear! It is unknown.
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlNode* TiXmlUnknown::Clone() const
Packit 47f805
{
Packit 47f805
	TiXmlUnknown* clone = new TiXmlUnknown();
Packit 47f805
Packit 47f805
	if ( !clone )
Packit 47f805
		return 0;
Packit 47f805
Packit 47f805
	CopyToClone( clone );
Packit 47f805
	return clone;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlAttributeSet::TiXmlAttributeSet()
Packit 47f805
{
Packit 47f805
	sentinel.next = &sentinel;
Packit 47f805
	sentinel.prev = &sentinel;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlAttributeSet::~TiXmlAttributeSet()
Packit 47f805
{
Packit 47f805
	assert( sentinel.next == &sentinel );
Packit 47f805
	assert( sentinel.prev == &sentinel );
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
void TiXmlAttributeSet::Add( TiXmlAttribute* addMe )
Packit 47f805
{
Packit 47f805
	assert( !Find( addMe->Name() ) );	// Shouldn't be multiply adding to the set.
Packit 47f805
	
Packit 47f805
	addMe->next = &sentinel;
Packit 47f805
	addMe->prev = sentinel.prev;
Packit 47f805
Packit 47f805
	sentinel.prev->next = addMe;
Packit 47f805
	sentinel.prev      = addMe;
Packit 47f805
}
Packit 47f805
Packit 47f805
void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe )
Packit 47f805
{
Packit 47f805
	TiXmlAttribute* node;
Packit 47f805
Packit 47f805
	for( node = sentinel.next; node != &sentinel; node = node->next )
Packit 47f805
	{
Packit 47f805
		if ( node == removeMe )
Packit 47f805
		{
Packit 47f805
			node->prev->next = node->next;
Packit 47f805
			node->next->prev = node->prev;
Packit 47f805
			node->next = 0;
Packit 47f805
			node->prev = 0;
Packit 47f805
			return;
Packit 47f805
		}
Packit 47f805
	}
Packit 47f805
	assert( 0 );		// we tried to remove a non-linked attribute.
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
TiXmlAttribute*	TiXmlAttributeSet::Find( const std::string& name ) const
Packit 47f805
{
Packit 47f805
	TiXmlAttribute* node;
Packit 47f805
Packit 47f805
	for( node = sentinel.next; node != &sentinel; node = node->next )
Packit 47f805
	{
Packit 47f805
		if ( node->Name() == name )
Packit 47f805
			return node;
Packit 47f805
	}
Packit 47f805
	return 0;
Packit 47f805
}
Packit 47f805