aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/core/lib
diff options
context:
space:
mode:
authorGravatar A. Unique TensorFlower <gardener@tensorflow.org>2018-03-16 10:10:16 -0700
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2018-03-16 10:14:17 -0700
commit386ba370d41e8872a9db0d45239d7b00c14ef309 (patch)
treeb7aa83e59e1345fcc1fbf6cb89db5601966c91b3 /tensorflow/core/lib
parenta0bd058ad1406585634330772bfda76fd27d87d7 (diff)
Added StrContains, StartsWith, and EndsWith functions to str_util.h.
Marked contains, starts_with, ends_with, and consume StringPiece methods as deprecated. This will allow tensorflow::StringPiece to be more easily replaced with absl::string_view (once the deprecated methods are removed) as absl::string_view does not contain those methods. PiperOrigin-RevId: 189355316
Diffstat (limited to 'tensorflow/core/lib')
-rw-r--r--tensorflow/core/lib/core/stringpiece.h4
-rw-r--r--tensorflow/core/lib/strings/str_util.cc21
-rw-r--r--tensorflow/core/lib/strings/str_util.h15
-rw-r--r--tensorflow/core/lib/strings/str_util_test.cc52
4 files changed, 90 insertions, 2 deletions
diff --git a/tensorflow/core/lib/core/stringpiece.h b/tensorflow/core/lib/core/stringpiece.h
index 910e4d9e2a..79409cce4b 100644
--- a/tensorflow/core/lib/core/stringpiece.h
+++ b/tensorflow/core/lib/core/stringpiece.h
@@ -88,11 +88,13 @@ class StringPiece {
size_t find(char c, size_t pos = 0) const;
size_t rfind(char c, size_t pos = npos) const;
+ // DEPRECATED: Use tensorflow::str_util::StrContains instead.
bool contains(StringPiece s) const;
// Checks whether StringPiece starts with x and if so advances the beginning
// of it to past the match. It's basically a shortcut for starts_with
// followed by remove_prefix.
+ // DEPRECATED: Use tensorflow::str_util::ConsumePrefix instead.
bool Consume(StringPiece x) {
if (starts_with(x)) {
remove_prefix(x.size_);
@@ -113,10 +115,12 @@ class StringPiece {
int compare(StringPiece b) const;
// Return true iff "x" is a prefix of "*this"
+ // DEPRECATED: Use tensorflow::str_util::StartsWith instead.
bool starts_with(StringPiece x) const {
return ((size_ >= x.size_) && (memcmp(data_, x.data_, x.size_) == 0));
}
// Return true iff "x" is a suffix of "*this"
+ // DEPRECATED: Use tensorflow::str_util::EndsWith instead.
bool ends_with(StringPiece x) const {
return ((size_ >= x.size_) &&
(memcmp(data_ + (size_ - x.size_), x.data_, x.size_) == 0));
diff --git a/tensorflow/core/lib/strings/str_util.cc b/tensorflow/core/lib/strings/str_util.cc
index d28857803d..9dbb74f6b8 100644
--- a/tensorflow/core/lib/strings/str_util.cc
+++ b/tensorflow/core/lib/strings/str_util.cc
@@ -373,7 +373,7 @@ size_t RemoveWhitespaceContext(StringPiece* text) {
}
bool ConsumePrefix(StringPiece* s, StringPiece expected) {
- if (s->starts_with(expected)) {
+ if (StartsWith(*s, expected)) {
s->remove_prefix(expected.size());
return true;
}
@@ -381,7 +381,7 @@ bool ConsumePrefix(StringPiece* s, StringPiece expected) {
}
bool ConsumeSuffix(StringPiece* s, StringPiece expected) {
- if (s->ends_with(expected)) {
+ if (EndsWith(*s, expected)) {
s->remove_suffix(expected.size());
return true;
}
@@ -452,5 +452,22 @@ bool SplitAndParseAsFloats(StringPiece text, char delim,
result);
}
+bool StrContains(StringPiece haystack, StringPiece needle) {
+ return std::search(haystack.begin(), haystack.end(), needle.begin(),
+ needle.end()) != haystack.end();
+}
+
+bool StartsWith(StringPiece text, StringPiece prefix) {
+ return prefix.empty() ||
+ (text.size() >= prefix.size() &&
+ memcmp(text.data(), prefix.data(), prefix.size()) == 0);
+}
+
+bool EndsWith(StringPiece text, StringPiece suffix) {
+ return suffix.empty() || (text.size() >= suffix.size() &&
+ memcmp(text.data() + (text.size() - suffix.size()),
+ suffix.data(), suffix.size()) == 0);
+}
+
} // namespace str_util
} // namespace tensorflow
diff --git a/tensorflow/core/lib/strings/str_util.h b/tensorflow/core/lib/strings/str_util.h
index 44c52850fa..f062eddef8 100644
--- a/tensorflow/core/lib/strings/str_util.h
+++ b/tensorflow/core/lib/strings/str_util.h
@@ -141,6 +141,21 @@ bool SplitAndParseAsInts(StringPiece text, char delim,
bool SplitAndParseAsFloats(StringPiece text, char delim,
std::vector<float>* result);
+// StartsWith()
+//
+// Returns whether a given string `text` begins with `prefix`.
+bool StartsWith(StringPiece text, StringPiece prefix);
+
+// EndsWith()
+//
+// Returns whether a given string `text` ends with `suffix`.
+bool EndsWith(StringPiece text, StringPiece suffix);
+
+// StrContains()
+//
+// Returns whether a given string `haystack` contains the substring `needle`.
+bool StrContains(StringPiece haystack, StringPiece needle);
+
// ------------------------------------------------------------------
// Implementation details below
template <typename T>
diff --git a/tensorflow/core/lib/strings/str_util_test.cc b/tensorflow/core/lib/strings/str_util_test.cc
index 6d461241f7..63643c3e8e 100644
--- a/tensorflow/core/lib/strings/str_util_test.cc
+++ b/tensorflow/core/lib/strings/str_util_test.cc
@@ -430,4 +430,56 @@ TEST(StringReplace, EmptyStringReplaceAll) {
EXPECT_EQ("", str_util::StringReplace("", "a", "X", /*replace_all=*/true));
}
+TEST(StartsWith, Basic) {
+ const string s1(
+ "123"
+ "\0"
+ "456",
+ 7);
+ const StringPiece a("foobar");
+ const StringPiece b(s1);
+ const StringPiece e;
+ EXPECT_TRUE(str_util::StartsWith(a, a));
+ EXPECT_TRUE(str_util::StartsWith(a, "foo"));
+ EXPECT_TRUE(str_util::StartsWith(a, e));
+ EXPECT_TRUE(str_util::StartsWith(b, s1));
+ EXPECT_TRUE(str_util::StartsWith(b, b));
+ EXPECT_TRUE(str_util::StartsWith(b, e));
+ EXPECT_TRUE(str_util::StartsWith(e, ""));
+ EXPECT_FALSE(str_util::StartsWith(a, b));
+ EXPECT_FALSE(str_util::StartsWith(b, a));
+ EXPECT_FALSE(str_util::StartsWith(e, a));
+}
+
+TEST(EndsWith, Basic) {
+ const string s1(
+ "123"
+ "\0"
+ "456",
+ 7);
+ const StringPiece a("foobar");
+ const StringPiece b(s1);
+ const StringPiece e;
+ EXPECT_TRUE(str_util::EndsWith(a, a));
+ EXPECT_TRUE(str_util::EndsWith(a, "bar"));
+ EXPECT_TRUE(str_util::EndsWith(a, e));
+ EXPECT_TRUE(str_util::EndsWith(b, s1));
+ EXPECT_TRUE(str_util::EndsWith(b, b));
+ EXPECT_TRUE(str_util::EndsWith(b, e));
+ EXPECT_TRUE(str_util::EndsWith(e, ""));
+ EXPECT_FALSE(str_util::EndsWith(a, b));
+ EXPECT_FALSE(str_util::EndsWith(b, a));
+ EXPECT_FALSE(str_util::EndsWith(e, a));
+}
+
+TEST(StrContains, Basic) {
+ StringPiece a("abcdefg");
+ StringPiece b("abcd");
+ StringPiece c("efg");
+ StringPiece d("gh");
+ EXPECT_TRUE(str_util::StrContains(a, b));
+ EXPECT_TRUE(str_util::StrContains(a, c));
+ EXPECT_TRUE(!str_util::StrContains(a, d));
+}
+
} // namespace tensorflow