1*6dbdd20aSAndroid Build Coastguard Worker /*
2*6dbdd20aSAndroid Build Coastguard Worker * Copyright (C) 2018 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_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
StringSplitter(std::string str,char delimiter,EmptyTokenMode empty_token_mode)26*6dbdd20aSAndroid Build Coastguard Worker StringSplitter::StringSplitter(std::string 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 // It's legal to access str[str.size()] in C++11 (it always returns \0),
33*6dbdd20aSAndroid Build Coastguard Worker // hence the +1 (which becomes just size() after the -1 in Initialize()).
34*6dbdd20aSAndroid Build Coastguard Worker Initialize(&str_[0], str_.size() + 1);
35*6dbdd20aSAndroid Build Coastguard Worker }
36*6dbdd20aSAndroid Build Coastguard Worker
StringSplitter(char * str,size_t size,char delimiter,EmptyTokenMode empty_token_mode)37*6dbdd20aSAndroid Build Coastguard Worker StringSplitter::StringSplitter(char* str,
38*6dbdd20aSAndroid Build Coastguard Worker size_t size,
39*6dbdd20aSAndroid Build Coastguard Worker char delimiter,
40*6dbdd20aSAndroid Build Coastguard Worker EmptyTokenMode empty_token_mode)
41*6dbdd20aSAndroid Build Coastguard Worker : delimiter_(delimiter), empty_token_mode_(empty_token_mode) {
42*6dbdd20aSAndroid Build Coastguard Worker Initialize(str, size);
43*6dbdd20aSAndroid Build Coastguard Worker }
44*6dbdd20aSAndroid Build Coastguard Worker
StringSplitter(StringSplitter * outer,char delimiter,EmptyTokenMode empty_token_mode)45*6dbdd20aSAndroid Build Coastguard Worker StringSplitter::StringSplitter(StringSplitter* outer,
46*6dbdd20aSAndroid Build Coastguard Worker char delimiter,
47*6dbdd20aSAndroid Build Coastguard Worker EmptyTokenMode empty_token_mode)
48*6dbdd20aSAndroid Build Coastguard Worker : delimiter_(delimiter), empty_token_mode_(empty_token_mode) {
49*6dbdd20aSAndroid Build Coastguard Worker Initialize(outer->cur_token(), outer->cur_token_size() + 1);
50*6dbdd20aSAndroid Build Coastguard Worker }
51*6dbdd20aSAndroid Build Coastguard Worker
Initialize(char * str,size_t size)52*6dbdd20aSAndroid Build Coastguard Worker void StringSplitter::Initialize(char* str, size_t size) {
53*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_DCHECK(!size || str);
54*6dbdd20aSAndroid Build Coastguard Worker next_ = str;
55*6dbdd20aSAndroid Build Coastguard Worker end_ = str + size;
56*6dbdd20aSAndroid Build Coastguard Worker cur_ = nullptr;
57*6dbdd20aSAndroid Build Coastguard Worker cur_size_ = 0;
58*6dbdd20aSAndroid Build Coastguard Worker if (size)
59*6dbdd20aSAndroid Build Coastguard Worker next_[size - 1] = '\0';
60*6dbdd20aSAndroid Build Coastguard Worker }
61*6dbdd20aSAndroid Build Coastguard Worker
Next()62*6dbdd20aSAndroid Build Coastguard Worker bool StringSplitter::Next() {
63*6dbdd20aSAndroid Build Coastguard Worker for (; next_ < end_; next_++) {
64*6dbdd20aSAndroid Build Coastguard Worker if (*next_ == delimiter_ &&
65*6dbdd20aSAndroid Build Coastguard Worker empty_token_mode_ == EmptyTokenMode::DISALLOW_EMPTY_TOKENS) {
66*6dbdd20aSAndroid Build Coastguard Worker // If empty tokens are disallowed, find fist non-delimiter character.
67*6dbdd20aSAndroid Build Coastguard Worker continue;
68*6dbdd20aSAndroid Build Coastguard Worker }
69*6dbdd20aSAndroid Build Coastguard Worker cur_ = next_;
70*6dbdd20aSAndroid Build Coastguard Worker for (;; next_++) {
71*6dbdd20aSAndroid Build Coastguard Worker if (*next_ == delimiter_) {
72*6dbdd20aSAndroid Build Coastguard Worker cur_size_ = static_cast<size_t>(next_ - cur_);
73*6dbdd20aSAndroid Build Coastguard Worker *(next_++) = '\0';
74*6dbdd20aSAndroid Build Coastguard Worker break;
75*6dbdd20aSAndroid Build Coastguard Worker }
76*6dbdd20aSAndroid Build Coastguard Worker if (*next_ == '\0') {
77*6dbdd20aSAndroid Build Coastguard Worker cur_size_ = static_cast<size_t>(next_ - cur_);
78*6dbdd20aSAndroid Build Coastguard Worker next_ = end_;
79*6dbdd20aSAndroid Build Coastguard Worker break;
80*6dbdd20aSAndroid Build Coastguard Worker }
81*6dbdd20aSAndroid Build Coastguard Worker }
82*6dbdd20aSAndroid Build Coastguard Worker if (*cur_ || empty_token_mode_ == EmptyTokenMode::ALLOW_EMPTY_TOKENS)
83*6dbdd20aSAndroid Build Coastguard Worker return true;
84*6dbdd20aSAndroid Build Coastguard Worker break;
85*6dbdd20aSAndroid Build Coastguard Worker }
86*6dbdd20aSAndroid Build Coastguard Worker cur_ = nullptr;
87*6dbdd20aSAndroid Build Coastguard Worker cur_size_ = 0;
88*6dbdd20aSAndroid Build Coastguard Worker return false;
89*6dbdd20aSAndroid Build Coastguard Worker }
90*6dbdd20aSAndroid Build Coastguard Worker
91*6dbdd20aSAndroid Build Coastguard Worker } // namespace base
92*6dbdd20aSAndroid Build Coastguard Worker } // namespace perfetto
93