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

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

Issue 2058613002: Move WTF string to number converter functions to StringToNumber.h (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: missing files. Created 4 years, 6 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
11 namespace WTF {
12
13 static bool isCharacterAllowedInBase(UChar c, int base)
14 {
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, size_t length, b ool* ok, int base)
30 {
31 static const IntegralType integralMax = std::numeric_limits<IntegralType>::m ax();
32 static const bool isSigned = std::numeric_limits<IntegralType>::is_signed;
33 const IntegralType maxMultiplier = integralMax / base;
34
35 IntegralType value = 0;
36 bool isOk = false;
37 bool isNegative = false;
38
39 if (!data)
40 goto bye;
41
42 // skip leading whitespace
43 while (length && isSpaceOrNewline(*data)) {
44 --length;
45 ++data;
46 }
47
48 if (isSigned && length && *data == '-') {
49 --length;
50 ++data;
51 isNegative = true;
52 } else if (length && *data == '+') {
53 --length;
54 ++data;
55 }
56
57 if (!length || !isCharacterAllowedInBase(*data, base))
58 goto bye;
59
60 while (length && isCharacterAllowedInBase(*data, base)) {
61 --length;
62 IntegralType digitValue;
63 CharType c = *data;
64 if (isASCIIDigit(c))
65 digitValue = c - '0';
66 else if (c >= 'a')
67 digitValue = c - 'a' + 10;
68 else
69 digitValue = c - 'A' + 10;
70
71 if (value > maxMultiplier || (value == maxMultiplier && digitValue > (in tegralMax % base) + isNegative))
72 goto bye;
73
74 value = base * value + digitValue;
75 ++data;
76 }
77
78 #if COMPILER(MSVC)
79 #pragma warning(push, 0)
80 #pragma warning(disable:4146)
81 #endif
82
83 if (isNegative)
84 value = -value;
85
86 #if COMPILER(MSVC)
87 #pragma warning(pop)
88 #endif
89
90 // skip trailing space
91 while (length && isSpaceOrNewline(*data)) {
92 --length;
93 ++data;
94 }
95
96 if (!length)
97 isOk = true;
98 bye:
99 if (ok)
100 *ok = isOk;
101 return isOk ? value : 0;
102 }
103
104 template <typename CharType>
105 static unsigned lengthOfCharactersAsInteger(const CharType* data, size_t length)
106 {
107 size_t i = 0;
108
109 // Allow leading spaces.
110 for (; i != length; ++i) {
111 if (!isSpaceOrNewline(data[i]))
112 break;
113 }
114
115 // Allow sign.
116 if (i != length && (data[i] == '+' || data[i] == '-'))
117 ++i;
118
119 // Allow digits.
120 for (; i != length; ++i) {
121 if (!isASCIIDigit(data[i]))
122 break;
123 }
124
125 return i;
126 }
127
128 int charactersToIntStrict(const LChar* data, size_t length, bool* ok, int base)
129 {
130 return toIntegralType<int, LChar>(data, length, ok, base);
131 }
132
133 int charactersToIntStrict(const UChar* data, size_t length, bool* ok, int base)
134 {
135 return toIntegralType<int, UChar>(data, length, ok, base);
136 }
137
138 unsigned charactersToUIntStrict(const LChar* data, size_t length, bool* ok, int base)
139 {
140 return toIntegralType<unsigned, LChar>(data, length, ok, base);
141 }
142
143 unsigned charactersToUIntStrict(const UChar* data, size_t length, bool* ok, int base)
144 {
145 return toIntegralType<unsigned, UChar>(data, length, ok, base);
146 }
147
148 int64_t charactersToInt64Strict(const LChar* data, size_t length, bool* ok, int base)
149 {
150 return toIntegralType<int64_t, LChar>(data, length, ok, base);
151 }
152
153 int64_t charactersToInt64Strict(const UChar* data, size_t length, bool* ok, int base)
154 {
155 return toIntegralType<int64_t, UChar>(data, length, ok, base);
156 }
157
158 uint64_t charactersToUInt64Strict(const LChar* data, size_t length, bool* ok, in t base)
159 {
160 return toIntegralType<uint64_t, LChar>(data, length, ok, base);
161 }
162
163 uint64_t charactersToUInt64Strict(const UChar* data, size_t length, bool* ok, in t base)
164 {
165 return toIntegralType<uint64_t, UChar>(data, length, ok, base);
166 }
167
168 int charactersToInt(const LChar* data, size_t length, bool* ok)
169 {
170 return toIntegralType<int, LChar>(data, lengthOfCharactersAsInteger<LChar>(d ata, length), ok, 10);
171 }
172
173 int charactersToInt(const UChar* data, size_t length, bool* ok)
174 {
175 return toIntegralType<int, UChar>(data, lengthOfCharactersAsInteger(data, le ngth), ok, 10);
176 }
177
178 unsigned charactersToUInt(const LChar* data, size_t length, bool* ok)
179 {
180 return toIntegralType<unsigned, LChar>(data, lengthOfCharactersAsInteger<LCh ar>(data, length), ok, 10);
181 }
182
183 unsigned charactersToUInt(const UChar* data, size_t length, bool* ok)
184 {
185 return toIntegralType<unsigned, UChar>(data, lengthOfCharactersAsInteger<UCh ar>(data, length), ok, 10);
186 }
187
188 int64_t charactersToInt64(const LChar* data, size_t length, bool* ok)
189 {
190 return toIntegralType<int64_t, LChar>(data, lengthOfCharactersAsInteger<LCha r>(data, length), ok, 10);
191 }
192
193 int64_t charactersToInt64(const UChar* data, size_t length, bool* ok)
194 {
195 return toIntegralType<int64_t, UChar>(data, lengthOfCharactersAsInteger<UCha r>(data, length), ok, 10);
196 }
197
198 uint64_t charactersToUInt64(const LChar* data, size_t length, bool* ok)
199 {
200 return toIntegralType<uint64_t, LChar>(data, lengthOfCharactersAsInteger<LCh ar>(data, length), ok, 10);
201 }
202
203 uint64_t charactersToUInt64(const UChar* data, size_t length, bool* ok)
204 {
205 return toIntegralType<uint64_t, UChar>(data, lengthOfCharactersAsInteger<UCh ar>(data, length), ok, 10);
206 }
207
208 enum TrailingJunkPolicy { DisallowTrailingJunk, AllowTrailingJunk };
209
210 template <typename CharType, TrailingJunkPolicy policy>
211 static inline double toDoubleType(const CharType* data, size_t length, bool* ok, size_t& parsedLength)
212 {
213 size_t leadingSpacesLength = 0;
214 while (leadingSpacesLength < length && isASCIISpace(data[leadingSpacesLength ]))
215 ++leadingSpacesLength;
216
217 double number = parseDouble(data + leadingSpacesLength, length - leadingSpac esLength, parsedLength);
218 if (!parsedLength) {
219 if (ok)
220 *ok = false;
221 return 0.0;
222 }
223
224 parsedLength += leadingSpacesLength;
225 if (ok)
226 *ok = policy == AllowTrailingJunk || parsedLength == length;
227 return number;
228 }
229
230 double charactersToDouble(const LChar* data, size_t length, bool* ok)
231 {
232 size_t parsedLength;
233 return toDoubleType<LChar, DisallowTrailingJunk>(data, length, ok, parsedLen gth);
234 }
235
236 double charactersToDouble(const UChar* data, size_t length, bool* ok)
237 {
238 size_t parsedLength;
239 return toDoubleType<UChar, DisallowTrailingJunk>(data, length, ok, parsedLen gth);
240 }
241
242 double charactersToDouble(const LChar* data, size_t length, size_t& parsedLength )
243 {
244 return toDoubleType<LChar, AllowTrailingJunk>(data, length, nullptr, parsedL ength);
245 }
246
247 double charactersToDouble(const UChar* data, size_t length, size_t& parsedLength )
248 {
249 return toDoubleType<UChar, AllowTrailingJunk>(data, length, nullptr, parsedL ength);
250 }
251
252 float charactersToFloat(const LChar* data, size_t length, bool* ok)
253 {
254 // FIXME: This will return ok even when the string fits into a double but
255 // not a float.
256 size_t parsedLength;
257 return static_cast<float>(toDoubleType<LChar, DisallowTrailingJunk>(data, le ngth, ok, parsedLength));
258 }
259
260 float charactersToFloat(const UChar* data, size_t length, bool* ok)
261 {
262 // FIXME: This will return ok even when the string fits into a double but
263 // not a float.
264 size_t parsedLength;
265 return static_cast<float>(toDoubleType<UChar, DisallowTrailingJunk>(data, le ngth, ok, parsedLength));
266 }
267
268 float charactersToFloat(const LChar* data, size_t length, size_t& parsedLength)
269 {
270 // FIXME: This will return ok even when the string fits into a double but
271 // not a float.
272 return static_cast<float>(toDoubleType<LChar, AllowTrailingJunk>(data, lengt h, 0, parsedLength));
273 }
274
275 float charactersToFloat(const UChar* data, size_t length, size_t& parsedLength)
276 {
277 // FIXME: This will return ok even when the string fits into a double but
278 // not a float.
279 return static_cast<float>(toDoubleType<UChar, AllowTrailingJunk>(data, lengt h, 0, parsedLength));
280 }
281
282 } // namespace WTF
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/wtf/text/StringToNumber.h ('k') | third_party/WebKit/Source/wtf/text/WTFString.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698