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, charTypeUnsigned) \
12 uintType ConvertStringTo ## uintType(const charType *s, const charType **end) throw() { \
13 if (end) *end = s; \
14 uintType res = 0; \
15 for (;; s++) { \
16 charTypeUnsigned c = (charTypeUnsigned)*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
CONVERT_STRING_TO_UINT_FUNC(UInt32,char,Byte)24 CONVERT_STRING_TO_UINT_FUNC(UInt32, char, Byte)
25 CONVERT_STRING_TO_UINT_FUNC(UInt32, wchar_t, wchar_t)
26 CONVERT_STRING_TO_UINT_FUNC(UInt64, char, Byte)
27 CONVERT_STRING_TO_UINT_FUNC(UInt64, wchar_t, 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
ConvertOctStringToUInt32(const char * s,const char ** end)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 unsigned c = (unsigned char)*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
ConvertOctStringToUInt64(const char * s,const char ** end)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 unsigned c = (unsigned char)*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
ConvertHexStringToUInt32(const char * s,const char ** end)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 unsigned c = (Byte)*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
ConvertHexStringToUInt64(const char * s,const char ** end)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 unsigned c = (Byte)*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