diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index a854944969fbf..45901aa51c07e 100755 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -285,7 +285,9 @@ FILE: ../../../flutter/fml/platform/win/message_loop_win.h FILE: ../../../flutter/fml/platform/win/native_library_win.cc FILE: ../../../flutter/fml/platform/win/paths_win.cc FILE: ../../../flutter/fml/platform/win/posix_wrappers_win.cc +FILE: ../../../flutter/fml/platform/win/wstring_conversion.cc FILE: ../../../flutter/fml/platform/win/wstring_conversion.h +FILE: ../../../flutter/fml/platform/win/wstring_conversion_unittests.cc FILE: ../../../flutter/fml/posix_wrappers.h FILE: ../../../flutter/fml/raster_thread_merger.cc FILE: ../../../flutter/fml/raster_thread_merger.h @@ -294,6 +296,9 @@ FILE: ../../../flutter/fml/shared_thread_merger.cc FILE: ../../../flutter/fml/shared_thread_merger.h FILE: ../../../flutter/fml/size.h FILE: ../../../flutter/fml/status.h +FILE: ../../../flutter/fml/string_conversion.cc +FILE: ../../../flutter/fml/string_conversion.h +FILE: ../../../flutter/fml/string_conversion_unittests.cc FILE: ../../../flutter/fml/synchronization/atomic_object.h FILE: ../../../flutter/fml/synchronization/count_down_latch.cc FILE: ../../../flutter/fml/synchronization/count_down_latch.h @@ -2049,9 +2054,6 @@ FILE: ../../../flutter/shell/platform/windows/public/flutter_windows.h FILE: ../../../flutter/shell/platform/windows/sequential_id_generator.cc FILE: ../../../flutter/shell/platform/windows/sequential_id_generator.h FILE: ../../../flutter/shell/platform/windows/sequential_id_generator_unittests.cc -FILE: ../../../flutter/shell/platform/windows/string_conversion.cc -FILE: ../../../flutter/shell/platform/windows/string_conversion.h -FILE: ../../../flutter/shell/platform/windows/string_conversion_unittests.cc FILE: ../../../flutter/shell/platform/windows/system_utils.h FILE: ../../../flutter/shell/platform/windows/system_utils_unittests.cc FILE: ../../../flutter/shell/platform/windows/system_utils_win32.cc diff --git a/fml/BUILD.gn b/fml/BUILD.gn index 39610f6aa5613..71f3f929a542b 100644 --- a/fml/BUILD.gn +++ b/fml/BUILD.gn @@ -104,7 +104,11 @@ source_set("fml") { sources += [ "backtrace_stub.cc" ] } - public_deps = [ ":command_line" ] + public_deps = [ + ":build_config", + ":command_line", + ":string_conversion", + ] deps = [ "//third_party/abseil-cpp/absl/debugging:symbolize", @@ -217,11 +221,7 @@ source_set("fml") { "platform/win/native_library_win.cc", "platform/win/paths_win.cc", "platform/win/posix_wrappers_win.cc", - "platform/win/wstring_conversion.h", ] - - # For wstring_conversion. See issue #50053. - defines = [ "_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING" ] } else { sources += [ "platform/posix/file_posix.cc", @@ -233,6 +233,15 @@ source_set("fml") { } } +source_set("build_config") { + sources = [ "build_config.h" ] + + public_configs = [ + "//flutter:config", + "//flutter/common:flutter_config", + ] +} + source_set("command_line") { sources = [ "command_line.cc", @@ -245,6 +254,30 @@ source_set("command_line") { ] } +source_set("string_conversion") { + sources = [ + "string_conversion.cc", + "string_conversion.h", + ] + + if (is_win) { + sources += [ + "platform/win/wstring_conversion.cc", + "platform/win/wstring_conversion.h", + ] + + # TODO(cbracken): https://github.com/flutter/flutter/issues/50053 + defines = [ "_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING" ] + } + + deps = [ ":build_config" ] + + public_configs = [ + "//flutter:config", + "//flutter/common:flutter_config", + ] +} + if (enable_unittests) { test_fixtures("fml_fixtures") { fixtures = [] @@ -286,6 +319,7 @@ if (enable_unittests) { "message_loop_unittests.cc", "paths_unittests.cc", "raster_thread_merger_unittests.cc", + "string_conversion_unittests.cc", "synchronization/count_down_latch_unittests.cc", "synchronization/semaphore_unittest.cc", "synchronization/sync_switch_unittest.cc", @@ -307,6 +341,10 @@ if (enable_unittests) { ] } + if (is_win) { + sources += [ "platform/win/wstring_conversion_unittests.cc" ] + } + deps = [ ":fml_fixtures", "//flutter/fml", diff --git a/fml/platform/win/errors_win.cc b/fml/platform/win/errors_win.cc index 7370ee86ff425..35f5b0add6843 100644 --- a/fml/platform/win/errors_win.cc +++ b/fml/platform/win/errors_win.cc @@ -40,7 +40,7 @@ std::string GetLastErrorMessage() { std::wstringstream stream; stream << message << " (" << last_error << ")."; - return WideStringToString(stream.str()); + return WideStringToUtf8(stream.str()); } } // namespace fml diff --git a/fml/platform/win/file_win.cc b/fml/platform/win/file_win.cc index c5a3eb1775daa..9f60ea59d86d3 100644 --- a/fml/platform/win/file_win.cc +++ b/fml/platform/win/file_win.cc @@ -45,7 +45,7 @@ static std::string GetFullHandlePath(const fml::UniqueFD& handle) { // was cached if (result && memcmp(found.value().id.Identifier, info.FileId.Identifier, sizeof(FILE_ID_INFO))) { - return WideStringToString(found.value().filename); + return WideStringToUtf8(found.value().filename); } else { fml::internal::os_win::UniqueFDTraits::RemoveCacheEntry(handle.get()); } @@ -59,7 +59,7 @@ static std::string GetFullHandlePath(const fml::UniqueFD& handle) { if (buffer_size == 0) { return {}; } - return WideStringToString({buffer, buffer_size}); + return WideStringToUtf8({buffer, buffer_size}); #endif } @@ -106,7 +106,7 @@ static DWORD GetShareFlags(FilePermission permission) { } static DWORD GetFileAttributesForUtf8Path(const char* absolute_path) { - return ::GetFileAttributes(StringToWideString(absolute_path).c_str()); + return ::GetFileAttributes(Utf8ToWideString(absolute_path).c_str()); } static DWORD GetFileAttributesForUtf8Path(const fml::UniqueFD& base_directory, @@ -147,7 +147,7 @@ std::string CreateTemporaryDirectory() { stream << temp_dir_container << "\\" << uuid_str; auto temp_dir = stream.str(); - auto dir_fd = OpenDirectory(WideStringToString(temp_dir).c_str(), true, + auto dir_fd = OpenDirectory(WideStringToUtf8(temp_dir).c_str(), true, FilePermission::kReadWrite); if (!dir_fd.is_valid()) { FML_DLOG(ERROR) << "Could not get temporary directory file descriptor. " @@ -155,7 +155,7 @@ std::string CreateTemporaryDirectory() { return {}; } - return WideStringToString(std::move(temp_dir)); + return WideStringToUtf8(std::move(temp_dir)); } fml::UniqueFD OpenFile(const fml::UniqueFD& base_directory, @@ -173,7 +173,7 @@ fml::UniqueFD OpenFile(const char* path, return {}; } - auto file_name = StringToWideString({path}); + auto file_name = Utf8ToWideString({path}); if (file_name.size() == 0) { return {}; @@ -216,7 +216,7 @@ fml::UniqueFD OpenDirectory(const char* path, return {}; } - auto file_name = StringToWideString({path}); + auto file_name = Utf8ToWideString({path}); if (file_name.size() == 0) { return {}; @@ -314,7 +314,7 @@ bool IsFile(const std::string& path) { } bool UnlinkDirectory(const char* path) { - if (!::RemoveDirectory(StringToWideString(path).c_str())) { + if (!::RemoveDirectory(Utf8ToWideString(path).c_str())) { FML_DLOG(ERROR) << "Could not remove directory: '" << path << "'. " << GetLastErrorMessage(); return false; @@ -324,7 +324,7 @@ bool UnlinkDirectory(const char* path) { bool UnlinkDirectory(const fml::UniqueFD& base_directory, const char* path) { if (!::RemoveDirectory( - StringToWideString(GetAbsolutePath(base_directory, path)).c_str())) { + Utf8ToWideString(GetAbsolutePath(base_directory, path)).c_str())) { FML_DLOG(ERROR) << "Could not remove directory: '" << path << "'. " << GetLastErrorMessage(); return false; @@ -333,7 +333,7 @@ bool UnlinkDirectory(const fml::UniqueFD& base_directory, const char* path) { } bool UnlinkFile(const char* path) { - if (!::DeleteFile(StringToWideString(path).c_str())) { + if (!::DeleteFile(Utf8ToWideString(path).c_str())) { FML_DLOG(ERROR) << "Could not remove file: '" << path << "'. " << GetLastErrorMessage(); return false; @@ -343,7 +343,7 @@ bool UnlinkFile(const char* path) { bool UnlinkFile(const fml::UniqueFD& base_directory, const char* path) { if (!::DeleteFile( - StringToWideString(GetAbsolutePath(base_directory, path)).c_str())) { + Utf8ToWideString(GetAbsolutePath(base_directory, path)).c_str())) { FML_DLOG(ERROR) << "Could not remove file: '" << path << "'. " << GetLastErrorMessage(); return false; @@ -436,8 +436,8 @@ bool WriteAtomically(const fml::UniqueFD& base_directory, temp_file.reset(); - if (!::MoveFile(StringToWideString(temp_file_path).c_str(), - StringToWideString(file_path).c_str())) { + if (!::MoveFile(Utf8ToWideString(temp_file_path).c_str(), + Utf8ToWideString(file_path).c_str())) { FML_DLOG(ERROR) << "Could not replace temp file at correct path. File path: " << file_path << ". Temp file path: " << temp_file_path << " " @@ -451,8 +451,8 @@ bool WriteAtomically(const fml::UniqueFD& base_directory, bool VisitFiles(const fml::UniqueFD& directory, const FileVisitor& visitor) { std::string search_pattern = GetFullHandlePath(directory) + "\\*"; WIN32_FIND_DATA find_file_data; - HANDLE find_handle = ::FindFirstFile( - StringToWideString(search_pattern).c_str(), &find_file_data); + HANDLE find_handle = ::FindFirstFile(Utf8ToWideString(search_pattern).c_str(), + &find_file_data); if (find_handle == INVALID_HANDLE_VALUE) { FML_DLOG(ERROR) << "Can't open the directory. Error: " @@ -461,7 +461,7 @@ bool VisitFiles(const fml::UniqueFD& directory, const FileVisitor& visitor) { } do { - std::string filename = WideStringToString(find_file_data.cFileName); + std::string filename = WideStringToUtf8(find_file_data.cFileName); if (filename != "." && filename != "..") { if (!visitor(directory, filename)) { ::FindClose(find_handle); diff --git a/fml/platform/win/native_library_win.cc b/fml/platform/win/native_library_win.cc index 27a880066110f..6c1bf5c94e098 100644 --- a/fml/platform/win/native_library_win.cc +++ b/fml/platform/win/native_library_win.cc @@ -16,7 +16,7 @@ NativeLibrary::NativeLibrary(const char* path) return; } - handle_ = ::LoadLibrary(StringToWideString(path).c_str()); + handle_ = ::LoadLibrary(Utf8ToWideString(path).c_str()); } NativeLibrary::NativeLibrary(Handle handle, bool close_handle) diff --git a/fml/platform/win/wstring_conversion.cc b/fml/platform/win/wstring_conversion.cc new file mode 100644 index 0000000000000..6e4e36e8cf629 --- /dev/null +++ b/fml/platform/win/wstring_conversion.cc @@ -0,0 +1,26 @@ +// 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/platform/win/wstring_conversion.h" + +#include +#include +#include + +namespace fml { + +using WideStringConverter = + std::wstring_convert, wchar_t>; + +std::string WideStringToUtf8(const std::wstring_view str) { + WideStringConverter converter; + return converter.to_bytes(str.data()); +} + +std::wstring Utf8ToWideString(const std::string_view str) { + WideStringConverter converter; + return converter.from_bytes(str.data()); +} + +} // namespace fml diff --git a/fml/platform/win/wstring_conversion.h b/fml/platform/win/wstring_conversion.h index d68f6156730b0..4e7c110685491 100644 --- a/fml/platform/win/wstring_conversion.h +++ b/fml/platform/win/wstring_conversion.h @@ -5,24 +5,16 @@ #ifndef FLUTTER_FML_PLATFORM_WIN_WSTRING_CONVERSION_H_ #define FLUTTER_FML_PLATFORM_WIN_WSTRING_CONVERSION_H_ -#include -#include #include namespace fml { -using WideStringConvertor = - std::wstring_convert, wchar_t>; +// Returns a UTF-8 encoded equivalent of a UTF-16 encoded input wide string. +std::string WideStringToUtf8(const std::wstring_view str); -inline std::wstring StringToWideString(const std::string& str) { - WideStringConvertor converter; - return converter.from_bytes(str); -} - -inline std::string WideStringToString(const std::wstring& wstr) { - WideStringConvertor converter; - return converter.to_bytes(wstr); -} +// Returns a UTF-16 encoded wide string equivalent of a UTF-8 encoded input +// string. +std::wstring Utf8ToWideString(const std::string_view str); } // namespace fml diff --git a/fml/platform/win/wstring_conversion_unittests.cc b/fml/platform/win/wstring_conversion_unittests.cc new file mode 100644 index 0000000000000..81af2594ce94c --- /dev/null +++ b/fml/platform/win/wstring_conversion_unittests.cc @@ -0,0 +1,37 @@ +// 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/platform/win/wstring_conversion.h" + +#include "gtest/gtest.h" + +namespace fml { +namespace testing { + +TEST(StringConversion, Utf16ToWideStringEmpty) { + EXPECT_EQ(Utf8ToWideString(""), L""); +} + +TEST(StringConversion, Utf8ToWideStringAscii) { + EXPECT_EQ(Utf8ToWideString("abc123"), L"abc123"); +} + +TEST(StringConversion, Utf8ToWideStringUnicode) { + EXPECT_EQ(Utf8ToWideString("\xe2\x98\x83"), L"\x2603"); +} + +TEST(StringConversion, WideStringToUtf8Empty) { + EXPECT_EQ(WideStringToUtf8(L""), ""); +} + +TEST(StringConversion, WideStringToUtf8Ascii) { + EXPECT_EQ(WideStringToUtf8(L"abc123"), "abc123"); +} + +TEST(StringConversion, WideStringToUtf8Unicode) { + EXPECT_EQ(WideStringToUtf8(L"\x2603"), "\xe2\x98\x83"); +} + +} // namespace testing +} // namespace fml diff --git a/fml/string_conversion.cc b/fml/string_conversion.cc new file mode 100644 index 0000000000000..7b718fef19394 --- /dev/null +++ b/fml/string_conversion.cc @@ -0,0 +1,35 @@ +// 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_conversion.h" + +#include +#include +#include + +#include "flutter/fml/build_config.h" + +#if defined(FML_OS_WIN) +// TODO(naifu): https://github.com/flutter/flutter/issues/98074 +// Eliminate this workaround for a link error on Windows when the underlying +// bug is fixed. +std::locale::id std::codecvt::id; +#endif // defined(FML_OS_WIN) + +namespace fml { + +using Utf16StringConverter = + std::wstring_convert, char16_t>; + +std::string Utf16ToUtf8(const std::u16string_view string) { + Utf16StringConverter converter; + return converter.to_bytes(string.data()); +} + +std::u16string Utf8ToUtf16(const std::string_view string) { + Utf16StringConverter converter; + return converter.from_bytes(string.data()); +} + +} // namespace fml diff --git a/fml/string_conversion.h b/fml/string_conversion.h new file mode 100644 index 0000000000000..5c2402980dab5 --- /dev/null +++ b/fml/string_conversion.h @@ -0,0 +1,20 @@ +// 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_CONVERSION_H_ +#define FLUTTER_FML_STRING_CONVERSION_H_ + +#include + +namespace fml { + +// Returns a UTF-8 encoded equivalent of a UTF-16 encoded input string. +std::string Utf16ToUtf8(const std::u16string_view string); + +// Returns a UTF-16 encoded equivalent of a UTF-8 encoded input string. +std::u16string Utf8ToUtf16(const std::string_view string); + +} // namespace fml + +#endif // FLUTTER_FML_STRING_CONVERSION_H_ diff --git a/fml/string_conversion_unittests.cc b/fml/string_conversion_unittests.cc new file mode 100644 index 0000000000000..4d12075709014 --- /dev/null +++ b/fml/string_conversion_unittests.cc @@ -0,0 +1,37 @@ +// 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_conversion.h" + +#include "gtest/gtest.h" + +namespace fml { +namespace testing { + +TEST(StringConversion, Utf16ToUtf16Empty) { + EXPECT_EQ(Utf8ToUtf16(""), u""); +} + +TEST(StringConversion, Utf8ToUtf16Ascii) { + EXPECT_EQ(Utf8ToUtf16("abc123"), u"abc123"); +} + +TEST(StringConversion, Utf8ToUtf16Unicode) { + EXPECT_EQ(Utf8ToUtf16("\xe2\x98\x83"), u"\x2603"); +} + +TEST(StringConversion, Utf16ToUtf8Empty) { + EXPECT_EQ(Utf16ToUtf8(u""), ""); +} + +TEST(StringConversion, Utf16ToUtf8Ascii) { + EXPECT_EQ(Utf16ToUtf8(u"abc123"), "abc123"); +} + +TEST(StringConversion, Utf16ToUtf8Unicode) { + EXPECT_EQ(Utf16ToUtf8(u"\x2603"), "\xe2\x98\x83"); +} + +} // namespace testing +} // namespace fml diff --git a/shell/platform/common/BUILD.gn b/shell/platform/common/BUILD.gn index 1125ee35553ce..0f0136d2320ea 100644 --- a/shell/platform/common/BUILD.gn +++ b/shell/platform/common/BUILD.gn @@ -54,11 +54,6 @@ source_set("common_cpp_input") { public_configs = [ "//flutter:config" ] deps = [ "//flutter/fml:fml" ] - - if (is_win) { - # For wstring_conversion. See issue #50053. - defines = [ "_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING" ] - } } source_set("common_cpp_switches") { @@ -181,6 +176,7 @@ if (enable_unittests) { ":common_cpp_fixtures", ":common_cpp_input", ":common_cpp_switches", + "//flutter/fml:string_conversion", "//flutter/shell/platform/common/client_wrapper:client_wrapper", "//flutter/shell/platform/common/client_wrapper:client_wrapper_library_stubs", "//flutter/testing", diff --git a/shell/platform/common/text_editing_delta.cc b/shell/platform/common/text_editing_delta.cc index e07cdcb30a1b6..2c89a2cd5ef31 100644 --- a/shell/platform/common/text_editing_delta.cc +++ b/shell/platform/common/text_editing_delta.cc @@ -4,6 +4,8 @@ #include "flutter/shell/platform/common/text_editing_delta.h" +#include "flutter/fml/string_conversion.h" + namespace flutter { TextEditingDelta::TextEditingDelta(const std::u16string& text_before_change, @@ -17,8 +19,8 @@ TextEditingDelta::TextEditingDelta(const std::u16string& text_before_change, TextEditingDelta::TextEditingDelta(const std::string& text_before_change, TextRange range, const std::string& text) - : old_text_(Utf8ToUtf16(text_before_change)), - delta_text_(Utf8ToUtf16(text)), + : old_text_(fml::Utf8ToUtf16(text_before_change)), + delta_text_(fml::Utf8ToUtf16(text)), delta_start_(range.start()), delta_end_(range.start() + range.length()) {} @@ -26,7 +28,7 @@ TextEditingDelta::TextEditingDelta(const std::u16string& text) : old_text_(text), delta_text_(u""), delta_start_(-1), delta_end_(-1) {} TextEditingDelta::TextEditingDelta(const std::string& text) - : old_text_(Utf8ToUtf16(text)), + : old_text_(fml::Utf8ToUtf16(text)), delta_text_(u""), delta_start_(-1), delta_end_(-1) {} diff --git a/shell/platform/common/text_editing_delta.h b/shell/platform/common/text_editing_delta.h index e66e891f7db18..528277b67306f 100644 --- a/shell/platform/common/text_editing_delta.h +++ b/shell/platform/common/text_editing_delta.h @@ -4,11 +4,10 @@ #ifndef FLUTTER_SHELL_PLATFORM_COMMON_TEXT_EDITING_DELTA_H_ #define FLUTTER_SHELL_PLATFORM_COMMON_TEXT_EDITING_DELTA_H_ -#define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING -#include #include +#include "flutter/fml/string_conversion.h" #include "flutter/shell/platform/common/text_range.h" namespace flutter { @@ -32,12 +31,12 @@ struct TextEditingDelta { /// Get the old_text_ value. /// /// All strings are stored as UTF16 but converted to UTF8 when accessed. - std::string old_text() const { return Utf16ToUtf8(old_text_); } + std::string old_text() const { return fml::Utf16ToUtf8(old_text_); } /// Get the delta_text value. /// /// All strings are stored as UTF16 but converted to UTF8 when accessed. - std::string delta_text() const { return Utf16ToUtf8(delta_text_); } + std::string delta_text() const { return fml::Utf16ToUtf8(delta_text_); } /// Get the delta_start_ value. int delta_start() const { return delta_start_; } @@ -71,20 +70,6 @@ struct TextEditingDelta { void set_delta_start(int delta_start) { delta_start_ = delta_start; } void set_delta_end(int delta_end) { delta_end_ = delta_end; } - - // Given a UTF16-encoded string, returns the string encoded in UTF8. - static std::string Utf16ToUtf8(const std::u16string& string) { - std::wstring_convert, char16_t> - utf8_converter; - return utf8_converter.to_bytes(string); - } - - // Given a UTF8-encoded string, returns the string encoded in UTF16. - static std::u16string Utf8ToUtf16(const std::string& string) { - std::wstring_convert, char16_t> - utf16_converter; - return utf16_converter.from_bytes(string); - } }; } // namespace flutter diff --git a/shell/platform/common/text_input_model.cc b/shell/platform/common/text_input_model.cc index d6354650b2f72..93f297df91840 100644 --- a/shell/platform/common/text_input_model.cc +++ b/shell/platform/common/text_input_model.cc @@ -5,14 +5,9 @@ #include "flutter/shell/platform/common/text_input_model.h" #include -#include -#include +#include -#if defined(_MSC_VER) -// TODO(naifu): This temporary code is to solve link error.(VS2015/2017) -// https://social.msdn.microsoft.com/Forums/vstudio/en-US/8f40dcd8-c67f-4eba-9134-a19b9178e481/vs-2015-rc-linker-stdcodecvt-error -std::locale::id std::codecvt::id; -#endif // defined(_MSC_VER) +#include "flutter/fml/string_conversion.h" namespace flutter { @@ -34,9 +29,7 @@ TextInputModel::TextInputModel() = default; TextInputModel::~TextInputModel() = default; void TextInputModel::SetText(const std::string& text) { - std::wstring_convert, char16_t> - utf16_converter; - text_ = utf16_converter.from_bytes(text); + text_ = fml::Utf8ToUtf16(text); selection_ = TextRange(0); composing_range_ = TextRange(0); } @@ -79,9 +72,7 @@ void TextInputModel::UpdateComposingText(const std::u16string& text) { } void TextInputModel::UpdateComposingText(const std::string& text) { - std::wstring_convert, char16_t> - utf16_converter; - UpdateComposingText(utf16_converter.from_bytes(text)); + UpdateComposingText(fml::Utf8ToUtf16(text)); } void TextInputModel::CommitComposing() { @@ -140,9 +131,7 @@ void TextInputModel::AddText(const std::u16string& text) { } void TextInputModel::AddText(const std::string& text) { - std::wstring_convert, char16_t> - utf16_converter; - AddText(utf16_converter.from_bytes(text)); + AddText(fml::Utf8ToUtf16(text)); } bool TextInputModel::Backspace() { @@ -290,18 +279,14 @@ bool TextInputModel::MoveCursorBack() { } std::string TextInputModel::GetText() const { - std::wstring_convert, char16_t> - utf8_converter; - return utf8_converter.to_bytes(text_); + return fml::Utf16ToUtf8(text_); } int TextInputModel::GetCursorOffset() const { // Measure the length of the current text up to the selection extent. // There is probably a much more efficient way of doing this. auto leading_text = text_.substr(0, selection_.extent()); - std::wstring_convert, char16_t> - utf8_converter; - return utf8_converter.to_bytes(leading_text).size(); + return fml::Utf16ToUtf8(leading_text).size(); } } // namespace flutter diff --git a/shell/platform/windows/BUILD.gn b/shell/platform/windows/BUILD.gn index a19418e2aa75d..ee8504033e701 100644 --- a/shell/platform/windows/BUILD.gn +++ b/shell/platform/windows/BUILD.gn @@ -165,7 +165,7 @@ source_set("flutter_windows_source") { } public_deps = [ - ":string_conversion", + "//flutter/fml:string_conversion", "//flutter/shell/platform/common:common_cpp_accessibility", ] @@ -187,18 +187,6 @@ source_set("flutter_windows_source") { ] } -# String encoding conversion utilities. -source_set("string_conversion") { - sources = [ - "string_conversion.cc", - "string_conversion.h", - ] - - if (target_os == "winuwp") { - cflags = [ "/EHsc" ] - } -} - copy("publish_headers_windows") { sources = _public_headers outputs = [ "$root_out_dir/{{source_file_part}}" ] @@ -238,7 +226,6 @@ executable("flutter_windows_unittests") { # "flutter_project_bundle_unittests.cc", //TODO failing due to switches test failing. Blocked on https://github.com/flutter/flutter/issues/74153 # "flutter_windows_engine_unittests.cc", //TODO failing to send / receive platform message get plugins working first. Blocked on https://github.com/flutter/flutter/issues/74155 "sequential_id_generator_unittests.cc", - "string_conversion_unittests.cc", "system_utils_unittests.cc", "task_runner_unittests.cc", "testing/engine_modifier.h", @@ -352,7 +339,7 @@ source_set("uwptool_utils") { "uwptool_utils.h", ] - deps = [ ":string_conversion" ] + deps = [ "//flutter/fml:string_conversion" ] defines = [ "_SILENCE_CLANG_COROUTINE_MESSAGE" ] } @@ -372,9 +359,9 @@ executable("uwptool") { sources = [ "uwptool_main.cc" ] deps = [ - ":string_conversion", ":uwptool_utils", "//flutter/fml:command_line", + "//flutter/fml:string_conversion", ] defines = [ "_SILENCE_CLANG_COROUTINE_MESSAGE" ] diff --git a/shell/platform/windows/flutter_windows_engine.cc b/shell/platform/windows/flutter_windows_engine.cc index 418c1b5baf7bf..ec4a556f7098b 100644 --- a/shell/platform/windows/flutter_windows_engine.cc +++ b/shell/platform/windows/flutter_windows_engine.cc @@ -8,12 +8,12 @@ #include #include +#include "flutter/fml/platform/win/wstring_conversion.h" #include "flutter/shell/platform/common/client_wrapper/binary_messenger_impl.h" #include "flutter/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h" #include "flutter/shell/platform/common/json_message_codec.h" #include "flutter/shell/platform/common/path_utils.h" #include "flutter/shell/platform/windows/flutter_windows_view.h" -#include "flutter/shell/platform/windows/string_conversion.h" #include "flutter/shell/platform/windows/system_utils.h" #include "flutter/shell/platform/windows/task_runner.h" #include "third_party/rapidjson/include/rapidjson/document.h" @@ -448,7 +448,8 @@ void FlutterWindowsEngine::SendSystemSettings() { Prefer24HourTime(GetUserTimeFormat()), allocator); settings.AddMember("textScaleFactor", 1.0, allocator); settings.AddMember("platformBrightness", - Utf8FromUtf16(GetPreferredBrightness()), allocator); + fml::WideStringToUtf8(GetPreferredBrightness()), + allocator); settings_channel_->Send(settings); } diff --git a/shell/platform/windows/keyboard_key_embedder_handler.cc b/shell/platform/windows/keyboard_key_embedder_handler.cc index bc4632877e963..ca8e5a9cdadfd 100644 --- a/shell/platform/windows/keyboard_key_embedder_handler.cc +++ b/shell/platform/windows/keyboard_key_embedder_handler.cc @@ -8,12 +8,10 @@ #include #include -#include #include #include #include "flutter/shell/platform/windows/keyboard_win32_common.h" -#include "flutter/shell/platform/windows/string_conversion.h" namespace flutter { diff --git a/shell/platform/windows/platform_handler_win32.cc b/shell/platform/windows/platform_handler_win32.cc index 1985f85ed27b5..9e73e431ddbd1 100644 --- a/shell/platform/windows/platform_handler_win32.cc +++ b/shell/platform/windows/platform_handler_win32.cc @@ -10,8 +10,8 @@ #include #include +#include "flutter/fml/platform/win/wstring_conversion.h" #include "flutter/shell/platform/windows/flutter_windows_view.h" -#include "flutter/shell/platform/windows/string_conversion.h" static constexpr char kValueKey[] = "value"; @@ -227,7 +227,8 @@ void PlatformHandlerWin32::GetPlainText( rapidjson::Document::AllocatorType& allocator = document.GetAllocator(); document.AddMember( rapidjson::Value(key.data(), allocator), - rapidjson::Value(Utf8FromUtf16(*clipboard_string), allocator), allocator); + rapidjson::Value(fml::WideStringToUtf8(*clipboard_string), allocator), + allocator); result->Success(document); } @@ -259,7 +260,7 @@ void PlatformHandlerWin32::SetPlainText( result->Error(kClipboardError, "Unable to open clipboard", error_code); return; } - if (!clipboard.SetString(Utf16FromUtf8(text))) { + if (!clipboard.SetString(fml::Utf8ToWideString(text))) { rapidjson::Document error_code; error_code.SetInt(::GetLastError()); result->Error(kClipboardError, "Unable to set clipboard data", error_code); diff --git a/shell/platform/windows/platform_handler_winuwp.cc b/shell/platform/windows/platform_handler_winuwp.cc index f0bc19d0f1efe..3134727847fed 100644 --- a/shell/platform/windows/platform_handler_winuwp.cc +++ b/shell/platform/windows/platform_handler_winuwp.cc @@ -8,8 +8,8 @@ #include "third_party/cppwinrt/generated/winrt/Windows.Foundation.h" #include "third_party/cppwinrt/generated/winrt/Windows.UI.Core.h" +#include "flutter/fml/platform/win/wstring_conversion.h" #include "flutter/shell/platform/windows/flutter_windows_view.h" -#include "flutter/shell/platform/windows/string_conversion.h" static constexpr char kValueKey[] = "value"; @@ -61,19 +61,19 @@ void PlatformHandlerWinUwp::GetPlainText( // Waiting `DataPackageView::GetTextAsync()` using `TResult.get()` on the // platform thread will causes the application stop, so we continue // response on this callback. - content.GetTextAsync().Completed( - [result = std::move(result), key](auto async_info, auto _async_status) { - auto clipboard_string = async_info.GetResults(); - - rapidjson::Document document; - document.SetObject(); - rapidjson::Document::AllocatorType& allocator = document.GetAllocator(); - document.AddMember( - rapidjson::Value(key.data(), allocator), - rapidjson::Value(Utf8FromUtf16(clipboard_string), allocator), - allocator); - result->Success(document); - }); + content.GetTextAsync().Completed([result = std::move(result), key]( + auto async_info, auto _async_status) { + auto clipboard_string = async_info.GetResults(); + + rapidjson::Document document; + document.SetObject(); + rapidjson::Document::AllocatorType& allocator = document.GetAllocator(); + document.AddMember( + rapidjson::Value(key.data(), allocator), + rapidjson::Value(fml::WideStringToUtf8(clipboard_string), allocator), + allocator); + result->Success(document); + }); } void PlatformHandlerWinUwp::GetHasStrings( @@ -101,7 +101,7 @@ void PlatformHandlerWinUwp::SetPlainText( const std::string& text, std::unique_ptr> result) { winrt::Windows::ApplicationModel::DataTransfer::DataPackage content; - content.SetText(Utf16FromUtf8(text)); + content.SetText(fml::Utf8ToWideString(text)); winrt::Windows::ApplicationModel::DataTransfer::Clipboard::SetContent( content); diff --git a/shell/platform/windows/string_conversion.cc b/shell/platform/windows/string_conversion.cc deleted file mode 100644 index d3ab3143ea7f6..0000000000000 --- a/shell/platform/windows/string_conversion.cc +++ /dev/null @@ -1,55 +0,0 @@ -// 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/shell/platform/windows/string_conversion.h" - -#include - -namespace flutter { - -std::string Utf8FromUtf16(const std::wstring_view utf16_string) { - if (utf16_string.empty()) { - return std::string(); - } - int target_length = ::WideCharToMultiByte( - CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string.data(), - static_cast(utf16_string.length()), nullptr, 0, nullptr, nullptr); - if (target_length == 0) { - return std::string(); - } - std::string utf8_string; - utf8_string.resize(target_length); - int converted_length = ::WideCharToMultiByte( - CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string.data(), - static_cast(utf16_string.length()), utf8_string.data(), - target_length, nullptr, nullptr); - if (converted_length == 0) { - return std::string(); - } - return utf8_string; -} - -std::wstring Utf16FromUtf8(const std::string_view utf8_string) { - if (utf8_string.empty()) { - return std::wstring(); - } - int target_length = - ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, utf8_string.data(), - static_cast(utf8_string.length()), nullptr, 0); - if (target_length == 0) { - return std::wstring(); - } - std::wstring utf16_string; - utf16_string.resize(target_length); - int converted_length = - ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, utf8_string.data(), - static_cast(utf8_string.length()), - utf16_string.data(), target_length); - if (converted_length == 0) { - return std::wstring(); - } - return utf16_string; -} - -} // namespace flutter diff --git a/shell/platform/windows/string_conversion.h b/shell/platform/windows/string_conversion.h deleted file mode 100644 index b79aed4711072..0000000000000 --- a/shell/platform/windows/string_conversion.h +++ /dev/null @@ -1,22 +0,0 @@ -// 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_SHELL_PLATFORM_WINDOWS_STRING_CONVERSION_H_ -#define FLUTTER_SHELL_PLATFORM_WINDOWS_STRING_CONVERSION_H_ - -#include - -namespace flutter { - -// Converts a string from UTF-16 to UTF-8. Returns an empty string if the -// input is not valid UTF-16. -std::string Utf8FromUtf16(const std::wstring_view utf16_string); - -// Converts a string from UTF-8 to UTF-16. Returns an empty string if the -// input is not valid UTF-8. -std::wstring Utf16FromUtf8(const std::string_view utf8_string); - -} // namespace flutter - -#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_STRING_CONVERSION_H_ diff --git a/shell/platform/windows/string_conversion_unittests.cc b/shell/platform/windows/string_conversion_unittests.cc deleted file mode 100644 index aa8dc967f3c81..0000000000000 --- a/shell/platform/windows/string_conversion_unittests.cc +++ /dev/null @@ -1,37 +0,0 @@ -// 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/shell/platform/windows/string_conversion.h" - -#include "gtest/gtest.h" - -namespace flutter { -namespace testing { - -TEST(StringConversion, Utf16FromUtf8Empty) { - EXPECT_EQ(Utf16FromUtf8(""), L""); -} - -TEST(StringConversion, Utf16FromUtf8Ascii) { - EXPECT_EQ(Utf16FromUtf8("abc123"), L"abc123"); -} - -TEST(StringConversion, Utf16FromUtf8Unicode) { - EXPECT_EQ(Utf16FromUtf8("\xe2\x98\x83"), L"\x2603"); -} - -TEST(StringConversion, Utf8FromUtf16Empty) { - EXPECT_EQ(Utf8FromUtf16(L""), ""); -} - -TEST(StringConversion, Utf8FromUtf16Ascii) { - EXPECT_EQ(Utf8FromUtf16(L"abc123"), "abc123"); -} - -TEST(StringConversion, Utf8FromUtf16Unicode) { - EXPECT_EQ(Utf8FromUtf16(L"\x2603"), "\xe2\x98\x83"); -} - -} // namespace testing -} // namespace flutter diff --git a/shell/platform/windows/system_utils_win32.cc b/shell/platform/windows/system_utils_win32.cc index 23147296c1604..7df7794477817 100644 --- a/shell/platform/windows/system_utils_win32.cc +++ b/shell/platform/windows/system_utils_win32.cc @@ -8,7 +8,7 @@ #include -#include "flutter/shell/platform/windows/string_conversion.h" +#include "flutter/fml/platform/win/wstring_conversion.h" namespace flutter { @@ -65,7 +65,7 @@ LanguageInfo ParseLanguageName(std::wstring language_name) { // Split by '-', discarding any suplemental language info (-x-foo). std::vector components; - std::istringstream stream(Utf8FromUtf16(language_name)); + std::istringstream stream(fml::WideStringToUtf8(language_name)); std::string component; while (getline(stream, component, '-')) { if (component == "x") { diff --git a/shell/platform/windows/system_utils_winuwp.cc b/shell/platform/windows/system_utils_winuwp.cc index cdee09e30f506..698fb1e70abe0 100644 --- a/shell/platform/windows/system_utils_winuwp.cc +++ b/shell/platform/windows/system_utils_winuwp.cc @@ -13,7 +13,7 @@ #include "third_party/cppwinrt/generated/winrt/Windows.UI.ViewManagement.h" #include "third_party/cppwinrt/generated/winrt/Windows.UI.h" -#include "flutter/shell/platform/windows/string_conversion.h" +#include "flutter/fml/platform/win/wstring_conversion.h" namespace flutter { @@ -41,7 +41,7 @@ LanguageInfo ParseLanguageName(std::wstring language_name) { // Split by '-', discarding any suplemental language info (-x-foo). std::vector components; - std::istringstream stream(Utf8FromUtf16(language_name)); + std::istringstream stream(fml::WideStringToUtf8(language_name)); std::string component; while (getline(stream, component, '-')) { if (component == "x") { diff --git a/shell/platform/windows/uwptool_commands.cc b/shell/platform/windows/uwptool_commands.cc index b524a398f37e1..1a8f5605262ca 100644 --- a/shell/platform/windows/uwptool_commands.cc +++ b/shell/platform/windows/uwptool_commands.cc @@ -3,7 +3,7 @@ #include #include -#include "flutter/shell/platform/windows/string_conversion.h" +#include "flutter/fml/platform/win/wstring_conversion.h" #include "flutter/shell/platform/windows/uwptool_utils.h" namespace flutter { @@ -25,10 +25,10 @@ bool InstallCommand::ValidateArgs(const std::vector& args) const { } int InstallCommand::Run(const std::vector& args) const { - std::wstring package_uri = flutter::Utf16FromUtf8(args[0]); + std::wstring package_uri = fml::Utf8ToWideString(args[0]); std::vector dependency_uris; for (int i = 1; i < args.size(); ++i) { - dependency_uris.push_back(flutter::Utf16FromUtf8(args[i])); + dependency_uris.push_back(fml::Utf8ToWideString(args[i])); } flutter::ApplicationStore app_store; if (app_store.Install(package_uri, dependency_uris)) { @@ -45,7 +45,7 @@ bool UninstallCommand::ValidateArgs( int UninstallCommand::Run(const std::vector& args) const { flutter::ApplicationStore app_store; - std::wstring package_family = flutter::Utf16FromUtf8(args[0]); + std::wstring package_family = fml::Utf8ToWideString(args[0]); return app_store.Uninstall(package_family) ? 0 : 1; } @@ -66,8 +66,8 @@ int LaunchCommand::Run(const std::vector& args) const { } } flutter::ApplicationStore app_store; - int process_id = app_store.Launch(flutter::Utf16FromUtf8(package_family), - flutter::Utf16FromUtf8(app_args.str())); + int process_id = app_store.Launch(fml::Utf8ToWideString(package_family), + fml::Utf8ToWideString(app_args.str())); if (process_id == -1) { std::cerr << "error: Failed to launch app with package family " << package_family << " arguments [" << app_args.str() << "]"