Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(147)

Side by Side Diff: base/strings/string_util.cc

Issue 1169393003: Add new SplitString backend. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/strings/string_util.h ('k') | base/strings/string_util_constants.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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>
11 #include <stdio.h> 11 #include <stdio.h>
12 #include <stdlib.h> 12 #include <stdlib.h>
13 #include <string.h> 13 #include <string.h>
14 #include <time.h> 14 #include <time.h>
15 #include <wchar.h> 15 #include <wchar.h>
16 #include <wctype.h> 16 #include <wctype.h>
17 17
18 #include <algorithm> 18 #include <algorithm>
19 #include <vector> 19 #include <vector>
20 20
21 #include "base/basictypes.h" 21 #include "base/basictypes.h"
22 #include "base/logging.h" 22 #include "base/logging.h"
23 #include "base/memory/singleton.h" 23 #include "base/memory/singleton.h"
24 #include "base/strings/string_split.h"
24 #include "base/strings/utf_string_conversion_utils.h" 25 #include "base/strings/utf_string_conversion_utils.h"
25 #include "base/strings/utf_string_conversions.h" 26 #include "base/strings/utf_string_conversions.h"
26 #include "base/third_party/icu/icu_utf.h" 27 #include "base/third_party/icu/icu_utf.h"
27 #include "build/build_config.h" 28 #include "build/build_config.h"
28 29
29 // Remove when this entire file is in the base namespace. 30 // Remove when this entire file is in the base namespace.
30 using base::char16; 31 using base::char16;
31 using base::string16; 32 using base::string16;
32 33
33 namespace { 34 namespace {
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 string16* output) { 187 string16* output) {
187 return ReplaceChars(input, remove_chars.as_string(), string16(), output); 188 return ReplaceChars(input, remove_chars.as_string(), string16(), output);
188 } 189 }
189 190
190 bool RemoveChars(const std::string& input, 191 bool RemoveChars(const std::string& input,
191 const base::StringPiece& remove_chars, 192 const base::StringPiece& remove_chars,
192 std::string* output) { 193 std::string* output) {
193 return ReplaceChars(input, remove_chars.as_string(), std::string(), output); 194 return ReplaceChars(input, remove_chars.as_string(), std::string(), output);
194 } 195 }
195 196
196 template<typename STR> 197 template<typename Str>
197 TrimPositions TrimStringT(const STR& input, 198 TrimPositions TrimStringT(const Str& input,
198 const STR& trim_chars, 199 BasicStringPiece<Str> trim_chars,
199 TrimPositions positions, 200 TrimPositions positions,
200 STR* output) { 201 Str* output) {
201 // Find the edges of leading/trailing whitespace as desired. 202 // Find the edges of leading/trailing whitespace as desired. Need to use
203 // a StringPiece version of input to be able to call find* on it with the
204 // StringPiece version of trim_chars (normally the trim_chars will be a
205 // constant so avoid making a copy).
206 BasicStringPiece<Str> input_piece(input);
202 const size_t last_char = input.length() - 1; 207 const size_t last_char = input.length() - 1;
203 const size_t first_good_char = (positions & TRIM_LEADING) ? 208 const size_t first_good_char = (positions & TRIM_LEADING) ?
204 input.find_first_not_of(trim_chars) : 0; 209 input_piece.find_first_not_of(trim_chars) : 0;
205 const size_t last_good_char = (positions & TRIM_TRAILING) ? 210 const size_t last_good_char = (positions & TRIM_TRAILING) ?
206 input.find_last_not_of(trim_chars) : last_char; 211 input_piece.find_last_not_of(trim_chars) : last_char;
207 212
208 // When the string was all whitespace, report that we stripped off whitespace 213 // When the string was all trimmed, report that we stripped off characters
209 // from whichever position the caller was interested in. For empty input, we 214 // from whichever position the caller was interested in. For empty input, we
210 // stripped no whitespace, but we still need to clear |output|. 215 // stripped no characters, but we still need to clear |output|.
211 if (input.empty() || 216 if (input.empty() ||
212 (first_good_char == STR::npos) || (last_good_char == STR::npos)) { 217 (first_good_char == Str::npos) || (last_good_char == Str::npos)) {
213 bool input_was_empty = input.empty(); // in case output == &input 218 bool input_was_empty = input.empty(); // in case output == &input
214 output->clear(); 219 output->clear();
215 return input_was_empty ? TRIM_NONE : positions; 220 return input_was_empty ? TRIM_NONE : positions;
216 } 221 }
217 222
218 // Trim the whitespace. 223 // Trim.
219 *output = 224 *output =
220 input.substr(first_good_char, last_good_char - first_good_char + 1); 225 input.substr(first_good_char, last_good_char - first_good_char + 1);
221 226
222 // Return where we trimmed from. 227 // Return where we trimmed from.
223 return static_cast<TrimPositions>( 228 return static_cast<TrimPositions>(
224 ((first_good_char == 0) ? TRIM_NONE : TRIM_LEADING) | 229 ((first_good_char == 0) ? TRIM_NONE : TRIM_LEADING) |
225 ((last_good_char == last_char) ? TRIM_NONE : TRIM_TRAILING)); 230 ((last_good_char == last_char) ? TRIM_NONE : TRIM_TRAILING));
226 } 231 }
227 232
228 bool TrimString(const string16& input, 233 bool TrimString(const string16& input,
229 const base::StringPiece16& trim_chars, 234 base::StringPiece16 trim_chars,
230 string16* output) { 235 string16* output) {
231 return TrimStringT(input, trim_chars.as_string(), TRIM_ALL, output) != 236 return TrimStringT(input, trim_chars, TRIM_ALL, output) != TRIM_NONE;
232 TRIM_NONE;
233 } 237 }
234 238
235 bool TrimString(const std::string& input, 239 bool TrimString(const std::string& input,
236 const base::StringPiece& trim_chars, 240 base::StringPiece trim_chars,
237 std::string* output) { 241 std::string* output) {
238 return TrimStringT(input, trim_chars.as_string(), TRIM_ALL, output) != 242 return TrimStringT(input, trim_chars, TRIM_ALL, output) != TRIM_NONE;
239 TRIM_NONE; 243 }
244
245 template<typename Str>
246 BasicStringPiece<Str> TrimStringPieceT(BasicStringPiece<Str> input,
247 BasicStringPiece<Str> trim_chars,
248 TrimPositions positions) {
249 size_t begin = (positions & TRIM_LEADING) ?
250 input.find_first_not_of(trim_chars) : 0;
251 size_t end = (positions & TRIM_TRAILING) ?
252 input.find_last_not_of(trim_chars) + 1 : input.size();
253 return input.substr(begin, end - begin);
254 }
255
256 StringPiece16 TrimString(StringPiece16 input,
257 const base::StringPiece16& trim_chars,
258 TrimPositions positions) {
259 return TrimStringPieceT(input, trim_chars, positions);
260 }
261
262 StringPiece TrimString(StringPiece input,
263 const base::StringPiece& trim_chars,
264 TrimPositions positions) {
265 return TrimStringPieceT(input, trim_chars, positions);
240 } 266 }
241 267
242 void TruncateUTF8ToByteSize(const std::string& input, 268 void TruncateUTF8ToByteSize(const std::string& input,
243 const size_t byte_size, 269 const size_t byte_size,
244 std::string* output) { 270 std::string* output) {
245 DCHECK(output); 271 DCHECK(output);
246 if (byte_size > input.length()) { 272 if (byte_size > input.length()) {
247 *output = input; 273 *output = input;
248 return; 274 return;
249 } 275 }
(...skipping 21 matching lines...) Expand all
271 297
272 if (char_index >= 0 ) 298 if (char_index >= 0 )
273 *output = input.substr(0, char_index); 299 *output = input.substr(0, char_index);
274 else 300 else
275 output->clear(); 301 output->clear();
276 } 302 }
277 303
278 TrimPositions TrimWhitespace(const string16& input, 304 TrimPositions TrimWhitespace(const string16& input,
279 TrimPositions positions, 305 TrimPositions positions,
280 string16* output) { 306 string16* output) {
281 return TrimStringT(input, base::string16(kWhitespaceUTF16), positions, 307 return TrimStringT(input, StringPiece16(kWhitespaceUTF16), positions, output);
282 output);
283 } 308 }
284 309
285 TrimPositions TrimWhitespaceASCII(const std::string& input, 310 TrimPositions TrimWhitespaceASCII(const std::string& input,
286 TrimPositions positions, 311 TrimPositions positions,
287 std::string* output) { 312 std::string* output) {
288 return TrimStringT(input, std::string(kWhitespaceASCII), positions, output); 313 return TrimStringT(input, StringPiece(kWhitespaceASCII), positions, output);
289 } 314 }
290 315
291 // This function is only for backward-compatibility. 316 // This function is only for backward-compatibility.
292 // To be removed when all callers are updated. 317 // To be removed when all callers are updated.
293 TrimPositions TrimWhitespace(const std::string& input, 318 TrimPositions TrimWhitespace(const std::string& input,
294 TrimPositions positions, 319 TrimPositions positions,
295 std::string* output) { 320 std::string* output) {
296 return TrimWhitespaceASCII(input, positions, output); 321 return TrimWhitespaceASCII(input, positions, output);
297 } 322 }
298 323
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
689 } 714 }
690 715
691 void ReplaceSubstringsAfterOffset(std::string* str, 716 void ReplaceSubstringsAfterOffset(std::string* str,
692 size_t start_offset, 717 size_t start_offset,
693 const std::string& find_this, 718 const std::string& find_this,
694 const std::string& replace_with) { 719 const std::string& replace_with) {
695 DoReplaceSubstringsAfterOffset(str, start_offset, find_this, replace_with, 720 DoReplaceSubstringsAfterOffset(str, start_offset, find_this, replace_with,
696 true); // replace all instances 721 true); // replace all instances
697 } 722 }
698 723
699 724 size_t Tokenize(const base::string16& str,
700 template<typename STR> 725 const base::string16& delimiters,
701 static size_t TokenizeT(const STR& str, 726 std::vector<base::string16>* tokens) {
702 const STR& delimiters, 727 *tokens = base::SplitString(
703 std::vector<STR>* tokens) { 728 str, delimiters, base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
704 tokens->clear();
705
706 size_t start = str.find_first_not_of(delimiters);
707 while (start != STR::npos) {
708 size_t end = str.find_first_of(delimiters, start + 1);
709 if (end == STR::npos) {
710 tokens->push_back(str.substr(start));
711 break;
712 } else {
713 tokens->push_back(str.substr(start, end - start));
714 start = str.find_first_not_of(delimiters, end + 1);
715 }
716 }
717
718 return tokens->size(); 729 return tokens->size();
719 } 730 }
720 731
721 size_t Tokenize(const string16& str,
722 const string16& delimiters,
723 std::vector<string16>* tokens) {
724 return TokenizeT(str, delimiters, tokens);
725 }
726
727 size_t Tokenize(const std::string& str, 732 size_t Tokenize(const std::string& str,
728 const std::string& delimiters, 733 const std::string& delimiters,
729 std::vector<std::string>* tokens) { 734 std::vector<std::string>* tokens) {
730 return TokenizeT(str, delimiters, tokens); 735 *tokens = base::SplitString(
736 str, delimiters, base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
737 return tokens->size();
731 } 738 }
732 739
733 size_t Tokenize(const base::StringPiece& str, 740 size_t Tokenize(const base::StringPiece& str,
734 const base::StringPiece& delimiters, 741 const base::StringPiece& delimiters,
735 std::vector<base::StringPiece>* tokens) { 742 std::vector<base::StringPiece>* tokens) {
736 return TokenizeT(str, delimiters, tokens); 743 *tokens = base::SplitStringPiece(
744 str, delimiters, base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
745 return tokens->size();
737 } 746 }
738 747
739 template<typename STR> 748 template<typename STR>
740 static STR JoinStringT(const std::vector<STR>& parts, const STR& sep) { 749 static STR JoinStringT(const std::vector<STR>& parts, const STR& sep) {
741 if (parts.empty()) 750 if (parts.empty())
742 return STR(); 751 return STR();
743 752
744 STR result(parts[0]); 753 STR result(parts[0]);
745 typename std::vector<STR>::const_iterator iter = parts.begin(); 754 typename std::vector<STR>::const_iterator iter = parts.begin();
746 ++iter; 755 ++iter;
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
1037 } 1046 }
1038 1047
1039 } // namespace 1048 } // namespace
1040 1049
1041 size_t base::strlcpy(char* dst, const char* src, size_t dst_size) { 1050 size_t base::strlcpy(char* dst, const char* src, size_t dst_size) {
1042 return lcpyT<char>(dst, src, dst_size); 1051 return lcpyT<char>(dst, src, dst_size);
1043 } 1052 }
1044 size_t base::wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size) { 1053 size_t base::wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size) {
1045 return lcpyT<wchar_t>(dst, src, dst_size); 1054 return lcpyT<wchar_t>(dst, src, dst_size);
1046 } 1055 }
OLDNEW
« no previous file with comments | « base/strings/string_util.h ('k') | base/strings/string_util_constants.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698