summaryrefslogtreecommitdiff
path: root/cpp/src/IceUtil/InputUtil.cpp
diff options
context:
space:
mode:
authorBernard Normier <bernard@zeroc.com>2005-04-21 14:34:44 +0000
committerBernard Normier <bernard@zeroc.com>2005-04-21 14:34:44 +0000
commitc14f104f362adc8bac4ed061c8b1b8bfab129f27 (patch)
tree746cae42ed32e04b4b3f5b268ed301bc9cad8689 /cpp/src/IceUtil/InputUtil.cpp
parentBAcked out unwanted change (diff)
downloadice-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.cpp144
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)