1// Common/StringToInt.cpp
2
3#include "StdAfx.h"
4
5#include "StringToInt.h"
6
7static const UInt32 k_UInt32_max = 0xFFFFFFFF;
8static 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
24CONVERT_STRING_TO_UINT_FUNC(UInt32, char)
25CONVERT_STRING_TO_UINT_FUNC(UInt32, wchar_t)
26CONVERT_STRING_TO_UINT_FUNC(UInt64, char)
27CONVERT_STRING_TO_UINT_FUNC(UInt64, wchar_t)
28
29Int32 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
54UInt32 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
75UInt64 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
96UInt32 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
121UInt64 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