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