OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/string_util.h" | 5 #include "base/string_util.h" |
6 | 6 |
7 #include "build/build_config.h" | 7 #include "build/build_config.h" |
8 | 8 |
9 #include <ctype.h> | 9 #include <ctype.h> |
10 #include <errno.h> | 10 #include <errno.h> |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 // does not begin with a parseable number. endptr is compared to the | 87 // does not begin with a parseable number. endptr is compared to the |
88 // expected end given the string's stated length to correctly catch cases | 88 // expected end given the string's stated length to correctly catch cases |
89 // where the string contains embedded NUL characters. | 89 // where the string contains embedded NUL characters. |
90 // - valid_func determines that the input is not in preferred form. | 90 // - valid_func determines that the input is not in preferred form. |
91 return errno == 0 && | 91 return errno == 0 && |
92 !input.empty() && | 92 !input.empty() && |
93 input.c_str() + input.length() == endptr && | 93 input.c_str() + input.length() == endptr && |
94 traits::valid_func(input); | 94 traits::valid_func(input); |
95 } | 95 } |
96 | 96 |
97 class StringToLongTraits { | 97 static int strtoi(const char *nptr, char **endptr, int base) { |
| 98 long res = strtol(nptr, endptr, base); |
| 99 #if __LP64__ |
| 100 // Long is 64-bits, we have to handle under/overflow ourselves. |
| 101 if (res > kint32max) { |
| 102 res = kint32max; |
| 103 errno = ERANGE; |
| 104 } else if (res < kint32min) { |
| 105 res = kint32min; |
| 106 errno = ERANGE; |
| 107 } |
| 108 #endif |
| 109 return static_cast<int>(res); |
| 110 } |
| 111 |
| 112 static unsigned int strtoui(const char *nptr, char **endptr, int base) { |
| 113 unsigned long res = strtoul(nptr, endptr, base); |
| 114 #if __LP64__ |
| 115 // Long is 64-bits, we have to handle under/overflow ourselves. Test to see |
| 116 // if the result can fit into 32-bits (as signed or unsigned). |
| 117 if (static_cast<int>(static_cast<long>(res)) != static_cast<long>(res) && |
| 118 static_cast<unsigned int>(res) != res) { |
| 119 res = kuint32max; |
| 120 errno = ERANGE; |
| 121 } |
| 122 #endif |
| 123 return static_cast<unsigned int>(res); |
| 124 } |
| 125 |
| 126 class StringToIntTraits { |
98 public: | 127 public: |
99 typedef std::string string_type; | 128 typedef std::string string_type; |
100 typedef long value_type; | 129 typedef int value_type; |
101 static const int kBase = 10; | 130 static const int kBase = 10; |
102 static inline value_type convert_func(const string_type::value_type* str, | 131 static inline value_type convert_func(const string_type::value_type* str, |
103 string_type::value_type** endptr) { | 132 string_type::value_type** endptr) { |
104 return strtol(str, endptr, kBase); | 133 return strtoi(str, endptr, kBase); |
105 } | 134 } |
106 static inline bool valid_func(const string_type& str) { | 135 static inline bool valid_func(const string_type& str) { |
107 return !str.empty() && !isspace(str[0]); | 136 return !str.empty() && !isspace(str[0]); |
108 } | 137 } |
109 }; | 138 }; |
110 | 139 |
111 class String16ToLongTraits { | 140 class String16ToIntTraits { |
112 public: | 141 public: |
113 typedef string16 string_type; | 142 typedef string16 string_type; |
114 typedef long value_type; | 143 typedef int value_type; |
115 static const int kBase = 10; | 144 static const int kBase = 10; |
116 static inline value_type convert_func(const string_type::value_type* str, | 145 static inline value_type convert_func(const string_type::value_type* str, |
117 string_type::value_type** endptr) { | 146 string_type::value_type** endptr) { |
118 #if defined(WCHAR_T_IS_UTF16) | 147 #if defined(WCHAR_T_IS_UTF16) |
119 return wcstol(str, endptr, kBase); | 148 return wcstol(str, endptr, kBase); |
120 #elif defined(WCHAR_T_IS_UTF32) | 149 #elif defined(WCHAR_T_IS_UTF32) |
121 std::string ascii_string = UTF16ToASCII(string16(str)); | 150 std::string ascii_string = UTF16ToASCII(string16(str)); |
122 char* ascii_end = NULL; | 151 char* ascii_end = NULL; |
123 value_type ret = strtol(ascii_string.c_str(), &ascii_end, kBase); | 152 value_type ret = strtoi(ascii_string.c_str(), &ascii_end, kBase); |
124 if (ascii_string.c_str() + ascii_string.length() == ascii_end) { | 153 if (ascii_string.c_str() + ascii_string.length() == ascii_end) { |
125 *endptr = | 154 *endptr = |
126 const_cast<string_type::value_type*>(str) + ascii_string.length(); | 155 const_cast<string_type::value_type*>(str) + ascii_string.length(); |
127 } | 156 } |
128 return ret; | 157 return ret; |
129 #endif | 158 #endif |
130 } | 159 } |
131 static inline bool valid_func(const string_type& str) { | 160 static inline bool valid_func(const string_type& str) { |
132 return !str.empty() && !iswspace(str[0]); | 161 return !str.empty() && !iswspace(str[0]); |
133 } | 162 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 #endif | 201 #endif |
173 } | 202 } |
174 static inline bool valid_func(const string_type& str) { | 203 static inline bool valid_func(const string_type& str) { |
175 return !str.empty() && !iswspace(str[0]); | 204 return !str.empty() && !iswspace(str[0]); |
176 } | 205 } |
177 }; | 206 }; |
178 | 207 |
179 // For the HexString variants, use the unsigned variants like strtoul for | 208 // For the HexString variants, use the unsigned variants like strtoul for |
180 // convert_func so that input like "0x80000000" doesn't result in an overflow. | 209 // convert_func so that input like "0x80000000" doesn't result in an overflow. |
181 | 210 |
182 class HexStringToLongTraits { | 211 class HexStringToIntTraits { |
183 public: | 212 public: |
184 typedef std::string string_type; | 213 typedef std::string string_type; |
185 typedef long value_type; | 214 typedef int value_type; |
186 static const int kBase = 16; | 215 static const int kBase = 16; |
187 static inline value_type convert_func(const string_type::value_type* str, | 216 static inline value_type convert_func(const string_type::value_type* str, |
188 string_type::value_type** endptr) { | 217 string_type::value_type** endptr) { |
189 return strtoul(str, endptr, kBase); | 218 return strtoui(str, endptr, kBase); |
190 } | 219 } |
191 static inline bool valid_func(const string_type& str) { | 220 static inline bool valid_func(const string_type& str) { |
192 return !str.empty() && !isspace(str[0]); | 221 return !str.empty() && !isspace(str[0]); |
193 } | 222 } |
194 }; | 223 }; |
195 | 224 |
196 class HexString16ToLongTraits { | 225 class HexString16ToIntTraits { |
197 public: | 226 public: |
198 typedef string16 string_type; | 227 typedef string16 string_type; |
199 typedef long value_type; | 228 typedef int value_type; |
200 static const int kBase = 16; | 229 static const int kBase = 16; |
201 static inline value_type convert_func(const string_type::value_type* str, | 230 static inline value_type convert_func(const string_type::value_type* str, |
202 string_type::value_type** endptr) { | 231 string_type::value_type** endptr) { |
203 #if defined(WCHAR_T_IS_UTF16) | 232 #if defined(WCHAR_T_IS_UTF16) |
204 return wcstoul(str, endptr, kBase); | 233 return wcstoul(str, endptr, kBase); |
205 #elif defined(WCHAR_T_IS_UTF32) | 234 #elif defined(WCHAR_T_IS_UTF32) |
206 std::string ascii_string = UTF16ToASCII(string16(str)); | 235 std::string ascii_string = UTF16ToASCII(string16(str)); |
207 char* ascii_end = NULL; | 236 char* ascii_end = NULL; |
208 value_type ret = strtoul(ascii_string.c_str(), &ascii_end, kBase); | 237 value_type ret = strtoui(ascii_string.c_str(), &ascii_end, kBase); |
209 if (ascii_string.c_str() + ascii_string.length() == ascii_end) { | 238 if (ascii_string.c_str() + ascii_string.length() == ascii_end) { |
210 *endptr = | 239 *endptr = |
211 const_cast<string_type::value_type*>(str) + ascii_string.length(); | 240 const_cast<string_type::value_type*>(str) + ascii_string.length(); |
212 } | 241 } |
213 return ret; | 242 return ret; |
214 #endif | 243 #endif |
215 } | 244 } |
216 static inline bool valid_func(const string_type& str) { | 245 static inline bool valid_func(const string_type& str) { |
217 return !str.empty() && !iswspace(str[0]); | 246 return !str.empty() && !iswspace(str[0]); |
218 } | 247 } |
(...skipping 1214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1433 } | 1462 } |
1434 | 1463 |
1435 bool MatchPattern(const std::wstring& eval, const std::wstring& pattern) { | 1464 bool MatchPattern(const std::wstring& eval, const std::wstring& pattern) { |
1436 return MatchPatternT(eval.c_str(), pattern.c_str()); | 1465 return MatchPatternT(eval.c_str(), pattern.c_str()); |
1437 } | 1466 } |
1438 | 1467 |
1439 bool MatchPattern(const std::string& eval, const std::string& pattern) { | 1468 bool MatchPattern(const std::string& eval, const std::string& pattern) { |
1440 return MatchPatternT(eval.c_str(), pattern.c_str()); | 1469 return MatchPatternT(eval.c_str(), pattern.c_str()); |
1441 } | 1470 } |
1442 | 1471 |
1443 // For the various *ToInt conversions, there are no *ToIntTraits classes to use | |
1444 // because there's no such thing as strtoi. Use *ToLongTraits through a cast | |
1445 // instead, requiring that long and int are compatible and equal-width. They | |
1446 // are on our target platforms. | |
1447 | |
1448 bool StringToInt(const std::string& input, int* output) { | 1472 bool StringToInt(const std::string& input, int* output) { |
1449 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int); | 1473 return StringToNumber<StringToIntTraits>(input, output); |
1450 return StringToNumber<StringToLongTraits>(input, | |
1451 reinterpret_cast<long*>(output)); | |
1452 } | 1474 } |
1453 | 1475 |
1454 bool StringToInt(const string16& input, int* output) { | 1476 bool StringToInt(const string16& input, int* output) { |
1455 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int); | 1477 return StringToNumber<String16ToIntTraits>(input, output); |
1456 return StringToNumber<String16ToLongTraits>(input, | |
1457 reinterpret_cast<long*>(output)); | |
1458 } | 1478 } |
1459 | 1479 |
1460 bool StringToInt64(const std::string& input, int64* output) { | 1480 bool StringToInt64(const std::string& input, int64* output) { |
1461 return StringToNumber<StringToInt64Traits>(input, output); | 1481 return StringToNumber<StringToInt64Traits>(input, output); |
1462 } | 1482 } |
1463 | 1483 |
1464 bool StringToInt64(const string16& input, int64* output) { | 1484 bool StringToInt64(const string16& input, int64* output) { |
1465 return StringToNumber<String16ToInt64Traits>(input, output); | 1485 return StringToNumber<String16ToInt64Traits>(input, output); |
1466 } | 1486 } |
1467 | 1487 |
1468 bool HexStringToInt(const std::string& input, int* output) { | 1488 bool HexStringToInt(const std::string& input, int* output) { |
1469 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int); | 1489 return StringToNumber<HexStringToIntTraits>(input, output); |
1470 return StringToNumber<HexStringToLongTraits>(input, | |
1471 reinterpret_cast<long*>(output)); | |
1472 } | 1490 } |
1473 | 1491 |
1474 bool HexStringToInt(const string16& input, int* output) { | 1492 bool HexStringToInt(const string16& input, int* output) { |
1475 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int); | 1493 return StringToNumber<HexString16ToIntTraits>(input, output); |
1476 return StringToNumber<HexString16ToLongTraits>( | |
1477 input, reinterpret_cast<long*>(output)); | |
1478 } | 1494 } |
1479 | 1495 |
1480 namespace { | 1496 namespace { |
1481 | 1497 |
1482 template<class CHAR> | 1498 template<class CHAR> |
1483 bool HexDigitToIntT(const CHAR digit, uint8* val) { | 1499 bool HexDigitToIntT(const CHAR digit, uint8* val) { |
1484 if (digit >= '0' && digit <= '9') | 1500 if (digit >= '0' && digit <= '9') |
1485 *val = digit - '0'; | 1501 *val = digit - '0'; |
1486 else if (digit >= 'a' && digit <= 'f') | 1502 else if (digit >= 'a' && digit <= 'f') |
1487 *val = 10 + digit - 'a'; | 1503 *val = 10 + digit - 'a'; |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1649 // Each input byte creates two output hex characters. | 1665 // Each input byte creates two output hex characters. |
1650 std::string ret(size * 2, '\0'); | 1666 std::string ret(size * 2, '\0'); |
1651 | 1667 |
1652 for (size_t i = 0; i < size; ++i) { | 1668 for (size_t i = 0; i < size; ++i) { |
1653 char b = reinterpret_cast<const char*>(bytes)[i]; | 1669 char b = reinterpret_cast<const char*>(bytes)[i]; |
1654 ret[(i * 2)] = kHexChars[(b >> 4) & 0xf]; | 1670 ret[(i * 2)] = kHexChars[(b >> 4) & 0xf]; |
1655 ret[(i * 2) + 1] = kHexChars[b & 0xf]; | 1671 ret[(i * 2) + 1] = kHexChars[b & 0xf]; |
1656 } | 1672 } |
1657 return ret; | 1673 return ret; |
1658 } | 1674 } |
OLD | NEW |