added attribute handling. StrPair can now new/delete memory.
diff --git a/tinyxml2.cpp b/tinyxml2.cpp
index 2241fd2..22cf5cb 100644
--- a/tinyxml2.cpp
+++ b/tinyxml2.cpp
@@ -37,6 +37,85 @@
};
+StrPair::~StrPair()
+{
+ Reset();
+}
+
+
+void StrPair::Reset()
+{
+ if ( flags & NEEDS_DELETE ) {
+ delete [] start;
+ }
+ flags = 0;
+ start = 0;
+ end = 0;
+}
+
+
+void StrPair::SetStr( const char* str, int flags )
+{
+ Reset();
+ size_t len = strlen( str );
+ start = new char[ len+1 ];
+ strncpy( start, str, len );
+ end = start + len;
+ this->flags = flags | NEEDS_DELETE;
+}
+
+
+char* StrPair::ParseText( char* p, const char* endTag, int strFlags )
+{
+ TIXMLASSERT( endTag && *endTag );
+
+ char* start = p; // fixme: hides a member
+ char endChar = *endTag;
+ int length = strlen( endTag );
+
+ // Inner loop of text parsing.
+ while ( *p ) {
+ if ( *p == endChar && strncmp( p, endTag, length ) == 0 ) {
+ Set( start, p, strFlags );
+ return p + length;
+ }
+ ++p;
+ }
+ return p;
+}
+
+
+char* StrPair::ParseName( char* p )
+{
+ char* start = p;
+
+ start = p;
+ if ( !start || !(*start) ) {
+ return 0;
+ }
+
+ if ( !XMLUtil::IsAlpha( *p ) ) {
+ return 0;
+ }
+
+ while( *p && (
+ XMLUtil::IsAlphaNum( (unsigned char) *p )
+ || *p == '_'
+ || *p == '-'
+ || *p == '.'
+ || *p == ':' ))
+ {
+ ++p;
+ }
+
+ if ( p > start ) {
+ Set( start, p, 0 );
+ return p;
+ }
+ return 0;
+}
+
+
const char* StrPair::GetStr()
{
if ( flags & NEEDS_FLUSH ) {
@@ -96,91 +175,15 @@
}
*q = 0;
}
- flags = 0;
+ flags = (flags & NEEDS_DELETE);
}
return start;
}
-/*
-const char* StringPool::Intern( const char* str )
-{
- // Treat the array as a linear, inplace hash table.
- // Nothing can get deleted, so that's handy.
- if ( size > pool.Size()*3/4 ) {
- DynArray< const char*, 20 > store;
- for( int i=0; i<pool.Size(); ++i ) {
- if ( pool[i] != 0 ) {
- store.Push( pool[i] );
- }
- }
- int newSize = pool.Size() * 2;
- pool.PopArr( pool.Size() );
-
- const char** mem = pool.PushArr( newSize );
- memset( (void*)mem, 0, sizeof(char)*newSize );
-
- while ( !store.Empty() ) {
- Intern( store.Pop() );
- }
- }
-
-}
-*/
// --------- XMLUtil ----------- //
-char* StrPair::ParseText( char* p, const char* endTag, int strFlags )
-{
- TIXMLASSERT( endTag && *endTag );
-
- char* start = p;
- char endChar = *endTag;
- int length = strlen( endTag );
-
- // Inner loop of text parsing.
- while ( *p ) {
- if ( *p == endChar && strncmp( p, endTag, length ) == 0 ) {
- Set( start, p, strFlags );
- return p + length;
- }
- ++p;
- }
- return p;
-}
-
-
-char* StrPair::ParseName( char* p )
-{
- char* start = p;
-
- start = p;
- if ( !start || !(*start) ) {
- return 0;
- }
-
- if ( !XMLUtil::IsAlpha( *p ) ) {
- return 0;
- }
-
- while( *p && (
- XMLUtil::IsAlphaNum( (unsigned char) *p )
- || *p == '_'
- || *p == '-'
- || *p == '.'
- || *p == ':' ))
- {
- ++p;
- }
-
- if ( p > start ) {
- Set( start, p, 0 );
- return p;
- }
- return 0;
-}
-
-
char* XMLDocument::Identify( char* p, XMLNode** node )
{
XMLNode* returnNode = 0;
@@ -290,6 +293,15 @@
}
+void XMLNode::SetValue( const char* str, bool staticMem )
+{
+ if ( staticMem )
+ value.SetInternedStr( str );
+ else
+ value.SetStr( str );
+}
+
+
void XMLNode::ClearChildren()
{
while( firstChild ) {
@@ -557,16 +569,16 @@
int XMLAttribute::QueryIntAttribute( int* value ) const
{
- if ( TIXML_SSCANF( Value(), "%d", value ) == 1 )
- return ATTRIBUTE_SUCCESS;
+ if ( TIXML_SSCANF( Value(), "%d", value ) == 1 )
+ return ATTRIBUTE_SUCCESS;
return WRONG_ATTRIBUTE_TYPE;
}
int XMLAttribute::QueryUnsignedAttribute( unsigned int* value ) const
{
- if ( TIXML_SSCANF( Value(), "%u", value ) == 1 )
- return ATTRIBUTE_SUCCESS;
+ if ( TIXML_SSCANF( Value(), "%u", value ) == 1 )
+ return ATTRIBUTE_SUCCESS;
return WRONG_ATTRIBUTE_TYPE;
}
@@ -582,43 +594,71 @@
}
else if ( ival == 0 || XMLUtil::StringEqual( Value(), "false" ) ) {
*value = false;
- return ATTRIBUTE_SUCCESS;
- }
+ return ATTRIBUTE_SUCCESS;
+ }
return WRONG_ATTRIBUTE_TYPE;
}
int XMLAttribute::QueryDoubleAttribute( double* value ) const
{
- if ( TIXML_SSCANF( Value(), "%lf", value ) == 1 )
- return ATTRIBUTE_SUCCESS;
+ if ( TIXML_SSCANF( Value(), "%lf", value ) == 1 )
+ return ATTRIBUTE_SUCCESS;
return WRONG_ATTRIBUTE_TYPE;
}
int XMLAttribute::QueryFloatAttribute( float* value ) const
{
- if ( TIXML_SSCANF( Value(), "%f", value ) == 1 )
- return ATTRIBUTE_SUCCESS;
+ if ( TIXML_SSCANF( Value(), "%f", value ) == 1 )
+ return ATTRIBUTE_SUCCESS;
return WRONG_ATTRIBUTE_TYPE;
}
void XMLAttribute::SetAttribute( const char* v )
{
- value.SetInternedStr( v );
+ value.SetStr( v );
}
-/*
void XMLAttribute::SetAttribute( int v )
{
char buf[BUF_SIZE];
- TIXML_SNPRINTF( buf, BUF_SIZE-1, "%d" );
-
- value.SetInternedStr( v );
+ TIXML_SNPRINTF( buf, BUF_SIZE-1, "%d", v );
+ value.SetStr( buf );
}
-*/
+
+
+void XMLAttribute::SetAttribute( unsigned v )
+{
+ char buf[BUF_SIZE];
+ TIXML_SNPRINTF( buf, BUF_SIZE-1, "%u", v );
+ value.SetStr( buf );
+}
+
+
+void XMLAttribute::SetAttribute( bool v )
+{
+ char buf[BUF_SIZE];
+ TIXML_SNPRINTF( buf, BUF_SIZE-1, "%d", v ? 1 : 0 );
+ value.SetStr( buf );
+}
+
+void XMLAttribute::SetAttribute( double v )
+{
+ char buf[BUF_SIZE];
+ TIXML_SNPRINTF( buf, BUF_SIZE-1, "%f", v );
+ value.SetStr( buf );
+}
+
+void XMLAttribute::SetAttribute( float v )
+{
+ char buf[BUF_SIZE];
+ TIXML_SNPRINTF( buf, BUF_SIZE-1, "%f", v );
+ value.SetStr( buf );
+}
+
// --------- XMLElement ---------- //
XMLElement::XMLElement( XMLDocument* doc ) : XMLNode( doc ),
@@ -640,6 +680,39 @@
}
+XMLAttribute* XMLElement::FindAttribute( const char* name )
+{
+ XMLAttribute* a = 0;
+ for( a=rootAttribute; a; a = a->next ) {
+ if ( XMLUtil::StringEqual( a->Name(), name ) )
+ return a;
+ }
+ return 0;
+}
+
+
+const XMLAttribute* XMLElement::FindAttribute( const char* name ) const
+{
+ XMLAttribute* a = 0;
+ for( a=rootAttribute; a; a = a->next ) {
+ if ( XMLUtil::StringEqual( a->Name(), name ) )
+ return a;
+ }
+ return 0;
+}
+
+
+XMLAttribute* XMLElement::FindOrCreateAttribute( const char* name )
+{
+ XMLAttribute* attrib = FindAttribute( name );
+ if ( !attrib ) {
+ attrib = new (document->attributePool.Alloc() ) XMLAttribute( this );
+ attrib->memPool = &document->attributePool;
+ }
+ return attrib;
+}
+
+
char* XMLElement::ParseAttributes( char* p, bool* closedElement )
{
const char* start = p;