Created
November 25, 2019 14:40
-
-
Save Youlean/0b5ae19369a6f1f593f15f62b0a99854 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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