Skip to content

Commit

Permalink
Bolted rudimentary unarchiver into BMOEDNReader. Added tests. (closes #…
Browse files Browse the repository at this point in the history
  • Loading branch information
benmosher committed Jul 13, 2014
1 parent bbbf62c commit 1c98bcb
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 10 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Tagged elements (such as the built-in `uuid` and `inst`) may be converted to con

'Unknown' tagged elements will be converted to/from `BMOEDNTaggedElement` during de/serialization.

Objects that implement keyed `NSCoding` will be written out as a map tagged with `#edn-objc/[the class name]`, but are currently read in as `BMOEDNTaggedElement`.
Objects that implement keyed `NSCoding` will be written out as a map tagged with `#edn-objc/[the class name]`. Objects serialized this way may also be reconstituted at read time. Secure decoding is not yet supported.

Numbers are read exclusively into `NSDecimalNumber` and seem to afford around 128 bits of mantissa. So far, no support for arbitrary precision integers. Ratios are also supported by default, but disabled in 'strict' mode.

Expand Down
14 changes: 12 additions & 2 deletions edn-objc-tests/NSCodingBar.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,18 @@ -(void)encodeWithCoder:(NSCoder *)aCoder {
}

-(id)initWithCoder:(NSCoder *)aDecoder {
// NOOP ATM
return nil;
if (self = [super init]){
_array = [aDecoder decodeObjectForKey:@"array"];
_dict = [aDecoder decodeObjectForKey:@"dict"];
}
return self;
}

-(BOOL)isEqual:(id)object {
if (![object isMemberOfClass:[NSCodingBar class]]) return false;
return
(_array == [object array] || [_array isEqual:[object array]]) &&
(_dict == [object dict] || [_dict isEqual:[object dict]]);
}

@end
16 changes: 14 additions & 2 deletions edn-objc-tests/NSCodingFoo.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,20 @@ -(void)encodeWithCoder:(NSCoder *)aCoder {
}

-(id)initWithCoder:(NSCoder *)aDecoder {
// NOOP ATM
return nil;
if (self = [super init]) {
_a = [aDecoder decodeIntegerForKey:@"a"];
_b = [aDecoder decodeObjectForKey:@"b"];
_bar = [aDecoder decodeObjectForKey:@"bar"];
}
return self;
}

-(BOOL)isEqual:(id)object {
if (![object isMemberOfClass:[NSCodingFoo class]]) return false;
return
[object a] == _a &&
[_b isEqualToString:[object b]] &&
[_bar isEqual:[object bar]];
}

@end
21 changes: 21 additions & 0 deletions edn-objc-tests/edn-objc-tests.m
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,12 @@ - (void)testWriteNSData {
STAssertEqualObjects([anonData ednString], expected, @"");
}

- (void)testReadNSData {
NSData *anonData = [[NSData alloc] initWithBase64EncodedString:@"KMaSIFt4IHldICjGkiAoKyB4IHkpKSk=" options:0];
id roundTripped = [[anonData ednString] ednObject];
STAssertEqualObjects(anonData, roundTripped, @"");
}

- (void)testWriteArbitraryNSCoding {
NSCodingFoo *foo = [NSCodingFoo new];
foo.a = 42;
Expand All @@ -668,4 +674,19 @@ - (void)testWriteArbitraryNSCoding {
NSString *expected = @"#edn-objc/NSCodingFoo { :a 42 :b \"life, the universe, everything\" :bar #edn-objc/NSCodingBar { :array [ 3 2 1 ] :dict nil } }";
STAssertEqualObjects([foo ednString], expected, @"");
}

- (void)testReadArbitraryNSCoding {
NSCodingFoo *foo = [NSCodingFoo new];
foo.a = 42;
foo.b = @"life, the universe, everything";

NSCodingBar *bar = [NSCodingBar new];
bar.array = @[@3, @2, @1];

foo.bar = bar;

id roundTripped = [[foo ednString] ednObject];
STAssertEqualObjects(foo, roundTripped, @"");
}

@end
9 changes: 8 additions & 1 deletion edn-objc/BMOEDNReader.m
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#import "BMOEDNError.h"
#import "BMOEDNRatio.h"

#import "BMOEDNUnarchiver.h"

static NSCharacterSet *whitespace,*quoted,*numberPrefix,*digits,*symbolChars,*delimiters;

@interface BMOEDNReader () {
Expand Down Expand Up @@ -248,13 +250,18 @@ -(id)parseTaggedObject:(id<BMOEDNReaderState>)parserState {
&& [symbolChars characterIsMember:parserState.currentCharacter]) {
[parserState moveAhead];
}
id tag = BMOParseSymbolType(parserState,[BMOEDNSymbol class]);
BMOEDNSymbol *tag = BMOParseSymbolType(parserState,[BMOEDNSymbol class]);
if (parserState.error) return nil;

id innards = [self parseObject:parserState];
if (parserState.error) return nil;
BMOEDNTaggedElement *taggedElement = [[BMOEDNTaggedElement alloc] initWithTag:tag element:innards];

if ([tag.ns isEqualToString:@"edn-objc"]) {
BMOEDNUnarchiver *unarchie = [[BMOEDNUnarchiver alloc] initForReadingWithTaggedElement:taggedElement];
return [unarchie decodeRootObject];
}

// check for fanciness
Class registeredClass;
BMOEDNTransmogrifier transmogrifier;
Expand Down
9 changes: 5 additions & 4 deletions edn-objc/BMOEDNUnarchiver.m
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@ -(instancetype)initForReadingWithTaggedElement:(BMOEDNTaggedElement *)data {
return self;
}

-(NSData *)decodeDataObject {
Class rootClass = NSClassFromString(_data.tag.name);
return [[rootClass alloc] initWithBase64EncodedString:_data.element options:0];
}

-(id)decodeRootObject {
Class rootClass = NSClassFromString(_data.tag.name);
if ([rootClass isKindOfClass:[NSData class]]){
return [[rootClass alloc] initWithBase64EncodedString:_data.element options:0];
}
// TODO: check that tagged element is a map
return [[rootClass alloc] initWithCoder:self];
}

Expand Down

0 comments on commit 1c98bcb

Please sign in to comment.