Use new private method to scan double values.

This commit is contained in:
Richard Frith-Macdonald 2020-12-30 12:25:18 +00:00
parent 657e49edeb
commit 3dc437524e
2 changed files with 30 additions and 49 deletions

View file

@ -77,6 +77,7 @@ static Class GSUnicodeStringClass;
static Class GSMutableStringClass;
static Class GSPlaceholderStringClass;
static id _holder;
static NSString *_empty;
static NSCharacterSet *defaultSkipSet;
static SEL memSel;
static NSStringEncoding internalEncoding = NSISOLatin1StringEncoding;
@ -159,6 +160,7 @@ typedef GSString *ivars;
GSMutableStringClass = [GSMutableString class];
GSPlaceholderStringClass = [GSPlaceholderString class];
_holder = (id)NSAllocateObject(GSPlaceholderStringClass, 0, 0);
_empty = [_holder initWithString: @""];
externalEncoding = [NSString defaultCStringEncoding];
if (GSPrivateIsByteEncoding(externalEncoding) == YES)
{
@ -196,9 +198,13 @@ typedef GSString *ivars;
return scanner;
}
- (BOOL) _setString: (NSString*)aString
- (void) _setString: (NSString*)aString
{
_scanLocation = 0;
if (nil == aString)
{
aString = _empty;
}
if (aString != _string)
{
Class c = object_getClass(aString);
@ -216,14 +222,13 @@ typedef GSString *ivars;
{
_string = RETAIN(aString);
}
else if ([aString isKindOfClass: NSStringClass])
else if (GSObjCIsKindOf(c, NSStringClass) == YES)
{
_string = [_holder initWithString: aString];
}
else
{
NSLog(@"Scanner initialised with something not a string");
return NO;
_string = [_holder initWithString: [aString description]];
}
c = object_getClass(_string);
if (GSObjCIsKindOf(c, GSUnicodeStringClass) == YES)
@ -231,11 +236,12 @@ typedef GSString *ivars;
_isUnicode = YES;
}
}
return YES;
}
/** Used by NSString/GSString to avoid creating/destroying a new scanner
* every time we want to scan a double.
* Since this is a private method, we trust that the caller supplies a
* valid string argument.
*/
+ (BOOL) _scanDouble: (double*)value from: (NSString*)str
{
@ -246,12 +252,11 @@ typedef GSString *ivars;
pthread_mutex_lock(&myLock);
if (nil == doubleScanner)
{
doubleScanner = [[self alloc] initWithString: @""];
doubleScanner = [[self alloc] initWithString: _empty];
}
if ([doubleScanner _setString: str])
{
[doubleScanner _setString: str];
ok = [doubleScanner scanDouble: value];
}
[doubleScanner _setString: _empty]; // Release scanned string
pthread_mutex_unlock(&myLock);
return ok;
}
@ -275,16 +280,20 @@ typedef GSString *ivars;
if (aString == nil)
{
NSLog(@"Scanner initialised with nil string");
aString = @"";
aString = _empty;
}
if (NO == [self _setString: aString])
if ([aString isKindOfClass: NSStringClass] == NO)
{
NSLog(@"Scanner initialised with something not a string");
DESTROY(self);
return nil;
}
else
{
[self _setString: aString];
[self setCharactersToBeSkipped: defaultSkipSet];
_decimal = '.';
}
}
return self;
}

View file

@ -67,6 +67,7 @@
#import "Foundation/NSLocale.h"
#import "Foundation/NSLock.h"
#import "Foundation/NSNotification.h"
#import "Foundation/NSScanner.h"
#import "Foundation/NSUserDefaults.h"
#import "Foundation/FoundationErrors.h"
// For private method _decodePropertyListForKey:
@ -127,7 +128,9 @@ uni_tolower(unichar ch)
#import "GNUstepBase/Unicode.h"
extern BOOL GSScanDouble(unichar*, unsigned, double*);
@interface NSScanner (Double)
+ (BOOL) _scanDouble: (double*)value from: (NSString*)str;
@end
@class GSString;
@class GSMutableString;
@ -200,19 +203,6 @@ static inline BOOL isWhiteSpace(unichar c)
#define GS_IS_WHITESPACE(X) isWhiteSpace(X)
static NSCharacterSet *nonspace = nil;
static void setupNonspace(void)
{
if (nil == nonspace)
{
NSCharacterSet *w;
w = [NSCharacterSet whitespaceAndNewlineCharacterSet];
nonspace = [[w invertedSet] retain];
}
}
/* A non-spacing character is one which is part of a 'user-perceived character'
* where the user perceived character consists of a base character followed
@ -3967,17 +3957,8 @@ GSICUCollatorOpen(NSStringCompareOptions mask, NSLocale *locale)
*/
- (double) doubleValue
{
unichar buf[32];
double d = 0.0;
NSRange r;
setupNonspace();
r = [self rangeOfCharacterFromSet: nonspace];
if (NSNotFound == r.location) return 0.0;
r.length = [self length] - r.location;
if (r.length > 32) r.length = 32;
[self getCharacters: buf range: r];
GSScanDouble(buf, r.length, &d);
[NSScanner _scanDouble: &d from: self];
return d;
}
@ -3988,17 +3969,8 @@ GSICUCollatorOpen(NSStringCompareOptions mask, NSLocale *locale)
*/
- (float) floatValue
{
unichar buf[32];
double d = 0.0;
NSRange r;
setupNonspace();
r = [self rangeOfCharacterFromSet: nonspace];
if (NSNotFound == r.location) return 0.0;
r.length = [self length] - r.location;
if (r.length > 32) r.length = 32;
[self getCharacters: buf range: r];
GSScanDouble(buf, r.length, &d);
[NSScanner _scanDouble: &d from: self];
return (float)d;
}