From e9a04bcf29b056dc95b7b93cfd81a3a91068427d Mon Sep 17 00:00:00 2001 From: Markus Gans Date: Sun, 28 Jun 2015 20:23:39 +0200 Subject: [PATCH] Class FString: add exception handling for toLong() and toULong() --- src/fstring.cpp | 109 +++++++++++++++++++++++++---------------------- test/fstring.cpp | 31 +++++++++++--- 2 files changed, 84 insertions(+), 56 deletions(-) diff --git a/src/fstring.cpp b/src/fstring.cpp index 6f657e2a..f9beedcf 100644 --- a/src/fstring.cpp +++ b/src/fstring.cpp @@ -942,38 +942,38 @@ long FString::toLong() const s = this->trim(); p = s.string; - if ( p ) + if ( ! p ) + throw std::invalid_argument ("null value"); + + if ( ! *p ) + throw std::invalid_argument ("empty value"); + + if ( *p == L'-' ) { - register bool neg = false; - register bool overflow = false; - if ( *p == '-' ) - { - p++; - neg = true; - tenth_limit = -(LONG_MIN / 10); - tenth_limit_digit += 1; - } - else if ( *p == '+' ) - { - p++; - } - while ( isdigit(*p) ) - { - register uChar d = uChar((*p) - '0'); - if ( num > tenth_limit - || (num == tenth_limit && d > tenth_limit_digit) ) - { - overflow = true; - break; - } - num = (num<<3)+(num<<1) + d; // (10 * num) + d - p++; - } - if ( overflow ) - num = neg ? LONG_MIN : LONG_MAX; - else if ( neg ) - num = (~num) + 1; + p++; + tenth_limit = -(LONG_MIN / 10); + tenth_limit_digit += 1; } + else if ( *p == L'+' ) + { + p++; + } + + while ( isdigit(*p) ) + { + register uChar d = uChar((*p) - L'0'); + if ( num > tenth_limit + || (num == tenth_limit && d > tenth_limit_digit) ) + { + throw std::out_of_range ("overflow"); + } + num = (num<<3)+(num<<1) + d; // (10 * num) + d + p++; + } + + if ( *p != L'\0' && ! isdigit(*p) ) + throw std::invalid_argument ("no valid number"); + return num; } @@ -992,28 +992,32 @@ uLong FString::toULong() const s = this->trim(); p = s.string; - if ( p ) + if ( ! p ) + throw std::invalid_argument ("null value"); + + if ( ! *p ) + throw std::invalid_argument ("empty value"); + + if ( *p == L'+' ) { - register bool overflow = false; - if ( *p == '+' ) - { - p++; - } - while ( isdigit(*p) ) - { - register uChar d = uChar((*p) - '0'); - if ( num > tenth_limit - || (num == tenth_limit && d > tenth_limit_digit) ) - { - overflow = true; - break; - } - num = (num<<3)+(num<<1) + d; // (10 * num) + d - p++; - } - if ( overflow ) - num = ULONG_MAX; + p++; } + + while ( isdigit(*p) ) + { + register uChar d = uChar((*p) - L'0'); + if ( num > tenth_limit + || (num == tenth_limit && d > tenth_limit_digit) ) + { + throw std::out_of_range ("overflow"); + } + num = (num<<3)+(num<<1) + d; // (10 * num) + d + p++; + } + + if ( *p != L'\0' && ! isdigit(*p) ) + throw std::invalid_argument ("no valid number"); + return num; } @@ -1023,9 +1027,12 @@ double FString::toDouble() const wchar_t* p; register double ret; - if ( ! this->string || ! *this->string ) + if ( ! this->string ) throw std::invalid_argument ("null value"); + if ( ! *this->string ) + throw std::invalid_argument ("empty value"); + ret = wcstod(this->string, &p); if ( p != 0 && *p != '\0' ) diff --git a/test/fstring.cpp b/test/fstring.cpp index 0069a19d..7f6777c6 100644 --- a/test/fstring.cpp +++ b/test/fstring.cpp @@ -117,12 +117,33 @@ int main (int, char**) std::cout << " formatted: " << formatStr.sprintf("sqrt(%d) = %d", 16, 4) << std::endl; + try + { + uLong ulong_num = FString("123456789").toULong(); + 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; + } - uLong ulong_num = FString("123456789").toULong(); - std::cout << " toULong: " << ulong_num << std::endl; - - long long_num = FString("-9876543210").toLong(); - std::cout << " toLong: " << long_num << std::endl; + try + { + long long_num = FString("-9876543210").toLong(); + 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"); try