Class cluster and encoding/decoding fixes.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@7825 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
richard 2000-10-16 12:35:42 +00:00
parent 1770f4dc78
commit 65241c052d
12 changed files with 276 additions and 178 deletions

View file

@ -1,3 +1,31 @@
2000-10-16 Richard Frith-Macdonald <rfm@gnu.org>
Attempts to make sure that when members of a class cluster are encoded
(either for archiving or for sending over DO), they are encoded as
the abstract class hiding the other classes in the cluster - this
should mean that (in future) changes in the private concrete classes
used should not effect existing archives and running DO applications.
* Source/NSDate.m: Implement -classForCoder to encode as the
abstract class. Implement ([-encodeWithCoder:]) and ([-initWithCoder:])
in abstract class.
* Source/NSDictionary.m: Implement -classForCoder to encode as the
abstract class. Implement ([-encodeWithCoder:]) and ([-initWithCoder:])
in abstract class.
* Source/NSArray.m: Implement -classForCoder to encode as the abstract
class.
* Source/NSAttributedString.m: Implement -classForCoder to encode as
the abstract class. Implement ([-encodeWithCoder:]) and
([-initWithCoder:]) in abstract class.
* Source/NSGAttributedString.m: Remove coding/encoding stuff - now done
in abstract class.
* Source/NSNumber.m: Implement -classForCoder to encode numbers as the
abstract class.
Modified ([-encodeWithCoder:]) and ([-initWithCoder:]) to encode objc
type when encoding as abstract class.
* Source/NSConcreteNumber.m: Modified encoding method to mirror
abstract class method. Old ([-initWithCoder:]) method retained to
decode old format records from archives.
2000-10-11 Adam Fedor <fedor@gnu.org> 2000-10-11 Adam Fedor <fedor@gnu.org>
* Source/NSObject.m (+initialize): Initialize Window sockets * Source/NSObject.m (+initialize): Initialize Window sockets

View file

@ -137,6 +137,11 @@ static SEL rlSel = @selector(removeLastObject);
/* The NSCoding Protocol */ /* The NSCoding Protocol */
- (Class) classForCoder
{
return NSArray_abstract_class;
}
- (void) encodeWithCoder: (NSCoder*)aCoder - (void) encodeWithCoder: (NSCoder*)aCoder
{ {
unsigned count = [self count]; unsigned count = [self count];
@ -802,6 +807,11 @@ static NSString *indentStrings[] = {
} }
} }
- (Class) classForCoder
{
return NSMutableArray_abstract_class;
}
/* The NSCopying Protocol */ /* The NSCopying Protocol */
- (id) copyWithZone: (NSZone*)zone - (id) copyWithZone: (NSZone*)zone

View file

@ -117,20 +117,73 @@ static Class NSMutableAttributedString_concrete_class;
return NSAllocateObject(self, 0, z); return NSAllocateObject(self, 0, z);
} }
- (Class) classForCoder
{
return NSAttributedString_abstract_class;
}
- (void) encodeWithCoder: (NSCoder*)aCoder - (void) encodeWithCoder: (NSCoder*)aCoder
{ {
[self subclassResponsibility: _cmd]; NSRange r = NSMakeRange(0, 0);
unsigned index = NSMaxRange(r);
unsigned length = [self length];
NSString *string = [self string];
NSDictionary *attrs;
[aCoder encodeObject: string];
while (index < length)
{
attrs = [self attributesAtIndex: index effectiveRange: &r];
index = NSMaxRange(r);
[aCoder encodeValueOfObjCType: @encode(unsigned int) at: &index];
[aCoder encodeObject: attrs];
}
} }
- (id) initWithCoder: (NSCoder*)aDecoder - (id) initWithCoder: (NSCoder*)aDecoder
{ {
[self subclassResponsibility: _cmd]; NSString *string = [aDecoder decodeObject];
return nil; unsigned length = [string length];
}
- (Class) classForPortCoder if (length == 0)
{ {
return [self class]; self = [self initWithString: string attributes: nil];
}
else
{
unsigned index;
NSDictionary *attrs;
[aDecoder decodeValueOfObjCType: @encode(unsigned int) at: &index];
attrs = [aDecoder decodeObject];
if (index == length)
{
self = [self initWithString: string attributes: attrs];
}
else
{
NSRange r = NSMakeRange(0, index);
unsigned last = index;
NSMutableAttributedString *m;
m = [NSMutableAttributedString alloc];
m = [m initWithString: string attributes: nil];
[m setAttributes: attrs range: r];
while (index < length);
{
[aDecoder decodeValueOfObjCType: @encode(unsigned int)
at: &index];
attrs = [aDecoder decodeObject];
r = NSMakeRange(last, index - last);
[m setAttributes: attrs range: r];
last = index;
}
RELEASE(self);
self = [m copy];
RELEASE(m);
}
}
return self;
} }
- (id) replacementObjectForPortCoder: (NSPortCoder*)aCoder - (id) replacementObjectForPortCoder: (NSPortCoder*)aCoder
@ -473,7 +526,7 @@ static Class NSMutableAttributedString_concrete_class;
@implementation NSMutableAttributedString @implementation NSMutableAttributedString
+ allocWithZone: (NSZone*)z + (id) allocWithZone: (NSZone*)z
{ {
if (self == NSMutableAttributedString_abstract_class) if (self == NSMutableAttributedString_abstract_class)
return NSAllocateObject(NSMutableAttributedString_concrete_class, 0, z); return NSAllocateObject(NSMutableAttributedString_concrete_class, 0, z);
@ -481,6 +534,52 @@ static Class NSMutableAttributedString_concrete_class;
return NSAllocateObject(self, 0, z); return NSAllocateObject(self, 0, z);
} }
- (Class) classForCoder
{
return NSMutableAttributedString_abstract_class;
}
- (id) initWithCoder: (NSCoder*)aDecoder
{
NSString *string = [aDecoder decodeObject];
unsigned length = [string length];
if (length == 0)
{
self = [self initWithString: string attributes: nil];
}
else
{
unsigned index;
NSDictionary *attrs;
[aDecoder decodeValueOfObjCType: @encode(unsigned int) at: &index];
attrs = [aDecoder decodeObject];
if (index == length)
{
self = [self initWithString: string attributes: attrs];
}
else
{
NSRange r = NSMakeRange(0, index);
unsigned last = index;
self = [self initWithString: string attributes: nil];
[self setAttributes: attrs range: r];
while (index < length);
{
[aDecoder decodeValueOfObjCType: @encode(unsigned int)
at: &index];
attrs = [aDecoder decodeObject];
r = NSMakeRange(last, index - last);
[self setAttributes: attrs range: r];
last = index;
}
}
}
return self;
}
//Retrieving character information //Retrieving character information
- (NSMutableString*) mutableString - (NSMutableString*) mutableString
{ {

View file

@ -175,7 +175,7 @@ GSTime(int day, int month, int year, int h, int m, int s)
return newObj; return newObj;
} }
- (Class) classForPortCoder - (Class) classForCoder
{ {
return [self class]; return [self class];
} }

View file

@ -439,23 +439,23 @@
} }
// NSCoding // NSCoding
- (Class) classForCoder
{
return [self class];
}
- (id) replacementObjectForPortCoder: (NSPortCoder*)aCoder
{
if ([aCoder isByref] == NO)
return self;
return [super replacementObjectForPortCoder: aCoder];
}
/*
* Exact mirror of NSNumber abstract class coding method.
*/
- (void) encodeWithCoder: (NSCoder*)coder - (void) encodeWithCoder: (NSCoder*)coder
{ {
[coder encodeValueOfObjCType: @encode(TYPE_TYPE) at: &data]; const char *t = @encode(TYPE_TYPE);
[coder encodeValueOfObjCType: @encode(char) at: t];
[coder encodeValueOfObjCType: t at: &data];
} }
/*
* NSNumber objects should have been encoded with their class set to the
* abstract class. If they haven't then we must be encoding from an old
* archive, so we must implement the old initWithCoder: method.
*/
- (id) initWithCoder: (NSCoder*)coder - (id) initWithCoder: (NSCoder*)coder
{ {
[coder decodeValueOfObjCType: @encode(TYPE_TYPE) at: &data]; [coder decodeValueOfObjCType: @encode(TYPE_TYPE) at: &data];

View file

@ -1913,23 +1913,11 @@ failure:
return self; return self;
} }
/* NSCoding */
- (Class) classForArchiver
{
return dataMalloc; /* Will not be static data when decoded. */
}
- (Class) classForCoder - (Class) classForCoder
{ {
return dataMalloc; /* Will not be static data when decoded. */ return dataMalloc; /* Will not be static data when decoded. */
} }
- (Class) classForPortCoder
{
return dataMalloc; /* Will not be static data when decoded. */
}
/* Basic methods */ /* Basic methods */
- (const void*) bytes - (const void*) bytes
@ -2510,21 +2498,11 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
return (NSData*)NSAllocateObject(mutableDataMalloc, 0, z); return (NSData*)NSAllocateObject(mutableDataMalloc, 0, z);
} }
- (Class) classForArchiver
{
return mutableDataMalloc;
}
- (Class) classForCoder - (Class) classForCoder
{ {
return mutableDataMalloc; return mutableDataMalloc;
} }
- (Class) classForPortCoder
{
return mutableDataMalloc;
}
- (id) copy - (id) copy
{ {
return [[dataMalloc allocWithZone: NSDefaultMallocZone()] return [[dataMalloc allocWithZone: NSDefaultMallocZone()]

View file

@ -870,15 +870,15 @@ GSTimeNow()
return NSCopyObject(self, 0, zone); return NSCopyObject(self, 0, zone);
} }
- (Class) classForPortCoder - (Class) classForCoder
{ {
/* Make sure that Connection's always send us bycopy,
i.e. as our own class, not a Proxy class. */
return abstractClass; return abstractClass;
} }
- (id) replacementObjectForPortCoder: (NSPortCoder*)aRmc - (id) replacementObjectForPortCoder: (NSPortCoder*)aRmc
{ {
/* Make sure that Connection's always send us bycopy,
i.e. as our own class, not a Proxy class. */
return self; return self;
} }
@ -895,8 +895,20 @@ GSTimeNow()
id o; id o;
[coder decodeValueOfObjCType: @encode(NSTimeInterval) at: &interval]; [coder decodeValueOfObjCType: @encode(NSTimeInterval) at: &interval];
o = [[concreteClass alloc] initWithTimeIntervalSinceReferenceDate: interval]; if (interval == DISTANT_PAST)
[self release]; {
o = RETAIN([abstractClass distantPast]);
}
else if (interval == DISTANT_FUTURE)
{
o = RETAIN([abstractClass distantFuture]);
}
else
{
o = [concreteClass allocWithZone: NSDefaultMallocZone()];
o = [o initWithTimeIntervalSinceReferenceDate: interval];
}
RELEASE(self);
return o; return o;
} }
@ -1116,16 +1128,6 @@ GSTimeNow()
} }
} }
- (Class) classForPortCoder
{
return [self class];
}
- (id) replacementObjectForPortCoder: (NSPortCoder*)aRmc
{
return self;
}
- (void) encodeWithCoder: (NSCoder*)coder - (void) encodeWithCoder: (NSCoder*)coder
{ {
[coder encodeValueOfObjCType: @encode(NSTimeInterval) [coder encodeValueOfObjCType: @encode(NSTimeInterval)
@ -1259,25 +1261,6 @@ GSTimeNow()
} }
} }
- (Class) classForPortCoder
{
return [self class];
}
- (id) replacementObjectForPortCoder: (NSPortCoder*)aRmc
{
return self;
}
- (void) encodeWithCoder: (NSCoder*)coder
{
}
- (id) initWithCoder: (NSCoder*)coder
{
return self;
}
- (id) autorelease - (id) autorelease
{ {
return self; return self;

View file

@ -33,6 +33,7 @@
#include <Foundation/NSAutoreleasePool.h> #include <Foundation/NSAutoreleasePool.h>
#include <Foundation/NSFileManager.h> #include <Foundation/NSFileManager.h>
#include <Foundation/NSUserDefaults.h> #include <Foundation/NSUserDefaults.h>
#include <Foundation/NSCoder.h>
#include <Foundation/NSDebug.h> #include <Foundation/NSDebug.h>
@interface NSDictionaryNonCore : NSDictionary @interface NSDictionaryNonCore : NSDictionary
@ -126,15 +127,62 @@ static SEL appSel = @selector(appendString:);
initWithDictionary: self]; initWithDictionary: self];
} }
- (Class) classForCoder
{
return NSDictionary_abstract_class;
}
- (void) encodeWithCoder: (NSCoder*)aCoder - (void) encodeWithCoder: (NSCoder*)aCoder
{ {
[self subclassResponsibility: _cmd]; unsigned count = [self count];
[aCoder encodeValueOfObjCType: @encode(unsigned) at: &count];
if (count > 0)
{
NSEnumerator *enumerator = [self keyEnumerator];
id key;
IMP enc;
IMP nxt;
IMP ofk;
nxt = [enumerator methodForSelector: @selector(nextObject)];
enc = [aCoder methodForSelector: @selector(encodeObject:)];
ofk = [self methodForSelector: @selector(objectForKey:)];
while ((key = (*nxt)(enumerator, @selector(nextObject))) != nil)
{
id val = (*ofk)(self, @selector(objectForKey:), key);
(*enc)(aCoder, @selector(encodeObject:), key);
(*enc)(aCoder, @selector(encodeObject:), val);
}
}
} }
- (id) initWithCoder: (NSCoder*)aCoder - (id) initWithCoder: (NSCoder*)aCoder
{ {
[self subclassResponsibility: _cmd]; unsigned count;
return nil;
[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;
} }
@end @end
@ -898,6 +946,11 @@ static NSString *indentStrings[] = {
return newDictionary; return newDictionary;
} }
- (Class) classForCoder
{
return NSMutableDictionary_abstract_class;
}
/* This is the designated initializer */ /* This is the designated initializer */
- (id) initWithCapacity: (unsigned)numItems - (id) initWithCapacity: (unsigned)numItems
{ {

View file

@ -33,7 +33,7 @@
/* Warning - [-initWithString:attributes:] is the designated initialiser, /* Warning - [-initWithString:attributes:] is the designated initialiser,
* but it doesn't provide any way to perform the function of the * but it doesn't provide any way to perform the function of the
* [-initWithAttributedString:] initialiser. * [-initWithAttributedString:] initialiser.
* In order to work youd this, the string argument of the * In order to work round this, the string argument of the
* designated initialiser has been overloaded such that it * designated initialiser has been overloaded such that it
* is expected to accept an NSAttributedString here instead of * is expected to accept an NSAttributedString here instead of
* a string. If you create an NSAttributedString subclass, you * a string. If you create an NSAttributedString subclass, you
@ -89,29 +89,6 @@
loc, attrs]; loc, attrs];
} }
- (Class) classForPortCoder
{
return [self class];
}
- (id) replacementObjectForPortCoder: (NSPortCoder*)aCoder
{
return self;
}
- (void) encodeWithCoder: (NSCoder*)aCoder
{
[aCoder encodeValueOfObjCType: @encode(unsigned) at: &loc];
[aCoder encodeValueOfObjCType: @encode(id) at: &attrs];
}
- (id) initWithCoder: (NSCoder*)aCoder
{
[aCoder decodeValueOfObjCType: @encode(unsigned) at: &loc];
[aCoder decodeValueOfObjCType: @encode(id) at: &attrs];
return self;
}
@end @end
@ -289,29 +266,6 @@ _attributesAtIndexEffectiveRange(
_setup(); _setup();
} }
- (Class) classForPortCoder
{
return [self class];
}
- (id) replacementObjectForPortCoder: (NSPortCoder*)aCoder
{
return self;
}
- (void) encodeWithCoder: (NSCoder*)aCoder
{
[aCoder encodeValueOfObjCType: @encode(id) at: &_textChars];
[aCoder encodeValueOfObjCType: @encode(id) at: &_infoArray];
}
- (id) initWithCoder: (NSCoder*)aCoder
{
[aCoder decodeValueOfObjCType: @encode(id) at: &_textChars];
[aCoder decodeValueOfObjCType: @encode(id) at: &_infoArray];
return self;
}
- (id) initWithString: (NSString*)aString - (id) initWithString: (NSString*)aString
attributes: (NSDictionary*)attributes attributes: (NSDictionary*)attributes
{ {
@ -396,29 +350,6 @@ _attributesAtIndexEffectiveRange(
_setup(); _setup();
} }
- (Class) classForPortCoder
{
return [self class];
}
- (id) replacementObjectForPortCoder: (NSPortCoder*)aCoder
{
return self;
}
- (void) encodeWithCoder: (NSCoder*)aCoder
{
[aCoder encodeValueOfObjCType: @encode(id) at: &_textChars];
[aCoder encodeValueOfObjCType: @encode(id) at: &_infoArray];
}
- (id) initWithCoder: (NSCoder*)aCoder
{
[aCoder decodeValueOfObjCType: @encode(id) at: &_textChars];
[aCoder decodeValueOfObjCType: @encode(id) at: &_infoArray];
return self;
}
- (id) initWithString: (NSString*)aString - (id) initWithString: (NSString*)aString
attributes: (NSDictionary*)attributes attributes: (NSDictionary*)attributes
{ {

View file

@ -358,10 +358,6 @@ static NSString *myHostName = nil;
} }
/* Methods for encoding/decoding*/ /* Methods for encoding/decoding*/
- (Class) classForPortCoder
{
return [self class];
}
- (id) replacementObjectForPortCoder: (NSPortCoder*)aCoder - (id) replacementObjectForPortCoder: (NSPortCoder*)aCoder
{ {

View file

@ -2255,9 +2255,9 @@ static Class doubleNumberClass;
* NSCoding * NSCoding
*/ */
- (Class) classForPortCoder - (Class) classForCoder
{ {
return [self class]; return abstractClass;
} }
- (id) replacementObjectForPortCoder: (NSPortCoder*)aCoder - (id) replacementObjectForPortCoder: (NSPortCoder*)aCoder
@ -2269,12 +2269,52 @@ static Class doubleNumberClass;
- (void) encodeWithCoder: (NSCoder*)coder - (void) encodeWithCoder: (NSCoder*)coder
{ {
[coder encodeValueOfObjCType: [self objCType] at: [self pointerValue]]; const char *t = [self objCType];
[coder encodeValueOfObjCType: @encode(char) at: t];
[coder encodeValueOfObjCType: t at: [self pointerValue]];
} }
- (id) initWithCoder: (NSCoder*)coder - (id) initWithCoder: (NSCoder*)coder
{ {
[coder decodeValueOfObjCType: [self objCType] at: [self pointerValue]]; char t[2];
union {
signed char c;
unsigned char C;
signed short s;
unsigned short S;
signed int i;
unsigned int I;
signed long l;
unsigned long L;
signed long long q;
unsigned long long Q;
float f;
double d;
} data;
[coder decodeValueOfObjCType: @encode(char) at: t];
t[1] = '\0';
[coder decodeValueOfObjCType: t at: &data];
switch (*t)
{
case 'c': self = [self initWithChar: data.c]; break;
case 'C': self = [self initWithUnsignedChar: data.C]; break;
case 's': self = [self initWithShort: data.s]; break;
case 'S': self = [self initWithUnsignedShort: data.S]; break;
case 'i': self = [self initWithInt: data.i]; break;
case 'I': self = [self initWithUnsignedInt: data.I]; break;
case 'l': self = [self initWithLong: data.l]; break;
case 'L': self = [self initWithUnsignedLong: data.L]; break;
case 'q': self = [self initWithLongLong: data.q]; break;
case 'Q': self = [self initWithUnsignedLongLong: data.Q]; break;
case 'f': self = [self initWithFloat: data.f]; break;
case 'd': self = [self initWithDouble: data.d]; break;
default:
[self dealloc];
self = nil;
NSLog(@"Attempt to decode number with unknown ObjC type");
}
return self; return self;
} }
@end @end

View file

@ -2824,21 +2824,11 @@ handle_printf_atsign (FILE *stream,
return self; return self;
} }
- (Class) classForArchiver
{
return NSString_class;
}
- (Class) classForCoder - (Class) classForCoder
{ {
return NSString_class; return NSString_class;
} }
- (Class) classForPortCoder
{
return NSString_class;
}
- (id) replacementObjectForPortCoder: (NSPortCoder*)aCoder - (id) replacementObjectForPortCoder: (NSPortCoder*)aCoder
{ {
if ([aCoder isByref] == NO) if ([aCoder isByref] == NO)
@ -2999,21 +2989,11 @@ handle_printf_atsign (FILE *stream,
RELEASE(tmp); RELEASE(tmp);
} }
- (Class) classForArchiver
{
return NSMutableString_class;
}
- (Class) classForCoder - (Class) classForCoder
{ {
return NSMutableString_class; return NSMutableString_class;
} }
- (Class) classForPortCoder
{
return NSMutableString_class;
}
- (void) deleteCharactersInRange: (NSRange)range - (void) deleteCharactersInRange: (NSRange)range
{ {
[self replaceCharactersInRange: range withString: nil]; [self replaceCharactersInRange: range withString: nil];