util.h: Add Win32 Unicode string conversion functions.
These will be used more extensively in future CLs
and make for cleaner code.
Fuchsia-Topic: advanced-ipc
Original-Change-Id: Iba0ff0f6a534df373ba9720c45ecce905391c904
Change-Id: I49ac43b384e993aa214ef07234dbbfc9060c0f81
Reviewed-on: https://fuchsia-review.googlesource.com/c/third_party/github.com/ninja-build/ninja/+/975453
Reviewed-by: David Fang <fangism@google.com>
Reviewed-by: Tyler Mandry <tmandry@google.com>
Commit-Queue: David Turner <digit@google.com>
diff --git a/src/ipc_handle-win32.cc b/src/ipc_handle-win32.cc
index 0da7956..2922eb1 100644
--- a/src/ipc_handle-win32.cc
+++ b/src/ipc_handle-win32.cc
@@ -35,16 +35,6 @@
return Win32ErrorMessage(prefix, GetLastError());
}
-std::wstring Utf8ToWideChar(StringPiece str) {
- std::wstring result;
- int count = MultiByteToWideChar(CP_UTF8, 0, str.str_, str.len_, nullptr, 0);
- if (count > 0) {
- result.resize(count);
- MultiByteToWideChar(CP_UTF8, 0, str.str_, str.len_, &result[0], count);
- }
- return result;
-}
-
std::wstring CurrentUserName() {
wchar_t user[UNLEN + 1];
DWORD count = UNLEN + 1;
@@ -59,7 +49,7 @@
std::wstring result = L"\\\\.\\pipe\\basic_ipc-";
result += CurrentUserName();
result += L'-';
- result += Utf8ToWideChar(service_name);
+ result += ConvertToUnicodeString(service_name.str_, service_name.len_);
return result;
}
diff --git a/src/util.cc b/src/util.cc
index 644413e..f551810 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -186,6 +186,53 @@
Fatal("Could not format string!");
}
+#ifdef _WIN32
+std::wstring ConvertToUnicodeString(const char* str, size_t size) {
+ std::wstring result;
+ if (size > 0) {
+ int int_size = static_cast<int>(size);
+ if (int_size != size)
+ Fatal("Input UTF-8 string is far too long!");
+
+ int wide_size = MultiByteToWideChar(CP_UTF8, 0, str, int_size, nullptr, 0);
+ if (wide_size <= 0)
+ Win32Fatal("MultiByteToWideChar");
+
+ result.resize(static_cast<size_t>(wide_size));
+ MultiByteToWideChar(CP_UTF8, 0, str, int_size, &result[0], wide_size);
+ }
+ return result;
+}
+
+std::wstring ConvertToUnicodeString(const std::string& str) {
+ return ConvertToUnicodeString(str.c_str(), str.size());
+}
+
+std::string ConvertFromUnicodeString(const wchar_t* str, size_t size) {
+ std::string result;
+ if (size > 0) {
+ int int_size = static_cast<int>(size);
+ if (int_size != size)
+ Fatal("Input Unicode string is far too long!");
+
+ int utf8_size =
+ WideCharToMultiByte(CP_UTF8, 0, str, int_size, NULL, 0, NULL, NULL);
+ if (utf8_size <= 0)
+ Win32Fatal("WideCharToMultiByte");
+
+ result.resize(static_cast<size_t>(utf8_size));
+ WideCharToMultiByte(CP_UTF8, 0, str, int_size, &result[0], utf8_size, NULL,
+ NULL);
+ }
+ return result;
+}
+
+std::string ConvertFromUnicodeString(const std::wstring& str) {
+ return ConvertFromUnicodeString(str.c_str(), str.size());
+}
+
+#endif // _WIN32
+
void CanonicalizePath(string* path, uint64_t* slash_bits) {
size_t len = path->size();
char* str = 0;
@@ -674,7 +721,7 @@
filename.resize(static_cast<size_t>(ret));
break;
}
- return ToUtf8Path(filename);
+ return ConvertFromUnicodeString(filename);
#elif defined(__APPLE__)
uint32_t size = 0;
_NSGetExecutablePath(nullptr, &size);
diff --git a/src/util.h b/src/util.h
index d9c6cf8..c8c5fdb 100644
--- a/src/util.h
+++ b/src/util.h
@@ -149,6 +149,15 @@
NORETURN void Win32Fatal(const char* function, const char* hint = NULL);
NORETURN void Win32Fatal(const char* function, unsigned long error,
const char* hint = NULL);
+
+/// Convert Win32 unicode string into UTF8 string.
+std::string ConvertFromUnicodeString(const wchar_t* str, size_t size);
+std::string ConvertFromUnicodeString(const std::wstring& str);
+
+/// Convert UTF8 string to a Win32 unicode string.
+std::wstring ConvertToUnicodeString(const char* str, size_t size);
+std::wstring ConvertToUnicodeString(const std::string& str);
+
#endif // !_WIN32
NORETURN void ErrnoFatal(const char* function, const char* hint = NULL);
diff --git a/src/util_test.cc b/src/util_test.cc
index 2e39e2f..0e21123 100644
--- a/src/util_test.cc
+++ b/src/util_test.cc
@@ -641,3 +641,14 @@
#endif
ASSERT_EQ(expected, IsRunningUnderWine());
}
+
+#ifdef _WIN32
+TEST(ConvertToUnicodeString, Test) {
+ EXPECT_EQ(std::wstring(L"Bébé"), ConvertToUnicodeString("Bébé"));
+}
+
+TEST(ConvertFromUnicodeString, Test) {
+ EXPECT_EQ(std::string("Bébé"), ConvertFromUnicodeString(L"Bébé"));
+}
+
+#endif // _WIN32