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 std::basic_string_view<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>
SplitStringT(T str,T delimiter,WhitespaceHandling whitespace,SplitResult result_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 std::basic_string_view<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>
SplitStringUsingSubstrT(T input,T delimiter,WhitespaceHandling whitespace,SplitResult result_type)68 std::vector<OutputStringType> SplitStringUsingSubstrT(
69 T input,
70 T delimiter,
71 WhitespaceHandling whitespace,
72 SplitResult result_type) {
73 using Piece = std::basic_string_view<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_
104