Better attribute system. Removes redundant list searching of LinkAttribute. Faster parsing on initial read. Added badly needed missing test cases.
This commit is contained in:
48
tinyxml2.cpp
48
tinyxml2.cpp
@@ -1092,34 +1092,33 @@ const char* XMLElement::GetText() const
|
||||
}
|
||||
|
||||
|
||||
|
||||
XMLAttribute* XMLElement::FindOrCreateAttribute( const char* name )
|
||||
{
|
||||
XMLAttribute* attrib = FindAttribute( name );
|
||||
XMLAttribute* last = 0;
|
||||
XMLAttribute* attrib = 0;
|
||||
for( attrib = rootAttribute;
|
||||
attrib;
|
||||
last = attrib, attrib = attrib->next )
|
||||
{
|
||||
if ( XMLUtil::StringEqual( attrib->Name(), name ) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !attrib ) {
|
||||
attrib = new (document->attributePool.Alloc() ) XMLAttribute();
|
||||
attrib->memPool = &document->attributePool;
|
||||
LinkAttribute( attrib );
|
||||
if ( last ) {
|
||||
last->next = attrib;
|
||||
}
|
||||
else {
|
||||
rootAttribute = 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void XMLElement::DeleteAttribute( const char* name )
|
||||
{
|
||||
XMLAttribute* prev = 0;
|
||||
@@ -1142,6 +1141,7 @@ void XMLElement::DeleteAttribute( const char* name )
|
||||
char* XMLElement::ParseAttributes( char* p )
|
||||
{
|
||||
const char* start = p;
|
||||
XMLAttribute* prevAttribute = 0;
|
||||
|
||||
// Read the attributes.
|
||||
while( p ) {
|
||||
@@ -1162,7 +1162,19 @@ char* XMLElement::ParseAttributes( char* p )
|
||||
document->SetError( XML_ERROR_PARSING_ATTRIBUTE, start, p );
|
||||
return 0;
|
||||
}
|
||||
LinkAttribute( attrib );
|
||||
// There is a minor bug here: if the attribute in the source xml
|
||||
// document is duplicated, it will not be detected and the
|
||||
// attribute will be doubly added. However, tracking the 'prevAttribute'
|
||||
// avoids re-scanning the attribute list. Preferring performance for
|
||||
// now, may reconsider in the future.
|
||||
if ( prevAttribute ) {
|
||||
prevAttribute->next = attrib;
|
||||
prevAttribute = attrib;
|
||||
}
|
||||
else {
|
||||
rootAttribute = attrib;
|
||||
prevAttribute = rootAttribute;
|
||||
}
|
||||
}
|
||||
// end of the tag
|
||||
else if ( *p == '/' && *(p+1) == '>' ) {
|
||||
|
||||
Reference in New Issue
Block a user