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 = (unsigned)(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 /*
30 Int32 ConvertStringToInt32(const char *s, const char **end) throw()
31 {
32 if (end)
33 *end = s;
34 const char *s2 = s;
35 if (*s == '-')
36 s2++;
37 if (*s2 == 0)
38 return 0;
39 const char *end2;
40 UInt32 res = ConvertStringToUInt32(s2, &end2);
41 if (*s == '-')
42 {
43 if (res > ((UInt32)1 << (32 - 1)))
44 return 0;
45 }
46 else if ((res & ((UInt32)1 << (32 - 1))) != 0)
47 return 0;
48 if (end)
49 *end = end2;
50 if (*s == '-')
51 return -(Int32)res;
52 return (Int32)res;
53 }
54 */
55
56 Int32 ConvertStringToInt32(const wchar_t *s, const wchar_t **end) throw()
57 {
58 if (end)
59 *end = s;
60 const wchar_t *s2 = s;
61 if (*s == '-')
62 s2++;
63 if (*s2 == 0)
64 return 0;
65 const wchar_t *end2;
66 UInt32 res = ConvertStringToUInt32(s2, &end2);
67 if (*s == '-')
68 {
69 if (res > ((UInt32)1 << (32 - 1)))
70 return 0;
71 }
72 else if ((res & ((UInt32)1 << (32 - 1))) != 0)
73 return 0;
74 if (end)
75 *end = end2;
76 if (*s == '-')
77 return -(Int32)res;
78 return (Int32)res;
79 }
80
ConvertOctStringToUInt32(const char * s,const char ** end)81 UInt32 ConvertOctStringToUInt32(const char *s, const char **end) throw()
82 {
83 if (end)
84 *end = s;
85 UInt32 res = 0;
86 for (;; s++)
87 {
88 unsigned c = (unsigned char)*s;
89 if (c < '0' || c > '7')
90 {
91 if (end)
92 *end = s;
93 return res;
94 }
95 if ((res & (UInt32)7 << (32 - 3)) != 0)
96 return 0;
97 res <<= 3;
98 res |= (unsigned)(c - '0');
99 }
100 }
101
ConvertOctStringToUInt64(const char * s,const char ** end)102 UInt64 ConvertOctStringToUInt64(const char *s, const char **end) throw()
103 {
104 if (end)
105 *end = s;
106 UInt64 res = 0;
107 for (;; s++)
108 {
109 unsigned c = (unsigned char)*s;
110 if (c < '0' || c > '7')
111 {
112 if (end)
113 *end = s;
114 return res;
115 }
116 if ((res & (UInt64)7 << (64 - 3)) != 0)
117 return 0;
118 res <<= 3;
119 res |= (unsigned)(c - '0');
120 }
121 }
122
ConvertHexStringToUInt32(const char * s,const char ** end)123 UInt32 ConvertHexStringToUInt32(const char *s, const char **end) throw()
124 {
125 if (end)
126 *end = s;
127 UInt32 res = 0;
128 for (;; s++)
129 {
130 unsigned c = (Byte)*s;
131 unsigned v;
132 if (c >= '0' && c <= '9') v = (c - '0');
133 else if (c >= 'A' && c <= 'F') v = 10 + (c - 'A');
134 else if (c >= 'a' && c <= 'f') v = 10 + (c - 'a');
135 else
136 {
137 if (end)
138 *end = s;
139 return res;
140 }
141 if ((res & (UInt32)0xF << (32 - 4)) != 0)
142 return 0;
143 res <<= 4;
144 res |= v;
145 }
146 }
147
ConvertHexStringToUInt64(const char * s,const char ** end)148 UInt64 ConvertHexStringToUInt64(const char *s, const char **end) throw()
149 {
150 if (end)
151 *end = s;
152 UInt64 res = 0;
153 for (;; s++)
154 {
155 unsigned c = (Byte)*s;
156 unsigned v;
157 if (c >= '0' && c <= '9') v = (c - '0');
158 else if (c >= 'A' && c <= 'F') v = 10 + (c - 'A');
159 else if (c >= 'a' && c <= 'f') v = 10 + (c - 'a');
160 else
161 {
162 if (end)
163 *end = s;
164 return res;
165 }
166 if ((res & (UInt64)0xF << (64 - 4)) != 0)
167 return 0;
168 res <<= 4;
169 res |= v;
170 }
171 }
172