| 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 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 const std::wstring& EmptyWString() { | 111 const std::wstring& EmptyWString() { |
| 112 return EmptyStrings::GetInstance()->ws; | 112 return EmptyStrings::GetInstance()->ws; |
| 113 } | 113 } |
| 114 | 114 |
| 115 const string16& EmptyString16() { | 115 const string16& EmptyString16() { |
| 116 return EmptyStrings::GetInstance()->s16; | 116 return EmptyStrings::GetInstance()->s16; |
| 117 } | 117 } |
| 118 | 118 |
| 119 template<typename STR> | 119 template<typename STR> |
| 120 bool ReplaceCharsT(const STR& input, | 120 bool ReplaceCharsT(const STR& input, |
| 121 const typename STR::value_type replace_chars[], | 121 const STR& replace_chars, |
| 122 const STR& replace_with, | 122 const STR& replace_with, |
| 123 STR* output) { | 123 STR* output) { |
| 124 bool removed = false; | 124 bool removed = false; |
| 125 size_t replace_length = replace_with.length(); | 125 size_t replace_length = replace_with.length(); |
| 126 | 126 |
| 127 *output = input; | 127 *output = input; |
| 128 | 128 |
| 129 size_t found = output->find_first_of(replace_chars); | 129 size_t found = output->find_first_of(replace_chars); |
| 130 while (found != STR::npos) { | 130 while (found != STR::npos) { |
| 131 removed = true; | 131 removed = true; |
| 132 output->replace(found, 1, replace_with); | 132 output->replace(found, 1, replace_with); |
| 133 found = output->find_first_of(replace_chars, found + replace_length); | 133 found = output->find_first_of(replace_chars, found + replace_length); |
| 134 } | 134 } |
| 135 | 135 |
| 136 return removed; | 136 return removed; |
| 137 } | 137 } |
| 138 | 138 |
| 139 bool ReplaceChars(const string16& input, | 139 bool ReplaceChars(const string16& input, |
| 140 const char16 replace_chars[], | 140 const base::StringPiece16& replace_chars, |
| 141 const string16& replace_with, | 141 const string16& replace_with, |
| 142 string16* output) { | 142 string16* output) { |
| 143 return ReplaceCharsT(input, replace_chars, replace_with, output); | 143 return ReplaceCharsT(input, replace_chars.as_string(), replace_with, output); |
| 144 } | 144 } |
| 145 | 145 |
| 146 bool ReplaceChars(const std::string& input, | 146 bool ReplaceChars(const std::string& input, |
| 147 const char replace_chars[], | 147 const base::StringPiece& replace_chars, |
| 148 const std::string& replace_with, | 148 const std::string& replace_with, |
| 149 std::string* output) { | 149 std::string* output) { |
| 150 return ReplaceCharsT(input, replace_chars, replace_with, output); | 150 return ReplaceCharsT(input, replace_chars.as_string(), replace_with, output); |
| 151 } | 151 } |
| 152 | 152 |
| 153 bool RemoveChars(const string16& input, | 153 bool RemoveChars(const string16& input, |
| 154 const char16 remove_chars[], | 154 const base::StringPiece16& remove_chars, |
| 155 string16* output) { | 155 string16* output) { |
| 156 return ReplaceChars(input, remove_chars, string16(), output); | 156 return ReplaceChars(input, remove_chars.as_string(), string16(), output); |
| 157 } | 157 } |
| 158 | 158 |
| 159 bool RemoveChars(const std::string& input, | 159 bool RemoveChars(const std::string& input, |
| 160 const char remove_chars[], | 160 const base::StringPiece& remove_chars, |
| 161 std::string* output) { | 161 std::string* output) { |
| 162 return ReplaceChars(input, remove_chars, std::string(), output); | 162 return ReplaceChars(input, remove_chars.as_string(), std::string(), output); |
| 163 } | 163 } |
| 164 | 164 |
| 165 template<typename STR> | 165 template<typename STR> |
| 166 TrimPositions TrimStringT(const STR& input, | 166 TrimPositions TrimStringT(const STR& input, |
| 167 const typename STR::value_type trim_chars[], | 167 const STR& trim_chars, |
| 168 TrimPositions positions, | 168 TrimPositions positions, |
| 169 STR* output) { | 169 STR* output) { |
| 170 // Find the edges of leading/trailing whitespace as desired. | 170 // Find the edges of leading/trailing whitespace as desired. |
| 171 const typename STR::size_type last_char = input.length() - 1; | 171 const size_t last_char = input.length() - 1; |
| 172 const typename STR::size_type first_good_char = (positions & TRIM_LEADING) ? | 172 const size_t first_good_char = (positions & TRIM_LEADING) ? |
| 173 input.find_first_not_of(trim_chars) : 0; | 173 input.find_first_not_of(trim_chars) : 0; |
| 174 const typename STR::size_type last_good_char = (positions & TRIM_TRAILING) ? | 174 const size_t last_good_char = (positions & TRIM_TRAILING) ? |
| 175 input.find_last_not_of(trim_chars) : last_char; | 175 input.find_last_not_of(trim_chars) : last_char; |
| 176 | 176 |
| 177 // When the string was all whitespace, report that we stripped off whitespace | 177 // When the string was all whitespace, report that we stripped off whitespace |
| 178 // from whichever position the caller was interested in. For empty input, we | 178 // from whichever position the caller was interested in. For empty input, we |
| 179 // stripped no whitespace, but we still need to clear |output|. | 179 // stripped no whitespace, but we still need to clear |output|. |
| 180 if (input.empty() || | 180 if (input.empty() || |
| 181 (first_good_char == STR::npos) || (last_good_char == STR::npos)) { | 181 (first_good_char == STR::npos) || (last_good_char == STR::npos)) { |
| 182 bool input_was_empty = input.empty(); // in case output == &input | 182 bool input_was_empty = input.empty(); // in case output == &input |
| 183 output->clear(); | 183 output->clear(); |
| 184 return input_was_empty ? TRIM_NONE : positions; | 184 return input_was_empty ? TRIM_NONE : positions; |
| 185 } | 185 } |
| 186 | 186 |
| 187 // Trim the whitespace. | 187 // Trim the whitespace. |
| 188 *output = | 188 *output = |
| 189 input.substr(first_good_char, last_good_char - first_good_char + 1); | 189 input.substr(first_good_char, last_good_char - first_good_char + 1); |
| 190 | 190 |
| 191 // Return where we trimmed from. | 191 // Return where we trimmed from. |
| 192 return static_cast<TrimPositions>( | 192 return static_cast<TrimPositions>( |
| 193 ((first_good_char == 0) ? TRIM_NONE : TRIM_LEADING) | | 193 ((first_good_char == 0) ? TRIM_NONE : TRIM_LEADING) | |
| 194 ((last_good_char == last_char) ? TRIM_NONE : TRIM_TRAILING)); | 194 ((last_good_char == last_char) ? TRIM_NONE : TRIM_TRAILING)); |
| 195 } | 195 } |
| 196 | 196 |
| 197 bool TrimString(const string16& input, | 197 bool TrimString(const string16& input, |
| 198 const char16 trim_chars[], | 198 const base::StringPiece16& trim_chars, |
| 199 string16* output) { | 199 string16* output) { |
| 200 return TrimStringT(input, trim_chars, TRIM_ALL, output) != TRIM_NONE; | 200 return TrimStringT(input, trim_chars.as_string(), TRIM_ALL, output) != |
| 201 TRIM_NONE; |
| 201 } | 202 } |
| 202 | 203 |
| 203 bool TrimString(const std::string& input, | 204 bool TrimString(const std::string& input, |
| 204 const char trim_chars[], | 205 const base::StringPiece& trim_chars, |
| 205 std::string* output) { | 206 std::string* output) { |
| 206 return TrimStringT(input, trim_chars, TRIM_ALL, output) != TRIM_NONE; | 207 return TrimStringT(input, trim_chars.as_string(), TRIM_ALL, output) != |
| 208 TRIM_NONE; |
| 207 } | 209 } |
| 208 | 210 |
| 209 void TruncateUTF8ToByteSize(const std::string& input, | 211 void TruncateUTF8ToByteSize(const std::string& input, |
| 210 const size_t byte_size, | 212 const size_t byte_size, |
| 211 std::string* output) { | 213 std::string* output) { |
| 212 DCHECK(output); | 214 DCHECK(output); |
| 213 if (byte_size > input.length()) { | 215 if (byte_size > input.length()) { |
| 214 *output = input; | 216 *output = input; |
| 215 return; | 217 return; |
| 216 } | 218 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 238 | 240 |
| 239 if (char_index >= 0 ) | 241 if (char_index >= 0 ) |
| 240 *output = input.substr(0, char_index); | 242 *output = input.substr(0, char_index); |
| 241 else | 243 else |
| 242 output->clear(); | 244 output->clear(); |
| 243 } | 245 } |
| 244 | 246 |
| 245 TrimPositions TrimWhitespace(const string16& input, | 247 TrimPositions TrimWhitespace(const string16& input, |
| 246 TrimPositions positions, | 248 TrimPositions positions, |
| 247 string16* output) { | 249 string16* output) { |
| 248 return TrimStringT(input, kWhitespaceUTF16, positions, output); | 250 return TrimStringT(input, base::string16(kWhitespaceUTF16), positions, |
| 251 output); |
| 249 } | 252 } |
| 250 | 253 |
| 251 TrimPositions TrimWhitespaceASCII(const std::string& input, | 254 TrimPositions TrimWhitespaceASCII(const std::string& input, |
| 252 TrimPositions positions, | 255 TrimPositions positions, |
| 253 std::string* output) { | 256 std::string* output) { |
| 254 return TrimStringT(input, kWhitespaceASCII, positions, output); | 257 return TrimStringT(input, std::string(kWhitespaceASCII), positions, output); |
| 255 } | 258 } |
| 256 | 259 |
| 257 // This function is only for backward-compatibility. | 260 // This function is only for backward-compatibility. |
| 258 // To be removed when all callers are updated. | 261 // To be removed when all callers are updated. |
| 259 TrimPositions TrimWhitespace(const std::string& input, | 262 TrimPositions TrimWhitespace(const std::string& input, |
| 260 TrimPositions positions, | 263 TrimPositions positions, |
| 261 std::string* output) { | 264 std::string* output) { |
| 262 return TrimWhitespaceASCII(input, positions, output); | 265 return TrimWhitespaceASCII(input, positions, output); |
| 263 } | 266 } |
| 264 | 267 |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 } | 436 } |
| 434 } | 437 } |
| 435 | 438 |
| 436 bool StartsWith(const string16& str, const string16& search, | 439 bool StartsWith(const string16& str, const string16& search, |
| 437 bool case_sensitive) { | 440 bool case_sensitive) { |
| 438 return StartsWithT(str, search, case_sensitive); | 441 return StartsWithT(str, search, case_sensitive); |
| 439 } | 442 } |
| 440 | 443 |
| 441 template <typename STR> | 444 template <typename STR> |
| 442 bool EndsWithT(const STR& str, const STR& search, bool case_sensitive) { | 445 bool EndsWithT(const STR& str, const STR& search, bool case_sensitive) { |
| 443 typename STR::size_type str_length = str.length(); | 446 size_t str_length = str.length(); |
| 444 typename STR::size_type search_length = search.length(); | 447 size_t search_length = search.length(); |
| 445 if (search_length > str_length) | 448 if (search_length > str_length) |
| 446 return false; | 449 return false; |
| 447 if (case_sensitive) { | 450 if (case_sensitive) |
| 448 return str.compare(str_length - search_length, search_length, search) == 0; | 451 return str.compare(str_length - search_length, search_length, search) == 0; |
| 449 } else { | 452 return std::equal(search.begin(), search.end(), |
| 450 return std::equal(search.begin(), search.end(), | 453 str.begin() + (str_length - search_length), |
| 451 str.begin() + (str_length - search_length), | 454 base::CaseInsensitiveCompare<typename STR::value_type>()); |
| 452 base::CaseInsensitiveCompare<typename STR::value_type>()); | |
| 453 } | |
| 454 } | 455 } |
| 455 | 456 |
| 456 bool EndsWith(const std::string& str, const std::string& search, | 457 bool EndsWith(const std::string& str, const std::string& search, |
| 457 bool case_sensitive) { | 458 bool case_sensitive) { |
| 458 return EndsWithT(str, search, case_sensitive); | 459 return EndsWithT(str, search, case_sensitive); |
| 459 } | 460 } |
| 460 | 461 |
| 461 bool EndsWith(const string16& str, const string16& search, | 462 bool EndsWith(const string16& str, const string16& search, |
| 462 bool case_sensitive) { | 463 bool case_sensitive) { |
| 463 return EndsWithT(str, search, case_sensitive); | 464 return EndsWithT(str, search, case_sensitive); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 489 } else { | 490 } else { |
| 490 base::snprintf(buf, arraysize(buf), "%.0lf%s", unit_amount, | 491 base::snprintf(buf, arraysize(buf), "%.0lf%s", unit_amount, |
| 491 kByteStringsUnlocalized[dimension]); | 492 kByteStringsUnlocalized[dimension]); |
| 492 } | 493 } |
| 493 | 494 |
| 494 return base::ASCIIToUTF16(buf); | 495 return base::ASCIIToUTF16(buf); |
| 495 } | 496 } |
| 496 | 497 |
| 497 template<class StringType> | 498 template<class StringType> |
| 498 void DoReplaceSubstringsAfterOffset(StringType* str, | 499 void DoReplaceSubstringsAfterOffset(StringType* str, |
| 499 typename StringType::size_type start_offset, | 500 size_t start_offset, |
| 500 const StringType& find_this, | 501 const StringType& find_this, |
| 501 const StringType& replace_with, | 502 const StringType& replace_with, |
| 502 bool replace_all) { | 503 bool replace_all) { |
| 503 if ((start_offset == StringType::npos) || (start_offset >= str->length())) | 504 if ((start_offset == StringType::npos) || (start_offset >= str->length())) |
| 504 return; | 505 return; |
| 505 | 506 |
| 506 DCHECK(!find_this.empty()); | 507 DCHECK(!find_this.empty()); |
| 507 for (typename StringType::size_type offs(str->find(find_this, start_offset)); | 508 for (size_t offs(str->find(find_this, start_offset)); |
| 508 offs != StringType::npos; offs = str->find(find_this, offs)) { | 509 offs != StringType::npos; offs = str->find(find_this, offs)) { |
| 509 str->replace(offs, find_this.length(), replace_with); | 510 str->replace(offs, find_this.length(), replace_with); |
| 510 offs += replace_with.length(); | 511 offs += replace_with.length(); |
| 511 | 512 |
| 512 if (!replace_all) | 513 if (!replace_all) |
| 513 break; | 514 break; |
| 514 } | 515 } |
| 515 } | 516 } |
| 516 | 517 |
| 517 void ReplaceFirstSubstringAfterOffset(string16* str, | 518 void ReplaceFirstSubstringAfterOffset(string16* str, |
| 518 string16::size_type start_offset, | 519 size_t start_offset, |
| 519 const string16& find_this, | 520 const string16& find_this, |
| 520 const string16& replace_with) { | 521 const string16& replace_with) { |
| 521 DoReplaceSubstringsAfterOffset(str, start_offset, find_this, replace_with, | 522 DoReplaceSubstringsAfterOffset(str, start_offset, find_this, replace_with, |
| 522 false); // replace first instance | 523 false); // replace first instance |
| 523 } | 524 } |
| 524 | 525 |
| 525 void ReplaceFirstSubstringAfterOffset(std::string* str, | 526 void ReplaceFirstSubstringAfterOffset(std::string* str, |
| 526 std::string::size_type start_offset, | 527 size_t start_offset, |
| 527 const std::string& find_this, | 528 const std::string& find_this, |
| 528 const std::string& replace_with) { | 529 const std::string& replace_with) { |
| 529 DoReplaceSubstringsAfterOffset(str, start_offset, find_this, replace_with, | 530 DoReplaceSubstringsAfterOffset(str, start_offset, find_this, replace_with, |
| 530 false); // replace first instance | 531 false); // replace first instance |
| 531 } | 532 } |
| 532 | 533 |
| 533 void ReplaceSubstringsAfterOffset(string16* str, | 534 void ReplaceSubstringsAfterOffset(string16* str, |
| 534 string16::size_type start_offset, | 535 size_t start_offset, |
| 535 const string16& find_this, | 536 const string16& find_this, |
| 536 const string16& replace_with) { | 537 const string16& replace_with) { |
| 537 DoReplaceSubstringsAfterOffset(str, start_offset, find_this, replace_with, | 538 DoReplaceSubstringsAfterOffset(str, start_offset, find_this, replace_with, |
| 538 true); // replace all instances | 539 true); // replace all instances |
| 539 } | 540 } |
| 540 | 541 |
| 541 void ReplaceSubstringsAfterOffset(std::string* str, | 542 void ReplaceSubstringsAfterOffset(std::string* str, |
| 542 std::string::size_type start_offset, | 543 size_t start_offset, |
| 543 const std::string& find_this, | 544 const std::string& find_this, |
| 544 const std::string& replace_with) { | 545 const std::string& replace_with) { |
| 545 DoReplaceSubstringsAfterOffset(str, start_offset, find_this, replace_with, | 546 DoReplaceSubstringsAfterOffset(str, start_offset, find_this, replace_with, |
| 546 true); // replace all instances | 547 true); // replace all instances |
| 547 } | 548 } |
| 548 | 549 |
| 549 | 550 |
| 550 template<typename STR> | 551 template<typename STR> |
| 551 static size_t TokenizeT(const STR& str, | 552 static size_t TokenizeT(const STR& str, |
| 552 const STR& delimiters, | 553 const STR& delimiters, |
| 553 std::vector<STR>* tokens) { | 554 std::vector<STR>* tokens) { |
| 554 tokens->clear(); | 555 tokens->clear(); |
| 555 | 556 |
| 556 typename STR::size_type start = str.find_first_not_of(delimiters); | 557 size_t start = str.find_first_not_of(delimiters); |
| 557 while (start != STR::npos) { | 558 while (start != STR::npos) { |
| 558 typename STR::size_type end = str.find_first_of(delimiters, start + 1); | 559 size_t end = str.find_first_of(delimiters, start + 1); |
| 559 if (end == STR::npos) { | 560 if (end == STR::npos) { |
| 560 tokens->push_back(str.substr(start)); | 561 tokens->push_back(str.substr(start)); |
| 561 break; | 562 break; |
| 562 } else { | 563 } else { |
| 563 tokens->push_back(str.substr(start, end - start)); | 564 tokens->push_back(str.substr(start, end - start)); |
| 564 start = str.find_first_not_of(delimiters, end + 1); | 565 start = str.find_first_not_of(delimiters, end + 1); |
| 565 } | 566 } |
| 566 } | 567 } |
| 567 | 568 |
| 568 return tokens->size(); | 569 return tokens->size(); |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 887 } | 888 } |
| 888 | 889 |
| 889 } // namespace | 890 } // namespace |
| 890 | 891 |
| 891 size_t base::strlcpy(char* dst, const char* src, size_t dst_size) { | 892 size_t base::strlcpy(char* dst, const char* src, size_t dst_size) { |
| 892 return lcpyT<char>(dst, src, dst_size); | 893 return lcpyT<char>(dst, src, dst_size); |
| 893 } | 894 } |
| 894 size_t base::wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size) { | 895 size_t base::wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size) { |
| 895 return lcpyT<wchar_t>(dst, src, dst_size); | 896 return lcpyT<wchar_t>(dst, src, dst_size); |
| 896 } | 897 } |
| OLD | NEW |