([NSScanner -scanRadixUnsignedInt:]): New method.

([NSScanner -_scanInt:]): Deal with overflow better.  (?)
([NSScanner -scanLongLong:]): Likewise.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1777 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Andrew McCallum 1996-09-17 15:02:31 +00:00
parent 54b4126b08
commit b3c153c3d6

View file

@ -185,11 +185,9 @@
return NO;
if (value)
{
if (num > (negative ? -(unsigned int)INT_MIN : (unsigned int)INT_MAX))
overflow = YES;
if (overflow)
num = negative ? INT_MIN: INT_MAX;
if (negative)
if (overflow || (num > (negative ? (unsigned int)INT_MIN : (unsigned int)INT_MAX)))
*value = negative ? INT_MIN: INT_MAX;
else if (negative)
*value = -num;
else
*value = num;
@ -210,6 +208,108 @@
return NO;
}
/*
* Scan an unsigned int of the given radix into value.
*/
- (BOOL)scanRadixUnsignedInt: (unsigned int *)value
{
unsigned int num = 0;
unsigned int numLimit, digitLimit, digitValue, radix;
BOOL overflow = NO;
BOOL got_digits = NO;
unsigned int saveScanLocation = scanLocation;
/* Skip whitespace */
if (![self _skipToNextField])
{
scanLocation = saveScanLocation;
return NO;
}
/* Check radix */
radix = 10;
if ((scanLocation < len) && ([string characterAtIndex:scanLocation] == '0'))
{
radix = 8;
scanLocation++;
got_digits = YES;
if (scanLocation < len)
{
switch ([string characterAtIndex:scanLocation])
{
case 'x':
case 'X':
scanLocation++;
radix = 16;
got_digits = NO;
break;
}
}
}
numLimit = UINT_MAX / radix;
digitLimit = UINT_MAX % radix;
/* Process digits */
while (scanLocation < len)
{
unichar digit = [string characterAtIndex:scanLocation];
switch (digit)
{
case '0': digitValue = 0; break;
case '1': digitValue = 1; break;
case '2': digitValue = 2; break;
case '3': digitValue = 3; break;
case '4': digitValue = 4; break;
case '5': digitValue = 5; break;
case '6': digitValue = 6; break;
case '7': digitValue = 7; break;
case '8': digitValue = 8; break;
case '9': digitValue = 9; break;
case 'a': digitValue = 0xA; break;
case 'b': digitValue = 0xB; break;
case 'c': digitValue = 0xC; break;
case 'd': digitValue = 0xD; break;
case 'e': digitValue = 0xE; break;
case 'f': digitValue = 0xF; break;
case 'A': digitValue = 0xA; break;
case 'B': digitValue = 0xB; break;
case 'C': digitValue = 0xC; break;
case 'D': digitValue = 0xD; break;
case 'E': digitValue = 0xE; break;
case 'F': digitValue = 0xF; break;
default:
digitValue = radix;
break;
}
if (digitValue >= radix)
break;
if (!overflow)
{
if ((num > numLimit) || ((num == numLimit) && (digitValue > digitLimit)))
overflow = YES;
else
num = num * radix + digitValue;
}
scanLocation++;
got_digits = YES;
}
/* Save result */
if (!got_digits)
{
scanLocation = saveScanLocation;
return NO;
}
if (value)
{
if (overflow)
*value = UINT_MAX;
else
*value = num;
}
return YES;
}
/*
* Scan a long long int into value.
* Same as scanInt, except with different variable types and limits.
@ -267,12 +367,9 @@
}
if (value)
{
if (num > (unsigned long long)LONG_LONG_MAX)
/* xxx When would this ever be true? Isn't is impossible? mccallum. */
overflow = YES;
if (overflow)
num = negative ? LONG_LONG_MIN: LONG_LONG_MAX;
if (negative)
if (overflow || (num > (negative ? (unsigned long long)LONG_LONG_MIN : (unsigned long long)LONG_LONG_MAX)))
*value = negative ? LONG_LONG_MIN: LONG_LONG_MAX;
else if (negative)
*value = -num;
else
*value = num;