• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <limits.h>
38 #include <math.h>
39 
40 // ICU PATCH: Customize header file paths for ICU.
41 // The file fixed-dtoa.h is not needed.
42 
43 #include "double-conversion.h"
44 
45 #include "double-conversion-bignum-dtoa.h"
46 #include "double-conversion-fast-dtoa.h"
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 namespace double_conversion {
55 
56 #if 0  // not needed for ICU
57 const DoubleToStringConverter& DoubleToStringConverter::EcmaScriptConverter() {
58   int flags = UNIQUE_ZERO | EMIT_POSITIVE_EXPONENT_SIGN;
59   static DoubleToStringConverter converter(flags,
60                                            "Infinity",
61                                            "NaN",
62                                            'e',
63                                            -6, 21,
64                                            6, 0);
65   return converter;
66 }
67 
68 
69 bool DoubleToStringConverter::HandleSpecialValues(
70     double value,
71     StringBuilder* result_builder) const {
72   Double double_inspect(value);
73   if (double_inspect.IsInfinite()) {
74     if (infinity_symbol_ == NULL) return false;
75     if (value < 0) {
76       result_builder->AddCharacter('-');
77     }
78     result_builder->AddString(infinity_symbol_);
79     return true;
80   }
81   if (double_inspect.IsNan()) {
82     if (nan_symbol_ == NULL) return false;
83     result_builder->AddString(nan_symbol_);
84     return true;
85   }
86   return false;
87 }
88 
89 
90 void DoubleToStringConverter::CreateExponentialRepresentation(
91     const char* decimal_digits,
92     int length,
93     int exponent,
94     StringBuilder* result_builder) const {
95   ASSERT(length != 0);
96   result_builder->AddCharacter(decimal_digits[0]);
97   if (length != 1) {
98     result_builder->AddCharacter('.');
99     result_builder->AddSubstring(&decimal_digits[1], length-1);
100   }
101   result_builder->AddCharacter(exponent_character_);
102   if (exponent < 0) {
103     result_builder->AddCharacter('-');
104     exponent = -exponent;
105   } else {
106     if ((flags_ & EMIT_POSITIVE_EXPONENT_SIGN) != 0) {
107       result_builder->AddCharacter('+');
108     }
109   }
110   if (exponent == 0) {
111     result_builder->AddCharacter('0');
112     return;
113   }
114   ASSERT(exponent < 1e4);
115   const int kMaxExponentLength = 5;
116   char buffer[kMaxExponentLength + 1];
117   buffer[kMaxExponentLength] = '\0';
118   int first_char_pos = kMaxExponentLength;
119   while (exponent > 0) {
120     buffer[--first_char_pos] = '0' + (exponent % 10);
121     exponent /= 10;
122   }
123   result_builder->AddSubstring(&buffer[first_char_pos],
124                                kMaxExponentLength - first_char_pos);
125 }
126 
127 
128 void DoubleToStringConverter::CreateDecimalRepresentation(
129     const char* decimal_digits,
130     int length,
131     int decimal_point,
132     int digits_after_point,
133     StringBuilder* result_builder) const {
134   // Create a representation that is padded with zeros if needed.
135   if (decimal_point <= 0) {
136       // "0.00000decimal_rep" or "0.000decimal_rep00".
137     result_builder->AddCharacter('0');
138     if (digits_after_point > 0) {
139       result_builder->AddCharacter('.');
140       result_builder->AddPadding('0', -decimal_point);
141       ASSERT(length <= digits_after_point - (-decimal_point));
142       result_builder->AddSubstring(decimal_digits, length);
143       int remaining_digits = digits_after_point - (-decimal_point) - length;
144       result_builder->AddPadding('0', remaining_digits);
145     }
146   } else if (decimal_point >= length) {
147     // "decimal_rep0000.00000" or "decimal_rep.0000".
148     result_builder->AddSubstring(decimal_digits, length);
149     result_builder->AddPadding('0', decimal_point - length);
150     if (digits_after_point > 0) {
151       result_builder->AddCharacter('.');
152       result_builder->AddPadding('0', digits_after_point);
153     }
154   } else {
155     // "decima.l_rep000".
156     ASSERT(digits_after_point > 0);
157     result_builder->AddSubstring(decimal_digits, decimal_point);
158     result_builder->AddCharacter('.');
159     ASSERT(length - decimal_point <= digits_after_point);
160     result_builder->AddSubstring(&decimal_digits[decimal_point],
161                                  length - decimal_point);
162     int remaining_digits = digits_after_point - (length - decimal_point);
163     result_builder->AddPadding('0', remaining_digits);
164   }
165   if (digits_after_point == 0) {
166     if ((flags_ & EMIT_TRAILING_DECIMAL_POINT) != 0) {
167       result_builder->AddCharacter('.');
168     }
169     if ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) {
170       result_builder->AddCharacter('0');
171     }
172   }
173 }
174 
175 
176 bool DoubleToStringConverter::ToShortestIeeeNumber(
177     double value,
178     StringBuilder* result_builder,
179     DoubleToStringConverter::DtoaMode mode) const {
180   ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE);
181   if (Double(value).IsSpecial()) {
182     return HandleSpecialValues(value, result_builder);
183   }
184 
185   int decimal_point;
186   bool sign;
187   const int kDecimalRepCapacity = kBase10MaximalLength + 1;
188   char decimal_rep[kDecimalRepCapacity];
189   int decimal_rep_length;
190 
191   DoubleToAscii(value, mode, 0, decimal_rep, kDecimalRepCapacity,
192                 &sign, &decimal_rep_length, &decimal_point);
193 
194   bool unique_zero = (flags_ & UNIQUE_ZERO) != 0;
195   if (sign && (value != 0.0 || !unique_zero)) {
196     result_builder->AddCharacter('-');
197   }
198 
199   int exponent = decimal_point - 1;
200   if ((decimal_in_shortest_low_ <= exponent) &&
201       (exponent < decimal_in_shortest_high_)) {
202     CreateDecimalRepresentation(decimal_rep, decimal_rep_length,
203                                 decimal_point,
204                                 Max(0, decimal_rep_length - decimal_point),
205                                 result_builder);
206   } else {
207     CreateExponentialRepresentation(decimal_rep, decimal_rep_length, exponent,
208                                     result_builder);
209   }
210   return true;
211 }
212 
213 
214 bool DoubleToStringConverter::ToFixed(double value,
215                                       int requested_digits,
216                                       StringBuilder* result_builder) const {
217   ASSERT(kMaxFixedDigitsBeforePoint == 60);
218   const double kFirstNonFixed = 1e60;
219 
220   if (Double(value).IsSpecial()) {
221     return HandleSpecialValues(value, result_builder);
222   }
223 
224   if (requested_digits > kMaxFixedDigitsAfterPoint) return false;
225   if (value >= kFirstNonFixed || value <= -kFirstNonFixed) return false;
226 
227   // Find a sufficiently precise decimal representation of n.
228   int decimal_point;
229   bool sign;
230   // Add space for the '\0' byte.
231   const int kDecimalRepCapacity =
232       kMaxFixedDigitsBeforePoint + kMaxFixedDigitsAfterPoint + 1;
233   char decimal_rep[kDecimalRepCapacity];
234   int decimal_rep_length;
235   DoubleToAscii(value, FIXED, requested_digits,
236                 decimal_rep, kDecimalRepCapacity,
237                 &sign, &decimal_rep_length, &decimal_point);
238 
239   bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
240   if (sign && (value != 0.0 || !unique_zero)) {
241     result_builder->AddCharacter('-');
242   }
243 
244   CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
245                               requested_digits, result_builder);
246   return true;
247 }
248 
249 
250 bool DoubleToStringConverter::ToExponential(
251     double value,
252     int requested_digits,
253     StringBuilder* result_builder) const {
254   if (Double(value).IsSpecial()) {
255     return HandleSpecialValues(value, result_builder);
256   }
257 
258   if (requested_digits < -1) return false;
259   if (requested_digits > kMaxExponentialDigits) return false;
260 
261   int decimal_point;
262   bool sign;
263   // Add space for digit before the decimal point and the '\0' character.
264   const int kDecimalRepCapacity = kMaxExponentialDigits + 2;
265   ASSERT(kDecimalRepCapacity > kBase10MaximalLength);
266   char decimal_rep[kDecimalRepCapacity];
267   int decimal_rep_length;
268 
269   if (requested_digits == -1) {
270     DoubleToAscii(value, SHORTEST, 0,
271                   decimal_rep, kDecimalRepCapacity,
272                   &sign, &decimal_rep_length, &decimal_point);
273   } else {
274     DoubleToAscii(value, PRECISION, requested_digits + 1,
275                   decimal_rep, kDecimalRepCapacity,
276                   &sign, &decimal_rep_length, &decimal_point);
277     ASSERT(decimal_rep_length <= requested_digits + 1);
278 
279     for (int i = decimal_rep_length; i < requested_digits + 1; ++i) {
280       decimal_rep[i] = '0';
281     }
282     decimal_rep_length = requested_digits + 1;
283   }
284 
285   bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
286   if (sign && (value != 0.0 || !unique_zero)) {
287     result_builder->AddCharacter('-');
288   }
289 
290   int exponent = decimal_point - 1;
291   CreateExponentialRepresentation(decimal_rep,
292                                   decimal_rep_length,
293                                   exponent,
294                                   result_builder);
295   return true;
296 }
297 
298 
299 bool DoubleToStringConverter::ToPrecision(double value,
300                                           int precision,
301                                           StringBuilder* result_builder) const {
302   if (Double(value).IsSpecial()) {
303     return HandleSpecialValues(value, result_builder);
304   }
305 
306   if (precision < kMinPrecisionDigits || precision > kMaxPrecisionDigits) {
307     return false;
308   }
309 
310   // Find a sufficiently precise decimal representation of n.
311   int decimal_point;
312   bool sign;
313   // Add one for the terminating null character.
314   const int kDecimalRepCapacity = kMaxPrecisionDigits + 1;
315   char decimal_rep[kDecimalRepCapacity];
316   int decimal_rep_length;
317 
318   DoubleToAscii(value, PRECISION, precision,
319                 decimal_rep, kDecimalRepCapacity,
320                 &sign, &decimal_rep_length, &decimal_point);
321   ASSERT(decimal_rep_length <= precision);
322 
323   bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
324   if (sign && (value != 0.0 || !unique_zero)) {
325     result_builder->AddCharacter('-');
326   }
327 
328   // The exponent if we print the number as x.xxeyyy. That is with the
329   // decimal point after the first digit.
330   int exponent = decimal_point - 1;
331 
332   int extra_zero = ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) ? 1 : 0;
333   if ((-decimal_point + 1 > max_leading_padding_zeroes_in_precision_mode_) ||
334       (decimal_point - precision + extra_zero >
335        max_trailing_padding_zeroes_in_precision_mode_)) {
336     // Fill buffer to contain 'precision' digits.
337     // Usually the buffer is already at the correct length, but 'DoubleToAscii'
338     // is allowed to return less characters.
339     for (int i = decimal_rep_length; i < precision; ++i) {
340       decimal_rep[i] = '0';
341     }
342 
343     CreateExponentialRepresentation(decimal_rep,
344                                     precision,
345                                     exponent,
346                                     result_builder);
347   } else {
348     CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
349                                 Max(0, precision - decimal_point),
350                                 result_builder);
351   }
352   return true;
353 }
354 #endif // not needed for ICU
355 
356 
DtoaToBignumDtoaMode(DoubleToStringConverter::DtoaMode dtoa_mode)357 static BignumDtoaMode DtoaToBignumDtoaMode(
358     DoubleToStringConverter::DtoaMode dtoa_mode) {
359   switch (dtoa_mode) {
360     case DoubleToStringConverter::SHORTEST:  return BIGNUM_DTOA_SHORTEST;
361     case DoubleToStringConverter::SHORTEST_SINGLE:
362         return BIGNUM_DTOA_SHORTEST_SINGLE;
363     case DoubleToStringConverter::FIXED:     return BIGNUM_DTOA_FIXED;
364     case DoubleToStringConverter::PRECISION: return BIGNUM_DTOA_PRECISION;
365     default:
366       UNREACHABLE();
367   }
368 }
369 
370 
DoubleToAscii(double v,DtoaMode mode,int requested_digits,char * buffer,int buffer_length,bool * sign,int * length,int * point)371 void DoubleToStringConverter::DoubleToAscii(double v,
372                                             DtoaMode mode,
373                                             int requested_digits,
374                                             char* buffer,
375                                             int buffer_length,
376                                             bool* sign,
377                                             int* length,
378                                             int* point) {
379   Vector<char> vector(buffer, buffer_length);
380   ASSERT(!Double(v).IsSpecial());
381   ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE || requested_digits >= 0);
382 
383   if (Double(v).Sign() < 0) {
384     *sign = true;
385     v = -v;
386   } else {
387     *sign = false;
388   }
389 
390   if (mode == PRECISION && requested_digits == 0) {
391     vector[0] = '\0';
392     *length = 0;
393     return;
394   }
395 
396   if (v == 0) {
397     vector[0] = '0';
398     vector[1] = '\0';
399     *length = 1;
400     *point = 1;
401     return;
402   }
403 
404   bool fast_worked;
405   switch (mode) {
406     case SHORTEST:
407       fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST, 0, vector, length, point);
408       break;
409 #if 0 // not needed for ICU
410     case SHORTEST_SINGLE:
411       fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST_SINGLE, 0,
412                              vector, length, point);
413       break;
414     case FIXED:
415       fast_worked = FastFixedDtoa(v, requested_digits, vector, length, point);
416       break;
417     case PRECISION:
418       fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits,
419                              vector, length, point);
420       break;
421 #endif // not needed for ICU
422     default:
423       fast_worked = false;
424       UNREACHABLE();
425   }
426   if (fast_worked) return;
427 
428   // If the fast dtoa didn't succeed use the slower bignum version.
429   BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode);
430   BignumDtoa(v, bignum_mode, requested_digits, vector, length, point);
431   vector[*length] = '\0';
432 }
433 
434 
435 // Consumes the given substring from the iterator.
436 // Returns false, if the substring does not match.
437 template <class Iterator>
ConsumeSubString(Iterator * current,Iterator end,const char * substring)438 static bool ConsumeSubString(Iterator* current,
439                              Iterator end,
440                              const char* substring) {
441   ASSERT(**current == *substring);
442   for (substring++; *substring != '\0'; substring++) {
443     ++*current;
444     if (*current == end || **current != *substring) return false;
445   }
446   ++*current;
447   return true;
448 }
449 
450 
451 // Maximum number of significant digits in decimal representation.
452 // The longest possible double in decimal representation is
453 // (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074
454 // (768 digits). If we parse a number whose first digits are equal to a
455 // mean of 2 adjacent doubles (that could have up to 769 digits) the result
456 // must be rounded to the bigger one unless the tail consists of zeros, so
457 // we don't need to preserve all the digits.
458 const int kMaxSignificantDigits = 772;
459 
460 
461 static const char kWhitespaceTable7[] = { 32, 13, 10, 9, 11, 12 };
462 static const int kWhitespaceTable7Length = ARRAY_SIZE(kWhitespaceTable7);
463 
464 
465 static const uc16 kWhitespaceTable16[] = {
466   160, 8232, 8233, 5760, 6158, 8192, 8193, 8194, 8195,
467   8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 65279
468 };
469 static const int kWhitespaceTable16Length = ARRAY_SIZE(kWhitespaceTable16);
470 
471 
472 
isWhitespace(int x)473 static bool isWhitespace(int x) {
474   if (x < 128) {
475     for (int i = 0; i < kWhitespaceTable7Length; i++) {
476       if (kWhitespaceTable7[i] == x) return true;
477     }
478   } else {
479     for (int i = 0; i < kWhitespaceTable16Length; i++) {
480       if (kWhitespaceTable16[i] == x) return true;
481     }
482   }
483   return false;
484 }
485 
486 
487 // Returns true if a nonspace found and false if the end has reached.
488 template <class Iterator>
AdvanceToNonspace(Iterator * current,Iterator end)489 static inline bool AdvanceToNonspace(Iterator* current, Iterator end) {
490   while (*current != end) {
491     if (!isWhitespace(**current)) return true;
492     ++*current;
493   }
494   return false;
495 }
496 
497 
isDigit(int x,int radix)498 static bool isDigit(int x, int radix) {
499   return (x >= '0' && x <= '9' && x < '0' + radix)
500       || (radix > 10 && x >= 'a' && x < 'a' + radix - 10)
501       || (radix > 10 && x >= 'A' && x < 'A' + radix - 10);
502 }
503 
504 
SignedZero(bool sign)505 static double SignedZero(bool sign) {
506   return sign ? -0.0 : 0.0;
507 }
508 
509 
510 // Returns true if 'c' is a decimal digit that is valid for the given radix.
511 //
512 // The function is small and could be inlined, but VS2012 emitted a warning
513 // because it constant-propagated the radix and concluded that the last
514 // condition was always true. By moving it into a separate function the
515 // compiler wouldn't warn anymore.
516 #if _MSC_VER
517 #pragma optimize("",off)
IsDecimalDigitForRadix(int c,int radix)518 static bool IsDecimalDigitForRadix(int c, int radix) {
519   return '0' <= c && c <= '9' && (c - '0') < radix;
520 }
521 #pragma optimize("",on)
522 #else
IsDecimalDigitForRadix(int c,int radix)523 static bool inline IsDecimalDigitForRadix(int c, int radix) {
524 	return '0' <= c && c <= '9' && (c - '0') < radix;
525 }
526 #endif
527 // Returns true if 'c' is a character digit that is valid for the given radix.
528 // The 'a_character' should be 'a' or 'A'.
529 //
530 // The function is small and could be inlined, but VS2012 emitted a warning
531 // because it constant-propagated the radix and concluded that the first
532 // condition was always false. By moving it into a separate function the
533 // compiler wouldn't warn anymore.
IsCharacterDigitForRadix(int c,int radix,char a_character)534 static bool IsCharacterDigitForRadix(int c, int radix, char a_character) {
535   return radix > 10 && c >= a_character && c < a_character + radix - 10;
536 }
537 
538 
539 // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
540 template <int radix_log_2, class Iterator>
RadixStringToIeee(Iterator * current,Iterator end,bool sign,bool allow_trailing_junk,double junk_string_value,bool read_as_double,bool * result_is_junk)541 static double RadixStringToIeee(Iterator* current,
542                                 Iterator end,
543                                 bool sign,
544                                 bool allow_trailing_junk,
545                                 double junk_string_value,
546                                 bool read_as_double,
547                                 bool* result_is_junk) {
548   ASSERT(*current != end);
549 
550   const int kDoubleSize = Double::kSignificandSize;
551   const int kSingleSize = Single::kSignificandSize;
552   const int kSignificandSize = read_as_double? kDoubleSize: kSingleSize;
553 
554   *result_is_junk = true;
555 
556   // Skip leading 0s.
557   while (**current == '0') {
558     ++(*current);
559     if (*current == end) {
560       *result_is_junk = false;
561       return SignedZero(sign);
562     }
563   }
564 
565   int64_t number = 0;
566   int exponent = 0;
567   const int radix = (1 << radix_log_2);
568 
569   do {
570     int digit;
571     if (IsDecimalDigitForRadix(**current, radix)) {
572       digit = static_cast<char>(**current) - '0';
573     } else if (IsCharacterDigitForRadix(**current, radix, 'a')) {
574       digit = static_cast<char>(**current) - 'a' + 10;
575     } else if (IsCharacterDigitForRadix(**current, radix, 'A')) {
576       digit = static_cast<char>(**current) - 'A' + 10;
577     } else {
578       if (allow_trailing_junk || !AdvanceToNonspace(current, end)) {
579         break;
580       } else {
581         return junk_string_value;
582       }
583     }
584 
585     number = number * radix + digit;
586     int overflow = static_cast<int>(number >> kSignificandSize);
587     if (overflow != 0) {
588       // Overflow occurred. Need to determine which direction to round the
589       // result.
590       int overflow_bits_count = 1;
591       while (overflow > 1) {
592         overflow_bits_count++;
593         overflow >>= 1;
594       }
595 
596       int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
597       int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
598       number >>= overflow_bits_count;
599       exponent = overflow_bits_count;
600 
601       bool zero_tail = true;
602       for (;;) {
603         ++(*current);
604         if (*current == end || !isDigit(**current, radix)) break;
605         zero_tail = zero_tail && **current == '0';
606         exponent += radix_log_2;
607       }
608 
609       if (!allow_trailing_junk && AdvanceToNonspace(current, end)) {
610         return junk_string_value;
611       }
612 
613       int middle_value = (1 << (overflow_bits_count - 1));
614       if (dropped_bits > middle_value) {
615         number++;  // Rounding up.
616       } else if (dropped_bits == middle_value) {
617         // Rounding to even to consistency with decimals: half-way case rounds
618         // up if significant part is odd and down otherwise.
619         if ((number & 1) != 0 || !zero_tail) {
620           number++;  // Rounding up.
621         }
622       }
623 
624       // Rounding up may cause overflow.
625       if ((number & ((int64_t)1 << kSignificandSize)) != 0) {
626         exponent++;
627         number >>= 1;
628       }
629       break;
630     }
631     ++(*current);
632   } while (*current != end);
633 
634   ASSERT(number < ((int64_t)1 << kSignificandSize));
635   ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
636 
637   *result_is_junk = false;
638 
639   if (exponent == 0) {
640     if (sign) {
641       if (number == 0) return -0.0;
642       number = -number;
643     }
644     return static_cast<double>(number);
645   }
646 
647   ASSERT(number != 0);
648   return Double(DiyFp(number, exponent)).value();
649 }
650 
651 template <class Iterator>
StringToIeee(Iterator input,int length,bool read_as_double,int * processed_characters_count) const652 double StringToDoubleConverter::StringToIeee(
653     Iterator input,
654     int length,
655     bool read_as_double,
656     int* processed_characters_count) const {
657   Iterator current = input;
658   Iterator end = input + length;
659 
660   *processed_characters_count = 0;
661 
662   const bool allow_trailing_junk = (flags_ & ALLOW_TRAILING_JUNK) != 0;
663   const bool allow_leading_spaces = (flags_ & ALLOW_LEADING_SPACES) != 0;
664   const bool allow_trailing_spaces = (flags_ & ALLOW_TRAILING_SPACES) != 0;
665   const bool allow_spaces_after_sign = (flags_ & ALLOW_SPACES_AFTER_SIGN) != 0;
666 
667   // To make sure that iterator dereferencing is valid the following
668   // convention is used:
669   // 1. Each '++current' statement is followed by check for equality to 'end'.
670   // 2. If AdvanceToNonspace returned false then current == end.
671   // 3. If 'current' becomes equal to 'end' the function returns or goes to
672   // 'parsing_done'.
673   // 4. 'current' is not dereferenced after the 'parsing_done' label.
674   // 5. Code before 'parsing_done' may rely on 'current != end'.
675   if (current == end) return empty_string_value_;
676 
677   if (allow_leading_spaces || allow_trailing_spaces) {
678     if (!AdvanceToNonspace(&current, end)) {
679       *processed_characters_count = static_cast<int>(current - input);
680       return empty_string_value_;
681     }
682     if (!allow_leading_spaces && (input != current)) {
683       // No leading spaces allowed, but AdvanceToNonspace moved forward.
684       return junk_string_value_;
685     }
686   }
687 
688   // The longest form of simplified number is: "-<significant digits>.1eXXX\0".
689   const int kBufferSize = kMaxSignificantDigits + 10;
690   char buffer[kBufferSize];  // NOLINT: size is known at compile time.
691   int buffer_pos = 0;
692 
693   // Exponent will be adjusted if insignificant digits of the integer part
694   // or insignificant leading zeros of the fractional part are dropped.
695   int exponent = 0;
696   int significant_digits = 0;
697   int insignificant_digits = 0;
698   bool nonzero_digit_dropped = false;
699 
700   bool sign = false;
701 
702   if (*current == '+' || *current == '-') {
703     sign = (*current == '-');
704     ++current;
705     Iterator next_non_space = current;
706     // Skip following spaces (if allowed).
707     if (!AdvanceToNonspace(&next_non_space, end)) return junk_string_value_;
708     if (!allow_spaces_after_sign && (current != next_non_space)) {
709       return junk_string_value_;
710     }
711     current = next_non_space;
712   }
713 
714   if (infinity_symbol_ != NULL) {
715     if (*current == infinity_symbol_[0]) {
716       if (!ConsumeSubString(&current, end, infinity_symbol_)) {
717         return junk_string_value_;
718       }
719 
720       if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
721         return junk_string_value_;
722       }
723       if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
724         return junk_string_value_;
725       }
726 
727       ASSERT(buffer_pos == 0);
728       *processed_characters_count = static_cast<int>(current - input);
729       return sign ? -Double::Infinity() : Double::Infinity();
730     }
731   }
732 
733   if (nan_symbol_ != NULL) {
734     if (*current == nan_symbol_[0]) {
735       if (!ConsumeSubString(&current, end, nan_symbol_)) {
736         return junk_string_value_;
737       }
738 
739       if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
740         return junk_string_value_;
741       }
742       if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
743         return junk_string_value_;
744       }
745 
746       ASSERT(buffer_pos == 0);
747       *processed_characters_count = static_cast<int>(current - input);
748       return sign ? -Double::NaN() : Double::NaN();
749     }
750   }
751 
752   bool leading_zero = false;
753   if (*current == '0') {
754     ++current;
755     if (current == end) {
756       *processed_characters_count = static_cast<int>(current - input);
757       return SignedZero(sign);
758     }
759 
760     leading_zero = true;
761 
762     // It could be hexadecimal value.
763     if ((flags_ & ALLOW_HEX) && (*current == 'x' || *current == 'X')) {
764       ++current;
765       if (current == end || !isDigit(*current, 16)) {
766         return junk_string_value_;  // "0x".
767       }
768 
769       bool result_is_junk;
770       double result = RadixStringToIeee<4>(&current,
771                                            end,
772                                            sign,
773                                            allow_trailing_junk,
774                                            junk_string_value_,
775                                            read_as_double,
776                                            &result_is_junk);
777       if (!result_is_junk) {
778         if (allow_trailing_spaces) AdvanceToNonspace(&current, end);
779         *processed_characters_count = static_cast<int>(current - input);
780       }
781       return result;
782     }
783 
784     // Ignore leading zeros in the integer part.
785     while (*current == '0') {
786       ++current;
787       if (current == end) {
788         *processed_characters_count = static_cast<int>(current - input);
789         return SignedZero(sign);
790       }
791     }
792   }
793 
794   bool octal = leading_zero && (flags_ & ALLOW_OCTALS) != 0;
795 
796   // Copy significant digits of the integer part (if any) to the buffer.
797   while (*current >= '0' && *current <= '9') {
798     if (significant_digits < kMaxSignificantDigits) {
799       ASSERT(buffer_pos < kBufferSize);
800       buffer[buffer_pos++] = static_cast<char>(*current);
801       significant_digits++;
802       // Will later check if it's an octal in the buffer.
803     } else {
804       insignificant_digits++;  // Move the digit into the exponential part.
805       nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
806     }
807     octal = octal && *current < '8';
808     ++current;
809     if (current == end) goto parsing_done;
810   }
811 
812   if (significant_digits == 0) {
813     octal = false;
814   }
815 
816   if (*current == '.') {
817     if (octal && !allow_trailing_junk) return junk_string_value_;
818     if (octal) goto parsing_done;
819 
820     ++current;
821     if (current == end) {
822       if (significant_digits == 0 && !leading_zero) {
823         return junk_string_value_;
824       } else {
825         goto parsing_done;
826       }
827     }
828 
829     if (significant_digits == 0) {
830       // octal = false;
831       // Integer part consists of 0 or is absent. Significant digits start after
832       // leading zeros (if any).
833       while (*current == '0') {
834         ++current;
835         if (current == end) {
836           *processed_characters_count = static_cast<int>(current - input);
837           return SignedZero(sign);
838         }
839         exponent--;  // Move this 0 into the exponent.
840       }
841     }
842 
843     // There is a fractional part.
844     // We don't emit a '.', but adjust the exponent instead.
845     while (*current >= '0' && *current <= '9') {
846       if (significant_digits < kMaxSignificantDigits) {
847         ASSERT(buffer_pos < kBufferSize);
848         buffer[buffer_pos++] = static_cast<char>(*current);
849         significant_digits++;
850         exponent--;
851       } else {
852         // Ignore insignificant digits in the fractional part.
853         nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
854       }
855       ++current;
856       if (current == end) goto parsing_done;
857     }
858   }
859 
860   if (!leading_zero && exponent == 0 && significant_digits == 0) {
861     // If leading_zeros is true then the string contains zeros.
862     // If exponent < 0 then string was [+-]\.0*...
863     // If significant_digits != 0 the string is not equal to 0.
864     // Otherwise there are no digits in the string.
865     return junk_string_value_;
866   }
867 
868   // Parse exponential part.
869   if (*current == 'e' || *current == 'E') {
870     if (octal && !allow_trailing_junk) return junk_string_value_;
871     if (octal) goto parsing_done;
872     ++current;
873     if (current == end) {
874       if (allow_trailing_junk) {
875         goto parsing_done;
876       } else {
877         return junk_string_value_;
878       }
879     }
880     char exponen_sign = '+';
881     if (*current == '+' || *current == '-') {
882       exponen_sign = static_cast<char>(*current);
883       ++current;
884       if (current == end) {
885         if (allow_trailing_junk) {
886           goto parsing_done;
887         } else {
888           return junk_string_value_;
889         }
890       }
891     }
892 
893     if (current == end || *current < '0' || *current > '9') {
894       if (allow_trailing_junk) {
895         goto parsing_done;
896       } else {
897         return junk_string_value_;
898       }
899     }
900 
901     const int max_exponent = INT_MAX / 2;
902     ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
903     int num = 0;
904     do {
905       // Check overflow.
906       int digit = *current - '0';
907       if (num >= max_exponent / 10
908           && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
909         num = max_exponent;
910       } else {
911         num = num * 10 + digit;
912       }
913       ++current;
914     } while (current != end && *current >= '0' && *current <= '9');
915 
916     exponent += (exponen_sign == '-' ? -num : num);
917   }
918 
919   if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
920     return junk_string_value_;
921   }
922   if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
923     return junk_string_value_;
924   }
925   if (allow_trailing_spaces) {
926     AdvanceToNonspace(&current, end);
927   }
928 
929   parsing_done:
930   exponent += insignificant_digits;
931 
932   if (octal) {
933     double result;
934     bool result_is_junk;
935     char* start = buffer;
936     result = RadixStringToIeee<3>(&start,
937                                   buffer + buffer_pos,
938                                   sign,
939                                   allow_trailing_junk,
940                                   junk_string_value_,
941                                   read_as_double,
942                                   &result_is_junk);
943     ASSERT(!result_is_junk);
944     *processed_characters_count = static_cast<int>(current - input);
945     return result;
946   }
947 
948   if (nonzero_digit_dropped) {
949     buffer[buffer_pos++] = '1';
950     exponent--;
951   }
952 
953   ASSERT(buffer_pos < kBufferSize);
954   buffer[buffer_pos] = '\0';
955 
956   double converted;
957   if (read_as_double) {
958     converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
959   } else {
960     converted = Strtof(Vector<const char>(buffer, buffer_pos), exponent);
961   }
962   *processed_characters_count = static_cast<int>(current - input);
963   return sign? -converted: converted;
964 }
965 
966 
StringToDouble(const char * buffer,int length,int * processed_characters_count) const967 double StringToDoubleConverter::StringToDouble(
968     const char* buffer,
969     int length,
970     int* processed_characters_count) const {
971   return StringToIeee(buffer, length, true, processed_characters_count);
972 }
973 
974 
StringToDouble(const uc16 * buffer,int length,int * processed_characters_count) const975 double StringToDoubleConverter::StringToDouble(
976     const uc16* buffer,
977     int length,
978     int* processed_characters_count) const {
979   return StringToIeee(buffer, length, true, processed_characters_count);
980 }
981 
982 
StringToFloat(const char * buffer,int length,int * processed_characters_count) const983 float StringToDoubleConverter::StringToFloat(
984     const char* buffer,
985     int length,
986     int* processed_characters_count) const {
987   return static_cast<float>(StringToIeee(buffer, length, false,
988                                          processed_characters_count));
989 }
990 
991 
StringToFloat(const uc16 * buffer,int length,int * processed_characters_count) const992 float StringToDoubleConverter::StringToFloat(
993     const uc16* buffer,
994     int length,
995     int* processed_characters_count) const {
996   return static_cast<float>(StringToIeee(buffer, length, false,
997                                          processed_characters_count));
998 }
999 
1000 }  // namespace double_conversion
1001 
1002 // ICU PATCH: Close ICU namespace
1003 U_NAMESPACE_END
1004 #endif // ICU PATCH: close #if !UCONFIG_NO_FORMATTING
1005