Files
windows-user-space-emulator/src/common/platform/unicode.hpp
2025-02-08 14:07:51 +01:00

87 lines
2.4 KiB
C++

#pragma once
#include <string>
#include <filesystem>
template <typename Traits>
struct UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
EMULATOR_CAST(typename Traits::PVOID, char16_t*) Buffer;
};
inline std::u16string u8_to_u16(const std::string_view view)
{
return std::u16string(view.begin(), view.end());
}
inline std::string u16_to_u8(const std::u16string_view u16_view)
{
std::string utf8_str;
utf8_str.reserve(u16_view.size() * 2);
for (const char16_t ch : u16_view)
{
if (ch <= 0x7F)
{
utf8_str.push_back(static_cast<char>(ch));
}
else if (ch <= 0x7FF)
{
utf8_str.push_back(static_cast<char>(0xC0 | (ch >> 6)));
utf8_str.push_back(static_cast<char>(0x80 | (ch & 0x3F)));
}
else
{
utf8_str.push_back(static_cast<char>(0xE0 | (ch >> 12)));
utf8_str.push_back(static_cast<char>(0x80 | ((ch >> 6) & 0x3F)));
utf8_str.push_back(static_cast<char>(0x80 | (ch & 0x3F)));
}
}
return utf8_str;
}
inline std::string w_to_u8(const std::wstring_view w_view)
{
std::string utf8_str;
utf8_str.reserve(w_view.size() * 2);
for (const wchar_t w_ch : w_view)
{
const auto ch = static_cast<char16_t>(w_ch);
if (ch <= 0x7F)
{
utf8_str.push_back(static_cast<char>(ch));
}
else if (ch <= 0x7FF)
{
utf8_str.push_back(static_cast<char>(0xC0 | (ch >> 6)));
utf8_str.push_back(static_cast<char>(0x80 | (ch & 0x3F)));
}
else
{
utf8_str.push_back(static_cast<char>(0xE0 | (ch >> 12)));
utf8_str.push_back(static_cast<char>(0x80 | ((ch >> 6) & 0x3F)));
utf8_str.push_back(static_cast<char>(0x80 | (ch & 0x3F)));
}
}
return utf8_str;
}
#ifndef OS_WINDOWS
inline int open_unicode(FILE** handle, const std::filesystem::path& fileName, const std::u16string& mode)
{
*handle = fopen(fileName.string().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<const wchar_t*>(u16str.data()), u16str.size());
}
inline auto open_unicode(FILE** handle, const std::filesystem::path& fileName, const std::u16string& mode)
{
return _wfopen_s(handle, fileName.wstring().c_str(), u16_to_w(mode).c_str());
}
#endif