Class FString: add exception handling for toLong() and toULong()

This commit is contained in:
Markus Gans 2015-06-28 20:23:39 +02:00
parent 24091534e5
commit e9a04bcf29
2 changed files with 84 additions and 56 deletions

View File

@ -942,38 +942,38 @@ long FString::toLong() const
s = this->trim(); s = this->trim();
p = s.string; p = s.string;
if ( p ) if ( ! p )
{ throw std::invalid_argument ("null value");
register bool neg = false;
register bool overflow = false; if ( ! *p )
if ( *p == '-' ) throw std::invalid_argument ("empty value");
if ( *p == L'-' )
{ {
p++; p++;
neg = true;
tenth_limit = -(LONG_MIN / 10); tenth_limit = -(LONG_MIN / 10);
tenth_limit_digit += 1; tenth_limit_digit += 1;
} }
else if ( *p == '+' ) else if ( *p == L'+' )
{ {
p++; p++;
} }
while ( isdigit(*p) ) while ( isdigit(*p) )
{ {
register uChar d = uChar((*p) - '0'); register uChar d = uChar((*p) - L'0');
if ( num > tenth_limit if ( num > tenth_limit
|| (num == tenth_limit && d > tenth_limit_digit) ) || (num == tenth_limit && d > tenth_limit_digit) )
{ {
overflow = true; throw std::out_of_range ("overflow");
break;
} }
num = (num<<3)+(num<<1) + d; // (10 * num) + d num = (num<<3)+(num<<1) + d; // (10 * num) + d
p++; p++;
} }
if ( overflow )
num = neg ? LONG_MIN : LONG_MAX; if ( *p != L'\0' && ! isdigit(*p) )
else if ( neg ) throw std::invalid_argument ("no valid number");
num = (~num) + 1;
}
return num; return num;
} }
@ -992,28 +992,32 @@ uLong FString::toULong() const
s = this->trim(); s = this->trim();
p = s.string; p = s.string;
if ( p ) if ( ! p )
{ throw std::invalid_argument ("null value");
register bool overflow = false;
if ( *p == '+' ) if ( ! *p )
throw std::invalid_argument ("empty value");
if ( *p == L'+' )
{ {
p++; p++;
} }
while ( isdigit(*p) ) while ( isdigit(*p) )
{ {
register uChar d = uChar((*p) - '0'); register uChar d = uChar((*p) - L'0');
if ( num > tenth_limit if ( num > tenth_limit
|| (num == tenth_limit && d > tenth_limit_digit) ) || (num == tenth_limit && d > tenth_limit_digit) )
{ {
overflow = true; throw std::out_of_range ("overflow");
break;
} }
num = (num<<3)+(num<<1) + d; // (10 * num) + d num = (num<<3)+(num<<1) + d; // (10 * num) + d
p++; p++;
} }
if ( overflow )
num = ULONG_MAX; if ( *p != L'\0' && ! isdigit(*p) )
} throw std::invalid_argument ("no valid number");
return num; return num;
} }
@ -1023,9 +1027,12 @@ double FString::toDouble() const
wchar_t* p; wchar_t* p;
register double ret; register double ret;
if ( ! this->string || ! *this->string ) if ( ! this->string )
throw std::invalid_argument ("null value"); throw std::invalid_argument ("null value");
if ( ! *this->string )
throw std::invalid_argument ("empty value");
ret = wcstod(this->string, &p); ret = wcstod(this->string, &p);
if ( p != 0 && *p != '\0' ) if ( p != 0 && *p != '\0' )

View File

@ -117,12 +117,33 @@ int main (int, char**)
std::cout << " formatted: " std::cout << " formatted: "
<< formatStr.sprintf("sqrt(%d) = %d", 16, 4) << formatStr.sprintf("sqrt(%d) = %d", 16, 4)
<< std::endl; << std::endl;
try
{
uLong ulong_num = FString("123456789").toULong(); uLong ulong_num = FString("123456789").toULong();
std::cout << " toULong: " << ulong_num << std::endl; std::cout << " toULong: " << ulong_num << std::endl;
}
catch (const std::invalid_argument& ex)
{
std::cerr << "Invalid argument: " << ex.what() << std::endl;
}
catch (const std::out_of_range& ex)
{
std::cerr << "Out of range: " << ex.what() << std::endl;
}
try
{
long long_num = FString("-9876543210").toLong(); long long_num = FString("-9876543210").toLong();
std::cout << " toLong: " << long_num << std::endl; std::cout << " toLong: " << long_num << std::endl;
}
catch (const std::invalid_argument& ex)
{
std::cerr << "Invalid argument: " << ex.what() << std::endl;
}
catch (const std::out_of_range& ex)
{
std::cerr << "Out of range: " << ex.what() << std::endl;
}
setlocale(LC_NUMERIC, "C"); setlocale(LC_NUMERIC, "C");
try try