Skip to content
Browse files

GCMutableNode

  • Loading branch information...
1 parent aae9bee commit f770f9b5baf551029381e03bc435ff4c2871c5ca @mikkelee committed Apr 27, 2012
View
8 Gedcom.xcodeproj/project.pbxproj
@@ -18,6 +18,8 @@
3E252F0F1523915A00BAFCB1 /* GCHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E252F0D1523915900BAFCB1 /* GCHeader.h */; };
3E252F101523915A00BAFCB1 /* GCHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 3E252F0E1523915900BAFCB1 /* GCHeader.m */; };
3E29DB1A154A1D9600756CF4 /* GCDateAgeMathTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3E29DB18154A1C3800756CF4 /* GCDateAgeMathTests.m */; };
+ 3E29DB1D154A405100756CF4 /* GCMutableNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E29DB1B154A405100756CF4 /* GCMutableNode.h */; };
+ 3E29DB1E154A405100756CF4 /* GCMutableNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 3E29DB1C154A405100756CF4 /* GCMutableNode.m */; };
3E4373551521CB7200BA362F /* GCAttribute.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E4373531521CB7200BA362F /* GCAttribute.h */; };
3E4373561521CB7200BA362F /* GCAttribute.m in Sources */ = {isa = PBXBuildFile; fileRef = 3E4373541521CB7200BA362F /* GCAttribute.m */; };
3E57557B15202A9600A918D1 /* GCValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E57557915202A9600A918D1 /* GCValue.h */; };
@@ -92,6 +94,8 @@
3E252F0D1523915900BAFCB1 /* GCHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCHeader.h; sourceTree = "<group>"; };
3E252F0E1523915900BAFCB1 /* GCHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GCHeader.m; sourceTree = "<group>"; };
3E29DB18154A1C3800756CF4 /* GCDateAgeMathTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GCDateAgeMathTests.m; sourceTree = "<group>"; };
+ 3E29DB1B154A405100756CF4 /* GCMutableNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCMutableNode.h; sourceTree = "<group>"; };
+ 3E29DB1C154A405100756CF4 /* GCMutableNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GCMutableNode.m; sourceTree = "<group>"; };
3E4373531521CB7200BA362F /* GCAttribute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = GCAttribute.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
3E4373541521CB7200BA362F /* GCAttribute.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = GCAttribute.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
3E57557915202A9600A918D1 /* GCValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCValue.h; sourceTree = "<group>"; };
@@ -166,6 +170,8 @@
children = (
3EECFD5E151C32630074E26C /* GCNode.h */,
3EECFD5F151C32630074E26C /* GCNode.m */,
+ 3E29DB1B154A405100756CF4 /* GCMutableNode.h */,
+ 3E29DB1C154A405100756CF4 /* GCMutableNode.m */,
);
name = Nodes;
sourceTree = "<group>";
@@ -365,6 +371,7 @@
3E14EDCA15230DAF00080364 /* GCContext.h in Headers */,
3E252F0F1523915A00BAFCB1 /* GCHeader.h in Headers */,
3EB5ABD3153615E10036B4D5 /* GCMutableOrderedSetProxy.h in Headers */,
+ 3E29DB1D154A405100756CF4 /* GCMutableNode.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -498,6 +505,7 @@
3E14EDCB15230DAF00080364 /* GCContext.m in Sources */,
3E252F101523915A00BAFCB1 /* GCHeader.m in Sources */,
3EB5ABD4153615E10036B4D5 /* GCMutableOrderedSetProxy.m in Sources */,
+ 3E29DB1E154A405100756CF4 /* GCMutableNode.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
22 Gedcom/GCMutableNode.h
@@ -0,0 +1,22 @@
+//
+// GCMutableNode.h
+// Gedcom
+//
+// Created by Mikkel Eide Eriksen on 27/04/12.
+// Copyright (c) 2012 Mikkel Eide Eriksen. All rights reserved.
+//
+
+#import "GCNode.h"
+
+@interface GCMutableNode : GCNode
+
+- (void)addSubNode: (GCMutableNode *) n;
+- (void)addSubNodes: (NSArray *) a;
+
+@property NSString *gedTag;
+@property NSString *gedValue;
+@property NSString *xref;
+@property NSString *lineSeparator;
+@property NSArray *subNodes;
+
+@end
View
73 Gedcom/GCMutableNode.m
@@ -0,0 +1,73 @@
+//
+// GCMutableNode.m
+// Gedcom
+//
+// Created by Mikkel Eide Eriksen on 27/04/12.
+// Copyright (c) 2012 Mikkel Eide Eriksen. All rights reserved.
+//
+
+#import "GCMutableNode.h"
+
+@interface GCMutableNode ()
+
+@property GCNode *parent;
+
+@end;
+
+@implementation GCMutableNode {
+ NSMutableArray *_subNodes;
+}
+
+#pragma mark Initialization
+
+- (id)init
+{
+ self = [super init];
+
+ if (self) {
+ [self setLineSeparator:@"\n"];
+ _subNodes = [NSMutableArray array];
+ }
+
+ return self;
+}
+
+#pragma mark Description
+
+- (NSString *)description
+{
+ return [NSString stringWithFormat:@"[GCMutableNode tag: %@ xref: %@ value: %@ (subNodes: %@)]", [self gedTag], [self xref], [self gedValue], [self subNodes]];
+}
+
+#pragma mark Adding subnodes
+
+- (void)addSubNode:(GCMutableNode *)node
+{
+ NSParameterAssert(self != node);
+ NSParameterAssert([node isKindOfClass:[GCMutableNode class]]);
+
+ if (!_subNodes) {
+ _subNodes = [NSMutableArray array];
+ }
+
+ [_subNodes addObject:node];
+ [node setParent:self];
+}
+
+- (void)addSubNodes:(NSArray *)subNodes
+{
+ for (id subNode in subNodes) {
+ [self addSubNode:subNode];
+ }
+}
+
+#pragma mark Objective-C properties
+
+@synthesize parent = _parent;
+@synthesize gedTag = _gedTag;
+@synthesize gedValue = _gedValue;
+@synthesize xref = _xref;
+@synthesize lineSeparator = _lineSeparator;
+@synthesize subNodes = _subNodes;
+
+@end
View
2 Gedcom/GCNode.h
@@ -8,7 +8,7 @@
#import <Foundation/Foundation.h>
-@interface GCNode : NSObject <NSCopying, NSCoding>
+@interface GCNode : NSObject <NSCopying, NSCoding, NSMutableCopying>
#pragma mark Initialization
View
45 Gedcom/GCNode.m
@@ -9,6 +9,8 @@
#import "GCNode.h"
#import "GCTag.h"
+#import "GCMutableNode.h"
+
@interface GCNode ()
- (void)addSubNode: (GCNode *) n;
@@ -32,29 +34,26 @@ @implementation GCNode {
- (id)init
{
- self = [super init];
-
- if (self) {
- [self setLineSeparator:@"\n"];
- _subNodes = [NSMutableArray arrayWithCapacity:2];
- }
-
- return self;
+ [self doesNotRecognizeSelector:_cmd];
+ return nil;
}
- (id)initWithTag:(NSString *)tag value:(NSString *)value xref:(NSString *)xref subNodes:(NSArray *)subNodes
{
NSParameterAssert(tag != nil);
- self = [self init];
+ self = [super init];
if (self) {
+ [self setLineSeparator:@"\n"];
[self setGedTag:tag];
[self setXref:xref];
[self setGedValue:value];
if (subNodes) {
_subNodes = [subNodes mutableCopy];
+ } else {
+ _subNodes = [NSMutableArray arrayWithCapacity:2];
}
}
@@ -312,7 +311,6 @@ - (void)addSubNodes:(NSArray *)a
- (NSString *)description
{
- //return [[self gedTag] code];
return [NSString stringWithFormat:@"[GCNode tag: %@ xref: %@ value: %@ (subNodes: %@)]", [self gedTag], [self xref], [self gedValue], [self subNodes]];
}
@@ -346,13 +344,30 @@ - (id)initWithCoder:(NSCoder *)decoder
- (id)copyWithZone:(NSZone *)zone
{
- GCNode *copy = [[GCNode allocWithZone:zone] init];
+ GCNode *copy = [[GCNode allocWithZone:zone] initWithTag:[self gedTag]
+ value:[self gedValue]
+ xref:[self xref]
+ subNodes:[self subNodes]];
- [copy setValue:[self gedTag] forKey:@"gedTag"];
- [copy setValue:[self gedValue] forKey:@"gedValue"];
- [copy setValue:[self xref] forKey:@"xref"];
[copy setValue:[self lineSeparator] forKey:@"lineSeparator"];
- [copy setValue:[self subNodes] forKey:@"subNodes"];
+
+ return copy;
+}
+
+#pragma mark NSMutableCopying conformance
+
+- (id)mutableCopyWithZone:(NSZone *)zone
+{
+ GCMutableNode *copy = [[GCMutableNode allocWithZone:zone] initWithTag:[self gedTag]
+ value:[self gedValue]
+ xref:[self xref]
+ subNodes:nil];
+
+ [copy setValue:[self lineSeparator] forKey:@"lineSeparator"];
+
+ for (id subNode in [self subNodes]) {
+ [copy addSubNode:[subNode mutableCopy]];
+ }
return copy;
}
View
5 Gedcom/Gedcom.h
@@ -7,6 +7,8 @@
//
#import "GCNode.h"
+#import "GCMutableNode.h"
+
#import "GCTag.h"
#import "GCContext.h"
@@ -22,3 +24,6 @@
#import "GCValue.h"
#import "GCAge.h"
#import "GCDate.h"
+
+#import "GCAgeFormatter.h"
+#import "GCDateFormatter.h"
View
12 GedcomTests/GCKeyValueTests.m
@@ -80,6 +80,18 @@ @interface GCKeyValueTests : SenTestCase
@implementation GCKeyValueTests
+-(void)testValueForKey
+{
+ GCNode *aNode = [GCNode nodeWithTag:@"NAME" value:@"Jens /Hansen/"];
+
+ GCNode *bNode = [[GCNode alloc] initWithTag:@"INDI"
+ value:nil
+ xref:@"@I1@"
+ subNodes:[NSArray arrayWithObject:aNode]];
+
+ STAssertEqualObjects(aNode, [bNode valueForKey:@"NAME"], nil);
+}
+
- (void)testKVC
{
GCContext *ctx = [GCContext context];
View
25 GedcomTests/GCNodeTests.m
@@ -72,16 +72,23 @@ -(void)testAllGed
[self testFile:path countShouldBe:18];
}
--(void)testValueForKey
+- (void)testMutableNode
{
- GCNode *aNode = [GCNode nodeWithTag:@"NAME" value:@"Jens /Hansen/"];
-
- GCNode *bNode = [[GCNode alloc] initWithTag:@"INDI"
- value:nil
- xref:@"@I1@"
- subNodes:[NSArray arrayWithObject:aNode]];
-
- STAssertEqualObjects(aNode, [bNode valueForKey:@"NAME"], nil);
+ GCNode *node = [GCNode nodeWithTag:@"NAME" value:@"Jens /Hansen/"];
+
+ GCMutableNode *mutableNode = [node mutableCopy];
+
+ [mutableNode setGedValue:@"Jens /Hansen/ Smed"];
+
+ STAssertEqualObjects([mutableNode gedValue], @"Jens /Hansen/ Smed", nil);
+
+ GCMutableNode *nickname = [GCMutableNode nodeWithTag:@"NICK" value:@"Smeden"];
+
+ STAssertEquals([[mutableNode subNodes] count], (NSUInteger)0, nil);
+
+ [mutableNode addSubNode:nickname];
+
+ STAssertEquals([[mutableNode subNodes] count], (NSUInteger)1, nil);
}
@end
View
1 README.md
@@ -27,7 +27,6 @@ The intent is to hide the GEDCOM specifics, but to allow access if required.
# TODO #
* **tags.json**: Currently only partially done
-* **GCMutableNode**: Mutable version of GCNode
* **appledocs**: and better comments & cleaner headers in general
* **GCObject**: NSCoding

0 comments on commit f770f9b

Please sign in to comment.
Something went wrong with that request. Please try again.