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