Implemented keyed decoding for this classes.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@18491 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Fred Kiefer 2004-01-27 21:51:33 +00:00
parent bace205183
commit cb7a4b0777
8 changed files with 299 additions and 183 deletions

View file

@ -1,3 +1,14 @@
2004-01-27 Fred Kiefer <FredKiefer@gmx.de>
* Source/GSArray.m:
* Source/NSArray.m:
* Source/GSSet.m:
* Source/NSSet.m:
* Source/GSDictionary.m:
* Source/NSDictionary.m:
* Source/NSString.m:
Implemented keyed decoding in [initWithCoder:].
2004-01-27 Richard Frith-Macdonald <rfm@gnu.org>
* Headers/Foundation/NSKeyedArchiver.h: Expose internals a bit.

View file

@ -32,6 +32,8 @@
#include "Foundation/NSPortCoder.h"
#include "Foundation/NSDebug.h"
#include "Foundation/NSValue.h"
// For private method _decodeArrayOfObjectsForKey:
#include "Foundation/NSKeyedArchiver.h"
static SEL eqSel;
static SEL oaiSel;
@ -178,19 +180,29 @@ static Class GSInlineArrayClass;
- (id) initWithCoder: (NSCoder*)aCoder
{
[aCoder decodeValueOfObjCType: @encode(unsigned)
at: &_count];
if (_count > 0)
if ([aCoder allowsKeyedCoding])
{
_contents_array = NSZoneCalloc([self zone], _count, sizeof(id));
if (_contents_array == 0)
{
[NSException raise: NSMallocException
format: @"Unable to make array"];
}
[aCoder decodeArrayOfObjCType: @encode(id)
count: _count
at: _contents_array];
NSArray *array = [(NSKeyedUnarchiver*)aCoder _decodeArrayOfObjectsForKey:
@"NS.objects"];
[self initWithArray: array];
}
else
{
[aCoder decodeValueOfObjCType: @encode(unsigned)
at: &_count];
if (_count > 0)
{
_contents_array = NSZoneCalloc([self zone], _count, sizeof(id));
if (_contents_array == 0)
{
[NSException raise: NSMallocException
format: @"Unable to make array"];
}
[aCoder decodeArrayOfObjCType: @encode(id)
count: _count
at: _contents_array];
}
}
return self;
}
@ -462,21 +474,31 @@ static Class GSInlineArrayClass;
- (id) initWithCoder: (NSCoder*)aCoder
{
unsigned count;
if ([aCoder allowsKeyedCoding])
{
NSArray *array = [(NSKeyedUnarchiver*)aCoder _decodeArrayOfObjectsForKey:
@"NS.objects"];
[aCoder decodeValueOfObjCType: @encode(unsigned)
at: &count];
if ((self = [self initWithCapacity: count]) == nil)
{
[NSException raise: NSMallocException
format: @"Unable to make array while initializing from coder"];
[self initWithArray: array];
}
if (count > 0)
else
{
[aCoder decodeArrayOfObjCType: @encode(id)
count: count
at: _contents_array];
_count = count;
unsigned count;
[aCoder decodeValueOfObjCType: @encode(unsigned)
at: &count];
if ((self = [self initWithCapacity: count]) == nil)
{
[NSException raise: NSMallocException
format: @"Unable to make array while initializing from coder"];
}
if (count > 0)
{
[aCoder decodeArrayOfObjCType: @encode(id)
count: count
at: _contents_array];
_count = count;
}
}
return self;
}
@ -988,20 +1010,30 @@ static Class GSInlineArrayClass;
- (id) initWithCoder: (NSCoder*)aCoder
{
GSInlineArray *a;
unsigned c;
[aCoder decodeValueOfObjCType: @encode(unsigned) at: &c];
a = (id)NSAllocateObject(GSInlineArrayClass, sizeof(id)*c, GSObjCZone(self));
a->_contents_array = (id*)&a[1];
if (c > 0)
if ([aCoder allowsKeyedCoding])
{
[aCoder decodeArrayOfObjCType: @encode(id)
count: c
at: a->_contents_array];
NSArray *array = [(NSKeyedUnarchiver*)aCoder _decodeArrayOfObjectsForKey:
@"NS.objects"];
return array;
}
else
{
GSInlineArray *a;
unsigned c;
[aCoder decodeValueOfObjCType: @encode(unsigned) at: &c];
a = (id)NSAllocateObject(GSInlineArrayClass, sizeof(id)*c, GSObjCZone(self));
a->_contents_array = (id*)&a[1];
if (c > 0)
{
[aCoder decodeArrayOfObjCType: @encode(id)
count: c
at: a->_contents_array];
}
a->_count = c;
return a;
}
a->_count = c;
return a;
}
- (id) initWithObjects: (id*)objects count: (unsigned)count

View file

@ -30,6 +30,8 @@
#include "Foundation/NSException.h"
#include "Foundation/NSPortCoder.h"
#include "Foundation/NSDebug.h"
// For private method _decodeArrayOfObjectsForKey:
#include "Foundation/NSKeyedArchiver.h"
#include "GNUstepBase/GSObjCRuntime.h"
@ -125,22 +127,34 @@ static SEL objSel;
- (id) initWithCoder: (NSCoder*)aCoder
{
unsigned count;
id key;
id value;
SEL sel = @selector(decodeValueOfObjCType:at:);
IMP imp = [aCoder methodForSelector: sel];
const char *type = @encode(id);
[aCoder decodeValueOfObjCType: @encode(unsigned)
at: &count];
GSIMapInitWithZoneAndCapacity(&map, GSObjCZone(self), count);
while (count-- > 0)
if ([aCoder allowsKeyedCoding])
{
(*imp)(aCoder, sel, type, &key);
(*imp)(aCoder, sel, type, &value);
GSIMapAddPairNoRetain(&map, (GSIMapKey)key, (GSIMapVal)value);
NSArray *keys = [(NSKeyedUnarchiver*)aCoder _decodeArrayOfObjectsForKey:
@"NS.keys"];
NSArray *objects = [(NSKeyedUnarchiver*)aCoder _decodeArrayOfObjectsForKey:
@"NS.objects"];
self = [self initWithObjects: objects forKeys: keys];
}
else
{
unsigned count;
id key;
id value;
SEL sel = @selector(decodeValueOfObjCType:at:);
IMP imp = [aCoder methodForSelector: sel];
const char *type = @encode(id);
[aCoder decodeValueOfObjCType: @encode(unsigned)
at: &count];
GSIMapInitWithZoneAndCapacity(&map, GSObjCZone(self), count);
while (count-- > 0)
{
(*imp)(aCoder, sel, type, &key);
(*imp)(aCoder, sel, type, &value);
GSIMapAddPairNoRetain(&map, (GSIMapKey)key, (GSIMapVal)value);
}
}
return self;
}

View file

@ -33,6 +33,8 @@
#include "Foundation/NSPortCoder.h"
#include "Foundation/NSDebug.h"
#include "Foundation/NSObjCRuntime.h"
// For private method _decodeArrayOfObjectsForKey:
#include "Foundation/NSKeyedArchiver.h"
#define GSI_MAP_HAS_VALUE 0
#define GSI_MAP_KTYPES GSUNION_OBJ
@ -187,22 +189,32 @@ static Class mutableSetClass;
- (id) initWithCoder: (NSCoder*)aCoder
{
unsigned count;
id value;
SEL sel = @selector(decodeValueOfObjCType:at:);
IMP imp = [aCoder methodForSelector: sel];
const char *type = @encode(id);
(*imp)(aCoder, sel, @encode(unsigned), &count);
GSIMapInitWithZoneAndCapacity(&map, [self zone], count);
while (count-- > 0)
if ([aCoder allowsKeyedCoding])
{
(*imp)(aCoder, sel, type, &value);
GSIMapAddKeyNoRetain(&map, (GSIMapKey)value);
}
NSArray *array = [(NSKeyedUnarchiver*)aCoder _decodeArrayOfObjectsForKey:
@"NS.objects"];
return self;
return [self initWithArray: array];
}
else
{
unsigned count;
id value;
SEL sel = @selector(decodeValueOfObjCType:at:);
IMP imp = [aCoder methodForSelector: sel];
const char *type = @encode(id);
(*imp)(aCoder, sel, @encode(unsigned), &count);
GSIMapInitWithZoneAndCapacity(&map, [self zone], count);
while (count-- > 0)
{
(*imp)(aCoder, sel, type, &value);
GSIMapAddKeyNoRetain(&map, (GSIMapKey)value);
}
return self;
}
}
/* Designated initialiser */

View file

@ -45,6 +45,8 @@
#include "Foundation/NSDebug.h"
#include "Foundation/NSValue.h"
#include "Foundation/NSNull.h"
// For private method _decodeArrayOfObjectsForKey:
#include "Foundation/NSKeyedArchiver.h"
#include "GNUstepBase/GSCategories.h"
#include "GSPrivate.h"
@ -552,29 +554,39 @@ static SEL rlSel;
*/
- (id) initWithCoder: (NSCoder*)aCoder
{
unsigned count;
[aCoder decodeValueOfObjCType: @encode(unsigned)
at: &count];
if (count > 0)
if ([aCoder allowsKeyedCoding])
{
GS_BEGINIDBUF(contents, count)
NSArray *array = [(NSKeyedUnarchiver*)aCoder _decodeArrayOfObjectsForKey:
@"NS.objects"];
[aCoder decodeArrayOfObjCType: @encode(id)
count: count
at: contents];
self = [self initWithObjects: contents count: count];
#if GS_WITH_GC == 0
while (count-- > 0)
{
[contents[count] release];
}
#endif
GS_ENDIDBUF()
[self initWithArray: array];
}
else
{
self = [self initWithObjects: 0 count: 0];
unsigned count;
[aCoder decodeValueOfObjCType: @encode(unsigned)
at: &count];
if (count > 0)
{
GS_BEGINIDBUF(contents, count)
[aCoder decodeArrayOfObjCType: @encode(id)
count: count
at: contents];
self = [self initWithObjects: contents count: count];
#if GS_WITH_GC == 0
while (count-- > 0)
{
[contents[count] release];
}
#endif
GS_ENDIDBUF()
}
else
{
self = [self initWithObjects: 0 count: 0];
}
}
return self;
}

View file

@ -38,6 +38,8 @@
#include "Foundation/NSDebug.h"
#include "Foundation/NSObjCRuntime.h"
#include "Foundation/NSValue.h"
// For private method _decodeArrayOfObjectsForKey:
#include "Foundation/NSKeyedArchiver.h"
#include "GNUstepBase/GSCategories.h"
#include "GSPrivate.h"
@ -203,27 +205,38 @@ static SEL appSel;
- (id) initWithCoder: (NSCoder*)aCoder
{
unsigned count;
[aCoder decodeValueOfObjCType: @encode(unsigned) at: &count];
if (count > 0)
if ([aCoder allowsKeyedCoding])
{
id *keys = NSZoneMalloc(NSDefaultMallocZone(), sizeof(id)*count);
id *vals = NSZoneMalloc(NSDefaultMallocZone(), sizeof(id)*count);
unsigned i;
IMP dec;
NSArray *keys = [(NSKeyedUnarchiver*)aCoder _decodeArrayOfObjectsForKey:
@"NS.keys"];
NSArray *objects = [(NSKeyedUnarchiver*)aCoder _decodeArrayOfObjectsForKey:
@"NS.objects"];
dec = [aCoder methodForSelector: @selector(decodeObject)];
for (i = 0; i < count; i++)
{
keys[i] = (*dec)(aCoder, @selector(decodeObject));
vals[i] = (*dec)(aCoder, @selector(decodeObject));
}
self = [self initWithObjects: vals forKeys: keys count: count];
NSZoneFree(NSDefaultMallocZone(), keys);
NSZoneFree(NSDefaultMallocZone(), vals);
self = [self initWithObjects: objects forKeys: keys];
}
else
{
unsigned count;
[aCoder decodeValueOfObjCType: @encode(unsigned) at: &count];
if (count > 0)
{
id *keys = NSZoneMalloc(NSDefaultMallocZone(), sizeof(id)*count);
id *vals = NSZoneMalloc(NSDefaultMallocZone(), sizeof(id)*count);
unsigned i;
IMP dec;
dec = [aCoder methodForSelector: @selector(decodeObject)];
for (i = 0; i < count; i++)
{
keys[i] = (*dec)(aCoder, @selector(decodeObject));
vals[i] = (*dec)(aCoder, @selector(decodeObject));
}
self = [self initWithObjects: vals forKeys: keys count: count];
NSZoneFree(NSDefaultMallocZone(), keys);
NSZoneFree(NSDefaultMallocZone(), vals);
}
}
return self;
}

View file

@ -33,6 +33,8 @@
#include "Foundation/NSException.h"
#include "Foundation/NSObjCRuntime.h"
#include "Foundation/NSDebug.h"
// For private method _decodeArrayOfObjectsForKey:
#include "Foundation/NSKeyedArchiver.h"
#include "GNUstepBase/GSCategories.h"
@class GSSet;
@ -150,7 +152,6 @@ static Class NSMutableSet_concrete_class;
- (id) initWithCoder: (NSCoder*)aCoder
{
unsigned count;
Class c;
c = GSObjCClass(self);
@ -167,25 +168,37 @@ static Class NSMutableSet_concrete_class;
return [self initWithCoder: aCoder];
}
[aCoder decodeValueOfObjCType: @encode(unsigned) at: &count];
if (count > 0)
if ([aCoder allowsKeyedCoding])
{
id objs[count];
unsigned i;
NSArray *array = [(NSKeyedUnarchiver*)aCoder _decodeArrayOfObjectsForKey:
@"NS.objects"];
for (i = 0; i < count; i++)
{
[aCoder decodeValueOfObjCType: @encode(id) at: &objs[i]];
}
self = [self initWithObjects: objs count: count];
#if GS_WITH_GC == 0
while (count-- > 0)
{
[objs[count] release];
}
#endif
return [self initWithArray: array];
}
else
{
unsigned count;
[aCoder decodeValueOfObjCType: @encode(unsigned) at: &count];
if (count > 0)
{
id objs[count];
unsigned i;
for (i = 0; i < count; i++)
{
[aCoder decodeValueOfObjCType: @encode(id) at: &objs[i]];
}
self = [self initWithObjects: objs count: count];
#if GS_WITH_GC == 0
while (count-- > 0)
{
[objs[count] release];
}
#endif
}
return self;
}
return self;
}
/* <init />

View file

@ -3880,77 +3880,86 @@ handle_printf_atsign (FILE *stream,
- (id) initWithCoder: (NSCoder*)aCoder
{
unsigned count;
[aCoder decodeValueOfObjCType: @encode(unsigned int) at: &count];
if (count > 0)
if ([aCoder allowsKeyedCoding])
{
NSStringEncoding enc;
NSZone *zone;
NSString *string = [aCoder decodeObjectForKey: @"NS.string"];
[aCoder decodeValueOfObjCType: @encode(NSStringEncoding) at: &enc];
#if GS_WITH_GC
zone = GSAtomicMallocZone();
#else
zone = GSObjCZone(self);
#endif
if (enc == NSUnicodeStringEncoding)
{
unichar *chars;
chars = NSZoneMalloc(zone, count*sizeof(unichar));
[aCoder decodeArrayOfObjCType: @encode(unichar)
count: count
at: chars];
self = [self initWithCharactersNoCopy: chars
length: count
freeWhenDone: YES];
}
else if (enc == NSASCIIStringEncoding
|| enc == _DefaultStringEncoding)
{
unsigned char *chars;
chars = NSZoneMalloc(zone, count+1);
[aCoder decodeArrayOfObjCType: @encode(unsigned char)
count: count
at: chars];
self = [self initWithCStringNoCopy: chars
length: count
freeWhenDone: YES];
}
else if (enc == NSUTF8StringEncoding)
{
unsigned char *chars;
chars = NSZoneMalloc(zone, count+1);
[aCoder decodeArrayOfObjCType: @encode(unsigned char)
count: count
at: chars];
chars[count] = '\0';
self = [self initWithUTF8String: chars];
NSZoneFree(zone, chars);
}
else
{
unsigned char *chars;
NSData *data;
chars = NSZoneMalloc(zone, count);
[aCoder decodeArrayOfObjCType: @encode(unsigned char)
count: count
at: chars];
data = [NSDataClass allocWithZone: zone];
data = [data initWithBytesNoCopy: chars length: count];
self = [self initWithData: data encoding: enc];
RELEASE(data);
}
self = [self initWithString: string];
}
else
{
self = [self initWithCStringNoCopy: "" length: 0 freeWhenDone: NO];
unsigned count;
[aCoder decodeValueOfObjCType: @encode(unsigned int) at: &count];
if (count > 0)
{
NSStringEncoding enc;
NSZone *zone;
[aCoder decodeValueOfObjCType: @encode(NSStringEncoding) at: &enc];
#if GS_WITH_GC
zone = GSAtomicMallocZone();
#else
zone = GSObjCZone(self);
#endif
if (enc == NSUnicodeStringEncoding)
{
unichar *chars;
chars = NSZoneMalloc(zone, count*sizeof(unichar));
[aCoder decodeArrayOfObjCType: @encode(unichar)
count: count
at: chars];
self = [self initWithCharactersNoCopy: chars
length: count
freeWhenDone: YES];
}
else if (enc == NSASCIIStringEncoding
|| enc == _DefaultStringEncoding)
{
unsigned char *chars;
chars = NSZoneMalloc(zone, count+1);
[aCoder decodeArrayOfObjCType: @encode(unsigned char)
count: count
at: chars];
self = [self initWithCStringNoCopy: chars
length: count
freeWhenDone: YES];
}
else if (enc == NSUTF8StringEncoding)
{
unsigned char *chars;
chars = NSZoneMalloc(zone, count+1);
[aCoder decodeArrayOfObjCType: @encode(unsigned char)
count: count
at: chars];
chars[count] = '\0';
self = [self initWithUTF8String: chars];
NSZoneFree(zone, chars);
}
else
{
unsigned char *chars;
NSData *data;
chars = NSZoneMalloc(zone, count);
[aCoder decodeArrayOfObjCType: @encode(unsigned char)
count: count
at: chars];
data = [NSDataClass allocWithZone: zone];
data = [data initWithBytesNoCopy: chars length: count];
self = [self initWithData: data encoding: enc];
RELEASE(data);
}
}
else
{
self = [self initWithCStringNoCopy: "" length: 0 freeWhenDone: NO];
}
}
return self;
}