Index: src/OFXMLAttribute.h ================================================================== --- src/OFXMLAttribute.h +++ src/OFXMLAttribute.h @@ -30,10 +30,11 @@ { #if defined(OF_XML_ELEMENT_M) || defined(OF_XML_PARSER_M) @public #endif OFString *_name, *_Nullable _namespace, *_stringValue; + bool _useDoubleQuotes; } /*! * @brief The name of the attribute. */ Index: src/OFXMLElement.m ================================================================== --- src/OFXMLElement.m +++ src/OFXMLElement.m @@ -523,22 +523,26 @@ } /* Attributes */ for (OFXMLAttribute *attribute in _attributes) { void *pool2 = objc_autoreleasePoolPush(); - OFString *attributeName = [attribute name]; + const char *attributeNameCString = + [attribute->_name UTF8String]; + size_t attributeNameLength = + [attribute->_name UTF8StringLength]; OFString *attributePrefix = nil; OFString *tmp = [[attribute stringValue] stringByXMLEscaping]; + char delimiter = (attribute->_useDoubleQuotes ? '"' : '\''); - if ([attribute namespace] != nil && + if (attribute->_namespace != nil && (attributePrefix = [allNamespaces objectForKey: - [attribute namespace]]) == nil) + attribute->_namespace]) == nil) @throw [OFUnboundNamespaceException exceptionWithNamespace: [attribute namespace] element: self]; - length += [attributeName UTF8StringLength] + + length += attributeNameLength + (attributePrefix != nil ? [attributePrefix UTF8StringLength] + 1 : 0) + [tmp UTF8StringLength] + 4; @try { @@ -554,18 +558,17 @@ memcpy(cString + i, [attributePrefix UTF8String], [attributePrefix UTF8StringLength]); i += [attributePrefix UTF8StringLength]; cString[i++] = ':'; } - memcpy(cString + i, [attributeName UTF8String], - [attributeName UTF8StringLength]); - i += [attributeName UTF8StringLength]; + memcpy(cString + i, attributeNameCString, attributeNameLength); + i += attributeNameLength; cString[i++] = '='; - cString[i++] = '\''; + cString[i++] = delimiter; memcpy(cString + i, [tmp UTF8String], [tmp UTF8StringLength]); i += [tmp UTF8StringLength]; - cString[i++] = '\''; + cString[i++] = delimiter; objc_autoreleasePoolPop(pool2); } /* Children */ Index: src/OFXMLParser.m ================================================================== --- src/OFXMLParser.m +++ src/OFXMLParser.m @@ -840,10 +840,11 @@ - (void)of_inAttributeValueState { void *pool; OFString *attributeValue; size_t length; + OFXMLAttribute *attribute; if (_data[_i] != _delimiter) return; if ((length = _i - _last) > 0) @@ -857,14 +858,15 @@ forKey: @""]; if ([_attributePrefix isEqual: @"xmlns"]) [[_namespaces lastObject] setObject: attributeValue forKey: _attributeName]; - [_attributes addObject: - [OFXMLAttribute attributeWithName: _attributeName - namespace: _attributePrefix - stringValue: attributeValue]]; + attribute = [OFXMLAttribute attributeWithName: _attributeName + namespace: _attributePrefix + stringValue: attributeValue]; + attribute->_useDoubleQuotes = (_delimiter == '"'); + [_attributes addObject: attribute]; objc_autoreleasePoolPop(pool); [_buffer removeAllItems]; [_attributeName release];