From 5a58edde2266680e2099934524e645ddda608110 Mon Sep 17 00:00:00 2001 From: Andrey Filipenkov Date: Tue, 6 Feb 2024 01:29:13 +0300 Subject: [PATCH] use 32-bit minizip file funcs on old Android --- lib/filesystem/CZipLoader.cpp | 9 +++++++-- lib/filesystem/CZipLoader.h | 2 +- lib/filesystem/MinizipExtensions.cpp | 23 +++++++++++++++++++---- lib/filesystem/MinizipExtensions.h | 8 ++++++++ 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/lib/filesystem/CZipLoader.cpp b/lib/filesystem/CZipLoader.cpp index 60e28972e..f1f5cdf49 100644 --- a/lib/filesystem/CZipLoader.cpp +++ b/lib/filesystem/CZipLoader.cpp @@ -181,12 +181,17 @@ std::vector ZipArchive::listFiles() ZipArchive::ZipArchive(const boost::filesystem::path & from) { CDefaultIOApi zipAPI; - auto zipStructure = zipAPI.getApiStructure(); +#if MINIZIP_NEEDS_32BIT_FUNCS + auto zipStructure = zipAPI.getApiStructure32(); + archive = unzOpen2(from.c_str(), &zipStructure); +#else + auto zipStructure = zipAPI.getApiStructure(); archive = unzOpen2_64(from.c_str(), &zipStructure); +#endif if (archive == nullptr) - throw std::runtime_error("Failed to open file" + from.string() + "'%s'! Unable to list files!"); + throw std::runtime_error("Failed to open file '" + from.string() + "' - unable to list files!"); } ZipArchive::~ZipArchive() diff --git a/lib/filesystem/CZipLoader.h b/lib/filesystem/CZipLoader.h index be5428926..73a45e004 100644 --- a/lib/filesystem/CZipLoader.h +++ b/lib/filesystem/CZipLoader.h @@ -50,7 +50,7 @@ class DLL_LINKAGE CZipLoader : public ISimpleResourceLoader std::unordered_map listFiles(const std::string & mountPoint, const boost::filesystem::path &archive); public: - CZipLoader(const std::string & mountPoint, const boost::filesystem::path & archive, std::shared_ptr api = std::shared_ptr(new CDefaultIOApi())); + CZipLoader(const std::string & mountPoint, const boost::filesystem::path & archive, std::shared_ptr api = std::make_shared()); /// Interface implementation /// @see ISimpleResourceLoader diff --git a/lib/filesystem/MinizipExtensions.cpp b/lib/filesystem/MinizipExtensions.cpp index 9c7a2a407..ebc3bc487 100644 --- a/lib/filesystem/MinizipExtensions.cpp +++ b/lib/filesystem/MinizipExtensions.cpp @@ -12,6 +12,8 @@ #include "CMemoryBuffer.h" +#include + VCMI_LIB_NAMESPACE_BEGIN template @@ -130,16 +132,29 @@ static voidpf ZCALLBACK MinizipOpenFunc(voidpf opaque, const void* filename, int zlib_filefunc64_def CDefaultIOApi::getApiStructure() { static zlib_filefunc64_def MinizipFilefunc; - static bool initialized = false; - if (!initialized) + static std::once_flag flag; + std::call_once(flag, [] { fill_fopen64_filefunc(&MinizipFilefunc); MinizipFilefunc.zopen64_file = &MinizipOpenFunc; - initialized = true; - } + }); return MinizipFilefunc; } +#if MINIZIP_NEEDS_32BIT_FUNCS +zlib_filefunc_def CDefaultIOApi::getApiStructure32() +{ + static zlib_filefunc_def MinizipFilefunc; + static std::once_flag flag; + std::call_once(flag, [] + { + fill_fopen_filefunc(&MinizipFilefunc); + MinizipFilefunc.zopen_file = reinterpret_cast(&MinizipOpenFunc); + }); + return MinizipFilefunc; +} +#endif + ///CProxyIOApi CProxyIOApi::CProxyIOApi(CInputOutputStream * buffer): data(buffer) diff --git a/lib/filesystem/MinizipExtensions.h b/lib/filesystem/MinizipExtensions.h index 8bd73958e..c412ee183 100644 --- a/lib/filesystem/MinizipExtensions.h +++ b/lib/filesystem/MinizipExtensions.h @@ -19,6 +19,11 @@ #include "../minizip/ioapi.h" #endif +// system zlib on old Androids isn't capable of using _64 functions: https://github.com/madler/zlib/pull/436 +#if defined(__ANDROID_API__) && (__ANDROID_API__ < 24) +#define MINIZIP_NEEDS_32BIT_FUNCS 1 +#endif + VCMI_LIB_NAMESPACE_BEGIN class CInputStream; @@ -39,6 +44,9 @@ class DLL_LINKAGE CDefaultIOApi: public CIOApi { public: zlib_filefunc64_def getApiStructure() override; +#if MINIZIP_NEEDS_32BIT_FUNCS + zlib_filefunc_def getApiStructure32(); +#endif }; ///redirects all file IO to single stream