1 // Common/StringToInt.cpp 2 3 #include "StdAfx.h" 4 5 #include "StringToInt.h" 6 7 static const UInt32 k_UInt32_max = 0xFFFFFFFF; 8 static const UInt64 k_UInt64_max = UINT64_CONST(0xFFFFFFFFFFFFFFFF); 9 // static const UInt64 k_UInt64_max = (UInt64)(Int64)-1; 10 11 #define CONVERT_STRING_TO_UINT_FUNC(uintType, charType) \ 12 uintType ConvertStringTo ## uintType(const charType *s, const charType **end) throw() { \ 13 if (end) *end = s; \ 14 uintType res = 0; \ 15 for (;; s++) { \ 16 charType c = *s; \ 17 if (c < '0' || c > '9') { if (end) *end = s; return res; } \ 18 if (res > (k_ ## uintType ## _max) / 10) return 0; \ 19 res *= 10; \ 20 unsigned v = (c - '0'); \ 21 if (res > (k_ ## uintType ## _max) - v) return 0; \ 22 res += v; }} 23 24 CONVERT_STRING_TO_UINT_FUNC(UInt32, char) 25 CONVERT_STRING_TO_UINT_FUNC(UInt32, wchar_t) 26 CONVERT_STRING_TO_UINT_FUNC(UInt64, char) 27 CONVERT_STRING_TO_UINT_FUNC(UInt64, wchar_t) 28 29 Int32 ConvertStringToInt32(const wchar_t *s, const wchar_t **end) throw() 30 { 31 if (end) 32 *end = s; 33 const wchar_t *s2 = s; 34 if (*s == '-') 35 s2++; 36 if (*s2 == 0) 37 return 0; 38 const wchar_t *end2; 39 UInt32 res = ConvertStringToUInt32(s2, &end2); 40 if (*s == '-') 41 { 42 if (res > ((UInt32)1 << (32 - 1))) 43 return 0; 44 } 45 else if ((res & ((UInt32)1 << (32 - 1))) != 0) 46 return 0; 47 if (end) 48 *end = end2; 49 if (*s == '-') 50 return -(Int32)res; 51 return (Int32)res; 52 } 53 54 UInt32 ConvertOctStringToUInt32(const char *s, const char **end) throw() 55 { 56 if (end) 57 *end = s; 58 UInt32 res = 0; 59 for (;; s++) 60 { 61 char c = *s; 62 if (c < '0' || c > '7') 63 { 64 if (end) 65 *end = s; 66 return res; 67 } 68 if ((res & (UInt32)7 << (32 - 3)) != 0) 69 return 0; 70 res <<= 3; 71 res |= (unsigned)(c - '0'); 72 } 73 } 74 75 UInt64 ConvertOctStringToUInt64(const char *s, const char **end) throw() 76 { 77 if (end) 78 *end = s; 79 UInt64 res = 0; 80 for (;; s++) 81 { 82 char c = *s; 83 if (c < '0' || c > '7') 84 { 85 if (end) 86 *end = s; 87 return res; 88 } 89 if ((res & (UInt64)7 << (64 - 3)) != 0) 90 return 0; 91 res <<= 3; 92 res |= (unsigned)(c - '0'); 93 } 94 } 95 96 UInt32 ConvertHexStringToUInt32(const char *s, const char **end) throw() 97 { 98 if (end) 99 *end = s; 100 UInt32 res = 0; 101 for (;; s++) 102 { 103 char c = *s; 104 unsigned v; 105 if (c >= '0' && c <= '9') v = (c - '0'); 106 else if (c >= 'A' && c <= 'F') v = 10 + (c - 'A'); 107 else if (c >= 'a' && c <= 'f') v = 10 + (c - 'a'); 108 else 109 { 110 if (end) 111 *end = s; 112 return res; 113 } 114 if ((res & (UInt32)0xF << (32 - 4)) != 0) 115 return 0; 116 res <<= 4; 117 res |= v; 118 } 119 } 120 121 UInt64 ConvertHexStringToUInt64(const char *s, const char **end) throw() 122 { 123 if (end) 124 *end = s; 125 UInt64 res = 0; 126 for (;; s++) 127 { 128 char c = *s; 129 unsigned v; 130 if (c >= '0' && c <= '9') v = (c - '0'); 131 else if (c >= 'A' && c <= 'F') v = 10 + (c - 'A'); 132 else if (c >= 'a' && c <= 'f') v = 10 + (c - 'a'); 133 else 134 { 135 if (end) 136 *end = s; 137 return res; 138 } 139 if ((res & (UInt64)0xF << (64 - 4)) != 0) 140 return 0; 141 res <<= 4; 142 res |= v; 143 } 144 } 145