xref: /aosp_15_r20/external/cronet/base/strings/string_split_internal.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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