Implemented a few NSNumberFormatter methods.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31862 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Stefan Bidigaray 2011-01-09 20:18:51 +00:00
parent 85149f6b35
commit d3857cd49f
4 changed files with 492 additions and 13 deletions

View file

@ -1,6 +1,12 @@
2011-01-07 Stefan Bidigaray <stefanbidi@gmail.com> 2011-01-09 Stefan Bidigaray <stefanbidi@gmail.com>
* Source/NSLocale.m: Fixed a few errors exposed by testsuite. * Headers/Additions/GNUstepBase/config.h.in:
* Headers/Foundation/NSNumberFormatter.h:
* Source/NSNumberFormatter.m: Started adding code for new methods.
2011-01-08 Stefan Bidigaray <stefanbidi@gmail.com>
* Source/NSLocale.m: Fixed a few bugs exposed by testsuite.
2011-01-07 Stefan Bidigaray <stefanbidi@gmail.com> 2011-01-07 Stefan Bidigaray <stefanbidi@gmail.com>

View file

@ -621,6 +621,9 @@
/* Define to 1 if you have the <unicode/uregex.h> header file. */ /* Define to 1 if you have the <unicode/uregex.h> header file. */
#undef HAVE_UNICODE_UREGEX_H #undef HAVE_UNICODE_UREGEX_H
/* Define to 1 if you have the <unicode/unum.h> header file. */
#undef HAVE_UNICODE_UNUM_H
/* Define to 1 if you have the <unistd.h> header file. */ /* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H #undef HAVE_UNISTD_H

View file

@ -56,7 +56,7 @@ enum
{ {
NSNumberFormatterBehaviorDefault = 0, NSNumberFormatterBehaviorDefault = 0,
NSNumberFormatterBehavior10_0 = 1000, NSNumberFormatterBehavior10_0 = 1000,
NSNumberFormatterBehavior10_4 = 1040, NSNumberFormatterBehavior10_4 = 1040
}; };
typedef NSUInteger NSNumberFormatterBehavior; typedef NSUInteger NSNumberFormatterBehavior;
@ -137,6 +137,13 @@ typedef NSUInteger NSNumberFormatterRoundingMode;
NSString *_positiveFormat; NSString *_positiveFormat;
NSDictionary *_attributesForPositiveValues; NSDictionary *_attributesForPositiveValues;
NSDictionary *_attributesForNegativeValues; NSDictionary *_attributesForNegativeValues;
// 10.4+ variables
NSUInteger _behavior;
BOOL _genDecimal;
NSUInteger _style;
NSLocale *_locale;
void *_formatter;
#endif #endif
#if !GS_NONFRAGILE #if !GS_NONFRAGILE
void *_unused; void *_unused;

View file

@ -42,12 +42,174 @@
#import "GNUstepBase/GSLocale.h" #import "GNUstepBase/GSLocale.h"
@class NSDoubleNumber;
#if defined(HAVE_UNICODE_UNUM_H) #if defined(HAVE_UNICODE_UNUM_H)
# include <unicode/unum.h> # include <unicode/unum.h>
#endif #endif
#define MAX_SYMBOL_SIZE 32
#define MAX_TEXT_ATTRIB_SIZE 512
#if GS_USE_ICU == 1
static inline UNumberFormatStyle
_NSToICUFormatStyle (NSNumberFormatterStyle style)
{
UNumberFormatStyle result;
switch (style)
{
case NSNumberFormatterDecimalStyle:
result = UNUM_DECIMAL;
break;
case NSNumberFormatterCurrencyStyle:
result = UNUM_CURRENCY;
break;
case NSNumberFormatterPercentStyle:
result = UNUM_PERCENT;
break;
case NSNumberFormatterScientificStyle:
result = UNUM_SCIENTIFIC;
break;
case NSNumberFormatterSpellOutStyle:
result = UNUM_SPELLOUT;
break;
case NSNumberFormatterNoStyle:
default:
result = UNUM_IGNORE;
}
return result;
}
static inline UNumberFormatPadPosition
_NSToICUPadPosition (NSNumberFormatterPadPosition position)
{
UNumberFormatPadPosition result;
switch (position)
{
case NSNumberFormatterPadBeforePrefix:
result = UNUM_PAD_BEFORE_PREFIX;
break;
case NSNumberFormatterPadAfterPrefix:
result = UNUM_PAD_AFTER_PREFIX;
break;
case NSNumberFormatterPadBeforeSuffix:
result = UNUM_PAD_BEFORE_SUFFIX;
break;
case NSNumberFormatterPadAfterSuffix:
result = UNUM_PAD_AFTER_SUFFIX;
break;
}
return result;
}
static inline NSNumberFormatterPadPosition
_ICUToNSPadPosition (UNumberFormatPadPosition position)
{
NSNumberFormatterPadPosition result;
switch (position)
{
case UNUM_PAD_BEFORE_PREFIX:
result = NSNumberFormatterPadBeforePrefix;
break;
case UNUM_PAD_AFTER_PREFIX:
result = NSNumberFormatterPadAfterPrefix;
break;
case UNUM_PAD_BEFORE_SUFFIX:
result = NSNumberFormatterPadBeforeSuffix;
break;
case UNUM_PAD_AFTER_SUFFIX:
result = NSNumberFormatterPadAfterSuffix;
break;
}
return result;
}
static inline UNumberFormatRoundingMode
_NSToICURoundingMode (NSNumberFormatterRoundingMode mode)
{
UNumberFormatRoundingMode result = 0;
switch (mode)
{
case NSNumberFormatterRoundCeiling:
result = UNUM_ROUND_CEILING;
break;
case NSNumberFormatterRoundFloor:
result = UNUM_ROUND_FLOOR;
break;
case NSNumberFormatterRoundDown:
result = UNUM_ROUND_DOWN;
break;
case NSNumberFormatterRoundUp:
result = UNUM_ROUND_UP;
break;
case NSNumberFormatterRoundHalfEven:
result = UNUM_ROUND_HALFEVEN;
break;
case NSNumberFormatterRoundHalfDown:
result = UNUM_ROUND_HALFDOWN;
break;
case NSNumberFormatterRoundHalfUp:
result = UNUM_ROUND_HALFUP;
break;
}
return result;
}
static inline NSNumberFormatterRoundingMode
_ICUToNSRoundingMode (UNumberFormatRoundingMode mode)
{
NSNumberFormatterRoundingMode result = 0;
switch (mode)
{
case UNUM_ROUND_CEILING:
result = NSNumberFormatterRoundCeiling;
break;
case UNUM_ROUND_FLOOR:
result = NSNumberFormatterRoundFloor;
break;
case UNUM_ROUND_DOWN:
result = NSNumberFormatterRoundDown;
break;
case UNUM_ROUND_UP:
result = NSNumberFormatterRoundUp;
break;
case UNUM_ROUND_HALFEVEN:
result = NSNumberFormatterRoundHalfEven;
break;
case UNUM_ROUND_HALFDOWN:
result = NSNumberFormatterRoundHalfDown;
break;
case UNUM_ROUND_HALFUP:
result = NSNumberFormatterRoundHalfUp;
break;
}
return result;
}
#endif
@interface NSNumberFormatter (PrivateMethods)
- (void) _openUNumberFormat;
- (void) _closeUNumberFormat;
- (void) _setSymbol: (NSString *) string : (NSInteger) symbol;
- (NSString *) _getSymbol: (NSInteger) symbol;
- (void) _setTextAttribute: (NSString *) string : (NSInteger) attrib;
- (NSString *) _getTextAttribute: (NSInteger) attrib;
@end
@implementation NSNumberFormatter @implementation NSNumberFormatter
static NSUInteger _defaultBehavior = 0;
- (BOOL) allowsFloats - (BOOL) allowsFloats
{ {
return _allowsFloats; return _allowsFloats;
@ -138,6 +300,8 @@
RELEASE(_attributedStringForNil); RELEASE(_attributedStringForNil);
RELEASE(_attributedStringForNotANumber); RELEASE(_attributedStringForNotANumber);
RELEASE(_attributedStringForZero); RELEASE(_attributedStringForZero);
RELEASE(_locale);
[self _closeUNumberFormat];
[super dealloc]; [super dealloc];
} }
@ -249,6 +413,10 @@
[self setAttributedStringForNotANumber: o]; [self setAttributedStringForNotANumber: o];
RELEASE(o); RELEASE(o);
_behavior = _defaultBehavior;
_locale = [NSLocale currentLocale];
[self _openUNumberFormat];
return self; return self;
} }
@ -812,156 +980,252 @@
- (void) setFormatterBehavior: (NSNumberFormatterBehavior) behavior - (void) setFormatterBehavior: (NSNumberFormatterBehavior) behavior
{ {
return; _behavior = behavior;
} }
- (NSNumberFormatterBehavior) formatterBehavior - (NSNumberFormatterBehavior) formatterBehavior
{ {
return 0; return _behavior;
} }
+ (void) setDefaultFormatterBehavior: (NSNumberFormatterBehavior) behavior + (void) setDefaultFormatterBehavior: (NSNumberFormatterBehavior) behavior
{ {
return; _defaultBehavior = behavior;
} }
+ (NSNumberFormatterBehavior) defaultFormatterBehavior + (NSNumberFormatterBehavior) defaultFormatterBehavior
{ {
return 0; return _defaultBehavior;
} }
- (void) setNumberStyle: (NSNumberFormatterStyle) style - (void) setNumberStyle: (NSNumberFormatterStyle) style
{ {
return; [self _closeUNumberFormat];
_style = style;
[self _openUNumberFormat];
} }
- (NSNumberFormatterStyle) numberStyle - (NSNumberFormatterStyle) numberStyle
{ {
return 0; return _style;
} }
- (void) setGeneratesDecimalNumbers: (BOOL) flag - (void) setGeneratesDecimalNumbers: (BOOL) flag
{ {
return; _genDecimal = flag;
} }
- (BOOL) generatesDecimalNubmers - (BOOL) generatesDecimalNubmers
{ {
return NO; return _genDecimal;
} }
- (void) setLocale: (NSLocale *) locale - (void) setLocale: (NSLocale *) locale
{ {
return; RELEASE(_locale);
[self _closeUNumberFormat];
if (locale == nil)
locale = [NSLocale currentLocale];
_locale = RETAIN(locale);
[self _openUNumberFormat];
} }
- (NSLocale *) locale - (NSLocale *) locale
{ {
return nil; return _locale;
} }
- (void) setRoundingIncrement: (NSNumber *) number - (void) setRoundingIncrement: (NSNumber *) number
{ {
#if GS_USE_ICU == 1
if ([number class] == [NSDoubleNumber class])
unum_setDoubleAttribute (_formatter, UNUM_ROUNDING_INCREMENT,
[number doubleValue]);
#else
return; return;
#endif
} }
- (NSNumber *) roundingIncrement - (NSNumber *) roundingIncrement
{ {
#if GS_USE_ICU == 1
double value = unum_getDoubleAttribute (_formatter, UNUM_ROUNDING_INCREMENT);
return [NSNumber numberWithDouble: value];
#else
return nil; return nil;
#endif
} }
- (void) setRoundingMode: (NSNumberFormatterRoundingMode) mode - (void) setRoundingMode: (NSNumberFormatterRoundingMode) mode
{ {
#if GS_USE_ICU == 1
unum_setAttribute (_formatter, UNUM_ROUNDING_MODE,
_NSToICURoundingMode(mode));
#else
return; return;
#endif
} }
- (NSNumberFormatterRoundingMode) roundingMode - (NSNumberFormatterRoundingMode) roundingMode
{ {
#if GS_USE_ICU == 1
return _ICUToNSRoundingMode (unum_getAttribute (_formatter,
UNUM_ROUNDING_MODE));
#else
return 0; return 0;
#endif
} }
- (void) setFormatWidth: (NSUInteger) number - (void) setFormatWidth: (NSUInteger) number
{ {
#if GS_USE_ICU == 1
unum_setAttribute (_formatter, UNUM_FORMAT_WIDTH, (int32_t)number);
#else
return; return;
#endif
} }
- (NSUInteger) formatWidth - (NSUInteger) formatWidth
{ {
#if GS_USE_ICU == 1
return (NSUInteger)unum_getAttribute (_formatter, UNUM_FORMAT_WIDTH);
#else
return 0; return 0;
#endif
} }
- (void) setMultiplier: (NSNumber *) number - (void) setMultiplier: (NSNumber *) number
{ {
#if GS_USE_ICU == 1
double value = [number doubleValue];
unum_setDoubleAttribute (_formatter, UNUM_MULTIPLIER, value);
#else
return; return;
#endif
} }
- (NSNumber *) multiplier - (NSNumber *) multiplier
{ {
#if GS_USE_ICU == 1
double value = unum_getDoubleAttribute (_formatter, UNUM_MULTIPLIER);
return [NSNumber numberWithDouble: value];
#else
return nil; return nil;
#endif
} }
- (void) setPercentSymbol: (NSString *) string - (void) setPercentSymbol: (NSString *) string
{ {
#if GS_USE_ICU == 1
[self _setSymbol: string : UNUM_PERCENT_SYMBOL];
#else
return; return;
#endif
} }
- (NSString *) percentSymbol - (NSString *) percentSymbol
{ {
#if GS_USE_ICU == 1
return [self _getSymbol: UNUM_PERCENT_SYMBOL];
#else
return nil; return nil;
#endif
} }
- (void) setPerMillSymbol: (NSString *) string - (void) setPerMillSymbol: (NSString *) string
{ {
#if GS_USE_ICU == 1
[self _setSymbol: string : UNUM_PERMILL_SYMBOL];
#else
return; return;
#endif
} }
- (NSString *) perMillSymbol - (NSString *) perMillSymbol
{ {
#if GS_USE_ICU == 1
return [self _getSymbol: UNUM_PERMILL_SYMBOL];
#else
return nil; return nil;
#endif
} }
- (void) setMinusSign: (NSString *) string - (void) setMinusSign: (NSString *) string
{ {
#if GS_USE_ICU == 1
[self _setSymbol: string : UNUM_MINUS_SIGN_SYMBOL];
#else
return; return;
#endif
} }
- (NSString *) minusSign - (NSString *) minusSign
{ {
#if GS_USE_ICU == 1
return [self _getSymbol: UNUM_MINUS_SIGN_SYMBOL];
#else
return nil; return nil;
#endif
} }
- (void) setPlusSign: (NSString *) string - (void) setPlusSign: (NSString *) string
{ {
#if GS_USE_ICU == 1
[self _setSymbol: string : UNUM_PLUS_SIGN_SYMBOL];
#else
return; return;
#endif
} }
- (NSString *) plusSign - (NSString *) plusSign
{ {
#if GS_USE_ICU == 1
return [self _getSymbol: UNUM_PLUS_SIGN_SYMBOL];
#else
return nil; return nil;
#endif
} }
- (void) setExponentSymbol: (NSString *) string - (void) setExponentSymbol: (NSString *) string
{ {
#if GS_USE_ICU == 1
[self _setSymbol: string : UNUM_EXPONENTIAL_SYMBOL];
#else
return; return;
#endif
} }
- (NSString *) exponentSymbol - (NSString *) exponentSymbol
{ {
#if GS_USE_ICU == 1
return [self _getSymbol: UNUM_EXPONENTIAL_SYMBOL];
#else
return nil; return nil;
#endif
} }
- (void) setZeroSymbol: (NSString *) string - (void) setZeroSymbol: (NSString *) string
{ {
#if GS_USE_ICU == 1
[self _setSymbol: string : UNUM_ZERO_DIGIT_SYMBOL];
#else
return; return;
#endif
} }
- (NSString *) zeroSymbol - (NSString *) zeroSymbol
{ {
#if GS_USE_ICU == 1
return [self _getSymbol: UNUM_ZERO_DIGIT_SYMBOL];
#else
return nil; return nil;
#endif
} }
- (void) setNilSymbol: (NSString *) string - (void) setNilSymbol: (NSString *) string
@ -976,43 +1240,77 @@
- (void) setNotANumberSymbol: (NSString *) string - (void) setNotANumberSymbol: (NSString *) string
{ {
#if GS_USE_ICU == 1
[self _setSymbol: string : UNUM_NAN_SYMBOL];
#else
return; return;
#endif
} }
- (NSString *) notANumberSymbol - (NSString *) notANumberSymbol
{ {
#if GS_USE_ICU == 1
return [self _getSymbol: UNUM_NAN_SYMBOL];
#else
return nil; return nil;
#endif
} }
- (void) setNegativeInfinitySymbol: (NSString *) string - (void) setNegativeInfinitySymbol: (NSString *) string
{ {
#if GS_USE_ICU == 1
// FIXME: ICU doesn't differenciate between positive and negative infinity.
[self _setSymbol: string : UNUM_INFINITY_SYMBOL];
#else
return; return;
#endif
} }
- (NSString *) negativeInfinitySymbol - (NSString *) negativeInfinitySymbol
{ {
#if GS_USE_ICU == 1
return [self _getSymbol: UNUM_INFINITY_SYMBOL];
#else
return nil; return nil;
#endif
} }
- (void) setPositiveInfinitySymbol: (NSString *) string - (void) setPositiveInfinitySymbol: (NSString *) string
{ {
#if GS_USE_ICU == 1
// FIXME: ICU doesn't differenciate between positive and negative infinity.
[self _setSymbol: string : UNUM_INFINITY_SYMBOL];
#else
return; return;
#endif
} }
- (NSString *) positiveInfinitySymbol - (NSString *) positiveInfinitySymbol
{ {
#if GS_USE_ICU == 1
return [self _getSymbol: UNUM_INFINITY_SYMBOL];
#else
return nil; return nil;
#endif
} }
- (void) setCurrencySymbol: (NSString *) string - (void) setCurrencySymbol: (NSString *) string
{ {
#if GS_USE_ICU == 1
[self _setSymbol: string : UNUM_CURRENCY_SYMBOL];
#else
return; return;
#endif
} }
- (NSString *) currencySymbol - (NSString *) currencySymbol
{ {
#if GS_USE_ICU == 1
return [self _getSymbol: UNUM_CURRENCY_SYMBOL];
#else
return nil; return nil;
#endif
} }
- (void) setCurrencyCode: (NSString *) string - (void) setCurrencyCode: (NSString *) string
@ -1027,18 +1325,30 @@
- (void) setInternationalCurrencySymbol: (NSString *) string - (void) setInternationalCurrencySymbol: (NSString *) string
{ {
#if GS_USE_ICU == 1
[self _setSymbol: string : UNUM_INTL_CURRENCY_SYMBOL];
#else
return; return;
#endif
} }
- (NSString *) internationalCurrencySymbol - (NSString *) internationalCurrencySymbol
{ {
#if GS_USE_ICU == 1
return [self _getSymbol: UNUM_INTL_CURRENCY_SYMBOL];
#else
return nil; return nil;
#endif
} }
- (void) setPositivePrefix: (NSString *) string - (void) setPositivePrefix: (NSString *) string
{ {
#if GS_USE_ICU == 1
[self _setTextAttribute: string : UNUM_POSITIVE_PREFIX];
#else
return; return;
#endif
} }
- (NSString *) positivePrefix - (NSString *) positivePrefix
@ -1130,12 +1440,20 @@
- (void) setGroupingSeparator: (NSString *) string - (void) setGroupingSeparator: (NSString *) string
{ {
#if GS_USE_ICU == 1
[self _setSymbol: string : UNUM_GROUPING_SEPARATOR_SYMBOL];
#else
return; return;
#endif
} }
- (NSString *) groupingSeparator - (NSString *) groupingSeparator
{ {
#if GS_USE_ICU == 1
return [self _getSymbol: UNUM_GROUPING_SEPARATOR_SYMBOL];
#else
return nil; return nil;
#endif
} }
- (void) setUsesGroupingSeparator: (BOOL) flag - (void) setUsesGroupingSeparator: (BOOL) flag
@ -1160,12 +1478,20 @@
- (void) setCurrencyDecimalSeparator: (NSString *) string - (void) setCurrencyDecimalSeparator: (NSString *) string
{ {
#if GS_USE_ICU == 1
[self _setSymbol: string : UNUM_MONETARY_SEPARATOR_SYMBOL];
#else
return; return;
#endif
} }
- (NSString *) currencyDecimalSeparator - (NSString *) currencyDecimalSeparator
{ {
#if GS_USE_ICU == 1
return [self _getSymbol: UNUM_MONETARY_SEPARATOR_SYMBOL];
#else
return nil; return nil;
#endif
} }
- (void) setGroupingSize: (NSUInteger) number - (void) setGroupingSize: (NSUInteger) number
@ -1293,12 +1619,20 @@
- (void) setCurrencyGroupingSeparator: (NSString *) string - (void) setCurrencyGroupingSeparator: (NSString *) string
{ {
#if GS_USE_ICU == 1
[self _setSymbol: string : UNUM_MONETARY_GROUPING_SEPARATOR_SYMBOL];
#else
return; return;
#endif
} }
- (NSString *) currencyGroupingSeparator - (NSString *) currencyGroupingSeparator
{ {
#if GS_USE_ICU == 1
return [self _getSymbol: UNUM_MONETARY_GROUPING_SEPARATOR_SYMBOL];
#else
return nil; return nil;
#endif
} }
@ -1331,3 +1665,132 @@
} }
@end @end
@implementation NSNumberFormatter (PrivateMethods)
- (void) _openUNumberFormat
{
#if GS_USE_ICU == 1
UNumberFormatStyle style;
UErrorCode err = U_ZERO_ERROR;
const char *cLocaleId;
cLocaleId = [[_locale localeIdentifier] UTF8String];
style = _NSToICUFormatStyle (_style);
_formatter = unum_open (style, NULL, 0, cLocaleId, NULL, &err);
if (U_FAILURE(err))
_formatter = NULL;
#else
return;
#endif
}
- (void) _closeUNumberFormat
{
#if GS_USE_ICU == 1
unum_close (_formatter);
#else
return;
#endif
}
- (void) _setSymbol: (NSString *) string : (NSInteger) symbol
{
#if GS_USE_ICU == 1
unichar buffer[MAX_SYMBOL_SIZE];
unichar *str = buffer;
NSUInteger length;
UErrorCode err = U_ZERO_ERROR;
length = [string length];
if (length > MAX_SYMBOL_SIZE)
str = (unichar *)NSZoneMalloc ([self zone], length);
[string getCharacters: str range: NSMakeRange (0, length)];
unum_setSymbol (_formatter, symbol, str, length, &err);
if (length > MAX_SYMBOL_SIZE)
NSZoneFree ([self zone], str);
#else
return;
#endif
}
- (NSString *) _getSymbol: (NSInteger) symbol
{
#if GS_USE_ICU == 1
UChar buffer[MAX_SYMBOL_SIZE];
UChar *str = buffer;
int32_t length;
UErrorCode err = U_ZERO_ERROR;
NSString *result;
length = unum_getSymbol (_formatter, symbol, str,
MAX_SYMBOL_SIZE, &err);
if (length > MAX_SYMBOL_SIZE)
{
str = (UChar *)NSZoneMalloc ([self zone], length);
length = unum_getSymbol (_formatter, symbol, str,
length, &err);
}
result = [NSString stringWithCharacters: str length: length];
if (length > MAX_SYMBOL_SIZE)
NSZoneFree ([self zone], str);
return result;
#else
return nil;
#endif
}
- (void) _setTextAttribute: (NSString *) string : (NSInteger) attrib
{
#if GS_USE_ICU == 1
unichar buffer[MAX_TEXT_ATTRIB_SIZE];
unichar *str = buffer;
NSUInteger length;
UErrorCode err = U_ZERO_ERROR;
length = [string length];
if (length > MAX_TEXT_ATTRIB_SIZE)
str = (unichar *)NSZoneMalloc ([self zone], length);
[string getCharacters: str range: NSMakeRange (0, length)];
unum_setTextAttribute (_formatter, attrib, str, length, &err);
if (length > MAX_TEXT_ATTRIB_SIZE)
NSZoneFree ([self zone], str);
#else
return;
#endif
}
- (NSString *) _getTextAttribute: (NSInteger) attrib
{
#if GS_USE_ICU == 1
UChar buffer[MAX_TEXT_ATTRIB_SIZE];
UChar *str = buffer;
int32_t length;
UErrorCode err = U_ZERO_ERROR;
NSString *result;
length = unum_getTextAttribute (_formatter, attrib, str,
MAX_TEXT_ATTRIB_SIZE, &err);
if (length > MAX_TEXT_ATTRIB_SIZE)
{
str = (UChar *)NSZoneMalloc ([self zone], length);
length = unum_getTextAttribute (_formatter, attrib, str,
length, &err);
}
result = [NSString stringWithCharacters: str length: length];
if (length > MAX_TEXT_ATTRIB_SIZE)
NSZoneFree ([self zone], str);
return result;
#else
return nil;
#endif
}
@end