Coverage Report

Created: 2023-09-25 06:24

/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
5.91k
inline char ToLower(char ch) {
55
5.91k
  static const std::ctype<char>& cType =
56
5.91k
      std::use_facet<std::ctype<char> >(std::locale::classic());
57
5.91k
  return cType.tolower(ch);
58
5.91k
}
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
5.89k
                                         bool case_insensitivity) {
98
5.89k
  return case_insensitivity ? ToLower(ch) == str[0] : ch == str[0];
99
5.89k
}
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.73k
static bool isWhitespace(int x) {
124
5.73k
  if (x < 128) {
125
30.2k
    for (int i = 0; i < kWhitespaceTable7Length; i++) {
126
27.0k
      if (kWhitespaceTable7[i] == x) return true;
127
27.0k
    }
128
5.73k
  } else {
129
0
    for (int i = 0; i < kWhitespaceTable16Length; i++) {
130
0
      if (kWhitespaceTable16[i] == x) return true;
131
0
    }
132
0
  }
133
3.29k
  return false;
134
5.73k
}
135
136
137
// Returns true if a nonspace found and false if the end has reached.
138
template <class Iterator>
139
4.86k
static inline bool AdvanceToNonspace(Iterator* current, Iterator end) {
140
7.30k
  while (*current != end) {
141
5.73k
    if (!isWhitespace(**current)) return true;
142
2.44k
    ++*current;
143
2.44k
  }
144
1.56k
  return false;
145
4.86k
}
string-to-double.cc:bool double_conversion::AdvanceToNonspace<char const*>(char const**, char const*)
Line
Count
Source
139
4.86k
static inline bool AdvanceToNonspace(Iterator* current, Iterator end) {
140
7.30k
  while (*current != end) {
141
5.73k
    if (!isWhitespace(**current)) return true;
142
2.44k
    ++*current;
143
2.44k
  }
144
1.56k
  return false;
145
4.86k
}
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.50M
static bool isDigit(int x, int radix) {
149
7.50M
  return (x >= '0' && x <= '9' && x < '0' + radix)
150
7.50M
      || (radix > 10 && x >= 'a' && x < 'a' + radix - 10)
151
7.50M
      || (radix > 10 && x >= 'A' && x < 'A' + radix - 10);
152
7.50M
}
153
154
155
32
static double SignedZero(bool sign) {
156
32
  return sign ? -0.0 : 0.0;
157
32
}
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.43k
static bool IsCharacterDigitForRadix(int c, int radix, char a_character) {
185
4.43k
  return radix > 10 && c >= a_character && c < a_character + radix - 10;
186
4.43k
}
187
188
// Returns true, when the iterator is equal to end.
189
template<class Iterator>
190
13.5M
static bool Advance (Iterator* it, uc16 separator, int base, Iterator& end) {
191
13.5M
  if (separator == StringToDoubleConverter::kNoSeparator) {
192
13.5M
    ++(*it);
193
13.5M
    return *it == end;
194
13.5M
  }
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.5M
static bool Advance (Iterator* it, uc16 separator, int base, Iterator& end) {
191
13.5M
  if (separator == StringToDoubleConverter::kNoSeparator) {
192
13.5M
    ++(*it);
193
13.5M
    return *it == end;
194
13.5M
  }
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
8.91k
static bool Advance (Iterator* it, uc16 separator, int base, Iterator& end) {
191
8.91k
  if (separator == StringToDoubleConverter::kNoSeparator) {
192
8.91k
    ++(*it);
193
8.91k
    return *it == end;
194
8.91k
  }
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.02k
                             bool allow_trailing_junk) {
220
1.02k
  DOUBLE_CONVERSION_ASSERT(start != end);
221
222
0
  Iterator current = start;
223
224
1.02k
  bool saw_digit = false;
225
6.88k
  while (isDigit(*current, 16)) {
226
6.10k
    saw_digit = true;
227
6.10k
    if (Advance(&current, separator, 16, end)) return false;
228
6.10k
  }
229
786
  if (*current == '.') {
230
142
    if (Advance(&current, separator, 16, end)) return false;
231
7.48M
    while (isDigit(*current, 16)) {
232
7.48M
      saw_digit = true;
233
7.48M
      if (Advance(&current, separator, 16, end)) return false;
234
7.48M
    }
235
140
  }
236
769
  if (!saw_digit) return false;
237
709
  if (*current != 'p' && *current != 'P') return false;
238
609
  if (Advance(&current, separator, 16, end)) return false;
239
606
  if (*current == '+' || *current == '-') {
240
161
    if (Advance(&current, separator, 16, end)) return false;
241
161
  }
242
604
  if (!isDigit(*current, 10)) return false;
243
584
  if (Advance(&current, separator, 16, end)) return true;
244
2.45k
  while (isDigit(*current, 10)) {
245
2.40k
    if (Advance(&current, separator, 16, end)) return true;
246
2.40k
  }
247
56
  return allow_trailing_junk || !AdvanceToNonspace(&current, end);
248
354
}
string-to-double.cc:bool double_conversion::IsHexFloatString<char const*>(char const*, char const*, unsigned short, bool)
Line
Count
Source
219
1.02k
                             bool allow_trailing_junk) {
220
1.02k
  DOUBLE_CONVERSION_ASSERT(start != end);
221
222
0
  Iterator current = start;
223
224
1.02k
  bool saw_digit = false;
225
6.88k
  while (isDigit(*current, 16)) {
226
6.10k
    saw_digit = true;
227
6.10k
    if (Advance(&current, separator, 16, end)) return false;
228
6.10k
  }
229
786
  if (*current == '.') {
230
142
    if (Advance(&current, separator, 16, end)) return false;
231
7.48M
    while (isDigit(*current, 16)) {
232
7.48M
      saw_digit = true;
233
7.48M
      if (Advance(&current, separator, 16, end)) return false;
234
7.48M
    }
235
140
  }
236
769
  if (!saw_digit) return false;
237
709
  if (*current != 'p' && *current != 'P') return false;
238
609
  if (Advance(&current, separator, 16, end)) return false;
239
606
  if (*current == '+' || *current == '-') {
240
161
    if (Advance(&current, separator, 16, end)) return false;
241
161
  }
242
604
  if (!isDigit(*current, 10)) return false;
243
584
  if (Advance(&current, separator, 16, end)) return true;
244
2.45k
  while (isDigit(*current, 10)) {
245
2.40k
    if (Advance(&current, separator, 16, end)) return true;
246
2.40k
  }
247
56
  return allow_trailing_junk || !AdvanceToNonspace(&current, end);
248
354
}
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
862
                                bool* result_is_junk) {
265
862
  DOUBLE_CONVERSION_ASSERT(*current != end);
266
862
  DOUBLE_CONVERSION_ASSERT(!parse_as_hex_float ||
267
0
      IsHexFloatString(*current, end, separator, allow_trailing_junk));
268
269
0
  const int kDoubleSize = Double::kSignificandSize;
270
862
  const int kSingleSize = Single::kSignificandSize;
271
862
  const int kSignificandSize = read_as_double? kDoubleSize: kSingleSize;
272
273
862
  *result_is_junk = true;
274
275
862
  int64_t number = 0;
276
862
  int exponent = 0;
277
862
  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
862
  bool post_decimal = false;
281
282
  // Skip leading 0s.
283
1.34k
  while (**current == '0') {
284
486
    if (Advance(current, separator, radix, end)) {
285
8
      *result_is_junk = false;
286
8
      return SignedZero(sign);
287
8
    }
288
486
  }
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
1.08k
      digit = static_cast<char>(**current) - 'a' + 10;
297
1.08k
      if (post_decimal) exponent -= radix_log_2;
298
1.67k
    } else if (IsCharacterDigitForRadix(**current, radix, 'A')) {
299
1.27k
      digit = static_cast<char>(**current) - 'A' + 10;
300
1.27k
      if (post_decimal) exponent -= radix_log_2;
301
1.27k
    } else if (parse_as_hex_float && **current == '.') {
302
44
      post_decimal = true;
303
44
      Advance(current, separator, radix, end);
304
44
      DOUBLE_CONVERSION_ASSERT(*current != end);
305
0
      continue;
306
358
    } else if (parse_as_hex_float && (**current == 'p' || **current == 'P')) {
307
262
      break;
308
262
    } else {
309
96
      if (allow_trailing_junk || !AdvanceToNonspace(current, end)) {
310
96
        break;
311
96
      } else {
312
0
        return junk_string_value;
313
0
      }
314
96
    }
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
298
      int overflow_bits_count = 1;
322
578
      while (overflow > 1) {
323
280
        overflow_bits_count++;
324
280
        overflow >>= 1;
325
280
      }
326
327
298
      int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
328
298
      int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
329
298
      number >>= overflow_bits_count;
330
298
      exponent += overflow_bits_count;
331
332
298
      bool zero_tail = true;
333
7.74k
      for (;;) {
334
7.74k
        if (Advance(current, separator, radix, end)) break;
335
7.49k
        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
0
          post_decimal = true;
341
2
        }
342
7.49k
        if (!isDigit(**current, radix)) break;
343
7.44k
        zero_tail = zero_tail && **current == '0';
344
7.44k
        if (!post_decimal) exponent += radix_log_2;
345
7.44k
      }
346
347
298
      if (!parse_as_hex_float &&
348
298
          !allow_trailing_junk &&
349
298
          AdvanceToNonspace(current, end)) {
350
0
        return junk_string_value;
351
0
      }
352
353
298
      int middle_value = (1 << (overflow_bits_count - 1));
354
298
      if (dropped_bits > middle_value) {
355
64
        number++;  // Rounding up.
356
234
      } 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
63
          number++;  // Rounding up.
361
63
        }
362
83
      }
363
364
      // Rounding up may cause overflow.
365
298
      if ((number & ((int64_t)1 << kSignificandSize)) != 0) {
366
22
        exponent++;
367
22
        number >>= 1;
368
22
      }
369
298
      break;
370
298
    }
371
3.62M
    if (Advance(current, separator, radix, end)) break;
372
3.62M
  }
373
374
854
  DOUBLE_CONVERSION_ASSERT(number < ((int64_t)1 << kSignificandSize));
375
854
  DOUBLE_CONVERSION_ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
376
377
0
  *result_is_junk = false;
378
379
854
  if (parse_as_hex_float) {
380
292
    DOUBLE_CONVERSION_ASSERT(**current == 'p' || **current == 'P');
381
0
    Advance(current, separator, radix, end);
382
292
    DOUBLE_CONVERSION_ASSERT(*current != end);
383
0
    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
78
      is_negative = true;
389
78
      Advance(current, separator, radix, end);
390
78
      DOUBLE_CONVERSION_ASSERT(*current != end);
391
78
    }
392
0
    int written_exponent = 0;
393
1.52k
    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.49k
      if (abs(written_exponent) <= 100 * Double::kMaxExponent) {
397
1.04k
        written_exponent = 10 * written_exponent + **current - '0';
398
1.04k
      }
399
1.49k
      if (Advance(current, separator, radix, end)) break;
400
1.49k
    }
401
292
    if (is_negative) written_exponent = -written_exponent;
402
292
    exponent += written_exponent;
403
292
  }
404
405
854
  if (exponent == 0 || number == 0) {
406
323
    if (sign) {
407
74
      if (number == 0) return -0.0;
408
73
      number = -number;
409
73
    }
410
322
    return static_cast<double>(number);
411
323
  }
412
413
531
  DOUBLE_CONVERSION_ASSERT(number != 0);
414
0
  double result = Double(DiyFp(number, exponent)).value();
415
531
  return sign ? -result : result;
416
854
}
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
0
      IsHexFloatString(*current, end, separator, allow_trailing_junk));
268
269
0
  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.12k
  while (**current == '0') {
284
486
    if (Advance(current, separator, radix, end)) {
285
8
      *result_is_junk = false;
286
8
      return SignedZero(sign);
287
8
    }
288
486
  }
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
1.08k
      digit = static_cast<char>(**current) - 'a' + 10;
297
1.08k
      if (post_decimal) exponent -= radix_log_2;
298
1.67k
    } else if (IsCharacterDigitForRadix(**current, radix, 'A')) {
299
1.27k
      digit = static_cast<char>(**current) - 'A' + 10;
300
1.27k
      if (post_decimal) exponent -= radix_log_2;
301
1.27k
    } else if (parse_as_hex_float && **current == '.') {
302
44
      post_decimal = true;
303
44
      Advance(current, separator, radix, end);
304
44
      DOUBLE_CONVERSION_ASSERT(*current != end);
305
0
      continue;
306
358
    } else if (parse_as_hex_float && (**current == 'p' || **current == 'P')) {
307
262
      break;
308
262
    } else {
309
96
      if (allow_trailing_junk || !AdvanceToNonspace(current, end)) {
310
96
        break;
311
96
      } else {
312
0
        return junk_string_value;
313
0
      }
314
96
    }
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
154
      int overflow_bits_count = 1;
322
409
      while (overflow > 1) {
323
255
        overflow_bits_count++;
324
255
        overflow >>= 1;
325
255
      }
326
327
154
      int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
328
154
      int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
329
154
      number >>= overflow_bits_count;
330
154
      exponent += overflow_bits_count;
331
332
154
      bool zero_tail = true;
333
1.77k
      for (;;) {
334
1.77k
        if (Advance(current, separator, radix, end)) break;
335
1.67k
        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
0
          post_decimal = true;
341
2
        }
342
1.67k
        if (!isDigit(**current, radix)) break;
343
1.62k
        zero_tail = zero_tail && **current == '0';
344
1.62k
        if (!post_decimal) exponent += radix_log_2;
345
1.62k
      }
346
347
154
      if (!parse_as_hex_float &&
348
154
          !allow_trailing_junk &&
349
154
          AdvanceToNonspace(current, end)) {
350
0
        return junk_string_value;
351
0
      }
352
353
154
      int middle_value = (1 << (overflow_bits_count - 1));
354
154
      if (dropped_bits > middle_value) {
355
62
        number++;  // Rounding up.
356
92
      } 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
23
        if ((number & 1) != 0 || !zero_tail) {
360
18
          number++;  // Rounding up.
361
18
        }
362
23
      }
363
364
      // Rounding up may cause overflow.
365
154
      if ((number & ((int64_t)1 << kSignificandSize)) != 0) {
366
6
        exponent++;
367
6
        number >>= 1;
368
6
      }
369
154
      break;
370
154
    }
371
3.62M
    if (Advance(current, separator, radix, end)) break;
372
3.62M
  }
373
374
638
  DOUBLE_CONVERSION_ASSERT(number < ((int64_t)1 << kSignificandSize));
375
638
  DOUBLE_CONVERSION_ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
376
377
0
  *result_is_junk = false;
378
379
638
  if (parse_as_hex_float) {
380
292
    DOUBLE_CONVERSION_ASSERT(**current == 'p' || **current == 'P');
381
0
    Advance(current, separator, radix, end);
382
292
    DOUBLE_CONVERSION_ASSERT(*current != end);
383
0
    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
78
      is_negative = true;
389
78
      Advance(current, separator, radix, end);
390
78
      DOUBLE_CONVERSION_ASSERT(*current != end);
391
78
    }
392
0
    int written_exponent = 0;
393
1.52k
    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.49k
      if (abs(written_exponent) <= 100 * Double::kMaxExponent) {
397
1.04k
        written_exponent = 10 * written_exponent + **current - '0';
398
1.04k
      }
399
1.49k
      if (Advance(current, separator, radix, end)) break;
400
1.49k
    }
401
292
    if (is_negative) written_exponent = -written_exponent;
402
292
    exponent += written_exponent;
403
292
  }
404
405
638
  if (exponent == 0 || number == 0) {
406
251
    if (sign) {
407
54
      if (number == 0) return -0.0;
408
53
      number = -number;
409
53
    }
410
250
    return static_cast<double>(number);
411
251
  }
412
413
387
  DOUBLE_CONVERSION_ASSERT(number != 0);
414
0
  double result = Double(DiyFp(number, exponent)).value();
415
387
  return sign ? -result : result;
416
638
}
string-to-double.cc:double double_conversion::RadixStringToIeee<3, char*>(char**, char*, bool, unsigned short, bool, bool, double, bool, bool*)
Line
Count
Source
264
216
                                bool* result_is_junk) {
265
216
  DOUBLE_CONVERSION_ASSERT(*current != end);
266
216
  DOUBLE_CONVERSION_ASSERT(!parse_as_hex_float ||
267
0
      IsHexFloatString(*current, end, separator, allow_trailing_junk));
268
269
0
  const int kDoubleSize = Double::kSignificandSize;
270
216
  const int kSingleSize = Single::kSignificandSize;
271
216
  const int kSignificandSize = read_as_double? kDoubleSize: kSingleSize;
272
273
216
  *result_is_junk = true;
274
275
216
  int64_t number = 0;
276
216
  int exponent = 0;
277
216
  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
216
  bool post_decimal = false;
281
282
  // Skip leading 0s.
283
216
  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.09k
  while (true) {
291
3.09k
    int digit;
292
3.09k
    if (IsDecimalDigitForRadix(**current, radix)) {
293
3.09k
      digit = static_cast<char>(**current) - '0';
294
3.09k
      if (post_decimal) exponent -= radix_log_2;
295
3.09k
    } 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.09k
    number = number * radix + digit;
317
3.09k
    int overflow = static_cast<int>(number >> kSignificandSize);
318
3.09k
    if (overflow != 0) {
319
      // Overflow occurred. Need to determine which direction to round the
320
      // result.
321
144
      int overflow_bits_count = 1;
322
169
      while (overflow > 1) {
323
25
        overflow_bits_count++;
324
25
        overflow >>= 1;
325
25
      }
326
327
144
      int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
328
144
      int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
329
144
      number >>= overflow_bits_count;
330
144
      exponent += overflow_bits_count;
331
332
144
      bool zero_tail = true;
333
5.96k
      for (;;) {
334
5.96k
        if (Advance(current, separator, radix, end)) break;
335
5.82k
        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
5.82k
        if (!isDigit(**current, radix)) break;
343
5.82k
        zero_tail = zero_tail && **current == '0';
344
5.82k
        if (!post_decimal) exponent += radix_log_2;
345
5.82k
      }
346
347
144
      if (!parse_as_hex_float &&
348
144
          !allow_trailing_junk &&
349
144
          AdvanceToNonspace(current, end)) {
350
0
        return junk_string_value;
351
0
      }
352
353
144
      int middle_value = (1 << (overflow_bits_count - 1));
354
144
      if (dropped_bits > middle_value) {
355
2
        number++;  // Rounding up.
356
142
      } 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
60
        if ((number & 1) != 0 || !zero_tail) {
360
45
          number++;  // Rounding up.
361
45
        }
362
60
      }
363
364
      // Rounding up may cause overflow.
365
144
      if ((number & ((int64_t)1 << kSignificandSize)) != 0) {
366
16
        exponent++;
367
16
        number >>= 1;
368
16
      }
369
144
      break;
370
144
    }
371
2.95k
    if (Advance(current, separator, radix, end)) break;
372
2.95k
  }
373
374
216
  DOUBLE_CONVERSION_ASSERT(number < ((int64_t)1 << kSignificandSize));
375
216
  DOUBLE_CONVERSION_ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
376
377
0
  *result_is_junk = false;
378
379
216
  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
216
  if (exponent == 0 || number == 0) {
406
72
    if (sign) {
407
20
      if (number == 0) return -0.0;
408
20
      number = -number;
409
20
    }
410
72
    return static_cast<double>(number);
411
72
  }
412
413
144
  DOUBLE_CONVERSION_ASSERT(number != 0);
414
0
  double result = Double(DiyFp(number, exponent)).value();
415
144
  return sign ? -result : result;
416
216
}
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.00k
    int* processed_characters_count) const {
424
3.00k
  Iterator current = input;
425
3.00k
  Iterator end = input + length;
426
427
3.00k
  *processed_characters_count = 0;
428
429
3.00k
  const bool allow_trailing_junk = (flags_ & ALLOW_TRAILING_JUNK) != 0;
430
3.00k
  const bool allow_leading_spaces = (flags_ & ALLOW_LEADING_SPACES) != 0;
431
3.00k
  const bool allow_trailing_spaces = (flags_ & ALLOW_TRAILING_SPACES) != 0;
432
3.00k
  const bool allow_spaces_after_sign = (flags_ & ALLOW_SPACES_AFTER_SIGN) != 0;
433
3.00k
  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.00k
  if (current == end) return empty_string_value_;
444
445
3.00k
  if (allow_leading_spaces || allow_trailing_spaces) {
446
3.00k
    if (!AdvanceToNonspace(&current, end)) {
447
25
      *processed_characters_count = static_cast<int>(current - input);
448
25
      return empty_string_value_;
449
25
    }
450
2.97k
    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.97k
  }
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.97k
  int exponent = 0;
459
2.97k
  int significant_digits = 0;
460
2.97k
  int insignificant_digits = 0;
461
2.97k
  bool nonzero_digit_dropped = false;
462
463
2.97k
  bool sign = false;
464
465
2.97k
  if (*current == '+' || *current == '-') {
466
119
    sign = (*current == '-');
467
119
    ++current;
468
119
    Iterator next_non_space = current;
469
    // Skip following spaces (if allowed).
470
119
    if (!AdvanceToNonspace(&next_non_space, end)) return junk_string_value_;
471
93
    if (!allow_spaces_after_sign && (current != next_non_space)) {
472
0
      return junk_string_value_;
473
0
    }
474
93
    current = next_non_space;
475
93
  }
476
477
2.94k
  if (infinity_symbol_ != DOUBLE_CONVERSION_NULLPTR) {
478
2.94k
    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.94k
  }
494
495
2.94k
  if (nan_symbol_ != DOUBLE_CONVERSION_NULLPTR) {
496
2.94k
    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
2.94k
  }
512
513
2.94k
  bool leading_zero = false;
514
2.94k
  if (*current == '0') {
515
1.02k
    if (Advance(&current, separator_, 10, end)) {
516
2
      *processed_characters_count = static_cast<int>(current - input);
517
2
      return SignedZero(sign);
518
2
    }
519
520
1.02k
    leading_zero = true;
521
522
    // It could be hexadecimal value.
523
1.02k
    if (((flags_ & ALLOW_HEX) || (flags_ & ALLOW_HEX_FLOATS)) &&
524
1.02k
        (*current == 'x' || *current == 'X')) {
525
731
      ++current;
526
527
731
      if (current == end) return junk_string_value_;  // "0x"
528
529
729
      bool parse_as_hex_float = (flags_ & ALLOW_HEX_FLOATS) &&
530
729
                IsHexFloatString(current, end, separator_, allow_trailing_junk);
531
532
729
      if (!parse_as_hex_float && !isDigit(*current, 16)) {
533
83
        return junk_string_value_;
534
83
      }
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
729
    }
552
553
    // Ignore leading zeros in the integer part.
554
669
    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
289
  }
561
562
2.20k
  bool octal = leading_zero && (flags_ & ALLOW_OCTALS) != 0;
563
564
  // The longest form of simplified number is: "-<significant digits>.1eXXX\0".
565
2.20k
  const int kBufferSize = kMaxSignificantDigits + 10;
566
2.20k
  DOUBLE_CONVERSION_STACK_UNINITIALIZED char
567
2.20k
      buffer[kBufferSize];  // NOLINT: size is known at compile time.
568
2.20k
  int buffer_pos = 0;
569
570
  // Copy significant digits of the integer part (if any) to the buffer.
571
74.6k
  while (*current >= '0' && *current <= '9') {
572
73.2k
    if (significant_digits < kMaxSignificantDigits) {
573
72.8k
      DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize);
574
0
      buffer[buffer_pos++] = static_cast<char>(*current);
575
72.8k
      significant_digits++;
576
      // Will later check if it's an octal in the buffer.
577
72.8k
    } else {
578
396
      insignificant_digits++;  // Move the digit into the exponential part.
579
396
      nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
580
396
    }
581
73.2k
    octal = octal && *current < '8';
582
73.2k
    if (Advance(&current, separator_, 10, end)) goto parsing_done;
583
73.2k
  }
584
585
1.45k
  if (significant_digits == 0) {
586
278
    octal = false;
587
278
  }
588
589
1.45k
  if (*current == '.') {
590
344
    if (octal && !allow_trailing_junk) return junk_string_value_;
591
344
    if (octal) goto parsing_done;
592
593
343
    if (Advance(&current, separator_, 10, end)) {
594
3
      if (significant_digits == 0 && !leading_zero) {
595
1
        return junk_string_value_;
596
2
      } else {
597
2
        goto parsing_done;
598
2
      }
599
3
    }
600
601
340
    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.28M
      while (*current == '0') {
606
2.28M
        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.28M
        exponent--;  // Move this 0 into the exponent.
611
2.28M
      }
612
155
    }
613
614
    // There is a fractional part.
615
    // We don't emit a '.', but adjust the exponent instead.
616
59.7k
    while (*current >= '0' && *current <= '9') {
617
59.6k
      if (significant_digits < kMaxSignificantDigits) {
618
58.6k
        DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize);
619
0
        buffer[buffer_pos++] = static_cast<char>(*current);
620
58.6k
        significant_digits++;
621
58.6k
        exponent--;
622
58.6k
      } else {
623
        // Ignore insignificant digits in the fractional part.
624
1.00k
        nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
625
1.00k
      }
626
59.6k
      if (Advance(&current, separator_, 10, end)) goto parsing_done;
627
59.6k
    }
628
326
  }
629
630
1.21k
  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
80
    return junk_string_value_;
636
80
  }
637
638
  // Parse exponential part.
639
1.13k
  if (*current == 'e' || *current == 'E') {
640
1.02k
    if (octal && !allow_trailing_junk) return junk_string_value_;
641
1.02k
    if (octal) goto parsing_done;
642
1.01k
    Iterator junk_begin = current;
643
1.01k
    ++current;
644
1.01k
    if (current == end) {
645
10
      if (allow_trailing_junk) {
646
10
        current = junk_begin;
647
10
        goto parsing_done;
648
10
      } else {
649
0
        return junk_string_value_;
650
0
      }
651
10
    }
652
1.00k
    char exponen_sign = '+';
653
1.00k
    if (*current == '+' || *current == '-') {
654
394
      exponen_sign = static_cast<char>(*current);
655
394
      ++current;
656
394
      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
394
    }
665
666
1.00k
    if (current == end || *current < '0' || *current > '9') {
667
23
      if (allow_trailing_junk) {
668
23
        current = junk_begin;
669
23
        goto parsing_done;
670
23
      } else {
671
0
        return junk_string_value_;
672
0
      }
673
23
    }
674
675
984
    const int max_exponent = INT_MAX / 2;
676
984
    DOUBLE_CONVERSION_ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
677
0
    int num = 0;
678
3.42k
    do {
679
      // Check overflow.
680
3.42k
      int digit = *current - '0';
681
3.42k
      if (num >= max_exponent / 10
682
3.42k
          && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
683
233
        num = max_exponent;
684
3.19k
      } else {
685
3.19k
        num = num * 10 + digit;
686
3.19k
      }
687
3.42k
      ++current;
688
3.42k
    } while (current != end && *current >= '0' && *current <= '9');
689
690
984
    exponent += (exponen_sign == '-' ? -num : num);
691
984
  }
692
693
1.09k
  if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
694
0
    return junk_string_value_;
695
0
  }
696
1.09k
  if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
697
0
    return junk_string_value_;
698
0
  }
699
1.09k
  if (allow_trailing_spaces) {
700
1.09k
    AdvanceToNonspace(&current, end);
701
1.09k
  }
702
703
2.10k
  parsing_done:
704
2.10k
  exponent += insignificant_digits;
705
706
2.10k
  if (octal) {
707
216
    double result;
708
216
    bool result_is_junk;
709
216
    char* start = buffer;
710
216
    result = RadixStringToIeee<3>(&start,
711
216
                                  buffer + buffer_pos,
712
216
                                  sign,
713
216
                                  separator_,
714
216
                                  false, // Don't parse as hex_float.
715
216
                                  allow_trailing_junk,
716
216
                                  junk_string_value_,
717
216
                                  read_as_double,
718
216
                                  &result_is_junk);
719
216
    DOUBLE_CONVERSION_ASSERT(!result_is_junk);
720
0
    *processed_characters_count = static_cast<int>(current - input);
721
216
    return result;
722
216
  }
723
724
1.88k
  if (nonzero_digit_dropped) {
725
24
    buffer[buffer_pos++] = '1';
726
24
    exponent--;
727
24
  }
728
729
1.88k
  DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize);
730
0
  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.88k
  Vector<const char> chars(buffer, buffer_pos);
735
1.88k
  chars = TrimTrailingZeros(chars);
736
1.88k
  exponent += buffer_pos - chars.length();
737
738
1.88k
  double converted;
739
1.88k
  if (read_as_double) {
740
1.88k
    converted = StrtodTrimmed(chars, exponent);
741
1.88k
  } else {
742
0
    converted = StrtofTrimmed(chars, exponent);
743
0
  }
744
1.88k
  *processed_characters_count = static_cast<int>(current - input);
745
1.88k
  return sign? -converted: converted;
746
2.10k
}
double double_conversion::StringToDoubleConverter::StringToIeee<char const*>(char const*, int, bool, int*) const
Line
Count
Source
423
3.00k
    int* processed_characters_count) const {
424
3.00k
  Iterator current = input;
425
3.00k
  Iterator end = input + length;
426
427
3.00k
  *processed_characters_count = 0;
428
429
3.00k
  const bool allow_trailing_junk = (flags_ & ALLOW_TRAILING_JUNK) != 0;
430
3.00k
  const bool allow_leading_spaces = (flags_ & ALLOW_LEADING_SPACES) != 0;
431
3.00k
  const bool allow_trailing_spaces = (flags_ & ALLOW_TRAILING_SPACES) != 0;
432
3.00k
  const bool allow_spaces_after_sign = (flags_ & ALLOW_SPACES_AFTER_SIGN) != 0;
433
3.00k
  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.00k
  if (current == end) return empty_string_value_;
444
445
3.00k
  if (allow_leading_spaces || allow_trailing_spaces) {
446
3.00k
    if (!AdvanceToNonspace(&current, end)) {
447
25
      *processed_characters_count = static_cast<int>(current - input);
448
25
      return empty_string_value_;
449
25
    }
450
2.97k
    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.97k
  }
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.97k
  int exponent = 0;
459
2.97k
  int significant_digits = 0;
460
2.97k
  int insignificant_digits = 0;
461
2.97k
  bool nonzero_digit_dropped = false;
462
463
2.97k
  bool sign = false;
464
465
2.97k
  if (*current == '+' || *current == '-') {
466
119
    sign = (*current == '-');
467
119
    ++current;
468
119
    Iterator next_non_space = current;
469
    // Skip following spaces (if allowed).
470
119
    if (!AdvanceToNonspace(&next_non_space, end)) return junk_string_value_;
471
93
    if (!allow_spaces_after_sign && (current != next_non_space)) {
472
0
      return junk_string_value_;
473
0
    }
474
93
    current = next_non_space;
475
93
  }
476
477
2.94k
  if (infinity_symbol_ != DOUBLE_CONVERSION_NULLPTR) {
478
2.94k
    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.94k
  }
494
495
2.94k
  if (nan_symbol_ != DOUBLE_CONVERSION_NULLPTR) {
496
2.94k
    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
2.94k
  }
512
513
2.94k
  bool leading_zero = false;
514
2.94k
  if (*current == '0') {
515
1.02k
    if (Advance(&current, separator_, 10, end)) {
516
2
      *processed_characters_count = static_cast<int>(current - input);
517
2
      return SignedZero(sign);
518
2
    }
519
520
1.02k
    leading_zero = true;
521
522
    // It could be hexadecimal value.
523
1.02k
    if (((flags_ & ALLOW_HEX) || (flags_ & ALLOW_HEX_FLOATS)) &&
524
1.02k
        (*current == 'x' || *current == 'X')) {
525
731
      ++current;
526
527
731
      if (current == end) return junk_string_value_;  // "0x"
528
529
729
      bool parse_as_hex_float = (flags_ & ALLOW_HEX_FLOATS) &&
530
729
                IsHexFloatString(current, end, separator_, allow_trailing_junk);
531
532
729
      if (!parse_as_hex_float && !isDigit(*current, 16)) {
533
83
        return junk_string_value_;
534
83
      }
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
729
    }
552
553
    // Ignore leading zeros in the integer part.
554
669
    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
289
  }
561
562
2.20k
  bool octal = leading_zero && (flags_ & ALLOW_OCTALS) != 0;
563
564
  // The longest form of simplified number is: "-<significant digits>.1eXXX\0".
565
2.20k
  const int kBufferSize = kMaxSignificantDigits + 10;
566
2.20k
  DOUBLE_CONVERSION_STACK_UNINITIALIZED char
567
2.20k
      buffer[kBufferSize];  // NOLINT: size is known at compile time.
568
2.20k
  int buffer_pos = 0;
569
570
  // Copy significant digits of the integer part (if any) to the buffer.
571
74.6k
  while (*current >= '0' && *current <= '9') {
572
73.2k
    if (significant_digits < kMaxSignificantDigits) {
573
72.8k
      DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize);
574
0
      buffer[buffer_pos++] = static_cast<char>(*current);
575
72.8k
      significant_digits++;
576
      // Will later check if it's an octal in the buffer.
577
72.8k
    } else {
578
396
      insignificant_digits++;  // Move the digit into the exponential part.
579
396
      nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
580
396
    }
581
73.2k
    octal = octal && *current < '8';
582
73.2k
    if (Advance(&current, separator_, 10, end)) goto parsing_done;
583
73.2k
  }
584
585
1.45k
  if (significant_digits == 0) {
586
278
    octal = false;
587
278
  }
588
589
1.45k
  if (*current == '.') {
590
344
    if (octal && !allow_trailing_junk) return junk_string_value_;
591
344
    if (octal) goto parsing_done;
592
593
343
    if (Advance(&current, separator_, 10, end)) {
594
3
      if (significant_digits == 0 && !leading_zero) {
595
1
        return junk_string_value_;
596
2
      } else {
597
2
        goto parsing_done;
598
2
      }
599
3
    }
600
601
340
    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.28M
      while (*current == '0') {
606
2.28M
        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.28M
        exponent--;  // Move this 0 into the exponent.
611
2.28M
      }
612
155
    }
613
614
    // There is a fractional part.
615
    // We don't emit a '.', but adjust the exponent instead.
616
59.7k
    while (*current >= '0' && *current <= '9') {
617
59.6k
      if (significant_digits < kMaxSignificantDigits) {
618
58.6k
        DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize);
619
0
        buffer[buffer_pos++] = static_cast<char>(*current);
620
58.6k
        significant_digits++;
621
58.6k
        exponent--;
622
58.6k
      } else {
623
        // Ignore insignificant digits in the fractional part.
624
1.00k
        nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
625
1.00k
      }
626
59.6k
      if (Advance(&current, separator_, 10, end)) goto parsing_done;
627
59.6k
    }
628
326
  }
629
630
1.21k
  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
80
    return junk_string_value_;
636
80
  }
637
638
  // Parse exponential part.
639
1.13k
  if (*current == 'e' || *current == 'E') {
640
1.02k
    if (octal && !allow_trailing_junk) return junk_string_value_;
641
1.02k
    if (octal) goto parsing_done;
642
1.01k
    Iterator junk_begin = current;
643
1.01k
    ++current;
644
1.01k
    if (current == end) {
645
10
      if (allow_trailing_junk) {
646
10
        current = junk_begin;
647
10
        goto parsing_done;
648
10
      } else {
649
0
        return junk_string_value_;
650
0
      }
651
10
    }
652
1.00k
    char exponen_sign = '+';
653
1.00k
    if (*current == '+' || *current == '-') {
654
394
      exponen_sign = static_cast<char>(*current);
655
394
      ++current;
656
394
      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
394
    }
665
666
1.00k
    if (current == end || *current < '0' || *current > '9') {
667
23
      if (allow_trailing_junk) {
668
23
        current = junk_begin;
669
23
        goto parsing_done;
670
23
      } else {
671
0
        return junk_string_value_;
672
0
      }
673
23
    }
674
675
984
    const int max_exponent = INT_MAX / 2;
676
984
    DOUBLE_CONVERSION_ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
677
0
    int num = 0;
678
3.42k
    do {
679
      // Check overflow.
680
3.42k
      int digit = *current - '0';
681
3.42k
      if (num >= max_exponent / 10
682
3.42k
          && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
683
233
        num = max_exponent;
684
3.19k
      } else {
685
3.19k
        num = num * 10 + digit;
686
3.19k
      }
687
3.42k
      ++current;
688
3.42k
    } while (current != end && *current >= '0' && *current <= '9');
689
690
984
    exponent += (exponen_sign == '-' ? -num : num);
691
984
  }
692
693
1.09k
  if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
694
0
    return junk_string_value_;
695
0
  }
696
1.09k
  if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
697
0
    return junk_string_value_;
698
0
  }
699
1.09k
  if (allow_trailing_spaces) {
700
1.09k
    AdvanceToNonspace(&current, end);
701
1.09k
  }
702
703
2.10k
  parsing_done:
704
2.10k
  exponent += insignificant_digits;
705
706
2.10k
  if (octal) {
707
216
    double result;
708
216
    bool result_is_junk;
709
216
    char* start = buffer;
710
216
    result = RadixStringToIeee<3>(&start,
711
216
                                  buffer + buffer_pos,
712
216
                                  sign,
713
216
                                  separator_,
714
216
                                  false, // Don't parse as hex_float.
715
216
                                  allow_trailing_junk,
716
216
                                  junk_string_value_,
717
216
                                  read_as_double,
718
216
                                  &result_is_junk);
719
216
    DOUBLE_CONVERSION_ASSERT(!result_is_junk);
720
0
    *processed_characters_count = static_cast<int>(current - input);
721
216
    return result;
722
216
  }
723
724
1.88k
  if (nonzero_digit_dropped) {
725
24
    buffer[buffer_pos++] = '1';
726
24
    exponent--;
727
24
  }
728
729
1.88k
  DOUBLE_CONVERSION_ASSERT(buffer_pos < kBufferSize);
730
0
  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.88k
  Vector<const char> chars(buffer, buffer_pos);
735
1.88k
  chars = TrimTrailingZeros(chars);
736
1.88k
  exponent += buffer_pos - chars.length();
737
738
1.88k
  double converted;
739
1.88k
  if (read_as_double) {
740
1.88k
    converted = StrtodTrimmed(chars, exponent);
741
1.88k
  } else {
742
0
    converted = StrtofTrimmed(chars, exponent);
743
0
  }
744
1.88k
  *processed_characters_count = static_cast<int>(current - input);
745
1.88k
  return sign? -converted: converted;
746
2.10k
}
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.00k
    int* processed_characters_count) const {
753
3.00k
  return StringToIeee(buffer, length, true, processed_characters_count);
754
3.00k
}
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