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 |