print to memory support
diff --git a/tinyxml2.cpp b/tinyxml2.cpp
index 2287341..3a9b2c9 100644
--- a/tinyxml2.cpp
+++ b/tinyxml2.cpp
@@ -5,6 +5,7 @@
 #include <stdio.h>

 #include <ctype.h>

 #include <new.h>

+#include <stdarg.h>

 

 //#pragma warning ( disable : 4291 )

 

@@ -332,6 +333,13 @@
 }

 

 

+void XMLNode::DeleteChild( XMLNode* node )

+{

+	TIXMLASSERT( node->parent == this );

+	DELETE_NODE( node );

+}

+

+

 XMLNode* XMLNode::InsertEndChild( XMLNode* addThis )

 {

 	if ( lastChild ) {

@@ -428,13 +436,6 @@
 }

 

 

-void XMLNode::DeleteChild( XMLNode* node )

-{

-	TIXMLASSERT( node->parent == this );

-	TIXMLASSERT( 0 );

-}

-

-

 char* XMLNode::ParseDeep( char* p )

 {

 	while( p && *p ) {

@@ -733,6 +734,25 @@
 }

 

 

+void XMLElement::DeleteAttribute( const char* name )

+{

+	XMLAttribute* prev = 0;

+	for( XMLAttribute* a=rootAttribute; a; a=a->next ) {

+		if ( XMLUtil::StringEqual( name, a->Name() ) ) {

+			if ( prev ) {

+				prev->next = a->next;

+			}

+			else {

+				rootAttribute = a->next;

+			}

+			DELETE_ATTRIBUTE( a );

+			break;

+		}

+		prev = a;

+	}

+}

+

+

 char* XMLElement::ParseAttributes( char* p, bool* closedElement )

 {

 	const char* start = p;

@@ -947,13 +967,45 @@
 			entityFlag[ entities[i].value ] = true;

 		}

 	}

+	buffer.Push( 0 );

+}

+

+

+void XMLStreamer::Print( const char* format, ... )

+{

+    va_list     va;

+    va_start( va, format );

+

+	if ( fp ) {

+		vfprintf( fp, format, va );

+	}

+	else {

+		// This seems brutally complex. Haven't figured out a better

+		// way on windows.

+		#ifdef _MSC_VER

+			int len = -1;

+			while ( len < 0 ) {

+				len = vsnprintf_s( accumulator.Mem(), accumulator.Capacity(), accumulator.Capacity()-1, format, va );

+				if ( len < 0 ) {

+					accumulator.PushArr( 1000 );

+				}

+			}

+			char* p = buffer.PushArr( len ) - 1;

+			memcpy( p, accumulator.Mem(), len+1 );

+		#else

+			int len = vsnprintf( 0, 0, format, va );

+			char* p = buffer.PushArr( len ) - 1;

+			vsprintf_s( p, len+1, format, va );

+		#endif

+	}

+    va_end( va );

 }

 

 

 void XMLStreamer::PrintSpace( int depth )

 {

 	for( int i=0; i<depth; ++i ) {

-		fprintf( fp, "    " );

+		Print( "    " );

 	}

 }

 

@@ -970,12 +1022,12 @@
 			// entity, and keep looking.

 			if ( entityFlag[*q] ) {

 				while ( p < q ) {

-					fputc( *p, fp );

+					Print( "%c", *p );

 					++p;

 				}

 				for( int i=0; i<NUM_ENTITIES; ++i ) {

 					if ( entities[i].value == *q ) {

-						fprintf( fp, "&%s;", entities[i].pattern );

+						Print( "&%s;", entities[i].pattern );

 						break;

 					}

 				}

@@ -987,10 +1039,11 @@
 	// Flush the remaining string. This will be the entire

 	// string if an entity wasn't found.

 	if ( q-p > 0 ) {

-		fprintf( fp, "%s", p );

+		Print( "%s", p );

 	}

 }

 

+

 void XMLStreamer::OpenElement( const char* name )

 {

 	if ( elementJustOpened ) {

@@ -999,11 +1052,11 @@
 	stack.Push( name );

 

 	if ( textDepth < 0 && depth > 0) {

-		fprintf( fp, "\n" );

+		Print( "\n" );

 		PrintSpace( depth );

 	}

 

-	fprintf( fp, "<%s", name );

+	Print( "<%s", name );

 	elementJustOpened = true;

 	++depth;

 }

@@ -1012,9 +1065,9 @@
 void XMLStreamer::PushAttribute( const char* name, const char* value )

 {

 	TIXMLASSERT( elementJustOpened );

-	fprintf( fp, " %s=\"", name );

+	Print( " %s=\"", name );

 	PrintString( value );

-	fprintf( fp, "\"" );

+	Print( "\"" );

 }

 

 

@@ -1024,20 +1077,20 @@
 	const char* name = stack.Pop();

 

 	if ( elementJustOpened ) {

-		fprintf( fp, "/>" );

+		Print( "/>" );

 	}

 	else {

 		if ( textDepth < 0 ) {

-			fprintf( fp, "\n" );

+			Print( "\n" );

 			PrintSpace( depth );

 		}

-		fprintf( fp, "</%s>", name );

+		Print( "</%s>", name );

 	}

 

 	if ( textDepth == depth )

 		textDepth = -1;

 	if ( depth == 0 )

-		fprintf( fp, "\n" );

+		Print( "\n" );

 	elementJustOpened = false;

 }

 

@@ -1045,7 +1098,7 @@
 void XMLStreamer::SealElement()

 {

 	elementJustOpened = false;

-	fprintf( fp, ">" );

+	Print( ">" );

 }

 

 

@@ -1057,10 +1110,10 @@
 		SealElement();

 	}

 	if ( cdata )

-		fprintf( fp, "<![CDATA[" );

+		Print( "<![CDATA[" );

 	PrintString( text );

 	if ( cdata ) 

-		fprintf( fp, "]]>" );

+		Print( "]]>" );

 }

 

 

@@ -1070,10 +1123,10 @@
 		SealElement();

 	}

 	if ( textDepth < 0 && depth > 0) {

-		fprintf( fp, "\n" );

+		Print( "\n" );

 		PrintSpace( depth );

 	}

-	fprintf( fp, "<!--%s-->", comment );

+	Print( "<!--%s-->", comment );

 }