Skip to content

Instantly share code, notes, and snippets.

@Youlean
Created November 25, 2019 14:40
Show Gist options
  • Save Youlean/0b5ae19369a6f1f593f15f62b0a99854 to your computer and use it in GitHub Desktop.
Save Youlean/0b5ae19369a6f1f593f15f62b0a99854 to your computer and use it in GitHub Desktop.
#pragma once
#include <fstream>
#include <codecvt>
class Windows_UTF_Converter
{
public:
#ifdef WIN32
std::string utf8_to_ansi(std::string s)
{
BSTR bstrWide;
char* pszAnsi;
int nLength;
const char *pszCode = s.c_str();
nLength = MultiByteToWideChar(CP_UTF8, 0, pszCode, strlen(pszCode) + 1, NULL, NULL);
bstrWide = SysAllocStringLen(NULL, nLength);
MultiByteToWideChar(CP_UTF8, 0, pszCode, strlen(pszCode) + 1, bstrWide, nLength);
nLength = WideCharToMultiByte(CP_ACP, 0, bstrWide, -1, NULL, 0, NULL, NULL);
pszAnsi = new char[nLength];
WideCharToMultiByte(CP_ACP, 0, bstrWide, -1, pszAnsi, nLength, NULL, NULL);
SysFreeString(bstrWide);
std::string r(pszAnsi);
delete[] pszAnsi;
return r;
}
std::string utf16_to_utf8(std::wstring wstr)
{
std::string convertedString;
int requiredSize = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), wstr.length(), NULL, 0, NULL, NULL);
if (requiredSize > 0)
{
convertedString.resize(requiredSize);
WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), wstr.length(), &convertedString[0], requiredSize, NULL, NULL);
}
return convertedString;
}
std::wstring utf8_to_utf16(std::string str)
{
std::wstring convertedString;
int requiredSize = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), NULL, 0);
if (requiredSize > 0)
{
convertedString.resize(requiredSize);
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), &convertedString[0], requiredSize);
}
return convertedString;
}
std::string string_to_utf8(std::string str)
{
std::wstring w = utf8_to_utf16(str);
return utf16_to_utf8(w);
}
#endif
};
namespace utf8
{
#ifdef WIN32
class ifstream : public std::ifstream, Windows_UTF_Converter
{
public:
ifstream() : std::ifstream() {}
explicit ifstream(const char* fileName, std::ios_base::open_mode mode = std::ios_base::in) :
std::ifstream(utf8_to_utf16(fileName), mode)
{
}
explicit ifstream(const std::string& fileName, std::ios_base::open_mode mode = std::ios_base::in) :
std::ifstream(utf8_to_utf16(fileName), mode)
{
}
void open(const char* fileName, std::ios_base::open_mode mode = std::ios_base::in)
{
std::ifstream::open(utf8_to_utf16(fileName), mode);
}
void open(const std::string& fileName, std::ios_base::open_mode mode = std::ios_base::in)
{
std::ifstream::open(utf8_to_utf16(fileName), mode);
}
};
class ofstream : public std::ofstream, Windows_UTF_Converter
{
public:
ofstream() : std::ofstream() {}
explicit ofstream(const char* fileName, std::ios_base::open_mode mode = std::ios_base::out) :
std::ofstream(utf8_to_utf16(fileName), mode)
{
}
explicit ofstream(const std::string& fileName, std::ios_base::open_mode mode = std::ios_base::out) :
std::ofstream(utf8_to_utf16(fileName), mode)
{
}
void open(const char* fileName, std::ios_base::open_mode mode = std::ios_base::out)
{
std::ofstream::open(utf8_to_utf16(fileName), mode);
}
void open(const std::string& fileName, std::ios_base::open_mode mode = std::ios_base::out)
{
std::ofstream::open(utf8_to_utf16(fileName), mode);
}
};
#else
typedef std::ifstream ifstream;
typedef std::ofstream ofstream;
#endif
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment