1370b324cSopenharmony_ci// Common/StringToInt.cpp
2370b324cSopenharmony_ci
3370b324cSopenharmony_ci#include "StdAfx.h"
4370b324cSopenharmony_ci
5370b324cSopenharmony_ci#include "StringToInt.h"
6370b324cSopenharmony_ci
7370b324cSopenharmony_cistatic const UInt32 k_UInt32_max = 0xFFFFFFFF;
8370b324cSopenharmony_cistatic const UInt64 k_UInt64_max = UINT64_CONST(0xFFFFFFFFFFFFFFFF);
9370b324cSopenharmony_ci// static const UInt64 k_UInt64_max = (UInt64)(Int64)-1;
10370b324cSopenharmony_ci
11370b324cSopenharmony_ci#define CONVERT_STRING_TO_UINT_FUNC(uintType, charType, charTypeUnsigned) \
12370b324cSopenharmony_ci  uintType ConvertStringTo ## uintType(const charType *s, const charType **end) throw() { \
13370b324cSopenharmony_ci    if (end) *end = s; \
14370b324cSopenharmony_ci    uintType res = 0; \
15370b324cSopenharmony_ci    for (;; s++) { \
16370b324cSopenharmony_ci      charTypeUnsigned c = (charTypeUnsigned)*s; \
17370b324cSopenharmony_ci      if (c < '0' || c > '9') { if (end) *end = s; return res; } \
18370b324cSopenharmony_ci      if (res > (k_ ## uintType ## _max) / 10) return 0; \
19370b324cSopenharmony_ci      res *= 10; \
20370b324cSopenharmony_ci      unsigned v = (unsigned)(c - '0'); \
21370b324cSopenharmony_ci      if (res > (k_ ## uintType ## _max) - v) return 0; \
22370b324cSopenharmony_ci      res += v; }}
23370b324cSopenharmony_ci
24370b324cSopenharmony_ciCONVERT_STRING_TO_UINT_FUNC(UInt32, char, Byte)
25370b324cSopenharmony_ciCONVERT_STRING_TO_UINT_FUNC(UInt32, wchar_t, wchar_t)
26370b324cSopenharmony_ciCONVERT_STRING_TO_UINT_FUNC(UInt64, char, Byte)
27370b324cSopenharmony_ciCONVERT_STRING_TO_UINT_FUNC(UInt64, wchar_t, wchar_t)
28370b324cSopenharmony_ci
29370b324cSopenharmony_ci/*
30370b324cSopenharmony_ciInt32 ConvertStringToInt32(const char *s, const char **end) throw()
31370b324cSopenharmony_ci{
32370b324cSopenharmony_ci  if (end)
33370b324cSopenharmony_ci    *end = s;
34370b324cSopenharmony_ci  const char *s2 = s;
35370b324cSopenharmony_ci  if (*s == '-')
36370b324cSopenharmony_ci    s2++;
37370b324cSopenharmony_ci  if (*s2 == 0)
38370b324cSopenharmony_ci    return 0;
39370b324cSopenharmony_ci  const char *end2;
40370b324cSopenharmony_ci  UInt32 res = ConvertStringToUInt32(s2, &end2);
41370b324cSopenharmony_ci  if (*s == '-')
42370b324cSopenharmony_ci  {
43370b324cSopenharmony_ci    if (res > ((UInt32)1 << (32 - 1)))
44370b324cSopenharmony_ci      return 0;
45370b324cSopenharmony_ci  }
46370b324cSopenharmony_ci  else if ((res & ((UInt32)1 << (32 - 1))) != 0)
47370b324cSopenharmony_ci    return 0;
48370b324cSopenharmony_ci  if (end)
49370b324cSopenharmony_ci    *end = end2;
50370b324cSopenharmony_ci  if (*s == '-')
51370b324cSopenharmony_ci    return -(Int32)res;
52370b324cSopenharmony_ci  return (Int32)res;
53370b324cSopenharmony_ci}
54370b324cSopenharmony_ci*/
55370b324cSopenharmony_ci
56370b324cSopenharmony_ciInt32 ConvertStringToInt32(const wchar_t *s, const wchar_t **end) throw()
57370b324cSopenharmony_ci{
58370b324cSopenharmony_ci  if (end)
59370b324cSopenharmony_ci    *end = s;
60370b324cSopenharmony_ci  const wchar_t *s2 = s;
61370b324cSopenharmony_ci  if (*s == '-')
62370b324cSopenharmony_ci    s2++;
63370b324cSopenharmony_ci  if (*s2 == 0)
64370b324cSopenharmony_ci    return 0;
65370b324cSopenharmony_ci  const wchar_t *end2;
66370b324cSopenharmony_ci  UInt32 res = ConvertStringToUInt32(s2, &end2);
67370b324cSopenharmony_ci  if (*s == '-')
68370b324cSopenharmony_ci  {
69370b324cSopenharmony_ci    if (res > ((UInt32)1 << (32 - 1)))
70370b324cSopenharmony_ci      return 0;
71370b324cSopenharmony_ci  }
72370b324cSopenharmony_ci  else if ((res & ((UInt32)1 << (32 - 1))) != 0)
73370b324cSopenharmony_ci    return 0;
74370b324cSopenharmony_ci  if (end)
75370b324cSopenharmony_ci    *end = end2;
76370b324cSopenharmony_ci  if (*s == '-')
77370b324cSopenharmony_ci    return -(Int32)res;
78370b324cSopenharmony_ci  return (Int32)res;
79370b324cSopenharmony_ci}
80370b324cSopenharmony_ci
81370b324cSopenharmony_ciUInt32 ConvertOctStringToUInt32(const char *s, const char **end) throw()
82370b324cSopenharmony_ci{
83370b324cSopenharmony_ci  if (end)
84370b324cSopenharmony_ci    *end = s;
85370b324cSopenharmony_ci  UInt32 res = 0;
86370b324cSopenharmony_ci  for (;; s++)
87370b324cSopenharmony_ci  {
88370b324cSopenharmony_ci    unsigned c = (unsigned char)*s;
89370b324cSopenharmony_ci    if (c < '0' || c > '7')
90370b324cSopenharmony_ci    {
91370b324cSopenharmony_ci      if (end)
92370b324cSopenharmony_ci        *end = s;
93370b324cSopenharmony_ci      return res;
94370b324cSopenharmony_ci    }
95370b324cSopenharmony_ci    if ((res & (UInt32)7 << (32 - 3)) != 0)
96370b324cSopenharmony_ci      return 0;
97370b324cSopenharmony_ci    res <<= 3;
98370b324cSopenharmony_ci    res |= (unsigned)(c - '0');
99370b324cSopenharmony_ci  }
100370b324cSopenharmony_ci}
101370b324cSopenharmony_ci
102370b324cSopenharmony_ciUInt64 ConvertOctStringToUInt64(const char *s, const char **end) throw()
103370b324cSopenharmony_ci{
104370b324cSopenharmony_ci  if (end)
105370b324cSopenharmony_ci    *end = s;
106370b324cSopenharmony_ci  UInt64 res = 0;
107370b324cSopenharmony_ci  for (;; s++)
108370b324cSopenharmony_ci  {
109370b324cSopenharmony_ci    unsigned c = (unsigned char)*s;
110370b324cSopenharmony_ci    if (c < '0' || c > '7')
111370b324cSopenharmony_ci    {
112370b324cSopenharmony_ci      if (end)
113370b324cSopenharmony_ci        *end = s;
114370b324cSopenharmony_ci      return res;
115370b324cSopenharmony_ci    }
116370b324cSopenharmony_ci    if ((res & (UInt64)7 << (64 - 3)) != 0)
117370b324cSopenharmony_ci      return 0;
118370b324cSopenharmony_ci    res <<= 3;
119370b324cSopenharmony_ci    res |= (unsigned)(c - '0');
120370b324cSopenharmony_ci  }
121370b324cSopenharmony_ci}
122370b324cSopenharmony_ci
123370b324cSopenharmony_ciUInt32 ConvertHexStringToUInt32(const char *s, const char **end) throw()
124370b324cSopenharmony_ci{
125370b324cSopenharmony_ci  if (end)
126370b324cSopenharmony_ci    *end = s;
127370b324cSopenharmony_ci  UInt32 res = 0;
128370b324cSopenharmony_ci  for (;; s++)
129370b324cSopenharmony_ci  {
130370b324cSopenharmony_ci    unsigned c = (Byte)*s;
131370b324cSopenharmony_ci    unsigned v;
132370b324cSopenharmony_ci    if (c >= '0' && c <= '9') v = (c - '0');
133370b324cSopenharmony_ci    else if (c >= 'A' && c <= 'F') v = 10 + (c - 'A');
134370b324cSopenharmony_ci    else if (c >= 'a' && c <= 'f') v = 10 + (c - 'a');
135370b324cSopenharmony_ci    else
136370b324cSopenharmony_ci    {
137370b324cSopenharmony_ci      if (end)
138370b324cSopenharmony_ci        *end = s;
139370b324cSopenharmony_ci      return res;
140370b324cSopenharmony_ci    }
141370b324cSopenharmony_ci    if ((res & (UInt32)0xF << (32 - 4)) != 0)
142370b324cSopenharmony_ci      return 0;
143370b324cSopenharmony_ci    res <<= 4;
144370b324cSopenharmony_ci    res |= v;
145370b324cSopenharmony_ci  }
146370b324cSopenharmony_ci}
147370b324cSopenharmony_ci
148370b324cSopenharmony_ciUInt64 ConvertHexStringToUInt64(const char *s, const char **end) throw()
149370b324cSopenharmony_ci{
150370b324cSopenharmony_ci  if (end)
151370b324cSopenharmony_ci    *end = s;
152370b324cSopenharmony_ci  UInt64 res = 0;
153370b324cSopenharmony_ci  for (;; s++)
154370b324cSopenharmony_ci  {
155370b324cSopenharmony_ci    unsigned c = (Byte)*s;
156370b324cSopenharmony_ci    unsigned v;
157370b324cSopenharmony_ci    if (c >= '0' && c <= '9') v = (c - '0');
158370b324cSopenharmony_ci    else if (c >= 'A' && c <= 'F') v = 10 + (c - 'A');
159370b324cSopenharmony_ci    else if (c >= 'a' && c <= 'f') v = 10 + (c - 'a');
160370b324cSopenharmony_ci    else
161370b324cSopenharmony_ci    {
162370b324cSopenharmony_ci      if (end)
163370b324cSopenharmony_ci        *end = s;
164370b324cSopenharmony_ci      return res;
165370b324cSopenharmony_ci    }
166370b324cSopenharmony_ci    if ((res & (UInt64)0xF << (64 - 4)) != 0)
167370b324cSopenharmony_ci      return 0;
168370b324cSopenharmony_ci    res <<= 4;
169370b324cSopenharmony_ci    res |= v;
170370b324cSopenharmony_ci  }
171370b324cSopenharmony_ci}
172