diff --git a/ChangeLog b/ChangeLog index d93c96d48..6e5c6b209 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,18 @@ +2000-03-23 Richard Frith-Macdonald + + NSNumber - more extensive rewrite/optimisation ... + * Headers/gnustep/base/NSValue.h: simplified + * Source/NSNumber.m: Implemented efficient abstract methods and + improved caching. + * Source/NSConcreteNumber.m: More efficient implementations including + some previously missing methods. + 2000-03-23 Adam Fedor * configure.in: Check for vasprintf function * config/config.vasprintf.c: New file. -2000-03-19 Richard Frith-Macdonald +2000-03-22 Richard Frith-Macdonald NSNumber optimisation ... * Headers/gnustep/base/NSValue.h: Added a couple of GNUstep specific diff --git a/Headers/gnustep/base/NSValue.h b/Headers/gnustep/base/NSValue.h index d484446cb..6c5762dcd 100644 --- a/Headers/gnustep/base/NSValue.h +++ b/Headers/gnustep/base/NSValue.h @@ -114,7 +114,6 @@ - (NSComparisonResult) compare: (NSNumber*)otherNumber; - (BOOL) isEqualToNumber: (NSNumber*)otherNumber; - @end #ifndef NO_GNUSTEP @@ -131,22 +130,8 @@ * Cache info for internal use by NSNumber concrete subclasses. */ typedef struct { - int typeOrder; - int typeNext; - NSComparisonResult (*compValue)(NSNumber*, SEL, NSNumber*); - BOOL (*boolValue)(NSNumber*, SEL); - char (*charValue)(NSNumber*, SEL); - unsigned char (*unsignedCharValue)(NSNumber*, SEL); - short (*shortValue)(NSNumber*, SEL); - unsigned short (*unsignedShortValue)(NSNumber*, SEL); - int (*intValue)(NSNumber*, SEL); - unsigned int (*unsignedIntValue)(NSNumber*, SEL); - long (*longValue)(NSNumber*, SEL); - unsigned long (*unsignedLongValue)(NSNumber*, SEL); - long long (*longLongValue)(NSNumber*, SEL); - unsigned long long (*unsignedLongLongValue)(NSNumber*, SEL); - float (*floatValue)(NSNumber*, SEL); - double (*doubleValue)(NSNumber*, SEL); + int typeLevel; + void (*getValue)(NSNumber*, SEL, void*); } GSNumberInfo; GSNumberInfo *GSNumberInfoFromObject(NSNumber *o); diff --git a/Source/NSConcreteNumber.m b/Source/NSConcreteNumber.m index 5f2af0a7d..d25474115 100644 --- a/Source/NSConcreteNumber.m +++ b/Source/NSConcreteNumber.m @@ -1,10 +1,12 @@ # line 1 "NSConcreteNumber.m" /* So gdb knows which file we are in */ /* NSConcreteNumber - Object encapsulation of numbers - Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc. + Copyright (C) 1993, 1994, 1996, 2000 Free Software Foundation, Inc. Written by: Adam Fedor Date: Mar 1995 + Rewrite: Richard Frith-Macdonald + Date: Mar 2000 This file is part of the GNUstep Base Library. @@ -36,113 +38,58 @@ defined to a number from 0 to 12 cooresponding to each number type */ #if TYPE_ORDER == 0 # define NumberTemplate NSBoolNumber -# define TYPE_METHOD boolValue # define TYPE_FORMAT @"%u" -# define NEXT_ORDER 1 -# define NEXT_TYPE char -# define NEXT_METHOD charValue +# define TYPE_TYPE BOOL #elif TYPE_ORDER == 1 # define NumberTemplate NSCharNumber -# define TYPE_METHOD charValue # define TYPE_FORMAT @"%c" -# define NEXT_ORDER 3 -# define NEXT_TYPE short -# define NEXT_METHOD shortValue +# define TYPE_TYPE char #elif TYPE_ORDER == 2 # define NumberTemplate NSUCharNumber -# define TYPE_METHOD unsignedCharValue # define TYPE_FORMAT @"%c" -# define NEXT_ORDER 3 -# define NEXT_TYPE short -# define NEXT_METHOD shortValue +# define TYPE_TYPE unsigned char #elif TYPE_ORDER == 3 # define NumberTemplate NSShortNumber -# define TYPE_METHOD shortValue # define TYPE_FORMAT @"%hd" -# define NEXT_ORDER 5 -# define NEXT_TYPE int -# define NEXT_METHOD intValue +# define TYPE_TYPE short #elif TYPE_ORDER == 4 # define NumberTemplate NSUShortNumber -# define TYPE_METHOD unsignedShortValue # define TYPE_FORMAT @"%hu" -# define NEXT_ORDER 5 -# define NEXT_TYPE int -# define NEXT_METHOD intValue +# define TYPE_TYPE unsigned short #elif TYPE_ORDER == 5 # define NumberTemplate NSIntNumber -# define TYPE_METHOD intValue # define TYPE_FORMAT @"%d" -# define NEXT_ORDER 7 -# define NEXT_TYPE long -# define NEXT_METHOD longValue +# define TYPE_TYPE int #elif TYPE_ORDER == 6 # define NumberTemplate NSUIntNumber -# define TYPE_METHOD unsignedIntValue # define TYPE_FORMAT @"%u" -# define NEXT_ORDER 7 -# define NEXT_TYPE long -# define NEXT_METHOD longValue +# define TYPE_TYPE unsigned int #elif TYPE_ORDER == 7 # define NumberTemplate NSLongNumber -# define TYPE_METHOD longValue # define TYPE_FORMAT @"%ld" -# define NEXT_ORDER 9 -# define NEXT_TYPE long long -# define NEXT_METHOD longLongValue +# define TYPE_TYPE long #elif TYPE_ORDER == 8 # define NumberTemplate NSULongNumber -# define TYPE_METHOD unsignedLongValue # define TYPE_FORMAT @"%lu" -# define NEXT_ORDER 9 -# define NEXT_TYPE long long -# define NEXT_METHOD longLongValue +# define TYPE_TYPE unsigned long #elif TYPE_ORDER == 9 # define NumberTemplate NSLongLongNumber -# define TYPE_METHOD longLongValue # define TYPE_FORMAT @"%lld" -# define NEXT_ORDER 11 -# define NEXT_TYPE float -# define NEXT_METHOD floatValue +# define TYPE_TYPE long long #elif TYPE_ORDER == 10 # define NumberTemplate NSULongLongNumber -# define TYPE_METHOD unsignedLongLongValue # define TYPE_FORMAT @"%llu" -# define NEXT_ORDER 11 -# define NEXT_TYPE float -# define NEXT_METHOD floatValue +# define TYPE_TYPE unsigned long long #elif TYPE_ORDER == 11 # define NumberTemplate NSFloatNumber -# define TYPE_METHOD floatValue # define TYPE_FORMAT @"%f" -# define NEXT_ORDER 12 -# define NEXT_TYPE double -# define NEXT_METHOD doubleValue +# define TYPE_TYPE float #elif TYPE_ORDER == 12 # define NumberTemplate NSDoubleNumber -# define TYPE_METHOD doubleValue # define TYPE_FORMAT @"%g" -# define NEXT_ORDER 12 -# define NEXT_TYPE double -# define NEXT_METHOD doubleValue +# define TYPE_TYPE double #endif -@interface NSNumber (Private) -- (int) _typeNext; -- (int) _typeOrder; -@end - -@implementation NumberTemplate (Private) -- (int) _typeNext -{ - return NEXT_ORDER; -} -- (int) _typeOrder -{ - return TYPE_ORDER; -} -@end - @implementation NumberTemplate - (id) initWithBytes: (const void*)value objCType: (const char*)type @@ -192,67 +139,67 @@ - (BOOL) boolValue { - return data; + return (BOOL)data; } - (char) charValue { - return data; + return (char)data; } - (double) doubleValue { - return data; + return (double)data; } - (float) floatValue { - return data; + return (float)data; } - (int) intValue { - return data; + return (int)data; } - (long long) longLongValue { - return data; + return (long long)data; } - (long) longValue { - return data; + return (long)data; } - (short) shortValue { - return data; + return (short)data; } - (unsigned char) unsignedCharValue { - return data; + return (unsigned char)data; } - (unsigned int) unsignedIntValue { - return data; + return (unsigned int)data; } - (unsigned long long) unsignedLongLongValue { - return data; + return (unsigned long long)data; } - (unsigned long) unsignedLongValue { - return data; + return (unsigned long)data; } - (unsigned short) unsignedShortValue { - return data; + return (unsigned short)data; } - (NSComparisonResult) compare: (NSNumber*)other @@ -265,68 +212,168 @@ } info = GSNumberInfoFromObject(other); - /* - * If the two types are the same, or the other type can be promoted to ours. - */ - if (TYPE_ORDER == info->typeOrder || TYPE_ORDER >= info->typeNext) + switch (info->typeLevel) { - typedef __typeof__(data) _dt; - _dt other_data = (*(info->TYPE_METHOD))(other, @selector(TYPE_METHOD)); - - if (data == other_data) + case 0: { - return NSOrderedSame; - } - else if (data < other_data) - { - return NSOrderedAscending; - } - else - { - return NSOrderedDescending; - } - } + BOOL oData; - /* - * If we and the other object both promote to the same type - */ - if (NEXT_ORDER == info->typeNext) - { - int res; + (*(info->getValue))(other, @selector(getValue:), (void*)&oData); + if (data == oData) + return NSOrderedSame; + else if (data < oData) + return NSOrderedAscending; + else + return NSOrderedDescending; + } + case 1: + { + char oData; - res = ((NEXT_TYPE)data) - - (*(info->NEXT_METHOD))(other, @selector(NEXT_METHOD)); - if (res == 0) - { - return NSOrderedSame; + (*(info->getValue))(other, @selector(getValue:), (void*)&oData); + if (data == oData) + return NSOrderedSame; + else if (data < oData) + return NSOrderedAscending; + else + return NSOrderedDescending; } - else if (res < 0) + case 2: { - return NSOrderedAscending; - } - else - { - return NSOrderedDescending; - } - } - else - { - NSComparisonResult r; + unsigned char oData; - /* - * We must be promoted to match the other. - */ - r = (*(info->compValue))(other, @selector(compare:), self); + (*(info->getValue))(other, @selector(getValue:), (void*)&oData); + if (data == oData) + return NSOrderedSame; + else if (data < oData) + return NSOrderedAscending; + else + return NSOrderedDescending; + } + case 3: + { + short oData; - if (r == NSOrderedAscending) - { - return NSOrderedDescending; + (*(info->getValue))(other, @selector(getValue:), (void*)&oData); + if (data == oData) + return NSOrderedSame; + else if (data < oData) + return NSOrderedAscending; + else + return NSOrderedDescending; } - if (r == NSOrderedDescending) + case 4: { - return NSOrderedAscending; + unsigned short oData; + + (*(info->getValue))(other, @selector(getValue:), (void*)&oData); + if (data == oData) + return NSOrderedSame; + else if (data < oData) + return NSOrderedAscending; + else + return NSOrderedDescending; } - return r; + case 5: + { + int oData; + + (*(info->getValue))(other, @selector(getValue:), (void*)&oData); + if (data == oData) + return NSOrderedSame; + else if (data < oData) + return NSOrderedAscending; + else + return NSOrderedDescending; + } + case 6: + { + unsigned int oData; + + (*(info->getValue))(other, @selector(getValue:), (void*)&oData); + if (data == oData) + return NSOrderedSame; + else if (data < oData) + return NSOrderedAscending; + else + return NSOrderedDescending; + } + case 7: + { + long oData; + + (*(info->getValue))(other, @selector(getValue:), (void*)&oData); + if (data == oData) + return NSOrderedSame; + else if (data < oData) + return NSOrderedAscending; + else + return NSOrderedDescending; + } + case 8: + { + unsigned long oData; + + (*(info->getValue))(other, @selector(getValue:), (void*)&oData); + if (data == oData) + return NSOrderedSame; + else if (data < oData) + return NSOrderedAscending; + else + return NSOrderedDescending; + } + case 9: + { + long long oData; + + (*(info->getValue))(other, @selector(getValue:), (void*)&oData); + if (data == oData) + return NSOrderedSame; + else if (data < oData) + return NSOrderedAscending; + else + return NSOrderedDescending; + } + case 10: + { + unsigned long long oData; + + (*(info->getValue))(other, @selector(getValue:), (void*)&oData); + if (data == oData) + return NSOrderedSame; + else if (data < oData) + return NSOrderedAscending; + else + return NSOrderedDescending; + } + case 11: + { + float oData; + + (*(info->getValue))(other, @selector(getValue:), (void*)&oData); + if (data == oData) + return NSOrderedSame; + else if (data < oData) + return NSOrderedAscending; + else + return NSOrderedDescending; + } + case 12: + { + double oData; + + (*(info->getValue))(other, @selector(getValue:), (void*)&oData); + if (data == oData) + return NSOrderedSame; + else if (data < oData) + return NSOrderedAscending; + else + return NSOrderedDescending; + } + default: + [NSException raise: NSInvalidArgumentException + format: @"number type value for comparison"]; + return NSOrderedSame; } } @@ -339,22 +386,47 @@ #endif } +- (id) copy +{ + if (NSShouldRetainWithZone(self, NSDefaultMallocZone())) + return RETAIN(self); + else + return NSCopyObject(self, 0, NSDefaultMallocZone()); +} + +- (id) copyWithZone: (NSZone*)zone +{ + if (NSShouldRetainWithZone(self, zone)) + return RETAIN(self); + else + return NSCopyObject(self, 0, zone); +} + // Override these from NSValue - (void) getValue: (void*)value { if (value == 0) { [NSException raise: NSInvalidArgumentException - format: @"Cannot copy value into NULL pointer"]; + format: @"Cannot copy value into NULL pointer"]; /* NOT REACHED */ } - memcpy(value, &data, objc_sizeof_type([self objCType])); + memcpy(value, &data, objc_sizeof_type(@encode(TYPE_TYPE))); } - (const char*) objCType { - typedef __typeof__(data) _dt; - return @encode(_dt); + return @encode(TYPE_TYPE); +} + +- (id) nonretainedObjectValue +{ + return (id)(void*)&data; +} + +- (void*) pointerValue +{ + return (void*)&data; } // NSCoding @@ -370,16 +442,14 @@ return [super replacementObjectForPortCoder: aCoder]; } -- (void) encodeWithCoder: coder +- (void) encodeWithCoder: (NSCoder*)coder { - const char *type = [self objCType]; - [coder encodeValueOfObjCType: type at: &data]; + [coder encodeValueOfObjCType: @encode(TYPE_TYPE) at: &data]; } -- (id) initWithCoder: coder +- (id) initWithCoder: (NSCoder*)coder { - const char *type = [self objCType]; - [coder decodeValueOfObjCType: type at: &data]; + [coder decodeValueOfObjCType: @encode(TYPE_TYPE) at: &data]; return self; } diff --git a/Source/NSNumber.m b/Source/NSNumber.m index b43a69528..03ee95033 100644 --- a/Source/NSNumber.m +++ b/Source/NSNumber.m @@ -1,9 +1,11 @@ /* NSNumber - Object encapsulation of numbers - Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc. + Copyright (C) 1993, 1994, 1996, 2000 Free Software Foundation, Inc. Written by: Adam Fedor Created: Mar 1995 + Rewrite: Richard Frith-Macdonald + Date: Mar 2000 This file is part of the GNUstep Base Library. @@ -33,11 +35,7 @@ #include #include #include - -@interface NSNumber (Private) -- (int) _typeNext; -- (int) _typeOrder; -@end +#include @implementation NSNumber @@ -49,10 +47,8 @@ static NSNumber *smallIntegers[GS_SMALL * 2 + 1]; static unsigned int smallHashes[GS_SMALL * 2 + 1]; /* - * Cache info for each number class. The caches for all the standard types - * of number are built in the NSNumber +initialize method - which is protected - * by locks. Therafter, in a multi-threaded system we may waste some memory - * in order to get speed. + * Cache info for each number class. + * In a multi-threaded system we may waste some memory in order to get speed. */ GSNumberInfo* GSNumberInfoFromObject(NSNumber *o) @@ -64,37 +60,39 @@ GSNumberInfoFromObject(NSNumber *o) info = (GSNumberInfo*)NSMapGet (numberMap, (void*)c); if (info == 0) { + const char *t = [o objCType]; + int order = -1; + + if (strlen(t) != 1) + { + NSLog(@"Invalid return value (%s) from [%@ objCType]", t, c); + } + else + { + switch (*t) + { + case 'c': order = 1; break; + case 'C': order = 2; break; + case 's': order = 3; break; + case 'S': order = 4; break; + case 'i': order = 5; break; + case 'I': order = 6; break; + case 'l': order = 7; break; + case 'L': order = 8; break; + case 'q': order = 9; break; + case 'Q': order = 10; break; + case 'f': order = 11; break; + case 'd': order = 12; break; + default: + NSLog(@"Invalid return value (%s) from [%@ objCType]", t, c); + break; + } + } info = (GSNumberInfo*)objc_malloc(sizeof(GSNumberInfo)); - info->typeNext = [o _typeNext]; - info->typeOrder = [o _typeOrder]; - info->compValue = (NSComparisonResult (*)(NSNumber*, SEL, NSNumber*)) - [o methodForSelector: @selector(compare:)]; - info->boolValue = (BOOL (*)(NSNumber*, SEL)) - [o methodForSelector: @selector(boolValue)]; - info->charValue = (char (*)(NSNumber*, SEL)) - [o methodForSelector: @selector(charValue)]; - info->unsignedCharValue = (unsigned char (*)(NSNumber*, SEL)) - [o methodForSelector: @selector(unsignedCharValue)]; - info->shortValue = (short (*)(NSNumber*, SEL)) - [o methodForSelector: @selector(shortValue)]; - info->unsignedShortValue = (unsigned short (*)(NSNumber*, SEL)) - [o methodForSelector: @selector(unsignedShortValue)]; - info->intValue = (int (*)(NSNumber*, SEL)) - [o methodForSelector: @selector(intValue)]; - info->unsignedIntValue = (unsigned int (*)(NSNumber*, SEL)) - [o methodForSelector: @selector(unsignedIntValue)]; - info->longValue = (long (*)(NSNumber*, SEL)) - [o methodForSelector: @selector(longValue)]; - info->unsignedLongValue = (unsigned long (*)(NSNumber*, SEL)) - [o methodForSelector: @selector(unsignedLongValue)]; - info->longLongValue = (long long (*)(NSNumber*, SEL)) - [o methodForSelector: @selector(longLongValue)]; - info->unsignedLongLongValue = (unsigned long long (*)(NSNumber*, SEL)) - [o methodForSelector: @selector(unsignedLongLongValue)]; - info->floatValue = (float (*)(NSNumber*, SEL)) - [o methodForSelector: @selector(floatValue)]; - info->doubleValue = (double (*)(NSNumber*, SEL)) - [o methodForSelector: @selector(doubleValue)]; + info->typeLevel = order; + + info->getValue = (void (*)(NSNumber*, SEL, void*)) + [o methodForSelector: @selector(getValue:)]; if (multiThreaded == YES) { @@ -149,6 +147,8 @@ static Class doubleNumberClass; BOOL boolean; int integer; unsigned (*hasher)(NSNumber*, SEL); + GSNumberInfo *info; + CREATE_AUTORELEASE_POOL(pool); abstractClass = self; hasher = (unsigned (*)(NSNumber*, SEL)) @@ -164,18 +164,35 @@ static Class doubleNumberClass; * cache standard subclass info. */ boolNumberClass = [NSBoolNumber class]; + info = GSNumberInfoFromObject(AUTORELEASE([boolNumberClass alloc])); + /* + * Set the typeLevel for a boolean to be '0' + */ + info->typeLevel = 0; charNumberClass = [NSCharNumber class]; + GSNumberInfoFromObject(AUTORELEASE([charNumberClass alloc])); uCharNumberClass = [NSUCharNumber class]; + GSNumberInfoFromObject(AUTORELEASE([uCharNumberClass alloc])); shortNumberClass = [NSShortNumber class]; + GSNumberInfoFromObject(AUTORELEASE([shortNumberClass alloc])); uShortNumberClass = [NSUShortNumber class]; + GSNumberInfoFromObject(AUTORELEASE([uShortNumberClass alloc])); intNumberClass = [NSIntNumber class]; + GSNumberInfoFromObject(AUTORELEASE([intNumberClass alloc])); uIntNumberClass = [NSUIntNumber class]; + GSNumberInfoFromObject(AUTORELEASE([uIntNumberClass alloc])); longNumberClass = [NSLongNumber class]; + GSNumberInfoFromObject(AUTORELEASE([longNumberClass alloc])); uLongNumberClass = [NSULongNumber class]; + GSNumberInfoFromObject(AUTORELEASE([uLongNumberClass alloc])); longLongNumberClass = [NSLongLongNumber class]; + GSNumberInfoFromObject(AUTORELEASE([longLongNumberClass alloc])); uLongLongNumberClass = [NSULongLongNumber class]; + GSNumberInfoFromObject(AUTORELEASE([uLongLongNumberClass alloc])); floatNumberClass = [NSFloatNumber class]; + GSNumberInfoFromObject(AUTORELEASE([floatNumberClass alloc])); doubleNumberClass = [NSDoubleNumber class]; + GSNumberInfoFromObject(AUTORELEASE([doubleNumberClass alloc])); /* * cache bool values. @@ -221,6 +238,7 @@ static Class doubleNumberClass; name: NSWillBecomeMultiThreadedNotification object: nil]; } + RELEASE(pool); } } @@ -460,6 +478,14 @@ static Class doubleNumberClass; return [NSNumber numberWithInt: 0]; } +/* + * A moderately sane default init method - a zero value integer. + */ +- (id) init +{ + return [self initWithInt: 0]; +} + - (id) initWithBool: (BOOL)value { NSDeallocateObject(self); @@ -622,14 +648,12 @@ static Class doubleNumberClass; return self; } -- (id) copy -{ - return RETAIN(self); -} - - (id) copyWithZone: (NSZone*)zone { - return RETAIN(self); + if (NSShouldRetainWithZone(self, zone)) + return RETAIN(self); + else + return NSCopyObject(self, 0, zone); } - (NSString*) description @@ -639,56 +663,942 @@ static Class doubleNumberClass; - (NSString*) descriptionWithLocale: (NSDictionary*)locale { - [self subclassResponsibility: _cmd]; - return nil; + if (fastClass(self) == abstractClass) + { + [NSException raise: NSInternalInconsistencyException + format: @"descriptionWithLocale: for abstract NSNumber"]; + return nil; + } + else + { + GSNumberInfo *info = GSNumberInfoFromObject(self); + + switch (info->typeLevel) + { + case 0: + return [self boolValue] ? @"YES" : @"NO"; + case 1: + return [NSString stringWithFormat: @"%c", + [self charValue]]; + case 2: + return [NSString stringWithFormat: @"%c", + [self unsignedCharValue]]; + case 3: + return [NSString stringWithFormat: @"%hd", + [self shortValue]]; + case 4: + return [NSString stringWithFormat: @"%hu", + [self unsignedShortValue]]; + case 5: + return [NSString stringWithFormat: @"%d", + [self intValue]]; + case 6: + return [NSString stringWithFormat: @"%u", + [self unsignedIntValue]]; + case 7: + return [NSString stringWithFormat: @"%ld", + [self longValue]]; + case 8: + return [NSString stringWithFormat: @"%lu", + [self unsignedLongValue]]; + case 9: + return [NSString stringWithFormat: @"%lld", + [self longLongValue]]; + case 10: + return [NSString stringWithFormat: @"%llu", + [self unsignedLongLongValue]]; + case 11: + return [NSString stringWithFormat: @"%f", + [self floatValue]]; + case 12: + return [NSString stringWithFormat: @"%g", + [self doubleValue]]; + default: + [NSException raise: NSInvalidArgumentException + format: @"unknown number type value for description"]; + return nil; + } + } } /* All the rest of these methods must be implemented by a subclass */ - (BOOL) boolValue { - [self subclassResponsibility: _cmd]; + if (fastClass(self) == abstractClass) + [NSException raise: NSInternalInconsistencyException + format: @"get boolValue from abstract NSNumber"]; + else + { + GSNumberInfo *info = GSNumberInfoFromObject(self); + + switch (info->typeLevel) + { + case 0: + { + BOOL oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 1: + { + char oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 2: + { + unsigned char oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 3: + { + short oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 4: + { + unsigned short oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 5: + { + int oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 6: + { + unsigned int oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 7: + { + long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 8: + { + unsigned long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 9: + { + long long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 10: + { + unsigned long long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 11: + { + float oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 12: + { + double oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + default: + [NSException raise: NSInvalidArgumentException + format: @"unknown number type value for get"]; + } + } return 0; } - (char) charValue { - [self subclassResponsibility: _cmd]; + if (fastClass(self) == abstractClass) + [NSException raise: NSInternalInconsistencyException + format: @"get charValue from abstract NSNumber"]; + else + { + GSNumberInfo *info = GSNumberInfoFromObject(self); + + switch (info->typeLevel) + { + case 0: + { + BOOL oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 1: + { + char oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 2: + { + unsigned char oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 3: + { + short oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 4: + { + unsigned short oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 5: + { + int oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 6: + { + unsigned int oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 7: + { + long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 8: + { + unsigned long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 9: + { + long long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 10: + { + unsigned long long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 11: + { + float oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 12: + { + double oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + default: + [NSException raise: NSInvalidArgumentException + format: @"unknown number type value for get"]; + } + } return 0; } - (double) doubleValue { - [self subclassResponsibility: _cmd]; + if (fastClass(self) == abstractClass) + [NSException raise: NSInternalInconsistencyException + format: @"get doubleValue from abstract NSNumber"]; + else + { + GSNumberInfo *info = GSNumberInfoFromObject(self); + + switch (info->typeLevel) + { + case 0: + { + BOOL oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 1: + { + char oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 2: + { + unsigned char oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 3: + { + short oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 4: + { + unsigned short oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 5: + { + int oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 6: + { + unsigned int oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 7: + { + long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 8: + { + unsigned long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 9: + { + long long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 10: + { + unsigned long long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 11: + { + float oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 12: + { + double oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + default: + [NSException raise: NSInvalidArgumentException + format: @"unknown number type value for get"]; + } + } return 0; } - (float) floatValue { - [self subclassResponsibility: _cmd]; + if (fastClass(self) == abstractClass) + [NSException raise: NSInternalInconsistencyException + format: @"get floatValue from abstract NSNumber"]; + else + { + GSNumberInfo *info = GSNumberInfoFromObject(self); + + switch (info->typeLevel) + { + case 0: + { + BOOL oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 1: + { + char oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 2: + { + unsigned char oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 3: + { + short oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 4: + { + unsigned short oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 5: + { + int oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 6: + { + unsigned int oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 7: + { + long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 8: + { + unsigned long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 9: + { + long long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 10: + { + unsigned long long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 11: + { + float oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 12: + { + double oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + default: + [NSException raise: NSInvalidArgumentException + format: @"unknown number type value for get"]; + } + } return 0; } - (int) intValue { - [self subclassResponsibility: _cmd]; + if (fastClass(self) == abstractClass) + [NSException raise: NSInternalInconsistencyException + format: @"get intValue from abstract NSNumber"]; + else + { + GSNumberInfo *info = GSNumberInfoFromObject(self); + + switch (info->typeLevel) + { + case 0: + { + BOOL oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 1: + { + char oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 2: + { + unsigned char oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 3: + { + short oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 4: + { + unsigned short oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 5: + { + int oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 6: + { + unsigned int oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 7: + { + long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 8: + { + unsigned long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 9: + { + long long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 10: + { + unsigned long long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 11: + { + float oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 12: + { + double oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + default: + [NSException raise: NSInvalidArgumentException + format: @"unknown number type value for get"]; + } + } return 0; } - (long long) longLongValue { - [self subclassResponsibility: _cmd]; + if (fastClass(self) == abstractClass) + [NSException raise: NSInternalInconsistencyException + format: @"get longLongValue from abstract NSNumber"]; + else + { + GSNumberInfo *info = GSNumberInfoFromObject(self); + + switch (info->typeLevel) + { + case 0: + { + BOOL oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 1: + { + char oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 2: + { + unsigned char oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 3: + { + short oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 4: + { + unsigned short oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 5: + { + int oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 6: + { + unsigned int oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 7: + { + long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 8: + { + unsigned long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 9: + { + long long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 10: + { + unsigned long long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 11: + { + float oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 12: + { + double oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + default: + [NSException raise: NSInvalidArgumentException + format: @"unknown number type value for get"]; + } + } return 0; } - (long) longValue { - [self subclassResponsibility: _cmd]; + if (fastClass(self) == abstractClass) + [NSException raise: NSInternalInconsistencyException + format: @"get longValue from abstract NSNumber"]; + else + { + GSNumberInfo *info = GSNumberInfoFromObject(self); + + switch (info->typeLevel) + { + case 0: + { + BOOL oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 1: + { + char oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 2: + { + unsigned char oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 3: + { + short oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 4: + { + unsigned short oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 5: + { + int oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 6: + { + unsigned int oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 7: + { + long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 8: + { + unsigned long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 9: + { + long long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 10: + { + unsigned long long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 11: + { + float oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 12: + { + double oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + default: + [NSException raise: NSInvalidArgumentException + format: @"unknown number type value for get"]; + } + } return 0; } - (short) shortValue { - [self subclassResponsibility: _cmd]; + if (fastClass(self) == abstractClass) + [NSException raise: NSInternalInconsistencyException + format: @"get shortValue from abstract NSNumber"]; + else + { + GSNumberInfo *info = GSNumberInfoFromObject(self); + + switch (info->typeLevel) + { + case 0: + { + BOOL oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 1: + { + char oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 2: + { + unsigned char oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 3: + { + short oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 4: + { + unsigned short oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 5: + { + int oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 6: + { + unsigned int oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 7: + { + long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 8: + { + unsigned long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 9: + { + long long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 10: + { + unsigned long long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 11: + { + float oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 12: + { + double oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + default: + [NSException raise: NSInvalidArgumentException + format: @"unknown number type value for get"]; + } + } return 0; } @@ -699,45 +1609,561 @@ static Class doubleNumberClass; - (unsigned char) unsignedCharValue { - [self subclassResponsibility: _cmd]; + if (fastClass(self) == abstractClass) + [NSException raise: NSInternalInconsistencyException + format: @"get unsignedCharrValue from abstract NSNumber"]; + else + { + GSNumberInfo *info = GSNumberInfoFromObject(self); + + switch (info->typeLevel) + { + case 0: + { + BOOL oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 1: + { + char oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 2: + { + unsigned char oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 3: + { + short oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 4: + { + unsigned short oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 5: + { + int oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 6: + { + unsigned int oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 7: + { + long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 8: + { + unsigned long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 9: + { + long long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 10: + { + unsigned long long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 11: + { + float oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 12: + { + double oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + default: + [NSException raise: NSInvalidArgumentException + format: @"unknown number type value for get"]; + } + } return 0; } - (unsigned int) unsignedIntValue { - [self subclassResponsibility: _cmd]; + if (fastClass(self) == abstractClass) + [NSException raise: NSInternalInconsistencyException + format: @"get unsignedIntValue from abstract NSNumber"]; + else + { + GSNumberInfo *info = GSNumberInfoFromObject(self); + + switch (info->typeLevel) + { + case 0: + { + BOOL oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 1: + { + char oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 2: + { + unsigned char oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 3: + { + short oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 4: + { + unsigned short oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 5: + { + int oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 6: + { + unsigned int oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 7: + { + long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 8: + { + unsigned long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 9: + { + long long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 10: + { + unsigned long long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 11: + { + float oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 12: + { + double oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + default: + [NSException raise: NSInvalidArgumentException + format: @"unknown number type value for get"]; + } + } return 0; } - (unsigned long long) unsignedLongLongValue { - [self subclassResponsibility: _cmd]; + if (fastClass(self) == abstractClass) + [NSException raise: NSInternalInconsistencyException + format: @"get unsignedLongLongValue from abstract NSNumber"]; + else + { + GSNumberInfo *info = GSNumberInfoFromObject(self); + + switch (info->typeLevel) + { + case 0: + { + BOOL oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 1: + { + char oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 2: + { + unsigned char oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 3: + { + short oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 4: + { + unsigned short oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 5: + { + int oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 6: + { + unsigned int oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 7: + { + long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 8: + { + unsigned long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 9: + { + long long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 10: + { + unsigned long long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 11: + { + float oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 12: + { + double oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + default: + [NSException raise: NSInvalidArgumentException + format: @"unknown number type value for get"]; + } + } return 0; } - (unsigned long) unsignedLongValue { - [self subclassResponsibility: _cmd]; + if (fastClass(self) == abstractClass) + [NSException raise: NSInternalInconsistencyException + format: @"get unsignedLongValue from abstract NSNumber"]; + else + { + GSNumberInfo *info = GSNumberInfoFromObject(self); + + switch (info->typeLevel) + { + case 0: + { + BOOL oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 1: + { + char oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 2: + { + unsigned char oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 3: + { + short oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 4: + { + unsigned short oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 5: + { + int oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 6: + { + unsigned int oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 7: + { + long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 8: + { + unsigned long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 9: + { + long long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 10: + { + unsigned long long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 11: + { + float oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 12: + { + double oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + default: + [NSException raise: NSInvalidArgumentException + format: @"unknown number type value for get"]; + } + } return 0; } - (unsigned short) unsignedShortValue { - [self subclassResponsibility: _cmd]; + if (fastClass(self) == abstractClass) + [NSException raise: NSInternalInconsistencyException + format: @"get unsignedShortValue from abstract NSNumber"]; + else + { + GSNumberInfo *info = GSNumberInfoFromObject(self); + + switch (info->typeLevel) + { + case 0: + { + BOOL oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 1: + { + char oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 2: + { + unsigned char oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 3: + { + short oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 4: + { + unsigned short oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 5: + { + int oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 6: + { + unsigned int oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 7: + { + long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 8: + { + unsigned long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 9: + { + long long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 10: + { + unsigned long long oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 11: + { + float oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + case 12: + { + double oData; + + (*(info->getValue))(self, @selector(getValue:), &oData); + return oData; + } + default: + [NSException raise: NSInvalidArgumentException + format: @"unknown number type value for get"]; + } + } return 0; } - (NSComparisonResult) compare: (NSNumber*)other { - GSNumberInfo *otherInfo; - GSNumberInfo *myInfo; double otherValue; double myValue; - myInfo = GSNumberInfoFromObject(self); - otherInfo = GSNumberInfoFromObject(other); - myValue = (*(myInfo->doubleValue))(self, @selector(doubleValue)); - otherValue = (*(otherInfo->doubleValue))(other, @selector(doubleValue)); + myValue = [self doubleValue]; + otherValue = [other doubleValue]; if (myValue == otherValue) { @@ -804,26 +2230,30 @@ static Class doubleNumberClass; return NO; } -// NSCoding (done by subclasses) +/* + * NSCoding + */ + +- (Class) classForPortCoder +{ + return [self class]; +} + +- (id) replacementObjectForPortCoder: (NSPortCoder*)aCoder +{ + if ([aCoder isByref] == NO) + return self; + return [super replacementObjectForPortCoder: aCoder]; +} + - (void) encodeWithCoder: (NSCoder*)coder { - [self subclassResponsibility: _cmd]; + [coder encodeValueOfObjCType: [self objCType] at: [self pointerValue]]; } - (id) initWithCoder: (NSCoder*)coder { - [self subclassResponsibility: _cmd]; - return nil; + [coder decodeValueOfObjCType: [self objCType] at: [self pointerValue]]; + return self; } - -- (int) _typeNext -{ - return 12; -} - -- (int) _typeOrder -{ - return 12; -} - @end diff --git a/Source/NSString.m b/Source/NSString.m index a0e28111c..d32810671 100644 --- a/Source/NSString.m +++ b/Source/NSString.m @@ -1777,27 +1777,45 @@ handle_printf_atsign (FILE *stream, } /* Returns a new string with the path component given in aString - appended to the receiver. Raises an exception if aString starts with - a '/'. Checks the receiver to see if the last letter is a '/', if it - is not, a '/' is appended before appending aString */ + * appended to the receiver. + * Removes trailing separators and multiple separators. + */ - (NSString*) stringByAppendingPathComponent: (NSString*)aString { - unsigned length; + unsigned length = [self length]; + unsigned aLength = [aString length]; + unichar buf[length+aLength+1]; - if ([aString length] == 0) - return AUTORELEASE([self copy]); - length = [self length]; - if (length == 0) - return AUTORELEASE([aString copy]); + [self getCharacters: buf]; + if (aLength > 0) + { + buf[length++] = pathSepChar; + [aString getCharacters: &buf[length]]; + } + length += aLength; + while (length > 1 && pathSepMember(buf[length-1]) == YES) + { + length--; + } + aLength = length - 1; + while (aLength > 1) + { + if (pathSepMember(buf[aLength]) == YES) + { + if (pathSepMember(buf[aLength-1]) == YES) + { + unsigned pos; - if (pathSepMember([aString characterAtIndex: 0]) == YES) - [NSException raise: NSGenericException - format: @"attempt to append illegal path component"]; - - if (pathSepMember([self characterAtIndex: length-1]) == YES) - return [self stringByAppendingString: aString]; - else - return [self stringByAppendingFormat: @"%@%@", pathSepString, aString]; + for (pos = aLength+1; pos < length; pos++) + { + buf[pos-1] = buf[pos]; + } + length--; + } + } + aLength--; + } + return [NSString stringWithCharacters: buf length: length]; } /* Returns a new string with the path extension given in aString @@ -2192,30 +2210,34 @@ handle_printf_atsign (FILE *stream, - (NSArray*) pathComponents { - NSMutableArray *a; - NSArray *r; + NSMutableArray *a; + NSArray *r; - a = [[self componentsSeparatedByString: pathSepString] mutableCopy]; - if ([a count] > 0) { - int i; + a = [[self componentsSeparatedByString: pathSepString] mutableCopy]; + if ([a count] > 0) + { + int i; - /* If the path began with a '/' then the first path component must - * be a '/' rather than an empty string so that our output could be - * fed into [+pathWithComponents: ] - */ - if ([[a objectAtIndex: 0] length] == 0) { - [a replaceObjectAtIndex: 0 withObject: pathSepString]; + /* If the path began with a '/' then the first path component must + * be a '/' rather than an empty string so that our output could be + * fed into [+pathWithComponents: ] + */ + if ([[a objectAtIndex: 0] length] == 0) + { + [a replaceObjectAtIndex: 0 withObject: pathSepString]; } - /* Any empty path components (except a trailing one) must be removed. */ - for (i = [a count] - 2; i > 0; i--) { - if ([[a objectAtIndex: i] length] == 0) { - [a removeObjectAtIndex: i]; + /* Any empty path components (except a trailing one) must be removed. */ + for (i = [a count] - 2; i > 0; i--) + { + if ([[a objectAtIndex: i] length] == 0) + { + [a removeObjectAtIndex: i]; } } } - r = [a copy]; - RELEASE(a); - return AUTORELEASE(r); + r = [a copy]; + RELEASE(a); + return AUTORELEASE(r); } - (NSArray*) stringsByAppendingPaths: (NSArray*)paths