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