Coverage Report

Created: 2025-05-24 06:08

/src/double-conversion/double-conversion/string-to-double.cc
Line
Count
Source (jump to first uncovered line)
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
6.11k
inline char ToLower(char ch) {
55
6.11k
  static const std::ctype<char>& cType =
56
6.11k
      std::use_facet<std::ctype<char> >(std::locale::classic());
57
6.11k
  return cType.tolower(ch);
58
6.11k
}
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
8
                                        Converter converter) {
69
8
  DOUBLE_CONVERSION_ASSERT(converter(**current) == *substring);
70
17
  for (substring++; *substring != '\0'; substring++) {
71
13
    ++*current;
72
13
    if (*current == end || converter(**current) != *substring) {
73
4
      return false;
74
4
    }
75
13
  }
76
4
  ++*current;
77
4
  return true;
78
8
}
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
8
                                        Converter converter) {
69
8
  DOUBLE_CONVERSION_ASSERT(converter(**current) == *substring);
70
17
  for (substring++; *substring != '\0'; substring++) {
71
13
    ++*current;
72
13
    if (*current == end || converter(**current) != *substring) {
73
4
      return false;
74
4
    }
75
13
  }
76
4
  ++*current;
77
4
  return true;
78
8
}
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
8
                             bool allow_case_insensitivity) {
87
8
  if (allow_case_insensitivity) {
88
8
    return ConsumeSubStringImpl(current, end, substring, ToLower);
89
8
  } else {
90
0
    return ConsumeSubStringImpl(current, end, substring, Pass);
91
0
  }
92
8
}
string-to-double.cc:bool double_conversion::(anonymous namespace)::ConsumeSubString<char const*>(char const**, char const*, char const*, bool)
Line
Count
Source
86
8
                             bool allow_case_insensitivity) {
87
8
  if (allow_case_insensitivity) {
88
8
    return ConsumeSubStringImpl(current, end, substring, ToLower);
89
8
  } else {
90
0
    return ConsumeSubStringImpl(current, end, substring, Pass);
91
0
  }
92
8
}
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
6.10k
                                         bool case_insensitivity) {
98
6.10k
  return case_insensitivity ? ToLower(ch) == str[0] : ch == str[0];
99
6.10k
}
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
5.88k
static bool isWhitespace(int x) {
124
5.88k
  if (x < 128) {
125
30.7k
    for (int i = 0; i < kWhitespaceTable7Length; i++) {
126
27.2k
      if (kWhitespaceTable7[i] == x) return true;
127
27.2k
    }
128
5.88k
  } else {
129
0
    for (int i = 0; i < kWhitespaceTable16Length; i++) {
130
0
      if (kWhitespaceTable16[i] == x) return true;
131
0
    }
132
0
  }
133
3.41k
  return false;
134
5.88k
}
135
136
137
// Returns true if a nonspace found and false if the end has reached.
138
template <class Iterator>
139
5.01k
static inline bool AdvanceToNonspace(Iterator* current, Iterator end) {
140
7.47k
  while (*current != end) {
141
5.88k
    if (!isWhitespace(**current)) return true;
142
2.46k
    ++*current;
143
2.46k
  }
144
1.59k
  return false;
145
5.01k
}
string-to-double.cc:bool double_conversion::AdvanceToNonspace<char const*>(char const**, char const*)
Line
Count
Source
139
5.01k
static inline bool AdvanceToNonspace(Iterator* current, Iterator end) {
140
7.47k
  while (*current != end) {
141
5.88k
    if (!isWhitespace(**current)) return true;
142
2.46k
    ++*current;
143
2.46k
  }
144
1.59k
  return false;
145
5.01k
}
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
7.40M
static bool isDigit(int x, int radix) {
149
7.40M
  return (x >= '0' && x <= '9' && x < '0' + radix)
150
7.40M
      || (radix > 10 && x >= 'a' && x < 'a' + radix - 10)
151
7.40M
      || (radix > 10 && x >= 'A' && x < 'A' + radix - 10);
152
7.40M
}
153
154
155
35
static double SignedZero(bool sign) {
156
35
  return sign ? -0.0 : 0.0;
157
35
}
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
3.62M
static bool inline IsDecimalDigitForRadix(int c, int radix) {
174
3.62M
  return '0' <= c && c <= '9' && (c - '0') < radix;
175
3.62M
}
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.59k
static bool IsCharacterDigitForRadix(int c, int radix, char a_character) {
185
4.59k
  return radix > 10 && c >= a_character && c < a_character + radix - 10;
186
4.59k
}
187
188
// Returns true, when the iterator is equal to end.
189
template<class Iterator>
190
13.2M
static bool Advance (Iterator* it, uc16 separator, int base, Iterator& end) {
191
13.2M
  if (separator == StringToDoubleConverter::kNoSeparator) {
192
13.2M
    ++(*it);
193
13.2M
    return *it == end;
194
13.2M
  }
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
13.2M
static bool Advance (Iterator* it, uc16 separator, int base, Iterator& end) {
191
13.2M
  if (separator == StringToDoubleConverter::kNoSeparator) {
192
13.2M
    ++(*it);
193
13.2M
    return *it == end;
194
13.2M
  }
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
6.21k
static bool Advance (Iterator* it, uc16 separator, int base, Iterator& end) {
191
6.21k
  if (separator == StringToDoubleConverter::kNoSeparator) {
192
6.21k
    ++(*it);
193
6.21k
    return *it == end;
194
6.21k
  }
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.01k
                             bool allow_trailing_junk) {
220
1.01k
  DOUBLE_CONVERSION_ASSERT(start != end);
221
222
1.01k
  Iterator current = start;
223
224
1.01k
  bool saw_digit = false;
225
7.27k
  while (isDigit(*current, 16)) {
226
6.49k
    saw_digit = true;
227
6.49k
    if (Advance(&current, separator, 16, end)) return false;
228
6.49k
  }
229
781
  if (*current == '.') {
230
145
    if (Advance(&current, separator, 16, end)) return false;
231
7.39M
    while (isDigit(*current, 16)) {
232
7.39M
      saw_digit = true;
233
7.39M
      if (Advance(&current, separator, 16, end)) return false;
234
7.39M
    }
235
141
  }
236
763
  if (!saw_digit) return false;
237
707
  if (*current != 'p' && *current != 'P') return false;
238
615
  if (Advance(&current, separator, 16, end)) return false;
239
610
  if (*current == '+' || *current == '-') {
240
173
    if (Advance(&current, separator, 16, end)) return false;
241
173
  }
242
608
  if (!isDigit(*current, 10)) return false;
243
584
  if (Advance(&current, separator, 16, end)) return true;
244
2.51k
  while (isDigit(*current, 10)) {
245
2.47k
    if (Advance(&current, separator, 16, end)) return true;
246
2.47k
  }
247
46
  return allow_trailing_junk || !AdvanceToNonspace(&current, end);
248
358
}
string-to-double.cc:bool double_conversion::IsHexFloatString<char const*>(char const*, char const*, unsigned short, bool)
Line
Count
Source
219
1.01k
                             bool allow_trailing_junk) {
220
1.01k
  DOUBLE_CONVERSION_ASSERT(start != end);
221
222
1.01k
  Iterator current = start;
223
224
1.01k
  bool saw_digit = false;
225
7.27k
  while (isDigit(*current, 16)) {
226
6.49k
    saw_digit = true;
227
6.49k
    if (Advance(&current, separator, 16, end)) return false;
228
6.49k
  }
229
781
  if (*current == '.') {
230
145
    if (Advance(&current, separator, 16, end)) return false;
231
7.39M
    while (isDigit(*current, 16)) {
232
7.39M
      saw_digit = true;
233
7.39M
      if (Advance(&current, separator, 16, end)) return false;
234
7.39M
    }
235
141
  }
236
763
  if (!saw_digit) return false;
237
707
  if (*current != 'p' && *current != 'P') return false;
238
615
  if (Advance(&current, separator, 16, end)) return false;
239
610
  if (*current == '+' || *current == '-') {
240
173
    if (Advance(&current, separator, 16, end)) return false;
241
173
  }
242
608
  if (!isDigit(*current, 10)) return false;
243
584
  if (Advance(&current, separator, 16, end)) return true;
244
2.51k
  while (isDigit(*current, 10)) {
245
2.47k
    if (Advance(&current, separator, 16, end)) return true;
246
2.47k
  }
247
46
  return allow_trailing_junk || !AdvanceToNonspace(&current, end);
248
358
}
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
888
                                bool* result_is_junk) {
265
888
  DOUBLE_CONVERSION_ASSERT(*current != end);
266
888
  DOUBLE_CONVERSION_ASSERT(!parse_as_hex_float ||
267
888
      IsHexFloatString(*current, end, separator, allow_trailing_junk));
268
269
888
  const int kDoubleSize = Double::kSignificandSize;
270
888
  const int kSingleSize = Single::kSignificandSize;
271
888
  const int kSignificandSize = read_as_double? kDoubleSize: kSingleSize;
272
273
888
  *result_is_junk = true;
274
275
888
  int64_t number = 0;
276
888
  int exponent = 0;
277
888
  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
888
  bool post_decimal = false;
281
282
  // Skip leading 0s.
283
1.32k
  while (**current == '0') {
284
441
    if (Advance(current, separator, radix, end)) {
285
9
      *result_is_junk = false;
286
9
      return SignedZero(sign);
287
9
    }
288
441
  }
289
290
3.62M
  while (true) {
291
3.62M
    int digit;
292
3.62M
    if (IsDecimalDigitForRadix(**current, radix)) {
293
3.62M
      digit = static_cast<char>(**current) - '0';
294
3.62M
      if (post_decimal) exponent -= radix_log_2;
295
3.62M
    } else if (IsCharacterDigitForRadix(**current, radix, 'a')) {
296
853
      digit = static_cast<char>(**current) - 'a' + 10;
297
853
      if (post_decimal) exponent -= radix_log_2;
298
1.86k
    } else if (IsCharacterDigitForRadix(**current, radix, 'A')) {
299
1.46k
      digit = static_cast<char>(**current) - 'A' + 10;
300
1.46k
      if (post_decimal) exponent -= radix_log_2;
301
1.46k
    } else if (parse_as_hex_float && **current == '.') {
302
45
      post_decimal = true;
303
45
      Advance(current, separator, radix, end);
304
45
      DOUBLE_CONVERSION_ASSERT(*current != end);
305
45
      continue;
306
358
    } else if (parse_as_hex_float && (**current == 'p' || **current == 'P')) {
307
263
      break;
308
263
    } else {
309
95
      if (allow_trailing_junk || !AdvanceToNonspace(current, end)) {
310
95
        break;
311
95
      } else {
312
0
        return junk_string_value;
313
0
      }
314
95
    }
315
316
3.62M
    number = number * radix + digit;
317
3.62M
    int overflow = static_cast<int>(number >> kSignificandSize);
318
3.62M
    if (overflow != 0) {
319
      // Overflow occurred. Need to determine which direction to round the
320
      // result.
321
285
      int overflow_bits_count = 1;
322
575
      while (overflow > 1) {
323
290
        overflow_bits_count++;
324
290
        overflow >>= 1;
325
290
      }
326
327
285
      int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
328
285
      int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
329
285
      number >>= overflow_bits_count;
330
285
      exponent += overflow_bits_count;
331
332
285
      bool zero_tail = true;
333
5.09k
      for (;;) {
334
5.09k
        if (Advance(current, separator, radix, end)) break;
335
4.86k
        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
3
          Advance(current, separator, radix, end);
339
3
          DOUBLE_CONVERSION_ASSERT(*current != end);
340
3
          post_decimal = true;
341
3
        }
342
4.86k
        if (!isDigit(**current, radix)) break;
343
4.80k
        zero_tail = zero_tail && **current == '0';
344
4.80k
        if (!post_decimal) exponent += radix_log_2;
345
4.80k
      }
346
347
285
      if (!parse_as_hex_float &&
348
285
          !allow_trailing_junk &&
349
285
          AdvanceToNonspace(current, end)) {
350
0
        return junk_string_value;
351
0
      }
352
353
285
      int middle_value = (1 << (overflow_bits_count - 1));
354
285
      if (dropped_bits > middle_value) {
355
58
        number++;  // Rounding up.
356
227
      } 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
75
        if ((number & 1) != 0 || !zero_tail) {
360
51
          number++;  // Rounding up.
361
51
        }
362
75
      }
363
364
      // Rounding up may cause overflow.
365
285
      if ((number & ((int64_t)1 << kSignificandSize)) != 0) {
366
14
        exponent++;
367
14
        number >>= 1;
368
14
      }
369
285
      break;
370
285
    }
371
3.62M
    if (Advance(current, separator, radix, end)) break;
372
3.62M
  }
373
374
879
  DOUBLE_CONVERSION_ASSERT(number < ((int64_t)1 << kSignificandSize));
375
879
  DOUBLE_CONVERSION_ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
376
377
879
  *result_is_junk = false;
378
379
879
  if (parse_as_hex_float) {
380
292
    DOUBLE_CONVERSION_ASSERT(**current == 'p' || **current == 'P');
381
292
    Advance(current, separator, radix, end);
382
292
    DOUBLE_CONVERSION_ASSERT(*current != end);
383
292
    bool is_negative = false;
384
292
    if (**current == '+') {
385
1
      Advance(current, separator, radix, end);
386
1
      DOUBLE_CONVERSION_ASSERT(*current != end);
387
291
    } else if (**current == '-') {
388
84
      is_negative = true;
389
84
      Advance(current, separator, radix, end);
390
84
      DOUBLE_CONVERSION_ASSERT(*current != end);
391
84
    }
392
292
    int written_exponent = 0;
393
1.55k
    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.52k
      if (abs(written_exponent) <= 100 * Double::kMaxExponent) {
397
1.20k
        written_exponent = 10 * written_exponent + **current - '0';
398
1.20k
      }
399
1.52k
      if (Advance(current, separator, radix, end)) break;
400
1.52k
    }
401
292
    if (is_negative) written_exponent = -written_exponent;
402
292
    exponent += written_exponent;
403
292
  }
404
405
879
  if (exponent == 0 || number == 0) {
406
360
    if (sign) {
407
107
      if (number == 0) return -0.0;
408
106
      number = -number;
409
106
    }
410
359
    return static_cast<double>(number);
411
360
  }
412
413
519
  DOUBLE_CONVERSION_ASSERT(number != 0);
414
519
  double result = Double(DiyFp(number, exponent)).value();
415
519
  return sign ? -result : result;
416
519
}
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
646
                                bool* result_is_junk) {
265
646
  DOUBLE_CONVERSION_ASSERT(*current != end);
266
646
  DOUBLE_CONVERSION_ASSERT(!parse_as_hex_float ||
267
646
      IsHexFloatString(*current, end, separator, allow_trailing_junk));
268
269
646
  const int kDoubleSize = Double::kSignificandSize;
270
646
  const int kSingleSize = Single::kSignificandSize;
271
646
  const int kSignificandSize = read_as_double? kDoubleSize: kSingleSize;
272
273
646
  *result_is_junk = true;
274
275
646
  int64_t number = 0;
276
646
  int exponent = 0;
277
646
  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
646
  bool post_decimal = false;
281
282
  // Skip leading 0s.
283
1.07k
  while (**current == '0') {
284
441
    if (Advance(current, separator, radix, end)) {
285
9
      *result_is_junk = false;
286
9
      return SignedZero(sign);
287
9
    }
288
441
  }
289
290
3.62M
  while (true) {
291
3.62M
    int digit;
292
3.62M
    if (IsDecimalDigitForRadix(**current, radix)) {
293
3.61M
      digit = static_cast<char>(**current) - '0';
294
3.61M
      if (post_decimal) exponent -= radix_log_2;
295
3.61M
    } else if (IsCharacterDigitForRadix(**current, radix, 'a')) {
296
853
      digit = static_cast<char>(**current) - 'a' + 10;
297
853
      if (post_decimal) exponent -= radix_log_2;
298
1.86k
    } else if (IsCharacterDigitForRadix(**current, radix, 'A')) {
299
1.46k
      digit = static_cast<char>(**current) - 'A' + 10;
300
1.46k
      if (post_decimal) exponent -= radix_log_2;
301
1.46k
    } else if (parse_as_hex_float && **current == '.') {
302
45
      post_decimal = true;
303
45
      Advance(current, separator, radix, end);
304
45
      DOUBLE_CONVERSION_ASSERT(*current != end);
305
45
      continue;
306
358
    } else if (parse_as_hex_float && (**current == 'p' || **current == 'P')) {
307
263
      break;
308
263
    } else {
309
95
      if (allow_trailing_junk || !AdvanceToNonspace(current, end)) {
310
95
        break;
311
95
      } else {
312
0
        return junk_string_value;
313
0
      }
314
95
    }
315
316
3.62M
    number = number * radix + digit;
317
3.62M
    int overflow = static_cast<int>(number >> kSignificandSize);
318
3.62M
    if (overflow != 0) {
319
      // Overflow occurred. Need to determine which direction to round the
320
      // result.
321
156
      int overflow_bits_count = 1;
322
420
      while (overflow > 1) {
323
264
        overflow_bits_count++;
324
264
        overflow >>= 1;
325
264
      }
326
327
156
      int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
328
156
      int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
329
156
      number >>= overflow_bits_count;
330
156
      exponent += overflow_bits_count;
331
332
156
      bool zero_tail = true;
333
2.06k
      for (;;) {
334
2.06k
        if (Advance(current, separator, radix, end)) break;
335
1.95k
        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
3
          Advance(current, separator, radix, end);
339
3
          DOUBLE_CONVERSION_ASSERT(*current != end);
340
3
          post_decimal = true;
341
3
        }
342
1.95k
        if (!isDigit(**current, radix)) break;
343
1.90k
        zero_tail = zero_tail && **current == '0';
344
1.90k
        if (!post_decimal) exponent += radix_log_2;
345
1.90k
      }
346
347
156
      if (!parse_as_hex_float &&
348
156
          !allow_trailing_junk &&
349
156
          AdvanceToNonspace(current, end)) {
350
0
        return junk_string_value;
351
0
      }
352
353
156
      int middle_value = (1 << (overflow_bits_count - 1));
354
156
      if (dropped_bits > middle_value) {
355
56
        number++;  // Rounding up.
356
100
      } 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
20
        if ((number & 1) != 0 || !zero_tail) {
360
12
          number++;  // Rounding up.
361
12
        }
362
20
      }
363
364
      // Rounding up may cause overflow.
365
156
      if ((number & ((int64_t)1 << kSignificandSize)) != 0) {
366
9
        exponent++;
367
9
        number >>= 1;
368
9
      }
369
156
      break;
370
156
    }
371
3.62M
    if (Advance(current, separator, radix, end)) break;
372
3.62M
  }
373
374
637
  DOUBLE_CONVERSION_ASSERT(number < ((int64_t)1 << kSignificandSize));
375
637
  DOUBLE_CONVERSION_ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
376
377
637
  *result_is_junk = false;
378
379
637
  if (parse_as_hex_float) {
380
292
    DOUBLE_CONVERSION_ASSERT(**current == 'p' || **current == 'P');
381
292
    Advance(current, separator, radix, end);
382
292
    DOUBLE_CONVERSION_ASSERT(*current != end);
383
292
    bool is_negative = false;
384
292
    if (**current == '+') {
385
1
      Advance(current, separator, radix, end);
386
1
      DOUBLE_CONVERSION_ASSERT(*current != end);
387
291
    } else if (**current == '-') {
388
84
      is_negative = true;
389
84
      Advance(current, separator, radix, end);
390
84
      DOUBLE_CONVERSION_ASSERT(*current != end);
391
84
    }
392
292
    int written_exponent = 0;
393
1.55k
    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.52k
      if (abs(written_exponent) <= 100 * Double::kMaxExponent) {
397
1.20k
        written_exponent = 10 * written_exponent + **current - '0';
398
1.20k
      }
399
1.52k
      if (Advance(current, separator, radix, end)) break;
400
1.52k
    }
401
292
    if (is_negative) written_exponent = -written_exponent;
402
292
    exponent += written_exponent;
403
292
  }
404
405
637
  if (exponent == 0 || number == 0) {
406
247
    if (sign) {
407
54
      if (number == 0) return -0.0;
408
53
      number = -number;
409
53
    }
410
246
    return static_cast<double>(number);
411
247
  }
412
413
390
  DOUBLE_CONVERSION_ASSERT(number != 0);
414
390
  double result = Double(DiyFp(number, exponent)).value();
415
390
  return sign ? -result : result;
416
390
}
string-to-double.cc:double double_conversion::RadixStringToIeee<3, char*>(char**, char*, bool, unsigned short, bool, bool, double, bool, bool*)
Line
Count
Source
264
242
                                bool* result_is_junk) {
265
242
  DOUBLE_CONVERSION_ASSERT(*current != end);
266
242
  DOUBLE_CONVERSION_ASSERT(!parse_as_hex_float ||
267
242
      IsHexFloatString(*current, end, separator, allow_trailing_junk));
268
269
242
  const int kDoubleSize = Double::kSignificandSize;
270
242
  const int kSingleSize = Single::kSignificandSize;
271
242
  const int kSignificandSize = read_as_double? kDoubleSize: kSingleSize;
272
273
242
  *result_is_junk = true;
274
275
242
  int64_t number = 0;
276
242
  int exponent = 0;
277
242
  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
242
  bool post_decimal = false;
281
282
  // Skip leading 0s.
283
242
  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.31k
  while (true) {
291
3.31k
    int digit;
292
3.31k
    if (IsDecimalDigitForRadix(**current, radix)) {
293
3.31k
      digit = static_cast<char>(**current) - '0';
294
3.31k
      if (post_decimal) exponent -= radix_log_2;
295
3.31k
    } 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.31k
    number = number * radix + digit;
317
3.31k
    int overflow = static_cast<int>(number >> kSignificandSize);
318
3.31k
    if (overflow != 0) {
319
      // Overflow occurred. Need to determine which direction to round the
320
      // result.
321
129
      int overflow_bits_count = 1;
322
155
      while (overflow > 1) {
323
26
        overflow_bits_count++;
324
26
        overflow >>= 1;
325
26
      }
326
327
129
      int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
328
129
      int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
329
129
      number >>= overflow_bits_count;
330
129
      exponent += overflow_bits_count;
331
332
129
      bool zero_tail = true;
333
3.03k
      for (;;) {
334
3.03k
        if (Advance(current, separator, radix, end)) break;
335
2.90k
        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
2.90k
        if (!isDigit(**current, radix)) break;
343
2.90k
        zero_tail = zero_tail && **current == '0';
344
2.90k
        if (!post_decimal) exponent += radix_log_2;
345
2.90k
      }
346
347
129
      if (!parse_as_hex_float &&
348
129
          !allow_trailing_junk &&
349
129
          AdvanceToNonspace(current, end)) {
350
0
        return junk_string_value;
351
0
      }
352
353
129
      int middle_value = (1 << (overflow_bits_count - 1));
354
129
      if (dropped_bits > middle_value) {
355
2
        number++;  // Rounding up.
356
127
      } 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
55
        if ((number & 1) != 0 || !zero_tail) {
360
39
          number++;  // Rounding up.
361
39
        }
362
55
      }
363
364
      // Rounding up may cause overflow.
365
129
      if ((number & ((int64_t)1 << kSignificandSize)) != 0) {
366
5
        exponent++;
367
5
        number >>= 1;
368
5
      }
369
129
      break;
370
129
    }
371
3.18k
    if (Advance(current, separator, radix, end)) break;
372
3.18k
  }
373
374
242
  DOUBLE_CONVERSION_ASSERT(number < ((int64_t)1 << kSignificandSize));
375
242
  DOUBLE_CONVERSION_ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
376
377
242
  *result_is_junk = false;
378
379
242
  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
242
  if (exponent == 0 || number == 0) {
406
113
    if (sign) {
407
53
      if (number == 0) return -0.0;
408
53
      number = -number;
409
53
    }
410
113
    return static_cast<double>(number);
411
113
  }
412
413
129
  DOUBLE_CONVERSION_ASSERT(number != 0);
414
129
  double result = Double(DiyFp(number, exponent)).value();
415
129
  return sign ? -result : result;
416
129
}
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
3.09k
    int* processed_characters_count) const {
424
3.09k
  Iterator current = input;
425
3.09k
  Iterator end = input + length;
426
427
3.09k
  *processed_characters_count = 0;
428
429
3.09k
  const bool allow_trailing_junk = (flags_ & ALLOW_TRAILING_JUNK) != 0;
430
3.09k
  const bool allow_leading_spaces = (flags_ & ALLOW_LEADING_SPACES) != 0;
431
3.09k
  const bool allow_trailing_spaces = (flags_ & ALLOW_TRAILING_SPACES) != 0;
432
3.09k
  const bool allow_spaces_after_sign = (flags_ & ALLOW_SPACES_AFTER_SIGN) != 0;
433
3.09k
  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
3.09k
  if (current == end) return empty_string_value_;
444
445
3.09k
  if (allow_leading_spaces || allow_trailing_spaces) {
446
3.09k
    if (!AdvanceToNonspace(&current, end)) {
447
21
      *processed_characters_count = static_cast<int>(current - input);
448
21
      return empty_string_value_;
449
21
    }
450
3.07k
    if (!allow_leading_spaces && (input != current)) {
451
      // No leading spaces allowed, but AdvanceToNonspace moved forward.
452
0
      return junk_string_value_;
453
0
    }
454
3.07k
  }
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
3.07k
  int exponent = 0;
459
3.07k
  int significant_digits = 0;
460
3.07k
  int insignificant_digits = 0;
461
3.07k
  bool nonzero_digit_dropped = false;
462
463
3.07k
  bool sign = false;
464
465
3.07k
  if (*current == '+' || *current == '-') {
466
153
    sign = (*current == '-');
467
153
    ++current;
468
153
    Iterator next_non_space = current;
469
    // Skip following spaces (if allowed).
470
153
    if (!AdvanceToNonspace(&next_non_space, end)) return junk_string_value_;
471
130
    if (!allow_spaces_after_sign && (current != next_non_space)) {
472
0
      return junk_string_value_;
473
0
    }
474
130
    current = next_non_space;
475
130
  }
476
477
3.05k
  if (infinity_symbol_ != DOUBLE_CONVERSION_NULLPTR) {
478
3.05k
    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
3.05k
  }
494
495
3.04k
  if (nan_symbol_ != DOUBLE_CONVERSION_NULLPTR) {
496
3.04k
    if (ConsumeFirstCharacter(*current, nan_symbol_, allow_case_insensitivity)) {
497
4
      if (!ConsumeSubString(&current, end, nan_symbol_, allow_case_insensitivity)) {
498
2
        return junk_string_value_;
499
2
      }
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
3.04k
  }
512
513
3.04k
  bool leading_zero = false;
514
3.04k
  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
725
      ++current;
526
527
725
      if (current == end) return junk_string_value_;  // "0x"
528
529
723
      bool parse_as_hex_float = (flags_ & ALLOW_HEX_FLOATS) &&
530
723
                IsHexFloatString(current, end, separator_, allow_trailing_junk);
531
532
723
      if (!parse_as_hex_float && !isDigit(*current, 16)) {
533
77
        return junk_string_value_;
534
77
      }
535
536
646
      bool result_is_junk;
537
646
      double result = RadixStringToIeee<4>(&current,
538
646
                                           end,
539
646
                                           sign,
540
646
                                           separator_,
541
646
                                           parse_as_hex_float,
542
646
                                           allow_trailing_junk,
543
646
                                           junk_string_value_,
544
646
                                           read_as_double,
545
646
                                           &result_is_junk);
546
646
      if (!result_is_junk) {
547
646
        if (allow_trailing_spaces) AdvanceToNonspace(&current, end);
548
646
        *processed_characters_count = static_cast<int>(current - input);
549
646
      }
550
646
      return result;
551
723
    }
552
553
    // Ignore leading zeros in the integer part.
554
782
    while (*current == '0') {
555
470
      if (Advance(&current, separator_, 10, end)) {
556
9
        *processed_characters_count = static_cast<int>(current - input);
557
9
        return SignedZero(sign);
558
9
      }
559
470
    }
560
321
  }
561
562
2.30k
  bool octal = leading_zero && (flags_ & ALLOW_OCTALS) != 0;
563
564
  // The longest form of simplified number is: "-<significant digits>.1eXXX\0".
565
2.30k
  const int kBufferSize = kMaxSignificantDigits + 10;
566
2.30k
  DOUBLE_CONVERSION_STACK_UNINITIALIZED char
567
2.30k
      buffer[kBufferSize];  // NOLINT: size is known at compile time.
568
2.30k
  int buffer_pos = 0;
569
570
  // Copy significant digits of the integer part (if any) to the buffer.
571
73.8k
  while (*current >= '0' && *current <= '9') {
572
72.3k
    if (significant_digits < kMaxSignificantDigits) {
573
68.0k
      DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize);
574
68.0k
      buffer[buffer_pos++] = static_cast<char>(*current);
575
68.0k
      significant_digits++;
576
      // Will later check if it's an octal in the buffer.
577
68.0k
    } else {
578
4.31k
      insignificant_digits++;  // Move the digit into the exponential part.
579
4.31k
      nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
580
4.31k
    }
581
72.3k
    octal = octal && *current < '8';
582
72.3k
    if (Advance(&current, separator_, 10, end)) goto parsing_done;
583
72.3k
  }
584
585
1.48k
  if (significant_digits == 0) {
586
258
    octal = false;
587
258
  }
588
589
1.48k
  if (*current == '.') {
590
375
    if (octal && !allow_trailing_junk) return junk_string_value_;
591
375
    if (octal) goto parsing_done;
592
593
374
    if (Advance(&current, separator_, 10, end)) {
594
4
      if (significant_digits == 0 && !leading_zero) {
595
1
        return junk_string_value_;
596
3
      } else {
597
3
        goto parsing_done;
598
3
      }
599
4
    }
600
601
370
    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.11M
      while (*current == '0') {
606
2.11M
        if (Advance(&current, separator_, 10, end)) {
607
14
          *processed_characters_count = static_cast<int>(current - input);
608
14
          return SignedZero(sign);
609
14
        }
610
2.11M
        exponent--;  // Move this 0 into the exponent.
611
2.11M
      }
612
132
    }
613
614
    // There is a fractional part.
615
    // We don't emit a '.', but adjust the exponent instead.
616
70.1k
    while (*current >= '0' && *current <= '9') {
617
69.9k
      if (significant_digits < kMaxSignificantDigits) {
618
68.4k
        DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize);
619
68.4k
        buffer[buffer_pos++] = static_cast<char>(*current);
620
68.4k
        significant_digits++;
621
68.4k
        exponent--;
622
68.4k
      } else {
623
        // Ignore insignificant digits in the fractional part.
624
1.57k
        nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
625
1.57k
      }
626
69.9k
      if (Advance(&current, separator_, 10, end)) goto parsing_done;
627
69.9k
    }
628
356
  }
629
630
1.22k
  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
79
    return junk_string_value_;
636
79
  }
637
638
  // Parse exponential part.
639
1.14k
  if (*current == 'e' || *current == 'E') {
640
1.03k
    if (octal && !allow_trailing_junk) return junk_string_value_;
641
1.03k
    if (octal) goto parsing_done;
642
1.03k
    Iterator junk_begin = current;
643
1.03k
    ++current;
644
1.03k
    if (current == end) {
645
4
      if (allow_trailing_junk) {
646
4
        current = junk_begin;
647
4
        goto parsing_done;
648
4
      } else {
649
0
        return junk_string_value_;
650
0
      }
651
4
    }
652
1.03k
    char exponen_sign = '+';
653
1.03k
    if (*current == '+' || *current == '-') {
654
398
      exponen_sign = static_cast<char>(*current);
655
398
      ++current;
656
398
      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
398
    }
665
666
1.03k
    if (current == end || *current < '0' || *current > '9') {
667
20
      if (allow_trailing_junk) {
668
20
        current = junk_begin;
669
20
        goto parsing_done;
670
20
      } else {
671
0
        return junk_string_value_;
672
0
      }
673
20
    }
674
675
1.01k
    const int max_exponent = INT_MAX / 2;
676
1.01k
    DOUBLE_CONVERSION_ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
677
1.01k
    int num = 0;
678
7.78k
    do {
679
      // Check overflow.
680
7.78k
      int digit = *current - '0';
681
7.78k
      if (num >= max_exponent / 10
682
7.78k
          && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
683
3.89k
        num = max_exponent;
684
3.89k
      } else {
685
3.88k
        num = num * 10 + digit;
686
3.88k
      }
687
7.78k
      ++current;
688
7.78k
    } while (current != end && *current >= '0' && *current <= '9');
689
690
1.01k
    exponent += (exponen_sign == '-' ? -num : num);
691
1.01k
  }
692
693
1.11k
  if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
694
0
    return junk_string_value_;
695
0
  }
696
1.11k
  if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
697
0
    return junk_string_value_;
698
0
  }
699
1.11k
  if (allow_trailing_spaces) {
700
1.11k
    AdvanceToNonspace(&current, end);
701
1.11k
  }
702
703
2.21k
  parsing_done:
704
2.21k
  exponent += insignificant_digits;
705
706
2.21k
  if (octal) {
707
242
    double result;
708
242
    bool result_is_junk;
709
242
    char* start = buffer;
710
242
    result = RadixStringToIeee<3>(&start,
711
242
                                  buffer + buffer_pos,
712
242
                                  sign,
713
242
                                  separator_,
714
242
                                  false, // Don't parse as hex_float.
715
242
                                  allow_trailing_junk,
716
242
                                  junk_string_value_,
717
242
                                  read_as_double,
718
242
                                  &result_is_junk);
719
242
    DOUBLE_CONVERSION_ASSERT(!result_is_junk);
720
242
    *processed_characters_count = static_cast<int>(current - input);
721
242
    return result;
722
242
  }
723
724
1.97k
  if (nonzero_digit_dropped) {
725
28
    buffer[buffer_pos++] = '1';
726
28
    exponent--;
727
28
  }
728
729
1.97k
  DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize);
730
1.97k
  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.97k
  Vector<const char> chars(buffer, buffer_pos);
735
1.97k
  chars = TrimTrailingZeros(chars);
736
1.97k
  exponent += buffer_pos - chars.length();
737
738
1.97k
  double converted;
739
1.97k
  if (read_as_double) {
740
1.97k
    converted = StrtodTrimmed(chars, exponent);
741
1.97k
  } else {
742
0
    converted = StrtofTrimmed(chars, exponent);
743
0
  }
744
1.97k
  *processed_characters_count = static_cast<int>(current - input);
745
1.97k
  return sign? -converted: converted;
746
1.97k
}
double double_conversion::StringToDoubleConverter::StringToIeee<char const*>(char const*, int, bool, int*) const
Line
Count
Source
423
3.09k
    int* processed_characters_count) const {
424
3.09k
  Iterator current = input;
425
3.09k
  Iterator end = input + length;
426
427
3.09k
  *processed_characters_count = 0;
428
429
3.09k
  const bool allow_trailing_junk = (flags_ & ALLOW_TRAILING_JUNK) != 0;
430
3.09k
  const bool allow_leading_spaces = (flags_ & ALLOW_LEADING_SPACES) != 0;
431
3.09k
  const bool allow_trailing_spaces = (flags_ & ALLOW_TRAILING_SPACES) != 0;
432
3.09k
  const bool allow_spaces_after_sign = (flags_ & ALLOW_SPACES_AFTER_SIGN) != 0;
433
3.09k
  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
3.09k
  if (current == end) return empty_string_value_;
444
445
3.09k
  if (allow_leading_spaces || allow_trailing_spaces) {
446
3.09k
    if (!AdvanceToNonspace(&current, end)) {
447
21
      *processed_characters_count = static_cast<int>(current - input);
448
21
      return empty_string_value_;
449
21
    }
450
3.07k
    if (!allow_leading_spaces && (input != current)) {
451
      // No leading spaces allowed, but AdvanceToNonspace moved forward.
452
0
      return junk_string_value_;
453
0
    }
454
3.07k
  }
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
3.07k
  int exponent = 0;
459
3.07k
  int significant_digits = 0;
460
3.07k
  int insignificant_digits = 0;
461
3.07k
  bool nonzero_digit_dropped = false;
462
463
3.07k
  bool sign = false;
464
465
3.07k
  if (*current == '+' || *current == '-') {
466
153
    sign = (*current == '-');
467
153
    ++current;
468
153
    Iterator next_non_space = current;
469
    // Skip following spaces (if allowed).
470
153
    if (!AdvanceToNonspace(&next_non_space, end)) return junk_string_value_;
471
130
    if (!allow_spaces_after_sign && (current != next_non_space)) {
472
0
      return junk_string_value_;
473
0
    }
474
130
    current = next_non_space;
475
130
  }
476
477
3.05k
  if (infinity_symbol_ != DOUBLE_CONVERSION_NULLPTR) {
478
3.05k
    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
3.05k
  }
494
495
3.04k
  if (nan_symbol_ != DOUBLE_CONVERSION_NULLPTR) {
496
3.04k
    if (ConsumeFirstCharacter(*current, nan_symbol_, allow_case_insensitivity)) {
497
4
      if (!ConsumeSubString(&current, end, nan_symbol_, allow_case_insensitivity)) {
498
2
        return junk_string_value_;
499
2
      }
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
3.04k
  }
512
513
3.04k
  bool leading_zero = false;
514
3.04k
  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
725
      ++current;
526
527
725
      if (current == end) return junk_string_value_;  // "0x"
528
529
723
      bool parse_as_hex_float = (flags_ & ALLOW_HEX_FLOATS) &&
530
723
                IsHexFloatString(current, end, separator_, allow_trailing_junk);
531
532
723
      if (!parse_as_hex_float && !isDigit(*current, 16)) {
533
77
        return junk_string_value_;
534
77
      }
535
536
646
      bool result_is_junk;
537
646
      double result = RadixStringToIeee<4>(&current,
538
646
                                           end,
539
646
                                           sign,
540
646
                                           separator_,
541
646
                                           parse_as_hex_float,
542
646
                                           allow_trailing_junk,
543
646
                                           junk_string_value_,
544
646
                                           read_as_double,
545
646
                                           &result_is_junk);
546
646
      if (!result_is_junk) {
547
646
        if (allow_trailing_spaces) AdvanceToNonspace(&current, end);
548
646
        *processed_characters_count = static_cast<int>(current - input);
549
646
      }
550
646
      return result;
551
723
    }
552
553
    // Ignore leading zeros in the integer part.
554
782
    while (*current == '0') {
555
470
      if (Advance(&current, separator_, 10, end)) {
556
9
        *processed_characters_count = static_cast<int>(current - input);
557
9
        return SignedZero(sign);
558
9
      }
559
470
    }
560
321
  }
561
562
2.30k
  bool octal = leading_zero && (flags_ & ALLOW_OCTALS) != 0;
563
564
  // The longest form of simplified number is: "-<significant digits>.1eXXX\0".
565
2.30k
  const int kBufferSize = kMaxSignificantDigits + 10;
566
2.30k
  DOUBLE_CONVERSION_STACK_UNINITIALIZED char
567
2.30k
      buffer[kBufferSize];  // NOLINT: size is known at compile time.
568
2.30k
  int buffer_pos = 0;
569
570
  // Copy significant digits of the integer part (if any) to the buffer.
571
73.8k
  while (*current >= '0' && *current <= '9') {
572
72.3k
    if (significant_digits < kMaxSignificantDigits) {
573
68.0k
      DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize);
574
68.0k
      buffer[buffer_pos++] = static_cast<char>(*current);
575
68.0k
      significant_digits++;
576
      // Will later check if it's an octal in the buffer.
577
68.0k
    } else {
578
4.31k
      insignificant_digits++;  // Move the digit into the exponential part.
579
4.31k
      nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
580
4.31k
    }
581
72.3k
    octal = octal && *current < '8';
582
72.3k
    if (Advance(&current, separator_, 10, end)) goto parsing_done;
583
72.3k
  }
584
585
1.48k
  if (significant_digits == 0) {
586
258
    octal = false;
587
258
  }
588
589
1.48k
  if (*current == '.') {
590
375
    if (octal && !allow_trailing_junk) return junk_string_value_;
591
375
    if (octal) goto parsing_done;
592
593
374
    if (Advance(&current, separator_, 10, end)) {
594
4
      if (significant_digits == 0 && !leading_zero) {
595
1
        return junk_string_value_;
596
3
      } else {
597
3
        goto parsing_done;
598
3
      }
599
4
    }
600
601
370
    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.11M
      while (*current == '0') {
606
2.11M
        if (Advance(&current, separator_, 10, end)) {
607
14
          *processed_characters_count = static_cast<int>(current - input);
608
14
          return SignedZero(sign);
609
14
        }
610
2.11M
        exponent--;  // Move this 0 into the exponent.
611
2.11M
      }
612
132
    }
613
614
    // There is a fractional part.
615
    // We don't emit a '.', but adjust the exponent instead.
616
70.1k
    while (*current >= '0' && *current <= '9') {
617
69.9k
      if (significant_digits < kMaxSignificantDigits) {
618
68.4k
        DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize);
619
68.4k
        buffer[buffer_pos++] = static_cast<char>(*current);
620
68.4k
        significant_digits++;
621
68.4k
        exponent--;
622
68.4k
      } else {
623
        // Ignore insignificant digits in the fractional part.
624
1.57k
        nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
625
1.57k
      }
626
69.9k
      if (Advance(&current, separator_, 10, end)) goto parsing_done;
627
69.9k
    }
628
356
  }
629
630
1.22k
  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
79
    return junk_string_value_;
636
79
  }
637
638
  // Parse exponential part.
639
1.14k
  if (*current == 'e' || *current == 'E') {
640
1.03k
    if (octal && !allow_trailing_junk) return junk_string_value_;
641
1.03k
    if (octal) goto parsing_done;
642
1.03k
    Iterator junk_begin = current;
643
1.03k
    ++current;
644
1.03k
    if (current == end) {
645
4
      if (allow_trailing_junk) {
646
4
        current = junk_begin;
647
4
        goto parsing_done;
648
4
      } else {
649
0
        return junk_string_value_;
650
0
      }
651
4
    }
652
1.03k
    char exponen_sign = '+';
653
1.03k
    if (*current == '+' || *current == '-') {
654
398
      exponen_sign = static_cast<char>(*current);
655
398
      ++current;
656
398
      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
398
    }
665
666
1.03k
    if (current == end || *current < '0' || *current > '9') {
667
20
      if (allow_trailing_junk) {
668
20
        current = junk_begin;
669
20
        goto parsing_done;
670
20
      } else {
671
0
        return junk_string_value_;
672
0
      }
673
20
    }
674
675
1.01k
    const int max_exponent = INT_MAX / 2;
676
1.01k
    DOUBLE_CONVERSION_ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
677
1.01k
    int num = 0;
678
7.78k
    do {
679
      // Check overflow.
680
7.78k
      int digit = *current - '0';
681
7.78k
      if (num >= max_exponent / 10
682
7.78k
          && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
683
3.89k
        num = max_exponent;
684
3.89k
      } else {
685
3.88k
        num = num * 10 + digit;
686
3.88k
      }
687
7.78k
      ++current;
688
7.78k
    } while (current != end && *current >= '0' && *current <= '9');
689
690
1.01k
    exponent += (exponen_sign == '-' ? -num : num);
691
1.01k
  }
692
693
1.11k
  if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
694
0
    return junk_string_value_;
695
0
  }
696
1.11k
  if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
697
0
    return junk_string_value_;
698
0
  }
699
1.11k
  if (allow_trailing_spaces) {
700
1.11k
    AdvanceToNonspace(&current, end);
701
1.11k
  }
702
703
2.21k
  parsing_done:
704
2.21k
  exponent += insignificant_digits;
705
706
2.21k
  if (octal) {
707
242
    double result;
708
242
    bool result_is_junk;
709
242
    char* start = buffer;
710
242
    result = RadixStringToIeee<3>(&start,
711
242
                                  buffer + buffer_pos,
712
242
                                  sign,
713
242
                                  separator_,
714
242
                                  false, // Don't parse as hex_float.
715
242
                                  allow_trailing_junk,
716
242
                                  junk_string_value_,
717
242
                                  read_as_double,
718
242
                                  &result_is_junk);
719
242
    DOUBLE_CONVERSION_ASSERT(!result_is_junk);
720
242
    *processed_characters_count = static_cast<int>(current - input);
721
242
    return result;
722
242
  }
723
724
1.97k
  if (nonzero_digit_dropped) {
725
28
    buffer[buffer_pos++] = '1';
726
28
    exponent--;
727
28
  }
728
729
1.97k
  DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize);
730
1.97k
  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.97k
  Vector<const char> chars(buffer, buffer_pos);
735
1.97k
  chars = TrimTrailingZeros(chars);
736
1.97k
  exponent += buffer_pos - chars.length();
737
738
1.97k
  double converted;
739
1.97k
  if (read_as_double) {
740
1.97k
    converted = StrtodTrimmed(chars, exponent);
741
1.97k
  } else {
742
0
    converted = StrtofTrimmed(chars, exponent);
743
0
  }
744
1.97k
  *processed_characters_count = static_cast<int>(current - input);
745
1.97k
  return sign? -converted: converted;
746
1.97k
}
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
3.09k
    int* processed_characters_count) const {
753
3.09k
  return StringToIeee(buffer, length, true, processed_characters_count);
754
3.09k
}
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