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 );
}