Coverage Report

Created: 2026-05-30 06:46

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