OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/strings/string_util.h" | 5 #include "base/strings/string_util.h" |
6 | 6 |
7 #include <ctype.h> | 7 #include <ctype.h> |
8 #include <errno.h> | 8 #include <errno.h> |
9 #include <math.h> | 9 #include <math.h> |
10 #include <stdarg.h> | 10 #include <stdarg.h> |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 // Trim the whitespace. | 186 // Trim the whitespace. |
187 *output = | 187 *output = |
188 input.substr(first_good_char, last_good_char - first_good_char + 1); | 188 input.substr(first_good_char, last_good_char - first_good_char + 1); |
189 | 189 |
190 // Return where we trimmed from. | 190 // Return where we trimmed from. |
191 return static_cast<TrimPositions>( | 191 return static_cast<TrimPositions>( |
192 ((first_good_char == 0) ? TRIM_NONE : TRIM_LEADING) | | 192 ((first_good_char == 0) ? TRIM_NONE : TRIM_LEADING) | |
193 ((last_good_char == last_char) ? TRIM_NONE : TRIM_TRAILING)); | 193 ((last_good_char == last_char) ? TRIM_NONE : TRIM_TRAILING)); |
194 } | 194 } |
195 | 195 |
196 bool TrimString(const std::wstring& input, | |
197 const wchar_t trim_chars[], | |
198 std::wstring* output) { | |
199 return TrimStringT(input, trim_chars, TRIM_ALL, output) != TRIM_NONE; | |
200 } | |
201 | |
202 #if !defined(WCHAR_T_IS_UTF16) | |
203 bool TrimString(const string16& input, | 196 bool TrimString(const string16& input, |
204 const char16 trim_chars[], | 197 const char16 trim_chars[], |
205 string16* output) { | 198 string16* output) { |
206 return TrimStringT(input, trim_chars, TRIM_ALL, output) != TRIM_NONE; | 199 return TrimStringT(input, trim_chars, TRIM_ALL, output) != TRIM_NONE; |
207 } | 200 } |
208 #endif | |
209 | 201 |
210 bool TrimString(const std::string& input, | 202 bool TrimString(const std::string& input, |
211 const char trim_chars[], | 203 const char trim_chars[], |
212 std::string* output) { | 204 std::string* output) { |
213 return TrimStringT(input, trim_chars, TRIM_ALL, output) != TRIM_NONE; | 205 return TrimStringT(input, trim_chars, TRIM_ALL, output) != TRIM_NONE; |
214 } | 206 } |
215 | 207 |
216 void TruncateUTF8ToByteSize(const std::string& input, | 208 void TruncateUTF8ToByteSize(const std::string& input, |
217 const size_t byte_size, | 209 const size_t byte_size, |
218 std::string* output) { | 210 std::string* output) { |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 | 296 |
305 if (in_whitespace && !already_trimmed) { | 297 if (in_whitespace && !already_trimmed) { |
306 // Any trailing whitespace is eliminated. | 298 // Any trailing whitespace is eliminated. |
307 --chars_written; | 299 --chars_written; |
308 } | 300 } |
309 | 301 |
310 result.resize(chars_written); | 302 result.resize(chars_written); |
311 return result; | 303 return result; |
312 } | 304 } |
313 | 305 |
314 std::wstring CollapseWhitespace(const std::wstring& text, | |
315 bool trim_sequences_with_line_breaks) { | |
316 return CollapseWhitespaceT(text, trim_sequences_with_line_breaks); | |
317 } | |
318 | |
319 #if !defined(WCHAR_T_IS_UTF16) | |
320 string16 CollapseWhitespace(const string16& text, | 306 string16 CollapseWhitespace(const string16& text, |
321 bool trim_sequences_with_line_breaks) { | 307 bool trim_sequences_with_line_breaks) { |
322 return CollapseWhitespaceT(text, trim_sequences_with_line_breaks); | 308 return CollapseWhitespaceT(text, trim_sequences_with_line_breaks); |
323 } | 309 } |
324 #endif | |
325 | 310 |
326 std::string CollapseWhitespaceASCII(const std::string& text, | 311 std::string CollapseWhitespaceASCII(const std::string& text, |
327 bool trim_sequences_with_line_breaks) { | 312 bool trim_sequences_with_line_breaks) { |
328 return CollapseWhitespaceT(text, trim_sequences_with_line_breaks); | 313 return CollapseWhitespaceT(text, trim_sequences_with_line_breaks); |
329 } | 314 } |
330 | 315 |
331 bool ContainsOnlyWhitespaceASCII(const std::string& str) { | 316 bool ContainsOnlyWhitespaceASCII(const std::string& str) { |
332 for (std::string::const_iterator i(str.begin()); i != str.end(); ++i) { | 317 for (std::string::const_iterator i(str.begin()); i != str.end(); ++i) { |
333 if (!IsAsciiWhitespace(*i)) | 318 if (!IsAsciiWhitespace(*i)) |
334 return false; | 319 return false; |
335 } | 320 } |
336 return true; | 321 return true; |
337 } | 322 } |
338 | 323 |
339 bool ContainsOnlyWhitespace(const string16& str) { | 324 bool ContainsOnlyWhitespace(const string16& str) { |
340 return str.find_first_not_of(kWhitespaceUTF16) == string16::npos; | 325 return str.find_first_not_of(kWhitespaceUTF16) == string16::npos; |
341 } | 326 } |
342 | 327 |
343 template<typename STR> | 328 template<typename STR> |
344 static bool ContainsOnlyCharsT(const STR& input, const STR& characters) { | 329 static bool ContainsOnlyCharsT(const STR& input, const STR& characters) { |
345 for (typename STR::const_iterator iter = input.begin(); | 330 for (typename STR::const_iterator iter = input.begin(); |
346 iter != input.end(); ++iter) { | 331 iter != input.end(); ++iter) { |
347 if (characters.find(*iter) == STR::npos) | 332 if (characters.find(*iter) == STR::npos) |
348 return false; | 333 return false; |
349 } | 334 } |
350 return true; | 335 return true; |
351 } | 336 } |
352 | 337 |
353 bool ContainsOnlyChars(const std::wstring& input, | |
354 const std::wstring& characters) { | |
355 return ContainsOnlyCharsT(input, characters); | |
356 } | |
357 | |
358 #if !defined(WCHAR_T_IS_UTF16) | |
359 bool ContainsOnlyChars(const string16& input, const string16& characters) { | 338 bool ContainsOnlyChars(const string16& input, const string16& characters) { |
360 return ContainsOnlyCharsT(input, characters); | 339 return ContainsOnlyCharsT(input, characters); |
361 } | 340 } |
362 #endif | |
363 | 341 |
364 bool ContainsOnlyChars(const std::string& input, | 342 bool ContainsOnlyChars(const std::string& input, |
365 const std::string& characters) { | 343 const std::string& characters) { |
366 return ContainsOnlyCharsT(input, characters); | 344 return ContainsOnlyCharsT(input, characters); |
367 } | 345 } |
368 | 346 |
| 347 #if !defined(WCHAR_T_IS_UTF16) |
| 348 bool IsStringASCII(const std::wstring& str); |
| 349 #endif |
| 350 |
369 std::string WideToASCII(const std::wstring& wide) { | 351 std::string WideToASCII(const std::wstring& wide) { |
370 DCHECK(IsStringASCII(wide)) << wide; | 352 DCHECK(IsStringASCII(wide)) << wide; |
371 return std::string(wide.begin(), wide.end()); | 353 return std::string(wide.begin(), wide.end()); |
372 } | 354 } |
373 | 355 |
374 std::string UTF16ToASCII(const string16& utf16) { | 356 std::string UTF16ToASCII(const string16& utf16) { |
375 DCHECK(IsStringASCII(utf16)) << utf16; | 357 DCHECK(IsStringASCII(utf16)) << utf16; |
376 return std::string(utf16.begin(), utf16.end()); | 358 return std::string(utf16.begin(), utf16.end()); |
377 } | 359 } |
378 | 360 |
379 // Latin1 is just the low range of Unicode, so we can copy directly to convert. | |
380 bool WideToLatin1(const std::wstring& wide, std::string* latin1) { | |
381 std::string output; | |
382 output.resize(wide.size()); | |
383 latin1->clear(); | |
384 for (size_t i = 0; i < wide.size(); i++) { | |
385 if (wide[i] > 255) | |
386 return false; | |
387 output[i] = static_cast<char>(wide[i]); | |
388 } | |
389 latin1->swap(output); | |
390 return true; | |
391 } | |
392 | |
393 template<class STR> | 361 template<class STR> |
394 static bool DoIsStringASCII(const STR& str) { | 362 static bool DoIsStringASCII(const STR& str) { |
395 for (size_t i = 0; i < str.length(); i++) { | 363 for (size_t i = 0; i < str.length(); i++) { |
396 typename ToUnsigned<typename STR::value_type>::Unsigned c = str[i]; | 364 typename ToUnsigned<typename STR::value_type>::Unsigned c = str[i]; |
397 if (c > 0x7F) | 365 if (c > 0x7F) |
398 return false; | 366 return false; |
399 } | 367 } |
400 return true; | 368 return true; |
401 } | 369 } |
402 | 370 |
| 371 #if !defined(WCHAR_T_IS_UTF16) |
403 bool IsStringASCII(const std::wstring& str) { | 372 bool IsStringASCII(const std::wstring& str) { |
404 return DoIsStringASCII(str); | 373 return DoIsStringASCII(str); |
405 } | 374 } |
406 | |
407 #if !defined(WCHAR_T_IS_UTF16) | |
408 bool IsStringASCII(const string16& str) { | |
409 return DoIsStringASCII(str); | |
410 } | |
411 #endif | 375 #endif |
412 | 376 |
| 377 bool IsStringASCII(const string16& str) { |
| 378 return DoIsStringASCII(str); |
| 379 } |
| 380 |
413 bool IsStringASCII(const base::StringPiece& str) { | 381 bool IsStringASCII(const base::StringPiece& str) { |
414 return DoIsStringASCII(str); | 382 return DoIsStringASCII(str); |
415 } | 383 } |
416 | 384 |
417 bool IsStringUTF8(const std::string& str) { | 385 bool IsStringUTF8(const std::string& str) { |
418 const char *src = str.data(); | 386 const char *src = str.data(); |
419 int32 src_len = static_cast<int32>(str.length()); | 387 int32 src_len = static_cast<int32>(str.length()); |
420 int32 char_index = 0; | 388 int32 char_index = 0; |
421 | 389 |
422 while (char_index < src_len) { | 390 while (char_index < src_len) { |
(...skipping 14 matching lines...) Expand all Loading... |
437 return false; | 405 return false; |
438 } | 406 } |
439 return *b == 0; | 407 return *b == 0; |
440 } | 408 } |
441 | 409 |
442 // Front-ends for LowerCaseEqualsASCII. | 410 // Front-ends for LowerCaseEqualsASCII. |
443 bool LowerCaseEqualsASCII(const std::string& a, const char* b) { | 411 bool LowerCaseEqualsASCII(const std::string& a, const char* b) { |
444 return DoLowerCaseEqualsASCII(a.begin(), a.end(), b); | 412 return DoLowerCaseEqualsASCII(a.begin(), a.end(), b); |
445 } | 413 } |
446 | 414 |
447 bool LowerCaseEqualsASCII(const std::wstring& a, const char* b) { | 415 bool LowerCaseEqualsASCII(const string16& a, const char* b) { |
448 return DoLowerCaseEqualsASCII(a.begin(), a.end(), b); | 416 return DoLowerCaseEqualsASCII(a.begin(), a.end(), b); |
449 } | 417 } |
450 | 418 |
451 #if !defined(WCHAR_T_IS_UTF16) | |
452 bool LowerCaseEqualsASCII(const string16& a, const char* b) { | |
453 return DoLowerCaseEqualsASCII(a.begin(), a.end(), b); | |
454 } | |
455 #endif | |
456 | |
457 bool LowerCaseEqualsASCII(std::string::const_iterator a_begin, | 419 bool LowerCaseEqualsASCII(std::string::const_iterator a_begin, |
458 std::string::const_iterator a_end, | 420 std::string::const_iterator a_end, |
459 const char* b) { | 421 const char* b) { |
460 return DoLowerCaseEqualsASCII(a_begin, a_end, b); | 422 return DoLowerCaseEqualsASCII(a_begin, a_end, b); |
461 } | 423 } |
462 | 424 |
463 bool LowerCaseEqualsASCII(std::wstring::const_iterator a_begin, | |
464 std::wstring::const_iterator a_end, | |
465 const char* b) { | |
466 return DoLowerCaseEqualsASCII(a_begin, a_end, b); | |
467 } | |
468 | |
469 #if !defined(WCHAR_T_IS_UTF16) | |
470 bool LowerCaseEqualsASCII(string16::const_iterator a_begin, | 425 bool LowerCaseEqualsASCII(string16::const_iterator a_begin, |
471 string16::const_iterator a_end, | 426 string16::const_iterator a_end, |
472 const char* b) { | 427 const char* b) { |
473 return DoLowerCaseEqualsASCII(a_begin, a_end, b); | 428 return DoLowerCaseEqualsASCII(a_begin, a_end, b); |
474 } | 429 } |
475 #endif | |
476 | 430 |
477 // TODO(port): Resolve wchar_t/iterator issues that require OS_ANDROID here. | 431 // TODO(port): Resolve wchar_t/iterator issues that require OS_ANDROID here. |
478 #if !defined(OS_ANDROID) | 432 #if !defined(OS_ANDROID) |
479 bool LowerCaseEqualsASCII(const char* a_begin, | 433 bool LowerCaseEqualsASCII(const char* a_begin, |
480 const char* a_end, | 434 const char* a_end, |
481 const char* b) { | 435 const char* b) { |
482 return DoLowerCaseEqualsASCII(a_begin, a_end, b); | 436 return DoLowerCaseEqualsASCII(a_begin, a_end, b); |
483 } | 437 } |
484 | 438 |
485 bool LowerCaseEqualsASCII(const wchar_t* a_begin, | |
486 const wchar_t* a_end, | |
487 const char* b) { | |
488 return DoLowerCaseEqualsASCII(a_begin, a_end, b); | |
489 } | |
490 | |
491 #if !defined(WCHAR_T_IS_UTF16) | |
492 bool LowerCaseEqualsASCII(const char16* a_begin, | 439 bool LowerCaseEqualsASCII(const char16* a_begin, |
493 const char16* a_end, | 440 const char16* a_end, |
494 const char* b) { | 441 const char* b) { |
495 return DoLowerCaseEqualsASCII(a_begin, a_end, b); | 442 return DoLowerCaseEqualsASCII(a_begin, a_end, b); |
496 } | 443 } |
497 #endif | |
498 | 444 |
499 #endif // !defined(OS_ANDROID) | 445 #endif // !defined(OS_ANDROID) |
500 | 446 |
501 bool EqualsASCII(const string16& a, const base::StringPiece& b) { | 447 bool EqualsASCII(const string16& a, const base::StringPiece& b) { |
502 if (a.length() != b.length()) | 448 if (a.length() != b.length()) |
503 return false; | 449 return false; |
504 return std::equal(b.begin(), b.end(), a.begin()); | 450 return std::equal(b.begin(), b.end(), a.begin()); |
505 } | 451 } |
506 | 452 |
507 bool StartsWithASCII(const std::string& str, | 453 bool StartsWithASCII(const std::string& str, |
(...skipping 10 matching lines...) Expand all Loading... |
518 if (case_sensitive) { | 464 if (case_sensitive) { |
519 return str.compare(0, search.length(), search) == 0; | 465 return str.compare(0, search.length(), search) == 0; |
520 } else { | 466 } else { |
521 if (search.size() > str.size()) | 467 if (search.size() > str.size()) |
522 return false; | 468 return false; |
523 return std::equal(search.begin(), search.end(), str.begin(), | 469 return std::equal(search.begin(), search.end(), str.begin(), |
524 base::CaseInsensitiveCompare<typename STR::value_type>()); | 470 base::CaseInsensitiveCompare<typename STR::value_type>()); |
525 } | 471 } |
526 } | 472 } |
527 | 473 |
528 bool StartsWith(const std::wstring& str, const std::wstring& search, | 474 bool StartsWith(const string16& str, const string16& search, |
529 bool case_sensitive) { | 475 bool case_sensitive) { |
530 return StartsWithT(str, search, case_sensitive); | 476 return StartsWithT(str, search, case_sensitive); |
531 } | 477 } |
532 | 478 |
533 #if !defined(WCHAR_T_IS_UTF16) | |
534 bool StartsWith(const string16& str, const string16& search, | |
535 bool case_sensitive) { | |
536 return StartsWithT(str, search, case_sensitive); | |
537 } | |
538 #endif | |
539 | |
540 template <typename STR> | 479 template <typename STR> |
541 bool EndsWithT(const STR& str, const STR& search, bool case_sensitive) { | 480 bool EndsWithT(const STR& str, const STR& search, bool case_sensitive) { |
542 typename STR::size_type str_length = str.length(); | 481 typename STR::size_type str_length = str.length(); |
543 typename STR::size_type search_length = search.length(); | 482 typename STR::size_type search_length = search.length(); |
544 if (search_length > str_length) | 483 if (search_length > str_length) |
545 return false; | 484 return false; |
546 if (case_sensitive) { | 485 if (case_sensitive) { |
547 return str.compare(str_length - search_length, search_length, search) == 0; | 486 return str.compare(str_length - search_length, search_length, search) == 0; |
548 } else { | 487 } else { |
549 return std::equal(search.begin(), search.end(), | 488 return std::equal(search.begin(), search.end(), |
550 str.begin() + (str_length - search_length), | 489 str.begin() + (str_length - search_length), |
551 base::CaseInsensitiveCompare<typename STR::value_type>()); | 490 base::CaseInsensitiveCompare<typename STR::value_type>()); |
552 } | 491 } |
553 } | 492 } |
554 | 493 |
555 bool EndsWith(const std::string& str, const std::string& search, | 494 bool EndsWith(const std::string& str, const std::string& search, |
556 bool case_sensitive) { | 495 bool case_sensitive) { |
557 return EndsWithT(str, search, case_sensitive); | 496 return EndsWithT(str, search, case_sensitive); |
558 } | 497 } |
559 | 498 |
560 bool EndsWith(const std::wstring& str, const std::wstring& search, | 499 bool EndsWith(const string16& str, const string16& search, |
561 bool case_sensitive) { | 500 bool case_sensitive) { |
562 return EndsWithT(str, search, case_sensitive); | 501 return EndsWithT(str, search, case_sensitive); |
563 } | 502 } |
564 | 503 |
565 #if !defined(WCHAR_T_IS_UTF16) | |
566 bool EndsWith(const string16& str, const string16& search, | |
567 bool case_sensitive) { | |
568 return EndsWithT(str, search, case_sensitive); | |
569 } | |
570 #endif | |
571 | |
572 static const char* const kByteStringsUnlocalized[] = { | 504 static const char* const kByteStringsUnlocalized[] = { |
573 " B", | 505 " B", |
574 " kB", | 506 " kB", |
575 " MB", | 507 " MB", |
576 " GB", | 508 " GB", |
577 " TB", | 509 " TB", |
578 " PB" | 510 " PB" |
579 }; | 511 }; |
580 | 512 |
581 string16 FormatBytesUnlocalized(int64 bytes) { | 513 string16 FormatBytesUnlocalized(int64 bytes) { |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
667 break; | 599 break; |
668 } else { | 600 } else { |
669 tokens->push_back(str.substr(start, end - start)); | 601 tokens->push_back(str.substr(start, end - start)); |
670 start = str.find_first_not_of(delimiters, end + 1); | 602 start = str.find_first_not_of(delimiters, end + 1); |
671 } | 603 } |
672 } | 604 } |
673 | 605 |
674 return tokens->size(); | 606 return tokens->size(); |
675 } | 607 } |
676 | 608 |
677 size_t Tokenize(const std::wstring& str, | |
678 const std::wstring& delimiters, | |
679 std::vector<std::wstring>* tokens) { | |
680 return TokenizeT(str, delimiters, tokens); | |
681 } | |
682 | |
683 #if !defined(WCHAR_T_IS_UTF16) | |
684 size_t Tokenize(const string16& str, | 609 size_t Tokenize(const string16& str, |
685 const string16& delimiters, | 610 const string16& delimiters, |
686 std::vector<string16>* tokens) { | 611 std::vector<string16>* tokens) { |
687 return TokenizeT(str, delimiters, tokens); | 612 return TokenizeT(str, delimiters, tokens); |
688 } | 613 } |
689 #endif | |
690 | 614 |
691 size_t Tokenize(const std::string& str, | 615 size_t Tokenize(const std::string& str, |
692 const std::string& delimiters, | 616 const std::string& delimiters, |
693 std::vector<std::string>* tokens) { | 617 std::vector<std::string>* tokens) { |
694 return TokenizeT(str, delimiters, tokens); | 618 return TokenizeT(str, delimiters, tokens); |
695 } | 619 } |
696 | 620 |
697 size_t Tokenize(const base::StringPiece& str, | 621 size_t Tokenize(const base::StringPiece& str, |
698 const base::StringPiece& delimiters, | 622 const base::StringPiece& delimiters, |
699 std::vector<base::StringPiece>* tokens) { | 623 std::vector<base::StringPiece>* tokens) { |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
810 } | 734 } |
811 | 735 |
812 string16 ReplaceStringPlaceholders(const string16& format_string, | 736 string16 ReplaceStringPlaceholders(const string16& format_string, |
813 const string16& a, | 737 const string16& a, |
814 size_t* offset) { | 738 size_t* offset) { |
815 std::vector<size_t> offsets; | 739 std::vector<size_t> offsets; |
816 std::vector<string16> subst; | 740 std::vector<string16> subst; |
817 subst.push_back(a); | 741 subst.push_back(a); |
818 string16 result = ReplaceStringPlaceholders(format_string, subst, &offsets); | 742 string16 result = ReplaceStringPlaceholders(format_string, subst, &offsets); |
819 | 743 |
820 DCHECK(offsets.size() == 1); | 744 DCHECK_EQ(1U, offsets.size()); |
821 if (offset) { | 745 if (offset) |
822 *offset = offsets[0]; | 746 *offset = offsets[0]; |
823 } | |
824 return result; | 747 return result; |
825 } | 748 } |
826 | 749 |
827 static bool IsWildcard(base_icu::UChar32 character) { | 750 static bool IsWildcard(base_icu::UChar32 character) { |
828 return character == '*' || character == '?'; | 751 return character == '*' || character == '?'; |
829 } | 752 } |
830 | 753 |
831 // Move the strings pointers to the point where they start to differ. | 754 // Move the strings pointers to the point where they start to differ. |
832 template <typename CHAR, typename NEXT> | 755 template <typename CHAR, typename NEXT> |
833 static void EatSameChars(const CHAR** pattern, const CHAR* pattern_end, | 756 static void EatSameChars(const CHAR** pattern, const CHAR* pattern_end, |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1002 } | 925 } |
1003 | 926 |
1004 } // namespace | 927 } // namespace |
1005 | 928 |
1006 size_t base::strlcpy(char* dst, const char* src, size_t dst_size) { | 929 size_t base::strlcpy(char* dst, const char* src, size_t dst_size) { |
1007 return lcpyT<char>(dst, src, dst_size); | 930 return lcpyT<char>(dst, src, dst_size); |
1008 } | 931 } |
1009 size_t base::wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size) { | 932 size_t base::wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size) { |
1010 return lcpyT<wchar_t>(dst, src, dst_size); | 933 return lcpyT<wchar_t>(dst, src, dst_size); |
1011 } | 934 } |
OLD | NEW |