diff options
author | Bernard Normier <bernard@zeroc.com> | 2005-04-21 14:34:44 +0000 |
---|---|---|
committer | Bernard Normier <bernard@zeroc.com> | 2005-04-21 14:34:44 +0000 |
commit | c14f104f362adc8bac4ed061c8b1b8bfab129f27 (patch) | |
tree | 746cae42ed32e04b4b3f5b268ed301bc9cad8689 /cpp/src/IceUtil/InputUtil.cpp | |
parent | BAcked out unwanted change (diff) | |
download | ice-c14f104f362adc8bac4ed061c8b1b8bfab129f27.tar.bz2 ice-c14f104f362adc8bac4ed061c8b1b8bfab129f27.tar.xz ice-c14f104f362adc8bac4ed061c8b1b8bfab129f27.zip |
Fixed VC60 build
Diffstat (limited to 'cpp/src/IceUtil/InputUtil.cpp')
-rw-r--r-- | cpp/src/IceUtil/InputUtil.cpp | 144 |
1 files changed, 143 insertions, 1 deletions
diff --git a/cpp/src/IceUtil/InputUtil.cpp b/cpp/src/IceUtil/InputUtil.cpp index 1ec040a9def..a141cdef965 100644 --- a/cpp/src/IceUtil/InputUtil.cpp +++ b/cpp/src/IceUtil/InputUtil.cpp @@ -11,17 +11,159 @@ #include <stdlib.h> #include <errno.h> -using namespace std; +#if defined(_MSC_VER) && (_MSC_VER < 1300) +#include <limits.h> +#endif +using namespace std; namespace IceUtil { +#if defined(_MSC_VER) && (_MSC_VER < 1300) +// +// The VC60 runtime does not include _strtoi64, so we provide our own implementation +// + +static const string allDigits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + +// +// Table to convert ASCII digits/letters into their value (100 for unused slots) +// +static const char digitVal[] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // '0' - '9' + 100, 100, 100, 100, 100, 100, 100, // punctuation + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, // 'A' - 'J' + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, // 'K' - 'T' + 30, 31, 32, 33, 34, 35 // 'U' - 'Z' +}; + +static IceUtil::Int64 +strToInt64Impl(const char* s, char** endptr, int base) +{ + // + // Assume nothing will be there to convert for now + // + if(endptr) + { + *endptr = const_cast<char *>(s); + } + + // + // Skip leading whitespace + // + while(*s && isspace(*s)) + { + ++s; + } + + // + // Check for sign + // + int sign = 1; + if(*s == '+') + { + ++s; + } + else if(*s == '-') + { + sign = -1; + ++s; + } + + // + // Check that base is valid + // + if(base == 0) + { + if(*s == '0') + { + base = 8; + if(*++s == 'x' || *s == 'X') + { + base = 16; + ++s; + } + } + else + { + base = 10; + } + } + else if(base < 2 || base > 36) + { + errno = EINVAL; + return 0; + } + + // + // Check that we have something left to parse + // + if(*s == '\0') + { + return 0; + } + + Int64 result = 0; + bool overflow = false; + bool digitFound = false; + const string validDigits(allDigits.begin(), allDigits.begin() + base); + while(*s && validDigits.find_first_of(toupper(*s)) != validDigits.npos) + { + digitFound = true; + if(!overflow) + { + int digit = digitVal[toupper(*s) - '0']; + assert(digit != 100); + if(result < _I64_MAX / base) + { + result *= base; + result += digit; + } + else if((digit <= _I64_MAX % base) || (sign == -1 && digit == _I64_MAX % base + 1)) + { + result *= base; + result += digit; + } + else + { + overflow = true; + result = sign == -1 ? _I64_MIN : _I64_MAX; + } + } + ++s; + } + + if(overflow) + { + errno = ERANGE; + } + else + { + result *= sign; + } + + if(digitFound && endptr != 0) + { + *endptr = const_cast<char *>(s); + } + + return result; +} + +#endif + + Int64 strToInt64(const char* s, char** endptr, int base) { #if defined(_WIN32) +# if defined(_MSC_VER) && (_MSC_VER < 1300) + return strToInt64Impl(s, endptr, base); +# else return _strtoi64(s, endptr, base); +# endif #elif defined(ICE_64) return strtol(s, endptr, base); #elif defined(__hpux) |