xref: /aosp_15_r20/external/perfetto/src/base/string_splitter.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
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