Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(707)

Unified Diff: base/string_util.cc

Issue 159510: Rewrite StringToInt traits for dealing with non-32-bit longs. (Closed)
Patch Set: Created 11 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/string_util.cc
diff --git a/base/string_util.cc b/base/string_util.cc
index 2f20d780e9b3fa48a958e0b7a70eaef8a1283f85..b456376ee4460d10de3ecfb45fbdbb112a504fa5 100644
--- a/base/string_util.cc
+++ b/base/string_util.cc
@@ -94,24 +94,53 @@ bool StringToNumber(const typename StringToNumberTraits::string_type& input,
traits::valid_func(input);
}
-class StringToLongTraits {
+static int strtoi(const char *nptr, char **endptr, int base) {
+ long res = strtol(nptr, endptr, base);
+#if __LP64__
+ // Long is 64-bits, we have to handle under/overflow ourselves.
+ if (res > kint32max) {
+ res = kint32max;
+ errno = ERANGE;
+ } else if (res < kint32min) {
+ res = kint32min;
+ errno = ERANGE;
+ }
+#endif
+ return static_cast<int>(res);
+}
+
+static unsigned int strtoui(const char *nptr, char **endptr, int base) {
+ unsigned long res = strtoul(nptr, endptr, base);
+#if __LP64__
+ // Long is 64-bits, we have to handle under/overflow ourselves. Test to see
+ // if the result can fit into 32-bits (as signed or unsigned).
+ if (static_cast<int>(static_cast<long>(res)) != static_cast<long>(res) &&
+ static_cast<unsigned int>(res) != res) {
+ res = kuint32max;
+ errno = ERANGE;
+ }
+#endif
+ return static_cast<unsigned int>(res);
+}
+
+class StringToIntTraits {
public:
typedef std::string string_type;
- typedef long value_type;
+ typedef int value_type;
static const int kBase = 10;
static inline value_type convert_func(const string_type::value_type* str,
string_type::value_type** endptr) {
- return strtol(str, endptr, kBase);
+ return strtoi(str, endptr, kBase);
}
static inline bool valid_func(const string_type& str) {
return !str.empty() && !isspace(str[0]);
}
};
-class String16ToLongTraits {
+class String16ToIntTraits {
public:
typedef string16 string_type;
- typedef long value_type;
+ typedef int value_type;
static const int kBase = 10;
static inline value_type convert_func(const string_type::value_type* str,
string_type::value_type** endptr) {
@@ -120,7 +149,7 @@ class String16ToLongTraits {
#elif defined(WCHAR_T_IS_UTF32)
std::string ascii_string = UTF16ToASCII(string16(str));
char* ascii_end = NULL;
- value_type ret = strtol(ascii_string.c_str(), &ascii_end, kBase);
+ value_type ret = strtoi(ascii_string.c_str(), &ascii_end, kBase);
if (ascii_string.c_str() + ascii_string.length() == ascii_end) {
*endptr =
const_cast<string_type::value_type*>(str) + ascii_string.length();
@@ -179,24 +208,24 @@ class String16ToInt64Traits {
// For the HexString variants, use the unsigned variants like strtoul for
// convert_func so that input like "0x80000000" doesn't result in an overflow.
-class HexStringToLongTraits {
+class HexStringToIntTraits {
public:
typedef std::string string_type;
- typedef long value_type;
+ typedef int value_type;
static const int kBase = 16;
static inline value_type convert_func(const string_type::value_type* str,
string_type::value_type** endptr) {
- return strtoul(str, endptr, kBase);
+ return strtoui(str, endptr, kBase);
}
static inline bool valid_func(const string_type& str) {
return !str.empty() && !isspace(str[0]);
}
};
-class HexString16ToLongTraits {
+class HexString16ToIntTraits {
public:
typedef string16 string_type;
- typedef long value_type;
+ typedef int value_type;
static const int kBase = 16;
static inline value_type convert_func(const string_type::value_type* str,
string_type::value_type** endptr) {
@@ -205,7 +234,7 @@ class HexString16ToLongTraits {
#elif defined(WCHAR_T_IS_UTF32)
std::string ascii_string = UTF16ToASCII(string16(str));
char* ascii_end = NULL;
- value_type ret = strtoul(ascii_string.c_str(), &ascii_end, kBase);
+ value_type ret = strtoui(ascii_string.c_str(), &ascii_end, kBase);
if (ascii_string.c_str() + ascii_string.length() == ascii_end) {
*endptr =
const_cast<string_type::value_type*>(str) + ascii_string.length();
@@ -1440,21 +1469,12 @@ bool MatchPattern(const std::string& eval, const std::string& pattern) {
return MatchPatternT(eval.c_str(), pattern.c_str());
}
-// For the various *ToInt conversions, there are no *ToIntTraits classes to use
-// because there's no such thing as strtoi. Use *ToLongTraits through a cast
-// instead, requiring that long and int are compatible and equal-width. They
-// are on our target platforms.
-
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));
+ return StringToNumber<StringToIntTraits>(input, output);
}
bool StringToInt(const string16& input, int* output) {
- COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int);
- return StringToNumber<String16ToLongTraits>(input,
- reinterpret_cast<long*>(output));
+ return StringToNumber<String16ToIntTraits>(input, output);
}
bool StringToInt64(const std::string& input, int64* output) {
@@ -1466,15 +1486,11 @@ bool StringToInt64(const string16& input, int64* 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));
+ return StringToNumber<HexStringToIntTraits>(input, output);
}
bool HexStringToInt(const string16& input, int* output) {
- COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int);
- return StringToNumber<HexString16ToLongTraits>(
- input, reinterpret_cast<long*>(output));
+ return StringToNumber<HexString16ToIntTraits>(input, output);
}
namespace {
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698