1 /** @file
2
3 A brief file description
4
5 @section license License
6
7 Licensed to the Apache Software Foundation (ASF) under one
8 or more contributor license agreements. See the NOTICE file
9 distributed with this work for additional information
10 regarding copyright ownership. The ASF licenses this file
11 to you under the Apache License, Version 2.0 (the
12 "License"); you may not use this file except in compliance
13 with the License. You may obtain a copy of the License at
14
15 http://www.apache.org/licenses/LICENSE-2.0
16
17 Unless required by applicable law or agreed to in writing, software
18 distributed under the License is distributed on an "AS IS" BASIS,
19 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 See the License for the specific language governing permissions and
21 limitations under the License.
22 */
23
24 /*************************** -*- Mod: C++ -*- ******************************
25
26 ParseRules.h --
27
28
29 ****************************************************************************/
30
31 #include "tscore/ink_platform.h"
32 #include "tscore/ParseRules.h"
33
34 const unsigned int parseRulesCType[256] = {
35 #include "ParseRulesCType"
36 };
37 const char parseRulesCTypeToUpper[256] = {
38 #include "ParseRulesCTypeToUpper"
39 };
40 const char parseRulesCTypeToLower[256] = {
41 #include "ParseRulesCTypeToLower"
42 };
43
44 // Implement our atol() / strtol() utility functions. Note that these will
45 // deal with two cases atol does not:
46 //
47 // 1. They will handle both base 10 and base 16, always. 0x indicates hex.
48 // 2. They all honor the SI multipliers (i.e. K, M, G and T.
49 //
50 int64_t
ink_atoi64(const char * str,const char ** end)51 ink_atoi64(const char *str, const char **end)
52 {
53 int64_t num = 0;
54 int negative = 0;
55
56 while (*str && ParseRules::is_wslfcr(*str)) {
57 str += 1;
58 }
59
60 if (unlikely(str[0] == '0' && str[1] == 'x')) {
61 str += 2;
62 while (*str && ParseRules::is_hex(*str)) {
63 num = (num << 4) + ink_get_hex(*str++);
64 }
65 } else {
66 if (unlikely(*str == '-')) {
67 negative = 1;
68 str += 1;
69 }
70
71 /*
72 NOTE: we first compute the value as negative then correct the
73 sign back to positive. This enables us to correctly parse MININT.
74 */
75 while (*str && ParseRules::is_digit(*str)) {
76 num = (num * 10) - (*str++ - '0');
77 }
78 #if USE_SI_MULTIPLIERS
79 if (*str) {
80 if (*str == 'K') {
81 num = num * (1LL << 10);
82 str++;
83 } else if (*str == 'M') {
84 num = num * (1LL << 20);
85 str++;
86 } else if (*str == 'G') {
87 num = num * (1LL << 30);
88 str++;
89 } else if (*str == 'T') {
90 num = num * (1LL << 40);
91 str++;
92 }
93 }
94 #endif
95 if (!negative) {
96 num = -num;
97 }
98 }
99
100 if (end != nullptr) {
101 *end = str;
102 }
103
104 return num;
105 }
106
107 uint64_t
ink_atoui64(const char * str)108 ink_atoui64(const char *str)
109 {
110 uint64_t num = 0;
111
112 while (*str && ParseRules::is_wslfcr(*str)) {
113 str += 1;
114 }
115
116 if (unlikely(str[0] == '0' && str[1] == 'x')) {
117 str += 2;
118 while (*str && ParseRules::is_hex(*str)) {
119 num = (num << 4) + ink_get_hex(*str++);
120 }
121 } else {
122 while (*str && ParseRules::is_digit(*str)) {
123 num = (num * 10) + (*str++ - '0');
124 }
125 #if USE_SI_MULTIPLIERS
126 if (*str) {
127 if (*str == 'K') {
128 num = num * (1LL << 10);
129 } else if (*str == 'M') {
130 num = num * (1LL << 20);
131 } else if (*str == 'G') {
132 num = num * (1LL << 30);
133 } else if (*str == 'T') {
134 num = num * (1LL << 40);
135 }
136 }
137 #endif
138 }
139 return num;
140 }
141
142 int64_t
ink_atoi64(const char * str,int len)143 ink_atoi64(const char *str, int len)
144 {
145 int64_t num = 0;
146 int negative = 0;
147
148 while (len > 0 && *str && ParseRules::is_wslfcr(*str)) {
149 str += 1;
150 len--;
151 }
152
153 if (len < 1) {
154 return 0;
155 }
156
157 if (unlikely(str[0] == '0' && len > 1 && str[1] == 'x')) {
158 str += 2;
159 while (len > 0 && *str && ParseRules::is_hex(*str)) {
160 num = (num << 4) + ink_get_hex(*str++);
161 len--;
162 }
163 } else {
164 if (unlikely(*str == '-')) {
165 negative = 1;
166 str += 1;
167 }
168
169 /*
170 NOTE: we first compute the value as negative then correct the
171 sign back to positive. This enables us to correctly parse MININT.
172 */
173 while (len > 0 && *str && ParseRules::is_digit(*str)) {
174 num = (num * 10) - (*str++ - '0');
175 len--;
176 }
177 #if USE_SI_MULTIPLIERS
178 if (len > 0 && *str) {
179 if (*str == 'K') {
180 num = num * (1 << 10);
181 } else if (*str == 'M') {
182 num = num * (1 << 20);
183 } else if (*str == 'G') {
184 num = num * (1 << 30);
185 }
186 }
187 #endif
188
189 if (!negative) {
190 num = -num;
191 }
192 }
193 return num;
194 }
195