string_split_internal.h (3024B)
1 // Copyright 2020 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 #ifndef BASE_STRINGS_STRING_SPLIT_INTERNAL_H_ 6 #define BASE_STRINGS_STRING_SPLIT_INTERNAL_H_ 7 8 #include <vector> 9 10 #include "base/strings/string_piece.h" 11 #include "base/strings/string_util.h" 12 13 namespace base { 14 15 namespace internal { 16 17 // Returns either the ASCII or UTF-16 whitespace. 18 template <typename CharT> 19 BasicStringPiece<CharT> WhitespaceForType(); 20 21 template <> 22 inline StringPiece16 WhitespaceForType<char16_t>() { 23 return kWhitespaceUTF16; 24 } 25 template <> 26 inline StringPiece WhitespaceForType<char>() { 27 return kWhitespaceASCII; 28 } 29 30 // General string splitter template. Can take 8- or 16-bit input, can produce 31 // the corresponding string or StringPiece output. 32 template <typename OutputStringType, 33 typename T, 34 typename CharT = typename T::value_type> 35 static std::vector<OutputStringType> SplitStringT(T str, 36 T delimiter, 37 WhitespaceHandling whitespace, 38 SplitResult result_type) { 39 std::vector<OutputStringType> result; 40 if (str.empty()) 41 return result; 42 43 size_t start = 0; 44 while (start != std::basic_string<CharT>::npos) { 45 size_t end = str.find_first_of(delimiter, start); 46 47 BasicStringPiece<CharT> piece; 48 if (end == std::basic_string<CharT>::npos) { 49 piece = str.substr(start); 50 start = std::basic_string<CharT>::npos; 51 } else { 52 piece = str.substr(start, end - start); 53 start = end + 1; 54 } 55 56 if (whitespace == TRIM_WHITESPACE) 57 piece = TrimString(piece, WhitespaceForType<CharT>(), TRIM_ALL); 58 59 if (result_type == SPLIT_WANT_ALL || !piece.empty()) 60 result.emplace_back(piece); 61 } 62 return result; 63 } 64 65 template <typename OutputStringType, 66 typename T, 67 typename CharT = typename T::value_type> 68 std::vector<OutputStringType> SplitStringUsingSubstrT( 69 T input, 70 T delimiter, 71 WhitespaceHandling whitespace, 72 SplitResult result_type) { 73 using Piece = BasicStringPiece<CharT>; 74 using size_type = typename Piece::size_type; 75 76 std::vector<OutputStringType> result; 77 if (delimiter.size() == 0) { 78 result.emplace_back(input); 79 return result; 80 } 81 82 for (size_type begin_index = 0, end_index = 0; end_index != Piece::npos; 83 begin_index = end_index + delimiter.size()) { 84 end_index = input.find(delimiter, begin_index); 85 Piece term = end_index == Piece::npos 86 ? input.substr(begin_index) 87 : input.substr(begin_index, end_index - begin_index); 88 89 if (whitespace == TRIM_WHITESPACE) 90 term = TrimString(term, WhitespaceForType<CharT>(), TRIM_ALL); 91 92 if (result_type == SPLIT_WANT_ALL || !term.empty()) 93 result.emplace_back(term); 94 } 95 96 return result; 97 } 98 99 } // namespace internal 100 101 } // namespace base 102 103 #endif // BASE_STRINGS_STRING_SPLIT_INTERNAL_H_