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