/src/double-conversion/double-conversion/string-to-double.cc
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2010 the V8 project authors. All rights reserved. |
2 | | // Redistribution and use in source and binary forms, with or without |
3 | | // modification, are permitted provided that the following conditions are |
4 | | // met: |
5 | | // |
6 | | // * Redistributions of source code must retain the above copyright |
7 | | // notice, this list of conditions and the following disclaimer. |
8 | | // * Redistributions in binary form must reproduce the above |
9 | | // copyright notice, this list of conditions and the following |
10 | | // disclaimer in the documentation and/or other materials provided |
11 | | // with the distribution. |
12 | | // * Neither the name of Google Inc. nor the names of its |
13 | | // contributors may be used to endorse or promote products derived |
14 | | // from this software without specific prior written permission. |
15 | | // |
16 | | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
17 | | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
18 | | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
19 | | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
20 | | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
21 | | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
22 | | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 | | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 | | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 | | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 | | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | | |
28 | | #include <climits> |
29 | | #include <locale> |
30 | | #include <cmath> |
31 | | |
32 | | #include "string-to-double.h" |
33 | | |
34 | | #include "ieee.h" |
35 | | #include "strtod.h" |
36 | | #include "utils.h" |
37 | | |
38 | | #ifdef _MSC_VER |
39 | | # if _MSC_VER >= 1900 |
40 | | // Fix MSVC >= 2015 (_MSC_VER == 1900) warning |
41 | | // C4244: 'argument': conversion from 'const uc16' to 'char', possible loss of data |
42 | | // against Advance and friends, when instantiated with **it as char, not uc16. |
43 | | __pragma(warning(disable: 4244)) |
44 | | # endif |
45 | | # if _MSC_VER <= 1700 // VS2012, see IsDecimalDigitForRadix warning fix, below |
46 | | # define VS2012_RADIXWARN |
47 | | # endif |
48 | | #endif |
49 | | |
50 | | namespace double_conversion { |
51 | | |
52 | | namespace { |
53 | | |
54 | 5.91k | inline char ToLower(char ch) { |
55 | 5.91k | static const std::ctype<char>& cType = |
56 | 5.91k | std::use_facet<std::ctype<char> >(std::locale::classic()); |
57 | 5.91k | return cType.tolower(ch); |
58 | 5.91k | } |
59 | | |
60 | 0 | inline char Pass(char ch) { |
61 | 0 | return ch; |
62 | 0 | } |
63 | | |
64 | | template <class Iterator, class Converter> |
65 | | static inline bool ConsumeSubStringImpl(Iterator* current, |
66 | | Iterator end, |
67 | | const char* substring, |
68 | 8 | Converter converter) { |
69 | 8 | DOUBLE_CONVERSION_ASSERT(converter(**current) == *substring); |
70 | 17 | for (substring++; *substring != '\0'; substring++) { |
71 | 13 | ++*current; |
72 | 13 | if (*current == end || converter(**current) != *substring) { |
73 | 4 | return false; |
74 | 4 | } |
75 | 13 | } |
76 | 4 | ++*current; |
77 | 4 | return true; |
78 | 8 | } string-to-double.cc:bool double_conversion::(anonymous namespace)::ConsumeSubStringImpl<char const*, char (*)(char)>(char const**, char const*, char const*, char (*)(char)) Line | Count | Source | 68 | 8 | Converter converter) { | 69 | 8 | DOUBLE_CONVERSION_ASSERT(converter(**current) == *substring); | 70 | 17 | for (substring++; *substring != '\0'; substring++) { | 71 | 13 | ++*current; | 72 | 13 | if (*current == end || converter(**current) != *substring) { | 73 | 4 | return false; | 74 | 4 | } | 75 | 13 | } | 76 | 4 | ++*current; | 77 | 4 | return true; | 78 | 8 | } |
Unexecuted instantiation: string-to-double.cc:bool double_conversion::(anonymous namespace)::ConsumeSubStringImpl<unsigned short const*, char (*)(char)>(unsigned short const**, unsigned short const*, char const*, char (*)(char)) |
79 | | |
80 | | // Consumes the given substring from the iterator. |
81 | | // Returns false, if the substring does not match. |
82 | | template <class Iterator> |
83 | | static bool ConsumeSubString(Iterator* current, |
84 | | Iterator end, |
85 | | const char* substring, |
86 | 8 | bool allow_case_insensitivity) { |
87 | 8 | if (allow_case_insensitivity) { |
88 | 8 | return ConsumeSubStringImpl(current, end, substring, ToLower); |
89 | 8 | } else { |
90 | 0 | return ConsumeSubStringImpl(current, end, substring, Pass); |
91 | 0 | } |
92 | 8 | } string-to-double.cc:bool double_conversion::(anonymous namespace)::ConsumeSubString<char const*>(char const**, char const*, char const*, bool) Line | Count | Source | 86 | 8 | bool allow_case_insensitivity) { | 87 | 8 | if (allow_case_insensitivity) { | 88 | 8 | return ConsumeSubStringImpl(current, end, substring, ToLower); | 89 | 8 | } else { | 90 | 0 | return ConsumeSubStringImpl(current, end, substring, Pass); | 91 | 0 | } | 92 | 8 | } |
Unexecuted instantiation: string-to-double.cc:bool double_conversion::(anonymous namespace)::ConsumeSubString<unsigned short const*>(unsigned short const**, unsigned short const*, char const*, bool) |
93 | | |
94 | | // Consumes first character of the str is equal to ch |
95 | | inline bool ConsumeFirstCharacter(char ch, |
96 | | const char* str, |
97 | 5.89k | bool case_insensitivity) { |
98 | 5.89k | return case_insensitivity ? ToLower(ch) == str[0] : ch == str[0]; |
99 | 5.89k | } |
100 | | } // namespace |
101 | | |
102 | | // Maximum number of significant digits in decimal representation. |
103 | | // The longest possible double in decimal representation is |
104 | | // (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074 |
105 | | // (768 digits). If we parse a number whose first digits are equal to a |
106 | | // mean of 2 adjacent doubles (that could have up to 769 digits) the result |
107 | | // must be rounded to the bigger one unless the tail consists of zeros, so |
108 | | // we don't need to preserve all the digits. |
109 | | const int kMaxSignificantDigits = 772; |
110 | | |
111 | | |
112 | | static const char kWhitespaceTable7[] = { 32, 13, 10, 9, 11, 12 }; |
113 | | static const int kWhitespaceTable7Length = DOUBLE_CONVERSION_ARRAY_SIZE(kWhitespaceTable7); |
114 | | |
115 | | |
116 | | static const uc16 kWhitespaceTable16[] = { |
117 | | 160, 8232, 8233, 5760, 6158, 8192, 8193, 8194, 8195, |
118 | | 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 65279 |
119 | | }; |
120 | | static const int kWhitespaceTable16Length = DOUBLE_CONVERSION_ARRAY_SIZE(kWhitespaceTable16); |
121 | | |
122 | | |
123 | 5.73k | static bool isWhitespace(int x) { |
124 | 5.73k | if (x < 128) { |
125 | 30.2k | for (int i = 0; i < kWhitespaceTable7Length; i++) { |
126 | 27.0k | if (kWhitespaceTable7[i] == x) return true; |
127 | 27.0k | } |
128 | 5.73k | } else { |
129 | 0 | for (int i = 0; i < kWhitespaceTable16Length; i++) { |
130 | 0 | if (kWhitespaceTable16[i] == x) return true; |
131 | 0 | } |
132 | 0 | } |
133 | 3.29k | return false; |
134 | 5.73k | } |
135 | | |
136 | | |
137 | | // Returns true if a nonspace found and false if the end has reached. |
138 | | template <class Iterator> |
139 | 4.86k | static inline bool AdvanceToNonspace(Iterator* current, Iterator end) { |
140 | 7.30k | while (*current != end) { |
141 | 5.73k | if (!isWhitespace(**current)) return true; |
142 | 2.44k | ++*current; |
143 | 2.44k | } |
144 | 1.56k | return false; |
145 | 4.86k | } string-to-double.cc:bool double_conversion::AdvanceToNonspace<char const*>(char const**, char const*) Line | Count | Source | 139 | 4.86k | static inline bool AdvanceToNonspace(Iterator* current, Iterator end) { | 140 | 7.30k | while (*current != end) { | 141 | 5.73k | if (!isWhitespace(**current)) return true; | 142 | 2.44k | ++*current; | 143 | 2.44k | } | 144 | 1.56k | return false; | 145 | 4.86k | } |
Unexecuted instantiation: string-to-double.cc:bool double_conversion::AdvanceToNonspace<char*>(char**, char*) Unexecuted instantiation: string-to-double.cc:bool double_conversion::AdvanceToNonspace<unsigned short const*>(unsigned short const**, unsigned short const*) |
146 | | |
147 | | |
148 | 7.50M | static bool isDigit(int x, int radix) { |
149 | 7.50M | return (x >= '0' && x <= '9' && x < '0' + radix) |
150 | 7.50M | || (radix > 10 && x >= 'a' && x < 'a' + radix - 10) |
151 | 7.50M | || (radix > 10 && x >= 'A' && x < 'A' + radix - 10); |
152 | 7.50M | } |
153 | | |
154 | | |
155 | 32 | static double SignedZero(bool sign) { |
156 | 32 | return sign ? -0.0 : 0.0; |
157 | 32 | } |
158 | | |
159 | | |
160 | | // Returns true if 'c' is a decimal digit that is valid for the given radix. |
161 | | // |
162 | | // The function is small and could be inlined, but VS2012 emitted a warning |
163 | | // because it constant-propagated the radix and concluded that the last |
164 | | // condition was always true. Moving it into a separate function and |
165 | | // suppressing optimisation keeps the compiler from warning. |
166 | | #ifdef VS2012_RADIXWARN |
167 | | #pragma optimize("",off) |
168 | | static bool IsDecimalDigitForRadix(int c, int radix) { |
169 | | return '0' <= c && c <= '9' && (c - '0') < radix; |
170 | | } |
171 | | #pragma optimize("",on) |
172 | | #else |
173 | 3.62M | static bool inline IsDecimalDigitForRadix(int c, int radix) { |
174 | 3.62M | return '0' <= c && c <= '9' && (c - '0') < radix; |
175 | 3.62M | } |
176 | | #endif |
177 | | // Returns true if 'c' is a character digit that is valid for the given radix. |
178 | | // The 'a_character' should be 'a' or 'A'. |
179 | | // |
180 | | // The function is small and could be inlined, but VS2012 emitted a warning |
181 | | // because it constant-propagated the radix and concluded that the first |
182 | | // condition was always false. By moving it into a separate function the |
183 | | // compiler wouldn't warn anymore. |
184 | 4.43k | static bool IsCharacterDigitForRadix(int c, int radix, char a_character) { |
185 | 4.43k | return radix > 10 && c >= a_character && c < a_character + radix - 10; |
186 | 4.43k | } |
187 | | |
188 | | // Returns true, when the iterator is equal to end. |
189 | | template<class Iterator> |
190 | 13.5M | static bool Advance (Iterator* it, uc16 separator, int base, Iterator& end) { |
191 | 13.5M | if (separator == StringToDoubleConverter::kNoSeparator) { |
192 | 13.5M | ++(*it); |
193 | 13.5M | return *it == end; |
194 | 13.5M | } |
195 | 0 | if (!isDigit(**it, base)) { |
196 | 0 | ++(*it); |
197 | 0 | return *it == end; |
198 | 0 | } |
199 | 0 | ++(*it); |
200 | 0 | if (*it == end) return true; |
201 | 0 | if (*it + 1 == end) return false; |
202 | 0 | if (**it == separator && isDigit(*(*it + 1), base)) { |
203 | 0 | ++(*it); |
204 | 0 | } |
205 | 0 | return *it == end; |
206 | 0 | } string-to-double.cc:bool double_conversion::Advance<char const*>(char const**, unsigned short, int, char const*&) Line | Count | Source | 190 | 13.5M | static bool Advance (Iterator* it, uc16 separator, int base, Iterator& end) { | 191 | 13.5M | if (separator == StringToDoubleConverter::kNoSeparator) { | 192 | 13.5M | ++(*it); | 193 | 13.5M | return *it == end; | 194 | 13.5M | } | 195 | 0 | if (!isDigit(**it, base)) { | 196 | 0 | ++(*it); | 197 | 0 | return *it == end; | 198 | 0 | } | 199 | 0 | ++(*it); | 200 | 0 | if (*it == end) return true; | 201 | 0 | if (*it + 1 == end) return false; | 202 | 0 | if (**it == separator && isDigit(*(*it + 1), base)) { | 203 | 0 | ++(*it); | 204 | 0 | } | 205 | 0 | return *it == end; | 206 | 0 | } |
string-to-double.cc:bool double_conversion::Advance<char*>(char**, unsigned short, int, char*&) Line | Count | Source | 190 | 8.91k | static bool Advance (Iterator* it, uc16 separator, int base, Iterator& end) { | 191 | 8.91k | if (separator == StringToDoubleConverter::kNoSeparator) { | 192 | 8.91k | ++(*it); | 193 | 8.91k | return *it == end; | 194 | 8.91k | } | 195 | 0 | if (!isDigit(**it, base)) { | 196 | 0 | ++(*it); | 197 | 0 | return *it == end; | 198 | 0 | } | 199 | 0 | ++(*it); | 200 | 0 | if (*it == end) return true; | 201 | 0 | if (*it + 1 == end) return false; | 202 | 0 | if (**it == separator && isDigit(*(*it + 1), base)) { | 203 | 0 | ++(*it); | 204 | 0 | } | 205 | 0 | return *it == end; | 206 | 0 | } |
Unexecuted instantiation: string-to-double.cc:bool double_conversion::Advance<unsigned short const*>(unsigned short const**, unsigned short, int, unsigned short const*&) |
207 | | |
208 | | // Checks whether the string in the range start-end is a hex-float string. |
209 | | // This function assumes that the leading '0x'/'0X' is already consumed. |
210 | | // |
211 | | // Hex float strings are of one of the following forms: |
212 | | // - hex_digits+ 'p' ('+'|'-')? exponent_digits+ |
213 | | // - hex_digits* '.' hex_digits+ 'p' ('+'|'-')? exponent_digits+ |
214 | | // - hex_digits+ '.' 'p' ('+'|'-')? exponent_digits+ |
215 | | template<class Iterator> |
216 | | static bool IsHexFloatString(Iterator start, |
217 | | Iterator end, |
218 | | uc16 separator, |
219 | 1.02k | bool allow_trailing_junk) { |
220 | 1.02k | DOUBLE_CONVERSION_ASSERT(start != end); |
221 | | |
222 | 0 | Iterator current = start; |
223 | | |
224 | 1.02k | bool saw_digit = false; |
225 | 6.88k | while (isDigit(*current, 16)) { |
226 | 6.10k | saw_digit = true; |
227 | 6.10k | if (Advance(¤t, separator, 16, end)) return false; |
228 | 6.10k | } |
229 | 786 | if (*current == '.') { |
230 | 142 | if (Advance(¤t, separator, 16, end)) return false; |
231 | 7.48M | while (isDigit(*current, 16)) { |
232 | 7.48M | saw_digit = true; |
233 | 7.48M | if (Advance(¤t, separator, 16, end)) return false; |
234 | 7.48M | } |
235 | 140 | } |
236 | 769 | if (!saw_digit) return false; |
237 | 709 | if (*current != 'p' && *current != 'P') return false; |
238 | 609 | if (Advance(¤t, separator, 16, end)) return false; |
239 | 606 | if (*current == '+' || *current == '-') { |
240 | 161 | if (Advance(¤t, separator, 16, end)) return false; |
241 | 161 | } |
242 | 604 | if (!isDigit(*current, 10)) return false; |
243 | 584 | if (Advance(¤t, separator, 16, end)) return true; |
244 | 2.45k | while (isDigit(*current, 10)) { |
245 | 2.40k | if (Advance(¤t, separator, 16, end)) return true; |
246 | 2.40k | } |
247 | 56 | return allow_trailing_junk || !AdvanceToNonspace(¤t, end); |
248 | 354 | } string-to-double.cc:bool double_conversion::IsHexFloatString<char const*>(char const*, char const*, unsigned short, bool) Line | Count | Source | 219 | 1.02k | bool allow_trailing_junk) { | 220 | 1.02k | DOUBLE_CONVERSION_ASSERT(start != end); | 221 | | | 222 | 0 | Iterator current = start; | 223 | | | 224 | 1.02k | bool saw_digit = false; | 225 | 6.88k | while (isDigit(*current, 16)) { | 226 | 6.10k | saw_digit = true; | 227 | 6.10k | if (Advance(¤t, separator, 16, end)) return false; | 228 | 6.10k | } | 229 | 786 | if (*current == '.') { | 230 | 142 | if (Advance(¤t, separator, 16, end)) return false; | 231 | 7.48M | while (isDigit(*current, 16)) { | 232 | 7.48M | saw_digit = true; | 233 | 7.48M | if (Advance(¤t, separator, 16, end)) return false; | 234 | 7.48M | } | 235 | 140 | } | 236 | 769 | if (!saw_digit) return false; | 237 | 709 | if (*current != 'p' && *current != 'P') return false; | 238 | 609 | if (Advance(¤t, separator, 16, end)) return false; | 239 | 606 | if (*current == '+' || *current == '-') { | 240 | 161 | if (Advance(¤t, separator, 16, end)) return false; | 241 | 161 | } | 242 | 604 | if (!isDigit(*current, 10)) return false; | 243 | 584 | if (Advance(¤t, separator, 16, end)) return true; | 244 | 2.45k | while (isDigit(*current, 10)) { | 245 | 2.40k | if (Advance(¤t, separator, 16, end)) return true; | 246 | 2.40k | } | 247 | 56 | return allow_trailing_junk || !AdvanceToNonspace(¤t, end); | 248 | 354 | } |
Unexecuted instantiation: string-to-double.cc:bool double_conversion::IsHexFloatString<char*>(char*, char*, unsigned short, bool) Unexecuted instantiation: string-to-double.cc:bool double_conversion::IsHexFloatString<unsigned short const*>(unsigned short const*, unsigned short const*, unsigned short, bool) |
249 | | |
250 | | |
251 | | // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end. |
252 | | // |
253 | | // If parse_as_hex_float is true, then the string must be a valid |
254 | | // hex-float. |
255 | | template <int radix_log_2, class Iterator> |
256 | | static double RadixStringToIeee(Iterator* current, |
257 | | Iterator end, |
258 | | bool sign, |
259 | | uc16 separator, |
260 | | bool parse_as_hex_float, |
261 | | bool allow_trailing_junk, |
262 | | double junk_string_value, |
263 | | bool read_as_double, |
264 | 862 | bool* result_is_junk) { |
265 | 862 | DOUBLE_CONVERSION_ASSERT(*current != end); |
266 | 862 | DOUBLE_CONVERSION_ASSERT(!parse_as_hex_float || |
267 | 0 | IsHexFloatString(*current, end, separator, allow_trailing_junk)); |
268 | | |
269 | 0 | const int kDoubleSize = Double::kSignificandSize; |
270 | 862 | const int kSingleSize = Single::kSignificandSize; |
271 | 862 | const int kSignificandSize = read_as_double? kDoubleSize: kSingleSize; |
272 | | |
273 | 862 | *result_is_junk = true; |
274 | | |
275 | 862 | int64_t number = 0; |
276 | 862 | int exponent = 0; |
277 | 862 | const int radix = (1 << radix_log_2); |
278 | | // Whether we have encountered a '.' and are parsing the decimal digits. |
279 | | // Only relevant if parse_as_hex_float is true. |
280 | 862 | bool post_decimal = false; |
281 | | |
282 | | // Skip leading 0s. |
283 | 1.34k | while (**current == '0') { |
284 | 486 | if (Advance(current, separator, radix, end)) { |
285 | 8 | *result_is_junk = false; |
286 | 8 | return SignedZero(sign); |
287 | 8 | } |
288 | 486 | } |
289 | | |
290 | 3.62M | while (true) { |
291 | 3.62M | int digit; |
292 | 3.62M | if (IsDecimalDigitForRadix(**current, radix)) { |
293 | 3.62M | digit = static_cast<char>(**current) - '0'; |
294 | 3.62M | if (post_decimal) exponent -= radix_log_2; |
295 | 3.62M | } else if (IsCharacterDigitForRadix(**current, radix, 'a')) { |
296 | 1.08k | digit = static_cast<char>(**current) - 'a' + 10; |
297 | 1.08k | if (post_decimal) exponent -= radix_log_2; |
298 | 1.67k | } else if (IsCharacterDigitForRadix(**current, radix, 'A')) { |
299 | 1.27k | digit = static_cast<char>(**current) - 'A' + 10; |
300 | 1.27k | if (post_decimal) exponent -= radix_log_2; |
301 | 1.27k | } else if (parse_as_hex_float && **current == '.') { |
302 | 44 | post_decimal = true; |
303 | 44 | Advance(current, separator, radix, end); |
304 | 44 | DOUBLE_CONVERSION_ASSERT(*current != end); |
305 | 0 | continue; |
306 | 358 | } else if (parse_as_hex_float && (**current == 'p' || **current == 'P')) { |
307 | 262 | break; |
308 | 262 | } else { |
309 | 96 | if (allow_trailing_junk || !AdvanceToNonspace(current, end)) { |
310 | 96 | break; |
311 | 96 | } else { |
312 | 0 | return junk_string_value; |
313 | 0 | } |
314 | 96 | } |
315 | | |
316 | 3.62M | number = number * radix + digit; |
317 | 3.62M | int overflow = static_cast<int>(number >> kSignificandSize); |
318 | 3.62M | if (overflow != 0) { |
319 | | // Overflow occurred. Need to determine which direction to round the |
320 | | // result. |
321 | 298 | int overflow_bits_count = 1; |
322 | 578 | while (overflow > 1) { |
323 | 280 | overflow_bits_count++; |
324 | 280 | overflow >>= 1; |
325 | 280 | } |
326 | | |
327 | 298 | int dropped_bits_mask = ((1 << overflow_bits_count) - 1); |
328 | 298 | int dropped_bits = static_cast<int>(number) & dropped_bits_mask; |
329 | 298 | number >>= overflow_bits_count; |
330 | 298 | exponent += overflow_bits_count; |
331 | | |
332 | 298 | bool zero_tail = true; |
333 | 7.74k | for (;;) { |
334 | 7.74k | if (Advance(current, separator, radix, end)) break; |
335 | 7.49k | if (parse_as_hex_float && **current == '.') { |
336 | | // Just run over the '.'. We are just trying to see whether there is |
337 | | // a non-zero digit somewhere. |
338 | 2 | Advance(current, separator, radix, end); |
339 | 2 | DOUBLE_CONVERSION_ASSERT(*current != end); |
340 | 0 | post_decimal = true; |
341 | 2 | } |
342 | 7.49k | if (!isDigit(**current, radix)) break; |
343 | 7.44k | zero_tail = zero_tail && **current == '0'; |
344 | 7.44k | if (!post_decimal) exponent += radix_log_2; |
345 | 7.44k | } |
346 | | |
347 | 298 | if (!parse_as_hex_float && |
348 | 298 | !allow_trailing_junk && |
349 | 298 | AdvanceToNonspace(current, end)) { |
350 | 0 | return junk_string_value; |
351 | 0 | } |
352 | | |
353 | 298 | int middle_value = (1 << (overflow_bits_count - 1)); |
354 | 298 | if (dropped_bits > middle_value) { |
355 | 64 | number++; // Rounding up. |
356 | 234 | } else if (dropped_bits == middle_value) { |
357 | | // Rounding to even to consistency with decimals: half-way case rounds |
358 | | // up if significant part is odd and down otherwise. |
359 | 83 | if ((number & 1) != 0 || !zero_tail) { |
360 | 63 | number++; // Rounding up. |
361 | 63 | } |
362 | 83 | } |
363 | | |
364 | | // Rounding up may cause overflow. |
365 | 298 | if ((number & ((int64_t)1 << kSignificandSize)) != 0) { |
366 | 22 | exponent++; |
367 | 22 | number >>= 1; |
368 | 22 | } |
369 | 298 | break; |
370 | 298 | } |
371 | 3.62M | if (Advance(current, separator, radix, end)) break; |
372 | 3.62M | } |
373 | | |
374 | 854 | DOUBLE_CONVERSION_ASSERT(number < ((int64_t)1 << kSignificandSize)); |
375 | 854 | DOUBLE_CONVERSION_ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number); |
376 | | |
377 | 0 | *result_is_junk = false; |
378 | | |
379 | 854 | if (parse_as_hex_float) { |
380 | 292 | DOUBLE_CONVERSION_ASSERT(**current == 'p' || **current == 'P'); |
381 | 0 | Advance(current, separator, radix, end); |
382 | 292 | DOUBLE_CONVERSION_ASSERT(*current != end); |
383 | 0 | bool is_negative = false; |
384 | 292 | if (**current == '+') { |
385 | 1 | Advance(current, separator, radix, end); |
386 | 1 | DOUBLE_CONVERSION_ASSERT(*current != end); |
387 | 291 | } else if (**current == '-') { |
388 | 78 | is_negative = true; |
389 | 78 | Advance(current, separator, radix, end); |
390 | 78 | DOUBLE_CONVERSION_ASSERT(*current != end); |
391 | 78 | } |
392 | 0 | int written_exponent = 0; |
393 | 1.52k | while (IsDecimalDigitForRadix(**current, 10)) { |
394 | | // No need to read exponents if they are too big. That could potentially overflow |
395 | | // the `written_exponent` variable. |
396 | 1.49k | if (abs(written_exponent) <= 100 * Double::kMaxExponent) { |
397 | 1.04k | written_exponent = 10 * written_exponent + **current - '0'; |
398 | 1.04k | } |
399 | 1.49k | if (Advance(current, separator, radix, end)) break; |
400 | 1.49k | } |
401 | 292 | if (is_negative) written_exponent = -written_exponent; |
402 | 292 | exponent += written_exponent; |
403 | 292 | } |
404 | | |
405 | 854 | if (exponent == 0 || number == 0) { |
406 | 323 | if (sign) { |
407 | 74 | if (number == 0) return -0.0; |
408 | 73 | number = -number; |
409 | 73 | } |
410 | 322 | return static_cast<double>(number); |
411 | 323 | } |
412 | | |
413 | 531 | DOUBLE_CONVERSION_ASSERT(number != 0); |
414 | 0 | double result = Double(DiyFp(number, exponent)).value(); |
415 | 531 | return sign ? -result : result; |
416 | 854 | } string-to-double.cc:double double_conversion::RadixStringToIeee<4, char const*>(char const**, char const*, bool, unsigned short, bool, bool, double, bool, bool*) Line | Count | Source | 264 | 646 | bool* result_is_junk) { | 265 | 646 | DOUBLE_CONVERSION_ASSERT(*current != end); | 266 | 646 | DOUBLE_CONVERSION_ASSERT(!parse_as_hex_float || | 267 | 0 | IsHexFloatString(*current, end, separator, allow_trailing_junk)); | 268 | | | 269 | 0 | const int kDoubleSize = Double::kSignificandSize; | 270 | 646 | const int kSingleSize = Single::kSignificandSize; | 271 | 646 | const int kSignificandSize = read_as_double? kDoubleSize: kSingleSize; | 272 | | | 273 | 646 | *result_is_junk = true; | 274 | | | 275 | 646 | int64_t number = 0; | 276 | 646 | int exponent = 0; | 277 | 646 | const int radix = (1 << radix_log_2); | 278 | | // Whether we have encountered a '.' and are parsing the decimal digits. | 279 | | // Only relevant if parse_as_hex_float is true. | 280 | 646 | bool post_decimal = false; | 281 | | | 282 | | // Skip leading 0s. | 283 | 1.12k | while (**current == '0') { | 284 | 486 | if (Advance(current, separator, radix, end)) { | 285 | 8 | *result_is_junk = false; | 286 | 8 | return SignedZero(sign); | 287 | 8 | } | 288 | 486 | } | 289 | | | 290 | 3.62M | while (true) { | 291 | 3.62M | int digit; | 292 | 3.62M | if (IsDecimalDigitForRadix(**current, radix)) { | 293 | 3.61M | digit = static_cast<char>(**current) - '0'; | 294 | 3.61M | if (post_decimal) exponent -= radix_log_2; | 295 | 3.61M | } else if (IsCharacterDigitForRadix(**current, radix, 'a')) { | 296 | 1.08k | digit = static_cast<char>(**current) - 'a' + 10; | 297 | 1.08k | if (post_decimal) exponent -= radix_log_2; | 298 | 1.67k | } else if (IsCharacterDigitForRadix(**current, radix, 'A')) { | 299 | 1.27k | digit = static_cast<char>(**current) - 'A' + 10; | 300 | 1.27k | if (post_decimal) exponent -= radix_log_2; | 301 | 1.27k | } else if (parse_as_hex_float && **current == '.') { | 302 | 44 | post_decimal = true; | 303 | 44 | Advance(current, separator, radix, end); | 304 | 44 | DOUBLE_CONVERSION_ASSERT(*current != end); | 305 | 0 | continue; | 306 | 358 | } else if (parse_as_hex_float && (**current == 'p' || **current == 'P')) { | 307 | 262 | break; | 308 | 262 | } else { | 309 | 96 | if (allow_trailing_junk || !AdvanceToNonspace(current, end)) { | 310 | 96 | break; | 311 | 96 | } else { | 312 | 0 | return junk_string_value; | 313 | 0 | } | 314 | 96 | } | 315 | | | 316 | 3.62M | number = number * radix + digit; | 317 | 3.62M | int overflow = static_cast<int>(number >> kSignificandSize); | 318 | 3.62M | if (overflow != 0) { | 319 | | // Overflow occurred. Need to determine which direction to round the | 320 | | // result. | 321 | 154 | int overflow_bits_count = 1; | 322 | 409 | while (overflow > 1) { | 323 | 255 | overflow_bits_count++; | 324 | 255 | overflow >>= 1; | 325 | 255 | } | 326 | | | 327 | 154 | int dropped_bits_mask = ((1 << overflow_bits_count) - 1); | 328 | 154 | int dropped_bits = static_cast<int>(number) & dropped_bits_mask; | 329 | 154 | number >>= overflow_bits_count; | 330 | 154 | exponent += overflow_bits_count; | 331 | | | 332 | 154 | bool zero_tail = true; | 333 | 1.77k | for (;;) { | 334 | 1.77k | if (Advance(current, separator, radix, end)) break; | 335 | 1.67k | if (parse_as_hex_float && **current == '.') { | 336 | | // Just run over the '.'. We are just trying to see whether there is | 337 | | // a non-zero digit somewhere. | 338 | 2 | Advance(current, separator, radix, end); | 339 | 2 | DOUBLE_CONVERSION_ASSERT(*current != end); | 340 | 0 | post_decimal = true; | 341 | 2 | } | 342 | 1.67k | if (!isDigit(**current, radix)) break; | 343 | 1.62k | zero_tail = zero_tail && **current == '0'; | 344 | 1.62k | if (!post_decimal) exponent += radix_log_2; | 345 | 1.62k | } | 346 | | | 347 | 154 | if (!parse_as_hex_float && | 348 | 154 | !allow_trailing_junk && | 349 | 154 | AdvanceToNonspace(current, end)) { | 350 | 0 | return junk_string_value; | 351 | 0 | } | 352 | | | 353 | 154 | int middle_value = (1 << (overflow_bits_count - 1)); | 354 | 154 | if (dropped_bits > middle_value) { | 355 | 62 | number++; // Rounding up. | 356 | 92 | } else if (dropped_bits == middle_value) { | 357 | | // Rounding to even to consistency with decimals: half-way case rounds | 358 | | // up if significant part is odd and down otherwise. | 359 | 23 | if ((number & 1) != 0 || !zero_tail) { | 360 | 18 | number++; // Rounding up. | 361 | 18 | } | 362 | 23 | } | 363 | | | 364 | | // Rounding up may cause overflow. | 365 | 154 | if ((number & ((int64_t)1 << kSignificandSize)) != 0) { | 366 | 6 | exponent++; | 367 | 6 | number >>= 1; | 368 | 6 | } | 369 | 154 | break; | 370 | 154 | } | 371 | 3.62M | if (Advance(current, separator, radix, end)) break; | 372 | 3.62M | } | 373 | | | 374 | 638 | DOUBLE_CONVERSION_ASSERT(number < ((int64_t)1 << kSignificandSize)); | 375 | 638 | DOUBLE_CONVERSION_ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number); | 376 | | | 377 | 0 | *result_is_junk = false; | 378 | | | 379 | 638 | if (parse_as_hex_float) { | 380 | 292 | DOUBLE_CONVERSION_ASSERT(**current == 'p' || **current == 'P'); | 381 | 0 | Advance(current, separator, radix, end); | 382 | 292 | DOUBLE_CONVERSION_ASSERT(*current != end); | 383 | 0 | bool is_negative = false; | 384 | 292 | if (**current == '+') { | 385 | 1 | Advance(current, separator, radix, end); | 386 | 1 | DOUBLE_CONVERSION_ASSERT(*current != end); | 387 | 291 | } else if (**current == '-') { | 388 | 78 | is_negative = true; | 389 | 78 | Advance(current, separator, radix, end); | 390 | 78 | DOUBLE_CONVERSION_ASSERT(*current != end); | 391 | 78 | } | 392 | 0 | int written_exponent = 0; | 393 | 1.52k | while (IsDecimalDigitForRadix(**current, 10)) { | 394 | | // No need to read exponents if they are too big. That could potentially overflow | 395 | | // the `written_exponent` variable. | 396 | 1.49k | if (abs(written_exponent) <= 100 * Double::kMaxExponent) { | 397 | 1.04k | written_exponent = 10 * written_exponent + **current - '0'; | 398 | 1.04k | } | 399 | 1.49k | if (Advance(current, separator, radix, end)) break; | 400 | 1.49k | } | 401 | 292 | if (is_negative) written_exponent = -written_exponent; | 402 | 292 | exponent += written_exponent; | 403 | 292 | } | 404 | | | 405 | 638 | if (exponent == 0 || number == 0) { | 406 | 251 | if (sign) { | 407 | 54 | if (number == 0) return -0.0; | 408 | 53 | number = -number; | 409 | 53 | } | 410 | 250 | return static_cast<double>(number); | 411 | 251 | } | 412 | | | 413 | 387 | DOUBLE_CONVERSION_ASSERT(number != 0); | 414 | 0 | double result = Double(DiyFp(number, exponent)).value(); | 415 | 387 | return sign ? -result : result; | 416 | 638 | } |
string-to-double.cc:double double_conversion::RadixStringToIeee<3, char*>(char**, char*, bool, unsigned short, bool, bool, double, bool, bool*) Line | Count | Source | 264 | 216 | bool* result_is_junk) { | 265 | 216 | DOUBLE_CONVERSION_ASSERT(*current != end); | 266 | 216 | DOUBLE_CONVERSION_ASSERT(!parse_as_hex_float || | 267 | 0 | IsHexFloatString(*current, end, separator, allow_trailing_junk)); | 268 | | | 269 | 0 | const int kDoubleSize = Double::kSignificandSize; | 270 | 216 | const int kSingleSize = Single::kSignificandSize; | 271 | 216 | const int kSignificandSize = read_as_double? kDoubleSize: kSingleSize; | 272 | | | 273 | 216 | *result_is_junk = true; | 274 | | | 275 | 216 | int64_t number = 0; | 276 | 216 | int exponent = 0; | 277 | 216 | const int radix = (1 << radix_log_2); | 278 | | // Whether we have encountered a '.' and are parsing the decimal digits. | 279 | | // Only relevant if parse_as_hex_float is true. | 280 | 216 | bool post_decimal = false; | 281 | | | 282 | | // Skip leading 0s. | 283 | 216 | while (**current == '0') { | 284 | 0 | if (Advance(current, separator, radix, end)) { | 285 | 0 | *result_is_junk = false; | 286 | 0 | return SignedZero(sign); | 287 | 0 | } | 288 | 0 | } | 289 | | | 290 | 3.09k | while (true) { | 291 | 3.09k | int digit; | 292 | 3.09k | if (IsDecimalDigitForRadix(**current, radix)) { | 293 | 3.09k | digit = static_cast<char>(**current) - '0'; | 294 | 3.09k | if (post_decimal) exponent -= radix_log_2; | 295 | 3.09k | } else if (IsCharacterDigitForRadix(**current, radix, 'a')) { | 296 | 0 | digit = static_cast<char>(**current) - 'a' + 10; | 297 | 0 | if (post_decimal) exponent -= radix_log_2; | 298 | 0 | } else if (IsCharacterDigitForRadix(**current, radix, 'A')) { | 299 | 0 | digit = static_cast<char>(**current) - 'A' + 10; | 300 | 0 | if (post_decimal) exponent -= radix_log_2; | 301 | 0 | } else if (parse_as_hex_float && **current == '.') { | 302 | 0 | post_decimal = true; | 303 | 0 | Advance(current, separator, radix, end); | 304 | 0 | DOUBLE_CONVERSION_ASSERT(*current != end); | 305 | 0 | continue; | 306 | 0 | } else if (parse_as_hex_float && (**current == 'p' || **current == 'P')) { | 307 | 0 | break; | 308 | 0 | } else { | 309 | 0 | if (allow_trailing_junk || !AdvanceToNonspace(current, end)) { | 310 | 0 | break; | 311 | 0 | } else { | 312 | 0 | return junk_string_value; | 313 | 0 | } | 314 | 0 | } | 315 | | | 316 | 3.09k | number = number * radix + digit; | 317 | 3.09k | int overflow = static_cast<int>(number >> kSignificandSize); | 318 | 3.09k | if (overflow != 0) { | 319 | | // Overflow occurred. Need to determine which direction to round the | 320 | | // result. | 321 | 144 | int overflow_bits_count = 1; | 322 | 169 | while (overflow > 1) { | 323 | 25 | overflow_bits_count++; | 324 | 25 | overflow >>= 1; | 325 | 25 | } | 326 | | | 327 | 144 | int dropped_bits_mask = ((1 << overflow_bits_count) - 1); | 328 | 144 | int dropped_bits = static_cast<int>(number) & dropped_bits_mask; | 329 | 144 | number >>= overflow_bits_count; | 330 | 144 | exponent += overflow_bits_count; | 331 | | | 332 | 144 | bool zero_tail = true; | 333 | 5.96k | for (;;) { | 334 | 5.96k | if (Advance(current, separator, radix, end)) break; | 335 | 5.82k | if (parse_as_hex_float && **current == '.') { | 336 | | // Just run over the '.'. We are just trying to see whether there is | 337 | | // a non-zero digit somewhere. | 338 | 0 | Advance(current, separator, radix, end); | 339 | 0 | DOUBLE_CONVERSION_ASSERT(*current != end); | 340 | 0 | post_decimal = true; | 341 | 0 | } | 342 | 5.82k | if (!isDigit(**current, radix)) break; | 343 | 5.82k | zero_tail = zero_tail && **current == '0'; | 344 | 5.82k | if (!post_decimal) exponent += radix_log_2; | 345 | 5.82k | } | 346 | | | 347 | 144 | if (!parse_as_hex_float && | 348 | 144 | !allow_trailing_junk && | 349 | 144 | AdvanceToNonspace(current, end)) { | 350 | 0 | return junk_string_value; | 351 | 0 | } | 352 | | | 353 | 144 | int middle_value = (1 << (overflow_bits_count - 1)); | 354 | 144 | if (dropped_bits > middle_value) { | 355 | 2 | number++; // Rounding up. | 356 | 142 | } else if (dropped_bits == middle_value) { | 357 | | // Rounding to even to consistency with decimals: half-way case rounds | 358 | | // up if significant part is odd and down otherwise. | 359 | 60 | if ((number & 1) != 0 || !zero_tail) { | 360 | 45 | number++; // Rounding up. | 361 | 45 | } | 362 | 60 | } | 363 | | | 364 | | // Rounding up may cause overflow. | 365 | 144 | if ((number & ((int64_t)1 << kSignificandSize)) != 0) { | 366 | 16 | exponent++; | 367 | 16 | number >>= 1; | 368 | 16 | } | 369 | 144 | break; | 370 | 144 | } | 371 | 2.95k | if (Advance(current, separator, radix, end)) break; | 372 | 2.95k | } | 373 | | | 374 | 216 | DOUBLE_CONVERSION_ASSERT(number < ((int64_t)1 << kSignificandSize)); | 375 | 216 | DOUBLE_CONVERSION_ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number); | 376 | | | 377 | 0 | *result_is_junk = false; | 378 | | | 379 | 216 | if (parse_as_hex_float) { | 380 | 0 | DOUBLE_CONVERSION_ASSERT(**current == 'p' || **current == 'P'); | 381 | 0 | Advance(current, separator, radix, end); | 382 | 0 | DOUBLE_CONVERSION_ASSERT(*current != end); | 383 | 0 | bool is_negative = false; | 384 | 0 | if (**current == '+') { | 385 | 0 | Advance(current, separator, radix, end); | 386 | 0 | DOUBLE_CONVERSION_ASSERT(*current != end); | 387 | 0 | } else if (**current == '-') { | 388 | 0 | is_negative = true; | 389 | 0 | Advance(current, separator, radix, end); | 390 | 0 | DOUBLE_CONVERSION_ASSERT(*current != end); | 391 | 0 | } | 392 | 0 | int written_exponent = 0; | 393 | 0 | while (IsDecimalDigitForRadix(**current, 10)) { | 394 | | // No need to read exponents if they are too big. That could potentially overflow | 395 | | // the `written_exponent` variable. | 396 | 0 | if (abs(written_exponent) <= 100 * Double::kMaxExponent) { | 397 | 0 | written_exponent = 10 * written_exponent + **current - '0'; | 398 | 0 | } | 399 | 0 | if (Advance(current, separator, radix, end)) break; | 400 | 0 | } | 401 | 0 | if (is_negative) written_exponent = -written_exponent; | 402 | 0 | exponent += written_exponent; | 403 | 0 | } | 404 | | | 405 | 216 | if (exponent == 0 || number == 0) { | 406 | 72 | if (sign) { | 407 | 20 | if (number == 0) return -0.0; | 408 | 20 | number = -number; | 409 | 20 | } | 410 | 72 | return static_cast<double>(number); | 411 | 72 | } | 412 | | | 413 | 144 | DOUBLE_CONVERSION_ASSERT(number != 0); | 414 | 0 | double result = Double(DiyFp(number, exponent)).value(); | 415 | 144 | return sign ? -result : result; | 416 | 216 | } |
Unexecuted instantiation: string-to-double.cc:double double_conversion::RadixStringToIeee<4, unsigned short const*>(unsigned short const**, unsigned short const*, bool, unsigned short, bool, bool, double, bool, bool*) |
417 | | |
418 | | template <class Iterator> |
419 | | double StringToDoubleConverter::StringToIeee( |
420 | | Iterator input, |
421 | | int length, |
422 | | bool read_as_double, |
423 | 3.00k | int* processed_characters_count) const { |
424 | 3.00k | Iterator current = input; |
425 | 3.00k | Iterator end = input + length; |
426 | | |
427 | 3.00k | *processed_characters_count = 0; |
428 | | |
429 | 3.00k | const bool allow_trailing_junk = (flags_ & ALLOW_TRAILING_JUNK) != 0; |
430 | 3.00k | const bool allow_leading_spaces = (flags_ & ALLOW_LEADING_SPACES) != 0; |
431 | 3.00k | const bool allow_trailing_spaces = (flags_ & ALLOW_TRAILING_SPACES) != 0; |
432 | 3.00k | const bool allow_spaces_after_sign = (flags_ & ALLOW_SPACES_AFTER_SIGN) != 0; |
433 | 3.00k | const bool allow_case_insensitivity = (flags_ & ALLOW_CASE_INSENSITIVITY) != 0; |
434 | | |
435 | | // To make sure that iterator dereferencing is valid the following |
436 | | // convention is used: |
437 | | // 1. Each '++current' statement is followed by check for equality to 'end'. |
438 | | // 2. If AdvanceToNonspace returned false then current == end. |
439 | | // 3. If 'current' becomes equal to 'end' the function returns or goes to |
440 | | // 'parsing_done'. |
441 | | // 4. 'current' is not dereferenced after the 'parsing_done' label. |
442 | | // 5. Code before 'parsing_done' may rely on 'current != end'. |
443 | 3.00k | if (current == end) return empty_string_value_; |
444 | | |
445 | 3.00k | if (allow_leading_spaces || allow_trailing_spaces) { |
446 | 3.00k | if (!AdvanceToNonspace(¤t, end)) { |
447 | 25 | *processed_characters_count = static_cast<int>(current - input); |
448 | 25 | return empty_string_value_; |
449 | 25 | } |
450 | 2.97k | if (!allow_leading_spaces && (input != current)) { |
451 | | // No leading spaces allowed, but AdvanceToNonspace moved forward. |
452 | 0 | return junk_string_value_; |
453 | 0 | } |
454 | 2.97k | } |
455 | | |
456 | | // Exponent will be adjusted if insignificant digits of the integer part |
457 | | // or insignificant leading zeros of the fractional part are dropped. |
458 | 2.97k | int exponent = 0; |
459 | 2.97k | int significant_digits = 0; |
460 | 2.97k | int insignificant_digits = 0; |
461 | 2.97k | bool nonzero_digit_dropped = false; |
462 | | |
463 | 2.97k | bool sign = false; |
464 | | |
465 | 2.97k | if (*current == '+' || *current == '-') { |
466 | 119 | sign = (*current == '-'); |
467 | 119 | ++current; |
468 | 119 | Iterator next_non_space = current; |
469 | | // Skip following spaces (if allowed). |
470 | 119 | if (!AdvanceToNonspace(&next_non_space, end)) return junk_string_value_; |
471 | 93 | if (!allow_spaces_after_sign && (current != next_non_space)) { |
472 | 0 | return junk_string_value_; |
473 | 0 | } |
474 | 93 | current = next_non_space; |
475 | 93 | } |
476 | | |
477 | 2.94k | if (infinity_symbol_ != DOUBLE_CONVERSION_NULLPTR) { |
478 | 2.94k | if (ConsumeFirstCharacter(*current, infinity_symbol_, allow_case_insensitivity)) { |
479 | 4 | if (!ConsumeSubString(¤t, end, infinity_symbol_, allow_case_insensitivity)) { |
480 | 2 | return junk_string_value_; |
481 | 2 | } |
482 | | |
483 | 2 | if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) { |
484 | 0 | return junk_string_value_; |
485 | 0 | } |
486 | 2 | if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { |
487 | 0 | return junk_string_value_; |
488 | 0 | } |
489 | | |
490 | 2 | *processed_characters_count = static_cast<int>(current - input); |
491 | 2 | return sign ? -Double::Infinity() : Double::Infinity(); |
492 | 2 | } |
493 | 2.94k | } |
494 | | |
495 | 2.94k | if (nan_symbol_ != DOUBLE_CONVERSION_NULLPTR) { |
496 | 2.94k | if (ConsumeFirstCharacter(*current, nan_symbol_, allow_case_insensitivity)) { |
497 | 4 | if (!ConsumeSubString(¤t, end, nan_symbol_, allow_case_insensitivity)) { |
498 | 2 | return junk_string_value_; |
499 | 2 | } |
500 | | |
501 | 2 | if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) { |
502 | 0 | return junk_string_value_; |
503 | 0 | } |
504 | 2 | if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { |
505 | 0 | return junk_string_value_; |
506 | 0 | } |
507 | | |
508 | 2 | *processed_characters_count = static_cast<int>(current - input); |
509 | 2 | return sign ? -Double::NaN() : Double::NaN(); |
510 | 2 | } |
511 | 2.94k | } |
512 | | |
513 | 2.94k | bool leading_zero = false; |
514 | 2.94k | if (*current == '0') { |
515 | 1.02k | if (Advance(¤t, separator_, 10, end)) { |
516 | 2 | *processed_characters_count = static_cast<int>(current - input); |
517 | 2 | return SignedZero(sign); |
518 | 2 | } |
519 | | |
520 | 1.02k | leading_zero = true; |
521 | | |
522 | | // It could be hexadecimal value. |
523 | 1.02k | if (((flags_ & ALLOW_HEX) || (flags_ & ALLOW_HEX_FLOATS)) && |
524 | 1.02k | (*current == 'x' || *current == 'X')) { |
525 | 731 | ++current; |
526 | | |
527 | 731 | if (current == end) return junk_string_value_; // "0x" |
528 | | |
529 | 729 | bool parse_as_hex_float = (flags_ & ALLOW_HEX_FLOATS) && |
530 | 729 | IsHexFloatString(current, end, separator_, allow_trailing_junk); |
531 | | |
532 | 729 | if (!parse_as_hex_float && !isDigit(*current, 16)) { |
533 | 83 | return junk_string_value_; |
534 | 83 | } |
535 | | |
536 | 646 | bool result_is_junk; |
537 | 646 | double result = RadixStringToIeee<4>(¤t, |
538 | 646 | end, |
539 | 646 | sign, |
540 | 646 | separator_, |
541 | 646 | parse_as_hex_float, |
542 | 646 | allow_trailing_junk, |
543 | 646 | junk_string_value_, |
544 | 646 | read_as_double, |
545 | 646 | &result_is_junk); |
546 | 646 | if (!result_is_junk) { |
547 | 646 | if (allow_trailing_spaces) AdvanceToNonspace(¤t, end); |
548 | 646 | *processed_characters_count = static_cast<int>(current - input); |
549 | 646 | } |
550 | 646 | return result; |
551 | 729 | } |
552 | | |
553 | | // Ignore leading zeros in the integer part. |
554 | 669 | while (*current == '0') { |
555 | 388 | if (Advance(¤t, separator_, 10, end)) { |
556 | 8 | *processed_characters_count = static_cast<int>(current - input); |
557 | 8 | return SignedZero(sign); |
558 | 8 | } |
559 | 388 | } |
560 | 289 | } |
561 | | |
562 | 2.20k | bool octal = leading_zero && (flags_ & ALLOW_OCTALS) != 0; |
563 | | |
564 | | // The longest form of simplified number is: "-<significant digits>.1eXXX\0". |
565 | 2.20k | const int kBufferSize = kMaxSignificantDigits + 10; |
566 | 2.20k | DOUBLE_CONVERSION_STACK_UNINITIALIZED char |
567 | 2.20k | buffer[kBufferSize]; // NOLINT: size is known at compile time. |
568 | 2.20k | int buffer_pos = 0; |
569 | | |
570 | | // Copy significant digits of the integer part (if any) to the buffer. |
571 | 74.6k | while (*current >= '0' && *current <= '9') { |
572 | 73.2k | if (significant_digits < kMaxSignificantDigits) { |
573 | 72.8k | DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize); |
574 | 0 | buffer[buffer_pos++] = static_cast<char>(*current); |
575 | 72.8k | significant_digits++; |
576 | | // Will later check if it's an octal in the buffer. |
577 | 72.8k | } else { |
578 | 396 | insignificant_digits++; // Move the digit into the exponential part. |
579 | 396 | nonzero_digit_dropped = nonzero_digit_dropped || *current != '0'; |
580 | 396 | } |
581 | 73.2k | octal = octal && *current < '8'; |
582 | 73.2k | if (Advance(¤t, separator_, 10, end)) goto parsing_done; |
583 | 73.2k | } |
584 | | |
585 | 1.45k | if (significant_digits == 0) { |
586 | 278 | octal = false; |
587 | 278 | } |
588 | | |
589 | 1.45k | if (*current == '.') { |
590 | 344 | if (octal && !allow_trailing_junk) return junk_string_value_; |
591 | 344 | if (octal) goto parsing_done; |
592 | | |
593 | 343 | if (Advance(¤t, separator_, 10, end)) { |
594 | 3 | if (significant_digits == 0 && !leading_zero) { |
595 | 1 | return junk_string_value_; |
596 | 2 | } else { |
597 | 2 | goto parsing_done; |
598 | 2 | } |
599 | 3 | } |
600 | | |
601 | 340 | if (significant_digits == 0) { |
602 | | // octal = false; |
603 | | // Integer part consists of 0 or is absent. Significant digits start after |
604 | | // leading zeros (if any). |
605 | 2.28M | while (*current == '0') { |
606 | 2.28M | if (Advance(¤t, separator_, 10, end)) { |
607 | 14 | *processed_characters_count = static_cast<int>(current - input); |
608 | 14 | return SignedZero(sign); |
609 | 14 | } |
610 | 2.28M | exponent--; // Move this 0 into the exponent. |
611 | 2.28M | } |
612 | 155 | } |
613 | | |
614 | | // There is a fractional part. |
615 | | // We don't emit a '.', but adjust the exponent instead. |
616 | 59.7k | while (*current >= '0' && *current <= '9') { |
617 | 59.6k | if (significant_digits < kMaxSignificantDigits) { |
618 | 58.6k | DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize); |
619 | 0 | buffer[buffer_pos++] = static_cast<char>(*current); |
620 | 58.6k | significant_digits++; |
621 | 58.6k | exponent--; |
622 | 58.6k | } else { |
623 | | // Ignore insignificant digits in the fractional part. |
624 | 1.00k | nonzero_digit_dropped = nonzero_digit_dropped || *current != '0'; |
625 | 1.00k | } |
626 | 59.6k | if (Advance(¤t, separator_, 10, end)) goto parsing_done; |
627 | 59.6k | } |
628 | 326 | } |
629 | | |
630 | 1.21k | if (!leading_zero && exponent == 0 && significant_digits == 0) { |
631 | | // If leading_zeros is true then the string contains zeros. |
632 | | // If exponent < 0 then string was [+-]\.0*... |
633 | | // If significant_digits != 0 the string is not equal to 0. |
634 | | // Otherwise there are no digits in the string. |
635 | 80 | return junk_string_value_; |
636 | 80 | } |
637 | | |
638 | | // Parse exponential part. |
639 | 1.13k | if (*current == 'e' || *current == 'E') { |
640 | 1.02k | if (octal && !allow_trailing_junk) return junk_string_value_; |
641 | 1.02k | if (octal) goto parsing_done; |
642 | 1.01k | Iterator junk_begin = current; |
643 | 1.01k | ++current; |
644 | 1.01k | if (current == end) { |
645 | 10 | if (allow_trailing_junk) { |
646 | 10 | current = junk_begin; |
647 | 10 | goto parsing_done; |
648 | 10 | } else { |
649 | 0 | return junk_string_value_; |
650 | 0 | } |
651 | 10 | } |
652 | 1.00k | char exponen_sign = '+'; |
653 | 1.00k | if (*current == '+' || *current == '-') { |
654 | 394 | exponen_sign = static_cast<char>(*current); |
655 | 394 | ++current; |
656 | 394 | if (current == end) { |
657 | 2 | if (allow_trailing_junk) { |
658 | 2 | current = junk_begin; |
659 | 2 | goto parsing_done; |
660 | 2 | } else { |
661 | 0 | return junk_string_value_; |
662 | 0 | } |
663 | 2 | } |
664 | 394 | } |
665 | | |
666 | 1.00k | if (current == end || *current < '0' || *current > '9') { |
667 | 23 | if (allow_trailing_junk) { |
668 | 23 | current = junk_begin; |
669 | 23 | goto parsing_done; |
670 | 23 | } else { |
671 | 0 | return junk_string_value_; |
672 | 0 | } |
673 | 23 | } |
674 | | |
675 | 984 | const int max_exponent = INT_MAX / 2; |
676 | 984 | DOUBLE_CONVERSION_ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2); |
677 | 0 | int num = 0; |
678 | 3.42k | do { |
679 | | // Check overflow. |
680 | 3.42k | int digit = *current - '0'; |
681 | 3.42k | if (num >= max_exponent / 10 |
682 | 3.42k | && !(num == max_exponent / 10 && digit <= max_exponent % 10)) { |
683 | 233 | num = max_exponent; |
684 | 3.19k | } else { |
685 | 3.19k | num = num * 10 + digit; |
686 | 3.19k | } |
687 | 3.42k | ++current; |
688 | 3.42k | } while (current != end && *current >= '0' && *current <= '9'); |
689 | | |
690 | 984 | exponent += (exponen_sign == '-' ? -num : num); |
691 | 984 | } |
692 | | |
693 | 1.09k | if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) { |
694 | 0 | return junk_string_value_; |
695 | 0 | } |
696 | 1.09k | if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { |
697 | 0 | return junk_string_value_; |
698 | 0 | } |
699 | 1.09k | if (allow_trailing_spaces) { |
700 | 1.09k | AdvanceToNonspace(¤t, end); |
701 | 1.09k | } |
702 | | |
703 | 2.10k | parsing_done: |
704 | 2.10k | exponent += insignificant_digits; |
705 | | |
706 | 2.10k | if (octal) { |
707 | 216 | double result; |
708 | 216 | bool result_is_junk; |
709 | 216 | char* start = buffer; |
710 | 216 | result = RadixStringToIeee<3>(&start, |
711 | 216 | buffer + buffer_pos, |
712 | 216 | sign, |
713 | 216 | separator_, |
714 | 216 | false, // Don't parse as hex_float. |
715 | 216 | allow_trailing_junk, |
716 | 216 | junk_string_value_, |
717 | 216 | read_as_double, |
718 | 216 | &result_is_junk); |
719 | 216 | DOUBLE_CONVERSION_ASSERT(!result_is_junk); |
720 | 0 | *processed_characters_count = static_cast<int>(current - input); |
721 | 216 | return result; |
722 | 216 | } |
723 | | |
724 | 1.88k | if (nonzero_digit_dropped) { |
725 | 24 | buffer[buffer_pos++] = '1'; |
726 | 24 | exponent--; |
727 | 24 | } |
728 | | |
729 | 1.88k | DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize); |
730 | 0 | buffer[buffer_pos] = '\0'; |
731 | | |
732 | | // Code above ensures there are no leading zeros and the buffer has fewer than |
733 | | // kMaxSignificantDecimalDigits characters. Trim trailing zeros. |
734 | 1.88k | Vector<const char> chars(buffer, buffer_pos); |
735 | 1.88k | chars = TrimTrailingZeros(chars); |
736 | 1.88k | exponent += buffer_pos - chars.length(); |
737 | | |
738 | 1.88k | double converted; |
739 | 1.88k | if (read_as_double) { |
740 | 1.88k | converted = StrtodTrimmed(chars, exponent); |
741 | 1.88k | } else { |
742 | 0 | converted = StrtofTrimmed(chars, exponent); |
743 | 0 | } |
744 | 1.88k | *processed_characters_count = static_cast<int>(current - input); |
745 | 1.88k | return sign? -converted: converted; |
746 | 2.10k | } double double_conversion::StringToDoubleConverter::StringToIeee<char const*>(char const*, int, bool, int*) const Line | Count | Source | 423 | 3.00k | int* processed_characters_count) const { | 424 | 3.00k | Iterator current = input; | 425 | 3.00k | Iterator end = input + length; | 426 | | | 427 | 3.00k | *processed_characters_count = 0; | 428 | | | 429 | 3.00k | const bool allow_trailing_junk = (flags_ & ALLOW_TRAILING_JUNK) != 0; | 430 | 3.00k | const bool allow_leading_spaces = (flags_ & ALLOW_LEADING_SPACES) != 0; | 431 | 3.00k | const bool allow_trailing_spaces = (flags_ & ALLOW_TRAILING_SPACES) != 0; | 432 | 3.00k | const bool allow_spaces_after_sign = (flags_ & ALLOW_SPACES_AFTER_SIGN) != 0; | 433 | 3.00k | const bool allow_case_insensitivity = (flags_ & ALLOW_CASE_INSENSITIVITY) != 0; | 434 | | | 435 | | // To make sure that iterator dereferencing is valid the following | 436 | | // convention is used: | 437 | | // 1. Each '++current' statement is followed by check for equality to 'end'. | 438 | | // 2. If AdvanceToNonspace returned false then current == end. | 439 | | // 3. If 'current' becomes equal to 'end' the function returns or goes to | 440 | | // 'parsing_done'. | 441 | | // 4. 'current' is not dereferenced after the 'parsing_done' label. | 442 | | // 5. Code before 'parsing_done' may rely on 'current != end'. | 443 | 3.00k | if (current == end) return empty_string_value_; | 444 | | | 445 | 3.00k | if (allow_leading_spaces || allow_trailing_spaces) { | 446 | 3.00k | if (!AdvanceToNonspace(¤t, end)) { | 447 | 25 | *processed_characters_count = static_cast<int>(current - input); | 448 | 25 | return empty_string_value_; | 449 | 25 | } | 450 | 2.97k | if (!allow_leading_spaces && (input != current)) { | 451 | | // No leading spaces allowed, but AdvanceToNonspace moved forward. | 452 | 0 | return junk_string_value_; | 453 | 0 | } | 454 | 2.97k | } | 455 | | | 456 | | // Exponent will be adjusted if insignificant digits of the integer part | 457 | | // or insignificant leading zeros of the fractional part are dropped. | 458 | 2.97k | int exponent = 0; | 459 | 2.97k | int significant_digits = 0; | 460 | 2.97k | int insignificant_digits = 0; | 461 | 2.97k | bool nonzero_digit_dropped = false; | 462 | | | 463 | 2.97k | bool sign = false; | 464 | | | 465 | 2.97k | if (*current == '+' || *current == '-') { | 466 | 119 | sign = (*current == '-'); | 467 | 119 | ++current; | 468 | 119 | Iterator next_non_space = current; | 469 | | // Skip following spaces (if allowed). | 470 | 119 | if (!AdvanceToNonspace(&next_non_space, end)) return junk_string_value_; | 471 | 93 | if (!allow_spaces_after_sign && (current != next_non_space)) { | 472 | 0 | return junk_string_value_; | 473 | 0 | } | 474 | 93 | current = next_non_space; | 475 | 93 | } | 476 | | | 477 | 2.94k | if (infinity_symbol_ != DOUBLE_CONVERSION_NULLPTR) { | 478 | 2.94k | if (ConsumeFirstCharacter(*current, infinity_symbol_, allow_case_insensitivity)) { | 479 | 4 | if (!ConsumeSubString(¤t, end, infinity_symbol_, allow_case_insensitivity)) { | 480 | 2 | return junk_string_value_; | 481 | 2 | } | 482 | | | 483 | 2 | if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) { | 484 | 0 | return junk_string_value_; | 485 | 0 | } | 486 | 2 | if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { | 487 | 0 | return junk_string_value_; | 488 | 0 | } | 489 | | | 490 | 2 | *processed_characters_count = static_cast<int>(current - input); | 491 | 2 | return sign ? -Double::Infinity() : Double::Infinity(); | 492 | 2 | } | 493 | 2.94k | } | 494 | | | 495 | 2.94k | if (nan_symbol_ != DOUBLE_CONVERSION_NULLPTR) { | 496 | 2.94k | if (ConsumeFirstCharacter(*current, nan_symbol_, allow_case_insensitivity)) { | 497 | 4 | if (!ConsumeSubString(¤t, end, nan_symbol_, allow_case_insensitivity)) { | 498 | 2 | return junk_string_value_; | 499 | 2 | } | 500 | | | 501 | 2 | if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) { | 502 | 0 | return junk_string_value_; | 503 | 0 | } | 504 | 2 | if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { | 505 | 0 | return junk_string_value_; | 506 | 0 | } | 507 | | | 508 | 2 | *processed_characters_count = static_cast<int>(current - input); | 509 | 2 | return sign ? -Double::NaN() : Double::NaN(); | 510 | 2 | } | 511 | 2.94k | } | 512 | | | 513 | 2.94k | bool leading_zero = false; | 514 | 2.94k | if (*current == '0') { | 515 | 1.02k | if (Advance(¤t, separator_, 10, end)) { | 516 | 2 | *processed_characters_count = static_cast<int>(current - input); | 517 | 2 | return SignedZero(sign); | 518 | 2 | } | 519 | | | 520 | 1.02k | leading_zero = true; | 521 | | | 522 | | // It could be hexadecimal value. | 523 | 1.02k | if (((flags_ & ALLOW_HEX) || (flags_ & ALLOW_HEX_FLOATS)) && | 524 | 1.02k | (*current == 'x' || *current == 'X')) { | 525 | 731 | ++current; | 526 | | | 527 | 731 | if (current == end) return junk_string_value_; // "0x" | 528 | | | 529 | 729 | bool parse_as_hex_float = (flags_ & ALLOW_HEX_FLOATS) && | 530 | 729 | IsHexFloatString(current, end, separator_, allow_trailing_junk); | 531 | | | 532 | 729 | if (!parse_as_hex_float && !isDigit(*current, 16)) { | 533 | 83 | return junk_string_value_; | 534 | 83 | } | 535 | | | 536 | 646 | bool result_is_junk; | 537 | 646 | double result = RadixStringToIeee<4>(¤t, | 538 | 646 | end, | 539 | 646 | sign, | 540 | 646 | separator_, | 541 | 646 | parse_as_hex_float, | 542 | 646 | allow_trailing_junk, | 543 | 646 | junk_string_value_, | 544 | 646 | read_as_double, | 545 | 646 | &result_is_junk); | 546 | 646 | if (!result_is_junk) { | 547 | 646 | if (allow_trailing_spaces) AdvanceToNonspace(¤t, end); | 548 | 646 | *processed_characters_count = static_cast<int>(current - input); | 549 | 646 | } | 550 | 646 | return result; | 551 | 729 | } | 552 | | | 553 | | // Ignore leading zeros in the integer part. | 554 | 669 | while (*current == '0') { | 555 | 388 | if (Advance(¤t, separator_, 10, end)) { | 556 | 8 | *processed_characters_count = static_cast<int>(current - input); | 557 | 8 | return SignedZero(sign); | 558 | 8 | } | 559 | 388 | } | 560 | 289 | } | 561 | | | 562 | 2.20k | bool octal = leading_zero && (flags_ & ALLOW_OCTALS) != 0; | 563 | | | 564 | | // The longest form of simplified number is: "-<significant digits>.1eXXX\0". | 565 | 2.20k | const int kBufferSize = kMaxSignificantDigits + 10; | 566 | 2.20k | DOUBLE_CONVERSION_STACK_UNINITIALIZED char | 567 | 2.20k | buffer[kBufferSize]; // NOLINT: size is known at compile time. | 568 | 2.20k | int buffer_pos = 0; | 569 | | | 570 | | // Copy significant digits of the integer part (if any) to the buffer. | 571 | 74.6k | while (*current >= '0' && *current <= '9') { | 572 | 73.2k | if (significant_digits < kMaxSignificantDigits) { | 573 | 72.8k | DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize); | 574 | 0 | buffer[buffer_pos++] = static_cast<char>(*current); | 575 | 72.8k | significant_digits++; | 576 | | // Will later check if it's an octal in the buffer. | 577 | 72.8k | } else { | 578 | 396 | insignificant_digits++; // Move the digit into the exponential part. | 579 | 396 | nonzero_digit_dropped = nonzero_digit_dropped || *current != '0'; | 580 | 396 | } | 581 | 73.2k | octal = octal && *current < '8'; | 582 | 73.2k | if (Advance(¤t, separator_, 10, end)) goto parsing_done; | 583 | 73.2k | } | 584 | | | 585 | 1.45k | if (significant_digits == 0) { | 586 | 278 | octal = false; | 587 | 278 | } | 588 | | | 589 | 1.45k | if (*current == '.') { | 590 | 344 | if (octal && !allow_trailing_junk) return junk_string_value_; | 591 | 344 | if (octal) goto parsing_done; | 592 | | | 593 | 343 | if (Advance(¤t, separator_, 10, end)) { | 594 | 3 | if (significant_digits == 0 && !leading_zero) { | 595 | 1 | return junk_string_value_; | 596 | 2 | } else { | 597 | 2 | goto parsing_done; | 598 | 2 | } | 599 | 3 | } | 600 | | | 601 | 340 | if (significant_digits == 0) { | 602 | | // octal = false; | 603 | | // Integer part consists of 0 or is absent. Significant digits start after | 604 | | // leading zeros (if any). | 605 | 2.28M | while (*current == '0') { | 606 | 2.28M | if (Advance(¤t, separator_, 10, end)) { | 607 | 14 | *processed_characters_count = static_cast<int>(current - input); | 608 | 14 | return SignedZero(sign); | 609 | 14 | } | 610 | 2.28M | exponent--; // Move this 0 into the exponent. | 611 | 2.28M | } | 612 | 155 | } | 613 | | | 614 | | // There is a fractional part. | 615 | | // We don't emit a '.', but adjust the exponent instead. | 616 | 59.7k | while (*current >= '0' && *current <= '9') { | 617 | 59.6k | if (significant_digits < kMaxSignificantDigits) { | 618 | 58.6k | DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize); | 619 | 0 | buffer[buffer_pos++] = static_cast<char>(*current); | 620 | 58.6k | significant_digits++; | 621 | 58.6k | exponent--; | 622 | 58.6k | } else { | 623 | | // Ignore insignificant digits in the fractional part. | 624 | 1.00k | nonzero_digit_dropped = nonzero_digit_dropped || *current != '0'; | 625 | 1.00k | } | 626 | 59.6k | if (Advance(¤t, separator_, 10, end)) goto parsing_done; | 627 | 59.6k | } | 628 | 326 | } | 629 | | | 630 | 1.21k | if (!leading_zero && exponent == 0 && significant_digits == 0) { | 631 | | // If leading_zeros is true then the string contains zeros. | 632 | | // If exponent < 0 then string was [+-]\.0*... | 633 | | // If significant_digits != 0 the string is not equal to 0. | 634 | | // Otherwise there are no digits in the string. | 635 | 80 | return junk_string_value_; | 636 | 80 | } | 637 | | | 638 | | // Parse exponential part. | 639 | 1.13k | if (*current == 'e' || *current == 'E') { | 640 | 1.02k | if (octal && !allow_trailing_junk) return junk_string_value_; | 641 | 1.02k | if (octal) goto parsing_done; | 642 | 1.01k | Iterator junk_begin = current; | 643 | 1.01k | ++current; | 644 | 1.01k | if (current == end) { | 645 | 10 | if (allow_trailing_junk) { | 646 | 10 | current = junk_begin; | 647 | 10 | goto parsing_done; | 648 | 10 | } else { | 649 | 0 | return junk_string_value_; | 650 | 0 | } | 651 | 10 | } | 652 | 1.00k | char exponen_sign = '+'; | 653 | 1.00k | if (*current == '+' || *current == '-') { | 654 | 394 | exponen_sign = static_cast<char>(*current); | 655 | 394 | ++current; | 656 | 394 | if (current == end) { | 657 | 2 | if (allow_trailing_junk) { | 658 | 2 | current = junk_begin; | 659 | 2 | goto parsing_done; | 660 | 2 | } else { | 661 | 0 | return junk_string_value_; | 662 | 0 | } | 663 | 2 | } | 664 | 394 | } | 665 | | | 666 | 1.00k | if (current == end || *current < '0' || *current > '9') { | 667 | 23 | if (allow_trailing_junk) { | 668 | 23 | current = junk_begin; | 669 | 23 | goto parsing_done; | 670 | 23 | } else { | 671 | 0 | return junk_string_value_; | 672 | 0 | } | 673 | 23 | } | 674 | | | 675 | 984 | const int max_exponent = INT_MAX / 2; | 676 | 984 | DOUBLE_CONVERSION_ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2); | 677 | 0 | int num = 0; | 678 | 3.42k | do { | 679 | | // Check overflow. | 680 | 3.42k | int digit = *current - '0'; | 681 | 3.42k | if (num >= max_exponent / 10 | 682 | 3.42k | && !(num == max_exponent / 10 && digit <= max_exponent % 10)) { | 683 | 233 | num = max_exponent; | 684 | 3.19k | } else { | 685 | 3.19k | num = num * 10 + digit; | 686 | 3.19k | } | 687 | 3.42k | ++current; | 688 | 3.42k | } while (current != end && *current >= '0' && *current <= '9'); | 689 | | | 690 | 984 | exponent += (exponen_sign == '-' ? -num : num); | 691 | 984 | } | 692 | | | 693 | 1.09k | if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) { | 694 | 0 | return junk_string_value_; | 695 | 0 | } | 696 | 1.09k | if (!allow_trailing_junk && AdvanceToNonspace(¤t, end)) { | 697 | 0 | return junk_string_value_; | 698 | 0 | } | 699 | 1.09k | if (allow_trailing_spaces) { | 700 | 1.09k | AdvanceToNonspace(¤t, end); | 701 | 1.09k | } | 702 | | | 703 | 2.10k | parsing_done: | 704 | 2.10k | exponent += insignificant_digits; | 705 | | | 706 | 2.10k | if (octal) { | 707 | 216 | double result; | 708 | 216 | bool result_is_junk; | 709 | 216 | char* start = buffer; | 710 | 216 | result = RadixStringToIeee<3>(&start, | 711 | 216 | buffer + buffer_pos, | 712 | 216 | sign, | 713 | 216 | separator_, | 714 | 216 | false, // Don't parse as hex_float. | 715 | 216 | allow_trailing_junk, | 716 | 216 | junk_string_value_, | 717 | 216 | read_as_double, | 718 | 216 | &result_is_junk); | 719 | 216 | DOUBLE_CONVERSION_ASSERT(!result_is_junk); | 720 | 0 | *processed_characters_count = static_cast<int>(current - input); | 721 | 216 | return result; | 722 | 216 | } | 723 | | | 724 | 1.88k | if (nonzero_digit_dropped) { | 725 | 24 | buffer[buffer_pos++] = '1'; | 726 | 24 | exponent--; | 727 | 24 | } | 728 | | | 729 | 1.88k | DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize); | 730 | 0 | buffer[buffer_pos] = '\0'; | 731 | | | 732 | | // Code above ensures there are no leading zeros and the buffer has fewer than | 733 | | // kMaxSignificantDecimalDigits characters. Trim trailing zeros. | 734 | 1.88k | Vector<const char> chars(buffer, buffer_pos); | 735 | 1.88k | chars = TrimTrailingZeros(chars); | 736 | 1.88k | exponent += buffer_pos - chars.length(); | 737 | | | 738 | 1.88k | double converted; | 739 | 1.88k | if (read_as_double) { | 740 | 1.88k | converted = StrtodTrimmed(chars, exponent); | 741 | 1.88k | } else { | 742 | 0 | converted = StrtofTrimmed(chars, exponent); | 743 | 0 | } | 744 | 1.88k | *processed_characters_count = static_cast<int>(current - input); | 745 | 1.88k | return sign? -converted: converted; | 746 | 2.10k | } |
Unexecuted instantiation: double double_conversion::StringToDoubleConverter::StringToIeee<unsigned short const*>(unsigned short const*, int, bool, int*) const |
747 | | |
748 | | |
749 | | double StringToDoubleConverter::StringToDouble( |
750 | | const char* buffer, |
751 | | int length, |
752 | 3.00k | int* processed_characters_count) const { |
753 | 3.00k | return StringToIeee(buffer, length, true, processed_characters_count); |
754 | 3.00k | } |
755 | | |
756 | | |
757 | | double StringToDoubleConverter::StringToDouble( |
758 | | const uc16* buffer, |
759 | | int length, |
760 | 0 | int* processed_characters_count) const { |
761 | 0 | return StringToIeee(buffer, length, true, processed_characters_count); |
762 | 0 | } |
763 | | |
764 | | |
765 | | float StringToDoubleConverter::StringToFloat( |
766 | | const char* buffer, |
767 | | int length, |
768 | 0 | int* processed_characters_count) const { |
769 | 0 | return static_cast<float>(StringToIeee(buffer, length, false, |
770 | 0 | processed_characters_count)); |
771 | 0 | } |
772 | | |
773 | | |
774 | | float StringToDoubleConverter::StringToFloat( |
775 | | const uc16* buffer, |
776 | | int length, |
777 | 0 | int* processed_characters_count) const { |
778 | 0 | return static_cast<float>(StringToIeee(buffer, length, false, |
779 | 0 | processed_characters_count)); |
780 | 0 | } |
781 | | |
782 | | |
783 | | template<> |
784 | | double StringToDoubleConverter::StringTo<double>( |
785 | | const char* buffer, |
786 | | int length, |
787 | 0 | int* processed_characters_count) const { |
788 | 0 | return StringToDouble(buffer, length, processed_characters_count); |
789 | 0 | } |
790 | | |
791 | | |
792 | | template<> |
793 | | float StringToDoubleConverter::StringTo<float>( |
794 | | const char* buffer, |
795 | | int length, |
796 | 0 | int* processed_characters_count) const { |
797 | 0 | return StringToFloat(buffer, length, processed_characters_count); |
798 | 0 | } |
799 | | |
800 | | |
801 | | template<> |
802 | | double StringToDoubleConverter::StringTo<double>( |
803 | | const uc16* buffer, |
804 | | int length, |
805 | 0 | int* processed_characters_count) const { |
806 | 0 | return StringToDouble(buffer, length, processed_characters_count); |
807 | 0 | } |
808 | | |
809 | | |
810 | | template<> |
811 | | float StringToDoubleConverter::StringTo<float>( |
812 | | const uc16* buffer, |
813 | | int length, |
814 | 0 | int* processed_characters_count) const { |
815 | 0 | return StringToFloat(buffer, length, processed_characters_count); |
816 | 0 | } |
817 | | |
818 | | } // namespace double_conversion |