Index: src/OFXMLAttribute.m ================================================================== --- src/OFXMLAttribute.m +++ src/OFXMLAttribute.m @@ -180,10 +180,10 @@ return [element autorelease]; } - (OFString*)description { - return [OFString stringWithFormat: @"", _name, _namespace, _stringValue]; } @end Index: src/OFXMLParser.h ================================================================== --- src/OFXMLParser.h +++ src/OFXMLParser.h @@ -132,15 +132,16 @@ OF_XMLPARSER_TAG_OPENED, OF_XMLPARSER_IN_PROCESSING_INSTRUCTIONS, OF_XMLPARSER_IN_TAG_NAME, OF_XMLPARSER_IN_CLOSE_TAG_NAME, OF_XMLPARSER_IN_TAG, - OF_XMLPARSER_IN_ATTR_NAME, - OF_XMLPARSER_EXPECT_DELIMITER, - OF_XMLPARSER_IN_ATTR_VALUE, - OF_XMLPARSER_EXPECT_CLOSE, - OF_XMLPARSER_EXPECT_SPACE_OR_CLOSE, + OF_XMLPARSER_IN_ATTRIBUTE_NAME, + OF_XMLPARSER_EXPECT_ATTRIBUTE_EQUAL_SIGN, + OF_XMLPARSER_EXPECT_ATTRIBUTE_DELIMITER, + OF_XMLPARSER_IN_ATTRIBUTE_VALUE, + OF_XMLPARSER_EXPECT_TAG_CLOSE, + OF_XMLPARSER_EXPECT_SPACE_OR_TAG_CLOSE, OF_XMLPARSER_IN_EXCLAMATIONMARK, OF_XMLPARSER_IN_CDATA_OPENING, OF_XMLPARSER_IN_CDATA, OF_XMLPARSER_IN_COMMENT_OPENING, OF_XMLPARSER_IN_COMMENT_1, Index: src/OFXMLParser.m ================================================================== --- src/OFXMLParser.m +++ src/OFXMLParser.m @@ -146,14 +146,15 @@ @selector(OF_inProcessingInstructionsState), @selector(OF_inTagNameState), @selector(OF_inCloseTagNameState), @selector(OF_inTagState), @selector(OF_inAttributeNameState), - @selector(OF_expectDelimiterState), + @selector(OF_expectAttributeEqualSignState), + @selector(OF_expectAttributeDelimiterState), @selector(OF_inAttributeValueState), - @selector(OF_expectCloseState), - @selector(OF_expectSpaceOrCloseState), + @selector(OF_expectTagCloseState), + @selector(OF_expectSpaceOrTagCloseState), @selector(OF_inExclamationMarkState), @selector(OF_inCDATAOpeningState), @selector(OF_inCDATAState), @selector(OF_inCommentOpeningState), @selector(OF_inCommentState1), @@ -604,11 +605,11 @@ [_name release]; [_prefix release]; _name = _prefix = nil; _state = (_data[_i] == '/' - ? OF_XMLPARSER_EXPECT_CLOSE + ? OF_XMLPARSER_EXPECT_TAG_CLOSE : OF_XMLPARSER_OUTSIDE_TAG); } else _state = OF_XMLPARSER_IN_TAG; if (_data[_i] != '/') @@ -682,11 +683,11 @@ _name = _prefix = nil; _last = _i + 1; _state = (_data[_i] == '>' ? OF_XMLPARSER_OUTSIDE_TAG - : OF_XMLPARSER_EXPECT_SPACE_OR_CLOSE); + : OF_XMLPARSER_EXPECT_SPACE_OR_TAG_CLOSE); if ([_previous count] == 0) _finishedParsing = true; } @@ -700,11 +701,11 @@ if (_data[_i] != '>' && _data[_i] != '/') { if (_data[_i] != ' ' && _data[_i] != '\t' && _data[_i] != '\n' && _data[_i] != '\r') { _last = _i; - _state = OF_XMLPARSER_IN_ATTR_NAME; + _state = OF_XMLPARSER_IN_ATTRIBUTE_NAME; _i--; } return; } @@ -758,35 +759,33 @@ [_attributes removeAllObjects]; _name = _prefix = nil; _last = _i + 1; _state = (_data[_i] == '/' - ? OF_XMLPARSER_EXPECT_CLOSE + ? OF_XMLPARSER_EXPECT_TAG_CLOSE : OF_XMLPARSER_OUTSIDE_TAG); } /* Looking for attribute name */ - (void)OF_inAttributeNameState { void *pool; - OFMutableString *bufferString; + OFString *bufferString; const char *bufferCString, *tmp; size_t length, bufferLength; - if (_data[_i] != '=') + if (_data[_i] != '=' && _data[_i] != ' ' && _data[_i] != '\t' && + _data[_i] != '\n' && _data[_i] != '\r') return; if ((length = _i - _last) > 0) buffer_append(_buffer, _data + _last, _encoding, length); pool = objc_autoreleasePoolPush(); - bufferString = [OFMutableString stringWithUTF8String: [_buffer items] - length: [_buffer count]]; - [bufferString deleteEnclosingWhitespaces]; - /* Prevent a useless copy later */ - [bufferString makeImmutable]; + bufferString = [OFString stringWithUTF8String: [_buffer items] + length: [_buffer count]]; bufferCString = [bufferString UTF8String]; bufferLength = [bufferString UTF8StringLength]; if ((tmp = memchr(bufferCString, ':', bufferLength)) != NULL) { @@ -805,15 +804,31 @@ objc_autoreleasePoolPop(pool); [_buffer removeAllItems]; _last = _i + 1; - _state = OF_XMLPARSER_EXPECT_DELIMITER; + _state = (_data[_i] == '=' + ? OF_XMLPARSER_EXPECT_ATTRIBUTE_DELIMITER + : OF_XMLPARSER_EXPECT_ATTRIBUTE_EQUAL_SIGN); +} + +/* Expecting equal sign of an attribute */ +- (void)OF_expectAttributeEqualSignState +{ + if (_data[_i] == '=') { + _last = _i + 1; + _state = OF_XMLPARSER_EXPECT_ATTRIBUTE_DELIMITER; + return; + } + + if (_data[_i] != ' ' && _data[_i] != '\t' && _data[_i] != '\n' && + _data[_i] != '\r') + @throw [OFMalformedXMLException exceptionWithParser: self]; } -/* Expecting delimiter */ -- (void)OF_expectDelimiterState +/* Expecting name/value delimiter of an attribute */ +- (void)OF_expectAttributeDelimiterState { _last = _i + 1; if (_data[_i] == ' ' || _data[_i] == '\t' || _data[_i] == '\n' || _data[_i] == '\r') @@ -821,11 +836,11 @@ if (_data[_i] != '\'' && _data[_i] != '"') @throw [OFMalformedXMLException exceptionWithParser: self]; _delimiter = _data[_i]; - _state = OF_XMLPARSER_IN_ATTR_VALUE; + _state = OF_XMLPARSER_IN_ATTRIBUTE_VALUE; } /* Looking for attribute value */ - (void)OF_inAttributeValueState { @@ -864,21 +879,21 @@ _last = _i + 1; _state = OF_XMLPARSER_IN_TAG; } /* Expecting closing '>' */ -- (void)OF_expectCloseState +- (void)OF_expectTagCloseState { if (_data[_i] == '>') { _last = _i + 1; _state = OF_XMLPARSER_OUTSIDE_TAG; } else @throw [OFMalformedXMLException exceptionWithParser: self]; } /* Expecting closing '>' or space */ -- (void)OF_expectSpaceOrCloseState +- (void)OF_expectSpaceOrTagCloseState { if (_data[_i] == '>') { _last = _i + 1; _state = OF_XMLPARSER_OUTSIDE_TAG; } else if (_data[_i] != ' ' && _data[_i] != '\t' &&