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(&current, separator, 16, end)) return false;
249   }
250   if (*current == '.') {
251     if (Advance(&current, separator, 16, end)) return false;
252     while (isDigit(*current, 16)) {
253       saw_digit = true;
254       if (Advance(&current, separator, 16, end)) return false;
255     }
256   }
257   if (!saw_digit) return false;
258   if (*current != 'p' && *current != 'P') return false;
259   if (Advance(&current, separator, 16, end)) return false;
260   if (*current == '+' || *current == '-') {
261     if (Advance(&current, separator, 16, end)) return false;
262   }
263   if (!isDigit(*current, 10)) return false;
264   if (Advance(&current, separator, 16, end)) return true;
265   while (isDigit(*current, 10)) {
266     if (Advance(&current, separator, 16, end)) return true;
267   }
268   return allow_trailing_junk || !AdvanceToNonspace(&current, 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(&current, 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(&current, 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(&current, 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(&current, 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(&current, 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(&current, 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>(&current,
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(&current, 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(&current, 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(&current, 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(&current, 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(&current, 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(&current, 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(&current, end)) {
718     return junk_string_value_;
719   }
720   if (allow_trailing_spaces) {
721     AdvanceToNonspace(&current, 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