| 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 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 static const int kBase = 10; | 120 static const int kBase = 10; |
| 121 static inline value_type convert_func(const string_type::value_type* str, | 121 static inline value_type convert_func(const string_type::value_type* str, |
| 122 string_type::value_type** endptr) { | 122 string_type::value_type** endptr) { |
| 123 return strtol(str, endptr, kBase); | 123 return strtol(str, endptr, kBase); |
| 124 } | 124 } |
| 125 static inline bool valid_func(const string_type& str) { | 125 static inline bool valid_func(const string_type& str) { |
| 126 return !str.empty() && !isspace(str[0]); | 126 return !str.empty() && !isspace(str[0]); |
| 127 } | 127 } |
| 128 }; | 128 }; |
| 129 | 129 |
| 130 class WStringToLongTraits { | 130 class String16ToLongTraits { |
| 131 public: | 131 public: |
| 132 typedef std::wstring string_type; | 132 typedef string16 string_type; |
| 133 typedef long value_type; | 133 typedef long value_type; |
| 134 static const int kBase = 10; | 134 static const int kBase = 10; |
| 135 static inline value_type convert_func(const string_type::value_type* str, | 135 static inline value_type convert_func(const string_type::value_type* str, |
| 136 string_type::value_type** endptr) { | 136 string_type::value_type** endptr) { |
| 137 #if defined(WCHAR_T_IS_UTF16) |
| 137 return wcstol(str, endptr, kBase); | 138 return wcstol(str, endptr, kBase); |
| 139 #elif defined(WCHAR_T_IS_UTF32) |
| 140 std::string ascii_string = UTF16ToASCII(string16(str)); |
| 141 char* ascii_end = NULL; |
| 142 value_type ret = strtol(ascii_string.c_str(), &ascii_end, kBase); |
| 143 if (ascii_string.c_str() + ascii_string.length() == ascii_end) { |
| 144 *endptr = |
| 145 const_cast<string_type::value_type*>(str) + ascii_string.length(); |
| 146 } |
| 147 return ret; |
| 148 #endif |
| 138 } | 149 } |
| 139 static inline bool valid_func(const string_type& str) { | 150 static inline bool valid_func(const string_type& str) { |
| 140 return !str.empty() && !iswspace(str[0]); | 151 return !str.empty() && !iswspace(str[0]); |
| 141 } | 152 } |
| 142 }; | 153 }; |
| 143 | 154 |
| 144 class StringToInt64Traits { | 155 class StringToInt64Traits { |
| 145 public: | 156 public: |
| 146 typedef std::string string_type; | 157 typedef std::string string_type; |
| 147 typedef int64 value_type; | 158 typedef int64 value_type; |
| 148 static const int kBase = 10; | 159 static const int kBase = 10; |
| 149 static inline value_type convert_func(const string_type::value_type* str, | 160 static inline value_type convert_func(const string_type::value_type* str, |
| 150 string_type::value_type** endptr) { | 161 string_type::value_type** endptr) { |
| 151 #ifdef OS_WIN | 162 #ifdef OS_WIN |
| 152 return _strtoi64(str, endptr, kBase); | 163 return _strtoi64(str, endptr, kBase); |
| 153 #else // assume OS_POSIX | 164 #else // assume OS_POSIX |
| 154 return strtoll(str, endptr, kBase); | 165 return strtoll(str, endptr, kBase); |
| 155 #endif | 166 #endif |
| 156 } | 167 } |
| 157 static inline bool valid_func(const string_type& str) { | 168 static inline bool valid_func(const string_type& str) { |
| 158 return !str.empty() && !isspace(str[0]); | 169 return !str.empty() && !isspace(str[0]); |
| 159 } | 170 } |
| 160 }; | 171 }; |
| 161 | 172 |
| 162 class WStringToInt64Traits { | 173 class String16ToInt64Traits { |
| 163 public: | 174 public: |
| 164 typedef std::wstring string_type; | 175 typedef string16 string_type; |
| 165 typedef int64 value_type; | 176 typedef int64 value_type; |
| 166 static const int kBase = 10; | 177 static const int kBase = 10; |
| 167 static inline value_type convert_func(const string_type::value_type* str, | 178 static inline value_type convert_func(const string_type::value_type* str, |
| 168 string_type::value_type** endptr) { | 179 string_type::value_type** endptr) { |
| 169 #ifdef OS_WIN | 180 #ifdef OS_WIN |
| 170 return _wcstoi64(str, endptr, kBase); | 181 return _wcstoi64(str, endptr, kBase); |
| 171 #else // assume OS_POSIX | 182 #else // assume OS_POSIX |
| 172 return wcstoll(str, endptr, kBase); | 183 std::string ascii_string = UTF16ToASCII(string16(str)); |
| 184 char* ascii_end = NULL; |
| 185 value_type ret = strtoll(ascii_string.c_str(), &ascii_end, kBase); |
| 186 if (ascii_string.c_str() + ascii_string.length() == ascii_end) { |
| 187 *endptr = |
| 188 const_cast<string_type::value_type*>(str) + ascii_string.length(); |
| 189 } |
| 190 return ret; |
| 173 #endif | 191 #endif |
| 174 } | 192 } |
| 175 static inline bool valid_func(const string_type& str) { | 193 static inline bool valid_func(const string_type& str) { |
| 176 return !str.empty() && !iswspace(str[0]); | 194 return !str.empty() && !iswspace(str[0]); |
| 177 } | 195 } |
| 178 }; | 196 }; |
| 179 | 197 |
| 180 // For the HexString variants, use the unsigned variants like strtoul for | 198 // For the HexString variants, use the unsigned variants like strtoul for |
| 181 // convert_func so that input like "0x80000000" doesn't result in an overflow. | 199 // convert_func so that input like "0x80000000" doesn't result in an overflow. |
| 182 | 200 |
| 183 class HexStringToLongTraits { | 201 class HexStringToLongTraits { |
| 184 public: | 202 public: |
| 185 typedef std::string string_type; | 203 typedef std::string string_type; |
| 186 typedef long value_type; | 204 typedef long value_type; |
| 187 static const int kBase = 16; | 205 static const int kBase = 16; |
| 188 static inline value_type convert_func(const string_type::value_type* str, | 206 static inline value_type convert_func(const string_type::value_type* str, |
| 189 string_type::value_type** endptr) { | 207 string_type::value_type** endptr) { |
| 190 return strtoul(str, endptr, kBase); | 208 return strtoul(str, endptr, kBase); |
| 191 } | 209 } |
| 192 static inline bool valid_func(const string_type& str) { | 210 static inline bool valid_func(const string_type& str) { |
| 193 return !str.empty() && !isspace(str[0]); | 211 return !str.empty() && !isspace(str[0]); |
| 194 } | 212 } |
| 195 }; | 213 }; |
| 196 | 214 |
| 197 class HexWStringToLongTraits { | 215 class HexString16ToLongTraits { |
| 198 public: | 216 public: |
| 199 typedef std::wstring string_type; | 217 typedef string16 string_type; |
| 200 typedef long value_type; | 218 typedef long value_type; |
| 201 static const int kBase = 16; | 219 static const int kBase = 16; |
| 202 static inline value_type convert_func(const string_type::value_type* str, | 220 static inline value_type convert_func(const string_type::value_type* str, |
| 203 string_type::value_type** endptr) { | 221 string_type::value_type** endptr) { |
| 222 #if defined(WCHAR_T_IS_UTF16) |
| 204 return wcstoul(str, endptr, kBase); | 223 return wcstoul(str, endptr, kBase); |
| 224 #elif defined(WCHAR_T_IS_UTF32) |
| 225 std::string ascii_string = UTF16ToASCII(string16(str)); |
| 226 char* ascii_end = NULL; |
| 227 value_type ret = strtoul(ascii_string.c_str(), &ascii_end, kBase); |
| 228 if (ascii_string.c_str() + ascii_string.length() == ascii_end) { |
| 229 *endptr = |
| 230 const_cast<string_type::value_type*>(str) + ascii_string.length(); |
| 231 } |
| 232 return ret; |
| 233 #endif |
| 205 } | 234 } |
| 206 static inline bool valid_func(const string_type& str) { | 235 static inline bool valid_func(const string_type& str) { |
| 207 return !str.empty() && !iswspace(str[0]); | 236 return !str.empty() && !iswspace(str[0]); |
| 208 } | 237 } |
| 209 }; | 238 }; |
| 210 | 239 |
| 211 class StringToDoubleTraits { | 240 class StringToDoubleTraits { |
| 212 public: | 241 public: |
| 213 typedef std::string string_type; | 242 typedef std::string string_type; |
| 214 typedef double value_type; | 243 typedef double value_type; |
| 215 static inline value_type convert_func(const string_type::value_type* str, | 244 static inline value_type convert_func(const string_type::value_type* str, |
| 216 string_type::value_type** endptr) { | 245 string_type::value_type** endptr) { |
| 217 return dmg_fp::strtod(str, endptr); | 246 return dmg_fp::strtod(str, endptr); |
| 218 } | 247 } |
| 219 static inline bool valid_func(const string_type& str) { | 248 static inline bool valid_func(const string_type& str) { |
| 220 return !str.empty() && !isspace(str[0]); | 249 return !str.empty() && !isspace(str[0]); |
| 221 } | 250 } |
| 222 }; | 251 }; |
| 223 | 252 |
| 224 class WStringToDoubleTraits { | 253 class String16ToDoubleTraits { |
| 225 public: | 254 public: |
| 226 typedef std::wstring string_type; | 255 typedef string16 string_type; |
| 227 typedef double value_type; | 256 typedef double value_type; |
| 228 static inline value_type convert_func(const string_type::value_type* str, | 257 static inline value_type convert_func(const string_type::value_type* str, |
| 229 string_type::value_type** endptr) { | 258 string_type::value_type** endptr) { |
| 230 // Because dmg_fp::strtod does not like wchar_t, we convert it to ASCII. | 259 // Because dmg_fp::strtod does not like char16, we convert it to ASCII. |
| 231 // In theory, this should be safe, but it's possible that wide chars | 260 // In theory, this should be safe, but it's possible that 16-bit chars |
| 232 // might get ignored by accident causing something to be parsed when it | 261 // might get ignored by accident causing something to be parsed when it |
| 233 // shouldn't. | 262 // shouldn't. |
| 234 std::string ascii_string = WideToASCII(std::wstring(str)); | 263 std::string ascii_string = UTF16ToASCII(string16(str)); |
| 235 char* ascii_end = NULL; | 264 char* ascii_end = NULL; |
| 236 value_type ret = dmg_fp::strtod(ascii_string.c_str(), &ascii_end); | 265 value_type ret = dmg_fp::strtod(ascii_string.c_str(), &ascii_end); |
| 237 if (ascii_string.c_str() + ascii_string.length() == ascii_end) { | 266 if (ascii_string.c_str() + ascii_string.length() == ascii_end) { |
| 238 // Put endptr at end of input string, so it's not recognized as an error. | 267 // Put endptr at end of input string, so it's not recognized as an error. |
| 239 *endptr = const_cast<string_type::value_type*>(str) + wcslen(str); | 268 *endptr = |
| 269 const_cast<string_type::value_type*>(str) + ascii_string.length(); |
| 240 } | 270 } |
| 241 | 271 |
| 242 return ret; | 272 return ret; |
| 243 } | 273 } |
| 244 static inline bool valid_func(const string_type& str) { | 274 static inline bool valid_func(const string_type& str) { |
| 245 return !str.empty() && !iswspace(str[0]); | 275 return !str.empty() && !iswspace(str[0]); |
| 246 } | 276 } |
| 247 }; | 277 }; |
| 248 | 278 |
| 249 } // namespace | 279 } // namespace |
| (...skipping 1169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1419 // because there's no such thing as strtoi. Use *ToLongTraits through a cast | 1449 // because there's no such thing as strtoi. Use *ToLongTraits through a cast |
| 1420 // instead, requiring that long and int are compatible and equal-width. They | 1450 // instead, requiring that long and int are compatible and equal-width. They |
| 1421 // are on our target platforms. | 1451 // are on our target platforms. |
| 1422 | 1452 |
| 1423 bool StringToInt(const std::string& input, int* output) { | 1453 bool StringToInt(const std::string& input, int* output) { |
| 1424 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int); | 1454 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int); |
| 1425 return StringToNumber<StringToLongTraits>(input, | 1455 return StringToNumber<StringToLongTraits>(input, |
| 1426 reinterpret_cast<long*>(output)); | 1456 reinterpret_cast<long*>(output)); |
| 1427 } | 1457 } |
| 1428 | 1458 |
| 1429 bool StringToInt(const std::wstring& input, int* output) { | 1459 bool StringToInt(const string16& input, int* output) { |
| 1430 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int); | 1460 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int); |
| 1431 return StringToNumber<WStringToLongTraits>(input, | 1461 return StringToNumber<String16ToLongTraits>(input, |
| 1432 reinterpret_cast<long*>(output)); | 1462 reinterpret_cast<long*>(output)); |
| 1433 } | 1463 } |
| 1434 | 1464 |
| 1435 bool StringToInt64(const std::string& input, int64* output) { | 1465 bool StringToInt64(const std::string& input, int64* output) { |
| 1436 return StringToNumber<StringToInt64Traits>(input, output); | 1466 return StringToNumber<StringToInt64Traits>(input, output); |
| 1437 } | 1467 } |
| 1438 | 1468 |
| 1439 bool StringToInt64(const std::wstring& input, int64* output) { | 1469 bool StringToInt64(const string16& input, int64* output) { |
| 1440 return StringToNumber<WStringToInt64Traits>(input, output); | 1470 return StringToNumber<String16ToInt64Traits>(input, output); |
| 1441 } | 1471 } |
| 1442 | 1472 |
| 1443 bool HexStringToInt(const std::string& input, int* output) { | 1473 bool HexStringToInt(const std::string& input, int* output) { |
| 1444 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int); | 1474 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int); |
| 1445 return StringToNumber<HexStringToLongTraits>(input, | 1475 return StringToNumber<HexStringToLongTraits>(input, |
| 1446 reinterpret_cast<long*>(output)); | 1476 reinterpret_cast<long*>(output)); |
| 1447 } | 1477 } |
| 1448 | 1478 |
| 1449 bool HexStringToInt(const std::wstring& input, int* output) { | 1479 bool HexStringToInt(const string16& input, int* output) { |
| 1450 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int); | 1480 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int); |
| 1451 return StringToNumber<HexWStringToLongTraits>( | 1481 return StringToNumber<HexString16ToLongTraits>( |
| 1452 input, reinterpret_cast<long*>(output)); | 1482 input, reinterpret_cast<long*>(output)); |
| 1453 } | 1483 } |
| 1454 | 1484 |
| 1455 namespace { | 1485 namespace { |
| 1456 | 1486 |
| 1457 template<class CHAR> | 1487 template<class CHAR> |
| 1458 bool HexDigitToIntT(const CHAR digit, uint8* val) { | 1488 bool HexDigitToIntT(const CHAR digit, uint8* val) { |
| 1459 if (digit >= '0' && digit <= '9') | 1489 if (digit >= '0' && digit <= '9') |
| 1460 *val = digit - '0'; | 1490 *val = digit - '0'; |
| 1461 else if (digit >= 'a' && digit <= 'f') | 1491 else if (digit >= 'a' && digit <= 'f') |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1483 } | 1513 } |
| 1484 return true; | 1514 return true; |
| 1485 } | 1515 } |
| 1486 | 1516 |
| 1487 } // namespace | 1517 } // namespace |
| 1488 | 1518 |
| 1489 bool HexStringToBytes(const std::string& input, std::vector<uint8>* output) { | 1519 bool HexStringToBytes(const std::string& input, std::vector<uint8>* output) { |
| 1490 return HexStringToBytesT(input, output); | 1520 return HexStringToBytesT(input, output); |
| 1491 } | 1521 } |
| 1492 | 1522 |
| 1493 bool HexStringToBytes(const std::wstring& input, std::vector<uint8>* output) { | 1523 bool HexStringToBytes(const string16& input, std::vector<uint8>* output) { |
| 1494 return HexStringToBytesT(input, output); | 1524 return HexStringToBytesT(input, output); |
| 1495 } | 1525 } |
| 1496 | 1526 |
| 1497 int StringToInt(const std::string& value) { | 1527 int StringToInt(const std::string& value) { |
| 1498 int result; | 1528 int result; |
| 1499 StringToInt(value, &result); | 1529 StringToInt(value, &result); |
| 1500 return result; | 1530 return result; |
| 1501 } | 1531 } |
| 1502 | 1532 |
| 1503 int StringToInt(const std::wstring& value) { | 1533 int StringToInt(const string16& value) { |
| 1504 int result; | 1534 int result; |
| 1505 StringToInt(value, &result); | 1535 StringToInt(value, &result); |
| 1506 return result; | 1536 return result; |
| 1507 } | 1537 } |
| 1508 | 1538 |
| 1509 int64 StringToInt64(const std::string& value) { | 1539 int64 StringToInt64(const std::string& value) { |
| 1510 int64 result; | 1540 int64 result; |
| 1511 StringToInt64(value, &result); | 1541 StringToInt64(value, &result); |
| 1512 return result; | 1542 return result; |
| 1513 } | 1543 } |
| 1514 | 1544 |
| 1515 int64 StringToInt64(const std::wstring& value) { | 1545 int64 StringToInt64(const string16& value) { |
| 1516 int64 result; | 1546 int64 result; |
| 1517 StringToInt64(value, &result); | 1547 StringToInt64(value, &result); |
| 1518 return result; | 1548 return result; |
| 1519 } | 1549 } |
| 1520 | 1550 |
| 1521 int HexStringToInt(const std::string& value) { | 1551 int HexStringToInt(const std::string& value) { |
| 1522 int result; | 1552 int result; |
| 1523 HexStringToInt(value, &result); | 1553 HexStringToInt(value, &result); |
| 1524 return result; | 1554 return result; |
| 1525 } | 1555 } |
| 1526 | 1556 |
| 1527 int HexStringToInt(const std::wstring& value) { | 1557 int HexStringToInt(const string16& value) { |
| 1528 int result; | 1558 int result; |
| 1529 HexStringToInt(value, &result); | 1559 HexStringToInt(value, &result); |
| 1530 return result; | 1560 return result; |
| 1531 } | 1561 } |
| 1532 | 1562 |
| 1533 bool StringToDouble(const std::string& input, double* output) { | 1563 bool StringToDouble(const std::string& input, double* output) { |
| 1534 return StringToNumber<StringToDoubleTraits>(input, output); | 1564 return StringToNumber<StringToDoubleTraits>(input, output); |
| 1535 } | 1565 } |
| 1536 | 1566 |
| 1537 bool StringToDouble(const std::wstring& input, double* output) { | 1567 bool StringToDouble(const string16& input, double* output) { |
| 1538 return StringToNumber<WStringToDoubleTraits>(input, output); | 1568 return StringToNumber<String16ToDoubleTraits>(input, output); |
| 1539 } | 1569 } |
| 1540 | 1570 |
| 1541 double StringToDouble(const std::string& value) { | 1571 double StringToDouble(const std::string& value) { |
| 1542 double result; | 1572 double result; |
| 1543 StringToDouble(value, &result); | 1573 StringToDouble(value, &result); |
| 1544 return result; | 1574 return result; |
| 1545 } | 1575 } |
| 1546 | 1576 |
| 1547 double StringToDouble(const std::wstring& value) { | 1577 double StringToDouble(const string16& value) { |
| 1548 double result; | 1578 double result; |
| 1549 StringToDouble(value, &result); | 1579 StringToDouble(value, &result); |
| 1550 return result; | 1580 return result; |
| 1551 } | 1581 } |
| 1552 | 1582 |
| 1553 // The following code is compatible with the OpenBSD lcpy interface. See: | 1583 // The following code is compatible with the OpenBSD lcpy interface. See: |
| 1554 // http://www.gratisoft.us/todd/papers/strlcpy.html | 1584 // http://www.gratisoft.us/todd/papers/strlcpy.html |
| 1555 // ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/{wcs,str}lcpy.c | 1585 // ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/{wcs,str}lcpy.c |
| 1556 | 1586 |
| 1557 namespace { | 1587 namespace { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1624 // Each input byte creates two output hex characters. | 1654 // Each input byte creates two output hex characters. |
| 1625 std::string ret(size * 2, '\0'); | 1655 std::string ret(size * 2, '\0'); |
| 1626 | 1656 |
| 1627 for (size_t i = 0; i < size; ++i) { | 1657 for (size_t i = 0; i < size; ++i) { |
| 1628 char b = reinterpret_cast<const char*>(bytes)[i]; | 1658 char b = reinterpret_cast<const char*>(bytes)[i]; |
| 1629 ret[(i * 2)] = kHexChars[(b >> 4) & 0xf]; | 1659 ret[(i * 2)] = kHexChars[(b >> 4) & 0xf]; |
| 1630 ret[(i * 2) + 1] = kHexChars[b & 0xf]; | 1660 ret[(i * 2) + 1] = kHexChars[b & 0xf]; |
| 1631 } | 1661 } |
| 1632 return ret; | 1662 return ret; |
| 1633 } | 1663 } |
| OLD | NEW |