From: helge Date: Fri, 5 Aug 2005 10:21:11 +0000 (+0000) Subject: fixed decoding of arrays in kv archiver X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d7633bf34a4b4df966c93d74320676c55a178e4d;p=sope fixed decoding of arrays in kv archiver added 'selectorName' support in EOSortOrdering kv decoding added kv archiving to EODetailDataSource git-svn-id: http://svn.opengroupware.org/SOPE/trunk@974 e4a50df8-12e2-0310-a44c-efbce7f8a7e3 --- diff --git a/sope-core/EOControl/ChangeLog b/sope-core/EOControl/ChangeLog index 8039c15c..f6e8f381 100644 --- a/sope-core/EOControl/ChangeLog +++ b/sope-core/EOControl/ChangeLog @@ -1,5 +1,18 @@ +2005-08-05 Helge Hess + + * v4.5.58 + + * EODetailDataSource.m: added EOKeyValueArchiving + + * EOSortOrdering.m: use 'selectorName' instead of 'selector' for + kv archiving + + * EOKeyValueArchiver.m: fixed decoding of arrays + 2005-08-04 Helge Hess + * EOKeyValueArchiver.m: fixed a bug with decoding references (v4.5.57) + * EOKeyValueArchiver.m: print a warning if a class specified in the archive could not be found (v4.5.56) diff --git a/sope-core/EOControl/EODetailDataSource.h b/sope-core/EOControl/EODetailDataSource.h index 9cc939af..67e798a7 100644 --- a/sope-core/EOControl/EODetailDataSource.h +++ b/sope-core/EOControl/EODetailDataSource.h @@ -23,10 +23,11 @@ #define __EOControl_EODetailDataSource_H__ #include +#include @class EOClassDescription; -@interface EODetailDataSource : EODataSource +@interface EODetailDataSource : EODataSource < EOKeyValueArchiving > { EOClassDescription *masterClassDescription; EODataSource *masterDataSource; diff --git a/sope-core/EOControl/EODetailDataSource.m b/sope-core/EOControl/EODetailDataSource.m index b5ad8aae..764858cf 100644 --- a/sope-core/EOControl/EODetailDataSource.m +++ b/sope-core/EOControl/EODetailDataSource.m @@ -155,4 +155,31 @@ [eo removeObject:_object fromPropertyWithKey:dk]; } +/* key/value archiving */ + +- (id)initWithKeyValueUnarchiver:(EOKeyValueUnarchiver *)_unarchiver { + /* + dataSource = { + class = EODetailDataSource; + detailKey = roles; + masterClassDescription = Movie; + }; + */ + if ((self = [super init])) { + NSString *ename; + + self->detailKey = [[_unarchiver decodeObjectForKey:@"detailKey"] copy]; + + ename = [_unarchiver decodeObjectForKey:@"masterClassDescription"]; + NSLog(@"TODO(%s): set class description: %@", + __PRETTY_FUNCTION__, ename); + } + return self; +} +- (void)encodeWithKeyValueArchiver:(EOKeyValueArchiver *)_archiver { + [_archiver encodeObject:[self detailKey] forKey:@"detailKey"]; + [_archiver encodeObject:[[self masterClassDescription] entityName] + forKey:@"masterClassDescription"]; +} + @end /* EODetailDataSource */ diff --git a/sope-core/EOControl/EOKeyValueArchiver.h b/sope-core/EOControl/EOKeyValueArchiver.h index e451fc9e..a03bbd77 100644 --- a/sope-core/EOControl/EOKeyValueArchiver.h +++ b/sope-core/EOControl/EOKeyValueArchiver.h @@ -68,6 +68,8 @@ - (BOOL)decodeBoolForKey:(NSString *)_key; - (int)decodeIntForKey:(NSString *)_key; +- (id)decodeObjectAtIndex:(unsigned)_idx; + /* operations */ - (void)ensureObjectAwake:(id)_object; diff --git a/sope-core/EOControl/EOKeyValueArchiver.m b/sope-core/EOControl/EOKeyValueArchiver.m index f2eabf52..9b8b2fe5 100644 --- a/sope-core/EOControl/EOKeyValueArchiver.m +++ b/sope-core/EOControl/EOKeyValueArchiver.m @@ -112,12 +112,14 @@ static BOOL isPListObject(id _obj) { @end /* EOKeyValueArchiver */ + @implementation EOKeyValueUnarchiver - (id)initWithDictionary:(NSDictionary *)_dict { self->plist = [_dict copy]; - self->unarchivedObjects = [[NSMutableArray alloc] init]; - self->awakeObjects = [[NSMutableSet alloc] init]; // should be a hashtable + self->unarchivedObjects = [[NSMutableArray alloc] initWithCapacity:16]; + // should be a hashtable + self->awakeObjects = [[NSMutableSet alloc] initWithCapacity:16]; return self; } - (id)init { @@ -182,45 +184,93 @@ static BOOL isPListObject(id _obj) { /* decoding */ +- (id)_decodeCurrentPlist { + NSString *className; + Class clazz; + id obj; + + if ([self->plist isKindOfClass:[NSArray class]]) { + unsigned count; + + if ((count = [self->plist count]) == 0) + obj = [[self->plist copy] autorelease]; + else { + unsigned i; + id *objs; + + objs = calloc(count + 1, sizeof(id)); + for (i = 0; i < count; i++) + objs[i] = [self decodeObjectAtIndex:i]; + + obj = [NSArray arrayWithObjects:objs count:count]; + if (objs != NULL) free(objs); + } + return obj; + } + + if (![self->plist isKindOfClass:[NSDictionary class]]) + return [[self->plist copy] autorelease]; + + /* handle dictionary */ + + if ((className = [self->plist objectForKey:@"class"]) == nil) + return [[self->plist copy] autorelease]; /* treat as plain dictionary */ + + if ((clazz = [self classForName:className]) == nil) { + NSLog(@"WARNING(%s): did not find class specified in archive '%@': %@", + __PRETTY_FUNCTION__, className, self->plist); + return nil; + } + + /* create custom object */ + + obj = [clazz alloc]; + obj = [obj initWithKeyValueUnarchiver:self]; + + if (obj != nil) + [self->unarchivedObjects addObject:obj]; + else { + NSLog(@"WARNING(%s): could not unarchive object %@", + __PRETTY_FUNCTION__, self->plist); + } + if (self->unarchivedObjects != nil) + [obj release]; + else + [obj autorelease]; + + return obj; +} + +- (id)decodeObjectAtIndex:(unsigned)_idx { + NSDictionary *lastParent; + id obj; + + /* push */ + lastParent = self->parent; + self->parent = self->plist; + self->plist = [(NSArray *)self->parent objectAtIndex:_idx]; + + obj = [self _decodeCurrentPlist]; + + /* pop */ + self->plist = self->parent; + self->parent = lastParent; + + return obj ? obj : [NSNull null]; +} + - (id)decodeObjectForKey:(NSString *)_key { - NSString *className; NSDictionary *lastParent; id obj; + /* push */ lastParent = self->parent; self->parent = self->plist; self->plist = [(NSDictionary *)self->parent objectForKey:_key]; - if (![self->plist isKindOfClass:[NSDictionary class]]) { - obj = [[self->plist copy] autorelease]; - } - else if ((className = [self->plist objectForKey:@"class"]) != nil) { - Class clazz; - - if ((clazz = [self classForName:className]) != nil) { - obj = [clazz alloc]; - obj = [obj initWithKeyValueUnarchiver:self]; - - if (obj != nil) - [self->unarchivedObjects addObject:obj]; - else { - NSLog(@"WARNING(%s): could not unarchive object %@", - __PRETTY_FUNCTION__, self->plist); - } - if (self->unarchivedObjects != nil) - [obj release]; - else - [obj autorelease]; - } - else { - NSLog(@"WARNING(%s): did not find class specified in archive '%@': %@", - __PRETTY_FUNCTION__, className, self->plist); - } - } - else { - obj = nil; - } + obj = [self _decodeCurrentPlist]; + /* pop */ self->plist = self->parent; self->parent = lastParent; @@ -235,7 +285,8 @@ static BOOL isPListObject(id _obj) { @selector(unarchiver:objectForReference:)]) { obj = [self->delegate unarchiver:self objectForReference:refObj]; - [self->unarchivedObjects addObject:obj]; + if (obj != nil) + [self->unarchivedObjects addObject:obj]; } else { /* if delegate does not dereference, pass back the reference object */ @@ -266,7 +317,7 @@ static BOOL isPListObject(id _obj) { id obj; e = [self->unarchivedObjects objectEnumerator]; - while ((obj = [e nextObject])) + while ((obj = [e nextObject]) != nil) [self ensureObjectAwake:obj]; } @@ -275,7 +326,7 @@ static BOOL isPListObject(id _obj) { id obj; e = [self->unarchivedObjects objectEnumerator]; - while ((obj = [e nextObject])) { + while ((obj = [e nextObject]) != nil) { if ([obj respondsToSelector: @selector(finishInitializationWithKeyValueUnarchiver:)]) [obj finishInitializationWithKeyValueUnarchiver:self]; diff --git a/sope-core/EOControl/EOSortOrdering.m b/sope-core/EOControl/EOSortOrdering.m index 93d2c01d..3dd7e00c 100644 --- a/sope-core/EOControl/EOSortOrdering.m +++ b/sope-core/EOControl/EOSortOrdering.m @@ -121,16 +121,23 @@ EOControl_DECLARE SEL EOCompareCaseInsensitiveDescending = - (id)initWithKeyValueUnarchiver:(EOKeyValueUnarchiver *)_unarchiver { if ((self = [super init]) != nil) { + NSString *s; + self->key = [[_unarchiver decodeObjectForKey:@"key"] copy]; - self->selector = - NSSelectorFromString([_unarchiver decodeObjectForKey:@"selector"]); + + if ((s = [_unarchiver decodeObjectForKey:@"selector"]) != nil) + self->selector = NSSelectorFromString(s); + else if ((s = [_unarchiver decodeObjectForKey:@"selectorName"]) != nil) { + if (![s hasSuffix:@":"]) s = [s stringByAppendingString:@":"]; + self->selector = NSSelectorFromString(s); + } } return self; } - (void)encodeWithKeyValueArchiver:(EOKeyValueArchiver *)_archiver { [_archiver encodeObject:[self key] forKey:@"key"]; [_archiver encodeObject:NSStringFromSelector([self selector]) - forKey:@"selector"]; + forKey:@"selectorName"]; } /* description */ diff --git a/sope-core/EOControl/Version b/sope-core/EOControl/Version index 0d71e766..31494853 100644 --- a/sope-core/EOControl/Version +++ b/sope-core/EOControl/Version @@ -1,3 +1,3 @@ # version file -SUBMINOR_VERSION:=56 +SUBMINOR_VERSION:=58