mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 22:56:12 -04:00
Update wstring converter
PiperOrigin-RevId: 682112846
This commit is contained in:
committed by
Copybara-Service
parent
ab00092c6c
commit
25d4aca219
@@ -41,7 +41,9 @@ cc_library(
|
||||
"utils.h",
|
||||
],
|
||||
defines = ["_SILENCE_CLANG_COROUTINE_MESSAGE"],
|
||||
visibility = ["//sharing/internal/impl/windows:__pkg__"],
|
||||
visibility = [
|
||||
"//sharing/internal/impl/windows:__pkg__",
|
||||
],
|
||||
deps = [
|
||||
":comm",
|
||||
"//internal/base:bluetooth_address",
|
||||
@@ -143,6 +145,26 @@ cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "string_utils",
|
||||
srcs = [
|
||||
"string_utils.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"string_utils.h",
|
||||
],
|
||||
compatible_with = ["//buildenv/target:non_prod"],
|
||||
visibility = [
|
||||
"//internal/platform:__subpackages__",
|
||||
"//location/nearby:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
"//internal/platform:logging",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/strings:str_format",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "windows",
|
||||
srcs = [
|
||||
@@ -209,6 +231,7 @@ cc_library(
|
||||
deps = [
|
||||
":comm",
|
||||
":crypto", # build_cleaner: keep
|
||||
":string_utils",
|
||||
":types",
|
||||
"//connections/implementation/flags:connections_flags",
|
||||
"//internal/account",
|
||||
@@ -313,3 +336,17 @@ cc_test(
|
||||
"@nlohmann_json//:json",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "string_utils_test",
|
||||
size = "small",
|
||||
timeout = "short",
|
||||
srcs = [
|
||||
"string_utils_test.cc",
|
||||
],
|
||||
deps = [
|
||||
":string_utils",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/implementation/windows/utils.h"
|
||||
#include "internal/platform/implementation/windows/string_utils.h"
|
||||
#include "internal/platform/logging.h"
|
||||
|
||||
namespace nearby {
|
||||
@@ -38,7 +38,8 @@ std::unique_ptr<IOFile> IOFile::CreateInputFile(absl::string_view file_path,
|
||||
|
||||
IOFile::IOFile(absl::string_view file_path, size_t size) : path_(file_path) {
|
||||
// Always open input file path as wide string on Windows platform.
|
||||
std::wstring wide_path = string_to_wstring(std::string(file_path));
|
||||
std::wstring wide_path = string_utils::StringToWideString(
|
||||
std::string(file_path));
|
||||
file_.open(wide_path, std::ios::binary | std::ios::in | std::ios::ate);
|
||||
|
||||
total_size_ = file_.tellg();
|
||||
@@ -59,7 +60,8 @@ std::unique_ptr<IOFile> IOFile::CreateOutputFile(absl::string_view path) {
|
||||
IOFile::IOFile(absl::string_view file_path)
|
||||
: file_(), path_(file_path), total_size_(0) {
|
||||
// Always open input file path as wide string on Windows platform.
|
||||
std::wstring wide_path = string_to_wstring(path_);
|
||||
std::wstring wide_path =
|
||||
string_utils::StringToWideString(path_);
|
||||
file_.open(wide_path, std::ios::binary | std::ios::out);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "absl/types/span.h"
|
||||
#include "connections/implementation/flags/nearby_connections_feature_flags.h"
|
||||
#include "internal/flags/nearby_flags.h"
|
||||
#include "internal/platform/implementation/windows/string_utils.h"
|
||||
#include "internal/platform/implementation/windows/utils.h"
|
||||
#include "internal/platform/logging.h"
|
||||
|
||||
@@ -177,8 +178,8 @@ std::wstring FilePath::CreateOutputFileWithRename(std::wstring path) {
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
LOG(INFO) << "Renamed " << wstring_to_string(path) << " to "
|
||||
<< wstring_to_string(target);
|
||||
LOG(INFO) << "Renamed " << string_utils::WideStringToString(path) << " to "
|
||||
<< string_utils::WideStringToString(target);
|
||||
}
|
||||
|
||||
// The above leaves the file open, so close it.
|
||||
@@ -216,8 +217,9 @@ std::wstring FilePath::MutateForbiddenPathElements(std::wstring& str) {
|
||||
if (tmp_path_element.size() == 1 && tmp_path_element[0] == kDot) {
|
||||
// Change the dot path name to an underscore.
|
||||
tmp_path_element[0] = kReplacementChar;
|
||||
LOG(INFO) << "Renamed path element " << wstring_to_string(path_element)
|
||||
<< " to " << wstring_to_string(tmp_path_element);
|
||||
LOG(INFO) << "Renamed path element "
|
||||
<< string_utils::WideStringToString(path_element) << " to "
|
||||
<< string_utils::WideStringToString(tmp_path_element);
|
||||
path_element[0] = kReplacementChar;
|
||||
}
|
||||
|
||||
@@ -228,8 +230,9 @@ std::wstring FilePath::MutateForbiddenPathElements(std::wstring& str) {
|
||||
while (std::find(forbidden.begin(), forbidden.end(), tmp_path_element) !=
|
||||
forbidden.end()) {
|
||||
tmp_path_element.insert(tmp_path_element.begin(), kReplacementChar);
|
||||
LOG(INFO) << "Renamed path element " << wstring_to_string(path_element)
|
||||
<< " to " << wstring_to_string(tmp_path_element);
|
||||
LOG(INFO) << "Renamed path element "
|
||||
<< string_utils::WideStringToString(path_element) << " to "
|
||||
<< string_utils::WideStringToString(tmp_path_element);
|
||||
path_element.insert(path_element.begin(), kReplacementChar);
|
||||
}
|
||||
|
||||
@@ -263,21 +266,21 @@ void FilePath::ReplaceInvalidCharacters(std::wstring& path) {
|
||||
for (; it != path.end(); it++) {
|
||||
// If 0 < character < 32, it's illegal, replace it
|
||||
if (*it > 0 && *it < 32) {
|
||||
LOG(INFO) << "In path " << wstring_to_string(path) << " replaced \'"
|
||||
<< std::string(1, *it) << "\' with \'"
|
||||
LOG(INFO) << "In path " << string_utils::WideStringToString(path)
|
||||
<< " replaced \'" << std::string(1, *it) << "\' with \'"
|
||||
<< std::string(1, kReplacementChar);
|
||||
*it = kReplacementChar;
|
||||
}
|
||||
if (*it == 0) { // character is null
|
||||
LOG(INFO) << "In path " << wstring_to_string(path)
|
||||
LOG(INFO) << "In path " << string_utils::WideStringToString(path)
|
||||
<< " replaced \'NULL\' with \'"
|
||||
<< std::string(1, kReplacementChar) << "\'";
|
||||
*it = kReplacementChar;
|
||||
}
|
||||
for (auto illegal_character : kIllegalFileCharacters) {
|
||||
if (*it == illegal_character) {
|
||||
LOG(INFO) << "In path " << wstring_to_string(path) << " replaced \'"
|
||||
<< std::string(1, *it) << "\' with \'"
|
||||
LOG(INFO) << "In path " << string_utils::WideStringToString(path)
|
||||
<< " replaced \'" << std::string(1, *it) << "\' with \'"
|
||||
<< std::string(1, kReplacementChar);
|
||||
*it = kReplacementChar;
|
||||
}
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
#include "internal/platform/implementation/windows/preferences_manager.h"
|
||||
#include "internal/platform/implementation/windows/scheduled_executor.h"
|
||||
#include "internal/platform/implementation/windows/server_sync.h"
|
||||
#include "internal/platform/implementation/windows/string_utils.h"
|
||||
#include "internal/platform/implementation/windows/submittable_executor.h"
|
||||
#include "internal/platform/implementation/windows/timer.h"
|
||||
#include "internal/platform/implementation/windows/utils.h"
|
||||
@@ -114,28 +115,28 @@ std::string GetApplicationName(DWORD pid) {
|
||||
|
||||
std::string ImplementationPlatform::GetCustomSavePath(
|
||||
const std::string& parent_folder, const std::string& file_name) {
|
||||
auto parent = windows::string_to_wstring(parent_folder);
|
||||
auto file = windows::string_to_wstring(file_name);
|
||||
auto parent = windows::string_utils::StringToWideString(parent_folder);
|
||||
auto file = windows::string_utils::StringToWideString(file_name);
|
||||
|
||||
return windows::wstring_to_string(
|
||||
return windows::string_utils::WideStringToString(
|
||||
windows::FilePath::GetCustomSavePath(parent, file));
|
||||
}
|
||||
|
||||
std::string ImplementationPlatform::GetDownloadPath(
|
||||
const std::string& parent_folder, const std::string& file_name) {
|
||||
auto parent = windows::string_to_wstring(std::string(parent_folder));
|
||||
auto file = windows::string_to_wstring(std::string(file_name));
|
||||
auto parent = windows::string_utils::StringToWideString(parent_folder);
|
||||
auto file = windows::string_utils::StringToWideString(file_name);
|
||||
|
||||
return windows::wstring_to_string(
|
||||
return windows::string_utils::WideStringToString(
|
||||
windows::FilePath::GetDownloadPath(parent, file));
|
||||
}
|
||||
|
||||
std::string ImplementationPlatform::GetDownloadPath(
|
||||
const std::string& file_name) {
|
||||
std::wstring fake_parent_path;
|
||||
auto file = windows::string_to_wstring(std::string(file_name));
|
||||
auto file = windows::string_utils::StringToWideString(file_name);
|
||||
|
||||
return windows::wstring_to_string(
|
||||
return windows::string_utils::WideStringToString(
|
||||
windows::FilePath::GetDownloadPath(fake_parent_path, file));
|
||||
}
|
||||
|
||||
@@ -229,8 +230,8 @@ std::unique_ptr<OutputFile> ImplementationPlatform::CreateOutputFile(
|
||||
const std::string& file_path) {
|
||||
std::string path(file_path);
|
||||
|
||||
auto folder_path =
|
||||
windows::string_to_wstring(path.substr(0, path.find_last_of('/')));
|
||||
auto folder_path = windows::string_utils::StringToWideString(
|
||||
path.substr(0, path.find_last_of('/')));
|
||||
// Verifies that a path is a valid directory.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-pathisdirectoryw
|
||||
if (!PathIsDirectoryW(folder_path.data())) {
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
// Copyright 2024 Google LLC
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// https://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 "internal/platform/implementation/windows/string_utils.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "internal/platform/logging.h"
|
||||
|
||||
namespace nearby::windows::string_utils {
|
||||
|
||||
// Converts std::string to wstring
|
||||
std::wstring StringToWideString(std::string str) {
|
||||
if (str.empty()) {
|
||||
return L"";
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-multibytetowidechar
|
||||
int output_length =
|
||||
MultiByteToWideChar(/*CodePage=*/CP_UTF8,
|
||||
/*dwFlags=*/0,
|
||||
/*lpMultiByteStr=*/str.c_str(),
|
||||
/*cbMultiByte=*/static_cast<int>(str.length()),
|
||||
/*lpWideCharStr=*/nullptr,
|
||||
/*cchWideChar=*/0);
|
||||
if (output_length == 0) {
|
||||
return L"";
|
||||
}
|
||||
std::wstring output(output_length, L'\0');
|
||||
int result = MultiByteToWideChar(
|
||||
/*CodePage=*/CP_UTF8, /*dwFlags=*/0, /*lpMultiByteStr=*/str.c_str(),
|
||||
/*cbMultiByte=*/static_cast<int>(str.length()),
|
||||
/*lpWideCharStr=*/&output[0],
|
||||
/*cchWideChar=*/output_length);
|
||||
if (result == 0) {
|
||||
LOG(INFO) << "Error converting String to Wstring. Error code: "
|
||||
<< GetLastError();
|
||||
return L"";
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
// Converts wstring to std::string
|
||||
std::string WideStringToString(std::wstring wstr) {
|
||||
if (wstr.empty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string output;
|
||||
size_t start = 0;
|
||||
size_t index = 0;
|
||||
|
||||
// Iterate over the wstring buffer, chop it into wchar chunks and convert them
|
||||
// one-by-one
|
||||
do {
|
||||
index = wstr.find(L'\0', start);
|
||||
if (index == std::wstring::npos) index = wstr.length();
|
||||
if (start <= wstr.length()) {
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-widechartomultibyte
|
||||
int size =
|
||||
WideCharToMultiByte(/*CodePage=*/CP_UTF8,
|
||||
/*dwFlags=*/WC_ERR_INVALID_CHARS,
|
||||
/*lpWideCharStr=*/&wstr[start],
|
||||
/*cchWideChar=*/static_cast<int>(index - start),
|
||||
/*lpMultiByteStr=*/nullptr,
|
||||
/*cbMultiByte=*/0,
|
||||
/*lpDefaultChar=*/nullptr,
|
||||
/*lpUsedDefaultChar=*/nullptr);
|
||||
if (size == 0) {
|
||||
return "";
|
||||
}
|
||||
std::string converted_chunk = std::string(size, '\0');
|
||||
int result = WideCharToMultiByte(
|
||||
/*CodePage=*/CP_UTF8, /*dwFlags=*/WC_ERR_INVALID_CHARS,
|
||||
/*lpWideCharStr=*/&wstr[start],
|
||||
/*cchWideChar=*/static_cast<int>(index - start),
|
||||
/*lpMultiByteStr=*/&converted_chunk[0],
|
||||
/*cbMultiByte=*/static_cast<int>(converted_chunk.size()),
|
||||
/*lpDefaultChar=*/nullptr,
|
||||
/*lpUsedDefaultChar=*/nullptr);
|
||||
if (result == 0) {
|
||||
LOG(INFO) << "Error converting Wstring to String. Error code: "
|
||||
<< GetLastError();
|
||||
return "";
|
||||
}
|
||||
output.append(converted_chunk);
|
||||
// Append '\0' to handle the case of {wstring \0 wstring \0 wstring} ->
|
||||
// {string \0 string \0 string}
|
||||
if (index < wstr.length()) {
|
||||
LOG(INFO) << "Appending a null byte to string";
|
||||
output.append(1, '\0');
|
||||
}
|
||||
}
|
||||
start = index + 1;
|
||||
} while (index != std::wstring::npos && start < wstr.length());
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
} // namespace nearby::windows::string_utils
|
||||
@@ -0,0 +1,29 @@
|
||||
// Copyright 2024 Google LLC
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// https://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.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_WINDOWS_STRING_UTILS_H_
|
||||
#define THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_WINDOWS_STRING_UTILS_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace nearby::windows::string_utils {
|
||||
|
||||
// Converts UTF-8 encoded string to wstring
|
||||
std::wstring StringToWideString(std::string str);
|
||||
// Converts wstring to UTF-8 encoded string
|
||||
std::string WideStringToString(std::wstring wstr);
|
||||
|
||||
} // namespace nearby::windows::string_utils
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_WINDOWS_STRING_UTILS_H_
|
||||
@@ -0,0 +1,190 @@
|
||||
// Copyright 2024 Google LLC
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// https://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 "internal/platform/implementation/windows/string_utils.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace nearby::windows::string_utils {
|
||||
|
||||
const wchar_t* const kConvertRoundtripCasesWide[] = {
|
||||
L"Hello World!",
|
||||
L"Quick Share for Windows",
|
||||
// "附近分享 蓝牙 无线传送 »"
|
||||
L"\x9644\x8fd1\x5206\x4eab\x0020\x84dd\x7259\x0020\x65e0\x7ebf\x4f20\x9001"
|
||||
L"\x0020\x00bb",
|
||||
// "近隣のシェア"
|
||||
L"\x8fd1\x96a3\x306e\x30b7\x30a7\x30a2",
|
||||
// "주변 공유"
|
||||
L"\xc8fc\xbcc0\x0020\xacf5\xc720",
|
||||
// "आस-पास साझा करें"
|
||||
L"\x0906\x0938\x002d\x092a\x093e\x0938\x0020\x0938\x093e\x091d\x093e\x0020"
|
||||
L"\x0915\x0930\x0947\x0902",
|
||||
// "அருகிலுள்ள பகிர்வு"
|
||||
L"\x0b85\x0bb0\x0bc1\x0b95\x0bbf\x0bb2\x0bc1\x0bb3\x0bcd\x0bb3\x0020\x0baa"
|
||||
L"\x0b95\x0bbf\x0bb0\x0bcd\x0bb5\x0bc1",
|
||||
};
|
||||
|
||||
const wchar_t* const kWideStringWithNull[] = {
|
||||
L"A" L"\0" L"B" L"\0" L"C",
|
||||
L"Hello World!"
|
||||
L"\0"
|
||||
L"Quick Share for Windows"
|
||||
L"\0"
|
||||
// "附近分享 蓝牙 无线传送 »"
|
||||
L"\x9644\x8fd1\x5206\x4eab\x0020\x84dd\x7259\x0020\x65e0\x7ebf\x4f20\x9001"
|
||||
L"\x0020\x00bb",
|
||||
};
|
||||
|
||||
const wchar_t* const kSymbolsWideString[] = {
|
||||
// ????? (Mathematical Alphanumeric Symbols (U+011d40 - U+011d44 :
|
||||
// A,B,C,D,E)
|
||||
L"\xd807\xdd40\xd807\xdd41\xd807\xdd42\xd807\xdd43\xd807\xdd44",
|
||||
};
|
||||
|
||||
const char* const kConvertRoundtripCases[] = {
|
||||
"Hello World!",
|
||||
"Quick Share for Windows",
|
||||
"附近分享 蓝牙 无线传送 »",
|
||||
"近隣のシェア",
|
||||
"주변 공유",
|
||||
"आस-पास साझा करें",
|
||||
"அருகிலுள்ள பகிர்வு",
|
||||
};
|
||||
|
||||
const char* const kStringWithNull[] = {
|
||||
"A" "\0" "B" "\0" "C",
|
||||
"Hello World!"
|
||||
"\0"
|
||||
"Quick Share for Windows"
|
||||
"\0"
|
||||
"附近分享 蓝牙 无线传送 »",
|
||||
};
|
||||
|
||||
const char* const kStringWithoutNull[] = {
|
||||
"ABC",
|
||||
"Hello World!"
|
||||
"Quick Share for Windows"
|
||||
"附近分享 蓝牙 无线传送 »",
|
||||
};
|
||||
|
||||
const char* const kIllegalString[] = {
|
||||
"©pj·Å", // base64 decoded string of "malware.exe"
|
||||
};
|
||||
|
||||
TEST(StringUtilsTests, ConvertWideStringToString) {
|
||||
int count = sizeof(kConvertRoundtripCasesWide) /
|
||||
sizeof(kConvertRoundtripCasesWide[0]);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
std::ostringstream utf8;
|
||||
utf8 << WideStringToString(kConvertRoundtripCasesWide[i]);
|
||||
EXPECT_EQ(utf8.str(), kConvertRoundtripCases[i]);
|
||||
}
|
||||
|
||||
count = sizeof(kWideStringWithNull) /
|
||||
sizeof(kWideStringWithNull[0]);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
std::ostringstream utf8;
|
||||
utf8 << WideStringToString(kWideStringWithNull[i]);
|
||||
EXPECT_EQ(utf8.str(), kStringWithNull[i]);
|
||||
EXPECT_NE(utf8.str(), kStringWithoutNull[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(StringUtilsTests, ConvertWideStringToStringRoundTrip) {
|
||||
// we round-trip all the wide strings through UTF-8 to make sure everything
|
||||
// agrees on the conversion. This uses the stream operators to test them
|
||||
// simultaneously.
|
||||
for (auto* i : kConvertRoundtripCasesWide) {
|
||||
std::ostringstream utf8;
|
||||
utf8 << WideStringToString(i);
|
||||
std::wostringstream wide;
|
||||
wide << StringToWideString(utf8.str());
|
||||
|
||||
EXPECT_EQ(i, wide.str());
|
||||
}
|
||||
|
||||
for (auto* i : kSymbolsWideString) {
|
||||
std::ostringstream utf8;
|
||||
utf8 << WideStringToString(i);
|
||||
std::wostringstream wide;
|
||||
wide << StringToWideString(utf8.str());
|
||||
|
||||
EXPECT_EQ(i, wide.str());
|
||||
}
|
||||
|
||||
for (auto* i : kWideStringWithNull) {
|
||||
std::ostringstream utf8;
|
||||
utf8 << WideStringToString(i);
|
||||
std::wostringstream wide;
|
||||
wide << StringToWideString(utf8.str());
|
||||
|
||||
EXPECT_EQ(i, wide.str());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(StringUtilsTests, ConvertStringToWideString) {
|
||||
int count = sizeof(kConvertRoundtripCasesWide) /
|
||||
sizeof(kConvertRoundtripCasesWide[0]);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
std::wostringstream wide;
|
||||
wide << StringToWideString(kConvertRoundtripCases[i]);
|
||||
EXPECT_EQ(wide.str(), kConvertRoundtripCasesWide[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(StringUtilsTests, ConvertStringToWideStringRoundTrip) {
|
||||
// we round-trip all the wide strings through UTF-8 to make sure everything
|
||||
// agrees on the conversion. This uses the stream operators to test them
|
||||
// simultaneously.
|
||||
for (auto* i : kConvertRoundtripCases) {
|
||||
std::wostringstream wide;
|
||||
wide << StringToWideString(i);
|
||||
std::ostringstream utf8;
|
||||
utf8 << WideStringToString(wide.str());
|
||||
|
||||
EXPECT_EQ(i, utf8.str());
|
||||
}
|
||||
|
||||
for (auto* i : kIllegalString) {
|
||||
std::wostringstream wide;
|
||||
wide << StringToWideString(i);
|
||||
std::ostringstream utf8;
|
||||
utf8 << WideStringToString(wide.str());
|
||||
|
||||
EXPECT_EQ(i, utf8.str());
|
||||
}
|
||||
|
||||
for (auto* i : kStringWithNull) {
|
||||
std::wostringstream wide;
|
||||
wide << StringToWideString(i);
|
||||
std::ostringstream utf8;
|
||||
utf8 << WideStringToString(wide.str());
|
||||
|
||||
EXPECT_EQ(i, utf8.str());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(StringUtilsTests, ConvertEmptyStringAndWideString) {
|
||||
// An empty std::wstring should be converted to an empty std::string,
|
||||
// and vice versa.
|
||||
std::wstring wide_empty;
|
||||
std::string empty;
|
||||
EXPECT_EQ(empty, WideStringToString(wide_empty));
|
||||
EXPECT_EQ(wide_empty, StringToWideString(empty));
|
||||
}
|
||||
|
||||
} // namespace nearby::windows::string_utils
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020 Google LLC
|
||||
// Copyright 2020-2024 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "internal/platform/bluetooth_utils.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/implementation/crypto.h"
|
||||
#include "internal/platform/implementation/windows/string_utils.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/uuid.h"
|
||||
#include "winrt/Windows.Foundation.Collections.h"
|
||||
@@ -106,16 +107,6 @@ std::string ipaddr_dotdecimal_to_4bytes_string(std::string ipv4_s) {
|
||||
return std::string(ipv4_b, 4);
|
||||
}
|
||||
|
||||
std::wstring string_to_wstring(std::string str) {
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
||||
return converter.from_bytes(str);
|
||||
}
|
||||
|
||||
std::string wstring_to_string(std::wstring wstr) {
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
||||
return converter.to_bytes(wstr);
|
||||
}
|
||||
|
||||
std::vector<std::string> GetIpv4Addresses() {
|
||||
std::vector<std::string> result;
|
||||
std::vector<std::string> wifi_addresses;
|
||||
@@ -298,7 +289,8 @@ std::string InspectableReader::ReadString(IInspectable inspectable) {
|
||||
throw std::invalid_argument("not string data type.");
|
||||
}
|
||||
|
||||
return wstring_to_string(property_value.GetString().c_str());
|
||||
return nearby::windows::string_utils::WideStringToString(
|
||||
property_value.GetString().c_str());
|
||||
}
|
||||
|
||||
std::vector<std::string> InspectableReader::ReadStringArray(
|
||||
|
||||
@@ -39,8 +39,6 @@ std::string ipaddr_4bytes_to_dotdecimal_string(absl::string_view ipaddr_4bytes);
|
||||
std::string ipaddr_dotdecimal_to_4bytes_string(std::string ipv4_s);
|
||||
|
||||
// Helpers to windows platform
|
||||
std::wstring string_to_wstring(std::string str);
|
||||
std::string wstring_to_string(std::wstring wstr);
|
||||
ByteArray Sha256(absl::string_view input, size_t size);
|
||||
|
||||
// Reads the IPv4 addresses
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "internal/platform/cancellation_flag_listener.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/feature_flags.h"
|
||||
#include "internal/platform/implementation/windows/string_utils.h"
|
||||
#include "internal/platform/implementation/windows/utils.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/nsd_service_info.h"
|
||||
@@ -120,7 +121,7 @@ bool WifiLanMedium::StartAdvertising(const NsdServiceInfo& nsd_service_info) {
|
||||
LOG(INFO) << "mDNS instance name is " << instance_name;
|
||||
|
||||
dnssd_service_instance_ = DnssdServiceInstance{
|
||||
string_to_wstring(instance_name),
|
||||
string_utils::StringToWideString(instance_name),
|
||||
nullptr, // let windows use default computer's local name
|
||||
(uint16)nsd_service_info.GetPort()};
|
||||
|
||||
@@ -131,8 +132,8 @@ bool WifiLanMedium::StartAdvertising(const NsdServiceInfo& nsd_service_info) {
|
||||
nsd_service_info.GetTxtRecords();
|
||||
auto it = text_records.begin();
|
||||
while (it != text_records.end()) {
|
||||
text_attributes.Insert(string_to_wstring(it->first),
|
||||
string_to_wstring(it->second));
|
||||
text_attributes.Insert(string_utils::StringToWideString(it->first),
|
||||
string_utils::StringToWideString(it->second));
|
||||
it++;
|
||||
}
|
||||
|
||||
@@ -205,8 +206,8 @@ bool WifiLanMedium::StopAdvertising(const NsdServiceInfo& nsd_service_info) {
|
||||
kMdnsInstanceNameFormat.data(), nsd_service_info.GetServiceName(),
|
||||
nsd_service_info.GetServiceType());
|
||||
int port = nsd_service_info.GetPort();
|
||||
dns_service_instance_name_ =
|
||||
std::make_unique<std::wstring>(string_to_wstring(instance_name));
|
||||
dns_service_instance_name_ = std::make_unique<std::wstring>(
|
||||
string_utils::StringToWideString(instance_name));
|
||||
|
||||
dns_service_instance_.pszInstanceName =
|
||||
(LPWSTR)dns_service_instance_name_->c_str();
|
||||
@@ -278,7 +279,7 @@ bool WifiLanMedium::StartDiscovery(const std::string& service_type,
|
||||
L"System.Devices.Dnssd.TextAttributes"};
|
||||
|
||||
device_watcher_ = DeviceInformation::CreateWatcher(
|
||||
string_to_wstring(selector), requestedProperties,
|
||||
string_utils::StringToWideString(selector), requestedProperties,
|
||||
DeviceInformationKind::AssociationEndpointService);
|
||||
|
||||
device_watcher_added_event_token =
|
||||
@@ -351,7 +352,8 @@ std::unique_ptr<api::WifiLanSocket> WifiLanMedium::ConnectToService(
|
||||
std::unique_ptr<CancellationFlagListener> connection_cancellation_listener =
|
||||
nullptr;
|
||||
|
||||
HostName host_name{string_to_wstring(std::string(ipv4_address))};
|
||||
HostName host_name{
|
||||
string_utils::StringToWideString(std::string(ipv4_address))};
|
||||
winrt::hstring service_name{winrt::to_hstring(port)};
|
||||
|
||||
StreamSocket socket{};
|
||||
|
||||
Reference in New Issue
Block a user