CXMLAttribute* Engine::FileSystem::Config::CXMLElement::FindOrCreateAttribute( const char* name ) { CXMLAttribute* last = 0; CXMLAttribute* attrib = 0; for( attrib = rootAttribute; attrib; last = attrib, attrib = attrib->next ) { if ( CXMLUtil::StringEqual( attrib->Name(), name ) ) { break; } } if ( !attrib ) { attrib = new (document->attributePool.Alloc() ) CXMLAttribute(); attrib->XMLMemPool = &document->attributePool; if ( last ) { last->next = attrib; } else { rootAttribute = attrib; } attrib->SetName( name ); } return attrib; }
const CXMLAttribute* Engine::FileSystem::Config::CXMLElement::FindAttribute( const char* name ) const { CXMLAttribute* a = 0; for( a=rootAttribute; a; a = a->next ) { if ( CXMLUtil::StringEqual( a->Name(), name ) ) return a; } return 0; }
char* Engine::FileSystem::Config::CXMLElement::ParseAttributes( char* p ) { const char* start = p; CXMLAttribute* prevAttribute = 0; // Read the attributes. while( p ) { p = CXMLUtil::SkipWhiteSpace( p ); if ( !p || !(*p) ) { document->SetError( XML_ERROR_PARSING_ELEMENT, start, Name() ); return 0; } // attribute. if ( CXMLUtil::IsAlpha( *p ) ) { CXMLAttribute* attrib = new (document->attributePool.Alloc() ) CXMLAttribute(); attrib->XMLMemPool = &document->attributePool; p = attrib->ParseDeep( p, document->ProcessEntities() ); if ( !p || Attribute( attrib->Name() ) ) { DELETE_ATTRIBUTE( attrib ); document->SetError( XML_ERROR_PARSING_ATTRIBUTE, start, p ); return 0; } // 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; } else { rootAttribute = attrib; } prevAttribute = attrib; } // end of the tag else if ( *p == '/' && *(p+1) == '>' ) { closingType = CLOSED; return p+2; // done; sealed element. } // end of the tag else if ( *p == '>' ) { ++p; break; } else { document->SetError( XML_ERROR_PARSING_ELEMENT, start, p ); return 0; } } return p; }