// Common/StringToInt.cpp | |
#include "StdAfx.h" | |
#include "StringToInt.h" | |
static const UInt32 k_UInt32_max = 0xFFFFFFFF; | |
static const UInt64 k_UInt64_max = UINT64_CONST(0xFFFFFFFFFFFFFFFF); | |
// static const UInt64 k_UInt64_max = (UInt64)(Int64)-1; | |
#define CONVERT_STRING_TO_UINT_FUNC(uintType, charType) \ | |
uintType ConvertStringTo ## uintType(const charType *s, const charType **end) throw() { \ | |
if (end) *end = s; \ | |
uintType res = 0; \ | |
for (;; s++) { \ | |
charType c = *s; \ | |
if (c < '0' || c > '9') { if (end) *end = s; return res; } \ | |
if (res > (k_ ## uintType ## _max) / 10) return 0; \ | |
res *= 10; \ | |
unsigned v = (c - '0'); \ | |
if (res > (k_ ## uintType ## _max) - v) return 0; \ | |
res += v; }} | |
CONVERT_STRING_TO_UINT_FUNC(UInt32, char) | |
CONVERT_STRING_TO_UINT_FUNC(UInt32, wchar_t) | |
CONVERT_STRING_TO_UINT_FUNC(UInt64, char) | |
CONVERT_STRING_TO_UINT_FUNC(UInt64, wchar_t) | |
Int32 ConvertStringToInt32(const wchar_t *s, const wchar_t **end) throw() | |
{ | |
if (end) | |
*end = s; | |
const wchar_t *s2 = s; | |
if (*s == '-') | |
s2++; | |
if (*s2 == 0) | |
return 0; | |
const wchar_t *end2; | |
UInt32 res = ConvertStringToUInt32(s2, &end2); | |
if (*s == '-') | |
{ | |
if (res > ((UInt32)1 << (32 - 1))) | |
return 0; | |
} | |
else if ((res & ((UInt32)1 << (32 - 1))) != 0) | |
return 0; | |
if (end) | |
*end = end2; | |
if (*s == '-') | |
return -(Int32)res; | |
return (Int32)res; | |
} | |
UInt32 ConvertOctStringToUInt32(const char *s, const char **end) throw() | |
{ | |
if (end) | |
*end = s; | |
UInt32 res = 0; | |
for (;; s++) | |
{ | |
char c = *s; | |
if (c < '0' || c > '7') | |
{ | |
if (end) | |
*end = s; | |
return res; | |
} | |
if ((res & (UInt32)7 << (32 - 3)) != 0) | |
return 0; | |
res <<= 3; | |
res |= (unsigned)(c - '0'); | |
} | |
} | |
UInt64 ConvertOctStringToUInt64(const char *s, const char **end) throw() | |
{ | |
if (end) | |
*end = s; | |
UInt64 res = 0; | |
for (;; s++) | |
{ | |
char c = *s; | |
if (c < '0' || c > '7') | |
{ | |
if (end) | |
*end = s; | |
return res; | |
} | |
if ((res & (UInt64)7 << (64 - 3)) != 0) | |
return 0; | |
res <<= 3; | |
res |= (unsigned)(c - '0'); | |
} | |
} | |
UInt32 ConvertHexStringToUInt32(const char *s, const char **end) throw() | |
{ | |
if (end) | |
*end = s; | |
UInt32 res = 0; | |
for (;; s++) | |
{ | |
char c = *s; | |
unsigned v; | |
if (c >= '0' && c <= '9') v = (c - '0'); | |
else if (c >= 'A' && c <= 'F') v = 10 + (c - 'A'); | |
else if (c >= 'a' && c <= 'f') v = 10 + (c - 'a'); | |
else | |
{ | |
if (end) | |
*end = s; | |
return res; | |
} | |
if ((res & (UInt32)0xF << (32 - 4)) != 0) | |
return 0; | |
res <<= 4; | |
res |= v; | |
} | |
} | |
UInt64 ConvertHexStringToUInt64(const char *s, const char **end) throw() | |
{ | |
if (end) | |
*end = s; | |
UInt64 res = 0; | |
for (;; s++) | |
{ | |
char c = *s; | |
unsigned v; | |
if (c >= '0' && c <= '9') v = (c - '0'); | |
else if (c >= 'A' && c <= 'F') v = 10 + (c - 'A'); | |
else if (c >= 'a' && c <= 'f') v = 10 + (c - 'a'); | |
else | |
{ | |
if (end) | |
*end = s; | |
return res; | |
} | |
if ((res & (UInt64)0xF << (64 - 4)) != 0) | |
return 0; | |
res <<= 4; | |
res |= v; | |
} | |
} |