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 Frith-MacDonald 2000-10-16 12:35:42 +00:00
parent 1e756dcab1
commit db8f01b38e
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>
* Source/NSObject.m (+initialize): Initialize Window sockets

View file

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

View file

@ -117,20 +117,73 @@ static Class NSMutableAttributedString_concrete_class;
return NSAllocateObject(self, 0, z);
}
- (Class) classForCoder
{
return NSAttributedString_abstract_class;
}
- (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
{
[self subclassResponsibility: _cmd];
return nil;
}
NSString *string = [aDecoder decodeObject];
unsigned length = [string length];
- (Class) classForPortCoder
{
return [self class];
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;
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
@ -473,7 +526,7 @@ static Class NSMutableAttributedString_concrete_class;
@implementation NSMutableAttributedString
+ allocWithZone: (NSZone*)z
+ (id) allocWithZone: (NSZone*)z
{
if (self == NSMutableAttributedString_abstract_class)
return NSAllocateObject(NSMutableAttributedString_concrete_class, 0, z);
@ -481,6 +534,52 @@ static Class NSMutableAttributedString_concrete_class;
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
- (NSMutableString*) mutableString
{

View file

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

View file

@ -439,23 +439,23 @@
}
// 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
{
[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
{
[coder decodeValueOfObjCType: @encode(TYPE_TYPE) at: &data];

View file

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

View file

@ -870,15 +870,15 @@ GSTimeNow()
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;
}
- (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;
}
@ -895,8 +895,20 @@ GSTimeNow()
id o;
[coder decodeValueOfObjCType: @encode(NSTimeInterval) at: &interval];
o = [[concreteClass alloc] initWithTimeIntervalSinceReferenceDate: interval];
[self release];
if (interval == DISTANT_PAST)
{
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;
}
@ -1116,16 +1128,6 @@ GSTimeNow()
}
}
- (Class) classForPortCoder
{
return [self class];
}
- (id) replacementObjectForPortCoder: (NSPortCoder*)aRmc
{
return self;
}
- (void) encodeWithCoder: (NSCoder*)coder
{
[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
{
return self;

View file

@ -33,6 +33,7 @@
#include <Foundation/NSAutoreleasePool.h>
#include <Foundation/NSFileManager.h>
#include <Foundation/NSUserDefaults.h>
#include <Foundation/NSCoder.h>
#include <Foundation/NSDebug.h>
@interface NSDictionaryNonCore : NSDictionary
@ -126,15 +127,62 @@ static SEL appSel = @selector(appendString:);
initWithDictionary: self];
}
- (Class) classForCoder
{
return NSDictionary_abstract_class;
}
- (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
{
[self subclassResponsibility: _cmd];
return nil;
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;
}
@end
@ -898,6 +946,11 @@ static NSString *indentStrings[] = {
return newDictionary;
}
- (Class) classForCoder
{
return NSMutableDictionary_abstract_class;
}
/* This is the designated initializer */
- (id) initWithCapacity: (unsigned)numItems
{

View file

@ -33,7 +33,7 @@
/* Warning - [-initWithString:attributes:] is the designated initialiser,
* but it doesn't provide any way to perform the function of the
* [-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
* is expected to accept an NSAttributedString here instead of
* a string. If you create an NSAttributedString subclass, you
@ -89,29 +89,6 @@
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
@ -289,29 +266,6 @@ _attributesAtIndexEffectiveRange(
_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
attributes: (NSDictionary*)attributes
{
@ -396,29 +350,6 @@ _attributesAtIndexEffectiveRange(
_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
attributes: (NSDictionary*)attributes
{

View file

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

View file

@ -2255,9 +2255,9 @@ static Class doubleNumberClass;
* NSCoding
*/
- (Class) classForPortCoder
- (Class) classForCoder
{
return [self class];
return abstractClass;
}
- (id) replacementObjectForPortCoder: (NSPortCoder*)aCoder
@ -2269,12 +2269,52 @@ static Class doubleNumberClass;
- (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
{
[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;
}
@end

View file

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