43 __pragma(warning(disable: 4244))
46# define VS2012_RADIXWARN
54inline char ToLower(char ch) {
55 static const std::ctype<char>& cType =
56 std::use_facet<std::ctype<char> >(std::locale::classic());
57 return cType.tolower(ch);
60inline char Pass(
char ch) {
64template <
class Iterator,
class Converter>
65static inline bool ConsumeSubStringImpl(Iterator* current,
67 const char* substring,
68 Converter converter) {
70 for (substring++; *substring !=
'\0'; substring++) {
72 if (*current ==
end ||
converter(**current) != *substring) {
82template <
class Iterator>
83static bool ConsumeSubString(Iterator* current,
85 const char* substring,
86 bool allow_case_insensitivity) {
87 if (allow_case_insensitivity) {
88 return ConsumeSubStringImpl(current,
end, substring, ToLower);
90 return ConsumeSubStringImpl(current,
end, substring, Pass);
95inline bool ConsumeFirstCharacter(
char ch,
97 bool case_insensitivity) {
98 return case_insensitivity ? ToLower(ch) == str[0] : ch == str[0];
117 160, 8232, 8233, 5760, 6158, 8192, 8193, 8194, 8195,
118 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 65279
138template <
class Iterator>
140 while (*current !=
end) {
149 return (
x >=
'0' &&
x <=
'9' &&
x <
'0' + radix)
150 || (radix > 10 &&
x >=
'a' &&
x <
'a' + radix - 10)
151 || (radix > 10 &&
x >=
'A' &&
x <
'A' + radix - 10);
156 return sign ? -0.0 : 0.0;
166#ifdef VS2012_RADIXWARN
167#pragma optimize("",off)
168static bool IsDecimalDigitForRadix(
int c,
int radix) {
169 return '0' <= c && c <=
'9' && (c -
'0') < radix;
171#pragma optimize("",on)
174 return '0' <= c && c <=
'9' && (c -
'0') < radix;
185 return radix > 10 && c >= a_character && c < a_character + radix - 10;
189template<
class Iterator>
191 if (separator == StringToDoubleConverter::kNoSeparator) {
200 if (*it ==
end)
return true;
201 if (*it + 1 ==
end)
return false;
202 if (**it == separator &&
isDigit(*(*it + 1),
base)) {
215template<
class Iterator>
219 bool allow_trailing_junk) {
222 Iterator current =
start;
224 bool saw_digit =
false;
225 while (
isDigit(*current, 16)) {
227 if (
Advance(¤t, separator, 16,
end))
return false;
229 if (*current ==
'.') {
230 if (
Advance(¤t, separator, 16,
end))
return false;
231 while (
isDigit(*current, 16)) {
233 if (
Advance(¤t, separator, 16,
end))
return false;
236 if (!saw_digit)
return false;
237 if (*current !=
'p' && *current !=
'P')
return false;
238 if (
Advance(¤t, separator, 16,
end))
return false;
239 if (*current ==
'+' || *current ==
'-') {
240 if (
Advance(¤t, separator, 16,
end))
return false;
242 if (!
isDigit(*current, 10))
return false;
243 if (
Advance(¤t, separator, 16,
end))
return true;
244 while (
isDigit(*current, 10)) {
245 if (
Advance(¤t, separator, 16,
end))
return true;
255template <
int radix_log_2,
class Iterator>
260 bool parse_as_hex_float,
261 bool allow_trailing_junk,
262 double junk_string_value,
264 bool* result_is_junk) {
269 const int kDoubleSize = Double::kSignificandSize;
270 const int kSingleSize = Single::kSignificandSize;
271 const int kSignificandSize = read_as_double? kDoubleSize: kSingleSize;
273 *result_is_junk =
true;
277 const int radix = (1 << radix_log_2);
280 bool post_decimal =
false;
283 while (**current ==
'0') {
284 if (
Advance(current, separator, radix,
end)) {
285 *result_is_junk =
false;
293 digit =
static_cast<char>(**current) -
'0';
294 if (post_decimal) exponent -= radix_log_2;
296 digit =
static_cast<char>(**current) -
'a' + 10;
297 if (post_decimal) exponent -= radix_log_2;
299 digit =
static_cast<char>(**current) -
'A' + 10;
300 if (post_decimal) exponent -= radix_log_2;
301 }
else if (parse_as_hex_float && **current ==
'.') {
306 }
else if (parse_as_hex_float && (**current ==
'p' || **current ==
'P')) {
312 return junk_string_value;
316 number = number * radix + digit;
317 int overflow =
static_cast<int>(number >> kSignificandSize);
321 int overflow_bits_count = 1;
322 while (overflow > 1) {
323 overflow_bits_count++;
327 int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
328 int dropped_bits =
static_cast<int>(number) & dropped_bits_mask;
329 number >>= overflow_bits_count;
330 exponent += overflow_bits_count;
332 bool zero_tail =
true;
334 if (
Advance(current, separator, radix,
end))
break;
335 if (parse_as_hex_float && **current ==
'.') {
342 if (!
isDigit(**current, radix))
break;
343 zero_tail = zero_tail && **current ==
'0';
344 if (!post_decimal) exponent += radix_log_2;
347 if (!parse_as_hex_float &&
348 !allow_trailing_junk &&
350 return junk_string_value;
353 int middle_value = (1 << (overflow_bits_count - 1));
354 if (dropped_bits > middle_value) {
356 }
else if (dropped_bits == middle_value) {
359 if ((number & 1) != 0 || !zero_tail) {
365 if ((number & ((int64_t)1 << kSignificandSize)) != 0) {
371 if (
Advance(current, separator, radix,
end))
break;
377 *result_is_junk =
false;
379 if (parse_as_hex_float) {
383 bool is_negative =
false;
384 if (**current ==
'+') {
387 }
else if (**current ==
'-') {
392 int written_exponent = 0;
396 if (abs(written_exponent) <= 100 * Double::kMaxExponent) {
397 written_exponent = 10 * written_exponent + **current -
'0';
399 if (
Advance(current, separator, radix,
end))
break;
401 if (is_negative) written_exponent = -written_exponent;
402 exponent += written_exponent;
405 if (exponent == 0 || number == 0) {
407 if (number == 0)
return -0.0;
410 return static_cast<double>(number);
418template <
class Iterator>
419double StringToDoubleConverter::StringToIeee(
423 int* processed_characters_count)
const {
424 Iterator current = input;
427 *processed_characters_count = 0;
429 const bool allow_trailing_junk = (flags_ & ALLOW_TRAILING_JUNK) != 0;
430 const bool allow_leading_spaces = (flags_ & ALLOW_LEADING_SPACES) != 0;
431 const bool allow_trailing_spaces = (flags_ & ALLOW_TRAILING_SPACES) != 0;
432 const bool allow_spaces_after_sign = (flags_ & ALLOW_SPACES_AFTER_SIGN) != 0;
433 const bool allow_case_insensitivity = (flags_ & ALLOW_CASE_INSENSITIVITY) != 0;
443 if (current ==
end)
return empty_string_value_;
445 if (allow_leading_spaces || allow_trailing_spaces) {
446 if (!AdvanceToNonspace(¤t,
end)) {
447 *processed_characters_count =
static_cast<int>(current - input);
448 return empty_string_value_;
450 if (!allow_leading_spaces && (input != current)) {
452 return junk_string_value_;
459 int significant_digits = 0;
460 int insignificant_digits = 0;
461 bool nonzero_digit_dropped =
false;
465 if (*current ==
'+' || *current ==
'-') {
466 sign = (*current ==
'-');
468 Iterator next_non_space = current;
471 if (!allow_spaces_after_sign && (current != next_non_space)) {
472 return junk_string_value_;
474 current = next_non_space;
478 if (ConsumeFirstCharacter(*current, infinity_symbol_, allow_case_insensitivity)) {
479 if (!ConsumeSubString(¤t,
end, infinity_symbol_, allow_case_insensitivity)) {
480 return junk_string_value_;
483 if (!(allow_trailing_spaces || allow_trailing_junk) && (current !=
end)) {
484 return junk_string_value_;
487 return junk_string_value_;
490 *processed_characters_count =
static_cast<int>(current - input);
491 return sign ? -Double::Infinity() : Double::Infinity();
496 if (ConsumeFirstCharacter(*current, nan_symbol_, allow_case_insensitivity)) {
497 if (!ConsumeSubString(¤t,
end, nan_symbol_, allow_case_insensitivity)) {
498 return junk_string_value_;
501 if (!(allow_trailing_spaces || allow_trailing_junk) && (current !=
end)) {
502 return junk_string_value_;
505 return junk_string_value_;
508 *processed_characters_count =
static_cast<int>(current - input);
509 return sign ? -Double::NaN() : Double::NaN();
513 bool leading_zero =
false;
514 if (*current ==
'0') {
516 *processed_characters_count =
static_cast<int>(current - input);
523 if (((flags_ & ALLOW_HEX) || (flags_ & ALLOW_HEX_FLOATS)) &&
524 (*current ==
'x' || *current ==
'X')) {
527 if (current ==
end)
return junk_string_value_;
529 bool parse_as_hex_float = (flags_ & ALLOW_HEX_FLOATS) &&
532 if (!parse_as_hex_float && !
isDigit(*current, 16)) {
533 return junk_string_value_;
537 double result = RadixStringToIeee<4>(¤t,
546 if (!result_is_junk) {
548 *processed_characters_count =
static_cast<int>(current - input);
554 while (*current ==
'0') {
556 *processed_characters_count =
static_cast<int>(current - input);
562 bool octal = leading_zero && (flags_ & ALLOW_OCTALS) != 0;
571 while (*current >=
'0' && *current <=
'9') {
572 if (significant_digits < kMaxSignificantDigits) {
574 buffer[buffer_pos++] =
static_cast<char>(*current);
575 significant_digits++;
578 insignificant_digits++;
579 nonzero_digit_dropped = nonzero_digit_dropped || *current !=
'0';
581 octal = octal && *current <
'8';
582 if (
Advance(¤t, separator_, 10,
end))
goto parsing_done;
585 if (significant_digits == 0) {
589 if (*current ==
'.') {
590 if (octal && !allow_trailing_junk)
return junk_string_value_;
591 if (octal)
goto parsing_done;
594 if (significant_digits == 0 && !leading_zero) {
595 return junk_string_value_;
601 if (significant_digits == 0) {
605 while (*current ==
'0') {
607 *processed_characters_count =
static_cast<int>(current - input);
616 while (*current >=
'0' && *current <=
'9') {
617 if (significant_digits < kMaxSignificantDigits) {
619 buffer[buffer_pos++] =
static_cast<char>(*current);
620 significant_digits++;
624 nonzero_digit_dropped = nonzero_digit_dropped || *current !=
'0';
626 if (
Advance(¤t, separator_, 10,
end))
goto parsing_done;
630 if (!leading_zero && exponent == 0 && significant_digits == 0) {
635 return junk_string_value_;
639 if (*current ==
'e' || *current ==
'E') {
640 if (octal && !allow_trailing_junk)
return junk_string_value_;
641 if (octal)
goto parsing_done;
642 Iterator junk_begin = current;
644 if (current ==
end) {
645 if (allow_trailing_junk) {
646 current = junk_begin;
649 return junk_string_value_;
652 char exponen_sign =
'+';
653 if (*current ==
'+' || *current ==
'-') {
654 exponen_sign =
static_cast<char>(*current);
656 if (current ==
end) {
657 if (allow_trailing_junk) {
658 current = junk_begin;
661 return junk_string_value_;
666 if (current ==
end || *current <
'0' || *current >
'9') {
667 if (allow_trailing_junk) {
668 current = junk_begin;
671 return junk_string_value_;
675 const int max_exponent = INT_MAX / 2;
680 int digit = *current -
'0';
681 if (num >= max_exponent / 10
682 && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
685 num = num * 10 + digit;
688 }
while (current !=
end && *current >=
'0' && *current <=
'9');
690 exponent += (exponen_sign ==
'-' ? -num : num);
693 if (!(allow_trailing_spaces || allow_trailing_junk) && (current !=
end)) {
694 return junk_string_value_;
697 return junk_string_value_;
699 if (allow_trailing_spaces) {
704 exponent += insignificant_digits;
720 *processed_characters_count =
static_cast<int>(current - input);
724 if (nonzero_digit_dropped) {
725 buffer[buffer_pos++] =
'1';
730 buffer[buffer_pos] =
'\0';
734 Vector<const char> chars(
buffer, buffer_pos);
736 exponent += buffer_pos - chars.length();
739 if (read_as_double) {
744 *processed_characters_count =
static_cast<int>(current - input);
745 return sign? -converted: converted;
749double StringToDoubleConverter::StringToDouble(
752 int* processed_characters_count)
const {
753 return StringToIeee(
buffer,
length,
true, processed_characters_count);
757double StringToDoubleConverter::StringToDouble(
760 int* processed_characters_count)
const {
761 return StringToIeee(
buffer,
length,
true, processed_characters_count);
765float StringToDoubleConverter::StringToFloat(
768 int* processed_characters_count)
const {
769 return static_cast<float>(StringToIeee(
buffer,
length,
false,
770 processed_characters_count));
774float StringToDoubleConverter::StringToFloat(
777 int* processed_characters_count)
const {
778 return static_cast<float>(StringToIeee(
buffer,
length,
false,
779 processed_characters_count));
784double StringToDoubleConverter::StringTo<double>(
787 int* processed_characters_count)
const {
788 return StringToDouble(
buffer,
length, processed_characters_count);
793float StringToDoubleConverter::StringTo<float>(
796 int* processed_characters_count)
const {
797 return StringToFloat(
buffer,
length, processed_characters_count);
802double StringToDoubleConverter::StringTo<double>(
805 int* processed_characters_count)
const {
806 return StringToDouble(
buffer,
length, processed_characters_count);
811float StringToDoubleConverter::StringTo<float>(
814 int* processed_characters_count)
const {
815 return StringToFloat(
buffer,
length, processed_characters_count);
static int sign(SkScalar x)
static const size_t kBufferSize
static const uint8_t buffer[]
static bool IsHexFloatString(Iterator start, Iterator end, uc16 separator, bool allow_trailing_junk)
static bool IsDecimalDigitForRadix(int c, int radix)
const int kMaxSignificantDigits
static bool Advance(Iterator *it, uc16 separator, int base, Iterator &end)
static bool IsCharacterDigitForRadix(int c, int radix, char a_character)
static const int kWhitespaceTable7Length
static double RadixStringToIeee(Iterator *current, Iterator end, bool sign, uc16 separator, bool parse_as_hex_float, bool allow_trailing_junk, double junk_string_value, bool read_as_double, bool *result_is_junk)
float StrtofTrimmed(Vector< const char > trimmed, int exponent)
static bool isWhitespace(int x)
static const int kWhitespaceTable16Length
double StrtodTrimmed(Vector< const char > trimmed, int exponent)
static bool isDigit(int x, int radix)
static const uc16 kWhitespaceTable16[]
static double SignedZero(bool sign)
Vector< const char > TrimTrailingZeros(Vector< const char > buffer)
static const char kWhitespaceTable7[]
static bool AdvanceToNonspace(Iterator *current, Iterator end)
#define DOUBLE_CONVERSION_NULLPTR
#define DOUBLE_CONVERSION_ASSERT(condition)
#define DOUBLE_CONVERSION_STACK_UNINITIALIZED
#define DOUBLE_CONVERSION_ARRAY_SIZE(a)