diff --git a/Source/NSCTemplateValue.m b/Source/NSCTemplateValue.m index 0b93ff693..6c9732d1c 100644 --- a/Source/NSCTemplateValue.m +++ b/Source/NSCTemplateValue.m @@ -90,14 +90,17 @@ // NSCoding - (void)encodeWithCoder:(NSCoder *)coder { + const char *type; [super encodeWithCoder:coder]; - [coder encodeValueOfObjCType:[self objCType] at:&data]; + type = [self objCType]; + [coder encodeValueOfObjCType:@encode(char *) at:&type]; + [coder encodeValueOfObjCType:type at:&data]; } - (id)initWithCoder:(NSCoder *)coder { - self = [super initWithCoder:coder]; - [coder decodeValueOfObjCType:[self objCType] at:&data]; + [NSException raise:NSInconsistentArchiveException + format:@"Cannot unarchive class - Need NSValueDecoder."]; return self; } diff --git a/Source/NSConcreteNumber.m b/Source/NSConcreteNumber.m index 8bb968d06..805d455d3 100644 --- a/Source/NSConcreteNumber.m +++ b/Source/NSConcreteNumber.m @@ -195,14 +195,18 @@ // NSCoding - (void)encodeWithCoder:(NSCoder *)coder { + const char *type; [super encodeWithCoder:coder]; - [coder encodeValueOfObjCType:[self objCType] at:&data]; + type = [self objCType]; + [coder encodeValueOfObjCType:@encode(char *) at:&type]; + [coder encodeValueOfObjCType:type at:&data]; } - (id)initWithCoder:(NSCoder *)coder { + // This should raise an exception - Use NSValueDecoder to decode NSNumber self = [super initWithCoder:coder]; - [coder decodeValueOfObjCType:[self objCType] at:&data]; + //[coder decodeValueOfObjCType:[self objCType] at:&data]; return self; } diff --git a/Source/NSConcreteValue.m b/Source/NSConcreteValue.m index 95b31fdc6..7ee1c0b78 100644 --- a/Source/NSConcreteValue.m +++ b/Source/NSConcreteValue.m @@ -141,18 +141,19 @@ // NSCoding - (void)encodeWithCoder:(NSCoder *)coder { + const char *type; [super encodeWithCoder:coder]; // FIXME: Do we need to check for encoding void, void * or will // NSCoder do this for us? - [coder encodeObject:objctype]; - [coder encodeValueOfObjCType:[objctype cString] at:&data]; + type = [objctype cString]; + [coder encodeValueOfObjCType:@encode(char *) at:&type]; + [coder encodeValueOfObjCType:type at:&data]; } - (id)initWithCoder:(NSCoder *)coder { - self = [super initWithCoder:coder]; - objctype = [[coder decodeObject] retain]; - [coder decodeValueOfObjCType:[objctype cString] at:&data]; + [NSException raise:NSInconsistentArchiveException + format:@"Cannot unarchive class - Need NSValueDecoder."]; return self; } diff --git a/Source/NSNumber.m b/Source/NSNumber.m index 4ce7c96de..582dbf17b 100644 --- a/Source/NSNumber.m +++ b/Source/NSNumber.m @@ -168,100 +168,95 @@ /* All the rest of these methods must be implemented by a subclass */ - (BOOL)boolValue { - [self doesNotRecognizeSelector:_cmd]; + [self subclassResponsibility:_cmd]; return 0; } - (char)charValue { - [self doesNotRecognizeSelector:_cmd]; + [self subclassResponsibility:_cmd]; return 0; } - (double)doubleValue { - [self doesNotRecognizeSelector:_cmd]; + [self subclassResponsibility:_cmd]; return 0; } - (float)floatValue { - [self doesNotRecognizeSelector:_cmd]; + [self subclassResponsibility:_cmd]; return 0; } - (int)intValue { - [self doesNotRecognizeSelector:_cmd]; + [self subclassResponsibility:_cmd]; return 0; } - (long long)longLongValue { - [self doesNotRecognizeSelector:_cmd]; + [self subclassResponsibility:_cmd]; return 0; } - (long)longValue { - [self doesNotRecognizeSelector:_cmd]; + [self subclassResponsibility:_cmd]; return 0; } - (short)shortValue { - [self doesNotRecognizeSelector:_cmd]; + [self subclassResponsibility:_cmd]; return 0; } - (NSString *)stringValue { - [self doesNotRecognizeSelector:_cmd]; + [self subclassResponsibility:_cmd]; return 0; } - (unsigned char)unsignedCharValue { - [self doesNotRecognizeSelector:_cmd]; + [self subclassResponsibility:_cmd]; return 0; } - (unsigned int)unsignedIntValue { - [self doesNotRecognizeSelector:_cmd]; + [self subclassResponsibility:_cmd]; return 0; } - (unsigned long long)unsignedLongLongValue { - [self doesNotRecognizeSelector:_cmd]; + [self subclassResponsibility:_cmd]; return 0; } - (unsigned long)unsignedLongValue { - [self doesNotRecognizeSelector:_cmd]; + [self subclassResponsibility:_cmd]; return 0; } - (unsigned short)unsignedShortValue { - [self doesNotRecognizeSelector:_cmd]; + [self subclassResponsibility:_cmd]; return 0; } - (NSComparisonResult)compare:(NSNumber *)otherNumber { - [self doesNotRecognizeSelector:_cmd]; + [self subclassResponsibility:_cmd]; return 0; } // NSCoding (done by subclasses) -- classForCoder -{ - return [self class]; -} - - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; @@ -269,7 +264,8 @@ - (id)initWithCoder:(NSCoder *)coder { - self = [super initWithCoder:coder]; + [NSException raise:NSInconsistentArchiveException + format:@"Cannot unarchive from NSNumber class - Need NSValueDecoder."]; return self; } diff --git a/Source/NSValue.m b/Source/NSValue.m index a81b591eb..86cc302eb 100644 --- a/Source/NSValue.m +++ b/Source/NSValue.m @@ -21,9 +21,58 @@ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include #include +/* NSValueDecoder is a Class whose only purpose is to decode coded NSValue + objects. The only method(s) that should ever be called are +newWithCoder: + or -initWithCoder:. Should disallow any other method calls... */ +@interface NSValueDecoder : NSValue +{ +} + +@end + +@implementation NSValueDecoder + +- initValue:(const void *)value + withObjCType:(const char *)type +{ + [self shouldNotImplement:_cmd]; +} + ++ (id) newWithCoder: (NSCoder *)coder +{ + char *type; + void *data; + id new_value; + + [coder decodeValueOfObjCType:@encode(char *) at:&type]; + [coder decodeValueOfObjCType:type at:&data]; + /* Call NSNumber's implementation of this method, because NSValueDecoder + also stores NSNumber types */ + new_value = [[NSNumber valueClassWithObjCType:type] + allocWithZone:[coder objectZone]]; + [new_value initValue:data withObjCType:type]; + OBJC_FREE(data); + OBJC_FREE(type); + return new_value; +} + +/* Are you convinced that +newWithCoder is a better idea? Otherwise we + have to release ourselves and return a new instance of the correct + object. We hope that the calling method knows this and has nested the + alloc and init calls or knows that the object has been replaced. */ +- (id) initWithCoder: (NSCoder *)coder +{ + self = [super initWithCoder:coder]; + [self autorelease]; + return [NSValueDecoder newWithCoder:coder]; +} + +@end + @implementation NSValue // NSCopying @@ -111,50 +160,50 @@ /* All the rest of these methods must be implemented by a subclass */ - (void)getValue:(void *)value { - [self doesNotRecognizeSelector:_cmd]; + [self subclassResponsibility:_cmd]; } - (const char *)objCType { - [self doesNotRecognizeSelector:_cmd]; + [self subclassResponsibility:_cmd]; return 0; } // FIXME: Is this an error or an exception??? - (id)nonretainedObjectValue { - [self doesNotRecognizeSelector:_cmd]; + [self subclassResponsibility:_cmd]; return 0; } - (void *)pointerValue { - [self doesNotRecognizeSelector:_cmd]; + [self subclassResponsibility:_cmd]; return 0; } - (NSRect)rectValue { - [self doesNotRecognizeSelector:_cmd]; + [self subclassResponsibility:_cmd]; return NSMakeRect(0,0,0,0); } - (NSSize)sizeValue { - [self doesNotRecognizeSelector:_cmd]; + [self subclassResponsibility:_cmd]; return NSMakeSize(0,0); } - (NSPoint)pointValue { - [self doesNotRecognizeSelector:_cmd]; + [self subclassResponsibility:_cmd]; return NSMakePoint(0,0); } // NSCoding (done by subclasses) - classForCoder { - return [self class]; + return [NSValueDecoder class]; } - (void)encodeWithCoder:(NSCoder *)coder diff --git a/Source/TextCoder.m b/Source/TextCoder.m index 97902fb1b..1a72a98b9 100644 --- a/Source/TextCoder.m +++ b/Source/TextCoder.m @@ -98,11 +98,11 @@ static BOOL debug_textcoder = NO; indentation, "", name, (unsigned)*(unsigned char*)d]; break; case _C_FLT: - [stream writeFormat:"%*s<%s> (float) = %f\n", + [stream writeFormat:"%*s<%s> (float) = %g\n", indentation, "", name, *(float*)d]; break; case _C_DBL: - [stream writeFormat:"%*s<%s> (double) = %f\n", + [stream writeFormat:"%*s<%s> (double) = %g\n", indentation, "", name, *(double*)d]; break; case _C_CHARPTR: @@ -198,7 +198,7 @@ if (debug_textcoder) \ DECODE_DEBUG(float, f); break; case _C_DBL: - if ([stream readFormat:DECODER_FORMAT(double,f), + if ([stream readFormat:DECODER_FORMAT(double,lf), &tmpname, (double*)d] != 2) DECODE_ERROR(double); DECODE_DEBUG(double, f);