Index: src/OFXMLElement.h ================================================================== --- src/OFXMLElement.h +++ src/OFXMLElement.h @@ -120,19 +120,10 @@ */ + (instancetype)elementWithName: (OFString *)name namespace: (nullable OFString *)nameSpace stringValue: (nullable OFString *)stringValue; -/** - * @brief Creates a new element with the specified element. - * - * @param element An OFXMLElement to initialize the OFXMLElement with - * @return A new autoreleased OFXMLElement with the contents of the specified - * element - */ -+ (instancetype)elementWithElement: (OFXMLElement *)element; - /** * @brief Parses the string and returns an OFXMLElement for it. * * @param string The string to parse * @return A new autoreleased OFXMLElement with the contents of the string @@ -178,11 +169,12 @@ * @param nameSpace The namespace for the element * @return An initialized OFXMLElement with the specified element name and * namespace */ - (instancetype)initWithName: (OFString *)name - namespace: (nullable OFString *)nameSpace; + namespace: (nullable OFString *)nameSpace + OF_DESIGNATED_INITIALIZER; /** * @brief Initializes an already allocated OFXMLElement with the specified name, * namespace and value. * @@ -194,20 +186,10 @@ */ - (instancetype)initWithName: (OFString *)name namespace: (nullable OFString *)nameSpace stringValue: (nullable OFString *)stringValue; -/** - * @brief Initializes an already allocated OFXMLElement with the specified - * element. - * - * @param element An OFXMLElement to initialize the OFXMLElement with - * @return A new autoreleased OFXMLElement with the contents of the specified - * element - */ -- (instancetype)initWithElement: (OFXMLElement *)element; - /** * @brief Parses the string and initializes an already allocated OFXMLElement * with it. * * @param string The string to parse @@ -222,12 +204,10 @@ * @param stream The stream to parse * @return An initialized OFXMLElement with the contents of the specified stream */ - (instancetype)initWithStream: (OFStream *)stream; -- (instancetype)initWithSerialization: (OFXMLElement *)element; - /** * @brief Sets a prefix for a namespace. * * @param prefix The prefix for the namespace * @param nameSpace The namespace for which the prefix is set Index: src/OFXMLElement.m ================================================================== --- src/OFXMLElement.m +++ src/OFXMLElement.m @@ -101,15 +101,10 @@ return [[[self alloc] initWithName: name namespace: namespace stringValue: stringValue] autorelease]; } -+ (instancetype)elementWithElement: (OFXMLElement *)element -{ - return [[[self alloc] initWithElement: element] autorelease]; -} - + (instancetype)elementWithXMLString: (OFString *)string { return [[[self alloc] initWithXMLString: string] autorelease]; } @@ -137,17 +132,10 @@ } - (instancetype)initWithName: (OFString *)name namespace: (OFString *)namespace { - return [self initWithName: name namespace: namespace stringValue: nil]; -} - -- (instancetype)initWithName: (OFString *)name - namespace: (OFString *)namespace - stringValue: (OFString *)stringValue -{ self = [super of_init]; @try { if (name == nil) @throw [OFInvalidArgumentException exception]; @@ -157,36 +145,27 @@ _namespaces = [[OFMutableDictionary alloc] initWithKeysAndObjects: @"http://www.w3.org/XML/1998/namespace", @"xml", @"http://www.w3.org/2000/xmlns/", @"xmlns", nil]; - - if (stringValue != nil) - self.stringValue = stringValue; } @catch (id e) { [self release]; @throw e; } return self; } -- (instancetype)initWithElement: (OFXMLElement *)element +- (instancetype)initWithName: (OFString *)name + namespace: (OFString *)namespace + stringValue: (OFString *)stringValue { - self = [super of_init]; + self = [self initWithName: name namespace: namespace]; @try { - if (element == nil || - ![element isKindOfClass: [OFXMLElement class]]) - @throw [OFInvalidArgumentException exception]; - - _name = [element->_name copy]; - _namespace = [element->_namespace copy]; - _defaultNamespace = [element->_defaultNamespace copy]; - _attributes = [element->_attributes mutableCopy]; - _namespaces = [element->_namespaces mutableCopy]; - _children = [element->_children mutableCopy]; + if (stringValue != nil) + self.stringValue = stringValue; } @catch (id e) { [self release]; @throw e; } @@ -194,110 +173,176 @@ } - (instancetype)initWithXMLString: (OFString *)string { void *pool; - OFXMLParser *parser; - OFXMLElementBuilder *builder; - OFXMLElementElementBuilderDelegate *delegate; - - [self release]; - - if (string == nil) - @throw [OFInvalidArgumentException exception]; - - pool = objc_autoreleasePoolPush(); - - parser = [OFXMLParser parser]; - builder = [OFXMLElementBuilder builder]; - delegate = [[[OFXMLElementElementBuilderDelegate alloc] init] - autorelease]; - - parser.delegate = builder; - builder.delegate = delegate; - - [parser parseString: string]; - - if (!parser.hasFinishedParsing) - @throw [OFMalformedXMLException exceptionWithParser: parser]; - - self = [delegate->_element retain]; - - objc_autoreleasePoolPop(pool); + OFXMLElement *element; + + @try { + OFXMLParser *parser; + OFXMLElementBuilder *builder; + OFXMLElementElementBuilderDelegate *delegate; + + if (string == nil) + @throw [OFInvalidArgumentException exception]; + + pool = objc_autoreleasePoolPush(); + + parser = [OFXMLParser parser]; + builder = [OFXMLElementBuilder builder]; + delegate = [[[OFXMLElementElementBuilderDelegate alloc] init] + autorelease]; + + parser.delegate = builder; + builder.delegate = delegate; + + [parser parseString: string]; + + if (!parser.hasFinishedParsing) + @throw [OFMalformedXMLException + exceptionWithParser: parser]; + + element = delegate->_element; + } @catch (id e) { + [self release]; + @throw e; + } + + 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]; + _children = [element->_children retain]; + + objc_autoreleasePoolPop(pool); + } @catch (id e) { + [self release]; + @throw e; + } return self; } - (instancetype)initWithStream: (OFStream *)stream { void *pool; - OFXMLParser *parser; - OFXMLElementBuilder *builder; - OFXMLElementElementBuilderDelegate *delegate; - - [self release]; - - pool = objc_autoreleasePoolPush(); - - parser = [OFXMLParser parser]; - builder = [OFXMLElementBuilder builder]; - delegate = [[[OFXMLElementElementBuilderDelegate alloc] init] - autorelease]; - - parser.delegate = builder; - builder.delegate = delegate; - - [parser parseStream: stream]; - - if (!parser.hasFinishedParsing) - @throw [OFMalformedXMLException exceptionWithParser: parser]; - - self = [delegate->_element retain]; - - objc_autoreleasePoolPop(pool); + OFXMLElement *element; + + @try { + OFXMLParser *parser; + OFXMLElementBuilder *builder; + OFXMLElementElementBuilderDelegate *delegate; + + pool = objc_autoreleasePoolPush(); + + parser = [OFXMLParser parser]; + builder = [OFXMLElementBuilder builder]; + delegate = [[[OFXMLElementElementBuilderDelegate alloc] init] + autorelease]; + + parser.delegate = builder; + builder.delegate = delegate; + + [parser parseStream: stream]; + + if (!parser.hasFinishedParsing) + @throw [OFMalformedXMLException + exceptionWithParser: parser]; + + element = delegate->_element; + } @catch (id e) { + [self release]; + @throw e; + } + + 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]; + _children = [element->_children retain]; + + objc_autoreleasePoolPop(pool); + } @catch (id e) { + [self release]; + @throw e; + } return self; } - (instancetype)initWithSerialization: (OFXMLElement *)element { - self = [super of_init]; + void *pool; + OFString *name, *namespace; @try { - void *pool = objc_autoreleasePoolPush(); - OFXMLElement *attributesElement, *namespacesElement; - OFXMLElement *childrenElement; - OFEnumerator *keyEnumerator, *objectEnumerator; - OFString *key, *object; + 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]; + name = [element attributeForName: @"name"].stringValue; + namespace = + [element attributeForName: @"namespace"].stringValue; + } @catch (id e) { + [self release]; + @throw e; + } + + self = [self initWithName: name namespace: namespace]; + + @try { + 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; + namespace: OFSerializationNS] + elementsForNamespace: OFSerializationNS].firstObject; namespacesElement = [[element elementForName: @"namespaces" - namespace: OFSerializationNS] elementsForNamespace: - OFSerializationNS].firstObject; + namespace: OFSerializationNS] + elementsForNamespace: OFSerializationNS].firstObject; childrenElement = [[element elementForName: @"children" - namespace: OFSerializationNS] elementsForNamespace: - OFSerializationNS].firstObject; + namespace: OFSerializationNS] + elementsForNamespace: OFSerializationNS].firstObject; + [_attributes release]; + _attributes = nil; _attributes = [attributesElement.objectByDeserializing mutableCopy]; + + [_namespaces release]; + _namespaces = nil; _namespaces = [namespacesElement.objectByDeserializing mutableCopy]; + + [_children release]; + _children = nil; _children = [childrenElement.objectByDeserializing mutableCopy]; /* Sanity checks */ if ((_attributes != nil && ![_attributes isKindOfClass: @@ -330,13 +375,10 @@ setObject: @"xml" forKey: @"http://www.w3.org/XML/1998/namespace"]; [_namespaces setObject: @"xmlns" forKey: @"http://www.w3.org/2000/xmlns/"]; - if (_name == nil) - @throw [OFInvalidArgumentException exception]; - objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } @@ -1030,8 +1072,21 @@ return hash; } - (id)copy { - return [[[self class] alloc] initWithElement: self]; + 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]; + @throw e; + } + + return copy; } @end