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

Unified Diff: base/strings/string_split.cc

Issue 1291103002: Updates to StringSplit implementation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/strings/string_split.h ('k') | base/strings/string_util.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/strings/string_split.cc
diff --git a/base/strings/string_split.cc b/base/strings/string_split.cc
index b01ca66dea7476ff331a0a111e86d18617e0e5ee..4253e2f8f86b7ed393dfdf66193b91b489176bf8 100644
--- a/base/strings/string_split.cc
+++ b/base/strings/string_split.cc
@@ -99,52 +99,57 @@ static std::vector<OutputStringType> SplitStringT(
return result;
}
-bool SplitStringIntoKeyValue(const std::string& line,
- char key_value_delimiter,
- std::string* key,
- std::string* value) {
- key->clear();
- value->clear();
+bool AppendStringKeyValue(StringPiece input,
+ char delimiter,
+ StringPairs* result) {
+ // Always append a new item regardless of success (it might be empty). The
+ // below code will copy the strings directly into the result pair.
+ result->resize(result->size() + 1);
+ auto& result_pair = result->back();
// Find the delimiter.
- size_t end_key_pos = line.find_first_of(key_value_delimiter);
+ size_t end_key_pos = input.find_first_of(delimiter);
if (end_key_pos == std::string::npos) {
- DVLOG(1) << "cannot find delimiter in: " << line;
- return false; // no delimiter
+ DVLOG(1) << "cannot find delimiter in: " << input;
+ return false; // No delimiter.
}
- key->assign(line, 0, end_key_pos);
+ input.substr(0, end_key_pos).CopyToString(&result_pair.first);
// Find the value string.
- std::string remains(line, end_key_pos, line.size() - end_key_pos);
- size_t begin_value_pos = remains.find_first_not_of(key_value_delimiter);
- if (begin_value_pos == std::string::npos) {
- DVLOG(1) << "cannot parse value from line: " << line;
- return false; // no value
+ StringPiece remains = input.substr(end_key_pos, input.size() - end_key_pos);
+ size_t begin_value_pos = remains.find_first_not_of(delimiter);
+ if (begin_value_pos == StringPiece::npos) {
+ DVLOG(1) << "cannot parse value from input: " << input;
+ return false; // No value.
}
- value->assign(remains, begin_value_pos, remains.size() - begin_value_pos);
+ remains.substr(begin_value_pos, remains.size() - begin_value_pos)
+ .CopyToString(&result_pair.second);
+
return true;
}
-template <typename STR>
-void SplitStringUsingSubstrT(const STR& str,
- const STR& s,
- std::vector<STR>* r) {
- r->clear();
- typename STR::size_type begin_index = 0;
+template <typename Str>
+void SplitStringUsingSubstrT(BasicStringPiece<Str> input,
+ BasicStringPiece<Str> delimiter,
+ std::vector<Str>* result) {
+ using Piece = BasicStringPiece<Str>;
+ using size_type = typename Piece::size_type;
+
+ result->clear();
+ size_type begin_index = 0;
while (true) {
- const typename STR::size_type end_index = str.find(s, begin_index);
- if (end_index == STR::npos) {
- const STR term = str.substr(begin_index);
- STR tmp;
- TrimWhitespace(term, TRIM_ALL, &tmp);
- r->push_back(tmp);
+ size_type end_index = input.find(delimiter, begin_index);
+ if (end_index == Piece::npos) {
+ // No delimiter, use the rest of the string.
+ Piece term = TrimString(input.substr(begin_index),
+ WhitespaceForType<Str>(), TRIM_ALL);
+ result->push_back(term.as_string());
return;
}
- const STR term = str.substr(begin_index, end_index - begin_index);
- STR tmp;
- TrimWhitespace(term, TRIM_ALL, &tmp);
- r->push_back(tmp);
- begin_index = end_index + s.size();
+ Piece term = TrimString(input.substr(begin_index, end_index - begin_index),
+ WhitespaceForType<Str>(), TRIM_ALL);
+ result->push_back(term.as_string());
+ begin_index = end_index + delimiter.size();
}
}
@@ -198,77 +203,38 @@ std::vector<StringPiece16> SplitStringPiece(StringPiece16 input,
input, separators, whitespace, result_type);
}
-void SplitString(const string16& str,
- char16 c,
- std::vector<string16>* result) {
- DCHECK(CBU16_IS_SINGLE(c));
- *result = SplitStringT<string16, string16, char16>(
- str, c, TRIM_WHITESPACE, SPLIT_WANT_ALL);
-
- // Backward-compat hack: The old SplitString implementation would keep
- // empty substrings, for example:
- // "a,,b" -> ["a", "", "b"]
- // "a, ,b" -> ["a", "", "b"]
- // which the current code also does. But the old one would discard them when
- // the only result was that empty string:
- // " " -> []
- // In the latter case, our new code will give [""]
- if (result->size() == 1 && (*result)[0].empty())
- result->clear();
-}
-
-void SplitString(const std::string& str,
- char c,
- std::vector<std::string>* result) {
-#if CHAR_MIN < 0
- DCHECK_GE(c, 0);
-#endif
- DCHECK_LT(c, 0x7F);
- *result = SplitStringT<std::string, std::string, char>(
- str, c, TRIM_WHITESPACE, SPLIT_WANT_ALL);
-
- // Backward-compat hack, see above.
- if (result->size() == 1 && (*result)[0].empty())
- result->clear();
-}
-
-bool SplitStringIntoKeyValuePairs(const std::string& line,
+bool SplitStringIntoKeyValuePairs(StringPiece input,
char key_value_delimiter,
char key_value_pair_delimiter,
StringPairs* key_value_pairs) {
key_value_pairs->clear();
- std::vector<std::string> pairs;
- SplitString(line, key_value_pair_delimiter, &pairs);
+ std::vector<StringPiece> pairs = SplitStringPiece(
+ input, std::string(1, key_value_pair_delimiter),
+ TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY);
+ key_value_pairs->reserve(pairs.size());
bool success = true;
- for (size_t i = 0; i < pairs.size(); ++i) {
- // Don't add empty pairs into the result.
- if (pairs[i].empty())
- continue;
-
- std::string key;
- std::string value;
- if (!SplitStringIntoKeyValue(pairs[i], key_value_delimiter, &key, &value)) {
+ for (const StringPiece& pair : pairs) {
+ if (!AppendStringKeyValue(pair, key_value_delimiter, key_value_pairs)) {
// Don't return here, to allow for pairs without associated
// value or key; just record that the split failed.
success = false;
}
- key_value_pairs->push_back(make_pair(key, value));
}
return success;
}
-void SplitStringUsingSubstr(const string16& str,
- const string16& s,
- std::vector<string16>* r) {
- SplitStringUsingSubstrT(str, s, r);
+void SplitStringUsingSubstr(StringPiece16 input,
+ StringPiece16 delimiter,
+ std::vector<string16>* result) {
+ SplitStringUsingSubstrT(input, delimiter, result);
}
-void SplitStringUsingSubstr(const std::string& str,
- const std::string& s,
- std::vector<std::string>* r) {
- SplitStringUsingSubstrT(str, s, r);
+void SplitStringUsingSubstr(StringPiece input,
+ StringPiece delimiter,
+ std::vector<std::string>* result) {
+ SplitStringUsingSubstrT(input, delimiter, result);
}
} // namespace base
« no previous file with comments | « base/strings/string_split.h ('k') | base/strings/string_util.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698