/* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "perfetto/base/string_splitter.h" #include <utility> #include "perfetto/base/logging.h" namespace perfetto { namespace base { StringSplitter::StringSplitter(std::string str, char delimiter) : str_(std::move(str)), delimiter_(delimiter) { // It's legal to access str[str.size()] in C++11 (it always returns \0), // hence the +1 (which becomes just size() after the -1 in Initialize()). Initialize(&str_[0], str_.size() + 1); } StringSplitter::StringSplitter(char* str, size_t size, char delimiter) : delimiter_(delimiter) { Initialize(str, size); } StringSplitter::StringSplitter(StringSplitter* outer, char delimiter) : delimiter_(delimiter) { Initialize(outer->cur_token(), outer->cur_token_size() + 1); } void StringSplitter::Initialize(char* str, size_t size) { PERFETTO_DCHECK(!size || str); next_ = str; end_ = str + size; cur_ = nullptr; cur_size_ = 0; if (size) next_[size - 1] = '\0'; } bool StringSplitter::Next() { for (; next_ < end_; next_++) { if (*next_ == delimiter_) continue; cur_ = next_; for (;; next_++) { if (*next_ == delimiter_) { cur_size_ = static_cast<size_t>(next_ - cur_); *(next_++) = '\0'; break; } if (*next_ == '\0') { cur_size_ = static_cast<size_t>(next_ - cur_); next_ = end_; break; } } if (*cur_) return true; break; } cur_ = nullptr; cur_size_ = 0; return false; } } // namespace base } // namespace perfetto