Add find() and rfind() methods to base::StringView
Will be used by upcoming CLs in the trace processor.
Test: perfetto_unittests --gtest_filter=StringViewTest*
Change-Id: I98925deb816214cf23078a02b9582d544cc7ba86
diff --git a/Android.bp b/Android.bp
index 87e7112..8317acd 100644
--- a/Android.bp
+++ b/Android.bp
@@ -44,6 +44,7 @@
"src/base/pipe.cc",
"src/base/string_splitter.cc",
"src/base/string_utils.cc",
+ "src/base/string_view.cc",
"src/base/temp_file.cc",
"src/base/thread_checker.cc",
"src/base/time.cc",
@@ -158,6 +159,7 @@
"src/base/pipe.cc",
"src/base/string_splitter.cc",
"src/base/string_utils.cc",
+ "src/base/string_view.cc",
"src/base/temp_file.cc",
"src/base/thread_checker.cc",
"src/base/time.cc",
@@ -222,6 +224,7 @@
"src/base/pipe.cc",
"src/base/string_splitter.cc",
"src/base/string_utils.cc",
+ "src/base/string_view.cc",
"src/base/temp_file.cc",
"src/base/thread_checker.cc",
"src/base/time.cc",
@@ -399,6 +402,7 @@
"src/base/pipe.cc",
"src/base/string_splitter.cc",
"src/base/string_utils.cc",
+ "src/base/string_view.cc",
"src/base/temp_file.cc",
"src/base/thread_checker.cc",
"src/base/time.cc",
@@ -565,6 +569,7 @@
"src/base/pipe.cc",
"src/base/string_splitter.cc",
"src/base/string_utils.cc",
+ "src/base/string_view.cc",
"src/base/temp_file.cc",
"src/base/test/test_task_runner.cc",
"src/base/test/utils.cc",
@@ -2565,6 +2570,7 @@
"src/base/pipe.cc",
"src/base/string_splitter.cc",
"src/base/string_utils.cc",
+ "src/base/string_view.cc",
"src/base/temp_file.cc",
"src/base/thread_checker.cc",
"src/base/time.cc",
@@ -2802,6 +2808,7 @@
"src/base/string_splitter_unittest.cc",
"src/base/string_utils.cc",
"src/base/string_utils_unittest.cc",
+ "src/base/string_view.cc",
"src/base/string_view_unittest.cc",
"src/base/string_writer_unittest.cc",
"src/base/task_runner_unittest.cc",
@@ -3080,6 +3087,7 @@
"src/base/pipe.cc",
"src/base/string_splitter.cc",
"src/base/string_utils.cc",
+ "src/base/string_view.cc",
"src/base/temp_file.cc",
"src/base/thread_checker.cc",
"src/base/time.cc",
diff --git a/include/perfetto/base/string_view.h b/include/perfetto/base/string_view.h
index 9750755..648d8a5 100644
--- a/include/perfetto/base/string_view.h
+++ b/include/perfetto/base/string_view.h
@@ -22,6 +22,7 @@
#include <string>
#include "perfetto/base/hash.h"
+#include "perfetto/base/logging.h"
namespace perfetto {
namespace base {
@@ -30,6 +31,8 @@
// Strings are internally NOT null terminated.
class StringView {
public:
+ static constexpr size_t npos = static_cast<size_t>(-1);
+
StringView() : data_(""), size_(0) {}
StringView(const StringView&) = default;
StringView& operator=(const StringView&) = default;
@@ -48,6 +51,34 @@
size_t size() const { return size_; }
const char* data() const { return data_; }
+ char at(size_t pos) const {
+ PERFETTO_DCHECK(pos < size_);
+ return data_[pos];
+ }
+
+ size_t find(char c) const {
+ for (size_t i = 0; i < size_; ++i) {
+ if (data_[i] == c)
+ return i;
+ }
+ return npos;
+ }
+
+ size_t rfind(char c) const {
+ for (size_t i = size_; i > 0; --i) {
+ if (data_[i - 1] == c)
+ return i - 1;
+ }
+ return npos;
+ }
+
+ StringView substr(size_t pos, size_t count = npos) const {
+ if (pos >= size_)
+ return StringView();
+ size_t rcount = std::min(count, size_ - pos);
+ return StringView(data_ + pos, rcount);
+ }
+
std::string ToStdString() const { return std::string(data_, size_); }
uint64_t Hash() const {
diff --git a/src/base/BUILD.gn b/src/base/BUILD.gn
index 4546cca..25f3691 100644
--- a/src/base/BUILD.gn
+++ b/src/base/BUILD.gn
@@ -29,6 +29,7 @@
"paged_memory.cc",
"string_splitter.cc",
"string_utils.cc",
+ "string_view.cc",
"thread_checker.cc",
"time.cc",
"virtual_destructors.cc",
diff --git a/src/base/string_view.cc b/src/base/string_view.cc
new file mode 100644
index 0000000..b10239d
--- /dev/null
+++ b/src/base/string_view.cc
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2019 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_view.h"
+
+namespace perfetto {
+namespace base {
+
+// static
+constexpr size_t StringView::npos;
+
+} // namespace base
+} // namespace perfetto
diff --git a/src/base/string_view_unittest.cc b/src/base/string_view_unittest.cc
index fe7f545..5b1e492 100644
--- a/src/base/string_view_unittest.cc
+++ b/src/base/string_view_unittest.cc
@@ -52,6 +52,32 @@
EXPECT_TRUE(x == StringView("abc"));
EXPECT_TRUE(x != StringView("abcd"));
}
+
+ // Test find().
+ EXPECT_EQ(StringView("").find('x'), StringView::npos);
+ EXPECT_EQ(StringView("foo").find('x'), StringView::npos);
+ EXPECT_EQ(StringView("foo").find('f'), 0u);
+ EXPECT_EQ(StringView("foo").find('o'), 1u);
+
+ // Test rfind().
+ EXPECT_EQ(StringView("").rfind('x'), StringView::npos);
+ EXPECT_EQ(StringView("foo").rfind('x'), StringView::npos);
+ EXPECT_EQ(StringView("foo").rfind('f'), 0u);
+ EXPECT_EQ(StringView("foo").rfind('o'), 2u);
+
+ // Test substr().
+ EXPECT_EQ(StringView("foo").substr(3, 1).ToStdString(), "");
+ EXPECT_EQ(StringView("foo").substr(4, 0).ToStdString(), "");
+ EXPECT_EQ(StringView("foo").substr(4, 1).ToStdString(), "");
+ EXPECT_EQ(StringView("foo").substr(0, 1).ToStdString(), "f");
+ EXPECT_EQ(StringView("foo").substr(0, 3).ToStdString(), "foo");
+ EXPECT_EQ(StringView("foo").substr(0, 99).ToStdString(), "foo");
+ EXPECT_EQ(StringView("foo").substr(1, 2).ToStdString(), "oo");
+ EXPECT_EQ(StringView("foo").substr(1, 3).ToStdString(), "oo");
+ EXPECT_EQ(StringView("foo").substr(1, 99).ToStdString(), "oo");
+ EXPECT_EQ(StringView("xyz").substr(0).ToStdString(), "xyz");
+ EXPECT_EQ(StringView("xyz").substr(2).ToStdString(), "z");
+ EXPECT_EQ(StringView("xyz").substr(3).ToStdString(), "");
}
TEST(StringViewTest, HashCollisions) {