Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(173)

Side by Side Diff: third_party/WebKit/Source/wtf/text/StringToNumber.cpp

Issue 2764243002: Move files in wtf/ to platform/wtf/ (Part 9). (Closed)
Patch Set: Rebase. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "wtf/text/StringToNumber.h"
6
7 #include "wtf/ASCIICType.h"
8 #include "wtf/dtoa.h"
9 #include "wtf/text/StringImpl.h"
10 #include <type_traits>
11
12 namespace WTF {
13
14 static bool isCharacterAllowedInBase(UChar c, int base) {
15 if (c > 0x7F)
16 return false;
17 if (isASCIIDigit(c))
18 return c - '0' < base;
19 if (isASCIIAlpha(c)) {
20 if (base > 36)
21 base = 36;
22 return (c >= 'a' && c < 'a' + base - 10) ||
23 (c >= 'A' && c < 'A' + base - 10);
24 }
25 return false;
26 }
27
28 template <typename IntegralType, typename CharType>
29 static inline IntegralType toIntegralType(const CharType* data,
30 size_t length,
31 bool* ok,
32 int base) {
33 static_assert(std::is_integral<IntegralType>::value,
34 "IntegralType must be an integral type.");
35 static constexpr IntegralType integralMax =
36 std::numeric_limits<IntegralType>::max();
37 static constexpr IntegralType integralMin =
38 std::numeric_limits<IntegralType>::min();
39 static constexpr bool isSigned = std::numeric_limits<IntegralType>::is_signed;
40
41 IntegralType value = 0;
42 bool isOk = false;
43 bool isNegative = false;
44
45 if (!data)
46 goto bye;
47
48 // skip leading whitespace
49 while (length && isSpaceOrNewline(*data)) {
50 --length;
51 ++data;
52 }
53
54 if (isSigned && length && *data == '-') {
55 --length;
56 ++data;
57 isNegative = true;
58 } else if (length && *data == '+') {
59 --length;
60 ++data;
61 }
62
63 if (!length || !isCharacterAllowedInBase(*data, base))
64 goto bye;
65
66 while (length && isCharacterAllowedInBase(*data, base)) {
67 --length;
68 IntegralType digitValue;
69 CharType c = *data;
70 if (isASCIIDigit(c))
71 digitValue = c - '0';
72 else if (c >= 'a')
73 digitValue = c - 'a' + 10;
74 else
75 digitValue = c - 'A' + 10;
76
77 bool overflow;
78 if (isNegative) {
79 // Overflow condition:
80 // value * base - digitValue < integralMin
81 // <=> value < (integralMin + digitValue) / base
82 // We must be careful of rounding errors here, but the default rounding
83 // mode (round to zero) works well, so we can use this formula as-is.
84 overflow = value < (integralMin + digitValue) / base;
85 } else {
86 // Overflow condition:
87 // value * base + digitValue > integralMax
88 // <=> value > (integralMax + digitValue) / base
89 // Ditto regarding rounding errors.
90 overflow = value > (integralMax - digitValue) / base;
91 }
92 if (overflow)
93 goto bye;
94
95 if (isNegative)
96 value = base * value - digitValue;
97 else
98 value = base * value + digitValue;
99 ++data;
100 }
101
102 // skip trailing space
103 while (length && isSpaceOrNewline(*data)) {
104 --length;
105 ++data;
106 }
107
108 if (!length)
109 isOk = true;
110 bye:
111 if (ok)
112 *ok = isOk;
113 return isOk ? value : 0;
114 }
115
116 template <typename CharType>
117 static unsigned lengthOfCharactersAsInteger(const CharType* data,
118 size_t length) {
119 size_t i = 0;
120
121 // Allow leading spaces.
122 for (; i != length; ++i) {
123 if (!isSpaceOrNewline(data[i]))
124 break;
125 }
126
127 // Allow sign.
128 if (i != length && (data[i] == '+' || data[i] == '-'))
129 ++i;
130
131 // Allow digits.
132 for (; i != length; ++i) {
133 if (!isASCIIDigit(data[i]))
134 break;
135 }
136
137 return i;
138 }
139
140 int charactersToIntStrict(const LChar* data,
141 size_t length,
142 bool* ok,
143 int base) {
144 return toIntegralType<int, LChar>(data, length, ok, base);
145 }
146
147 int charactersToIntStrict(const UChar* data,
148 size_t length,
149 bool* ok,
150 int base) {
151 return toIntegralType<int, UChar>(data, length, ok, base);
152 }
153
154 unsigned charactersToUIntStrict(const LChar* data,
155 size_t length,
156 bool* ok,
157 int base) {
158 return toIntegralType<unsigned, LChar>(data, length, ok, base);
159 }
160
161 unsigned charactersToUIntStrict(const UChar* data,
162 size_t length,
163 bool* ok,
164 int base) {
165 return toIntegralType<unsigned, UChar>(data, length, ok, base);
166 }
167
168 int64_t charactersToInt64Strict(const LChar* data,
169 size_t length,
170 bool* ok,
171 int base) {
172 return toIntegralType<int64_t, LChar>(data, length, ok, base);
173 }
174
175 int64_t charactersToInt64Strict(const UChar* data,
176 size_t length,
177 bool* ok,
178 int base) {
179 return toIntegralType<int64_t, UChar>(data, length, ok, base);
180 }
181
182 uint64_t charactersToUInt64Strict(const LChar* data,
183 size_t length,
184 bool* ok,
185 int base) {
186 return toIntegralType<uint64_t, LChar>(data, length, ok, base);
187 }
188
189 uint64_t charactersToUInt64Strict(const UChar* data,
190 size_t length,
191 bool* ok,
192 int base) {
193 return toIntegralType<uint64_t, UChar>(data, length, ok, base);
194 }
195
196 int charactersToInt(const LChar* data, size_t length, bool* ok) {
197 return toIntegralType<int, LChar>(
198 data, lengthOfCharactersAsInteger<LChar>(data, length), ok, 10);
199 }
200
201 int charactersToInt(const UChar* data, size_t length, bool* ok) {
202 return toIntegralType<int, UChar>(
203 data, lengthOfCharactersAsInteger(data, length), ok, 10);
204 }
205
206 unsigned charactersToUInt(const LChar* data, size_t length, bool* ok) {
207 return toIntegralType<unsigned, LChar>(
208 data, lengthOfCharactersAsInteger<LChar>(data, length), ok, 10);
209 }
210
211 unsigned charactersToUInt(const UChar* data, size_t length, bool* ok) {
212 return toIntegralType<unsigned, UChar>(
213 data, lengthOfCharactersAsInteger<UChar>(data, length), ok, 10);
214 }
215
216 int64_t charactersToInt64(const LChar* data, size_t length, bool* ok) {
217 return toIntegralType<int64_t, LChar>(
218 data, lengthOfCharactersAsInteger<LChar>(data, length), ok, 10);
219 }
220
221 int64_t charactersToInt64(const UChar* data, size_t length, bool* ok) {
222 return toIntegralType<int64_t, UChar>(
223 data, lengthOfCharactersAsInteger<UChar>(data, length), ok, 10);
224 }
225
226 uint64_t charactersToUInt64(const LChar* data, size_t length, bool* ok) {
227 return toIntegralType<uint64_t, LChar>(
228 data, lengthOfCharactersAsInteger<LChar>(data, length), ok, 10);
229 }
230
231 uint64_t charactersToUInt64(const UChar* data, size_t length, bool* ok) {
232 return toIntegralType<uint64_t, UChar>(
233 data, lengthOfCharactersAsInteger<UChar>(data, length), ok, 10);
234 }
235
236 enum TrailingJunkPolicy { DisallowTrailingJunk, AllowTrailingJunk };
237
238 template <typename CharType, TrailingJunkPolicy policy>
239 static inline double toDoubleType(const CharType* data,
240 size_t length,
241 bool* ok,
242 size_t& parsedLength) {
243 size_t leadingSpacesLength = 0;
244 while (leadingSpacesLength < length &&
245 isASCIISpace(data[leadingSpacesLength]))
246 ++leadingSpacesLength;
247
248 double number = parseDouble(data + leadingSpacesLength,
249 length - leadingSpacesLength, parsedLength);
250 if (!parsedLength) {
251 if (ok)
252 *ok = false;
253 return 0.0;
254 }
255
256 parsedLength += leadingSpacesLength;
257 if (ok)
258 *ok = policy == AllowTrailingJunk || parsedLength == length;
259 return number;
260 }
261
262 double charactersToDouble(const LChar* data, size_t length, bool* ok) {
263 size_t parsedLength;
264 return toDoubleType<LChar, DisallowTrailingJunk>(data, length, ok,
265 parsedLength);
266 }
267
268 double charactersToDouble(const UChar* data, size_t length, bool* ok) {
269 size_t parsedLength;
270 return toDoubleType<UChar, DisallowTrailingJunk>(data, length, ok,
271 parsedLength);
272 }
273
274 double charactersToDouble(const LChar* data,
275 size_t length,
276 size_t& parsedLength) {
277 return toDoubleType<LChar, AllowTrailingJunk>(data, length, nullptr,
278 parsedLength);
279 }
280
281 double charactersToDouble(const UChar* data,
282 size_t length,
283 size_t& parsedLength) {
284 return toDoubleType<UChar, AllowTrailingJunk>(data, length, nullptr,
285 parsedLength);
286 }
287
288 float charactersToFloat(const LChar* data, size_t length, bool* ok) {
289 // FIXME: This will return ok even when the string fits into a double but
290 // not a float.
291 size_t parsedLength;
292 return static_cast<float>(toDoubleType<LChar, DisallowTrailingJunk>(
293 data, length, ok, parsedLength));
294 }
295
296 float charactersToFloat(const UChar* data, size_t length, bool* ok) {
297 // FIXME: This will return ok even when the string fits into a double but
298 // not a float.
299 size_t parsedLength;
300 return static_cast<float>(toDoubleType<UChar, DisallowTrailingJunk>(
301 data, length, ok, parsedLength));
302 }
303
304 float charactersToFloat(const LChar* data,
305 size_t length,
306 size_t& parsedLength) {
307 // FIXME: This will return ok even when the string fits into a double but
308 // not a float.
309 return static_cast<float>(
310 toDoubleType<LChar, AllowTrailingJunk>(data, length, 0, parsedLength));
311 }
312
313 float charactersToFloat(const UChar* data,
314 size_t length,
315 size_t& parsedLength) {
316 // FIXME: This will return ok even when the string fits into a double but
317 // not a float.
318 return static_cast<float>(
319 toDoubleType<UChar, AllowTrailingJunk>(data, length, 0, parsedLength));
320 }
321
322 } // namespace WTF
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/wtf/text/StringToNumber.h ('k') | third_party/WebKit/Source/wtf/text/StringView.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698