diff --git a/src/common/platform/unicode.hpp b/src/common/platform/unicode.hpp index ec20ba66..3171b9fa 100644 --- a/src/common/platform/unicode.hpp +++ b/src/common/platform/unicode.hpp @@ -25,4 +25,40 @@ inline std::string u16_to_u8(std::u16string_view u16_view) { } } return utf8_str; -} \ No newline at end of file +} + +inline std::string w_to_u8(std::wstring_view w_view) { + std::string utf8_str; + utf8_str.reserve(w_view.size() * 2); + for (char16_t ch : w_view) { + if (ch <= 0x7F) { + utf8_str.push_back(static_cast(ch)); + } else if (ch <= 0x7FF) { + utf8_str.push_back(static_cast(0xC0 | (ch >> 6))); + utf8_str.push_back(static_cast(0x80 | (ch & 0x3F))); + } else { + utf8_str.push_back(static_cast(0xE0 | (ch >> 12))); + utf8_str.push_back(static_cast(0x80 | ((ch >> 6) & 0x3F))); + utf8_str.push_back(static_cast(0x80 | (ch & 0x3F))); + } + } + return utf8_str; +} + +#ifndef OS_WINDOWS + inline int open_unicode(FILE** handle, std::u16string fileName, std::u16string mode) + { + *handle = fopen(u16_to_u8(fileName).c_str(), u16_to_u8(mode).c_str()); + return errno; + } +#else + inline std::wstring u16_to_w(const std::u16string& u16str) { + return std::wstring(reinterpret_cast(u16str.data()), u16str.size()); + } + + inline auto open_unicode(FILE** handle, std::u16string fileName, std::u16string mode) + { + return _wfopen_s(handle, u16_to_w(fileName).c_str(), u16_to_w(mode).c_str()); + } +#endif + diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index 59d5dcaa..c43ec421 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -2158,9 +2158,8 @@ namespace } FILE* file{}; - // TODO: fix unicode conversion - //const auto error = _wfopen_s(&file, f.name.c_str(), mode); - const auto error = EACCES; + + const auto error = open_unicode(&file, f.name.c_str(), mode.c_str()); if (!file) {