From 5cecef2b92ad0cb4cee3271ab0910e47229f898d Mon Sep 17 00:00:00 2001 From: Harokyang Date: Wed, 30 Oct 2019 15:16:46 +0800 Subject: [PATCH 1/3] Treat all filepath string as utf-8 encoded On Windows, convert utf-8 to wchar string before interact with filepath --- tiny_gltf.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tiny_gltf.h b/tiny_gltf.h index 23b16c9..d6ee24c 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -2227,7 +2227,10 @@ bool FileExists(const std::string &abs_filename, void *) { #else #ifdef _WIN32 FILE *fp; - errno_t err = fopen_s(&fp, abs_filename.c_str(), "rb"); + int wchar_size = MultiByteToWideChar(CP_UTF8, 0, abs_filename.data(), (int)abs_filename.size(), nullptr, 0); + std::wstring wstr(wchar_size, 0); + MultiByteToWideChar(CP_UTF8, 0, abs_filename.data(), (int)abs_filename.size(), wstr.data(), (int)wstr.size()); + errno_t err = _wfopen_s(&fp, wstr.c_str(), L"rb"); if (err != 0) { return false; } @@ -2321,8 +2324,15 @@ bool ReadWholeFile(std::vector *out, std::string *err, } return false; } +#else +#ifdef _WIN32 + int wchar_size = MultiByteToWideChar(CP_UTF8, 0, filepath.data(), (int)filepath.size(), nullptr, 0); + std::wstring wstr(wchar_size, 0); + MultiByteToWideChar(CP_UTF8, 0, filepath.data(), (int)filepath.size(), wstr.data(), (int)wstr.size()); + std::ifstream f(wstr.c_str(), std::ifstream::binary); #else std::ifstream f(filepath.c_str(), std::ifstream::binary); +#endif if (!f) { if (err) { (*err) += "File open error : " + filepath + "\n"; From fb256609f2fdc63abf974e265ed2247347cdc59f Mon Sep 17 00:00:00 2001 From: Harokyang Date: Wed, 30 Oct 2019 16:13:52 +0800 Subject: [PATCH 2/3] support writing with utf-8 filepath --- tiny_gltf.h | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/tiny_gltf.h b/tiny_gltf.h index d6ee24c..c54cc4a 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -2207,6 +2207,15 @@ bool WriteImageData(const std::string *basepath, const std::string *filename, void TinyGLTF::SetFsCallbacks(FsCallbacks callbacks) { fs = callbacks; } +#ifdef _WIN32 +static inline std::wstring UTF8ToWchar(const std::string &str) { + int wstr_size = MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), nullptr, 0); + std::wstring wstr(wstr_size, 0); + MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), wstr.data(), (int)wstr.size()); + return wstr; +} +#endif + #ifndef TINYGLTF_NO_FS // Default implementations of filesystem functions @@ -2227,10 +2236,7 @@ bool FileExists(const std::string &abs_filename, void *) { #else #ifdef _WIN32 FILE *fp; - int wchar_size = MultiByteToWideChar(CP_UTF8, 0, abs_filename.data(), (int)abs_filename.size(), nullptr, 0); - std::wstring wstr(wchar_size, 0); - MultiByteToWideChar(CP_UTF8, 0, abs_filename.data(), (int)abs_filename.size(), wstr.data(), (int)wstr.size()); - errno_t err = _wfopen_s(&fp, wstr.c_str(), L"rb"); + errno_t err = _wfopen_s(&fp, UTF8ToWchar(abs_filename).c_str(), L"rb"); if (err != 0) { return false; } @@ -2326,10 +2332,7 @@ bool ReadWholeFile(std::vector *out, std::string *err, } #else #ifdef _WIN32 - int wchar_size = MultiByteToWideChar(CP_UTF8, 0, filepath.data(), (int)filepath.size(), nullptr, 0); - std::wstring wstr(wchar_size, 0); - MultiByteToWideChar(CP_UTF8, 0, filepath.data(), (int)filepath.size(), wstr.data(), (int)wstr.size()); - std::ifstream f(wstr.c_str(), std::ifstream::binary); + std::ifstream f(UTF8ToWchar(filepath).c_str(), std::ifstream::binary); #else std::ifstream f(filepath.c_str(), std::ifstream::binary); #endif @@ -2368,7 +2371,11 @@ bool ReadWholeFile(std::vector *out, std::string *err, bool WriteWholeFile(std::string *err, const std::string &filepath, const std::vector &contents, void *) { +#ifdef _WIN32 + std::ofstream f(UTF8ToWchar(filepath).c_str(), std::ofstream::binary); +#else std::ofstream f(filepath.c_str(), std::ofstream::binary); +#endif if (!f) { if (err) { (*err) += "File open error for writing : " + filepath + "\n"; @@ -5641,7 +5648,11 @@ static void SerializeGltfBufferData(const std::vector &data, static bool SerializeGltfBufferData(const std::vector &data, const std::string &binFilename) { +#ifdef _WIN32 + std::ofstream output(UTF8ToWchar(binFilename).c_str(), std::ofstream::binary); +#else std::ofstream output(binFilename.c_str(), std::ofstream::binary); +#endif if (!output.is_open()) return false; output.write(reinterpret_cast(&data[0]), std::streamsize(data.size())); @@ -6499,7 +6510,11 @@ static bool WriteGltfStream(std::ostream &stream, const std::string &content) { static bool WriteGltfFile(const std::string &output, const std::string &content) { +#ifdef _WIN32 + std::ofstream gltfFile(UTF8ToWchar(output).c_str()); +#else std::ofstream gltfFile(output.c_str()); +#endif if (!gltfFile.is_open()) return false; return WriteGltfStream(gltfFile, content); } @@ -6536,7 +6551,11 @@ static void WriteBinaryGltfStream(std::ostream &stream, static void WriteBinaryGltfFile(const std::string &output, const std::string &content) { +#ifdef _WIN32 + std::ofstream gltfFile(UTF8ToWchar(output).c_str(), std::ios::binary); +#else std::ofstream gltfFile(output.c_str(), std::ios::binary); +#endif WriteBinaryGltfStream(gltfFile, content); } From 05a445694866c091bdac13775b737fa8f37dbe2c Mon Sep 17 00:00:00 2001 From: Harokyang Date: Wed, 30 Oct 2019 16:30:00 +0800 Subject: [PATCH 3/3] fix build error on C++11/C++14 --- tiny_gltf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tiny_gltf.h b/tiny_gltf.h index c54cc4a..b626835 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -2211,7 +2211,7 @@ void TinyGLTF::SetFsCallbacks(FsCallbacks callbacks) { fs = callbacks; } static inline std::wstring UTF8ToWchar(const std::string &str) { int wstr_size = MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), nullptr, 0); std::wstring wstr(wstr_size, 0); - MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), wstr.data(), (int)wstr.size()); + MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), &wstr[0], (int)wstr.size()); return wstr; } #endif