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
3 // found in the LICENSE file.
5 #include "base/strings/string_split.h"
7 #include "base/logging.h"
8 #include "base/strings/string_util.h"
9 #include "base/third_party/icu/icu_utf.h"
15 template <typename STR
>
16 void SplitStringT(const STR
& str
,
17 const typename
STR::value_type s
,
19 std::vector
<STR
>* r
) {
22 size_t c
= str
.size();
23 for (size_t i
= 0; i
<= c
; ++i
) {
24 if (i
== c
|| str
[i
] == s
) {
25 STR
tmp(str
, last
, i
- last
);
27 TrimWhitespace(tmp
, TRIM_ALL
, &tmp
);
28 // Avoid converting an empty or all-whitespace source string into a vector
29 // of one empty string.
30 if (i
!= c
|| !r
->empty() || !tmp
.empty())
37 bool SplitStringIntoKeyValue(const std::string
& line
,
38 char key_value_delimiter
,
44 // Find the delimiter.
45 size_t end_key_pos
= line
.find_first_of(key_value_delimiter
);
46 if (end_key_pos
== std::string::npos
) {
47 DVLOG(1) << "cannot find delimiter in: " << line
;
48 return false; // no delimiter
50 key
->assign(line
, 0, end_key_pos
);
52 // Find the value string.
53 std::string
remains(line
, end_key_pos
, line
.size() - end_key_pos
);
54 size_t begin_value_pos
= remains
.find_first_not_of(key_value_delimiter
);
55 if (begin_value_pos
== std::string::npos
) {
56 DVLOG(1) << "cannot parse value from line: " << line
;
57 return false; // no value
59 value
->assign(remains
, begin_value_pos
, remains
.size() - begin_value_pos
);
63 template <typename STR
>
64 void SplitStringUsingSubstrT(const STR
& str
,
66 std::vector
<STR
>* r
) {
68 typename
STR::size_type begin_index
= 0;
70 const typename
STR::size_type end_index
= str
.find(s
, begin_index
);
71 if (end_index
== STR::npos
) {
72 const STR term
= str
.substr(begin_index
);
74 TrimWhitespace(term
, TRIM_ALL
, &tmp
);
78 const STR term
= str
.substr(begin_index
, end_index
- begin_index
);
80 TrimWhitespace(term
, TRIM_ALL
, &tmp
);
82 begin_index
= end_index
+ s
.size();
86 template<typename STR
>
87 void SplitStringAlongWhitespaceT(const STR
& str
, std::vector
<STR
>* result
) {
89 const size_t length
= str
.length();
93 bool last_was_ws
= false;
94 size_t last_non_ws_start
= 0;
95 for (size_t i
= 0; i
< length
; ++i
) {
97 // HTML 5 defines whitespace as: space, tab, LF, line tab, FF, or CR.
107 str
.substr(last_non_ws_start
, i
- last_non_ws_start
));
113 default: // Not a space character.
116 last_non_ws_start
= i
;
123 str
.substr(last_non_ws_start
, length
- last_non_ws_start
));
129 void SplitString(const string16
& str
,
131 std::vector
<string16
>* r
) {
132 DCHECK(CBU16_IS_SINGLE(c
));
133 SplitStringT(str
, c
, true, r
);
136 void SplitString(const std::string
& str
,
138 std::vector
<std::string
>* r
) {
143 SplitStringT(str
, c
, true, r
);
146 bool SplitStringIntoKeyValuePairs(const std::string
& line
,
147 char key_value_delimiter
,
148 char key_value_pair_delimiter
,
149 StringPairs
* key_value_pairs
) {
150 key_value_pairs
->clear();
152 std::vector
<std::string
> pairs
;
153 SplitString(line
, key_value_pair_delimiter
, &pairs
);
156 for (size_t i
= 0; i
< pairs
.size(); ++i
) {
157 // Don't add empty pairs into the result.
158 if (pairs
[i
].empty())
163 if (!SplitStringIntoKeyValue(pairs
[i
], key_value_delimiter
, &key
, &value
)) {
164 // Don't return here, to allow for pairs without associated
165 // value or key; just record that the split failed.
168 key_value_pairs
->push_back(make_pair(key
, value
));
173 void SplitStringUsingSubstr(const string16
& str
,
175 std::vector
<string16
>* r
) {
176 SplitStringUsingSubstrT(str
, s
, r
);
179 void SplitStringUsingSubstr(const std::string
& str
,
180 const std::string
& s
,
181 std::vector
<std::string
>* r
) {
182 SplitStringUsingSubstrT(str
, s
, r
);
185 void SplitStringDontTrim(const string16
& str
,
187 std::vector
<string16
>* r
) {
188 DCHECK(CBU16_IS_SINGLE(c
));
189 SplitStringT(str
, c
, false, r
);
192 void SplitStringDontTrim(const std::string
& str
,
194 std::vector
<std::string
>* r
) {
199 SplitStringT(str
, c
, false, r
);
202 void SplitStringAlongWhitespace(const string16
& str
,
203 std::vector
<string16
>* result
) {
204 SplitStringAlongWhitespaceT(str
, result
);
207 void SplitStringAlongWhitespace(const std::string
& str
,
208 std::vector
<std::string
>* result
) {
209 SplitStringAlongWhitespaceT(str
, result
);