string_split.cc (5545B)
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 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 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 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 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 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 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 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 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 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 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 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