xref: /aosp_15_r20/external/cronet/base/strings/string_split.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/strings/string_split.h"
6 
7 #include <stddef.h>
8 
9 #include "base/logging.h"
10 #include "base/strings/string_split_internal.h"
11 #include "base/strings/string_util.h"
12 #include "base/third_party/icu/icu_utf.h"
13 
14 namespace base {
15 
16 namespace {
17 
AppendStringKeyValue(StringPiece input,char delimiter,StringPairs * result)18 bool AppendStringKeyValue(StringPiece input,
19                           char delimiter,
20                           StringPairs* result) {
21   // Always append a new item regardless of success (it might be empty). The
22   // below code will copy the strings directly into the result pair.
23   result->resize(result->size() + 1);
24   auto& result_pair = result->back();
25 
26   // Find the delimiter.
27   size_t end_key_pos = input.find_first_of(delimiter);
28   if (end_key_pos == std::string::npos) {
29     DVLOG(1) << "cannot find delimiter in: " << input;
30     return false;    // No delimiter.
31   }
32   result_pair.first = std::string(input.substr(0, end_key_pos));
33 
34   // Find the value string.
35   StringPiece remains = input.substr(end_key_pos, input.size() - end_key_pos);
36   size_t begin_value_pos = remains.find_first_not_of(delimiter);
37   if (begin_value_pos == StringPiece::npos) {
38     DVLOG(1) << "cannot parse value from input: " << input;
39     return false;   // No value.
40   }
41 
42   result_pair.second = std::string(
43       remains.substr(begin_value_pos, remains.size() - begin_value_pos));
44 
45   return true;
46 }
47 
48 }  // namespace
49 
SplitString(StringPiece input,StringPiece separators,WhitespaceHandling whitespace,SplitResult result_type)50 std::vector<std::string> SplitString(StringPiece input,
51                                      StringPiece separators,
52                                      WhitespaceHandling whitespace,
53                                      SplitResult result_type) {
54   return internal::SplitStringT<std::string>(input, separators, whitespace,
55                                              result_type);
56 }
57 
SplitString(StringPiece16 input,StringPiece16 separators,WhitespaceHandling whitespace,SplitResult result_type)58 std::vector<std::u16string> SplitString(StringPiece16 input,
59                                         StringPiece16 separators,
60                                         WhitespaceHandling whitespace,
61                                         SplitResult result_type) {
62   return internal::SplitStringT<std::u16string>(input, separators, whitespace,
63                                                 result_type);
64 }
65 
SplitStringPiece(StringPiece input,StringPiece separators,WhitespaceHandling whitespace,SplitResult result_type)66 std::vector<StringPiece> SplitStringPiece(StringPiece input,
67                                           StringPiece separators,
68                                           WhitespaceHandling whitespace,
69                                           SplitResult result_type) {
70   return internal::SplitStringT<StringPiece>(input, separators, whitespace,
71                                              result_type);
72 }
73 
SplitStringPiece(StringPiece16 input,StringPiece16 separators,WhitespaceHandling whitespace,SplitResult result_type)74 std::vector<StringPiece16> SplitStringPiece(StringPiece16 input,
75                                             StringPiece16 separators,
76                                             WhitespaceHandling whitespace,
77                                             SplitResult result_type) {
78   return internal::SplitStringT<StringPiece16>(input, separators, whitespace,
79                                                result_type);
80 }
81 
SplitStringIntoKeyValuePairs(StringPiece input,char key_value_delimiter,char key_value_pair_delimiter,StringPairs * key_value_pairs)82 bool SplitStringIntoKeyValuePairs(StringPiece input,
83                                   char key_value_delimiter,
84                                   char key_value_pair_delimiter,
85                                   StringPairs* key_value_pairs) {
86   return SplitStringIntoKeyValuePairsUsingSubstr(
87       input, key_value_delimiter, StringPiece(&key_value_pair_delimiter, 1),
88       key_value_pairs);
89 }
90 
SplitStringIntoKeyValuePairsUsingSubstr(StringPiece input,char key_value_delimiter,StringPiece key_value_pair_delimiter,StringPairs * key_value_pairs)91 bool SplitStringIntoKeyValuePairsUsingSubstr(
92     StringPiece input,
93     char key_value_delimiter,
94     StringPiece key_value_pair_delimiter,
95     StringPairs* key_value_pairs) {
96   key_value_pairs->clear();
97 
98   std::vector<StringPiece> pairs = SplitStringPieceUsingSubstr(
99       input, key_value_pair_delimiter, TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY);
100   key_value_pairs->reserve(pairs.size());
101 
102   bool success = true;
103   for (const StringPiece& pair : pairs) {
104     if (!AppendStringKeyValue(pair, key_value_delimiter, key_value_pairs)) {
105       // Don't return here, to allow for pairs without associated
106       // value or key; just record that the split failed.
107       success = false;
108     }
109   }
110   return success;
111 }
112 
SplitStringUsingSubstr(StringPiece16 input,StringPiece16 delimiter,WhitespaceHandling whitespace,SplitResult result_type)113 std::vector<std::u16string> SplitStringUsingSubstr(
114     StringPiece16 input,
115     StringPiece16 delimiter,
116     WhitespaceHandling whitespace,
117     SplitResult result_type) {
118   return internal::SplitStringUsingSubstrT<std::u16string>(
119       input, delimiter, whitespace, result_type);
120 }
121 
SplitStringUsingSubstr(StringPiece input,StringPiece delimiter,WhitespaceHandling whitespace,SplitResult result_type)122 std::vector<std::string> SplitStringUsingSubstr(StringPiece input,
123                                                 StringPiece delimiter,
124                                                 WhitespaceHandling whitespace,
125                                                 SplitResult result_type) {
126   return internal::SplitStringUsingSubstrT<std::string>(
127       input, delimiter, whitespace, result_type);
128 }
129 
SplitStringPieceUsingSubstr(StringPiece16 input,StringPiece16 delimiter,WhitespaceHandling whitespace,SplitResult result_type)130 std::vector<StringPiece16> SplitStringPieceUsingSubstr(
131     StringPiece16 input,
132     StringPiece16 delimiter,
133     WhitespaceHandling whitespace,
134     SplitResult result_type) {
135   std::vector<StringPiece16> result;
136   return internal::SplitStringUsingSubstrT<StringPiece16>(
137       input, delimiter, whitespace, result_type);
138 }
139 
SplitStringPieceUsingSubstr(StringPiece input,StringPiece delimiter,WhitespaceHandling whitespace,SplitResult result_type)140 std::vector<StringPiece> SplitStringPieceUsingSubstr(
141     StringPiece input,
142     StringPiece delimiter,
143     WhitespaceHandling whitespace,
144     SplitResult result_type) {
145   return internal::SplitStringUsingSubstrT<StringPiece>(
146       input, delimiter, whitespace, result_type);
147 }
148 
149 }  // namespace base
150