| 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;
|
| }
|
|
|
|
|