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