More optimisation - removed a couple of private methods and replaced them

with macros for skipping to next field.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@4884 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
richard 1999-09-13 08:52:57 +00:00
parent 92a427d24f
commit 3881c29981
3 changed files with 271 additions and 181 deletions

View file

@ -2,6 +2,7 @@ Mon Sep 13 6:45:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
Miscellaneous minor bugfixes plyus, Miscellaneous minor bugfixes plyus,
* Source/NSScanner.m: optimised (well, mostly). * Source/NSScanner.m: optimised (well, mostly).
* Headers/Foundation/NSScanner.h: update for optimisatio).
Sun Sep 12 20:22:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk> Sun Sep 12 20:22:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>

View file

@ -1,5 +1,5 @@
/* Definitions for NSScanner class /* Definitions for NSScanner class
Copyright (C) 1996 Free Software Foundation, Inc. Copyright (C) 1996,1999 Free Software Foundation, Inc.
Author: Eric Norum <eric@skatter.usask.ca> Author: Eric Norum <eric@skatter.usask.ca>
Created: 1996 Created: 1996
@ -25,65 +25,74 @@
#define __NSScanner_h_GNUSTEP_INCLUDE #define __NSScanner_h_GNUSTEP_INCLUDE
#include <base/preface.h> #include <base/preface.h>
#include <Foundation/NSDecimal.h>
#include <Foundation/NSDictionary.h> #include <Foundation/NSDictionary.h>
#include <Foundation/NSCharacterSet.h> #include <Foundation/NSCharacterSet.h>
// /*
// NSScanner class * NSScanner class
// */
@interface NSScanner : NSObject <NSCopying> @interface NSScanner : NSObject <NSCopying>
{ {
@private @private
NSString *string; NSString *string;
unsigned int len; NSCharacterSet *charactersToBeSkipped;
NSCharacterSet *charactersToBeSkipped; BOOL (*skipImp)(NSCharacterSet*, SEL, unichar);
NSDictionary *locale; NSDictionary *locale;
unsigned int scanLocation; unsigned int scanLocation;
BOOL caseSensitive; unichar decimal;
BOOL caseSensitive;
BOOL isUnicode;
} }
/* /*
* Creating an NSScanner * Creating an NSScanner
*/ */
+ localizedScannerWithString:(NSString *)aString; + (id) localizedScannerWithString: (NSString*)aString;
+ scannerWithString:(NSString *)aString; + (id) scannerWithString: (NSString*)aString;
- initWithString:(NSString *)aString; - (id) initWithString: (NSString*)aString;
/* /*
* Getting an NSScanner's string * Getting an NSScanner's string
*/ */
- (NSString *)string; - (NSString*) string;
/* /*
* Configuring an NSScanner * Configuring an NSScanner
*/ */
- (unsigned)scanLocation; - (unsigned) scanLocation;
- (void)setScanLocation:(unsigned int)anIndex; - (void) setScanLocation: (unsigned int)anIndex;
- (BOOL)caseSensitive;
- (void)setCaseSensitive:(BOOL)flag; - (BOOL) caseSensitive;
- (NSCharacterSet *)charactersToBeSkipped; - (void) setCaseSensitive: (BOOL)flag;
- (void)setCharactersToBeSkipped:(NSCharacterSet *)aSet;
- (NSDictionary *)locale; - (NSCharacterSet*) charactersToBeSkipped;
- (void)setLocale:(NSDictionary *)localeDictionary; - (void) setCharactersToBeSkipped: (NSCharacterSet *)aSet;
- (NSDictionary*)locale;
- (void)setLocale:(NSDictionary*)localeDictionary;
/* /*
* Scanning a string * Scanning a string
*/ */
- (BOOL)scanInt:(int *)value; - (BOOL) scanInt: (int*)value;
- (BOOL)scanInt:(int *)value; - (BOOL) scanInt: (int*)value;
- (BOOL)scanHexInt:(unsigned int *)value; - (BOOL) scanHexInt: (unsigned int*)value;
- (BOOL)scanRadixUnsignedInt:(unsigned int *)value; - (BOOL) scanRadixUnsignedInt: (unsigned int*)value;
- (BOOL)scanLongLong:(long long *)value; - (BOOL) scanLongLong: (long long*)value;
- (BOOL)scanFloat:(float *)value; - (BOOL) scanFloat: (float*)value;
- (BOOL)scanDouble:(double *)value; - (BOOL) scanDouble: (double*)value;
- (BOOL)scanString:(NSString *)string intoString:(NSString **)value; - (BOOL) scanString: (NSString*)string intoString: (NSString**)value;
- (BOOL)scanCharactersFromSet:(NSCharacterSet *)aSet - (BOOL) scanCharactersFromSet: (NSCharacterSet*)aSet
intoString:(NSString **)value; intoString: (NSString**)value;
- (BOOL)scanUpToString:(NSString *)string intoString:(NSString **)value; - (BOOL) scanUpToString: (NSString*)string intoString: (NSString**)value;
- (BOOL)scanUpToCharactersFromSet:(NSCharacterSet *)aSet - (BOOL) scanUpToCharactersFromSet: (NSCharacterSet*)aSet
intoString:(NSString **)value; intoString: (NSString**)value;
- (BOOL)isAtEnd; - (BOOL) isAtEnd;
#ifndef STRICT_OPENSTEP
- (BOOL) scanDecimal: (NSDecimal*)value;
#endif
@end @end
#endif /* __NSScanner_h_GNUSTEP_INCLUDE */ #endif /* __NSScanner_h_GNUSTEP_INCLUDE */

View file

@ -1,5 +1,5 @@
/* Implemenation of NSScanner class /* Implemenation of NSScanner class
Copyright (C) 1996 Free Software Foundation, Inc. Copyright (C) 1996,1999 Free Software Foundation, Inc.
Author: Eric Norum <eric@skatter.usask.ca> Author: Eric Norum <eric@skatter.usask.ca>
Date: 1996 Date: 1996
@ -23,9 +23,11 @@
#include <config.h> #include <config.h>
#include <base/fast.x> #include <base/fast.x>
#include <base/Unicode.h>
#include <Foundation/NSScanner.h> #include <Foundation/NSScanner.h>
#include <Foundation/NSException.h> #include <Foundation/NSException.h>
#include <Foundation/NSGString.h> #include <Foundation/NSGString.h>
#include <Foundation/NSGCString.h>
#include <Foundation/NSUserDefaults.h> #include <Foundation/NSUserDefaults.h>
#include <float.h> #include <float.h>
#include <limits.h> #include <limits.h>
@ -36,16 +38,37 @@
static Class NSString_class; static Class NSString_class;
static Class NSGString_class; static Class NSGString_class;
static Class NSGCString_class;
static NSCharacterSet *defaultSkipSet; static NSCharacterSet *defaultSkipSet;
static SEL memSel = @selector(characterIsMember:); static SEL memSel = @selector(characterIsMember:);
/* /*
* Hack for direct access to internals of an NSGString object. * Hack for direct access to internals of an NSGString object.
* NB. layout of NSGString and NSGCString must be the same as far as _count
*/ */
typedef struct { typedef struct {
@defs(NSGString) @defs(NSGString)
} *stringAccess; } *stringAccess;
#define charAtIndex(I) ((stringAccess)string)->_contents_chars[I] typedef struct {
@defs(NSGCString)
} *cStringAccess;
#define myLength() (((stringAccess)string)->_count)
#define myUnicode(I) (((stringAccess)string)->_contents_chars[I])
#define myChar(I) chartouni((((cStringAccess)string)->_contents_chars[I]))
#define myCharacter(I) (isUnicode ? myUnicode(I) : myChar(I))
/*
* Scan characters to be skipped.
* Return YES if there are more characters to be scanned.
* Return NO if the end of the string is reached.
* For internal use only.
*/
#define skipToNextField() ({ \
while (scanLocation < myLength() \
&& (*skipImp)(charactersToBeSkipped, memSel, myUnicode(scanLocation))) \
scanLocation++; \
(scanLocation >= myLength()) ? NO : YES; \
})
+ (void) initialize + (void) initialize
{ {
@ -55,6 +78,7 @@ typedef struct {
RETAIN(defaultSkipSet); RETAIN(defaultSkipSet);
NSString_class = [NSString class]; NSString_class = [NSString class];
NSGString_class = [NSGString class]; NSGString_class = [NSGString class];
NSGCString_class = [NSGCString class];
} }
} }
@ -63,15 +87,20 @@ typedef struct {
*/ */
+ (id) scannerWithString: (NSString *)aString + (id) scannerWithString: (NSString *)aString
{ {
return AUTORELEASE([[self alloc] initWithString: aString]); return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()]
initWithString: aString]);
} }
+ (id) localizedScannerWithString: (NSString*)aString + (id) localizedScannerWithString: (NSString*)aString
{ {
NSScanner *scanner = [self scannerWithString: aString]; NSScanner *scanner = [self scannerWithString: aString];
NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
scanner->locale = RETAIN([defs dictionaryRepresentation]); if (scanner != nil)
{
NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
[scanner setLocale: [defs dictionaryRepresentation]];
}
return scanner; return scanner;
} }
@ -86,17 +115,28 @@ typedef struct {
* Ensure that we have an NSGString so we can access its internals directly. * Ensure that we have an NSGString so we can access its internals directly.
*/ */
if (fastClass(aString) == NSGString_class) if (fastClass(aString) == NSGString_class)
string = RETAIN(aString); {
isUnicode = YES;
string = RETAIN(aString);
}
else if (fastClass(aString) == NSGCString_class)
{
isUnicode = NO;
string = RETAIN(aString);
}
else if ([aString isKindOfClass: NSString_class]) else if ([aString isKindOfClass: NSString_class])
string = [[NSGString_class alloc] initWithString: aString]; {
isUnicode = YES;
string = [[NSGString_class alloc] initWithString: aString];
}
else else
{ {
[self dealloc]; [self dealloc];
[NSException raise: NSInvalidArgumentException [NSException raise: NSInvalidArgumentException
format: @"Scanner initialised with something not a string"]; format: @"Scanner initialised with something not a string"];
} }
len = [string length]; [self setCharactersToBeSkipped: defaultSkipSet];
charactersToBeSkipped = RETAIN(defaultSkipSet); decimal = '.';
return self; return self;
} }
@ -111,53 +151,6 @@ typedef struct {
[super dealloc]; [super dealloc];
} }
/*
* Like scanCharactersFromSet: intoString: but no initial skip
* For internal use only.
*/
- (BOOL) _scanCharactersFromSet: (NSCharacterSet *)set
intoString: (NSString **)value;
{
unsigned int start;
BOOL (*memImp)(NSCharacterSet*, SEL, unichar);
if (scanLocation >= len)
return NO;
memImp = (BOOL (*)(NSCharacterSet*, SEL, unichar))
[set methodForSelector: memSel];
start = scanLocation;
while (scanLocation < len)
{
if ((*memImp)(set, memSel, charAtIndex(scanLocation)) == NO)
break;
scanLocation++;
}
if (scanLocation == start)
return NO;
if (value)
{
NSRange range;
range.location = start;
range.length = scanLocation - start;
*value = [string substringFromRange: range];
}
return YES;
}
/*
* Scan characters to be skipped.
* Return YES if there are more characters to be scanned.
* Return NO if the end of the string is reached.
* For internal use only.
*/
- (BOOL) _skipToNextField
{
[self _scanCharactersFromSet: charactersToBeSkipped intoString: NULL];
if (scanLocation >= len)
return NO;
return YES;
}
/* /*
* Returns YES if no more characters remain to be scanned. * Returns YES if no more characters remain to be scanned.
* Returns YES if all characters remaining to be scanned are to be skipped. * Returns YES if all characters remaining to be scanned are to be skipped.
@ -165,13 +158,13 @@ typedef struct {
*/ */
- (BOOL) isAtEnd - (BOOL) isAtEnd
{ {
unsigned int save_scanLocation; unsigned int save_scanLocation;
BOOL ret; BOOL ret;
if (scanLocation >= len) if (scanLocation >= myLength())
return YES; return YES;
save_scanLocation = scanLocation; save_scanLocation = scanLocation;
ret = ![self _skipToNextField]; ret = !skipToNextField();
scanLocation = save_scanLocation; scanLocation = save_scanLocation;
return ret; return ret;
} }
@ -198,9 +191,9 @@ typedef struct {
BOOL got_digits = NO; BOOL got_digits = NO;
/* Check for sign */ /* Check for sign */
if (scanLocation < len) if (scanLocation < myLength())
{ {
switch (charAtIndex(scanLocation)) switch (myCharacter(scanLocation))
{ {
case '+': case '+':
scanLocation++; scanLocation++;
@ -213,17 +206,19 @@ typedef struct {
} }
/* Process digits */ /* Process digits */
while (scanLocation < len) while (scanLocation < myLength())
{ {
unichar digit = charAtIndex(scanLocation); unichar digit = myCharacter(scanLocation);
if ((digit < '0') || (digit > '9')) if ((digit < '0') || (digit > '9'))
break; break;
if (!overflow) { if (!overflow)
if (num >= limit) {
overflow = YES; if (num >= limit)
else overflow = YES;
num = num * 10 + (digit - '0'); else
} num = num * 10 + (digit - '0');
}
scanLocation++; scanLocation++;
got_digits = YES; got_digits = YES;
} }
@ -251,7 +246,7 @@ typedef struct {
{ {
unsigned int saveScanLocation = scanLocation; unsigned int saveScanLocation = scanLocation;
if ([self _skipToNextField] && [self _scanInt: value]) if (skipToNextField() && [self _scanInt: value])
return YES; return YES;
scanLocation = saveScanLocation; scanLocation = saveScanLocation;
return NO; return NO;
@ -265,19 +260,20 @@ typedef struct {
radix: (int)radix radix: (int)radix
gotDigits: (BOOL)gotDigits gotDigits: (BOOL)gotDigits
{ {
unsigned int num = 0; unsigned int num = 0;
unsigned int numLimit, digitLimit, digitValue; unsigned int numLimit, digitLimit, digitValue;
BOOL overflow = NO; BOOL overflow = NO;
unsigned int saveScanLocation = scanLocation; unsigned int saveScanLocation = scanLocation;
/* Set limits */ /* Set limits */
numLimit = UINT_MAX / radix; numLimit = UINT_MAX / radix;
digitLimit = UINT_MAX % radix; digitLimit = UINT_MAX % radix;
/* Process digits */ /* Process digits */
while (scanLocation < len) while (scanLocation < myLength())
{ {
unichar digit = charAtIndex(scanLocation); unichar digit = myCharacter(scanLocation);
switch (digit) switch (digit)
{ {
case '0': digitValue = 0; break; case '0': digitValue = 0; break;
@ -341,12 +337,12 @@ typedef struct {
*/ */
- (BOOL) scanRadixUnsignedInt: (unsigned int *)value - (BOOL) scanRadixUnsignedInt: (unsigned int *)value
{ {
int radix; int radix;
BOOL gotDigits = NO; BOOL gotDigits = NO;
unsigned int saveScanLocation = scanLocation; unsigned int saveScanLocation = scanLocation;
/* Skip whitespace */ /* Skip whitespace */
if (![self _skipToNextField]) if (!skipToNextField())
{ {
scanLocation = saveScanLocation; scanLocation = saveScanLocation;
return NO; return NO;
@ -354,14 +350,14 @@ typedef struct {
/* Check radix */ /* Check radix */
radix = 10; radix = 10;
if ((scanLocation < len) && (charAtIndex(scanLocation) == '0')) if ((scanLocation < myLength()) && (myCharacter(scanLocation) == '0'))
{ {
radix = 8; radix = 8;
scanLocation++; scanLocation++;
gotDigits = YES; gotDigits = YES;
if (scanLocation < len) if (scanLocation < myLength())
{ {
switch (charAtIndex(scanLocation)) switch (myCharacter(scanLocation))
{ {
case 'x': case 'x':
case 'X': case 'X':
@ -386,7 +382,7 @@ typedef struct {
unsigned int saveScanLocation = scanLocation; unsigned int saveScanLocation = scanLocation;
/* Skip whitespace */ /* Skip whitespace */
if (![self _skipToNextField]) if (!skipToNextField())
{ {
scanLocation = saveScanLocation; scanLocation = saveScanLocation;
return NO; return NO;
@ -404,24 +400,24 @@ typedef struct {
- (BOOL) scanLongLong: (long long *)value - (BOOL) scanLongLong: (long long *)value
{ {
#if defined(LONG_LONG_MAX) #if defined(LONG_LONG_MAX)
unsigned long long num = 0; unsigned long long num = 0;
const unsigned long long limit = ULONG_LONG_MAX / 10; const unsigned long long limit = ULONG_LONG_MAX / 10;
BOOL negative = NO; BOOL negative = NO;
BOOL overflow = NO; BOOL overflow = NO;
BOOL got_digits = NO; BOOL got_digits = NO;
unsigned int saveScanLocation = scanLocation; unsigned int saveScanLocation = scanLocation;
/* Skip whitespace */ /* Skip whitespace */
if (![self _skipToNextField]) if (!skipToNextField())
{ {
scanLocation = saveScanLocation; scanLocation = saveScanLocation;
return NO; return NO;
} }
/* Check for sign */ /* Check for sign */
if (scanLocation < len) if (scanLocation < myLength())
{ {
switch (charAtIndex(scanLocation)) switch (myCharacter(scanLocation))
{ {
case '+': case '+':
scanLocation++; scanLocation++;
@ -434,9 +430,10 @@ typedef struct {
} }
/* Process digits */ /* Process digits */
while (scanLocation < len) while (scanLocation < myLength())
{ {
unichar digit = charAtIndex(scanLocation); unichar digit = myCharacter(scanLocation);
if ((digit < '0') || (digit > '9')) if ((digit < '0') || (digit > '9'))
break; break;
if (!overflow) { if (!overflow) {
@ -457,12 +454,20 @@ typedef struct {
} }
if (value) if (value)
{ {
if (overflow || (num > (negative ? (unsigned long long)LONG_LONG_MIN : (unsigned long long)LONG_LONG_MAX))) if (negative)
*value = negative ? LONG_LONG_MIN: LONG_LONG_MAX; {
else if (negative) if (overflow || (num > (unsigned long long)LONG_LONG_MIN))
*value = -num; *value = LONG_LONG_MIN;
else
*value = -num;
}
else else
*value = num; {
if (overflow || (num > (unsigned long long)LONG_LONG_MAX))
*value = LONG_LONG_MAX;
else
*value = num;
}
} }
return YES; return YES;
#else /* defined(LONG_LONG_MAX) */ #else /* defined(LONG_LONG_MAX) */
@ -476,6 +481,12 @@ typedef struct {
#endif /* defined(LONG_LONG_MAX) */ #endif /* defined(LONG_LONG_MAX) */
} }
- (BOOL) scanDecimal: (NSDecimal*)value
{
[self notImplemented:_cmd]; /* FIXME */
return NO;
}
/* /*
* Scan a double into value. * Scan a double into value.
* Returns YES if a valid floating-point expression was scanned. * Returns YES if a valid floating-point expression was scanned.
@ -486,7 +497,6 @@ typedef struct {
*/ */
- (BOOL) scanDouble: (double *)value - (BOOL) scanDouble: (double *)value
{ {
unichar decimal = '.';
unichar c = 0; unichar c = 0;
double num = 0.0; double num = 0.0;
long int exponent = 0; long int exponent = 0;
@ -496,28 +506,16 @@ typedef struct {
unsigned int saveScanLocation = scanLocation; unsigned int saveScanLocation = scanLocation;
/* Skip whitespace */ /* Skip whitespace */
if (![self _skipToNextField]) if (!skipToNextField())
{ {
scanLocation = saveScanLocation; scanLocation = saveScanLocation;
return NO; return NO;
} }
/*
* Get decimal point character from locale if necessary.
*/
if (locale != nil)
{
NSString *pointString;
pointString = [locale objectForKey: NSDecimalSeparator];
if ([pointString length] > 0)
decimal = [pointString characterAtIndex: 0];
}
/* Check for sign */ /* Check for sign */
if (scanLocation < len) if (scanLocation < myLength())
{ {
switch (charAtIndex(scanLocation)) switch (myCharacter(scanLocation))
{ {
case '+': case '+':
scanLocation++; scanLocation++;
@ -530,9 +528,9 @@ typedef struct {
} }
/* Process number */ /* Process number */
while (scanLocation < len) while (scanLocation < myLength())
{ {
c = charAtIndex(scanLocation); c = myCharacter(scanLocation);
if ((c >= '0') && (c <= '9')) if ((c >= '0') && (c <= '9'))
{ {
/* Ensure that the number being accumulated will not overflow. */ /* Ensure that the number being accumulated will not overflow. */
@ -569,7 +567,7 @@ typedef struct {
} }
/* Check for trailing exponent */ /* Check for trailing exponent */
if ((scanLocation < len) && ((c == 'e') || (c == 'E'))) if ((scanLocation < myLength()) && ((c == 'e') || (c == 'E')))
{ {
int expval; int expval;
@ -642,11 +640,51 @@ typedef struct {
- (BOOL) scanCharactersFromSet: (NSCharacterSet *)aSet - (BOOL) scanCharactersFromSet: (NSCharacterSet *)aSet
intoString: (NSString **)value; intoString: (NSString **)value;
{ {
unsigned int saveScanLocation = scanLocation; unsigned int saveScanLocation = scanLocation;
if ([self _skipToNextField] if (skipToNextField())
&& [self _scanCharactersFromSet: aSet intoString: value]) {
return YES; unsigned int start;
BOOL (*memImp)(NSCharacterSet*, SEL, unichar);
if (aSet == charactersToBeSkipped)
memImp = skipImp;
else
memImp = (BOOL (*)(NSCharacterSet*, SEL, unichar))
[aSet methodForSelector: memSel];
start = scanLocation;
if (isUnicode)
{
while (scanLocation < myLength())
{
if ((*memImp)(aSet, memSel, myUnicode(scanLocation)) == NO)
break;
scanLocation++;
}
}
else
{
while (scanLocation < myLength())
{
if ((*memImp)(aSet, memSel, myChar(scanLocation)) == NO)
break;
scanLocation++;
}
}
if (scanLocation != start)
{
if (value != 0)
{
NSRange range;
range.location = start;
range.length = scanLocation - start;
*value = [string substringFromRange: range];
}
return YES;
}
}
scanLocation = saveScanLocation; scanLocation = saveScanLocation;
return NO; return NO;
} }
@ -659,23 +697,41 @@ typedef struct {
* containing the scanned characters is returned by reference in value. * containing the scanned characters is returned by reference in value.
*/ */
- (BOOL) scanUpToCharactersFromSet: (NSCharacterSet *)set - (BOOL) scanUpToCharactersFromSet: (NSCharacterSet *)set
intoString: (NSString **)value; intoString: (NSString **)value;
{ {
unsigned int saveScanLocation = scanLocation; unsigned int saveScanLocation = scanLocation;
unsigned int start; unsigned int start;
BOOL (*memImp)(NSCharacterSet*, SEL, unichar); BOOL (*memImp)(NSCharacterSet*, SEL, unichar);
if (![self _skipToNextField]) if (!skipToNextField())
return NO; return NO;
if (set == charactersToBeSkipped)
memImp = skipImp;
else
memImp = (BOOL (*)(NSCharacterSet*, SEL, unichar))
[set methodForSelector: memSel];
start = scanLocation; start = scanLocation;
memImp = (BOOL (*)(NSCharacterSet*, SEL, unichar)) if (isUnicode)
[set methodForSelector: memSel];
while (scanLocation < len)
{ {
if ((*memImp)(set, memSel, charAtIndex(scanLocation)) == YES) while (scanLocation < myLength())
break; {
scanLocation++; if ((*memImp)(set, memSel, myUnicode(scanLocation)) == YES)
break;
scanLocation++;
}
} }
else
{
while (scanLocation < myLength())
{
if ((*memImp)(set, memSel, myChar(scanLocation)) == YES)
break;
scanLocation++;
}
}
if (scanLocation == start) if (scanLocation == start)
{ {
scanLocation = saveScanLocation; scanLocation = saveScanLocation;
@ -683,7 +739,8 @@ typedef struct {
} }
if (value) if (value)
{ {
NSRange range; NSRange range;
range.location = start; range.location = start;
range.length = scanLocation - start; range.length = scanLocation - start;
*value = [string substringFromRange: range]; *value = [string substringFromRange: range];
@ -701,13 +758,13 @@ typedef struct {
*/ */
- (BOOL) scanString: (NSString *)aString intoString: (NSString **)value; - (BOOL) scanString: (NSString *)aString intoString: (NSString **)value;
{ {
NSRange range; NSRange range;
unsigned int saveScanLocation = scanLocation; unsigned int saveScanLocation = scanLocation;
[self _skipToNextField]; skipToNextField();
range.location = scanLocation; range.location = scanLocation;
range.length = [aString length]; range.length = [aString length];
if (range.location + range.length > len) if (range.location + range.length > myLength())
return NO; return NO;
range = [string rangeOfString: aString range = [string rangeOfString: aString
options: caseSensitive ? 0 : NSCaseInsensitiveSearch options: caseSensitive ? 0 : NSCaseInsensitiveSearch
@ -731,15 +788,15 @@ typedef struct {
* containing the scanned characters is returned by reference in value. * containing the scanned characters is returned by reference in value.
*/ */
- (BOOL) scanUpToString: (NSString *)aString - (BOOL) scanUpToString: (NSString *)aString
intoString: (NSString **)value; intoString: (NSString **)value;
{ {
NSRange range; NSRange range;
NSRange found; NSRange found;
unsigned int saveScanLocation = scanLocation; unsigned int saveScanLocation = scanLocation;
[self _skipToNextField]; skipToNextField();
range.location = scanLocation; range.location = scanLocation;
range.length = len - scanLocation; range.length = myLength() - scanLocation;
found = [string rangeOfString: aString found = [string rangeOfString: aString
options: caseSensitive ? 0 : NSCaseInsensitiveSearch options: caseSensitive ? 0 : NSCaseInsensitiveSearch
range: range]; range: range];
@ -779,7 +836,11 @@ typedef struct {
*/ */
- (void) setScanLocation: (unsigned int)anIndex - (void) setScanLocation: (unsigned int)anIndex
{ {
scanLocation = anIndex; if (scanLocation <= myLength())
scanLocation = anIndex;
else
[NSException raise: NSRangeException
format: @"Attempt to set scan location beyond end of string"];
} }
/* /*
@ -817,6 +878,8 @@ typedef struct {
- (void) setCharactersToBeSkipped: (NSCharacterSet *)aSet - (void) setCharactersToBeSkipped: (NSCharacterSet *)aSet
{ {
ASSIGNCOPY(charactersToBeSkipped, aSet); ASSIGNCOPY(charactersToBeSkipped, aSet);
skipImp = (BOOL (*)(NSCharacterSet*, SEL, unichar))
[charactersToBeSkipped methodForSelector: memSel];
} }
/* /*
@ -835,6 +898,23 @@ typedef struct {
- (void) setLocale: (NSDictionary *)localeDictionary - (void) setLocale: (NSDictionary *)localeDictionary
{ {
ASSIGN(locale, localeDictionary); ASSIGN(locale, localeDictionary);
/*
* Get decimal point character from locale if necessary.
*/
if (locale == nil)
{
decimal = '.';
}
else
{
NSString *pointString;
pointString = [locale objectForKey: NSDecimalSeparator];
if ([pointString length] > 0)
decimal = [pointString characterAtIndex: 0];
else
decimal = '.';
}
} }
/* /*
@ -842,7 +922,7 @@ typedef struct {
*/ */
- (id) copyWithZone: (NSZone *)zone - (id) copyWithZone: (NSZone *)zone
{ {
NSScanner *n = [[self class] allocWithZone: zone]; NSScanner *n = [[self class] allocWithZone: zone];
[n initWithString: string]; [n initWithString: string];
[n setCharactersToBeSkipped: charactersToBeSkipped]; [n setCharactersToBeSkipped: charactersToBeSkipped];