Index: base/string_util.cc |
=================================================================== |
--- base/string_util.cc (revision 5165) |
+++ base/string_util.cc (working copy) |
@@ -4,6 +4,8 @@ |
#include "base/string_util.h" |
+#include "build/build_config.h" |
+ |
#include <ctype.h> |
#include <errno.h> |
#include <math.h> |
@@ -21,6 +23,7 @@ |
#include "base/basictypes.h" |
#include "base/logging.h" |
#include "base/singleton.h" |
+#include "third_party/dmg_fp/dmg_fp.h" |
namespace { |
@@ -86,13 +89,15 @@ |
// should check for leading whitespace. |
template<typename StringToNumberTraits> |
bool StringToNumber(const typename StringToNumberTraits::string_type& input, |
- typename StringToNumberTraits::value_type* output) { |
+ typename StringToNumberTraits::value_type* output, |
+ LocaleDependence locale_dependent) { |
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); |
+ &endptr, |
+ locale_dependent); |
*output = value; |
// Cases to return false: |
@@ -116,7 +121,8 @@ |
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) { |
+ string_type::value_type** endptr, |
+ bool locale_dependent) { |
return strtol(str, endptr, kBase); |
} |
static inline bool valid_func(const string_type& str) { |
@@ -130,7 +136,8 @@ |
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) { |
+ string_type::value_type** endptr, |
+ bool locale_dependent) { |
return wcstol(str, endptr, kBase); |
} |
static inline bool valid_func(const string_type& str) { |
@@ -144,7 +151,8 @@ |
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) { |
+ string_type::value_type** endptr, |
+ bool locale_dependent) { |
#ifdef OS_WIN |
return _strtoi64(str, endptr, kBase); |
#else // assume OS_POSIX |
@@ -162,7 +170,8 @@ |
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) { |
+ string_type::value_type** endptr, |
+ bool locale_dependent) { |
#ifdef OS_WIN |
return _wcstoi64(str, endptr, kBase); |
#else // assume OS_POSIX |
@@ -183,7 +192,8 @@ |
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) { |
+ string_type::value_type** endptr, |
+ bool locale_dependent) { |
return strtoul(str, endptr, kBase); |
} |
static inline bool valid_func(const string_type& str) { |
@@ -197,7 +207,8 @@ |
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) { |
+ string_type::value_type** endptr, |
+ bool locale_dependent) { |
return wcstoul(str, endptr, kBase); |
} |
static inline bool valid_func(const string_type& str) { |
@@ -210,8 +221,13 @@ |
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) { |
- return strtod(str, endptr); |
+ string_type::value_type** endptr, |
+ bool locale_dependent) { |
+ if (locale_dependent) { |
+ return strtod(str, endptr); |
+ } else { |
+ return dmg_fp::strtod(str, endptr); |
+ } |
} |
static inline bool valid_func(const string_type& str) { |
return !str.empty() && !isspace(str[0]); |
@@ -223,8 +239,21 @@ |
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) { |
- return wcstod(str, endptr); |
+ string_type::value_type** endptr, |
+ bool locale_dependent) { |
+ if (locale_dependent) { |
+ return wcstod(str, endptr); |
+ } else { |
+ // We are going to do some interesting things here, just because |
+ // dmg_fp::strtod does not like wchar_t. Converting to ASCII should |
+ // be fine. |
+ |
+ // 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); |
+ |
+ std::string ascii_string = WideToASCII(std::wstring(str)); |
+ return StringToDouble(ascii_string, LOCALE_INDEPENDENT); |
+ } |
} |
static inline bool valid_func(const string_type& str) { |
return !str.empty() && !iswspace(str[0]); |
@@ -982,6 +1011,20 @@ |
IntToString(value); |
} |
+std::string DoubleToString(double value, LocaleDependence locale_dependent) { |
+ if (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)); |
+} |
+ |
inline void StringAppendV(std::string* dst, const char* format, va_list ap) { |
StringAppendVT<char>(dst, format, ap); |
} |
@@ -992,6 +1035,22 @@ |
StringAppendVT<wchar_t>(dst, format, ap); |
} |
+bool StringToDouble(const std::string& input, double* output) { |
+ return StringToDouble(input, output, LOCALE_DEPENDENT); |
+} |
+ |
+bool StringToDouble(const std::wstring& input, double* output) { |
+ return StringToDouble(input, output, LOCALE_DEPENDENT); |
+} |
+ |
+double StringToDouble(const std::string& value) { |
+ return StringToDouble(value, LOCALE_DEPENDENT); |
+} |
+ |
+double StringToDouble(const std::wstring& value) { |
+ return StringToDouble(value, LOCALE_DEPENDENT); |
+} |
+ |
std::string StringPrintf(const char* format, ...) { |
va_list ap; |
va_start(ap, format); |
@@ -1331,41 +1390,48 @@ |
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)); |
+ reinterpret_cast<long*>(output), |
+ LOCALE_DEPENDENT); |
} |
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)); |
+ reinterpret_cast<long*>(output), |
+ LOCALE_DEPENDENT); |
} |
bool StringToInt64(const std::string& input, int64* output) { |
- return StringToNumber<StringToInt64Traits>(input, output); |
+ return StringToNumber<StringToInt64Traits>(input, output, LOCALE_DEPENDENT); |
} |
bool StringToInt64(const std::wstring& input, int64* output) { |
- return StringToNumber<WStringToInt64Traits>(input, output); |
+ return StringToNumber<WStringToInt64Traits>(input, output, LOCALE_DEPENDENT); |
} |
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)); |
+ reinterpret_cast<long*>(output), |
+ LOCALE_DEPENDENT); |
} |
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)); |
+ input, reinterpret_cast<long*>(output), LOCALE_DEPENDENT); |
} |
-bool StringToDouble(const std::string& input, double* output) { |
- return StringToNumber<StringToDoubleTraits>(input, output); |
+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) { |
- return StringToNumber<WStringToDoubleTraits>(input, output); |
+bool StringToDouble(const std::wstring& input, double* output, |
+ LocaleDependence locale_dependent) { |
+ return StringToNumber<WStringToDoubleTraits>(input, output, |
+ locale_dependent); |
} |
int StringToInt(const std::string& value) { |
@@ -1404,15 +1470,17 @@ |
return result; |
} |
-double StringToDouble(const std::string& value) { |
+double StringToDouble(const std::string& value, |
+ LocaleDependence locale_dependent) { |
double result; |
- StringToDouble(value, &result); |
+ StringToDouble(value, &result, locale_dependent); |
return result; |
} |
-double StringToDouble(const std::wstring& value) { |
+double StringToDouble(const std::wstring& value, |
+ LocaleDependence locale_dependent) { |
double result; |
- StringToDouble(value, &result); |
+ StringToDouble(value, &result, locale_dependent); |
return result; |
} |