| 1648 | |
| 1649 | |
| 1650 | char* XMLElement::ParseAttributes( char* p ) |
| 1651 | { |
| 1652 | const char* start = p; |
| 1653 | XMLAttribute* prevAttribute = 0; |
| 1654 | |
| 1655 | // Read the attributes. |
| 1656 | while( p ) { |
| 1657 | p = XMLUtil::SkipWhiteSpace( p ); |
| 1658 | if ( !(*p) ) { |
| 1659 | _document->SetError( XML_ERROR_PARSING_ELEMENT, start, Name() ); |
| 1660 | return 0; |
| 1661 | } |
| 1662 | |
| 1663 | // attribute. |
| 1664 | if (XMLUtil::IsNameStartChar( *p ) ) { |
| 1665 | TIXMLASSERT( sizeof( XMLAttribute ) == _document->_attributePool.ItemSize() ); |
| 1666 | XMLAttribute* attrib = new (_document->_attributePool.Alloc() ) XMLAttribute(); |
| 1667 | attrib->_memPool = &_document->_attributePool; |
| 1668 | attrib->_memPool->SetTracked(); |
| 1669 | |
| 1670 | p = attrib->ParseDeep( p, _document->ProcessEntities() ); |
| 1671 | if ( !p || Attribute( attrib->Name() ) ) { |
| 1672 | DeleteAttribute( attrib ); |
| 1673 | _document->SetError( XML_ERROR_PARSING_ATTRIBUTE, start, p ); |
| 1674 | return 0; |
| 1675 | } |
| 1676 | // There is a minor bug here: if the attribute in the source xml |
| 1677 | // document is duplicated, it will not be detected and the |
| 1678 | // attribute will be doubly added. However, tracking the 'prevAttribute' |
| 1679 | // avoids re-scanning the attribute list. Preferring performance for |
| 1680 | // now, may reconsider in the future. |
| 1681 | if ( prevAttribute ) { |
| 1682 | prevAttribute->_next = attrib; |
| 1683 | } |
| 1684 | else { |
| 1685 | _rootAttribute = attrib; |
| 1686 | } |
| 1687 | prevAttribute = attrib; |
| 1688 | } |
| 1689 | // end of the tag |
| 1690 | else if ( *p == '>' ) { |
| 1691 | ++p; |
| 1692 | break; |
| 1693 | } |
| 1694 | // end of the tag |
| 1695 | else if ( *p == '/' && *(p+1) == '>' ) { |
| 1696 | _closingType = CLOSED; |
| 1697 | return p+2; // done; sealed element. |
| 1698 | } |
| 1699 | else { |
| 1700 | _document->SetError( XML_ERROR_PARSING_ELEMENT, start, p ); |
| 1701 | return 0; |
| 1702 | } |
| 1703 | } |
| 1704 | return p; |
| 1705 | } |
| 1706 | |
| 1707 | void XMLElement::DeleteAttribute( XMLAttribute* attribute ) |