1*635a8641SAndroid Build Coastguard Worker# Libchrome does not support/require dmg_fp library. Instead, use standard 2*635a8641SAndroid Build Coastguard Worker# library. 3*635a8641SAndroid Build Coastguard Worker 4*635a8641SAndroid Build Coastguard Worker--- a/base/strings/string_number_conversions.cc 5*635a8641SAndroid Build Coastguard Worker+++ b/base/strings/string_number_conversions.cc 6*635a8641SAndroid Build Coastguard Worker@@ -16,7 +16,6 @@ 7*635a8641SAndroid Build Coastguard Worker #include "base/numerics/safe_math.h" 8*635a8641SAndroid Build Coastguard Worker #include "base/scoped_clear_errno.h" 9*635a8641SAndroid Build Coastguard Worker #include "base/strings/utf_string_conversions.h" 10*635a8641SAndroid Build Coastguard Worker-#include "base/third_party/dmg_fp/dmg_fp.h" 11*635a8641SAndroid Build Coastguard Worker 12*635a8641SAndroid Build Coastguard Worker namespace base { 13*635a8641SAndroid Build Coastguard Worker 14*635a8641SAndroid Build Coastguard Worker@@ -361,20 +360,35 @@ string16 NumberToString16(unsigned long long value) { 15*635a8641SAndroid Build Coastguard Worker } 16*635a8641SAndroid Build Coastguard Worker 17*635a8641SAndroid Build Coastguard Worker std::string NumberToString(double value) { 18*635a8641SAndroid Build Coastguard Worker- // According to g_fmt.cc, it is sufficient to declare a buffer of size 32. 19*635a8641SAndroid Build Coastguard Worker- char buffer[32]; 20*635a8641SAndroid Build Coastguard Worker- dmg_fp::g_fmt(buffer, value); 21*635a8641SAndroid Build Coastguard Worker- return std::string(buffer); 22*635a8641SAndroid Build Coastguard Worker+ auto ret = std::to_string(value); 23*635a8641SAndroid Build Coastguard Worker+ // If this returned an integer, don't do anything. 24*635a8641SAndroid Build Coastguard Worker+ if (ret.find('.') == std::string::npos) { 25*635a8641SAndroid Build Coastguard Worker+ return ret; 26*635a8641SAndroid Build Coastguard Worker+ } 27*635a8641SAndroid Build Coastguard Worker+ // Otherwise, it has an annoying tendency to leave trailing zeros. 28*635a8641SAndroid Build Coastguard Worker+ size_t len = ret.size(); 29*635a8641SAndroid Build Coastguard Worker+ while (len >= 2 && ret[len - 1] == '0' && ret[len - 2] != '.') { 30*635a8641SAndroid Build Coastguard Worker+ --len; 31*635a8641SAndroid Build Coastguard Worker+ } 32*635a8641SAndroid Build Coastguard Worker+ ret.erase(len); 33*635a8641SAndroid Build Coastguard Worker+ return ret; 34*635a8641SAndroid Build Coastguard Worker } 35*635a8641SAndroid Build Coastguard Worker 36*635a8641SAndroid Build Coastguard Worker base::string16 NumberToString16(double value) { 37*635a8641SAndroid Build Coastguard Worker- // According to g_fmt.cc, it is sufficient to declare a buffer of size 32. 38*635a8641SAndroid Build Coastguard Worker- char buffer[32]; 39*635a8641SAndroid Build Coastguard Worker- dmg_fp::g_fmt(buffer, value); 40*635a8641SAndroid Build Coastguard Worker+ auto tmp = std::to_string(value); 41*635a8641SAndroid Build Coastguard Worker+ base::string16 ret(tmp.c_str(), tmp.c_str() + tmp.length()); 42*635a8641SAndroid Build Coastguard Worker 43*635a8641SAndroid Build Coastguard Worker- // The number will be ASCII. This creates the string using the "input 44*635a8641SAndroid Build Coastguard Worker- // iterator" variant which promotes from 8-bit to 16-bit via "=". 45*635a8641SAndroid Build Coastguard Worker- return base::string16(&buffer[0], &buffer[strlen(buffer)]); 46*635a8641SAndroid Build Coastguard Worker+ // If this returned an integer, don't do anything. 47*635a8641SAndroid Build Coastguard Worker+ if (ret.find('.') == std::string::npos) { 48*635a8641SAndroid Build Coastguard Worker+ return ret; 49*635a8641SAndroid Build Coastguard Worker+ } 50*635a8641SAndroid Build Coastguard Worker+ // Otherwise, it has an annoying tendency to leave trailing zeros. 51*635a8641SAndroid Build Coastguard Worker+ size_t len = ret.size(); 52*635a8641SAndroid Build Coastguard Worker+ while (len >= 2 && ret[len - 1] == '0' && ret[len - 2] != '.') { 53*635a8641SAndroid Build Coastguard Worker+ --len; 54*635a8641SAndroid Build Coastguard Worker+ } 55*635a8641SAndroid Build Coastguard Worker+ ret.erase(len); 56*635a8641SAndroid Build Coastguard Worker+ return ret; 57*635a8641SAndroid Build Coastguard Worker } 58*635a8641SAndroid Build Coastguard Worker 59*635a8641SAndroid Build Coastguard Worker bool StringToInt(StringPiece input, int* output) { 60*635a8641SAndroid Build Coastguard Worker@@ -418,14 +432,10 @@ bool StringToSizeT(StringPiece16 input, size_t* output) { 61*635a8641SAndroid Build Coastguard Worker } 62*635a8641SAndroid Build Coastguard Worker 63*635a8641SAndroid Build Coastguard Worker bool StringToDouble(const std::string& input, double* output) { 64*635a8641SAndroid Build Coastguard Worker- // Thread-safe? It is on at least Mac, Linux, and Windows. 65*635a8641SAndroid Build Coastguard Worker- ScopedClearErrno clear_errno; 66*635a8641SAndroid Build Coastguard Worker- 67*635a8641SAndroid Build Coastguard Worker char* endptr = nullptr; 68*635a8641SAndroid Build Coastguard Worker- *output = dmg_fp::strtod(input.c_str(), &endptr); 69*635a8641SAndroid Build Coastguard Worker+ *output = strtod(input.c_str(), &endptr); 70*635a8641SAndroid Build Coastguard Worker 71*635a8641SAndroid Build Coastguard Worker // Cases to return false: 72*635a8641SAndroid Build Coastguard Worker- // - If errno is ERANGE, there was an overflow or underflow. 73*635a8641SAndroid Build Coastguard Worker // - If the input string is empty, there was nothing to parse. 74*635a8641SAndroid Build Coastguard Worker // - If endptr does not point to the end of the string, there are either 75*635a8641SAndroid Build Coastguard Worker // characters remaining in the string after a parsed number, or the string 76*635a8641SAndroid Build Coastguard Worker@@ -433,10 +443,11 @@ bool StringToDouble(const std::string& input, double* output) { 77*635a8641SAndroid Build Coastguard Worker // expected end given the string's stated length to correctly catch cases 78*635a8641SAndroid Build Coastguard Worker // where the string contains embedded NUL characters. 79*635a8641SAndroid Build Coastguard Worker // - If the first character is a space, there was leading whitespace 80*635a8641SAndroid Build Coastguard Worker- return errno == 0 && 81*635a8641SAndroid Build Coastguard Worker- !input.empty() && 82*635a8641SAndroid Build Coastguard Worker+ return !input.empty() && 83*635a8641SAndroid Build Coastguard Worker input.c_str() + input.length() == endptr && 84*635a8641SAndroid Build Coastguard Worker- !isspace(input[0]); 85*635a8641SAndroid Build Coastguard Worker+ !isspace(input[0]) && 86*635a8641SAndroid Build Coastguard Worker+ *output != std::numeric_limits<double>::infinity() && 87*635a8641SAndroid Build Coastguard Worker+ *output != -std::numeric_limits<double>::infinity(); 88*635a8641SAndroid Build Coastguard Worker } 89*635a8641SAndroid Build Coastguard Worker 90*635a8641SAndroid Build Coastguard Worker // Note: if you need to add String16ToDouble, first ask yourself if it's 91*635a8641SAndroid Build Coastguard Worker--- a/base/strings/string_number_conversions_unittest.cc 92*635a8641SAndroid Build Coastguard Worker+++ b/base/strings/string_number_conversions_unittest.cc 93*635a8641SAndroid Build Coastguard Worker@@ -754,20 +754,8 @@ TEST(StringNumberConversionsTest, StringToDouble) { 94*635a8641SAndroid Build Coastguard Worker {"9e999", HUGE_VAL, false}, 95*635a8641SAndroid Build Coastguard Worker {"9e1999", HUGE_VAL, false}, 96*635a8641SAndroid Build Coastguard Worker {"9e19999", HUGE_VAL, false}, 97*635a8641SAndroid Build Coastguard Worker- {"9e99999999999999999999", HUGE_VAL, false}, 98*635a8641SAndroid Build Coastguard Worker- {"-9e307", -9e307, true}, 99*635a8641SAndroid Build Coastguard Worker- {"-1.7976e308", -1.7976e308, true}, 100*635a8641SAndroid Build Coastguard Worker- {"-1.7977e308", -HUGE_VAL, false}, 101*635a8641SAndroid Build Coastguard Worker- {"-1.797693134862315807e+308", -HUGE_VAL, true}, 102*635a8641SAndroid Build Coastguard Worker- {"-1.797693134862315808e+308", -HUGE_VAL, false}, 103*635a8641SAndroid Build Coastguard Worker- {"-9e308", -HUGE_VAL, false}, 104*635a8641SAndroid Build Coastguard Worker- {"-9e309", -HUGE_VAL, false}, 105*635a8641SAndroid Build Coastguard Worker- {"-9e999", -HUGE_VAL, false}, 106*635a8641SAndroid Build Coastguard Worker- {"-9e1999", -HUGE_VAL, false}, 107*635a8641SAndroid Build Coastguard Worker- {"-9e19999", -HUGE_VAL, false}, 108*635a8641SAndroid Build Coastguard Worker- {"-9e99999999999999999999", -HUGE_VAL, false}, 109*635a8641SAndroid Build Coastguard Worker- 110*635a8641SAndroid Build Coastguard Worker- // Test more exponents. 111*635a8641SAndroid Build Coastguard Worker+ {"9e99999999999999999999", std::numeric_limits<double>::infinity(), false}, 112*635a8641SAndroid Build Coastguard Worker+ {"-9e99999999999999999999", -std::numeric_limits<double>::infinity(), false}, 113*635a8641SAndroid Build Coastguard Worker {"1e-2", 0.01, true}, 114*635a8641SAndroid Build Coastguard Worker {"42 ", 42.0, false}, 115*635a8641SAndroid Build Coastguard Worker {" 1e-2", 0.01, false}, 116*635a8641SAndroid Build Coastguard Worker@@ -797,7 +785,8 @@ TEST(StringNumberConversionsTest, StringToDouble) { 117*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < arraysize(cases); ++i) { 118*635a8641SAndroid Build Coastguard Worker double output; 119*635a8641SAndroid Build Coastguard Worker errno = 1; 120*635a8641SAndroid Build Coastguard Worker- EXPECT_EQ(cases[i].success, StringToDouble(cases[i].input, &output)); 121*635a8641SAndroid Build Coastguard Worker+ EXPECT_EQ(cases[i].success, StringToDouble(cases[i].input, &output)) 122*635a8641SAndroid Build Coastguard Worker+ << "for input=" << cases[i].input << "got output=" << output; 123*635a8641SAndroid Build Coastguard Worker if (cases[i].success) 124*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1, errno) << i; // confirm that errno is unchanged. 125*635a8641SAndroid Build Coastguard Worker EXPECT_DOUBLE_EQ(cases[i].output, output); 126*635a8641SAndroid Build Coastguard Worker@@ -818,13 +807,13 @@ TEST(StringNumberConversionsTest, DoubleToString) { 127*635a8641SAndroid Build Coastguard Worker double input; 128*635a8641SAndroid Build Coastguard Worker const char* expected; 129*635a8641SAndroid Build Coastguard Worker } cases[] = { 130*635a8641SAndroid Build Coastguard Worker- {0.0, "0"}, 131*635a8641SAndroid Build Coastguard Worker+ {0.0, "0.0"}, 132*635a8641SAndroid Build Coastguard Worker {1.25, "1.25"}, 133*635a8641SAndroid Build Coastguard Worker- {1.33518e+012, "1.33518e+12"}, 134*635a8641SAndroid Build Coastguard Worker- {1.33489e+012, "1.33489e+12"}, 135*635a8641SAndroid Build Coastguard Worker- {1.33505e+012, "1.33505e+12"}, 136*635a8641SAndroid Build Coastguard Worker- {1.33545e+009, "1335450000"}, 137*635a8641SAndroid Build Coastguard Worker- {1.33503e+009, "1335030000"}, 138*635a8641SAndroid Build Coastguard Worker+ {1.33518e+012, "1335180000000.0"}, 139*635a8641SAndroid Build Coastguard Worker+ {1.33489e+012, "1334890000000.0"}, 140*635a8641SAndroid Build Coastguard Worker+ {1.33505e+012, "1335050000000.0"}, 141*635a8641SAndroid Build Coastguard Worker+ {1.33545e+009, "1335450000.0"}, 142*635a8641SAndroid Build Coastguard Worker+ {1.33503e+009, "1335030000.0"}, 143*635a8641SAndroid Build Coastguard Worker }; 144*635a8641SAndroid Build Coastguard Worker 145*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < arraysize(cases); ++i) { 146*635a8641SAndroid Build Coastguard Worker@@ -836,12 +825,12 @@ TEST(StringNumberConversionsTest, DoubleToString) { 147*635a8641SAndroid Build Coastguard Worker const char input_bytes[8] = {0, 0, 0, 0, '\xee', '\x6d', '\x73', '\x42'}; 148*635a8641SAndroid Build Coastguard Worker double input = 0; 149*635a8641SAndroid Build Coastguard Worker memcpy(&input, input_bytes, arraysize(input_bytes)); 150*635a8641SAndroid Build Coastguard Worker- EXPECT_EQ("1335179083776", NumberToString(input)); 151*635a8641SAndroid Build Coastguard Worker+ EXPECT_EQ("1335179083776.0", NumberToString(input)); 152*635a8641SAndroid Build Coastguard Worker const char input_bytes2[8] = 153*635a8641SAndroid Build Coastguard Worker {0, 0, 0, '\xa0', '\xda', '\x6c', '\x73', '\x42'}; 154*635a8641SAndroid Build Coastguard Worker input = 0; 155*635a8641SAndroid Build Coastguard Worker memcpy(&input, input_bytes2, arraysize(input_bytes2)); 156*635a8641SAndroid Build Coastguard Worker- EXPECT_EQ("1334890332160", NumberToString(input)); 157*635a8641SAndroid Build Coastguard Worker+ EXPECT_EQ("1334890332160.0", NumberToString(input)); 158*635a8641SAndroid Build Coastguard Worker } 159*635a8641SAndroid Build Coastguard Worker 160*635a8641SAndroid Build Coastguard Worker TEST(StringNumberConversionsTest, HexEncode) { 161