Index: src/OFXMLAttribute.h ================================================================== --- src/OFXMLAttribute.h +++ src/OFXMLAttribute.h @@ -89,11 +89,11 @@ * @param stringValue The string value of the attribute * @return An initialized OFXMLAttribute with the specified parameters */ - (instancetype)initWithName: (OFString *)name namespace: (nullable OFString *)nameSpace - stringValue: (OFString *)stringValue; + stringValue: (OFString *)stringValue OF_DESIGNATED_INITIALIZER; - (instancetype)initWithSerialization: (OFXMLElement *)element; @end OF_ASSUME_NONNULL_END Index: src/OFXMLAttribute.m ================================================================== --- src/OFXMLAttribute.m +++ src/OFXMLAttribute.m @@ -68,25 +68,35 @@ return self; } - (instancetype)initWithSerialization: (OFXMLElement *)element { - self = [super of_init]; + void *pool; + OFString *name, *namespace, *stringValue; @try { - void *pool = objc_autoreleasePoolPush(); + pool = objc_autoreleasePoolPush(); if (![element.name isEqual: self.className] || ![element.namespace isEqual: OFSerializationNS]) @throw [OFInvalidArgumentException exception]; - _name = [[element attributeForName: @"name"].stringValue copy]; - _namespace = [[element attributeForName: @"namespace"] - .stringValue copy]; - _stringValue = [[element attributeForName: @"stringValue"] - .stringValue copy]; + name = [element attributeForName: @"name"].stringValue; + namespace = [element attributeForName: @"namespace"] + .stringValue; + stringValue = [element attributeForName: @"stringValue"] + .stringValue; + } @catch (id e) { + [self release]; + @throw e; + } + + self = [self initWithName: name + namespace: namespace + stringValue: stringValue]; + @try { objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } @@ -176,10 +186,11 @@ return [element autorelease]; } - (OFString *)description { - return [OFString stringWithFormat: @"", - _name, _namespace, _stringValue]; + return [OFString stringWithFormat: @"<%@: name=%@, namespace=%@, " + @"stringValue=%@>", + self.class, _name, _namespace, + _stringValue]; } @end Index: src/OFXMLCDATA.m ================================================================== --- src/OFXMLCDATA.m +++ src/OFXMLCDATA.m @@ -114,21 +114,10 @@ [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } -- (OFString *)XMLStringWithIndentation: (unsigned int)indentation -{ - return self.XMLString; -} - -- (OFString *)XMLStringWithIndentation: (unsigned int)indentation - level: (unsigned int)level -{ - return self.XMLString; -} - - (OFString *)description { return self.XMLString; } Index: src/OFXMLCharacters.m ================================================================== --- src/OFXMLCharacters.m +++ src/OFXMLCharacters.m @@ -106,28 +106,17 @@ - (OFString *)XMLString { return _characters.stringByXMLEscaping; } -- (OFString *)XMLStringWithIndentation: (unsigned int)indentation -{ - return _characters.stringByXMLEscaping; -} - -- (OFString *)XMLStringWithIndentation: (unsigned int)indentation - level: (unsigned int)level -{ - return _characters.stringByXMLEscaping; -} - - (OFString *)description { - return _characters.stringByXMLEscaping; + return self.XMLString; } - (OFXMLElement *)XMLElementBySerializing { return [OFXMLElement elementWithName: self.className namespace: OFSerializationNS stringValue: _characters]; } @end Index: src/OFXMLComment.m ================================================================== --- src/OFXMLComment.m +++ src/OFXMLComment.m @@ -103,44 +103,17 @@ - (OFString *)XMLString { return [OFString stringWithFormat: @"", _text]; } -- (OFString *)XMLStringWithIndentation: (unsigned int)indentation -{ - return [OFString stringWithFormat: @"", _text]; -} - -- (OFString *)XMLStringWithIndentation: (unsigned int)indentation - level: (unsigned int)level -{ - OFString *ret; - - if (indentation > 0 && level > 0) { - char *whitespaces = OFAllocMemory((level * indentation) + 1, 1); - memset(whitespaces, ' ', level * indentation); - whitespaces[level * indentation] = 0; - - @try { - ret = [OFString stringWithFormat: @"%s", - whitespaces, _text]; - } @finally { - OFFreeMemory(whitespaces); - } - } else - ret = [OFString stringWithFormat: @"", _text]; - - return ret; -} - - (OFString *)description { - return [OFString stringWithFormat: @"", _text]; + return self.XMLString; } - (OFXMLElement *)XMLElementBySerializing { return [OFXMLElement elementWithName: self.className namespace: OFSerializationNS stringValue: _text]; } @end Index: src/OFXMLElement.h ================================================================== --- src/OFXMLElement.h +++ src/OFXMLElement.h @@ -30,11 +30,11 @@ * * @brief A class which stores an XML element. */ @interface OFXMLElement: OFXMLNode { - OFString *_name, *_Nullable _namespace, *_Nullable _defaultNamespace; + OFString *_name, *_Nullable _namespace; OFMutableArray OF_GENERIC(OFXMLAttribute *) *_Nullable _attributes; OFMutableDictionary OF_GENERIC(OFString *, OFString *) *_Nullable _namespaces; OFMutableArray OF_GENERIC(OFXMLNode *) *_Nullable _children; OF_RESERVE_IVARS(OFXMLElement, 4) @@ -53,16 +53,10 @@ #else @property OF_NULLABLE_PROPERTY (copy, nonatomic, getter=namespace, setter=setNamespace:) OFString *nameSpace; #endif -/** - * @brief The default namespace for the element to be used if there is no - * parent. - */ -@property OF_NULLABLE_PROPERTY (copy, nonatomic) OFString *defaultNamespace; - /** * @brief An array with the attributes of the element. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFArray OF_GENERIC(OFXMLAttribute *) *attributes; @@ -327,12 +321,12 @@ /** * @brief Removes the child at the specified index. * * @param index The index of the child to remove */ - - (void)removeChildAtIndex: (size_t)index; + /** * @brief Replaces the first child that is equal to the specified OFXMLNode * with the specified node. * * @param child The child to replace @@ -351,12 +345,12 @@ /** * @brief Returns all children that have the specified namespace. * * @return All children that have the specified namespace */ -- (OFArray OF_GENERIC(OFXMLElement *) *)elementsForNamespace: - (nullable OFString *)elementNS; +- (OFArray OF_GENERIC(OFXMLElement *) *) + elementsForNamespace: (nullable OFString *)elementNS; /** * @brief Returns the first child element with the specified name. * * @param elementName The name of the element @@ -368,12 +362,12 @@ * @brief Returns the child elements with the specified name. * * @param elementName The name of the elements * @return The child elements with the specified name */ -- (OFArray OF_GENERIC(OFXMLElement *) *)elementsForName: - (OFString *)elementName; +- (OFArray OF_GENERIC(OFXMLElement *) *) + elementsForName: (OFString *)elementName; /** * @brief Returns the first child element with the specified name and namespace. * * @param elementName The name of the element @@ -391,10 +385,32 @@ * @return The child elements with the specified name and namespace */ - (OFArray OF_GENERIC(OFXMLElement *) *) elementsForName: (OFString *)elementName namespace: (nullable OFString *)elementNS; + +/** + * @brief Returns an OFString representing the OFXMLElement as an XML string + * with the specified indentation per level. + * + * @param indentation The indentation per level + * @return An OFString representing the OFXMLNode as an XML string with + * indentation + */ +- (OFString *)XMLStringWithIndentation: (unsigned int)indentation; + +/** + * @brief Returns an OFString representing the OFXMLElement as an XML string + * with the specified default namespace and indentation per level. + * + * @param defaultNS The default namespace + * @param indentation The indentation per level + * @return An OFString representing the OFXMLNode as an XML string with + * indentation + */ +- (OFString *)XMLStringWithDefaultNamespace: (OFString *)defaultNS + indentation: (unsigned int)indentation; @end OF_ASSUME_NONNULL_END #import "OFXMLElement+Serialization.h" Index: src/OFXMLElement.m ================================================================== --- src/OFXMLElement.m +++ src/OFXMLElement.m @@ -71,11 +71,10 @@ } @end @implementation OFXMLElement @synthesize name = _name, namespace = _namespace; -@synthesize defaultNamespace = _defaultNamespace; + (instancetype)elementWithName: (OFString *)name { return [[[self alloc] initWithName: name] autorelease]; } @@ -209,12 +208,10 @@ self = [self initWithName: element->_name namespace: element->_namespace]; @try { - [_defaultNamespace release]; - _defaultNamespace = [element->_defaultNamespace retain]; [_attributes release]; _attributes = [element->_attributes retain]; [_namespaces release]; _namespaces = [element->_namespaces retain]; [_children release]; @@ -263,12 +260,10 @@ self = [self initWithName: element->_name namespace: element->_namespace]; @try { - [_defaultNamespace release]; - _defaultNamespace = [element->_defaultNamespace retain]; [_attributes release]; _attributes = [element->_attributes retain]; [_namespaces release]; _namespaces = [element->_namespaces retain]; [_children release]; @@ -309,15 +304,10 @@ OFXMLElement *attributesElement, *namespacesElement; OFXMLElement *childrenElement; OFEnumerator *keyEnumerator, *objectEnumerator; OFString *key, *object; - [_defaultNamespace release]; - _defaultNamespace = nil; - _defaultNamespace = [[element attributeForName: - @"defaultNamespace"].stringValue copy]; - attributesElement = [[element elementForName: @"attributes" namespace: OFSerializationNS] elementsForNamespace: OFSerializationNS].firstObject; namespacesElement = [[element @@ -388,11 +378,10 @@ - (void)dealloc { [_name release]; [_namespace release]; - [_defaultNamespace release]; [_attributes release]; [_namespaces release]; [_children release]; [super dealloc]; @@ -445,28 +434,22 @@ [ret makeImmutable]; return ret; } -- (OFString *)of_XMLStringWithParent: (OFXMLElement *)parent - namespaces: (OFDictionary *)allNS - indentation: (unsigned int)indentation - level: (unsigned int)level OF_DIRECT +- (OFString *)of_XMLStringWithDefaultNS: (OFString *)defaultNS + namespaces: (OFDictionary *)allNS + indentation: (unsigned int)indentation + level: (unsigned int)level OF_DIRECT { void *pool; char *cString; size_t length, i; - OFString *prefix, *parentPrefix; - OFString *ret; - OFString *defaultNS; + OFString *prefix, *ret; pool = objc_autoreleasePoolPush(); - parentPrefix = [allNS objectForKey: - (parent != nil && parent->_namespace != nil - ? parent->_namespace : (OFString *)@"")]; - /* Add the namespaces of the current element */ if (allNS != nil) { OFEnumerator *keyEnumerator = [_namespaces keyEnumerator]; OFEnumerator *objectEnumerator = [_namespaces objectEnumerator]; OFMutableDictionary *tmp; @@ -483,17 +466,10 @@ allNS = _namespaces; prefix = [allNS objectForKey: (_namespace != nil ? _namespace : (OFString *)@"")]; - if (parent != nil && parent->_namespace != nil && parentPrefix == nil) - defaultNS = parent->_namespace; - else if (parent != nil && parent->_defaultNamespace != nil) - defaultNS = parent->_defaultNamespace; - else - defaultNS = _defaultNamespace; - i = 0; length = _name.UTF8StringLength + 3 + (level * indentation); cString = OFAllocMemory(length, 1); @try { @@ -501,11 +477,11 @@ i += level * indentation; /* Start of tag */ cString[i++] = '<'; - if (prefix != nil && ![_namespace isEqual: defaultNS]) { + if (prefix.length > 0) { length += prefix.UTF8StringLength + 1; cString = OFResizeMemory(cString, length, 1); memcpy(cString + i, prefix.UTF8String, prefix.UTF8StringLength); @@ -515,22 +491,23 @@ memcpy(cString + i, _name.UTF8String, _name.UTF8StringLength); i += _name.UTF8StringLength; /* xmlns if necessary */ - if (prefix == nil && ((_namespace != nil && - ![_namespace isEqual: defaultNS]) || - (_namespace == nil && defaultNS != nil))) { + if (prefix.length == 0 && defaultNS != _namespace && + ![defaultNS isEqual: _namespace]) { length += _namespace.UTF8StringLength + 9; cString = OFResizeMemory(cString, length, 1); memcpy(cString + i, " xmlns='", 8); i += 8; memcpy(cString + i, _namespace.UTF8String, _namespace.UTF8StringLength); i += _namespace.UTF8StringLength; cString[i++] = '\''; + + defaultNS = _namespace; } /* Attributes */ for (OFXMLAttribute *attribute in _attributes) { void *pool2 = objc_autoreleasePoolPush(); @@ -543,12 +520,12 @@ attribute.stringValue.stringByXMLEscaping; char delimiter = (attribute->_useDoubleQuotes ? '"' : '\''); if (attribute->_namespace != nil && - (attributePrefix = [allNS objectForKey: - attribute->_namespace]) == nil) + [(attributePrefix = [allNS objectForKey: + attribute->_namespace]) length] == 0) @throw [OFUnboundNamespaceException exceptionWithNamespace: attribute.namespace element: self]; length += attributeNameLength + (attributePrefix != nil @@ -603,19 +580,21 @@ if (ind) [tmp addItem: "\n"]; if ([child isKindOfClass: [OFXMLElement class]]) childString = [(OFXMLElement *)child - of_XMLStringWithParent: self - namespaces: allNS - indentation: ind - level: level + 1]; - else - childString = [child - XMLStringWithIndentation: ind - level: level + - 1]; + of_XMLStringWithDefaultNS: defaultNS + namespaces: allNS + indentation: ind + level: level + + 1]; + else { + childString = child.XMLString; + for (unsigned int j = 0; + j < ind * (level + 1); j++) + [tmp addItem: " "]; + } [tmp addItems: childString.UTF8String count: childString.UTF8StringLength]; } @@ -636,11 +615,11 @@ i += level * indentation; } cString[i++] = '<'; cString[i++] = '/'; - if (prefix != nil) { + if (prefix.length > 0) { length += prefix.UTF8StringLength + 1; cString = OFResizeMemory(cString, length, 1); memcpy(cString + i, prefix.UTF8String, prefix.UTF8StringLength); @@ -666,31 +645,31 @@ return ret; } - (OFString *)XMLString { - return [self of_XMLStringWithParent: nil - namespaces: nil - indentation: 0 - level: 0]; + return [self of_XMLStringWithDefaultNS: nil + namespaces: nil + indentation: 0 + level: 0]; } - (OFString *)XMLStringWithIndentation: (unsigned int)indentation { - return [self of_XMLStringWithParent: nil - namespaces: nil - indentation: indentation - level: 0]; + return [self of_XMLStringWithDefaultNS: nil + namespaces: nil + indentation: indentation + level: 0]; } -- (OFString *)XMLStringWithIndentation: (unsigned int)indentation - level: (unsigned int)level +- (OFString *)XMLStringWithDefaultNamespace: (OFString *)defaultNS + indentation: (unsigned int)indentation { - return [self of_XMLStringWithParent: nil - namespaces: nil - indentation: indentation - level: level]; + return [self of_XMLStringWithDefaultNS: defaultNS + namespaces: nil + indentation: indentation + level: 0]; } - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); @@ -704,14 +683,10 @@ if (_namespace != nil) [element addAttributeWithName: @"namespace" stringValue: _namespace]; - if (_defaultNamespace != nil) - [element addAttributeWithName: @"defaultNamespace" - stringValue: _defaultNamespace]; - if (_attributes != nil) { OFXMLElement *attributesElement; attributesElement = [OFXMLElement elementWithName: @"attributes" @@ -856,12 +831,10 @@ - (void)setPrefix: (OFString *)prefix forNamespace: (OFString *)namespace { if (prefix.length == 0) @throw [OFInvalidArgumentException exception]; - if (namespace == nil) - namespace = @""; [_namespaces setObject: prefix forKey: namespace]; } - (void)bindPrefix: (OFString *)prefix forNamespace: (OFString *)namespace @@ -1036,13 +1009,10 @@ if (element->_name != _name && ![element->_name isEqual: _name]) return false; if (element->_namespace != _namespace && ![element->_namespace isEqual: _namespace]) return false; - if (element->_defaultNamespace != _defaultNamespace && - ![element->_defaultNamespace isEqual: _defaultNamespace]) - return false; if (element->_attributes != _attributes && ![element->_attributes isEqual: _attributes]) return false; if (element->_namespaces != _namespaces && ![element->_namespaces isEqual: _namespaces]) @@ -1060,11 +1030,10 @@ OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAddHash(&hash, _namespace.hash); - OFHashAddHash(&hash, _defaultNamespace.hash); OFHashAddHash(&hash, _attributes.hash); OFHashAddHash(&hash, _namespaces.hash); OFHashAddHash(&hash, _children.hash); OFHashFinalize(&hash); @@ -1076,11 +1045,10 @@ { OFXMLElement *copy = [[OFXMLElement alloc] of_init]; @try { copy->_name = [_name copy]; copy->_namespace = [_namespace copy]; - copy->_defaultNamespace = [_defaultNamespace copy]; copy->_attributes = [_attributes mutableCopy]; copy->_namespaces = [_namespaces mutableCopy]; copy->_children = [_children mutableCopy]; } @catch (id e) { [copy release]; Index: src/OFXMLNode.h ================================================================== --- src/OFXMLNode.h +++ src/OFXMLNode.h @@ -64,32 +64,10 @@ @property (readonly, nonatomic) OFString *XMLString; - (instancetype)init OF_UNAVAILABLE; - (instancetype)initWithSerialization: (OFXMLElement *)element OF_UNAVAILABLE; -/** - * @brief Returns an OFString representing the OFXMLNode as an XML string with - * indentation. - * - * @param indentation The indentation for the XML string - * @return An OFString representing the OFXMLNode as an XML string with - * indentation - */ -- (OFString *)XMLStringWithIndentation: (unsigned int)indentation; - -/** - * @brief Returns an OFString representing the OFXMLNode as an XML string with - * indentation for the specified level. - * - * @param indentation The indentation for the XML string - * @param level The level of indentation - * @return An OFString representing the OFXMLNode as an XML string with - * indentation - */ -- (OFString *)XMLStringWithIndentation: (unsigned int)indentation - level: (unsigned int)level; - /** * @brief The contents of the receiver as a `long long` value in the specified * base. * * @param base The base to use. If the base is 0, base 16 is assumed if the Index: src/OFXMLNode.m ================================================================== --- src/OFXMLNode.m +++ src/OFXMLNode.m @@ -74,27 +74,16 @@ return self.stringValue.doubleValue; } - (OFString *)XMLString { - return [self XMLStringWithIndentation: 0 level: 0]; -} - -- (OFString *)XMLStringWithIndentation: (unsigned int)indentation -{ - return [self XMLStringWithIndentation: 0 level: 0]; -} - -- (OFString *)XMLStringWithIndentation: (unsigned int)indentation - level: (unsigned int)level -{ OF_UNRECOGNIZED_SELECTOR } - (OFString *)description { - return [self XMLStringWithIndentation: 2 level: 0]; + return self.XMLString; } - (OFXMLElement *)XMLElementBySerializing { OF_UNRECOGNIZED_SELECTOR Index: src/OFXMLParser.h ================================================================== --- src/OFXMLParser.h +++ src/OFXMLParser.h @@ -50,32 +50,32 @@ * tag. * * @param parser The parser which found a new tag * @param name The name of the tag which just started * @param prefix The prefix of the tag which just started or `nil` - * @param ns The namespace of the tag which just started or `nil` + * @param nameSpace The namespace of the tag which just started or `nil` * @param attributes The attributes included in the tag which just started or * `nil` */ - (void)parser: (OFXMLParser *)parser didStartElement: (OFString *)name prefix: (nullable OFString *)prefix - namespace: (nullable OFString *)ns + namespace: (nullable OFString *)nameSpace attributes: (nullable OFArray OF_GENERIC(OFXMLAttribute *) *)attributes; /** * @brief This callback is called when the XML parser found the end of a tag. * * @param parser The parser which found the end of a tag * @param name The name of the tag which just ended * @param prefix The prefix of the tag which just ended or `nil` - * @param ns The namespace of the tag which just ended or `nil` + * @param nameSpace The namespace of the tag which just ended or `nil` */ - (void)parser: (OFXMLParser *)parser didEndElement: (OFString *)name prefix: (nullable OFString *)prefix - namespace: (nullable OFString *)ns; + namespace: (nullable OFString *)nameSpace; /** * @brief This callback is called when the XML parser found characters. * * In case there are comments or CDATA, it is possible that this callback is Index: src/OFXMLParser.m ================================================================== --- src/OFXMLParser.m +++ src/OFXMLParser.m @@ -112,11 +112,11 @@ static OF_INLINE void appendToBuffer(OFMutableData *buffer, const char *string, OFStringEncoding encoding, size_t length) { - if OF_LIKELY(encoding == OFStringEncodingUTF8) + if OF_LIKELY (encoding == OFStringEncodingUTF8) [buffer addItems: string count: length]; else { void *pool = objc_autoreleasePoolPush(); OFString *tmp = [OFString stringWithCString: string encoding: encoding Index: src/OFXMLProcessingInstruction.m ================================================================== --- src/OFXMLProcessingInstruction.m +++ src/OFXMLProcessingInstruction.m @@ -132,41 +132,10 @@ _target, _text]; else return [OFString stringWithFormat: @"", _target]; } -- (OFString *)XMLStringWithIndentation: (unsigned int)indentation -{ - return self.XMLString; -} - -- (OFString *)XMLStringWithIndentation: (unsigned int)indentation - level: (unsigned int)level -{ - if (indentation > 0 && level > 0) { - OFString *ret; - char *whitespaces = OFAllocMemory((level * indentation) + 1, 1); - memset(whitespaces, ' ', level * indentation); - whitespaces[level * indentation] = 0; - - @try { - if (_text.length > 0) - ret = [OFString stringWithFormat: - @"%s", whitespaces, - _target, _text]; - else - ret = [OFString stringWithFormat: - @"%s", whitespaces, _target]; - } @finally { - OFFreeMemory(whitespaces); - } - - return ret; - } else - return self.XMLString; -} - - (OFString *)description { return self.XMLString; } Index: tests/serialization.xml ================================================================== --- tests/serialization.xml +++ tests/serialization.xml @@ -12,29 +12,10 @@ B"la - MDEyMzQ1Njc4OTo7PEFCQ0RFRkdISklLTE1OT1BRUlNUVVZXWFla - - - data - - - - Qu"xbar -test - 1234 - 40934a456d5cfaad - asd - 40934a456d5cfaad - - - - Hello - - Hello Wo ld! How are you? https://objfw.nil.im/ @@ -61,7 +42,26 @@ list + + MDEyMzQ1Njc4OTo7PEFCQ0RFRkdISklLTE1OT1BRUlNUVVZXWFla + + + data + + + + Qu"xbar +test + 1234 + 40934a456d5cfaad + asd + 40934a456d5cfaad + + + + Hello +