The situation is a bit better in nowadays, you should not modify sources of Minizip, but still will be required one #ifdef
in your code for support Unicode in file paths in Windows. Latest versions has new API functions for read/write ZIP:
- unzOpen2_64(const void path, zlib_filefunc64_def pzlib_filefunc_def)
- zipOpen2_64(const void pathname, int append, zipcharpc globalcomment, zlib_filefunc64_def* pzlib_filefunc_def)
The parameter zlib_filefunc64_def
may refer to structure with set of functions for work with file system (or memory). Additionally, Minizip package supplies header file 'iowin32.h' that have methods for fill zlib_filefunc64_def
structure using Windows API. So, for open file for reading you can use code like below:
zipFile openZipFile(const std::string& utf8FilePath)
{
zipFile hZipFile = nullptr;
#ifdef WIN32
zlib_filefunc64_def ffunc;
fill_win32_filefunc64W(&ffunc);
// Convert path from UTF-8 to Unicode
const int count = MultiByteToWideChar(CP_UTF8, 0, utf8FilePath.c_str(), static_cast<int>(utf8FilePath.size()), NULL, 0);
std::wstring unicodePath(count, 0);
MultiByteToWideChar(CP_UTF8, 0, utf8FilePath.c_str(), static_cast<int>(utf8FilePath.size()), &unicodePath[0], count);
hZipFile = zipOpen2_64(unicodePath.c_str(), 0, NULL, &ffunc);
#else
// Unix systems handles path in the UTF-8 by default
hZipFile = zipOpen64(utf8FilePath.c_str(), 0);
#endif
return hZipFile;
}
The second worked option that I've found - just set the locale to UTF-8. Better to do it at the application initialization layer, as it's not thread safe:
std::setlocale(LC_ALL, "en_us.utf8");
It looks much simpler, but I think that first variant is better and reliable as it doesn't depend to locale settings.