summaryrefslogtreecommitdiff
path: root/other-licenses/7zstub/src/CPP/Common/StringToInt.cpp
blob: 295816e16f90c1740c898ae4ac4baa4fc73e7f61 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// Common/StringToInt.cpp

#include "StdAfx.h"

#include "StringToInt.h"

static const UInt32 k_UInt32_max = 0xFFFFFFFF;
static const UInt64 k_UInt64_max = UINT64_CONST(0xFFFFFFFFFFFFFFFF);
// static const UInt64 k_UInt64_max = (UInt64)(Int64)-1;

#define CONVERT_STRING_TO_UINT_FUNC(uintType, charType, charTypeUnsigned) \
  uintType ConvertStringTo ## uintType(const charType *s, const charType **end) throw() { \
    if (end) *end = s; \
    uintType res = 0; \
    for (;; s++) { \
      charTypeUnsigned c = (charTypeUnsigned)*s; \
      if (c < '0' || c > '9') { if (end) *end = s; return res; } \
      if (res > (k_ ## uintType ## _max) / 10) return 0; \
      res *= 10; \
      unsigned v = (c - '0'); \
      if (res > (k_ ## uintType ## _max) - v) return 0; \
      res += v; }}

CONVERT_STRING_TO_UINT_FUNC(UInt32, char, Byte)
CONVERT_STRING_TO_UINT_FUNC(UInt32, wchar_t, wchar_t)
CONVERT_STRING_TO_UINT_FUNC(UInt64, char, Byte)
CONVERT_STRING_TO_UINT_FUNC(UInt64, wchar_t, wchar_t)

Int32 ConvertStringToInt32(const wchar_t *s, const wchar_t **end) throw()
{
  if (end)
    *end = s;
  const wchar_t *s2 = s;
  if (*s == '-')
    s2++;
  if (*s2 == 0)
    return 0;
  const wchar_t *end2;
  UInt32 res = ConvertStringToUInt32(s2, &end2);
  if (*s == '-')
  {
    if (res > ((UInt32)1 << (32 - 1)))
      return 0;
  }
  else if ((res & ((UInt32)1 << (32 - 1))) != 0)
    return 0;
  if (end)
    *end = end2;
  if (*s == '-')
    return -(Int32)res;
  return (Int32)res;
}

UInt32 ConvertOctStringToUInt32(const char *s, const char **end) throw()
{
  if (end)
    *end = s;
  UInt32 res = 0;
  for (;; s++)
  {
    unsigned c = (unsigned char)*s;
    if (c < '0' || c > '7')
    {
      if (end)
        *end = s;
      return res;
    }
    if ((res & (UInt32)7 << (32 - 3)) != 0)
      return 0;
    res <<= 3;
    res |= (unsigned)(c - '0');
  }
}

UInt64 ConvertOctStringToUInt64(const char *s, const char **end) throw()
{
  if (end)
    *end = s;
  UInt64 res = 0;
  for (;; s++)
  {
    unsigned c = (unsigned char)*s;
    if (c < '0' || c > '7')
    {
      if (end)
        *end = s;
      return res;
    }
    if ((res & (UInt64)7 << (64 - 3)) != 0)
      return 0;
    res <<= 3;
    res |= (unsigned)(c - '0');
  }
}

UInt32 ConvertHexStringToUInt32(const char *s, const char **end) throw()
{
  if (end)
    *end = s;
  UInt32 res = 0;
  for (;; s++)
  {
    unsigned c = (Byte)*s;
    unsigned v;
    if (c >= '0' && c <= '9') v = (c - '0');
    else if (c >= 'A' && c <= 'F') v = 10 + (c - 'A');
    else if (c >= 'a' && c <= 'f') v = 10 + (c - 'a');
    else
    {
      if (end)
        *end = s;
      return res;
    }
    if ((res & (UInt32)0xF << (32 - 4)) != 0)
      return 0;
    res <<= 4;
    res |= v;
  }
}

UInt64 ConvertHexStringToUInt64(const char *s, const char **end) throw()
{
  if (end)
    *end = s;
  UInt64 res = 0;
  for (;; s++)
  {
    unsigned c = (Byte)*s;
    unsigned v;
    if (c >= '0' && c <= '9') v = (c - '0');
    else if (c >= 'A' && c <= 'F') v = 10 + (c - 'A');
    else if (c >= 'a' && c <= 'f') v = 10 + (c - 'a');
    else
    {
      if (end)
        *end = s;
      return res;
    }
    if ((res & (UInt64)0xF << (64 - 4)) != 0)
      return 0;
    res <<= 4;
    res |= v;
  }
}