Permalink
Browse files

Fixed copy memory issues.

* XML Doc Ptr would be freed by first object to be deallocated.
* Using a strong reference holder to preserve it.
  • Loading branch information...
1 parent 51c1a21 commit 739729e7656b15d362f0ce2527a018d1357c1efc John Blanco committed Mar 5, 2013
Showing with 54 additions and 26 deletions.
  1. +2 −2 RaptureXML.xcodeproj/project.pbxproj
  2. +12 −3 RaptureXML/RXMLElement.h
  3. +40 −21 RaptureXML/RXMLElement.m
View
4 RaptureXML.xcodeproj/project.pbxproj
@@ -29,6 +29,7 @@
0252B2E0142ADFC60018B75D /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0252B2C3142ADFC60018B75D /* UIKit.framework */; };
0252B2E1142ADFC60018B75D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0252B2C5142ADFC60018B75D /* Foundation.framework */; };
0252B2E2142ADFC60018B75D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0252B2C7142ADFC60018B75D /* CoreGraphics.framework */; };
+ 02565F9916E6320700A882F9 /* CopyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1413670716D9BEC700501ABB /* CopyTests.m */; };
027B3571153C624700A4EDF2 /* DeepChildrenTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DEB8EC71467ED9C00024989 /* DeepChildrenTests.m */; };
027DAC3314FBF443001BA563 /* RXMLElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 027DAC2F14FBF443001BA563 /* RXMLElement.m */; };
027DAC3614FBF465001BA563 /* RXMLElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 027DAC2F14FBF443001BA563 /* RXMLElement.m */; };
@@ -44,7 +45,6 @@
02F3A3FF1526D22600E8C822 /* players.xml in Resources */ = {isa = PBXBuildFile; fileRef = 0DEB8F2D14681BD800024989 /* players.xml */; };
0DEB8EB51467EC9B00024989 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0252B2C5142ADFC60018B75D /* Foundation.framework */; };
0DEB8F2C14681A9400024989 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 0252B305142AE3FF0018B75D /* libz.dylib */; };
- 1413670916D9BF0D00501ABB /* CopyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1413670716D9BEC700501ABB /* CopyTests.m */; };
6BD1BDA91558B91400F1D055 /* RXMLElement.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 027DAC2E14FBF443001BA563 /* RXMLElement.h */; };
/* End PBXBuildFile section */
@@ -341,7 +341,6 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 1413670916D9BF0D00501ABB /* CopyTests.m in Sources */,
027DAC3314FBF443001BA563 /* RXMLElement.m in Sources */,
027B3571153C624700A4EDF2 /* DeepChildrenTests.m in Sources */,
02ADE6A216A0E33A008643D5 /* AttributeTests.m in Sources */,
@@ -353,6 +352,7 @@
02ADE6A816A0E491008643D5 /* WildcardTests.m in Sources */,
02ADE6A916A0E491008643D5 /* EncodingTests.m in Sources */,
02ADE6AA16A0E491008643D5 /* XPathTests.m in Sources */,
+ 02565F9916E6320700A882F9 /* CopyTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
15 RaptureXML/RXMLElement.h
@@ -34,8 +34,16 @@
#import <libxml/xpath.h>
#import <libxml/xpathInternals.h>
-@interface RXMLElement : NSObject<NSCopying> {
+@interface RXMLDocHolder : NSObject {
xmlDocPtr doc_;
+}
+
+- (id)initWithDocPtr:(xmlDocPtr)doc;
+- (xmlDocPtr)doc;
+
+@end
+
+@interface RXMLElement : NSObject<NSCopying> {
xmlNodePtr node_;
}
@@ -45,14 +53,14 @@
- (id)initFromXMLFilePath:(NSString *)fullPath;
- (id)initFromURL:(NSURL *)url __attribute__((deprecated));
- (id)initFromXMLData:(NSData *)data;
-- (id)initFromXMLNode:(xmlNodePtr)node;
+- (id)initFromXMLDoc:(RXMLDocHolder *)doc node:(xmlNodePtr)node;
+ (id)elementFromXMLString:(NSString *)xmlString encoding:(NSStringEncoding)encoding;
+ (id)elementFromXMLFile:(NSString *)filename;
+ (id)elementFromXMLFilename:(NSString *)filename fileExtension:(NSString *)extension;
+ (id)elementFromURL:(NSURL *)url __attribute__((deprecated));
+ (id)elementFromXMLData:(NSData *)data;
-+ (id)elementFromXMLNode:(xmlNodePtr)node;
++ (id)elementFromXMLDoc:(RXMLDocHolder *)doc node:(xmlNodePtr)node;
- (NSString *)attribute:(NSString *)attributeName;
- (NSString *)attribute:(NSString *)attributeName inNamespace:(NSString *)ns;
@@ -76,6 +84,7 @@
- (void)iterateWithRootXPath:(NSString *)xpath usingBlock:(void (^)(RXMLElement *))blk;
- (void)iterateElements:(NSArray *)elements usingBlock:(void (^)(RXMLElement *))blk;
+@property (nonatomic, strong) RXMLDocHolder *xmlDoc;
@property (nonatomic, readonly) NSString *tag;
@property (nonatomic, readonly) NSString *text;
@property (nonatomic, readonly) NSInteger textAsInt;
View
61 RaptureXML/RXMLElement.m
@@ -30,6 +30,28 @@
#import "RXMLElement.h"
+@implementation RXMLDocHolder
+
+- (id)initWithDocPtr:(xmlDocPtr)doc {
+ if ((self = [super init])) {
+ doc_ = doc;
+ }
+
+ return self;
+}
+
+- (void)dealloc {
+ if (doc_ != nil) {
+ xmlFreeDoc(doc_);
+ }
+}
+
+- (xmlDocPtr)doc {
+ return doc_;
+}
+
+@end
+
@implementation RXMLElement
- (id)initFromXMLString:(NSString *)xmlString encoding:(NSStringEncoding)encoding {
@@ -56,23 +78,24 @@ - (id)initFromURL:(NSURL *)url {
- (id)initFromXMLData:(NSData *)data {
if ((self = [super init])) {
- doc_ = xmlReadMemory([data bytes], [data length], "", nil, XML_PARSE_RECOVER);
+ xmlDocPtr doc = xmlReadMemory([data bytes], [data length], "", nil, XML_PARSE_RECOVER);
+ self.xmlDoc = [[RXMLDocHolder alloc] initWithDocPtr:doc];
if ([self isValid]) {
- node_ = xmlDocGetRootElement(doc_);
+ node_ = xmlDocGetRootElement(doc);
if (!node_) {
- xmlFreeDoc(doc_); doc_ = nil;
+ self.xmlDoc = nil;
}
}
}
return self;
}
-- (id)initFromXMLNode:(xmlNodePtr)node {
+- (id)initFromXMLDoc:(RXMLDocHolder *)doc node:(xmlNodePtr)node {
if ((self = [super init])) {
- doc_ = nil;
+ self.xmlDoc = doc;
node_ = node;
}
@@ -84,7 +107,7 @@ - (id)initFromXMLNode:(xmlNodePtr)node {
-(id)copyWithZone:(NSZone *)zone{
RXMLElement* new_element = [[RXMLElement alloc] init];
new_element->node_ = node_;
- new_element->doc_ = doc_;
+ new_element.xmlDoc = self.xmlDoc;
return new_element;
}
@@ -108,18 +131,14 @@ + (id)elementFromXMLData:(NSData *)data {
return [[RXMLElement alloc] initFromXMLData:data];
}
-+ (id)elementFromXMLNode:(xmlNodePtr)node {
- return [[RXMLElement alloc] initFromXMLNode:node];
++ (id)elementFromXMLDoc:(RXMLDocHolder *)doc node:(xmlNodePtr)node {
+ return [[RXMLElement alloc] initFromXMLDoc:doc node:node];
}
- (NSString *)description {
return [self text];
}
-- (void)dealloc {
- if (doc_ != nil) xmlFreeDoc(doc_);
-}
-
#pragma mark -
- (NSString *)tag {
@@ -191,7 +210,7 @@ - (double)attributeAsDouble:(NSString *)attName inNamespace:(NSString *)ns {
}
- (BOOL)isValid {
- return (doc_ != nil);
+ return (self.xmlDoc != nil);
}
#pragma mark -
@@ -227,7 +246,7 @@ - (RXMLElement *)child:(NSString *)tag {
}
if (cur) {
- return [RXMLElement elementFromXMLNode:cur];
+ return [RXMLElement elementFromXMLDoc:self.xmlDoc node:cur];
}
return nil;
@@ -265,7 +284,7 @@ - (RXMLElement *)child:(NSString *)tag inNamespace:(NSString *)ns {
}
if (cur) {
- return [RXMLElement elementFromXMLNode:cur];
+ return [RXMLElement elementFromXMLDoc:self.xmlDoc node:cur];
}
return nil;
@@ -278,7 +297,7 @@ - (NSArray *)children:(NSString *)tag {
while (cur != nil) {
if (cur->type == XML_ELEMENT_NODE && !xmlStrcmp(cur->name, tagC)) {
- [children addObject:[RXMLElement elementFromXMLNode:cur]];
+ [children addObject:[RXMLElement elementFromXMLDoc:self.xmlDoc node:cur]];
}
cur = cur->next;
@@ -295,7 +314,7 @@ - (NSArray *)children:(NSString *)tag inNamespace:(NSString *)ns {
while (cur != nil) {
if (cur->type == XML_ELEMENT_NODE && !xmlStrcmp(cur->name, tagC) && !xmlStrcmp(cur->ns->href, namespaceC)) {
- [children addObject:[RXMLElement elementFromXMLNode:cur]];
+ [children addObject:[RXMLElement elementFromXMLDoc:self.xmlDoc node:cur]];
}
cur = cur->next;
@@ -310,7 +329,7 @@ - (NSArray *)childrenWithRootXPath:(NSString *)xpath {
return [NSArray array];
}
- xmlXPathContextPtr context = xmlXPathNewContext(doc_);
+ xmlXPathContextPtr context = xmlXPathNewContext([self.xmlDoc doc]);
if (context == NULL) {
return nil;
@@ -329,7 +348,7 @@ - (NSArray *)childrenWithRootXPath:(NSString *)xpath {
NSMutableArray *resultNodes = [NSMutableArray array];
for (NSInteger i = 0; i < nodes->nodeNr; i++) {
- RXMLElement *element = [RXMLElement elementFromXMLNode:nodes->nodeTab[i]];
+ RXMLElement *element = [RXMLElement elementFromXMLDoc:self.xmlDoc node:nodes->nodeTab[i]];
if (element != NULL) {
[resultNodes addObject:element];
@@ -365,7 +384,7 @@ - (void)iterate:(NSString *)query usingBlock:(void (^)(RXMLElement *))blk {
// midstream
do {
if (cur->type == XML_ELEMENT_NODE) {
- RXMLElement *element = [RXMLElement elementFromXMLNode:cur];
+ RXMLElement *element = [RXMLElement elementFromXMLDoc:self.xmlDoc node:cur];
NSString *restOfQuery = [[components subarrayWithRange:NSMakeRange(i + 1, components.count - i - 1)] componentsJoinedByString:@"."];
[element iterate:restOfQuery usingBlock:blk];
}
@@ -398,7 +417,7 @@ - (void)iterate:(NSString *)query usingBlock:(void (^)(RXMLElement *))blk {
do {
if (cur->type == XML_ELEMENT_NODE) {
- RXMLElement *element = [RXMLElement elementFromXMLNode:cur];
+ RXMLElement *element = [RXMLElement elementFromXMLDoc:self.xmlDoc node:cur];
blk(element);
}

0 comments on commit 739729e

Please sign in to comment.