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

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

Issue 184233010: Cleanup SplitStringIntoKeyaluePairs implementation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 9 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 | Annotate | Revision Log
« base/strings/string_split.h ('K') | « base/strings/string_split.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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_split.h" 5 #include "base/strings/string_split.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/strings/string_util.h" 8 #include "base/strings/string_util.h"
9 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
10 #include "base/third_party/icu/icu_utf.h" 10 #include "base/third_party/icu/icu_utf.h"
11 11
12 namespace base { 12 namespace base {
13 13
14 template<typename STR> 14 namespace {
15 static void SplitStringT(const STR& str, 15
16 const typename STR::value_type s, 16 template <typename STR>
17 bool trim_whitespace, 17 void SplitStringT(const STR& str,
18 std::vector<STR>* r) { 18 const typename STR::value_type s,
19 bool trim_whitespace,
20 std::vector<STR>* r) {
19 r->clear(); 21 r->clear();
20 size_t last = 0; 22 size_t last = 0;
21 size_t c = str.size(); 23 size_t c = str.size();
22 for (size_t i = 0; i <= c; ++i) { 24 for (size_t i = 0; i <= c; ++i) {
23 if (i == c || str[i] == s) { 25 if (i == c || str[i] == s) {
24 STR tmp(str, last, i - last); 26 STR tmp(str, last, i - last);
25 if (trim_whitespace) 27 if (trim_whitespace)
26 TrimWhitespace(tmp, TRIM_ALL, &tmp); 28 TrimWhitespace(tmp, TRIM_ALL, &tmp);
27 // Avoid converting an empty or all-whitespace source string into a vector 29 // Avoid converting an empty or all-whitespace source string into a vector
28 // of one empty string. 30 // of one empty string.
29 if (i != c || !r->empty() || !tmp.empty()) 31 if (i != c || !r->empty() || !tmp.empty())
30 r->push_back(tmp); 32 r->push_back(tmp);
31 last = i + 1; 33 last = i + 1;
32 } 34 }
33 } 35 }
34 } 36 }
35 37
38 bool SplitStringIntoKeyValue(const std::string& line,
39 char key_value_delimiter,
40 std::string* key,
41 std::string* value) {
42 key->clear();
43 value->clear();
44
45 // Find the delimiter.
46 size_t end_key_pos = line.find_first_of(key_value_delimiter);
47 if (end_key_pos == std::string::npos) {
48 DVLOG(1) << "cannot find delimiter in: " << line;
49 return false; // no delimiter
50 }
51 key->assign(line, 0, end_key_pos);
52
53 // Find the value string.
54 std::string remains(line, end_key_pos, line.size() - end_key_pos);
55 size_t begin_value_pos = remains.find_first_not_of(key_value_delimiter);
56 if (begin_value_pos == std::string::npos) {
57 DVLOG(1) << "cannot parse value from line: " << line;
58 return false; // no value
59 }
60 value->assign(remains, begin_value_pos, remains.size() - begin_value_pos);
61 return true;
62 }
63
64 } // namespace
65
36 void SplitString(const string16& str, 66 void SplitString(const string16& str,
37 char16 c, 67 char16 c,
38 std::vector<string16>* r) { 68 std::vector<string16>* r) {
39 DCHECK(CBU16_IS_SINGLE(c)); 69 DCHECK(CBU16_IS_SINGLE(c));
40 SplitStringT(str, c, true, r); 70 SplitStringT(str, c, true, r);
41 } 71 }
42 72
43 void SplitString(const std::string& str, 73 void SplitString(const std::string& str,
44 char c, 74 char c,
45 std::vector<std::string>* r) { 75 std::vector<std::string>* r) {
46 #if CHAR_MIN < 0 76 #if CHAR_MIN < 0
47 DCHECK(c >= 0); 77 DCHECK(c >= 0);
48 #endif 78 #endif
49 DCHECK(c < 0x7F); 79 DCHECK(c < 0x7F);
50 SplitStringT(str, c, true, r); 80 SplitStringT(str, c, true, r);
51 } 81 }
52 82
53 bool SplitStringIntoKeyValues(
54 const std::string& line,
55 char key_value_delimiter,
56 std::string* key, std::vector<std::string>* values) {
57 key->clear();
58 values->clear();
59
60 // Find the key string.
61 size_t end_key_pos = line.find_first_of(key_value_delimiter);
62 if (end_key_pos == std::string::npos) {
63 DVLOG(1) << "cannot parse key from line: " << line;
64 return false; // no key
65 }
66 key->assign(line, 0, end_key_pos);
67
68 // Find the values string.
69 std::string remains(line, end_key_pos, line.size() - end_key_pos);
70 size_t begin_values_pos = remains.find_first_not_of(key_value_delimiter);
71 if (begin_values_pos == std::string::npos) {
72 DVLOG(1) << "cannot parse value from line: " << line;
73 return false; // no value
74 }
75 std::string values_string(remains, begin_values_pos,
76 remains.size() - begin_values_pos);
77
78 // Construct the values vector.
79 values->push_back(values_string);
80 return true;
81 }
82
83 bool SplitStringIntoKeyValuePairs(const std::string& line, 83 bool SplitStringIntoKeyValuePairs(const std::string& line,
84 char key_value_delimiter, 84 char key_value_delimiter,
85 char key_value_pair_delimiter, 85 char key_value_pair_delimiter,
86 StringPairs* key_value_pairs) { 86 StringPairs* key_value_pairs) {
87 key_value_pairs->clear(); 87 key_value_pairs->clear();
88 88
89 std::vector<std::string> pairs; 89 std::vector<std::string> pairs;
90 SplitString(line, key_value_pair_delimiter, &pairs); 90 SplitString(line, key_value_pair_delimiter, &pairs);
91 91
92 bool success = true; 92 bool success = true;
93 for (size_t i = 0; i < pairs.size(); ++i) { 93 for (size_t i = 0; i < pairs.size(); ++i) {
94 // Empty pair. SplitStringIntoKeyValues is more strict about an empty pair 94 // Don't add empty pairs into the result.
Mark Mentovai 2014/03/06 17:55:51 This is empty pairs after whitespace trimming. Des
95 // line, so continue with the next pair.
96 if (pairs[i].empty()) 95 if (pairs[i].empty())
97 continue; 96 continue;
98 97
99 std::string key; 98 std::string key;
100 std::vector<std::string> value; 99 std::string value;
101 if (!SplitStringIntoKeyValues(pairs[i], 100 if (!SplitStringIntoKeyValue(pairs[i], key_value_delimiter, &key, &value)) {
Mark Mentovai 2014/03/06 17:55:51 This whole thing would be better with StringPieces
102 key_value_delimiter, 101 // Don't return here, to allow for pairs without associated
103 &key, &value)) { 102 // value or key; just record that our split failed.
Mark Mentovai 2014/03/06 17:55:51 our split -> the split See the test CL. I’m not s
pneubeck (no reviews) 2014/03/07 17:12:11 Done.
104 // Don't return here, to allow for keys without associated
105 // values; just record that our split failed.
106 success = false; 103 success = false;
107 } 104 }
108 DCHECK_LE(value.size(), 1U); 105 DCHECK_LE(value.size(), 1U);
Mark Mentovai 2014/03/06 17:55:51 ?
pneubeck (no reviews) 2014/03/07 17:12:11 Ouch. yes that has to be removed. Done.
109 key_value_pairs->push_back( 106 key_value_pairs->push_back(make_pair(key, value));
110 make_pair(key, value.empty() ? std::string() : value[0]));
111 } 107 }
112 return success; 108 return success;
113 } 109 }
114 110
115 template <typename STR> 111 template <typename STR>
116 static void SplitStringUsingSubstrT(const STR& str, 112 static void SplitStringUsingSubstrT(const STR& str,
117 const STR& s, 113 const STR& s,
118 std::vector<STR>* r) { 114 std::vector<STR>* r) {
119 r->clear(); 115 r->clear();
120 typename STR::size_type begin_index = 0; 116 typename STR::size_type begin_index = 0;
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 std::vector<string16>* result) { 206 std::vector<string16>* result) {
211 SplitStringAlongWhitespaceT(str, result); 207 SplitStringAlongWhitespaceT(str, result);
212 } 208 }
213 209
214 void SplitStringAlongWhitespace(const std::string& str, 210 void SplitStringAlongWhitespace(const std::string& str,
215 std::vector<std::string>* result) { 211 std::vector<std::string>* result) {
216 SplitStringAlongWhitespaceT(str, result); 212 SplitStringAlongWhitespaceT(str, result);
217 } 213 }
218 214
219 } // namespace base 215 } // namespace base
OLDNEW
« base/strings/string_split.h ('K') | « base/strings/string_split.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698