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