external/tinyxml 2_4_3

Change-Id: Ie9d890a04285fc5b0dc3b1d7dad44c3d097808a8
diff --git a/tinyxml.cpp b/tinyxml.cpp
index 8706683..6a83291 100644
--- a/tinyxml.cpp
+++ b/tinyxml.cpp
@@ -27,6 +27,7 @@
 
 #ifdef TIXML_USE_STL
 #include <sstream>
+#include <iostream>
 #endif
 
 
@@ -192,6 +193,9 @@
 
 TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node )
 {
+	assert( node->parent == 0 || node->parent == this );
+	assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() );
+
 	node->parent = this;
 
 	node->prev = lastChild;
@@ -463,7 +467,8 @@
 
 void TiXmlElement::RemoveAttribute( const char * name )
 {
-	TiXmlAttribute* node = attributeSet.Find( name );
+	TIXML_STRING str( name );
+	TiXmlAttribute* node = attributeSet.Find( str );
 	if ( node )
 	{
 		attributeSet.Remove( node );
@@ -661,7 +666,8 @@
 
 const char * TiXmlElement::Attribute( const char * name ) const
 {
-	const TiXmlAttribute* node = attributeSet.Find( name );
+	TIXML_STRING str( name );
+	const TiXmlAttribute* node = attributeSet.Find( str );
 
 	if ( node )
 		return node->Value();
@@ -700,7 +706,8 @@
 
 int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const
 {
-	const TiXmlAttribute* node = attributeSet.Find( name );
+	TIXML_STRING str( name );
+	const TiXmlAttribute* node = attributeSet.Find( str );
 	if ( !node )
 		return TIXML_NO_ATTRIBUTE;
 
@@ -710,7 +717,8 @@
 
 int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const
 {
-	const TiXmlAttribute* node = attributeSet.Find( name );
+	TIXML_STRING str( name );
+	const TiXmlAttribute* node = attributeSet.Find( str );
 	if ( !node )
 		return TIXML_NO_ATTRIBUTE;
 
@@ -730,6 +738,16 @@
 }
 
 
+#ifdef TIXML_USE_STL
+void TiXmlElement::SetAttribute( const std::string& name, int val )
+{	
+   std::ostringstream oss;
+   oss << val;
+   SetAttribute( name, oss.str() );
+}
+#endif
+
+
 void TiXmlElement::SetDoubleAttribute( const char * name, double val )
 {	
 	char buf[256];
@@ -742,7 +760,33 @@
 }
 
 
-void TiXmlElement::SetAttribute( const char * name, const char * _value )
+void TiXmlElement::SetAttribute( const char * cname, const char * cvalue )
+{
+	TIXML_STRING _name( cname );
+	TIXML_STRING _value( cvalue );
+
+	TiXmlAttribute* node = attributeSet.Find( _name );
+	if ( node )
+	{
+		node->SetValue( cvalue );
+		return;
+	}
+
+	TiXmlAttribute* attrib = new TiXmlAttribute( cname, cvalue );
+	if ( attrib )
+	{
+		attributeSet.Add( attrib );
+	}
+	else
+	{
+		TiXmlDocument* document = GetDocument();
+		if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
+	}
+}
+
+
+#ifdef TIXML_USE_STL
+void TiXmlElement::SetAttribute( const std::string& name, const std::string& _value )
 {
 	TiXmlAttribute* node = attributeSet.Find( name );
 	if ( node )
@@ -762,6 +806,8 @@
 		if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
 	}
 }
+#endif
+
 
 void TiXmlElement::Print( FILE* cfile, int depth ) const
 {
@@ -957,10 +1003,6 @@
 
 bool TiXmlDocument::LoadFile( const char* filename, TiXmlEncoding encoding )
 {
-	// Delete the existing data:
-	Clear();
-	location.Clear();
-
 	// There was a really terrifying little bug here. The code:
 	//		value = filename
 	// in the STL case, cause the assignment method of the std::string to
@@ -976,137 +1018,162 @@
 
 	if ( file )
 	{
-		// Get the file size, so we can pre-allocate the string. HUGE speed impact.
-		long length = 0;
-		fseek( file, 0, SEEK_END );
-		length = ftell( file );
-		fseek( file, 0, SEEK_SET );
-
-		// Strange case, but good to handle up front.
-		if ( length == 0 )
-		{
-			fclose( file );
-			return false;
-		}
-
-		// If we have a file, assume it is all one big XML file, and read it in.
-		// The document parser may decide the document ends sooner than the entire file, however.
-		TIXML_STRING data;
-		data.reserve( length );
-
-		// Subtle bug here. TinyXml did use fgets. But from the XML spec:
-		// 2.11 End-of-Line Handling
-		// <snip>
-		// <quote>
-		// ...the XML processor MUST behave as if it normalized all line breaks in external 
-		// parsed entities (including the document entity) on input, before parsing, by translating 
-		// both the two-character sequence #xD #xA and any #xD that is not followed by #xA to 
-		// a single #xA character.
-		// </quote>
-		//
-		// It is not clear fgets does that, and certainly isn't clear it works cross platform. 
-		// Generally, you expect fgets to translate from the convention of the OS to the c/unix
-		// convention, and not work generally.
-
-		/*
-		while( fgets( buf, sizeof(buf), file ) )
-		{
-			data += buf;
-		}
-		*/
-
-		char* buf = new char[ length+1 ];
-		buf[0] = 0;
-
-		if ( fread( buf, length, 1, file ) != 1 ) {
-		//if ( fread( buf, 1, length, file ) != (size_t)length ) {
-			SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
-			fclose( file );
-			return false;
-		}
+		bool result = LoadFile( file, encoding );
 		fclose( file );
+		return result;
+	}
+	else
+	{
+		SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return false;
+	}
+}
 
-		const char* lastPos = buf;
-		const char* p = buf;
+bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding )
+{
+	if ( !file ) 
+	{
+		SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return false;
+	}
 
-		buf[length] = 0;
-		while( *p ) {
-			assert( p < (buf+length) );
-			if ( *p == 0xa ) {
-				// Newline character. No special rules for this. Append all the characters
-				// since the last string, and include the newline.
-				data.append( lastPos, p-lastPos+1 );	// append, include the newline
-				++p;									// move past the newline
-				lastPos = p;							// and point to the new buffer (may be 0)
+	// Delete the existing data:
+	Clear();
+	location.Clear();
+
+	// Get the file size, so we can pre-allocate the string. HUGE speed impact.
+	long length = 0;
+	fseek( file, 0, SEEK_END );
+	length = ftell( file );
+	fseek( file, 0, SEEK_SET );
+
+	// Strange case, but good to handle up front.
+	if ( length == 0 )
+	{
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return false;
+	}
+
+	// If we have a file, assume it is all one big XML file, and read it in.
+	// The document parser may decide the document ends sooner than the entire file, however.
+	TIXML_STRING data;
+	data.reserve( length );
+
+	// Subtle bug here. TinyXml did use fgets. But from the XML spec:
+	// 2.11 End-of-Line Handling
+	// <snip>
+	// <quote>
+	// ...the XML processor MUST behave as if it normalized all line breaks in external 
+	// parsed entities (including the document entity) on input, before parsing, by translating 
+	// both the two-character sequence #xD #xA and any #xD that is not followed by #xA to 
+	// a single #xA character.
+	// </quote>
+	//
+	// It is not clear fgets does that, and certainly isn't clear it works cross platform. 
+	// Generally, you expect fgets to translate from the convention of the OS to the c/unix
+	// convention, and not work generally.
+
+	/*
+	while( fgets( buf, sizeof(buf), file ) )
+	{
+		data += buf;
+	}
+	*/
+
+	char* buf = new char[ length+1 ];
+	buf[0] = 0;
+
+	if ( fread( buf, length, 1, file ) != 1 ) {
+		SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return false;
+	}
+
+	const char* lastPos = buf;
+	const char* p = buf;
+
+	buf[length] = 0;
+	while( *p ) {
+		assert( p < (buf+length) );
+		if ( *p == 0xa ) {
+			// Newline character. No special rules for this. Append all the characters
+			// since the last string, and include the newline.
+			data.append( lastPos, (p-lastPos+1) );	// append, include the newline
+			++p;									// move past the newline
+			lastPos = p;							// and point to the new buffer (may be 0)
+			assert( p <= (buf+length) );
+		}
+		else if ( *p == 0xd ) {
+			// Carriage return. Append what we have so far, then
+			// handle moving forward in the buffer.
+			if ( (p-lastPos) > 0 ) {
+				data.append( lastPos, p-lastPos );	// do not add the CR
+			}
+			data += (char)0xa;						// a proper newline
+
+			if ( *(p+1) == 0xa ) {
+				// Carriage return - new line sequence
+				p += 2;
+				lastPos = p;
 				assert( p <= (buf+length) );
 			}
-			else if ( *p == 0xd ) {
-				// Carriage return. Append what we have so far, then
-				// handle moving forward in the buffer.
-				if ( (p-lastPos) > 0 ) {
-					data.append( lastPos, p-lastPos );	// do not add the CR
-				}
-				data += (char)0xa;						// a proper newline
-
-				if ( *(p+1) == 0xa ) {
-					// Carriage return - new line sequence
-					p += 2;
-					lastPos = p;
-					assert( p <= (buf+length) );
-				}
-				else {
-					// it was followed by something else...that is presumably characters again.
-					++p;
-					lastPos = p;
-					assert( p <= (buf+length) );
-				}
-			}
 			else {
+				// it was followed by something else...that is presumably characters again.
 				++p;
+				lastPos = p;
+				assert( p <= (buf+length) );
 			}
 		}
-		// Handle any left over characters.
-		if ( p-lastPos ) {
-			data.append( lastPos, p-lastPos );
-		}		
-		delete [] buf;
-		buf = 0;
-
-		Parse( data.c_str(), 0, encoding );
-
-		if (  Error() )
-            return false;
-        else
-			return true;
+		else {
+			++p;
+		}
 	}
-	SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
-	return false;
+	// Handle any left over characters.
+	if ( p-lastPos ) {
+		data.append( lastPos, p-lastPos );
+	}		
+	delete [] buf;
+	buf = 0;
+
+	Parse( data.c_str(), 0, encoding );
+
+	if (  Error() )
+        return false;
+    else
+		return true;
 }
 
+
 bool TiXmlDocument::SaveFile( const char * filename ) const
 {
 	// The old c stuff lives on...
 	FILE* fp = fopen( filename, "w" );
 	if ( fp )
 	{
-		if ( useMicrosoftBOM ) 
-		{
-			const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
-			const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
-			const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
-
-			fputc( TIXML_UTF_LEAD_0, fp );
-			fputc( TIXML_UTF_LEAD_1, fp );
-			fputc( TIXML_UTF_LEAD_2, fp );
-		}
-		Print( fp, 0 );
+		bool result = SaveFile( fp );
 		fclose( fp );
-		return true;
+		return result;
 	}
 	return false;
 }
 
 
+bool TiXmlDocument::SaveFile( FILE* fp ) const
+{
+	if ( useMicrosoftBOM ) 
+	{
+		const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
+		const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
+		const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
+
+		fputc( TIXML_UTF_LEAD_0, fp );
+		fputc( TIXML_UTF_LEAD_1, fp );
+		fputc( TIXML_UTF_LEAD_2, fp );
+	}
+	Print( fp, 0 );
+	return true;
+}
+
+
 void TiXmlDocument::CopyTo( TiXmlDocument* target ) const
 {
 	TiXmlNode::CopyTo( target );
@@ -1525,7 +1592,7 @@
 
 void TiXmlAttributeSet::Add( TiXmlAttribute* addMe )
 {
-	assert( !Find( addMe->Name() ) );	// Shouldn't be multiply adding to the set.
+	assert( !Find( TIXML_STRING( addMe->Name() ) ) );	// Shouldn't be multiply adding to the set.
 
 	addMe->next = &sentinel;
 	addMe->prev = sentinel.prev;
@@ -1552,7 +1619,7 @@
 	assert( 0 );		// we tried to remove a non-linked attribute.
 }
 
-const TiXmlAttribute* TiXmlAttributeSet::Find( const char * name ) const
+const TiXmlAttribute* TiXmlAttributeSet::Find( const TIXML_STRING& name ) const
 {
 	const TiXmlAttribute* node;
 
@@ -1564,7 +1631,7 @@
 	return 0;
 }
 
-TiXmlAttribute*	TiXmlAttributeSet::Find( const char * name )
+TiXmlAttribute*	TiXmlAttributeSet::Find( const TIXML_STRING& name )
 {
 	TiXmlAttribute* node;