diff --git a/tinyxml2.cpp b/tinyxml2.cpp index 22cf5cb..2287341 100644 --- a/tinyxml2.cpp +++ b/tinyxml2.cpp @@ -59,7 +59,7 @@ void StrPair::SetStr( const char* str, int flags ) Reset(); size_t len = strlen( str ); start = new char[ len+1 ]; - strncpy( start, str, len ); + memcpy( start, str, len+1 ); end = start + len; this->flags = flags | NEEDS_DELETE; } @@ -341,17 +341,16 @@ XMLNode* XMLNode::InsertEndChild( XMLNode* addThis ) addThis->prev = lastChild; lastChild = addThis; - addThis->parent = this; addThis->next = 0; } else { TIXMLASSERT( firstChild == 0 ); firstChild = lastChild = addThis; - addThis->parent = this; addThis->prev = 0; addThis->next = 0; } + addThis->parent = this; return addThis; } @@ -366,17 +365,16 @@ XMLNode* XMLNode::InsertFirstChild( XMLNode* addThis ) addThis->next = firstChild; firstChild = addThis; - addThis->parent = this; addThis->prev = 0; } else { TIXMLASSERT( lastChild == 0 ); firstChild = lastChild = addThis; - addThis->parent = this; addThis->prev = 0; addThis->next = 0; } + addThis->parent = this; return addThis; } @@ -395,6 +393,7 @@ XMLNode* XMLNode::InsertAfterChild( XMLNode* afterThis, XMLNode* addThis ) addThis->next = afterThis->next; afterThis->next->prev = addThis; afterThis->next = addThis; + addThis->parent = this; return addThis; } @@ -567,6 +566,12 @@ char* XMLAttribute::ParseDeep( char* p ) } +void XMLAttribute::SetName( const char* n ) +{ + name.SetStr( n ); +} + + int XMLAttribute::QueryIntAttribute( int* value ) const { if ( TIXML_SSCANF( Value(), "%d", value ) == 1 ) @@ -663,19 +668,18 @@ void XMLAttribute::SetAttribute( float v ) // --------- XMLElement ---------- // XMLElement::XMLElement( XMLDocument* doc ) : XMLNode( doc ), closing( false ), - rootAttribute( 0 ), - lastAttribute( 0 ) + rootAttribute( 0 ) + //lastAttribute( 0 ) { } XMLElement::~XMLElement() { - XMLAttribute* attribute = rootAttribute; - while( attribute ) { - XMLAttribute* next = attribute->next; - DELETE_ATTRIBUTE( attribute ); - attribute = next; + while( rootAttribute ) { + XMLAttribute* next = rootAttribute->next; + DELETE_ATTRIBUTE( rootAttribute ); + rootAttribute = next; } } @@ -706,13 +710,29 @@ XMLAttribute* XMLElement::FindOrCreateAttribute( const char* name ) { XMLAttribute* attrib = FindAttribute( name ); if ( !attrib ) { - attrib = new (document->attributePool.Alloc() ) XMLAttribute( this ); + attrib = new (document->attributePool.Alloc() ) XMLAttribute( this ); attrib->memPool = &document->attributePool; + LinkAttribute( attrib ); + attrib->SetName( name ); } return attrib; } +void XMLElement::LinkAttribute( XMLAttribute* attrib ) +{ + if ( rootAttribute ) { + XMLAttribute* end = rootAttribute; + while ( end->next ) + end = end->next; + end->next = attrib; + } + else { + rootAttribute = attrib; + } +} + + char* XMLElement::ParseAttributes( char* p, bool* closedElement ) { const char* start = p; @@ -737,14 +757,7 @@ char* XMLElement::ParseAttributes( char* p, bool* closedElement ) document->SetError( XMLDocument::ERROR_PARSING_ATTRIBUTE, start, p ); return 0; } - if ( rootAttribute ) { - TIXMLASSERT( lastAttribute ); - lastAttribute->next = attrib; - lastAttribute = attrib; - } - else { - rootAttribute = lastAttribute = attrib; - } + LinkAttribute( attrib ); } // end of the tag else if ( *p == '/' && *(p+1) == '>' ) { @@ -876,10 +889,10 @@ XMLComment* XMLDocument::NewComment( const char* str ) XMLText* XMLDocument::NewText( const char* str ) { - XMLText* Text = new (textPool.Alloc()) XMLText( this ); - Text->memPool = &textPool; - Text->SetValue( str ); - return Text; + XMLText* text = new (textPool.Alloc()) XMLText( this ); + text->memPool = &textPool; + text->SetValue( str ); + return text; } @@ -923,44 +936,6 @@ void XMLDocument::SetError( int error, const char* str1, const char* str2 ) } -/* -StringStack::StringStack() -{ - nPositive = 0; - mem.Push( 0 ); // start with null. makes later code simpler. -} - - -StringStack::~StringStack() -{ -} - - -void StringStack::Push( const char* str ) { - int needed = strlen( str ) + 1; - char* p = mem.PushArr( needed ); - strcpy( p, str ); - if ( needed > 1 ) - nPositive++; -} - - -const char* StringStack::Pop() { - TIXMLASSERT( mem.Size() > 1 ); - const char* p = mem.Mem() + mem.Size() - 2; // end of final string. - if ( *p ) { - nPositive--; - } - while( *p ) { // stack starts with a null, don't need to check for 'mem' - TIXMLASSERT( p > mem.Mem() ); - --p; - } - mem.PopArr( strlen(p)+1 ); - return p+1; -} -*/ - - XMLStreamer::XMLStreamer( FILE* file ) : fp( file ), depth( 0 ), elementJustOpened( false ), textDepth( -1 ) { for( int i=0; i\n", comment ); + if ( textDepth < 0 && depth > 0) { + fprintf( fp, "\n" ); + PrintSpace( depth ); + } + fprintf( fp, "", comment ); } diff --git a/tinyxml2.h b/tinyxml2.h index 67e6d2d..0d5a591 100644 --- a/tinyxml2.h +++ b/tinyxml2.h @@ -564,10 +564,12 @@ public: private: enum { BUF_SIZE = 200 }; + XMLAttribute( XMLElement* element ) : next( 0 ) {} virtual ~XMLAttribute() {} XMLAttribute( const XMLAttribute& ); // not supported void operator=( const XMLAttribute& ); // not supported + void SetName( const char* name ); char* ParseDeep( char* p ); @@ -592,6 +594,12 @@ public: const char* Attribute( const char* name ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return 0; return a->Value(); } + int IntAttribute( const char* name ) const { int i=0; QueryIntAttribute( name, &i ); return i; } + unsigned UnsignedAttribute( const char* name ) const{ unsigned i=0; QueryUnsignedAttribute( name, &i ); return i; } + bool BoolAttribute( const char* name ) const { bool b=false; QueryBoolAttribute( name, &b ); return b; } + double DoubleAttribute( const char* name ) const { double d=0; QueryDoubleAttribute( name, &d ); return d; } + float FloatAttribute( const char* name ) const { float f=0; QueryFloatAttribute( name, &f ); return f; } + int QueryIntAttribute( const char* name, int* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryIntAttribute( value ); } int QueryUnsignedAttribute( const char* name, unsigned int* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryUnsignedAttribute( value ); } int QueryBoolAttribute( const char* name, bool* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryBoolAttribute( value ); } @@ -623,11 +631,11 @@ private: XMLAttribute* FindAttribute( const char* name ); XMLAttribute* FindOrCreateAttribute( const char* name ); + void LinkAttribute( XMLAttribute* attrib ); char* ParseAttributes( char* p, bool *closedElement ); bool closing; XMLAttribute* rootAttribute; - XMLAttribute* lastAttribute; // fixme: remove }; diff --git a/xmltest.cpp b/xmltest.cpp index cfb2183..a7194e0 100644 --- a/xmltest.cpp +++ b/xmltest.cpp @@ -14,7 +14,7 @@ using namespace tinyxml2; int gPass = 0; int gFail = 0; -bool XmlTest (const char* testString, const char* expected, const char* found, bool noEcho ) +bool XMLTest (const char* testString, const char* expected, const char* found, bool echo=true ) { bool pass = !strcmp( expected, found ); if ( pass ) @@ -22,7 +22,7 @@ bool XmlTest (const char* testString, const char* expected, const char* found, b else printf ("[fail]"); - if ( noEcho ) + if ( !echo ) printf (" %s\n", testString); else printf (" %s [%s][%s]\n", testString, expected, found); @@ -35,7 +35,7 @@ bool XmlTest (const char* testString, const char* expected, const char* found, b } -bool XmlTest( const char* testString, int expected, int found, bool noEcho ) +bool XMLTest( const char* testString, int expected, int found, bool echo=true ) { bool pass = ( expected == found ); if ( pass ) @@ -43,7 +43,7 @@ bool XmlTest( const char* testString, int expected, int found, bool noEcho ) else printf ("[fail]"); - if ( noEcho ) + if ( !echo ) printf (" %s\n", testString); else printf (" %s [%d][%d]\n", testString, expected, found); @@ -126,7 +126,7 @@ int main( int argc, const char* argv ) // // // - // With Text! + // & Text! // XMLDocument* doc = new XMLDocument(); @@ -140,8 +140,13 @@ int main( int argc, const char* argv ) XMLNode* comment = element->InsertFirstChild( doc->NewComment( "comment" ) ); element->InsertAfterChild( comment, sub[0] ); element->InsertAfterChild( sub[0], sub[1] ); - sub[2]->InsertFirstChild( doc->NewText( "With Text!" )); + sub[2]->InsertFirstChild( doc->NewText( "& Text!" )); doc->Print(); + XMLTest( "Programmatic DOM", "comment", doc->FirstChildElement( "element" )->FirstChild()->Value() ); + XMLTest( "Programmatic DOM", "0", doc->FirstChildElement( "element" )->FirstChildElement()->Attribute( "attrib" ) ); + XMLTest( "Programmatic DOM", 2, doc->FirstChildElement()->LastChildElement( "sub" )->IntAttribute( "attrib" ) ); + XMLTest( "Programmatic DOM", "& Text!", + doc->FirstChildElement()->LastChildElement( "sub" )->FirstChild()->ToText()->Value() ); delete doc; }