1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #include <climits>
29 #include <locale>
30 #include <cmath>
31 
32 #include <double-conversion/double-conversion.h>
33 
34 #include <double-conversion/bignum-dtoa.h>
35 #include <double-conversion/fast-dtoa.h>
36 #include <double-conversion/fixed-dtoa.h>
37 #include <double-conversion/ieee.h>
38 #include <double-conversion/strtod.h>
39 #include <double-conversion/utils.h>
40 
41 // Fix warning C4244: 'argument': conversion from 'const uc16' to 'char', possible loss of data
42 #ifdef _MSC_VER
43  __pragma(warning(disable: 4244))
44 #endif
45 
46 namespace double_conversion {
47 
EcmaScriptConverter()48 const DoubleToStringConverter& DoubleToStringConverter::EcmaScriptConverter() {
49   int flags = UNIQUE_ZERO | EMIT_POSITIVE_EXPONENT_SIGN;
50   static DoubleToStringConverter converter(flags,
51                                            "Infinity",
52                                            "NaN",
53                                            'e',
54                                            -6, 21,
55                                            6, 0);
56   return converter;
57 }
58 
59 
HandleSpecialValues(double value,StringBuilder * result_builder) const60 bool DoubleToStringConverter::HandleSpecialValues(
61     double value,
62     StringBuilder* result_builder) const {
63   Double double_inspect(value);
64   if (double_inspect.IsInfinite()) {
65     if (infinity_symbol_ == NULL) return false;
66     if (value < 0) {
67       result_builder->AddCharacter('-');
68     }
69     result_builder->AddString(infinity_symbol_);
70     return true;
71   }
72   if (double_inspect.IsNan()) {
73     if (nan_symbol_ == NULL) return false;
74     result_builder->AddString(nan_symbol_);
75     return true;
76   }
77   return false;
78 }
79 
80 
CreateExponentialRepresentation(const char * decimal_digits,int length,int exponent,StringBuilder * result_builder) const81 void DoubleToStringConverter::CreateExponentialRepresentation(
82     const char* decimal_digits,
83     int length,
84     int exponent,
85     StringBuilder* result_builder) const {
86   ASSERT(length != 0);
87   result_builder->AddCharacter(decimal_digits[0]);
88   if (length != 1) {
89     result_builder->AddCharacter('.');
90     result_builder->AddSubstring(&decimal_digits[1], length-1);
91   }
92   result_builder->AddCharacter(exponent_character_);
93   if (exponent < 0) {
94     result_builder->AddCharacter('-');
95     exponent = -exponent;
96   } else {
97     if ((flags_ & EMIT_POSITIVE_EXPONENT_SIGN) != 0) {
98       result_builder->AddCharacter('+');
99     }
100   }
101   if (exponent == 0) {
102     result_builder->AddCharacter('0');
103     return;
104   }
105   ASSERT(exponent < 1e4);
106   const int kMaxExponentLength = 5;
107   char buffer[kMaxExponentLength + 1];
108   buffer[kMaxExponentLength] = '\0';
109   int first_char_pos = kMaxExponentLength;
110   while (exponent > 0) {
111     buffer[--first_char_pos] = '0' + (exponent % 10);
112     exponent /= 10;
113   }
114   result_builder->AddSubstring(&buffer[first_char_pos],
115                                kMaxExponentLength - first_char_pos);
116 }
117 
118 
CreateDecimalRepresentation(const char * decimal_digits,int length,int decimal_point,int digits_after_point,StringBuilder * result_builder) const119 void DoubleToStringConverter::CreateDecimalRepresentation(
120     const char* decimal_digits,
121     int length,
122     int decimal_point,
123     int digits_after_point,
124     StringBuilder* result_builder) const {
125   // Create a representation that is padded with zeros if needed.
126   if (decimal_point <= 0) {
127       // "0.00000decimal_rep" or "0.000decimal_rep00".
128     result_builder->AddCharacter('0');
129     if (digits_after_point > 0) {
130       result_builder->AddCharacter('.');
131       result_builder->AddPadding('0', -decimal_point);
132       ASSERT(length <= digits_after_point - (-decimal_point));
133       result_builder->AddSubstring(decimal_digits, length);
134       int remaining_digits = digits_after_point - (-decimal_point) - length;
135       result_builder->AddPadding('0', remaining_digits);
136     }
137   } else if (decimal_point >= length) {
138     // "decimal_rep0000.00000" or "decimal_rep.0000".
139     result_builder->AddSubstring(decimal_digits, length);
140     result_builder->AddPadding('0', decimal_point - length);
141     if (digits_after_point > 0) {
142       result_builder->AddCharacter('.');
143       result_builder->AddPadding('0', digits_after_point);
144     }
145   } else {
146     // "decima.l_rep000".
147     ASSERT(digits_after_point > 0);
148     result_builder->AddSubstring(decimal_digits, decimal_point);
149     result_builder->AddCharacter('.');
150     ASSERT(length - decimal_point <= digits_after_point);
151     result_builder->AddSubstring(&decimal_digits[decimal_point],
152                                  length - decimal_point);
153     int remaining_digits = digits_after_point - (length - decimal_point);
154     result_builder->AddPadding('0', remaining_digits);
155   }
156   if (digits_after_point == 0) {
157     if ((flags_ & EMIT_TRAILING_DECIMAL_POINT) != 0) {
158       result_builder->AddCharacter('.');
159     }
160     if ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) {
161       result_builder->AddCharacter('0');
162     }
163   }
164 }
165 
166 
ToShortestIeeeNumber(double value,StringBuilder * result_builder,DoubleToStringConverter::DtoaMode mode) const167 bool DoubleToStringConverter::ToShortestIeeeNumber(
168     double value,
169     StringBuilder* result_builder,
170     DoubleToStringConverter::DtoaMode mode) const {
171   ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE);
172   if (Double(value).IsSpecial()) {
173     return HandleSpecialValues(value, result_builder);
174   }
175 
176   int decimal_point;
177   bool sign;
178   const int kDecimalRepCapacity = kBase10MaximalLength + 1;
179   char decimal_rep[kDecimalRepCapacity];
180   int decimal_rep_length;
181 
182   DoubleToAscii(value, mode, 0, decimal_rep, kDecimalRepCapacity,
183                 &sign, &decimal_rep_length, &decimal_point);
184 
185   bool unique_zero = (flags_ & UNIQUE_ZERO) != 0;
186   if (sign && (value != 0.0 || !unique_zero)) {
187     result_builder->AddCharacter('-');
188   }
189 
190   int exponent = decimal_point - 1;
191   if ((decimal_in_shortest_low_ <= exponent) &&
192       (exponent < decimal_in_shortest_high_)) {
193     CreateDecimalRepresentation(decimal_rep, decimal_rep_length,
194                                 decimal_point,
195                                 Max(0, decimal_rep_length - decimal_point),
196                                 result_builder);
197   } else {
198     CreateExponentialRepresentation(decimal_rep, decimal_rep_length, exponent,
199                                     result_builder);
200   }
201   return true;
202 }
203 
204 
ToFixed(double value,int requested_digits,StringBuilder * result_builder) const205 bool DoubleToStringConverter::ToFixed(double value,
206                                       int requested_digits,
207                                       StringBuilder* result_builder) const {
208   ASSERT(kMaxFixedDigitsBeforePoint == 60);
209   const double kFirstNonFixed = 1e60;
210 
211   if (Double(value).IsSpecial()) {
212     return HandleSpecialValues(value, result_builder);
213   }
214 
215   if (requested_digits > kMaxFixedDigitsAfterPoint) return false;
216   if (value >= kFirstNonFixed || value <= -kFirstNonFixed) return false;
217 
218   // Find a sufficiently precise decimal representation of n.
219   int decimal_point;
220   bool sign;
221   // Add space for the '\0' byte.
222   const int kDecimalRepCapacity =
223       kMaxFixedDigitsBeforePoint + kMaxFixedDigitsAfterPoint + 1;
224   char decimal_rep[kDecimalRepCapacity];
225   int decimal_rep_length;
226   DoubleToAscii(value, FIXED, requested_digits,
227                 decimal_rep, kDecimalRepCapacity,
228                 &sign, &decimal_rep_length, &decimal_point);
229 
230   bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
231   if (sign && (value != 0.0 || !unique_zero)) {
232     result_builder->AddCharacter('-');
233   }
234 
235   CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
236                               requested_digits, result_builder);
237   return true;
238 }
239 
240 
ToExponential(double value,int requested_digits,StringBuilder * result_builder) const241 bool DoubleToStringConverter::ToExponential(
242     double value,
243     int requested_digits,
244     StringBuilder* result_builder) const {
245   if (Double(value).IsSpecial()) {
246     return HandleSpecialValues(value, result_builder);
247   }
248 
249   if (requested_digits < -1) return false;
250   if (requested_digits > kMaxExponentialDigits) return false;
251 
252   int decimal_point;
253   bool sign;
254   // Add space for digit before the decimal point and the '\0' character.
255   const int kDecimalRepCapacity = kMaxExponentialDigits + 2;
256   ASSERT(kDecimalRepCapacity > kBase10MaximalLength);
257   char decimal_rep[kDecimalRepCapacity];
258 #ifndef NDEBUG
259   // Problem: there is an assert in StringBuilder::AddSubstring() that
260   // will pass this buffer to strlen(), and this buffer is not generally
261   // null-terminated.
262   memset(decimal_rep, 0, sizeof(decimal_rep));
263 #endif
264   int decimal_rep_length;
265 
266   if (requested_digits == -1) {
267     DoubleToAscii(value, SHORTEST, 0,
268                   decimal_rep, kDecimalRepCapacity,
269                   &sign, &decimal_rep_length, &decimal_point);
270   } else {
271     DoubleToAscii(value, PRECISION, requested_digits + 1,
272                   decimal_rep, kDecimalRepCapacity,
273                   &sign, &decimal_rep_length, &decimal_point);
274     ASSERT(decimal_rep_length <= requested_digits + 1);
275 
276     for (int i = decimal_rep_length; i < requested_digits + 1; ++i) {
277       decimal_rep[i] = '0';
278     }
279     decimal_rep_length = requested_digits + 1;
280   }
281 
282   bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
283   if (sign && (value != 0.0 || !unique_zero)) {
284     result_builder->AddCharacter('-');
285   }
286 
287   int exponent = decimal_point - 1;
288   CreateExponentialRepresentation(decimal_rep,
289                                   decimal_rep_length,
290                                   exponent,
291                                   result_builder);
292   return true;
293 }
294 
295 
ToPrecision(double value,int precision,StringBuilder * result_builder) const296 bool DoubleToStringConverter::ToPrecision(double value,
297                                           int precision,
298                                           StringBuilder* result_builder) const {
299   if (Double(value).IsSpecial()) {
300     return HandleSpecialValues(value, result_builder);
301   }
302 
303   if (precision < kMinPrecisionDigits || precision > kMaxPrecisionDigits) {
304     return false;
305   }
306 
307   // Find a sufficiently precise decimal representation of n.
308   int decimal_point;
309   bool sign;
310   // Add one for the terminating null character.
311   const int kDecimalRepCapacity = kMaxPrecisionDigits + 1;
312   char decimal_rep[kDecimalRepCapacity];
313   int decimal_rep_length;
314 
315   DoubleToAscii(value, PRECISION, precision,
316                 decimal_rep, kDecimalRepCapacity,
317                 &sign, &decimal_rep_length, &decimal_point);
318   ASSERT(decimal_rep_length <= precision);
319 
320   bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
321   if (sign && (value != 0.0 || !unique_zero)) {
322     result_builder->AddCharacter('-');
323   }
324 
325   // The exponent if we print the number as x.xxeyyy. That is with the
326   // decimal point after the first digit.
327   int exponent = decimal_point - 1;
328 
329   int extra_zero = ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) ? 1 : 0;
330   if ((-decimal_point + 1 > max_leading_padding_zeroes_in_precision_mode_) ||
331       (decimal_point - precision + extra_zero >
332        max_trailing_padding_zeroes_in_precision_mode_)) {
333     // Fill buffer to contain 'precision' digits.
334     // Usually the buffer is already at the correct length, but 'DoubleToAscii'
335     // is allowed to return less characters.
336     for (int i = decimal_rep_length; i < precision; ++i) {
337       decimal_rep[i] = '0';
338     }
339 
340     CreateExponentialRepresentation(decimal_rep,
341                                     precision,
342                                     exponent,
343                                     result_builder);
344   } else {
345     CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
346                                 Max(0, precision - decimal_point),
347                                 result_builder);
348   }
349   return true;
350 }
351 
352 
DtoaToBignumDtoaMode(DoubleToStringConverter::DtoaMode dtoa_mode)353 static BignumDtoaMode DtoaToBignumDtoaMode(
354     DoubleToStringConverter::DtoaMode dtoa_mode) {
355   switch (dtoa_mode) {
356     case DoubleToStringConverter::SHORTEST:  return BIGNUM_DTOA_SHORTEST;
357     case DoubleToStringConverter::SHORTEST_SINGLE:
358         return BIGNUM_DTOA_SHORTEST_SINGLE;
359     case DoubleToStringConverter::FIXED:     return BIGNUM_DTOA_FIXED;
360     case DoubleToStringConverter::PRECISION: return BIGNUM_DTOA_PRECISION;
361     default:
362       UNREACHABLE();
363   }
364 }
365 
366 
DoubleToAscii(double v,DtoaMode mode,int requested_digits,char * buffer,int buffer_length,bool * sign,int * length,int * point)367 void DoubleToStringConverter::DoubleToAscii(double v,
368                                             DtoaMode mode,
369                                             int requested_digits,
370                                             char* buffer,
371                                             int buffer_length,
372                                             bool* sign,
373                                             int* length,
374                                             int* point) {
375   Vector<char> vector(buffer, buffer_length);
376   ASSERT(!Double(v).IsSpecial());
377   ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE || requested_digits >= 0);
378 
379   if (Double(v).Sign() < 0) {
380     *sign = true;
381     v = -v;
382   } else {
383     *sign = false;
384   }
385 
386   if (mode == PRECISION && requested_digits == 0) {
387     vector[0] = '\0';
388     *length = 0;
389     return;
390   }
391 
392   if (v == 0) {
393     vector[0] = '0';
394     vector[1] = '\0';
395     *length = 1;
396     *point = 1;
397     return;
398   }
399 
400   bool fast_worked;
401   switch (mode) {
402     case SHORTEST:
403       fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST, 0, vector, length, point);
404       break;
405     case SHORTEST_SINGLE:
406       fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST_SINGLE, 0,
407                              vector, length, point);
408       break;
409     case FIXED:
410       fast_worked = FastFixedDtoa(v, requested_digits, vector, length, point);
411       break;
412     case PRECISION:
413       fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits,
414                              vector, length, point);
415       break;
416     default:
417       fast_worked = false;
418       UNREACHABLE();
419   }
420   if (fast_worked) return;
421 
422   // If the fast dtoa didn't succeed use the slower bignum version.
423   BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode);
424   BignumDtoa(v, bignum_mode, requested_digits, vector, length, point);
425   vector[*length] = '\0';
426 }
427 
428 
429 namespace {
430 
ToLower(char ch)431 inline char ToLower(char ch) {
432   static const std::ctype<char>& cType =
433       std::use_facet<std::ctype<char> >(std::locale::classic());
434   return cType.tolower(ch);
435 }
436 
Pass(char ch)437 inline char Pass(char ch) {
438   return ch;
439 }
440 
441 template <class Iterator, class Converter>
ConsumeSubStringImpl(Iterator * current,Iterator end,const char * substring,Converter converter)442 static inline bool ConsumeSubStringImpl(Iterator* current,
443                                         Iterator end,
444                                         const char* substring,
445                                         Converter converter) {
446   ASSERT(converter(**current) == *substring);
447   for (substring++; *substring != '\0'; substring++) {
448     ++*current;
449     if (*current == end || converter(**current) != *substring) {
450       return false;
451     }
452   }
453   ++*current;
454   return true;
455 }
456 
457 // Consumes the given substring from the iterator.
458 // Returns false, if the substring does not match.
459 template <class Iterator>
ConsumeSubString(Iterator * current,Iterator end,const char * substring,bool allow_case_insensibility)460 static bool ConsumeSubString(Iterator* current,
461                              Iterator end,
462                              const char* substring,
463                              bool allow_case_insensibility) {
464   if (allow_case_insensibility) {
465     return ConsumeSubStringImpl(current, end, substring, ToLower);
466   } else {
467     return ConsumeSubStringImpl(current, end, substring, Pass);
468   }
469 }
470 
471 // Consumes first character of the str is equal to ch
ConsumeFirstCharacter(char ch,const char * str,bool case_insensibility)472 inline bool ConsumeFirstCharacter(char ch,
473                                          const char* str,
474                                          bool case_insensibility) {
475   return case_insensibility ? ToLower(ch) == str[0] : ch == str[0];
476 }
477 }  // namespace
478 
479 // Maximum number of significant digits in decimal representation.
480 // The longest possible double in decimal representation is
481 // (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074
482 // (768 digits). If we parse a number whose first digits are equal to a
483 // mean of 2 adjacent doubles (that could have up to 769 digits) the result
484 // must be rounded to the bigger one unless the tail consists of zeros, so
485 // we don't need to preserve all the digits.
486 const int kMaxSignificantDigits = 772;
487 
488 
489 static const char kWhitespaceTable7[] = { 32, 13, 10, 9, 11, 12 };
490 static const int kWhitespaceTable7Length = ARRAY_SIZE(kWhitespaceTable7);
491 
492 
493 static const uc16 kWhitespaceTable16[] = {
494   160, 8232, 8233, 5760, 6158, 8192, 8193, 8194, 8195,
495   8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 65279
496 };
497 static const int kWhitespaceTable16Length = ARRAY_SIZE(kWhitespaceTable16);
498 
499 
isWhitespace(int x)500 static bool isWhitespace(int x) {
501   if (x < 128) {
502     for (int i = 0; i < kWhitespaceTable7Length; i++) {
503       if (kWhitespaceTable7[i] == x) return true;
504     }
505   } else {
506     for (int i = 0; i < kWhitespaceTable16Length; i++) {
507       if (kWhitespaceTable16[i] == x) return true;
508     }
509   }
510   return false;
511 }
512 
513 
514 // Returns true if a nonspace found and false if the end has reached.
515 template <class Iterator>
AdvanceToNonspace(Iterator * current,Iterator end)516 static inline bool AdvanceToNonspace(Iterator* current, Iterator end) {
517   while (*current != end) {
518     if (!isWhitespace(**current)) return true;
519     ++*current;
520   }
521   return false;
522 }
523 
524 
isDigit(int x,int radix)525 static bool isDigit(int x, int radix) {
526   return (x >= '0' && x <= '9' && x < '0' + radix)
527       || (radix > 10 && x >= 'a' && x < 'a' + radix - 10)
528       || (radix > 10 && x >= 'A' && x < 'A' + radix - 10);
529 }
530 
531 
SignedZero(bool sign)532 static double SignedZero(bool sign) {
533   return sign ? -0.0 : 0.0;
534 }
535 
536 
537 // Returns true if 'c' is a decimal digit that is valid for the given radix.
IsDecimalDigitForRadix(int c,int radix)538 static bool inline IsDecimalDigitForRadix(int c, int radix) {
539   return '0' <= c && c <= '9' && (c - '0') < radix;
540 }
541 
542 // Returns true if 'c' is a character digit that is valid for the given radix.
543 // The 'a_character' should be 'a' or 'A'.
544 //
545 // The function is small and could be inlined, but VS2012 emitted a warning
546 // because it constant-propagated the radix and concluded that the first
547 // condition was always false. By moving it into a separate function the
548 // compiler wouldn't warn anymore.
IsCharacterDigitForRadix(int c,int radix,char a_character)549 static bool IsCharacterDigitForRadix(int c, int radix, char a_character) {
550   return radix > 10 && c >= a_character && c < a_character + radix - 10;
551 }
552 
553 // Returns true, when the iterator is equal to end.
554 template<class Iterator>
Advance(Iterator * it,uc16 separator,int base,Iterator & end)555 static bool Advance (Iterator* it, uc16 separator, int base, Iterator& end) {
556   if (separator == StringToDoubleConverter::kNoSeparator) {
557     ++(*it);
558     return *it == end;
559   }
560   if (!isDigit(**it, base)) {
561     ++(*it);
562     return *it == end;
563   }
564   ++(*it);
565   if (*it == end) return true;
566   if (*it + 1 == end) return false;
567   if (**it == separator && isDigit(*(*it + 1), base)) {
568     ++(*it);
569   }
570   return *it == end;
571 }
572 
573 // Checks whether the string in the range start-end is a hex-float string.
574 // This function assumes that the leading '0x'/'0X' is already consumed.
575 //
576 // Hex float strings are of one of the following forms:
577 //   - hex_digits+ 'p' ('+'|'-')? exponent_digits+
578 //   - hex_digits* '.' hex_digits+ 'p' ('+'|'-')? exponent_digits+
579 //   - hex_digits+ '.' 'p' ('+'|'-')? exponent_digits+
580 template<class Iterator>
IsHexFloatString(Iterator start,Iterator end,uc16 separator,bool allow_trailing_junk)581 static bool IsHexFloatString(Iterator start,
582                              Iterator end,
583                              uc16 separator,
584                              bool allow_trailing_junk) {
585   ASSERT(start != end);
586 
587   Iterator current = start;
588 
589   bool saw_digit = false;
590   while (isDigit(*current, 16)) {
591     saw_digit = true;
592     if (Advance(&current, separator, 16, end)) return false;
593   }
594   if (*current == '.') {
595     if (Advance(&current, separator, 16, end)) return false;
596     while (isDigit(*current, 16)) {
597       saw_digit = true;
598       if (Advance(&current, separator, 16, end)) return false;
599     }
600   }
601   if (!saw_digit) return false;
602   if (*current != 'p' && *current != 'P') return false;
603   if (Advance(&current, separator, 16, end)) return false;
604   if (*current == '+' || *current == '-') {
605     if (Advance(&current, separator, 16, end)) return false;
606   }
607   if (!isDigit(*current, 10)) return false;
608   if (Advance(&current, separator, 16, end)) return true;
609   while (isDigit(*current, 10)) {
610     if (Advance(&current, separator, 16, end)) return true;
611   }
612   return allow_trailing_junk || !AdvanceToNonspace(&current, end);
613 }
614 
615 
616 // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
617 //
618 // If parse_as_hex_float is true, then the string must be a valid
619 // hex-float.
620 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)621 static double RadixStringToIeee(Iterator* current,
622                                 Iterator end,
623                                 bool sign,
624                                 uc16 separator,
625                                 bool parse_as_hex_float,
626                                 bool allow_trailing_junk,
627                                 double junk_string_value,
628                                 bool read_as_double,
629                                 bool* result_is_junk) {
630   ASSERT(*current != end);
631   ASSERT(!parse_as_hex_float ||
632       IsHexFloatString(*current, end, separator, allow_trailing_junk));
633 
634   const int kDoubleSize = Double::kSignificandSize;
635   const int kSingleSize = Single::kSignificandSize;
636   const int kSignificandSize = read_as_double? kDoubleSize: kSingleSize;
637 
638   *result_is_junk = true;
639 
640   int64_t number = 0;
641   int exponent = 0;
642   const int radix = (1 << radix_log_2);
643   // Whether we have encountered a '.' and are parsing the decimal digits.
644   // Only relevant if parse_as_hex_float is true.
645   bool post_decimal = false;
646 
647   // Skip leading 0s.
648   while (**current == '0') {
649     if (Advance(current, separator, radix, end)) {
650       *result_is_junk = false;
651       return SignedZero(sign);
652     }
653   }
654 
655   while (true) {
656     int digit;
657     if (IsDecimalDigitForRadix(**current, radix)) {
658       digit = static_cast<char>(**current) - '0';
659       if (post_decimal) exponent -= radix_log_2;
660     } else if (IsCharacterDigitForRadix(**current, radix, 'a')) {
661       digit = static_cast<char>(**current) - 'a' + 10;
662       if (post_decimal) exponent -= radix_log_2;
663     } else if (IsCharacterDigitForRadix(**current, radix, 'A')) {
664       digit = static_cast<char>(**current) - 'A' + 10;
665       if (post_decimal) exponent -= radix_log_2;
666     } else if (parse_as_hex_float && **current == '.') {
667       post_decimal = true;
668       Advance(current, separator, radix, end);
669       ASSERT(*current != end);
670       continue;
671     } else if (parse_as_hex_float && (**current == 'p' || **current == 'P')) {
672       break;
673     } else {
674       if (allow_trailing_junk || !AdvanceToNonspace(current, end)) {
675         break;
676       } else {
677         return junk_string_value;
678       }
679     }
680 
681     number = number * radix + digit;
682     int overflow = static_cast<int>(number >> kSignificandSize);
683     if (overflow != 0) {
684       // Overflow occurred. Need to determine which direction to round the
685       // result.
686       int overflow_bits_count = 1;
687       while (overflow > 1) {
688         overflow_bits_count++;
689         overflow >>= 1;
690       }
691 
692       int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
693       int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
694       number >>= overflow_bits_count;
695       exponent += overflow_bits_count;
696 
697       bool zero_tail = true;
698       for (;;) {
699         if (Advance(current, separator, radix, end)) break;
700         if (parse_as_hex_float && **current == '.') {
701           // Just run over the '.'. We are just trying to see whether there is
702           // a non-zero digit somewhere.
703           Advance(current, separator, radix, end);
704           ASSERT(*current != end);
705           post_decimal = true;
706         }
707         if (!isDigit(**current, radix)) break;
708         zero_tail = zero_tail && **current == '0';
709         if (!post_decimal) exponent += radix_log_2;
710       }
711 
712       if (!parse_as_hex_float &&
713           !allow_trailing_junk &&
714           AdvanceToNonspace(current, end)) {
715         return junk_string_value;
716       }
717 
718       int middle_value = (1 << (overflow_bits_count - 1));
719       if (dropped_bits > middle_value) {
720         number++;  // Rounding up.
721       } else if (dropped_bits == middle_value) {
722         // Rounding to even to consistency with decimals: half-way case rounds
723         // up if significant part is odd and down otherwise.
724         if ((number & 1) != 0 || !zero_tail) {
725           number++;  // Rounding up.
726         }
727       }
728 
729       // Rounding up may cause overflow.
730       if ((number & ((int64_t)1 << kSignificandSize)) != 0) {
731         exponent++;
732         number >>= 1;
733       }
734       break;
735     }
736     if (Advance(current, separator, radix, end)) break;
737   }
738 
739   ASSERT(number < ((int64_t)1 << kSignificandSize));
740   ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
741 
742   *result_is_junk = false;
743 
744   if (parse_as_hex_float) {
745     ASSERT(**current == 'p' || **current == 'P');
746     Advance(current, separator, radix, end);
747     ASSERT(*current != end);
748     bool is_negative = false;
749     if (**current == '+') {
750       Advance(current, separator, radix, end);
751       ASSERT(*current != end);
752     } else if (**current == '-') {
753       is_negative = true;
754       Advance(current, separator, radix, end);
755       ASSERT(*current != end);
756     }
757     int written_exponent = 0;
758     while (IsDecimalDigitForRadix(**current, 10)) {
759       // No need to read exponents if they are too big. That could potentially overflow
760       // the `written_exponent` variable.
761       if (abs(written_exponent) <= 100 * Double::kMaxExponent) {
762         written_exponent = 10 * written_exponent + **current - '0';
763       }
764       if (Advance(current, separator, radix, end)) break;
765     }
766     if (is_negative) written_exponent = -written_exponent;
767     exponent += written_exponent;
768   }
769 
770   if (exponent == 0 || number == 0) {
771     if (sign) {
772       if (number == 0) return -0.0;
773       number = -number;
774     }
775     return static_cast<double>(number);
776   }
777 
778   ASSERT(number != 0);
779   double result = Double(DiyFp(number, exponent)).value();
780   return sign ? -result : result;
781 }
782 
783 template <class Iterator>
StringToIeee(Iterator input,int length,bool read_as_double,int * processed_characters_count) const784 double StringToDoubleConverter::StringToIeee(
785     Iterator input,
786     int length,
787     bool read_as_double,
788     int* processed_characters_count) const {
789   Iterator current = input;
790   Iterator end = input + length;
791 
792   *processed_characters_count = 0;
793 
794   const bool allow_trailing_junk = (flags_ & ALLOW_TRAILING_JUNK) != 0;
795   const bool allow_leading_spaces = (flags_ & ALLOW_LEADING_SPACES) != 0;
796   const bool allow_trailing_spaces = (flags_ & ALLOW_TRAILING_SPACES) != 0;
797   const bool allow_spaces_after_sign = (flags_ & ALLOW_SPACES_AFTER_SIGN) != 0;
798   const bool allow_case_insensibility = (flags_ & ALLOW_CASE_INSENSIBILITY) != 0;
799 
800   // To make sure that iterator dereferencing is valid the following
801   // convention is used:
802   // 1. Each '++current' statement is followed by check for equality to 'end'.
803   // 2. If AdvanceToNonspace returned false then current == end.
804   // 3. If 'current' becomes equal to 'end' the function returns or goes to
805   // 'parsing_done'.
806   // 4. 'current' is not dereferenced after the 'parsing_done' label.
807   // 5. Code before 'parsing_done' may rely on 'current != end'.
808   if (current == end) return empty_string_value_;
809 
810   if (allow_leading_spaces || allow_trailing_spaces) {
811     if (!AdvanceToNonspace(&current, end)) {
812       *processed_characters_count = static_cast<int>(current - input);
813       return empty_string_value_;
814     }
815     if (!allow_leading_spaces && (input != current)) {
816       // No leading spaces allowed, but AdvanceToNonspace moved forward.
817       return junk_string_value_;
818     }
819   }
820 
821   // The longest form of simplified number is: "-<significant digits>.1eXXX\0".
822   const int kBufferSize = kMaxSignificantDigits + 10;
823   char buffer[kBufferSize];  // NOLINT: size is known at compile time.
824   int buffer_pos = 0;
825 
826   // Exponent will be adjusted if insignificant digits of the integer part
827   // or insignificant leading zeros of the fractional part are dropped.
828   int exponent = 0;
829   int significant_digits = 0;
830   int insignificant_digits = 0;
831   bool nonzero_digit_dropped = false;
832 
833   bool sign = false;
834 
835   if (*current == '+' || *current == '-') {
836     sign = (*current == '-');
837     ++current;
838     Iterator next_non_space = current;
839     // Skip following spaces (if allowed).
840     if (!AdvanceToNonspace(&next_non_space, end)) return junk_string_value_;
841     if (!allow_spaces_after_sign && (current != next_non_space)) {
842       return junk_string_value_;
843     }
844     current = next_non_space;
845   }
846 
847   if (infinity_symbol_ != NULL) {
848     if (ConsumeFirstCharacter(*current, infinity_symbol_, allow_case_insensibility)) {
849       if (!ConsumeSubString(&current, end, infinity_symbol_, allow_case_insensibility)) {
850         return junk_string_value_;
851       }
852 
853       if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
854         return junk_string_value_;
855       }
856       if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
857         return junk_string_value_;
858       }
859 
860       ASSERT(buffer_pos == 0);
861       *processed_characters_count = static_cast<int>(current - input);
862       return sign ? -Double::Infinity() : Double::Infinity();
863     }
864   }
865 
866   if (nan_symbol_ != NULL) {
867     if (ConsumeFirstCharacter(*current, nan_symbol_, allow_case_insensibility)) {
868       if (!ConsumeSubString(&current, end, nan_symbol_, allow_case_insensibility)) {
869         return junk_string_value_;
870       }
871 
872       if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
873         return junk_string_value_;
874       }
875       if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
876         return junk_string_value_;
877       }
878 
879       ASSERT(buffer_pos == 0);
880       *processed_characters_count = static_cast<int>(current - input);
881       return sign ? -Double::NaN() : Double::NaN();
882     }
883   }
884 
885   bool leading_zero = false;
886   if (*current == '0') {
887     if (Advance(&current, separator_, 10, end)) {
888       *processed_characters_count = static_cast<int>(current - input);
889       return SignedZero(sign);
890     }
891 
892     leading_zero = true;
893 
894     // It could be hexadecimal value.
895     if (((flags_ & ALLOW_HEX) || (flags_ & ALLOW_HEX_FLOATS)) &&
896         (*current == 'x' || *current == 'X')) {
897       ++current;
898 
899       if (current == end) return junk_string_value_;  // "0x"
900 
901       bool parse_as_hex_float = (flags_ & ALLOW_HEX_FLOATS) &&
902                 IsHexFloatString(current, end, separator_, allow_trailing_junk);
903 
904       if (!parse_as_hex_float && !isDigit(*current, 16)) {
905         return junk_string_value_;
906       }
907 
908       bool result_is_junk;
909       double result = RadixStringToIeee<4>(&current,
910                                            end,
911                                            sign,
912                                            separator_,
913                                            parse_as_hex_float,
914                                            allow_trailing_junk,
915                                            junk_string_value_,
916                                            read_as_double,
917                                            &result_is_junk);
918       if (!result_is_junk) {
919         if (allow_trailing_spaces) AdvanceToNonspace(&current, end);
920         *processed_characters_count = static_cast<int>(current - input);
921       }
922       return result;
923     }
924 
925     // Ignore leading zeros in the integer part.
926     while (*current == '0') {
927       if (Advance(&current, separator_, 10, end)) {
928         *processed_characters_count = static_cast<int>(current - input);
929         return SignedZero(sign);
930       }
931     }
932   }
933 
934   bool octal = leading_zero && (flags_ & ALLOW_OCTALS) != 0;
935 
936   // Copy significant digits of the integer part (if any) to the buffer.
937   while (*current >= '0' && *current <= '9') {
938     if (significant_digits < kMaxSignificantDigits) {
939       ASSERT(buffer_pos < kBufferSize);
940       buffer[buffer_pos++] = static_cast<char>(*current);
941       significant_digits++;
942       // Will later check if it's an octal in the buffer.
943     } else {
944       insignificant_digits++;  // Move the digit into the exponential part.
945       nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
946     }
947     octal = octal && *current < '8';
948     if (Advance(&current, separator_, 10, end)) goto parsing_done;
949   }
950 
951   if (significant_digits == 0) {
952     octal = false;
953   }
954 
955   if (*current == '.') {
956     if (octal && !allow_trailing_junk) return junk_string_value_;
957     if (octal) goto parsing_done;
958 
959     if (Advance(&current, separator_, 10, end)) {
960       if (significant_digits == 0 && !leading_zero) {
961         return junk_string_value_;
962       } else {
963         goto parsing_done;
964       }
965     }
966 
967     if (significant_digits == 0) {
968       // octal = false;
969       // Integer part consists of 0 or is absent. Significant digits start after
970       // leading zeros (if any).
971       while (*current == '0') {
972         if (Advance(&current, separator_, 10, end)) {
973           *processed_characters_count = static_cast<int>(current - input);
974           return SignedZero(sign);
975         }
976         exponent--;  // Move this 0 into the exponent.
977       }
978     }
979 
980     // There is a fractional part.
981     // We don't emit a '.', but adjust the exponent instead.
982     while (*current >= '0' && *current <= '9') {
983       if (significant_digits < kMaxSignificantDigits) {
984         ASSERT(buffer_pos < kBufferSize);
985         buffer[buffer_pos++] = static_cast<char>(*current);
986         significant_digits++;
987         exponent--;
988       } else {
989         // Ignore insignificant digits in the fractional part.
990         nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
991       }
992       if (Advance(&current, separator_, 10, end)) goto parsing_done;
993     }
994   }
995 
996   if (!leading_zero && exponent == 0 && significant_digits == 0) {
997     // If leading_zeros is true then the string contains zeros.
998     // If exponent < 0 then string was [+-]\.0*...
999     // If significant_digits != 0 the string is not equal to 0.
1000     // Otherwise there are no digits in the string.
1001     return junk_string_value_;
1002   }
1003 
1004   // Parse exponential part.
1005   if (*current == 'e' || *current == 'E') {
1006     if (octal && !allow_trailing_junk) return junk_string_value_;
1007     if (octal) goto parsing_done;
1008     Iterator junk_begin = current;
1009     ++current;
1010     if (current == end) {
1011       if (allow_trailing_junk) {
1012         current = junk_begin;
1013         goto parsing_done;
1014       } else {
1015         return junk_string_value_;
1016       }
1017     }
1018     char exponen_sign = '+';
1019     if (*current == '+' || *current == '-') {
1020       exponen_sign = static_cast<char>(*current);
1021       ++current;
1022       if (current == end) {
1023         if (allow_trailing_junk) {
1024           current = junk_begin;
1025           goto parsing_done;
1026         } else {
1027           return junk_string_value_;
1028         }
1029       }
1030     }
1031 
1032     if (current == end || *current < '0' || *current > '9') {
1033       if (allow_trailing_junk) {
1034         current = junk_begin;
1035         goto parsing_done;
1036       } else {
1037         return junk_string_value_;
1038       }
1039     }
1040 
1041     const int max_exponent = INT_MAX / 2;
1042     ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
1043     int num = 0;
1044     do {
1045       // Check overflow.
1046       int digit = *current - '0';
1047       if (num >= max_exponent / 10
1048           && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
1049         num = max_exponent;
1050       } else {
1051         num = num * 10 + digit;
1052       }
1053       ++current;
1054     } while (current != end && *current >= '0' && *current <= '9');
1055 
1056     exponent += (exponen_sign == '-' ? -num : num);
1057   }
1058 
1059   if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
1060     return junk_string_value_;
1061   }
1062   if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
1063     return junk_string_value_;
1064   }
1065   if (allow_trailing_spaces) {
1066     AdvanceToNonspace(&current, end);
1067   }
1068 
1069   parsing_done:
1070   exponent += insignificant_digits;
1071 
1072   if (octal) {
1073     double result;
1074     bool result_is_junk;
1075     char* start = buffer;
1076     result = RadixStringToIeee<3>(&start,
1077                                   buffer + buffer_pos,
1078                                   sign,
1079                                   separator_,
1080                                   false, // Don't parse as hex_float.
1081                                   allow_trailing_junk,
1082                                   junk_string_value_,
1083                                   read_as_double,
1084                                   &result_is_junk);
1085     ASSERT(!result_is_junk);
1086     *processed_characters_count = static_cast<int>(current - input);
1087     return result;
1088   }
1089 
1090   if (nonzero_digit_dropped) {
1091     buffer[buffer_pos++] = '1';
1092     exponent--;
1093   }
1094 
1095   ASSERT(buffer_pos < kBufferSize);
1096   buffer[buffer_pos] = '\0';
1097 
1098   double converted;
1099   if (read_as_double) {
1100     converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
1101   } else {
1102     converted = Strtof(Vector<const char>(buffer, buffer_pos), exponent);
1103   }
1104   *processed_characters_count = static_cast<int>(current - input);
1105   return sign? -converted: converted;
1106 }
1107 
1108 
StringToDouble(const char * buffer,int length,int * processed_characters_count) const1109 double StringToDoubleConverter::StringToDouble(
1110     const char* buffer,
1111     int length,
1112     int* processed_characters_count) const {
1113   return StringToIeee(buffer, length, true, processed_characters_count);
1114 }
1115 
1116 
StringToDouble(const uc16 * buffer,int length,int * processed_characters_count) const1117 double StringToDoubleConverter::StringToDouble(
1118     const uc16* buffer,
1119     int length,
1120     int* processed_characters_count) const {
1121   return StringToIeee(buffer, length, true, processed_characters_count);
1122 }
1123 
1124 
StringToFloat(const char * buffer,int length,int * processed_characters_count) const1125 float StringToDoubleConverter::StringToFloat(
1126     const char* buffer,
1127     int length,
1128     int* processed_characters_count) const {
1129   return static_cast<float>(StringToIeee(buffer, length, false,
1130                                          processed_characters_count));
1131 }
1132 
1133 
StringToFloat(const uc16 * buffer,int length,int * processed_characters_count) const1134 float StringToDoubleConverter::StringToFloat(
1135     const uc16* buffer,
1136     int length,
1137     int* processed_characters_count) const {
1138   return static_cast<float>(StringToIeee(buffer, length, false,
1139                                          processed_characters_count));
1140 }
1141 
1142 }  // namespace double_conversion
1143