Fixed errors found by test suite.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31967 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
stefanbidi 2011-01-29 02:01:42 +00:00
parent b1ce49ff43
commit 86b566f237
2 changed files with 324 additions and 314 deletions

View file

@ -1,3 +1,7 @@
2011-01-28 Stefan Bidigaray <stefanbidi@gmail.com>
* Source/NSNumberFormatter.m: Fixed errors found by test suite.
2011-01-27 Stefan Bidigaray <stefanbidi@gmail.com>
* Source/NSCalendar.m: Add -isEqual:.

View file

@ -428,7 +428,7 @@ static NSUInteger _defaultBehavior = 0;
_behavior = _defaultBehavior;
_locale = RETAIN([NSLocale currentLocale]);
_style = NSNumberFormatterDecimalStyle;
_style = NSNumberFormatterNoStyle;
[self _resetUNumberFormat];
if (_formatter == NULL)
{
@ -436,9 +436,6 @@ static NSUInteger _defaultBehavior = 0;
return nil;
}
// Set default values...
[self setMaximumFractionDigits: 2];
return self;
}
@ -721,6 +718,79 @@ static NSUInteger _defaultBehavior = 0;
- (NSString*) stringForObjectValue: (id)anObject
{
if (_behavior == NSNumberFormatterBehaviorDefault
|| _behavior == NSNumberFormatterBehavior10_4)
{
#if GS_USE_ICU == 1
#define STRING_FROM_NUMBER(function, number) do \
{ \
UChar *outStr = buffer; \
UErrorCode err = U_ZERO_ERROR; \
int32_t len; \
NSString *result; \
\
len = function (_formatter, number, outStr, MAX_BUFFER_SIZE, NULL, &err); \
if (len > MAX_BUFFER_SIZE) \
outStr = NSZoneMalloc ([self zone], len * sizeof(UChar));\
err = U_ZERO_ERROR; \
function (_formatter, number, outStr, MAX_BUFFER_SIZE, NULL, &err); \
result = [NSString stringWithCharacters: outStr length: len]; \
if (len > MAX_BUFFER_SIZE) \
NSZoneFree ([self zone], outStr); \
return result; \
} while (0)
// This is quite inefficient. See the GSUText stuff for how
// to use ICU 4.6 UText objects as NSStrings. This saves us from
// needing to do a load of O(n) things. In 4.6, these APIs in ICU
// haven't been updated to use UText (so we have to use the UChar buffer
// approach), but they probably will be in the future. We should
// revisit this code when they have been.
UChar buffer[MAX_BUFFER_SIZE];
// FIXME: What to do with unsigned types?
//
// The only unsigned case we actually need to worry about is unsigned
// long long - all of the others are stored as signed values. We're now
// falling through to the double case for this, which will lose us some
// precision, but hopefully not matter too much...
if (nil == anObject)
return [self nilSymbol];
if (![anObject isKindOfClass: [NSNumber class]])
return [self notANumberSymbol];
switch ([anObject objCType][0])
{
case _C_LNG_LNG:
STRING_FROM_NUMBER(unum_formatInt64, [anObject longLongValue]);
break;
case _C_INT:
STRING_FROM_NUMBER(unum_format, [anObject intValue]);
break;
// Note: This case is probably wrong: the compiler doesn't generate B
// for bool, it generates C or c (depending on the platform). I
// don't think it matters, because we don't bother with anything
// smaller than int for NSNumbers
case _C_BOOL:
STRING_FROM_NUMBER(unum_format, (int)[anObject boolValue]);
break;
// If it's not a type encoding that we recognise, let the receiver
// cast it to a double, which probably has enough precision for what
// we need. This needs testing with NSDecimalNumber though, because
// I managed to break stuff last time I did anything with NSNumber by
// forgetting that NSDecimalNumber existed...
default:
case _C_DBL:
STRING_FROM_NUMBER(unum_formatDouble, [anObject doubleValue]);
break;
case _C_FLT:
STRING_FROM_NUMBER(unum_formatDouble, (double)[anObject floatValue]);
break;
}
}
#endif
else if (_behavior == NSNumberFormatterBehavior10_0)
{
NSMutableDictionary *locale;
NSCharacterSet *formattingCharacters;
NSCharacterSet *placeHolders;
@ -975,6 +1045,8 @@ static NSUInteger _defaultBehavior = 0;
stringByAppendingString: suffix];
[formattedNumber release];
return wholeString;
}
return nil;
}
- (NSDictionary*) textAttributesForNegativeValues
@ -998,75 +1070,7 @@ static NSUInteger _defaultBehavior = 0;
- (NSString *) stringFromNumber: (NSNumber *)number
{
// This is a 10.4 and above method and should not work with earlier version.
#if GS_USE_ICU == 1
#define STRING_FROM_NUMBER(function, number) do \
{ \
UChar *outStr = buffer; \
UErrorCode err = U_ZERO_ERROR; \
int32_t len; \
NSString *result; \
\
len = function (_formatter, number, outStr, MAX_BUFFER_SIZE, NULL, &err); \
if (len > MAX_BUFFER_SIZE) \
outStr = NSZoneMalloc ([self zone], len * sizeof(UChar));\
err = U_ZERO_ERROR; \
function (_formatter, number, outStr, MAX_BUFFER_SIZE, NULL, &err); \
result = [NSString stringWithCharacters: outStr length: len]; \
if (len > MAX_BUFFER_SIZE) \
NSZoneFree ([self zone], outStr); \
return result; \
} while (0)
// This is quite inefficient. See the GSUText stuff for how
// to use ICU 4.6 UText objects as NSStrings. This saves us from
// needing to do a load of O(n) things. In 4.6, these APIs in ICU
// haven't been updated to use UText (so we have to use the UChar buffer
// approach), but they probably will be in the future. We should
// revisit this code when they have been.
UChar buffer[MAX_BUFFER_SIZE];
// FIXME: What to do with unsigned types?
//
// The only unsigned case we actually need to worry about is unsigned
// long long - all of the others are stored as signed values. We're now
// falling through to the double case for this, which will lose us some
// precision, but hopefully not matter too much...
if (nil == number)
return [self nilSymbol];
if (![number isKindOfClass: [NSNumber class]])
return [self notANumberSymbol];
switch ([number objCType][0])
{
case _C_LNG_LNG:
STRING_FROM_NUMBER(unum_formatInt64, [number longLongValue]);
break;
case _C_INT:
STRING_FROM_NUMBER(unum_format, [number intValue]);
break;
// Note: This case is probably wrong: the compiler doesn't generate B
// for bool, it generates C or c (depending on the platform). I
// don't think it matters, because we don't bother with anything
// smaller than int for NSNumbers
case _C_BOOL:
STRING_FROM_NUMBER(unum_format, (int)[number boolValue]);
break;
// If it's not a type encoding that we recognise, let the receiver
// cast it to a double, which probably has enough precision for what
// we need. This needs testing with NSDecimalNumber though, because
// I managed to break stuff last time I did anything with NSNumber by
// forgetting that NSDecimalNumber existed...
default:
case _C_DBL:
STRING_FROM_NUMBER(unum_formatDouble, [number doubleValue]);
break;
case _C_FLT:
STRING_FROM_NUMBER(unum_formatDouble, (double)[number floatValue]);
break;
}
#else
return nil;
#endif
return [self stringForObjectValue: number];
}
- (NSNumber *) numberFromString: (NSString *)string
@ -1990,6 +1994,8 @@ static NSUInteger _defaultBehavior = 0;
_formatter = unum_open (style, NULL, 0, cLocaleId, NULL, &err);
if (U_FAILURE(err))
_formatter = NULL;
[self setMaximumFractionDigits: 0];
#else
return;
#endif