未验证 提交 f600ae83 编写于 作者: C Chinmay Garde 提交者: GitHub

Use libc++ variant of string view and remove the FML variant. (#9737)

上级 564f53f0
......@@ -186,9 +186,6 @@ FILE: ../../../flutter/fml/platform/win/native_library_win.cc
FILE: ../../../flutter/fml/platform/win/paths_win.cc
FILE: ../../../flutter/fml/platform/win/wstring_conversion.h
FILE: ../../../flutter/fml/size.h
FILE: ../../../flutter/fml/string_view.cc
FILE: ../../../flutter/fml/string_view.h
FILE: ../../../flutter/fml/string_view_unittest.cc
FILE: ../../../flutter/fml/synchronization/atomic_object.h
FILE: ../../../flutter/fml/synchronization/count_down_latch.cc
FILE: ../../../flutter/fml/synchronization/count_down_latch.h
......
......@@ -52,8 +52,6 @@ source_set("fml") {
"paths.cc",
"paths.h",
"size.h",
"string_view.cc",
"string_view.h",
"synchronization/atomic_object.h",
"synchronization/count_down_latch.cc",
"synchronization/count_down_latch.h",
......@@ -206,7 +204,6 @@ executable("fml_unittests") {
"message_unittests.cc",
"paths_unittests.cc",
"platform/darwin/string_range_sanitization_unittests.mm",
"string_view_unittest.cc",
"synchronization/count_down_latch_unittests.cc",
"synchronization/semaphore_unittest.cc",
"synchronization/thread_annotations_unittest.cc",
......
......@@ -5,14 +5,13 @@
#include "flutter/fml/base32.h"
#include <limits>
#include "flutter/fml/macros.h"
#include <string>
namespace fml {
static constexpr char kEncoding[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
std::pair<bool, std::string> Base32Encode(StringView input) {
std::pair<bool, std::string> Base32Encode(std::string_view input) {
if (input.empty()) {
return {true, ""};
}
......
......@@ -5,14 +5,12 @@
#ifndef FLUTTER_FML_BASE32_H_
#define FLUTTER_FML_BASE32_H_
#include <string>
#include <string_view>
#include <utility>
#include "flutter/fml/string_view.h"
namespace fml {
std::pair<bool, std::string> Base32Encode(StringView input);
std::pair<bool, std::string> Base32Encode(std::string_view input);
} // namespace fml
......
......@@ -36,8 +36,8 @@ CommandLine& CommandLine::operator=(const CommandLine& from) = default;
CommandLine& CommandLine::operator=(CommandLine&& from) = default;
bool CommandLine::HasOption(StringView name, size_t* index) const {
auto it = option_index_.find(name.ToString());
bool CommandLine::HasOption(std::string_view name, size_t* index) const {
auto it = option_index_.find(name.data());
if (it == option_index_.end())
return false;
if (index)
......@@ -45,7 +45,8 @@ bool CommandLine::HasOption(StringView name, size_t* index) const {
return true;
}
bool CommandLine::GetOptionValue(StringView name, std::string* value) const {
bool CommandLine::GetOptionValue(std::string_view name,
std::string* value) const {
size_t index;
if (!HasOption(name, &index))
return false;
......@@ -53,9 +54,9 @@ bool CommandLine::GetOptionValue(StringView name, std::string* value) const {
return true;
}
std::vector<fml::StringView> CommandLine::GetOptionValues(
StringView name) const {
std::vector<fml::StringView> ret;
std::vector<std::string_view> CommandLine::GetOptionValues(
std::string_view name) const {
std::vector<std::string_view> ret;
for (const auto& option : options_) {
if (option.name == name)
ret.push_back(option.value);
......@@ -64,11 +65,11 @@ std::vector<fml::StringView> CommandLine::GetOptionValues(
}
std::string CommandLine::GetOptionValueWithDefault(
StringView name,
StringView default_value) const {
std::string_view name,
std::string_view default_value) const {
size_t index;
if (!HasOption(name, &index))
return default_value.ToString();
return {default_value.data(), default_value.size()};
return options_[index].value;
}
......
......@@ -40,11 +40,11 @@
#include <initializer_list>
#include <string>
#include <string_view>
#include <unordered_map>
#include <vector>
#include "flutter/fml/macros.h"
#include "flutter/fml/string_view.h"
namespace fml {
......@@ -108,21 +108,21 @@ class CommandLine final {
// Returns true if this command line has the option |name| (and if |index| is
// non-null, sets |*index| to the index of the *last* occurrence of the given
// option in |options()|) and false if not.
bool HasOption(StringView name, size_t* index = nullptr) const;
bool HasOption(std::string_view name, size_t* index = nullptr) const;
// Gets the value of the option |name|. Returns true (and sets |*value|) on
// success and false (leaving |*value| alone) on failure.
bool GetOptionValue(StringView name, std::string* value) const;
bool GetOptionValue(std::string_view name, std::string* value) const;
// Gets all values of the option |name|. Returns all values, which may be
// empty if the option is not specified.
std::vector<StringView> GetOptionValues(StringView name) const;
std::vector<std::string_view> GetOptionValues(std::string_view name) const;
// Gets the value of the option |name|, with a default if the option is not
// specified. (Note: This doesn't return a const reference, since this would
// make the |default_value| argument inconvenient/dangerous.)
std::string GetOptionValueWithDefault(StringView name,
StringView default_value) const;
std::string GetOptionValueWithDefault(std::string_view name,
std::string_view default_value) const;
private:
bool has_argv0_ = false;
......
......@@ -4,6 +4,7 @@
#include "flutter/fml/command_line.h"
#include <string_view>
#include <utility>
#include "flutter/fml/macros.h"
......@@ -315,7 +316,7 @@ TEST(CommandLineTest, MultipleOccurrencesOfOption) {
CommandLine::Option("flag1", "value3")};
EXPECT_EQ("value3", cl.GetOptionValueWithDefault("flag1", "nope"));
EXPECT_EQ("value2", cl.GetOptionValueWithDefault("flag2", "nope"));
std::vector<StringView> values = cl.GetOptionValues("flag1");
std::vector<std::string_view> values = cl.GetOptionValues("flag1");
ASSERT_EQ(2u, values.size());
EXPECT_EQ("value1", values[0]);
EXPECT_EQ("value3", values[1]);
......
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/fml/string_view.h"
#include <string.h>
#include <algorithm>
#include <limits>
namespace fml {
constexpr size_t StringView::npos;
namespace {
// For each character in characters_wanted, sets the index corresponding
// to the code for that character to 1 in table. This is used by the
// find_.*_of methods below to tell whether or not a character is in the lookup
// table in constant time.
// The argument `table' must be an array that is large enough to hold all
// the possible values of an unsigned char. Thus it should be be declared
// as follows:
// bool table[std::numeric_limits<unsigned char>::max() + 1]
inline void BuildLookupTable(StringView characters_wanted, bool* table) {
size_t length = characters_wanted.size();
const char* data = characters_wanted.data();
for (size_t i = 0; i < length; ++i) {
table[static_cast<unsigned char>(data[i])] = true;
}
}
} // namespace
int StringView::compare(StringView other) {
size_t len = std::min(size_, other.size_);
int retval = memcmp(data_, other.data_, len);
if (retval == 0) {
if (size_ == other.size_) {
return 0;
}
return size_ < other.size_ ? -1 : 1;
}
return retval;
}
bool operator==(StringView lhs, StringView rhs) {
if (lhs.size() != rhs.size())
return false;
return lhs.compare(rhs) == 0;
}
bool operator!=(StringView lhs, StringView rhs) {
if (lhs.size() != rhs.size())
return true;
return lhs.compare(rhs) != 0;
}
bool operator<(StringView lhs, StringView rhs) {
return lhs.compare(rhs) < 0;
}
bool operator>(StringView lhs, StringView rhs) {
return lhs.compare(rhs) > 0;
}
bool operator<=(StringView lhs, StringView rhs) {
return lhs.compare(rhs) <= 0;
}
bool operator>=(StringView lhs, StringView rhs) {
return lhs.compare(rhs) >= 0;
}
std::ostream& operator<<(std::ostream& o, StringView string_view) {
o.write(string_view.data(), static_cast<std::streamsize>(string_view.size()));
return o;
}
size_t StringView::find(StringView s, size_t pos) const {
if (pos > size_)
return npos;
if (s.empty())
return pos;
auto* result = std::search(begin() + pos, end(), s.begin(), s.end());
if (result == end())
return npos;
return result - begin();
}
size_t StringView::find(char c, size_t pos) const {
if (pos > size_)
return npos;
auto* result = std::find(begin() + pos, end(), c);
if (result == end())
return npos;
return result - begin();
}
size_t StringView::rfind(StringView s, size_t pos) const {
if (size_ < s.size())
return npos;
if (s.empty())
return std::min(pos, size_);
auto* last = begin() + std::min(size_ - s.size(), pos) + s.size();
auto* result = std::find_end(begin(), last, s.begin(), s.end());
if (result == last)
return npos;
return result - begin();
}
size_t StringView::rfind(char c, size_t pos) const {
if (size_ == 0)
return npos;
auto begin = rend() - std::min(size_ - 1, pos) - 1;
auto result = std::find(begin, rend(), c);
if (result == rend())
return npos;
return rend() - result - 1;
}
size_t StringView::find_first_of(StringView s, size_t pos) const {
if (pos >= size_ || s.size() == 0)
return npos;
// Avoid the cost of BuildLookupTable() for a single-character search.
if (s.size() == 1)
return find(s.data()[0], pos);
bool lookup[std::numeric_limits<unsigned char>::max() + 1] = {false};
BuildLookupTable(s, lookup);
for (size_t i = pos; i < size_; ++i) {
if (lookup[static_cast<unsigned char>(data_[i])]) {
return i;
}
}
return npos;
}
size_t StringView::find_last_of(StringView s, size_t pos) const {
if (size_ == 0 || s.size() == 0)
return npos;
// Avoid the cost of BuildLookupTable() for a single-character search.
if (s.size() == 1)
return rfind(s.data()[0], pos);
bool lookup[std::numeric_limits<unsigned char>::max() + 1] = {false};
BuildLookupTable(s, lookup);
for (size_t i = std::min(pos, size_ - 1);; --i) {
if (lookup[static_cast<unsigned char>(data_[i])])
return i;
if (i == 0)
break;
}
return npos;
}
size_t StringView::find_first_not_of(StringView s, size_t pos) const {
if (pos >= size_)
return npos;
// Avoid the cost of BuildLookupTable() for a single-character search.
if (s.size() == 1) {
for (size_t i = pos; i < size_; ++i) {
if (data_[i] != s[0])
return i;
}
return npos;
}
bool lookup[std::numeric_limits<unsigned char>::max() + 1] = {false};
BuildLookupTable(s, lookup);
for (size_t i = pos; i < size_; ++i) {
if (!lookup[static_cast<unsigned char>(data_[i])]) {
return i;
}
}
return npos;
}
size_t StringView::find_last_not_of(StringView s, size_t pos) const {
if (size_ == 0)
return npos;
// Avoid the cost of BuildLookupTable() for a single-character search.
if (s.size() == 1) {
for (size_t i = std::min(pos, size_ - 1);; --i) {
if (data_[i] != s[0])
return i;
if (i == 0)
break;
}
}
bool lookup[std::numeric_limits<unsigned char>::max() + 1] = {false};
BuildLookupTable(s, lookup);
for (size_t i = std::min(pos, size_ - 1);; --i) {
if (!lookup[static_cast<unsigned char>(data_[i])])
return i;
if (i == 0)
break;
}
return npos;
}
} // namespace fml
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_FML_STRING_VIEW_H_
#define FLUTTER_FML_STRING_VIEW_H_
#include <iosfwd>
#include <string>
#include <type_traits>
#include "flutter/fml/logging.h"
// MSVC 2015 doesn't support "extended constexpr" from C++14.
#if __cplusplus >= 201402L
// C++14 relaxed the limitation of the content of a constexpr function.
#define CONSTEXPR_IN_CPP14 constexpr
#else
#define CONSTEXPR_IN_CPP14
#endif
namespace fml {
// A string-like object that points to a sized piece of memory.
class StringView {
public:
// Types.
using const_iterator = const char*;
using iterator = const_iterator;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
using reverse_iterator = const_reverse_iterator;
constexpr static size_t npos = static_cast<size_t>(-1);
// Constructors.
constexpr StringView() : data_(""), size_(0u) {}
constexpr StringView(const StringView& string_view)
: data_(string_view.data_), size_(string_view.size_) {}
constexpr StringView(const char* str, size_t len) : data_(str), size_(len) {}
explicit constexpr StringView(const char* str)
: data_(str), size_(constexpr_strlen(str)) {}
// Implicit constructor for constant C strings.
template <size_t N>
constexpr StringView(const char (&str)[N])
: data_(str), size_(constexpr_strlen(str)) {}
// Implicit constructor.
StringView(const std::string& str) : data_(str.data()), size_(str.size()) {}
// Copy operators.
StringView& operator=(const StringView& other) {
data_ = other.data_;
size_ = other.size_;
return *this;
}
// Capacity methods.
constexpr size_t size() const { return size_; }
constexpr bool empty() const { return size_ == 0u; }
// Element access methods.
constexpr char operator[](size_t pos) const { return data_[pos]; };
constexpr char at(size_t pos) const { return data_[pos]; };
constexpr char front() const { return data_[0]; };
constexpr char back() const { return data_[size_ - 1]; };
constexpr const char* data() const { return data_; }
// Iterators.
constexpr const_iterator begin() const { return cbegin(); }
constexpr const_iterator end() const { return cend(); }
constexpr const_iterator cbegin() const { return data_; }
constexpr const_iterator cend() const { return data_ + size_; }
const_reverse_iterator rbegin() const {
return const_reverse_iterator(cend());
}
const_reverse_iterator rend() const {
return const_reverse_iterator(cbegin());
}
const_reverse_iterator crbegin() const {
return const_reverse_iterator(cend());
}
const_reverse_iterator crend() const {
return const_reverse_iterator(cbegin());
}
// Modifier methods.
CONSTEXPR_IN_CPP14 void clear() {
data_ = "";
size_ = 0;
}
CONSTEXPR_IN_CPP14 void remove_prefix(size_t n) {
FML_DCHECK(n <= size_);
data_ += n;
size_ -= n;
}
CONSTEXPR_IN_CPP14 void remove_suffix(size_t n) {
FML_DCHECK(n <= size_);
size_ -= n;
}
CONSTEXPR_IN_CPP14 void swap(StringView& other) {
const char* data = data_;
data_ = other.data_;
other.data_ = data;
size_t size = size_;
size_ = other.size_;
other.size_ = size;
}
// String conversion.
std::string ToString() const { return std::string(data_, size_); }
// String operations.
constexpr StringView substr(size_t pos = 0, size_t n = npos) const {
return StringView(data_ + pos, min(n, size_ - pos));
}
// Returns negative, 0, or positive when |this| is lexigraphically
// less than, equal to, or greater than |other|, a la
// std::basic_string_view::compare.
int compare(StringView other);
size_t find(StringView s, size_t pos = 0) const;
size_t find(char c, size_t pos = 0) const;
size_t rfind(StringView s, size_t pos = npos) const;
size_t rfind(char c, size_t pos = npos) const;
size_t find_first_of(StringView s, size_t pos = 0) const;
size_t find_last_of(StringView s, size_t pos = npos) const;
size_t find_first_not_of(StringView s, size_t pos = 0) const;
size_t find_last_not_of(StringView s, size_t pos = npos) const;
private:
constexpr static size_t min(size_t v1, size_t v2) {
return v1 < v2 ? v1 : v2;
}
constexpr static int constexpr_strlen(const char* str) {
#if defined(_MSC_VER)
return *str ? 1 + constexpr_strlen(str + 1) : 0;
#else
return __builtin_strlen(str);
#endif
}
const char* data_;
size_t size_;
};
// Comparison.
bool operator==(StringView lhs, StringView rhs);
bool operator!=(StringView lhs, StringView rhs);
bool operator<(StringView lhs, StringView rhs);
bool operator>(StringView lhs, StringView rhs);
bool operator<=(StringView lhs, StringView rhs);
bool operator>=(StringView lhs, StringView rhs);
// IO.
std::ostream& operator<<(std::ostream& o, StringView string_view);
} // namespace fml
#endif // FLUTTER_FML_STRING_VIEW_H_
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/fml/string_view.h"
#include <functional>
#include "gtest/gtest.h"
namespace fml {
namespace {
#define TEST_STRING "Hello\0u"
#define TEST_STRING_LENGTH 5u
// Loops over all substrings of |needles|, and calls |callback| for each.
void LoopOverSubstrings(StringView haystack,
StringView needles,
std::function<void(std::string haystack_str,
StringView haystack_sw,
std::string to_find_str,
StringView to_find_sw,
int start_index)> callback) {
std::string haystack_str = haystack.ToString();
for (size_t substring_size = 0; substring_size < needles.size();
++substring_size) {
for (size_t start_index = 0; start_index <= needles.size(); ++start_index) {
auto to_find = needles.substr(start_index, substring_size);
for (size_t start_pos = 0; start_pos <= haystack.size(); ++start_pos) {
callback(haystack_str, haystack, to_find.ToString(), to_find,
start_pos);
}
}
}
};
// Loops over all characters in |needles|, and calls |callback| for each.
void LoopOverChars(StringView haystack,
StringView needles,
std::function<void(std::string haystack_str,
StringView haystack_sw,
char c,
int start_index)> callback) {
std::string haystack_str = haystack.ToString();
for (size_t index = 0; index < needles.size(); ++index) {
for (size_t start_index = 0; start_index <= haystack.size();
++start_index) {
callback(haystack_str, haystack, needles[index], start_index);
}
}
}
// Loops over all combinations of characters present in |needles|, and calls
// |callback| for each.
void LoopOverCharCombinations(StringView haystack,
StringView needles,
std::function<void(std::string haystack_str,
StringView haystack_sw,
std::string current_chars,
size_t pos)> callback) {
// Look for all chars combinations, and compare with string.
std::set<char> chars(needles.begin(), needles.end());
std::string haystack_str = haystack.ToString();
for (size_t selector = 0; selector < (1 << chars.size()); ++selector) {
std::string current_chars;
size_t current = selector;
for (auto it = chars.begin(); it != chars.end(); ++it) {
if (current & 1)
current_chars += *it;
current = current >> 1;
}
for (size_t pos = 0; pos <= haystack.size(); ++pos) {
callback(haystack_str, haystack, current_chars, pos);
}
}
}
TEST(StringView, Constructors) {
std::string str1("Hello");
StringView sw1(str1);
EXPECT_EQ(str1.data(), sw1.data());
EXPECT_EQ(str1.size(), sw1.size());
EXPECT_EQ(TEST_STRING_LENGTH, sw1.size());
const char* str2 = str1.data();
StringView sw2(str2);
EXPECT_EQ(str1.data(), sw2.data());
EXPECT_EQ(TEST_STRING_LENGTH, sw2.size());
}
TEST(StringView, ConstExprConstructors) {
constexpr StringView sw1;
EXPECT_EQ(0u, sw1.size());
constexpr StringView sw2(sw1);
EXPECT_EQ(0u, sw2.size());
EXPECT_EQ(sw1.data(), sw2.data());
constexpr StringView sw3(TEST_STRING, TEST_STRING_LENGTH);
EXPECT_EQ(TEST_STRING_LENGTH, sw3.size());
constexpr StringView sw4(TEST_STRING);
EXPECT_EQ(TEST_STRING_LENGTH, sw4.size());
constexpr const char* string_ptr = TEST_STRING;
constexpr StringView sw5(string_ptr);
EXPECT_EQ(TEST_STRING_LENGTH, sw5.size());
}
TEST(StringView, CopyOperator) {
StringView sw1;
StringView sw2(TEST_STRING);
sw1 = sw2;
EXPECT_EQ(sw2.data(), sw1.data());
sw1 = TEST_STRING;
EXPECT_EQ(TEST_STRING_LENGTH, sw1.size());
sw1 = std::string(TEST_STRING);
EXPECT_EQ(TEST_STRING_LENGTH, sw1.size());
}
TEST(StringView, CapacityMethods) {
StringView sw1;
EXPECT_EQ(0u, sw1.size());
EXPECT_TRUE(sw1.empty());
StringView sw2(TEST_STRING);
EXPECT_EQ(TEST_STRING_LENGTH, sw2.size());
EXPECT_FALSE(sw2.empty());
}
TEST(StringView, AccessMethods) {
const char* str = TEST_STRING;
StringView sw1(str);
EXPECT_EQ('H', sw1.front());
EXPECT_EQ('e', sw1[1]);
EXPECT_EQ('l', sw1.at(2));
EXPECT_EQ('o', sw1.back());
EXPECT_EQ(str, sw1.data());
}
TEST(StringView, Iterators) {
StringView sw1(TEST_STRING);
std::string str1(sw1.begin(), sw1.end());
EXPECT_EQ(TEST_STRING, str1);
std::string str2(sw1.cbegin(), sw1.cend());
EXPECT_EQ(TEST_STRING, str2);
std::string str3(sw1.rbegin(), sw1.rend());
EXPECT_EQ("olleH", str3);
std::string str4(sw1.crbegin(), sw1.crend());
EXPECT_EQ("olleH", str4);
}
TEST(StringView, Modifiers) {
StringView sw1(TEST_STRING);
sw1.remove_prefix(1);
EXPECT_EQ("ello", sw1.ToString());
sw1.remove_suffix(1);
EXPECT_EQ("ell", sw1.ToString());
sw1.clear();
EXPECT_EQ(0u, sw1.size());
StringView sw2(TEST_STRING);
sw1.swap(sw2);
EXPECT_EQ(0u, sw2.size());
EXPECT_EQ(TEST_STRING, sw1.ToString());
}
TEST(StringView, SubString) {
StringView sw1(TEST_STRING);
StringView sw2 = sw1.substr(1, 2);
EXPECT_EQ("el", sw2.ToString());
}
TEST(StringView, Compare) {
StringView sw1(TEST_STRING);
StringView sw2(TEST_STRING);
EXPECT_EQ(0, sw1.compare(sw2));
sw1 = "a";
sw2 = "b";
EXPECT_GT(0, sw1.compare(sw2));
EXPECT_LT(0, sw2.compare(sw1));
sw1 = "a";
sw2 = "aa";
EXPECT_GT(0, sw1.compare(sw2));
EXPECT_LT(0, sw2.compare(sw1));
std::string str1("a\0a", 3);
std::string str2("a\0b", 3);
sw1 = str1;
sw2 = str2;
EXPECT_GT(0, sw1.compare(sw2));
EXPECT_LT(0, sw2.compare(sw1));
}
TEST(StringView, ComparaisonFunctions) {
StringView sw1 = "a";
StringView sw2 = "b";
EXPECT_TRUE(sw1 == sw1);
EXPECT_FALSE(sw1 == sw2);
EXPECT_FALSE(sw1 != sw1);
EXPECT_TRUE(sw1 != sw2);
EXPECT_TRUE(sw1 < sw2);
EXPECT_FALSE(sw2 < sw1);
EXPECT_TRUE(sw1 <= sw1);
EXPECT_TRUE(sw1 <= sw2);
EXPECT_FALSE(sw2 <= sw1);
EXPECT_TRUE(sw2 > sw1);
EXPECT_FALSE(sw1 > sw2);
EXPECT_TRUE(sw1 >= sw1);
EXPECT_TRUE(sw2 >= sw1);
EXPECT_FALSE(sw1 >= sw2);
}
TEST(StringView, Stream) {
StringView sw1(TEST_STRING);
std::stringstream ss;
ss << sw1;
EXPECT_EQ(TEST_STRING, ss.str());
}
TEST(StringView, find_String) {
StringView sw("Hello World");
EXPECT_EQ(StringView::npos, sw.find("z"));
EXPECT_EQ(StringView::npos, sw.find(" "));
EXPECT_EQ(StringView::npos, sw.find("lll"));
EXPECT_EQ(StringView::npos, sw.find("H", 1));
EXPECT_EQ(StringView::npos, sw.find("H", 255));
EXPECT_EQ(StringView::npos, sw.find("H", sw.size()));
auto test_callback = [](std::string haystack_str, StringView haystack_sw,
std::string to_find_str, StringView to_find_sw,
int start_index) {
EXPECT_EQ(haystack_str.find(to_find_str, start_index),
haystack_sw.find(to_find_sw, start_index));
};
LoopOverSubstrings(sw, sw, test_callback);
// Use another string for negative examples.
StringView other_sw("Fuchsia World");
LoopOverSubstrings(sw, other_sw, test_callback);
}
TEST(StringView, find_Chars) {
StringView sw("Hello World");
EXPECT_EQ(StringView::npos, sw.find('z'));
EXPECT_EQ(StringView::npos, sw.find('H', 1));
EXPECT_EQ(StringView::npos, sw.find('H', 255));
EXPECT_EQ(StringView::npos, sw.find('H', sw.size()));
auto test_callback = [](std::string haystack_str, StringView haystack_sw,
char c, int start_index) {
EXPECT_EQ(haystack_str.find(c, start_index),
haystack_sw.find(c, start_index));
};
// Look for all chars at all position, and compare with string.
LoopOverChars(sw, sw, test_callback);
// Use another string for negative examples.
StringView other_sw("Fuchsia World");
LoopOverChars(sw, other_sw, test_callback);
}
TEST(StringView, rfind_String) {
StringView sw("Hello World");
EXPECT_EQ(StringView::npos, sw.rfind("z"));
EXPECT_EQ(StringView::npos, sw.rfind(" "));
EXPECT_EQ(StringView::npos, sw.rfind("lll"));
EXPECT_EQ(StringView::npos, sw.rfind("d", sw.size() - 2));
EXPECT_EQ(StringView::npos, sw.rfind("d", 0));
EXPECT_EQ(StringView::npos, sw.rfind("d", 1));
// Look for all substring at all position, and compare with string.
auto test_callback = [](std::string haystack_str, StringView haystack_sw,
std::string to_find_str, StringView to_find_sw,
int start_index) {
EXPECT_EQ(haystack_str.rfind(to_find_str, start_index),
haystack_sw.rfind(to_find_sw, start_index));
};
LoopOverSubstrings(sw, sw, test_callback);
// Use another string for negative examples.
StringView other_sw("Fuchsia World");
LoopOverSubstrings(sw, other_sw, test_callback);
}
TEST(StringView, rfind_Char) {
StringView sw("Hello World");
EXPECT_EQ(StringView::npos, sw.rfind('z'));
EXPECT_EQ(StringView::npos, sw.rfind('d', sw.size() - 2));
EXPECT_EQ(StringView::npos, sw.rfind('d', 0));
EXPECT_EQ(StringView::npos, sw.rfind('d', 1));
auto test_callback = [](std::string haystack_str, StringView haystack_sw,
char c, int start_index) {
EXPECT_EQ(haystack_str.rfind(c, start_index),
haystack_sw.rfind(c, start_index));
};
// Look for all chars at all position, and compare with string.
LoopOverChars(sw, sw, test_callback);
// Use another string for negative examples.
StringView other_sw("Fuchsia World");
LoopOverChars(sw, other_sw, test_callback);
}
TEST(StringView, find_first_of) {
StringView sw("Hello World");
EXPECT_EQ(StringView::npos, sw.find_first_of(""));
EXPECT_EQ(StringView::npos, sw.find_first_of(std::string("xyz")));
EXPECT_EQ(StringView::npos, sw.find_first_of("xyHz", 1));
EXPECT_EQ(StringView::npos, sw.find_first_of("Hello World", sw.size()));
auto test_callback = [](std::string haystack_str, StringView haystack_sw,
std::string current_chars, size_t pos) {
EXPECT_EQ(haystack_str.find_first_of(current_chars, pos),
haystack_sw.find_first_of(current_chars, pos));
};
// Look for all chars combinations, and compare with string.
LoopOverCharCombinations(sw, sw, test_callback);
// Use another string for negative examples.
StringView other_sw("Fuchsia World");
LoopOverCharCombinations(sw, other_sw, test_callback);
}
TEST(StringView, find_last_of) {
StringView sw("Hello World");
EXPECT_EQ(StringView::npos, sw.find_last_of(""));
EXPECT_EQ(StringView::npos, sw.find_last_of(std::string("xyz")));
EXPECT_EQ(StringView::npos, sw.find_last_of("xydz", 1));
auto test_callback = [](std::string haystack_str, StringView haystack_sw,
std::string current_chars, size_t pos) {
EXPECT_EQ(haystack_str.find_last_of(current_chars, pos),
haystack_sw.find_last_of(current_chars, pos));
};
// Look for all chars combinations, and compare with string.
LoopOverCharCombinations(sw, sw, test_callback);
// Use another string for negative examples.
StringView other_sw("Fuchsia World");
LoopOverCharCombinations(sw, other_sw, test_callback);
}
TEST(StringView, find_first_not_of) {
StringView sw("Hello World");
EXPECT_EQ(StringView::npos, sw.find_first_not_of("Helo Wrd"));
EXPECT_EQ(StringView::npos, sw.find_first_not_of("elo Wrd", 1));
EXPECT_EQ(StringView::npos, sw.find_first_not_of("", sw.size()));
auto test_callback = [](std::string haystack_str, StringView haystack_sw,
std::string current_chars, size_t pos) {
EXPECT_EQ(haystack_str.find_first_not_of(current_chars, pos),
haystack_sw.find_first_not_of(current_chars, pos));
};
// Look for all chars combinations, and compare with string.
LoopOverCharCombinations(sw, sw, test_callback);
// Use another string for negative examples.
StringView other_sw("Fuchsia World");
LoopOverCharCombinations(sw, other_sw, test_callback);
}
TEST(StringView, find_last_not_of) {
StringView sw("Hello World");
EXPECT_EQ(StringView::npos, sw.find_last_not_of("Helo Wrd"));
EXPECT_EQ(StringView::npos, sw.find_last_not_of("H", 0));
auto test_callback = [](std::string haystack_str, StringView haystack_sw,
std::string current_chars, size_t pos) {
EXPECT_EQ(haystack_str.find_last_not_of(current_chars, pos),
haystack_sw.find_last_not_of(current_chars, pos));
};
// Look for all chars combinations, and compare with string.
LoopOverCharCombinations(sw, sw, test_callback);
// Use another string for negative examples.
StringView other_sw("Fuchsia World");
LoopOverCharCombinations(sw, other_sw, test_callback);
}
} // namespace
} // namespace fml
......@@ -20,21 +20,22 @@
namespace flutter {
const fml::StringView ServiceProtocol::kScreenshotExtensionName =
const std::string_view ServiceProtocol::kScreenshotExtensionName =
"_flutter.screenshot";
const fml::StringView ServiceProtocol::kScreenshotSkpExtensionName =
const std::string_view ServiceProtocol::kScreenshotSkpExtensionName =
"_flutter.screenshotSkp";
const fml::StringView ServiceProtocol::kRunInViewExtensionName =
const std::string_view ServiceProtocol::kRunInViewExtensionName =
"_flutter.runInView";
const fml::StringView ServiceProtocol::kFlushUIThreadTasksExtensionName =
const std::string_view ServiceProtocol::kFlushUIThreadTasksExtensionName =
"_flutter.flushUIThreadTasks";
const fml::StringView ServiceProtocol::kSetAssetBundlePathExtensionName =
const std::string_view ServiceProtocol::kSetAssetBundlePathExtensionName =
"_flutter.setAssetBundlePath";
const fml::StringView ServiceProtocol::kGetDisplayRefreshRateExtensionName =
const std::string_view ServiceProtocol::kGetDisplayRefreshRateExtensionName =
"_flutter.getDisplayRefreshRate";
static constexpr fml::StringView kViewIdPrefx = "_flutterView/";
static constexpr fml::StringView kListViewsExtensionName = "_flutter.listViews";
static constexpr std::string_view kViewIdPrefx = "_flutterView/";
static constexpr std::string_view kListViewsExtensionName =
"_flutter.listViews";
ServiceProtocol::ServiceProtocol()
: endpoints_({
......@@ -101,7 +102,7 @@ bool ServiceProtocol::HandleMessage(const char* method,
const char** json_object) {
Handler::ServiceProtocolMap params;
for (intptr_t i = 0; i < num_params; i++) {
params[fml::StringView{param_keys[i]}] = fml::StringView{param_values[i]};
params[std::string_view{param_keys[i]}] = std::string_view{param_values[i]};
}
#ifndef NDEBUG
......@@ -114,7 +115,7 @@ bool ServiceProtocol::HandleMessage(const char* method,
#endif // NDEBUG
rapidjson::Document document;
bool result = HandleMessage(fml::StringView{method}, //
bool result = HandleMessage(std::string_view{method}, //
params, //
static_cast<ServiceProtocol*>(user_data), //
document //
......@@ -132,7 +133,7 @@ bool ServiceProtocol::HandleMessage(const char* method,
return result;
}
bool ServiceProtocol::HandleMessage(fml::StringView method,
bool ServiceProtocol::HandleMessage(std::string_view method,
const Handler::ServiceProtocolMap& params,
ServiceProtocol* service_protocol,
rapidjson::Document& response) {
......@@ -147,7 +148,7 @@ bool ServiceProtocol::HandleMessage(fml::StringView method,
FML_WARN_UNUSED_RESULT
static bool HandleMessageOnHandler(
ServiceProtocol::Handler* handler,
fml::StringView method,
std::string_view method,
const ServiceProtocol::Handler::ServiceProtocolMap& params,
rapidjson::Document& document) {
FML_DCHECK(handler);
......@@ -170,7 +171,7 @@ static bool HandleMessageOnHandler(
return result;
}
bool ServiceProtocol::HandleMessage(fml::StringView method,
bool ServiceProtocol::HandleMessage(std::string_view method,
const Handler::ServiceProtocolMap& params,
rapidjson::Document& response) const {
if (method == kListViewsExtensionName) {
......@@ -188,7 +189,7 @@ bool ServiceProtocol::HandleMessage(fml::StringView method,
}
// Find the handler by its "viewId" in the params.
auto view_id_param_found = params.find(fml::StringView{"viewId"});
auto view_id_param_found = params.find(std::string_view{"viewId"});
if (view_id_param_found != params.end()) {
auto* handler = reinterpret_cast<Handler*>(std::stoull(
view_id_param_found->second.data() + kViewIdPrefx.size(), nullptr, 16));
......
......@@ -8,10 +8,10 @@
#include <map>
#include <set>
#include <string>
#include <string_view>
#include "flutter/fml/compiler_specific.h"
#include "flutter/fml/macros.h"
#include "flutter/fml/string_view.h"
#include "flutter/fml/synchronization/atomic_object.h"
#include "flutter/fml/synchronization/shared_mutex.h"
#include "flutter/fml/synchronization/thread_annotations.h"
......@@ -22,12 +22,12 @@ namespace flutter {
class ServiceProtocol {
public:
static const fml::StringView kScreenshotExtensionName;
static const fml::StringView kScreenshotSkpExtensionName;
static const fml::StringView kRunInViewExtensionName;
static const fml::StringView kFlushUIThreadTasksExtensionName;
static const fml::StringView kSetAssetBundlePathExtensionName;
static const fml::StringView kGetDisplayRefreshRateExtensionName;
static const std::string_view kScreenshotExtensionName;
static const std::string_view kScreenshotSkpExtensionName;
static const std::string_view kRunInViewExtensionName;
static const std::string_view kFlushUIThreadTasksExtensionName;
static const std::string_view kSetAssetBundlePathExtensionName;
static const std::string_view kGetDisplayRefreshRateExtensionName;
class Handler {
public:
......@@ -46,15 +46,15 @@ class ServiceProtocol {
rapidjson::MemoryPoolAllocator<>& allocator) const;
};
using ServiceProtocolMap = std::map<fml::StringView, fml::StringView>;
using ServiceProtocolMap = std::map<std::string_view, std::string_view>;
virtual fml::RefPtr<fml::TaskRunner> GetServiceProtocolHandlerTaskRunner(
fml::StringView method) const = 0;
std::string_view method) const = 0;
virtual Description GetServiceProtocolDescription() const = 0;
virtual bool HandleServiceProtocolMessage(
fml::StringView method, // one if the extension names specified above.
std::string_view method, // one if the extension names specified above.
const ServiceProtocolMap& params,
rapidjson::Document& response) = 0;
};
......@@ -73,7 +73,7 @@ class ServiceProtocol {
Handler::Description description);
private:
const std::set<fml::StringView> endpoints_;
const std::set<std::string_view> endpoints_;
std::unique_ptr<fml::SharedMutex> handlers_mutex_;
std::map<Handler*, fml::AtomicObject<Handler::Description>> handlers_;
......@@ -85,12 +85,12 @@ class ServiceProtocol {
void* user_data,
const char** json_object);
FML_WARN_UNUSED_RESULT
static bool HandleMessage(fml::StringView method,
static bool HandleMessage(std::string_view method,
const Handler::ServiceProtocolMap& params,
ServiceProtocol* service_protocol,
rapidjson::Document& response);
FML_WARN_UNUSED_RESULT
bool HandleMessage(fml::StringView method,
bool HandleMessage(std::string_view method,
const Handler::ServiceProtocolMap& params,
rapidjson::Document& response) const;
......
......@@ -6,6 +6,7 @@
#include <memory>
#include <string>
#include <string_view>
#include "flutter/fml/base32.h"
#include "flutter/fml/file.h"
......@@ -24,7 +25,8 @@ static std::string SkKeyToFilePath(const SkData& data) {
return "";
}
fml::StringView view(reinterpret_cast<const char*>(data.data()), data.size());
std::string_view view(reinterpret_cast<const char*>(data.data()),
data.size());
auto encode_result = fml::Base32Encode(view);
......
......@@ -285,33 +285,30 @@ Shell::Shell(DartVMRef vm, TaskRunners task_runners, Settings settings)
// Install service protocol handlers.
service_protocol_handlers_[ServiceProtocol::kScreenshotExtensionName
.ToString()] = {
service_protocol_handlers_[ServiceProtocol::kScreenshotExtensionName] = {
task_runners_.GetGPUTaskRunner(),
std::bind(&Shell::OnServiceProtocolScreenshot, this,
std::placeholders::_1, std::placeholders::_2)};
service_protocol_handlers_[ServiceProtocol::kScreenshotSkpExtensionName
.ToString()] = {
service_protocol_handlers_[ServiceProtocol::kScreenshotSkpExtensionName] = {
task_runners_.GetGPUTaskRunner(),
std::bind(&Shell::OnServiceProtocolScreenshotSKP, this,
std::placeholders::_1, std::placeholders::_2)};
service_protocol_handlers_[ServiceProtocol::kRunInViewExtensionName
.ToString()] = {
service_protocol_handlers_[ServiceProtocol::kRunInViewExtensionName] = {
task_runners_.GetUITaskRunner(),
std::bind(&Shell::OnServiceProtocolRunInView, this, std::placeholders::_1,
std::placeholders::_2)};
service_protocol_handlers_[ServiceProtocol::kFlushUIThreadTasksExtensionName
.ToString()] = {
task_runners_.GetUITaskRunner(),
std::bind(&Shell::OnServiceProtocolFlushUIThreadTasks, this,
std::placeholders::_1, std::placeholders::_2)};
service_protocol_handlers_[ServiceProtocol::kSetAssetBundlePathExtensionName
.ToString()] = {
task_runners_.GetUITaskRunner(),
std::bind(&Shell::OnServiceProtocolSetAssetBundlePath, this,
std::placeholders::_1, std::placeholders::_2)};
service_protocol_handlers_
[ServiceProtocol::kGetDisplayRefreshRateExtensionName.ToString()] = {
[ServiceProtocol::kFlushUIThreadTasksExtensionName] = {
task_runners_.GetUITaskRunner(),
std::bind(&Shell::OnServiceProtocolFlushUIThreadTasks, this,
std::placeholders::_1, std::placeholders::_2)};
service_protocol_handlers_
[ServiceProtocol::kSetAssetBundlePathExtensionName] = {
task_runners_.GetUITaskRunner(),
std::bind(&Shell::OnServiceProtocolSetAssetBundlePath, this,
std::placeholders::_1, std::placeholders::_2)};
service_protocol_handlers_
[ServiceProtocol::kGetDisplayRefreshRateExtensionName] = {
task_runners_.GetUITaskRunner(),
std::bind(&Shell::OnServiceProtocolGetDisplayRefreshRate, this,
std::placeholders::_1, std::placeholders::_2)};
......@@ -979,9 +976,9 @@ void Shell::OnFrameRasterized(const FrameTiming& timing) {
// |ServiceProtocol::Handler|
fml::RefPtr<fml::TaskRunner> Shell::GetServiceProtocolHandlerTaskRunner(
fml::StringView method) const {
std::string_view method) const {
FML_DCHECK(is_setup_);
auto found = service_protocol_handlers_.find(method.ToString());
auto found = service_protocol_handlers_.find(method);
if (found != service_protocol_handlers_.end()) {
return found->second.first;
}
......@@ -990,10 +987,10 @@ fml::RefPtr<fml::TaskRunner> Shell::GetServiceProtocolHandlerTaskRunner(
// |ServiceProtocol::Handler|
bool Shell::HandleServiceProtocolMessage(
fml::StringView method, // one if the extension names specified above.
std::string_view method, // one if the extension names specified above.
const ServiceProtocolMap& params,
rapidjson::Document& response) {
auto found = service_protocol_handlers_.find(method.ToString());
auto found = service_protocol_handlers_.find(method);
if (found != service_protocol_handlers_.end()) {
return found->second.second(params, response);
}
......@@ -1103,11 +1100,11 @@ bool Shell::OnServiceProtocolRunInView(
}
std::string main_script_path =
fml::paths::FromURI(params.at("mainScript").ToString());
fml::paths::FromURI(params.at("mainScript").data());
std::string packages_path =
fml::paths::FromURI(params.at("packagesFile").ToString());
fml::paths::FromURI(params.at("packagesFile").data());
std::string asset_directory_path =
fml::paths::FromURI(params.at("assetDirectory").ToString());
fml::paths::FromURI(params.at("assetDirectory").data());
auto main_script_file_mapping =
std::make_unique<fml::FileMapping>(fml::OpenFile(
......@@ -1186,7 +1183,7 @@ bool Shell::OnServiceProtocolSetAssetBundlePath(
auto asset_manager = std::make_shared<AssetManager>();
asset_manager->PushFront(std::make_unique<DirectoryAssetBundle>(
fml::OpenDirectory(params.at("assetDirectory").ToString().c_str(), false,
fml::OpenDirectory(params.at("assetDirectory").data(), false,
fml::FilePermission::kRead)));
if (engine_->UpdateAssetManager(std::move(asset_manager))) {
......
......@@ -6,6 +6,7 @@
#define SHELL_COMMON_SHELL_H_
#include <functional>
#include <string_view>
#include <unordered_map>
#include "flutter/common/settings.h"
......@@ -16,7 +17,6 @@
#include "flutter/fml/memory/ref_ptr.h"
#include "flutter/fml/memory/thread_checker.h"
#include "flutter/fml/memory/weak_ptr.h"
#include "flutter/fml/string_view.h"
#include "flutter/fml/synchronization/thread_annotations.h"
#include "flutter/fml/synchronization/waitable_event.h"
#include "flutter/fml/thread.h"
......@@ -261,7 +261,7 @@ class Shell final : public PlatformView::Delegate,
fml::WeakPtr<PlatformView>
weak_platform_view_; // to be shared across threads
std::unordered_map<std::string, // method
std::unordered_map<std::string_view, // method
std::pair<fml::RefPtr<fml::TaskRunner>,
ServiceProtocolHandler> // task-runner/function
// pair
......@@ -390,11 +390,11 @@ class Shell final : public PlatformView::Delegate,
// |ServiceProtocol::Handler|
fml::RefPtr<fml::TaskRunner> GetServiceProtocolHandlerTaskRunner(
fml::StringView method) const override;
std::string_view method) const override;
// |ServiceProtocol::Handler|
bool HandleServiceProtocolMessage(
fml::StringView method, // one if the extension names specified above.
std::string_view method, // one if the extension names specified above.
const ServiceProtocolMap& params,
rapidjson::Document& response) override;
......
......@@ -12,7 +12,6 @@
#include "flutter/fml/native_library.h"
#include "flutter/fml/paths.h"
#include "flutter/fml/size.h"
#include "flutter/fml/string_view.h"
#include "flutter/shell/version/version.h"
// Include once for the default enum definition.
......@@ -22,7 +21,7 @@
struct SwitchDesc {
flutter::Switch sw;
const fml::StringView flag;
const std::string_view flag;
const char* help;
};
......@@ -86,7 +85,9 @@ void PrintUsage(const std::string& executable_name) {
auto desc = gSwitchDescs[i];
std::cerr << std::setw(max_width)
<< std::string("--") + desc.flag.ToString() << " : ";
<< std::string("--") +
std::string{desc.flag.data(), desc.flag.size()}
<< " : ";
std::istringstream stream(desc.help);
int32_t remaining = help_width;
......@@ -108,13 +109,13 @@ void PrintUsage(const std::string& executable_name) {
std::cerr << std::string(column_width, '-') << std::endl;
}
const fml::StringView FlagForSwitch(Switch swtch) {
const std::string_view FlagForSwitch(Switch swtch) {
for (uint32_t i = 0; i < static_cast<uint32_t>(Switch::Sentinel); i++) {
if (gSwitchDescs[i].sw == swtch) {
return gSwitchDescs[i].flag;
}
}
return fml::StringView();
return std::string_view();
}
#if FLUTTER_RUNTIME_MODE != FLUTTER_RUNTIME_MODE_RELEASE
......
......@@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <string_view>
#include "flutter/common/settings.h"
#include "flutter/fml/command_line.h"
#include "flutter/fml/string_view.h"
#ifndef SHELL_COMMON_SWITCHES_H_
#define SHELL_COMMON_SWITCHES_H_
......@@ -157,7 +158,7 @@ DEF_SWITCHES_END
void PrintUsage(const std::string& executable_name);
const fml::StringView FlagForSwitch(Switch swtch);
const std::string_view FlagForSwitch(Switch swtch);
Settings SettingsFromCommandLine(const fml::CommandLine& command_line);
......
......@@ -16,6 +16,8 @@
#include "txt_test_utils.h"
#include <sstream>
#include "third_party/skia/include/core/SkTypeface.h"
#include "txt/asset_font_manager.h"
#include "txt/typeface_font_asset_provider.h"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册