1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_ 18 #define INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_ 19 20 #include <string> 21 22 namespace perfetto { 23 namespace base { 24 25 // C++ version of strtok(). Splits a string without making copies or any heap 26 // allocations. Destructs the original string passed in input. 27 // Supports the special case of using \0 as a delimiter. 28 // The token returned in output are valid as long as the input string is valid. 29 class StringSplitter { 30 public: 31 // Can take ownership of the string if passed via std::move(), e.g.: 32 // StringSplitter(std::move(str), '\n'); 33 StringSplitter(std::string, char delimiter); 34 35 // Splits a C-string. The input string will be forcefully null-terminated (so 36 // str[size - 1] should be == '\0' or the last char will be truncated). 37 StringSplitter(char* str, size_t size, char delimiter); 38 39 // Splits the current token from an outer StringSplitter instance. This is to 40 // chain splitters as follows: 41 // for (base::StringSplitter lines(x, '\n'); ss.Next();) 42 // for (base::StringSplitter words(&lines, ' '); words.Next();) 43 StringSplitter(StringSplitter*, char delimiter); 44 45 // Returns true if a token is found (in which case it will be stored in 46 // cur_token()), false if no more tokens are found. 47 bool Next(); 48 49 // Returns the current token iff last call to Next() returned true. In this 50 // case it guarantees that the returned string is always null terminated. 51 // In all other cases (before the 1st call to Next() and after Next() returns 52 // false) returns nullptr. cur_token()53 char* cur_token() { return cur_; } 54 55 // Returns the length of the current token (excluding the null terminator). cur_token_size()56 size_t cur_token_size() const { return cur_size_; } 57 58 private: 59 StringSplitter(const StringSplitter&) = delete; 60 StringSplitter& operator=(const StringSplitter&) = delete; 61 void Initialize(char* str, size_t size); 62 63 std::string str_; 64 char* cur_; 65 size_t cur_size_; 66 char* next_; 67 char* end_; // STL-style, points one past the last char. 68 const char delimiter_; 69 }; 70 71 } // namespace base 72 } // namespace perfetto 73 74 #endif // INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_ 75