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 |