mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 08:41:03 +00:00
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:
parent
92a427d24f
commit
3881c29981
3 changed files with 271 additions and 181 deletions
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue