Skip to content

Instantly share code, notes, and snippets.

@nekko1119
Last active February 10, 2024 09:38
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save nekko1119/f834549ffd30311a19296f8d5b4cc6e8 to your computer and use it in GitHub Desktop.
Save nekko1119/f834549ffd30311a19296f8d5b4cc6e8 to your computer and use it in GitHub Desktop.
#include <codecvt>
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <locale>
#include <string>
#include <system_error>
#include <vector>
#include <Windows.h>
std::wstring multi_to_wide_capi(std::string const& src)
{
std::size_t converted{};
std::vector<wchar_t> dest(src.size(), L'\0');
if (::_mbstowcs_s_l(&converted, dest.data(), dest.size(), src.data(), _TRUNCATE, ::_create_locale(LC_ALL, "jpn")) != 0) {
throw std::system_error{errno, std::system_category()};
}
dest.resize(std::char_traits<wchar_t>::length(dest.data()));
dest.shrink_to_fit();
return std::wstring(dest.begin(), dest.end());
}
std::wstring multi_to_wide_winapi(std::string const& src)
{
auto const dest_size = ::MultiByteToWideChar(CP_ACP, 0U, src.data(), -1, nullptr, 0U);
std::vector<wchar_t> dest(dest_size, L'\0');
if (::MultiByteToWideChar(CP_ACP, 0U, src.data(), -1, dest.data(), dest.size()) == 0) {
throw std::system_error{static_cast<int>(::GetLastError()), std::system_category()};
}
dest.resize(std::char_traits<wchar_t>::length(dest.data()));
dest.shrink_to_fit();
return std::wstring(dest.begin(), dest.end());
}
std::string wide_to_multi_capi(std::wstring const& src)
{
std::size_t converted{};
std::vector<char> dest(src.size() * sizeof(wchar_t) + 1, '\0');
if (::_wcstombs_s_l(&converted, dest.data(), dest.size(), src.data(), _TRUNCATE, ::_create_locale(LC_ALL, "jpn")) != 0) {
throw std::system_error{errno, std::system_category()};
}
dest.resize(std::char_traits<char>::length(dest.data()));
dest.shrink_to_fit();
return std::string(dest.begin(), dest.end());
}
std::string wide_to_multi_winapi(std::wstring const& src)
{
auto const dest_size = ::WideCharToMultiByte(CP_ACP, 0U, src.data(), -1, nullptr, 0, nullptr, nullptr);
std::vector<char> dest(dest_size, '\0');
if (::WideCharToMultiByte(CP_ACP, 0U, src.data(), -1, dest.data(), dest.size(), nullptr, nullptr) == 0) {
throw std::system_error{static_cast<int>(::GetLastError()), std::system_category()};
}
dest.resize(std::char_traits<char>::length(dest.data()));
dest.shrink_to_fit();
return std::string(dest.begin(), dest.end());
}
std::string wide_to_utf8_cppapi(std::wstring const& src)
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
return converter.to_bytes(src);
}
std::string wide_to_utf8_winapi(std::wstring const& src)
{
auto const dest_size = ::WideCharToMultiByte(CP_UTF8, 0U, src.data(), -1, nullptr, 0, nullptr, nullptr);
std::vector<char> dest(dest_size, '\0');
if (::WideCharToMultiByte(CP_UTF8, 0U, src.data(), -1, dest.data(), dest.size(), nullptr, nullptr) == 0) {
throw std::system_error{static_cast<int>(::GetLastError()), std::system_category()};
}
dest.resize(std::char_traits<char>::length(dest.data()));
dest.shrink_to_fit();
return std::string(dest.begin(), dest.end());
}
std::wstring utf8_to_wide_cppapi(std::string const& src)
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
return converter.from_bytes(src);
}
std::wstring utf8_to_wide_winapi(std::string const& src)
{
auto const dest_size = ::MultiByteToWideChar(CP_UTF8, 0U, src.data(), -1, nullptr, 0U);
std::vector<wchar_t> dest(dest_size, L'\0');
if (::MultiByteToWideChar(CP_UTF8, 0U, src.data(), -1, dest.data(), dest.size()) == 0) {
throw std::system_error{static_cast<int>(::GetLastError()), std::system_category()};
}
dest.resize(std::char_traits<wchar_t>::length(dest.data()));
dest.shrink_to_fit();
return std::wstring(dest.begin(), dest.end());
}
std::string multi_to_utf8_cppapi(std::string const& src)
{
auto const wide = multi_to_wide_capi(src);
return wide_to_utf8_cppapi(wide);
}
std::string multi_to_utf8_winapi(std::string const& src)
{
auto const wide = multi_to_wide_winapi(src);
return wide_to_utf8_winapi(wide);
}
std::string utf8_to_multi_cppapi(std::string const& src)
{
auto const wide = utf8_to_wide_cppapi(src);
return wide_to_multi_capi(wide);
}
std::string utf8_to_multi_winapi(std::string const& src)
{
auto const wide = utf8_to_wide_winapi(src);
return wide_to_multi_winapi(wide);
}
//std::u16string utf8_to_utf16(std::string const& src)
//{
// std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter;
// return converter.from_bytes(src);
//}
//
//std::string utf16_to_utf8(std::u16string const& src)
//{
// std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter;
// return converter.to_bytes(src);
//}
template <typename OS, typename T>
void dump(OS& os, T const* t)
{
bool is_first = true;
auto const* byte = reinterpret_cast<unsigned char const*>(t);
os << std::hex << std::uppercase << std::setfill('0') << std::setw(2);
while (*byte) {
if (!std::exchange(is_first, false)) {
os << " ";
}
os << static_cast<unsigned int>(*byte);
++byte;
}
os << std::endl;
}
int main()
{
{
std::string const src = "あ";
dump(std::cout, src.data());
auto const dest = multi_to_wide_capi(src);
dump(std::cout, dest.data());
}
{
std::string const src = "あ";
dump(std::cout, src.data());
auto const dest = multi_to_wide_winapi(src);
dump(std::cout, dest.data());
}
std::cout << std::endl;
{
std::wstring const src = L"あ";
dump(std::cout, src.data());
auto const dest = wide_to_multi_capi(src);
dump(std::cout, dest.data());
}
{
std::wstring const src = L"あ";
dump(std::cout, src.data());
auto const dest = wide_to_multi_winapi(src);
dump(std::cout, dest.data());
}
std::cout << std::endl;
{
std::wstring const src = L"あ";
dump(std::cout, src.data());
auto const dest = wide_to_utf8_cppapi(src);
dump(std::cout, dest.data());
}
{
std::wstring const src = L"あ";
dump(std::cout, src.data());
auto const dest = wide_to_utf8_winapi(src);
dump(std::cout, dest.data());
}
std::cout << std::endl;
{
std::string const src = u8"あ";
dump(std::cout, src.data());
auto const dest = utf8_to_wide_cppapi(src);
dump(std::cout, dest.data());
}
{
std::string const src = u8"あ";
dump(std::cout, src.data());
auto const dest = utf8_to_wide_winapi(src);
dump(std::cout, dest.data());
}
std::cout << std::endl;
{
std::string const src = "あ";
dump(std::cout, src.data());
auto const dest = multi_to_utf8_cppapi(src);
dump(std::cout, dest.data());
}
{
std::string const src = "あ";
dump(std::cout, src.data());
auto const dest = multi_to_utf8_winapi(src);
dump(std::cout, dest.data());
}
std::cout << std::endl;
{
std::string const src = u8"あ";
dump(std::cout, src.data());
auto const dest = utf8_to_multi_cppapi(src);
dump(std::cout, dest.data());
}
{
std::string const src = u8"あ";
dump(std::cout, src.data());
auto const dest = utf8_to_multi_winapi(src);
dump(std::cout, dest.data());
}
std::cout << std::endl;
//{
// std::string const src = u8"あ";
// dump(std::cout, src.data());
// auto const dest = utf8_to_utf16(src);
// dump(std::cout, dest.data());
//}
//{
// std::u16string const src = u"あ";
// dump(std::cout, src.data());
// auto const dest = utf16_to_utf8(src);
// dump(std::cout, dest.data());
//}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment