1*6dbdd20aSAndroid Build Coastguard Worker /*
2*6dbdd20aSAndroid Build Coastguard Worker * Copyright (C) 2024 The Android Open Source Project
3*6dbdd20aSAndroid Build Coastguard Worker *
4*6dbdd20aSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*6dbdd20aSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*6dbdd20aSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*6dbdd20aSAndroid Build Coastguard Worker *
8*6dbdd20aSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*6dbdd20aSAndroid Build Coastguard Worker *
10*6dbdd20aSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*6dbdd20aSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*6dbdd20aSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*6dbdd20aSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*6dbdd20aSAndroid Build Coastguard Worker * limitations under the License.
15*6dbdd20aSAndroid Build Coastguard Worker */
16*6dbdd20aSAndroid Build Coastguard Worker
17*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/string_view_splitter.h"
18*6dbdd20aSAndroid Build Coastguard Worker
19*6dbdd20aSAndroid Build Coastguard Worker #include <utility>
20*6dbdd20aSAndroid Build Coastguard Worker
21*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/logging.h"
22*6dbdd20aSAndroid Build Coastguard Worker
23*6dbdd20aSAndroid Build Coastguard Worker namespace perfetto {
24*6dbdd20aSAndroid Build Coastguard Worker namespace base {
25*6dbdd20aSAndroid Build Coastguard Worker
StringViewSplitter(base::StringView str,char delimiter,EmptyTokenMode empty_token_mode)26*6dbdd20aSAndroid Build Coastguard Worker StringViewSplitter::StringViewSplitter(base::StringView str,
27*6dbdd20aSAndroid Build Coastguard Worker char delimiter,
28*6dbdd20aSAndroid Build Coastguard Worker EmptyTokenMode empty_token_mode)
29*6dbdd20aSAndroid Build Coastguard Worker : str_(std::move(str)),
30*6dbdd20aSAndroid Build Coastguard Worker delimiter_(delimiter),
31*6dbdd20aSAndroid Build Coastguard Worker empty_token_mode_(empty_token_mode) {
32*6dbdd20aSAndroid Build Coastguard Worker Initialize(str);
33*6dbdd20aSAndroid Build Coastguard Worker }
34*6dbdd20aSAndroid Build Coastguard Worker
StringViewSplitter(StringViewSplitter * outer,char delimiter,EmptyTokenMode empty_token_mode)35*6dbdd20aSAndroid Build Coastguard Worker StringViewSplitter::StringViewSplitter(StringViewSplitter* outer,
36*6dbdd20aSAndroid Build Coastguard Worker char delimiter,
37*6dbdd20aSAndroid Build Coastguard Worker EmptyTokenMode empty_token_mode)
38*6dbdd20aSAndroid Build Coastguard Worker : delimiter_(delimiter), empty_token_mode_(empty_token_mode) {
39*6dbdd20aSAndroid Build Coastguard Worker Initialize(outer->cur_token());
40*6dbdd20aSAndroid Build Coastguard Worker }
41*6dbdd20aSAndroid Build Coastguard Worker
Initialize(base::StringView str)42*6dbdd20aSAndroid Build Coastguard Worker void StringViewSplitter::Initialize(base::StringView str) {
43*6dbdd20aSAndroid Build Coastguard Worker next_ = str;
44*6dbdd20aSAndroid Build Coastguard Worker cur_ = "";
45*6dbdd20aSAndroid Build Coastguard Worker end_of_input_ = false;
46*6dbdd20aSAndroid Build Coastguard Worker }
47*6dbdd20aSAndroid Build Coastguard Worker
Next()48*6dbdd20aSAndroid Build Coastguard Worker bool StringViewSplitter::Next() {
49*6dbdd20aSAndroid Build Coastguard Worker if (end_of_input_) {
50*6dbdd20aSAndroid Build Coastguard Worker cur_ = next_ = "";
51*6dbdd20aSAndroid Build Coastguard Worker return false;
52*6dbdd20aSAndroid Build Coastguard Worker }
53*6dbdd20aSAndroid Build Coastguard Worker
54*6dbdd20aSAndroid Build Coastguard Worker size_t substr_start = 0;
55*6dbdd20aSAndroid Build Coastguard Worker if (empty_token_mode_ == EmptyTokenMode::DISALLOW_EMPTY_TOKENS) {
56*6dbdd20aSAndroid Build Coastguard Worker while (substr_start < next_.size() &&
57*6dbdd20aSAndroid Build Coastguard Worker next_.at(substr_start) == delimiter_) {
58*6dbdd20aSAndroid Build Coastguard Worker substr_start++;
59*6dbdd20aSAndroid Build Coastguard Worker }
60*6dbdd20aSAndroid Build Coastguard Worker }
61*6dbdd20aSAndroid Build Coastguard Worker
62*6dbdd20aSAndroid Build Coastguard Worker if (substr_start >= next_.size()) {
63*6dbdd20aSAndroid Build Coastguard Worker end_of_input_ = true;
64*6dbdd20aSAndroid Build Coastguard Worker cur_ = next_ = "";
65*6dbdd20aSAndroid Build Coastguard Worker return !cur_.empty() ||
66*6dbdd20aSAndroid Build Coastguard Worker empty_token_mode_ == EmptyTokenMode::ALLOW_EMPTY_TOKENS;
67*6dbdd20aSAndroid Build Coastguard Worker }
68*6dbdd20aSAndroid Build Coastguard Worker
69*6dbdd20aSAndroid Build Coastguard Worker size_t delimiter_start = next_.find(delimiter_, substr_start);
70*6dbdd20aSAndroid Build Coastguard Worker if (delimiter_start == base::StringView::npos) {
71*6dbdd20aSAndroid Build Coastguard Worker cur_ = next_.substr(substr_start);
72*6dbdd20aSAndroid Build Coastguard Worker next_ = "";
73*6dbdd20aSAndroid Build Coastguard Worker end_of_input_ = true;
74*6dbdd20aSAndroid Build Coastguard Worker return !cur_.empty() ||
75*6dbdd20aSAndroid Build Coastguard Worker empty_token_mode_ == EmptyTokenMode::ALLOW_EMPTY_TOKENS;
76*6dbdd20aSAndroid Build Coastguard Worker }
77*6dbdd20aSAndroid Build Coastguard Worker
78*6dbdd20aSAndroid Build Coastguard Worker size_t delimiter_end = delimiter_start + 1;
79*6dbdd20aSAndroid Build Coastguard Worker
80*6dbdd20aSAndroid Build Coastguard Worker if (empty_token_mode_ == EmptyTokenMode::DISALLOW_EMPTY_TOKENS) {
81*6dbdd20aSAndroid Build Coastguard Worker while (delimiter_end < next_.size() &&
82*6dbdd20aSAndroid Build Coastguard Worker next_.at(delimiter_end) == delimiter_) {
83*6dbdd20aSAndroid Build Coastguard Worker delimiter_end++;
84*6dbdd20aSAndroid Build Coastguard Worker }
85*6dbdd20aSAndroid Build Coastguard Worker if (delimiter_end >= next_.size()) {
86*6dbdd20aSAndroid Build Coastguard Worker end_of_input_ = true;
87*6dbdd20aSAndroid Build Coastguard Worker }
88*6dbdd20aSAndroid Build Coastguard Worker }
89*6dbdd20aSAndroid Build Coastguard Worker
90*6dbdd20aSAndroid Build Coastguard Worker cur_ = next_.substr(substr_start, delimiter_start - substr_start);
91*6dbdd20aSAndroid Build Coastguard Worker next_ = next_.substr(delimiter_end);
92*6dbdd20aSAndroid Build Coastguard Worker
93*6dbdd20aSAndroid Build Coastguard Worker return !cur_.empty() ||
94*6dbdd20aSAndroid Build Coastguard Worker empty_token_mode_ == EmptyTokenMode::ALLOW_EMPTY_TOKENS;
95*6dbdd20aSAndroid Build Coastguard Worker }
96*6dbdd20aSAndroid Build Coastguard Worker
97*6dbdd20aSAndroid Build Coastguard Worker } // namespace base
98*6dbdd20aSAndroid Build Coastguard Worker } // namespace perfetto
99