xref: /third_party/lzma/CPP/Common/StringToInt.cpp (revision 370b324c)
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, 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
24CONVERT_STRING_TO_UINT_FUNC(UInt32, char, Byte)
25CONVERT_STRING_TO_UINT_FUNC(UInt32, wchar_t, wchar_t)
26CONVERT_STRING_TO_UINT_FUNC(UInt64, char, Byte)
27CONVERT_STRING_TO_UINT_FUNC(UInt64, wchar_t, wchar_t)
28
29/*
30Int32 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
56Int32 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
81UInt32 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
102UInt64 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
123UInt32 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
148UInt64 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