mirror of
https://github.com/lifegpc/pixiv_downloader.git
synced 2026-06-06 22:08:54 +08:00
94 lines
3.0 KiB
Diff
94 lines
3.0 KiB
Diff
diff --git a/src/basicio.cpp b/src/basicio.cpp
|
|
index 3971cb50c..b76f86e61 100644
|
|
--- a/src/basicio.cpp
|
|
+++ b/src/basicio.cpp
|
|
@@ -51,6 +51,64 @@ namespace fs = std::experimental::filesystem;
|
|
#endif
|
|
|
|
namespace Exiv2 {
|
|
+#if defined(__MINGW__) || (defined(WIN32) && !defined(__CYGWIN__))
|
|
+ /// Remove unsuportted options flags
|
|
+ unsigned long getMultiByteToWideCharOptions(const unsigned long ori_options, unsigned int cp) {
|
|
+ if (cp == CP_ACP) cp = GetACP();
|
|
+ if (cp == CP_OEMCP) cp = GetOEMCP();
|
|
+ switch (cp)
|
|
+ {
|
|
+ case 50220:
|
|
+ case 50221:
|
|
+ case 50222:
|
|
+ case 50225:
|
|
+ case 50227:
|
|
+ case 50229:
|
|
+ case CP_UTF7:
|
|
+ case 42:
|
|
+ return 0;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+ if (cp >= 57002 && cp <= 57011) return 0;
|
|
+ if (cp == CP_UTF8 || cp == 54936) {
|
|
+ return MB_ERR_INVALID_CHARS & ori_options;
|
|
+ }
|
|
+ return ori_options;
|
|
+ }
|
|
+ bool str_to_wstr(std::wstring& out, std::string inp, unsigned int cp) {
|
|
+ DWORD opt = getMultiByteToWideCharOptions(MB_ERR_INVALID_CHARS, cp);
|
|
+ int wlen = MultiByteToWideChar(cp, opt, inp.c_str(), inp.length(), nullptr, 0);
|
|
+ if (!wlen) {
|
|
+ return false;
|
|
+ }
|
|
+ wchar_t* wstr = (wchar_t*)malloc(wlen * sizeof(wchar_t));
|
|
+ if (wstr == nullptr) {
|
|
+ return false;
|
|
+ }
|
|
+ if (!MultiByteToWideChar(cp, opt, inp.c_str(), inp.length(), wstr, wlen)) {
|
|
+ free(wstr);
|
|
+ return false;
|
|
+ }
|
|
+ out = std::wstring(wstr, wlen);
|
|
+ free(wstr);
|
|
+ return true;
|
|
+ }
|
|
+ FILE* win32_fopen(const char* path, const char* mode) {
|
|
+ std::string p(path), m(mode);
|
|
+ FILE* f = nullptr;
|
|
+ unsigned long cps[] = { CP_UTF8, CP_ACP, CP_OEMCP };
|
|
+ for (int i = 0; i < 3; i++) {
|
|
+ std::wstring wp, wm;
|
|
+ if (str_to_wstr(wp, p, cps[i]) && str_to_wstr(wm, m, cps[i])) {
|
|
+ if ((f = _wfopen(wp.c_str(), wm.c_str()))) {
|
|
+ return f;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return std::fopen(path, mode);
|
|
+ }
|
|
+#endif
|
|
void BasicIo::readOrThrow(byte* buf, size_t rcount, ErrorCode err) {
|
|
const size_t nread = read(buf, rcount);
|
|
Internal::enforce(nread == rcount, err);
|
|
@@ -158,7 +216,11 @@ int FileIo::Impl::switchMode(OpMode opMode) {
|
|
std::fclose(fp_);
|
|
openMode_ = "r+b";
|
|
opMode_ = opSeek;
|
|
+#if defined(__MINGW__) || (defined(WIN32) && !defined(__CYGWIN__))
|
|
+ fp_ = win32_fopen(path_.c_str(), openMode_.c_str());
|
|
+#else
|
|
fp_ = std::fopen(path_.c_str(), openMode_.c_str());
|
|
+#endif
|
|
if (!fp_)
|
|
return 1;
|
|
#ifdef _WIN32
|
|
@@ -479,7 +541,11 @@ int FileIo::open(const std::string& mode) {
|
|
close();
|
|
p_->openMode_ = mode;
|
|
p_->opMode_ = Impl::opSeek;
|
|
+#if defined(__MINGW__) || (defined(WIN32) && !defined(__CYGWIN__))
|
|
+ p_->fp_ = win32_fopen(path().c_str(), mode.c_str());
|
|
+#else
|
|
p_->fp_ = ::fopen(path().c_str(), mode.c_str());
|
|
+#endif
|
|
if (!p_->fp_)
|
|
return 1;
|
|
return 0;
|