summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-18 00:14:28 +0000
committertc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-18 00:14:28 +0000
commit6dce8adece39efbb9ae73aa12ca82d88d98da577 (patch)
treebe636abf2c134ecba3ce7d89f8d90192f5e8987b
parentb2e01376481b16129cb33f31e931cde9a9cdbb88 (diff)
downloadchromium_src-6dce8adece39efbb9ae73aa12ca82d88d98da577.zip
chromium_src-6dce8adece39efbb9ae73aa12ca82d88d98da577.tar.gz
chromium_src-6dce8adece39efbb9ae73aa12ca82d88d98da577.tar.bz2
Remove the locale parameter from the StringToDouble and
DoubleToString methods and only leave the locale independent methods. It turns out this code is only used in the json code and if people want locale formatting, they should use ICU. Review URL: http://codereview.chromium.org/11423 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@5585 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/json_reader.cc3
-rw-r--r--base/json_reader_unittest.cc7
-rw-r--r--base/json_writer.cc2
-rw-r--r--base/string_util.cc164
-rw-r--r--base/string_util.h30
-rw-r--r--base/third_party/dmg_fp/dmg_fp.h3
6 files changed, 78 insertions, 131 deletions
diff --git a/base/json_reader.cc b/base/json_reader.cc
index 15d43cc..c0e019b 100644
--- a/base/json_reader.cc
+++ b/base/json_reader.cc
@@ -329,8 +329,7 @@ bool JSONReader::DecodeNumber(const Token& token, Value** node) {
}
double num_double;
- if (base::StringToDouble(num_string, &num_double, base::LOCALE_INDEPENDENT) &&
- base::IsFinite(num_double)) {
+ if (StringToDouble(num_string, &num_double) && base::IsFinite(num_double)) {
*node = Value::CreateRealValue(num_double);
return true;
}
diff --git a/base/json_reader_unittest.cc b/base/json_reader_unittest.cc
index 4339be1..ebc7062 100644
--- a/base/json_reader_unittest.cc
+++ b/base/json_reader_unittest.cc
@@ -183,6 +183,12 @@ TEST(JSONReaderTest, Reading) {
root = NULL;
ASSERT_FALSE(JSONReader::JsonToValue("NaN", &root, false, false));
ASSERT_FALSE(root);
+ root = NULL;
+ ASSERT_FALSE(JSONReader::JsonToValue("nan", &root, false, false));
+ ASSERT_FALSE(root);
+ root = NULL;
+ ASSERT_FALSE(JSONReader::JsonToValue("inf", &root, false, false));
+ ASSERT_FALSE(root);
// Invalid number formats
root = NULL;
@@ -495,4 +501,3 @@ TEST(JSONReaderTest, Reading) {
ASSERT_FALSE(JSONReader::Read("10", &root, false));
ASSERT_FALSE(JSONReader::Read("\"root\"", &root, false));
}
-
diff --git a/base/json_writer.cc b/base/json_writer.cc
index 4782eb55b..0da2925 100644
--- a/base/json_writer.cc
+++ b/base/json_writer.cc
@@ -58,7 +58,7 @@ void JSONWriter::BuildJSONString(const Value* const node, int depth) {
double value;
bool result = node->GetAsReal(&value);
DCHECK(result);
- std::string real = base::DoubleToString(value, base::LOCALE_INDEPENDENT);
+ std::string real = DoubleToString(value);
// Ensure that the number has a .0 if there's no decimal or 'e'. This
// makes sure that when we read the JSON back, it's interpreted as a
// real rather than an int.
diff --git a/base/string_util.cc b/base/string_util.cc
index 4cc67d7..b77a7fe 100644
--- a/base/string_util.cc
+++ b/base/string_util.cc
@@ -89,14 +89,13 @@ static bool CompareParameter(const ReplacementOffset& elem1,
// should check for leading whitespace.
template<typename StringToNumberTraits>
bool StringToNumber(const typename StringToNumberTraits::string_type& input,
- typename StringToNumberTraits::value_type* output,
- base::LocaleDependence locale_dependent) {
+ typename StringToNumberTraits::value_type* output) {
typedef StringToNumberTraits traits;
errno = 0; // Thread-safe? It is on at least Mac, Linux, and Windows.
typename traits::string_type::value_type* endptr = NULL;
typename traits::value_type value = traits::convert_func(input.c_str(),
- &endptr, locale_dependent == base::LOCALE_DEPENDENT);
+ &endptr);
*output = value;
// Cases to return false:
@@ -120,8 +119,7 @@ class StringToLongTraits {
typedef long value_type;
static const int kBase = 10;
static inline value_type convert_func(const string_type::value_type* str,
- string_type::value_type** endptr,
- bool locale_dependent) {
+ string_type::value_type** endptr) {
return strtol(str, endptr, kBase);
}
static inline bool valid_func(const string_type& str) {
@@ -135,8 +133,7 @@ class WStringToLongTraits {
typedef long value_type;
static const int kBase = 10;
static inline value_type convert_func(const string_type::value_type* str,
- string_type::value_type** endptr,
- bool locale_dependent) {
+ string_type::value_type** endptr) {
return wcstol(str, endptr, kBase);
}
static inline bool valid_func(const string_type& str) {
@@ -150,8 +147,7 @@ class StringToInt64Traits {
typedef int64 value_type;
static const int kBase = 10;
static inline value_type convert_func(const string_type::value_type* str,
- string_type::value_type** endptr,
- bool locale_dependent) {
+ string_type::value_type** endptr) {
#ifdef OS_WIN
return _strtoi64(str, endptr, kBase);
#else // assume OS_POSIX
@@ -169,8 +165,7 @@ class WStringToInt64Traits {
typedef int64 value_type;
static const int kBase = 10;
static inline value_type convert_func(const string_type::value_type* str,
- string_type::value_type** endptr,
- bool locale_dependent) {
+ string_type::value_type** endptr) {
#ifdef OS_WIN
return _wcstoi64(str, endptr, kBase);
#else // assume OS_POSIX
@@ -191,8 +186,7 @@ class HexStringToLongTraits {
typedef long value_type;
static const int kBase = 16;
static inline value_type convert_func(const string_type::value_type* str,
- string_type::value_type** endptr,
- bool locale_dependent) {
+ string_type::value_type** endptr) {
return strtoul(str, endptr, kBase);
}
static inline bool valid_func(const string_type& str) {
@@ -206,8 +200,7 @@ class HexWStringToLongTraits {
typedef long value_type;
static const int kBase = 16;
static inline value_type convert_func(const string_type::value_type* str,
- string_type::value_type** endptr,
- bool locale_dependent) {
+ string_type::value_type** endptr) {
return wcstoul(str, endptr, kBase);
}
static inline bool valid_func(const string_type& str) {
@@ -220,13 +213,8 @@ class StringToDoubleTraits {
typedef std::string string_type;
typedef double value_type;
static inline value_type convert_func(const string_type::value_type* str,
- string_type::value_type** endptr,
- bool locale_dependent) {
- if (locale_dependent) {
- return strtod(str, endptr);
- } else {
- return dmg_fp::strtod(str, endptr);
- }
+ string_type::value_type** endptr) {
+ return dmg_fp::strtod(str, endptr);
}
static inline bool valid_func(const string_type& str) {
return !str.empty() && !isspace(str[0]);
@@ -238,25 +226,20 @@ class WStringToDoubleTraits {
typedef std::wstring string_type;
typedef double value_type;
static inline value_type convert_func(const string_type::value_type* str,
- string_type::value_type** endptr,
- bool locale_dependent) {
- if (locale_dependent) {
- return wcstod(str, endptr);
- } else {
- // Because dmg_fp::strtod does not like wchar_t, we convert it to ASCII.
- // In theory, this should be safe, but it's possible that wide chars
- // might get ignored by accident causing something to be parsed when it
- // shouldn't.
- std::string ascii_string = WideToASCII(std::wstring(str));
- char* ascii_end = NULL;
- value_type ret = dmg_fp::strtod(ascii_string.c_str(), &ascii_end);
- if (ascii_string.c_str() + ascii_string.length() == ascii_end) {
- // Put endptr at end of input string, so it's not recognized as an error.
- *endptr = const_cast<string_type::value_type*>(str) + wcslen(str);
- }
-
- return ret;
+ string_type::value_type** endptr) {
+ // Because dmg_fp::strtod does not like wchar_t, we convert it to ASCII.
+ // In theory, this should be safe, but it's possible that wide chars
+ // might get ignored by accident causing something to be parsed when it
+ // shouldn't.
+ std::string ascii_string = WideToASCII(std::wstring(str));
+ char* ascii_end = NULL;
+ value_type ret = dmg_fp::strtod(ascii_string.c_str(), &ascii_end);
+ if (ascii_string.c_str() + ascii_string.length() == ascii_end) {
+ // Put endptr at end of input string, so it's not recognized as an error.
+ *endptr = const_cast<string_type::value_type*>(str) + wcslen(str);
}
+
+ return ret;
}
static inline bool valid_func(const string_type& str) {
return !str.empty() && !iswspace(str[0]);
@@ -305,45 +288,6 @@ bool IsWprintfFormatPortable(const wchar_t* format) {
return true;
}
-std::string DoubleToString(double value, LocaleDependence locale_dependent) {
- if (LOCALE_DEPENDENT == locale_dependent) {
- return StringPrintf("%g", value);
- } else {
- char buffer[32];
- dmg_fp::g_fmt(buffer, value);
- return std::string(buffer);
- }
-}
-
-std::wstring DoubleToWString(double value, LocaleDependence locale_dependent) {
- return ASCIIToWide(DoubleToString(value, locale_dependent));
-}
-
-bool StringToDouble(const std::string& input, double* output,
- LocaleDependence locale_dependent) {
- return StringToNumber<StringToDoubleTraits>(input, output,
- locale_dependent);
-}
-
-bool StringToDouble(const std::wstring& input, double* output,
- LocaleDependence locale_dependent) {
- return StringToNumber<WStringToDoubleTraits>(input, output,
- locale_dependent);
-}
-
-double StringToDouble(const std::string& value,
- LocaleDependence locale_dependent) {
- double result;
- StringToDouble(value, &result, locale_dependent);
- return result;
-}
-
-double StringToDouble(const std::wstring& value,
- LocaleDependence locale_dependent) {
- double result;
- StringToDouble(value, &result, locale_dependent);
- return result;
-}
} // namespace base
@@ -1054,6 +998,17 @@ std::wstring Uint64ToWString(uint64 value) {
IntToString(value);
}
+std::string DoubleToString(double value) {
+ // According to g_fmt.cc, it is sufficient to declare a buffer of size 32.
+ char buffer[32];
+ dmg_fp::g_fmt(buffer, value);
+ return std::string(buffer);
+}
+
+std::wstring DoubleToWString(double value) {
+ return ASCIIToWide(DoubleToString(value));
+}
+
inline void StringAppendV(std::string* dst, const char* format, va_list ap) {
StringAppendVT<char>(dst, format, ap);
}
@@ -1064,22 +1019,6 @@ inline void StringAppendV(std::wstring* dst,
StringAppendVT<wchar_t>(dst, format, ap);
}
-bool StringToDouble(const std::string& input, double* output) {
- return StringToDouble(input, output, base::LOCALE_DEPENDENT);
-}
-
-bool StringToDouble(const std::wstring& input, double* output) {
- return StringToDouble(input, output, base::LOCALE_DEPENDENT);
-}
-
-double StringToDouble(const std::string& value) {
- return StringToDouble(value, base::LOCALE_DEPENDENT);
-}
-
-double StringToDouble(const std::wstring& value) {
- return StringToDouble(value, base::LOCALE_DEPENDENT);
-}
-
std::string StringPrintf(const char* format, ...) {
va_list ap;
va_start(ap, format);
@@ -1419,36 +1358,33 @@ bool MatchPattern(const std::string& eval, const std::string& pattern) {
bool StringToInt(const std::string& input, int* output) {
COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int);
return StringToNumber<StringToLongTraits>(input,
- reinterpret_cast<long*>(output),
- base::LOCALE_DEPENDENT);
+ reinterpret_cast<long*>(output));
}
bool StringToInt(const std::wstring& input, int* output) {
COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int);
return StringToNumber<WStringToLongTraits>(input,
- reinterpret_cast<long*>(output),
- base::LOCALE_DEPENDENT);
+ reinterpret_cast<long*>(output));
}
bool StringToInt64(const std::string& input, int64* output) {
- return StringToNumber<StringToInt64Traits>(input, output, base::LOCALE_DEPENDENT);
+ return StringToNumber<StringToInt64Traits>(input, output);
}
bool StringToInt64(const std::wstring& input, int64* output) {
- return StringToNumber<WStringToInt64Traits>(input, output, base::LOCALE_DEPENDENT);
+ return StringToNumber<WStringToInt64Traits>(input, output);
}
bool HexStringToInt(const std::string& input, int* output) {
COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int);
return StringToNumber<HexStringToLongTraits>(input,
- reinterpret_cast<long*>(output),
- base::LOCALE_DEPENDENT);
+ reinterpret_cast<long*>(output));
}
bool HexStringToInt(const std::wstring& input, int* output) {
COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int);
return StringToNumber<HexWStringToLongTraits>(
- input, reinterpret_cast<long*>(output), base::LOCALE_DEPENDENT);
+ input, reinterpret_cast<long*>(output));
}
int StringToInt(const std::string& value) {
@@ -1487,6 +1423,26 @@ int HexStringToInt(const std::wstring& value) {
return result;
}
+bool StringToDouble(const std::string& input, double* output) {
+ return StringToNumber<StringToDoubleTraits>(input, output);
+}
+
+bool StringToDouble(const std::wstring& input, double* output) {
+ return StringToNumber<WStringToDoubleTraits>(input, output);
+}
+
+double StringToDouble(const std::string& value) {
+ double result;
+ StringToDouble(value, &result);
+ return result;
+}
+
+double StringToDouble(const std::wstring& value) {
+ double result;
+ StringToDouble(value, &result);
+ return result;
+}
+
// The following code is compatible with the OpenBSD lcpy interface. See:
// http://www.gratisoft.us/todd/papers/strlcpy.html
// ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/{wcs,str}lcpy.c
diff --git a/base/string_util.h b/base/string_util.h
index 488d4a2..71c4991 100644
--- a/base/string_util.h
+++ b/base/string_util.h
@@ -95,23 +95,6 @@ size_t wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size);
// This function is intended to be called from base::vswprintf.
bool IsWprintfFormatPortable(const wchar_t* format);
-enum LocaleDependence {
- LOCALE_DEPENDENT,
- LOCALE_INDEPENDENT
-};
-
-std::string DoubleToString(double value, LocaleDependence locale_dependent);
-std::wstring DoubleToWString(double value, LocaleDependence locale_dependent);
-
-bool StringToDouble(const std::string& input, double* output,
- LocaleDependence locale_dependent);
-bool StringToDouble(const std::wstring& input, double* output,
- LocaleDependence locale_dependent);
-double StringToDouble(const std::string& value,
- LocaleDependence locale_dependent);
-double StringToDouble(const std::wstring& value,
- LocaleDependence locale_dependent);
-
} // namespace base
#if defined(OS_WIN)
@@ -370,7 +353,10 @@ std::string Int64ToString(int64 value);
std::wstring Int64ToWString(int64 value);
std::string Uint64ToString(uint64 value);
std::wstring Uint64ToWString(uint64 value);
-
+// The DoubleToString methods convert the double to a string format that
+// ignores the locale. If you want to use locale specific formatting, use ICU.
+std::string DoubleToString(double value);
+std::wstring DoubleToWString(double value);
// Perform a best-effort conversion of the input string to a numeric type,
// setting |*output| to the result of the conversion. Returns true for
@@ -391,9 +377,10 @@ bool HexStringToInt(const std::wstring& input, int* output);
// For floating-point conversions, only conversions of input strings in decimal
// form are defined to work. Behavior with strings representing floating-point
-// numbers in hexadecimal, and strings representing non-fininte values (such
-// as NaN and inf) is undefined. Otherwise, these behave the same as the
-// integral variants above. By default, locale-dependent variant is used.
+// numbers in hexadecimal, and strings representing non-fininte values (such as
+// NaN and inf) is undefined. Otherwise, these behave the same as the integral
+// variants. This expects the input string to NOT be specific to the locale.
+// If your input is locale specific, use ICU to read the number.
bool StringToDouble(const std::string& input, double* output);
bool StringToDouble(const std::wstring& input, double* output);
@@ -406,7 +393,6 @@ int64 StringToInt64(const std::string& value);
int64 StringToInt64(const std::wstring& value);
int HexStringToInt(const std::string& value);
int HexStringToInt(const std::wstring& value);
-// By default, locale-dependent variant is used.
double StringToDouble(const std::string& value);
double StringToDouble(const std::wstring& value);
diff --git a/base/third_party/dmg_fp/dmg_fp.h b/base/third_party/dmg_fp/dmg_fp.h
index 21c7c97..4795397 100644
--- a/base/third_party/dmg_fp/dmg_fp.h
+++ b/base/third_party/dmg_fp/dmg_fp.h
@@ -21,7 +21,8 @@ char* dtoa(double d, int mode, int ndigits,
// Must be used to free values returned by dtoa.
void freedtoa(char* s);
-// Store the closest decimal approximation to x in b.
+// Store the closest decimal approximation to x in b (null terminated).
+// Returns a pointer to b. It is sufficient for |b| to be 32 characters.
char* g_fmt(char* b, double x);
} // namespace dmg_fp