Commit 140f896e authored by Gerhard Stein's avatar Gerhard Stein

Added some downloader and unzip code. Cosmetics are still missing and a selection dialog

parent 9c2ed910
......@@ -10,7 +10,7 @@ cmake_minimum_required(VERSION 2.8.12)
OPTION(OGG "Ogg/Vorbis support" Yes)
OPTION(TREMOR "Tremor support" No)
OPTION(DBFUSION "Dosbox fusion" No)
OPTION(DOWNLOADER "Internal Downloader" No)
OPTION(DOWNLOADER "Internal Downloader" Yes)
OPTION(USE_SDL2 "SDL2 support" Yes)
......
......@@ -237,7 +237,8 @@ How to compile it under Ubuntu:
- libogg-dev
- libgl1-mesa-dev
- libboost
-libcurl
- libcurl
- zlib
For SDL 1.2:
- libsdl1.2-dev
......
......@@ -233,9 +233,10 @@ drive_list GetDrives()
#ifndef WIN32
// checks, if path is statable (that means, it's existing)
// HINT: absolute path and there is not case fixing
// HINT: absolute path and there is no case fixing
// (used by GetExactFileName)
bool IsPathStatable(const std::string& f) {
bool IsPathStatable(const std::string& f)
{
std::string abs_f = f;
// remove trailing slashes
......@@ -501,7 +502,8 @@ void InitBaseSearchPaths() {
#endif
}
void CreateRecDir(const std::string& abs_filename, bool last_is_dir) {
void CreateRecDir(const std::string& abs_filename, bool last_is_dir)
{
std::string tmp;
std::string::const_iterator f = abs_filename.begin();
for(tmp = ""; f != abs_filename.end(); f++) {
......@@ -510,10 +512,13 @@ void CreateRecDir(const std::string& abs_filename, bool last_is_dir) {
tmp += *f;
}
if(last_is_dir)
{
mkdir(tmp.c_str(), 0777);
}
}
std::string GetFirstSearchPath() {
std::string GetFirstSearchPath()
{
if(tSearchPaths.size() > 0)
return tSearchPaths.front();
else if(basesearchpaths.size() > 0)
......
......@@ -197,6 +197,8 @@ std::string GetScriptInterpreterCommandForFile(const std::string& filename);
bool IsFileAvailable(const std::string& f, bool absolute = false);
std::string GetFirstSearchPath();
// the dir will be created recursivly
// IMPORTANT: filename is absolute; no game-path!
void CreateRecDir(const std::string& abs_filename, bool last_is_dir = true);
......
......@@ -114,6 +114,11 @@ IF (Boost_FOUND)
ENDIF()
find_package( ZLIB REQUIRED )
if ( ZLIB_FOUND )
include_directories( ${ZLIB_INCLUDE_DIRS} )
endif( ZLIB_FOUND )
if(DOWNLOADER)
FIND_PACKAGE(CURL)
IF(CURL_FOUND)
......@@ -208,6 +213,9 @@ set_property(TARGET CGeniusExe PROPERTY C_STANDARD 99)
target_link_libraries (CGeniusExe GsKit)
# Link zlib
target_link_libraries( CGeniusExe ${ZLIB_LIBRARIES} )
if(USE_SDL2)
target_link_libraries(CGeniusExe ${SDL2_LIBRARIES})
target_link_libraries(CGeniusExe ${SDL2IMAGE_LIBRARIES})
......@@ -286,7 +294,6 @@ if(DBFUSION)
target_link_libraries(CGeniusExe m)
target_link_libraries(CGeniusExe png)
target_link_libraries(CGeniusExe z)
if(WIN32)
target_link_libraries(CGeniusExe SDL2_net)
......@@ -299,6 +306,8 @@ if(DBFUSION)
endif(DBFUSION)
cotire(CGeniusExe)
# Stuff definitions in case we want to install it
......
......@@ -743,8 +743,6 @@ void CGameLauncher::ponderGameSelDialog(const float deltaT)
void CGameLauncher::ponderDownloadDialog()
{
mDownloadProgress++;
if(mDownloadProgress >= 1000)
{
mFinishedDownload = true;
......@@ -757,6 +755,7 @@ void CGameLauncher::ponderDownloadDialog()
if( mFinishedDownload && mpGameDownloader->finished )
{
mpDownloadDialog = nullptr;
gEventManager.add(new GMSwitchToGameLauncher() );
}
}
......
......@@ -21,6 +21,7 @@ endif()
add_subdirectory(refkeen)
add_library(engine OBJECT CGameLauncher.cpp CGameLauncher.h
gamedownloader.cpp gamedownloader.h)
gamedownloader.cpp gamedownloader.h
unzip/miniunz.c unzip/ioapi.c unzip/unzip.c)
set_property(GLOBAL APPEND PROPERTY CG_OBJ_LIBS $<TARGET_OBJECTS:engine>)
#include "gamedownloader.h"
#include <base/utils/FindFile.h>
#include <base/GsLogging.h>
#include <cstdio>
#include <curl/curl.h>
extern "C"
{
int unzipFile(const char *input,
const char *outputDir);
}
// Limit to max 1 GB
const curl_off_t STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES = 1024 * 1024 * 1024;
#define MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL 3
......@@ -14,6 +22,8 @@ struct myprogress {
int *progressPtr;
int gDlto, gDlfrom;
/* this is how the CURLOPT_XFERINFOFUNCTION callback works */
static int xferinfo(void *p,
curl_off_t dltotal, curl_off_t dlnow,
......@@ -28,19 +38,14 @@ static int xferinfo(void *p,
/* under certain circumstances it may be desirable for certain functionality
to only run every N seconds, in order to do this the transaction time can
be used */
if((curtime - myp->lastruntime) >= MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL) {
if((curtime - myp->lastruntime) >= MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL)
{
myp->lastruntime = curtime;
//fprintf(stderr, "TOTAL TIME: %f \r\n", curtime);
}
/*fprintf(stderr, "UP: %" CURL_FORMAT_CURL_OFF_T " of %" CURL_FORMAT_CURL_OFF_T
" DOWN: %" CURL_FORMAT_CURL_OFF_T " of %" CURL_FORMAT_CURL_OFF_T
"\r\n",
ulnow, ultotal, dlnow, dltotal);*/
if(dltotal > 0)
{
const int newProgress = (1000*dlnow)/dltotal;
const int newProgress = gDlfrom + ((gDlto-gDlfrom)*dlnow)/dltotal;
*progressPtr = newProgress;
}
......@@ -72,17 +77,18 @@ size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream)
int downloadFile(const std::string &filename, int &progress)
int downloadFile(const std::string &filename, int &progress,
const std::string &downloadDirPath)
{
progressPtr = &progress;
const std::string urlString = "http://downloads.sourceforge.net/project/clonekeenplus/Downloads/" + filename;
const std::string outputPath = JoinPaths(downloadDirPath, filename);
CURL *curl;
CURLcode res = CURLE_OK;
struct myprogress prog;
struct myprogress prog;
curl = curl_easy_init();
if(curl)
......@@ -99,7 +105,8 @@ int downloadFile(const std::string &filename, int &progress)
/* pass the struct pointer into the progress function */
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &prog);
FILE *fp = fopen("test.zip","wb");
FILE *fp = fopen(outputPath.c_str(),"wb");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
......@@ -124,6 +131,7 @@ int downloadFile(const std::string &filename, int &progress)
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
res = curl_easy_perform(curl);
// TODO: Put into central log
if(res != CURLE_OK)
fprintf(stderr, "%s\n", curl_easy_strerror(res));
......@@ -140,9 +148,69 @@ int downloadFile(const std::string &filename, int &progress)
int GameDownloader::handle()
{
int res;
int res = 0;
// Get the first path. We assume that one is writable
std::string searchPaths;
GetExactFileName(GetFirstSearchPath(), searchPaths);
const auto downloadPath = JoinPaths(searchPaths, "downloads");
const auto gamesPath = JoinPaths(searchPaths, "games");
// Create Download directory if it does not exist yet
CreateRecDir(downloadPath);
// Keeping the count
const int numGames = 1;
const int numSteps = 2;
int game = 0;
const int ratio = (1000/(numGames*numSteps));
// TODO: Need to check for a list of downloaded stuff and what we still need
const std::string gameName = "KEEN4Special";
{
int step = 0;
gDlfrom = mProgress = (game*numSteps+step)*ratio;
gDlto = (game*numSteps+step+1)*ratio;
const std::string gameFile = gameName + ".zip";
const auto downloadGamePath = JoinPaths(downloadPath, gameFile);
if( !IsFileAvailable(downloadGamePath) )
{
// TODO: We also must pass the gamepath and a downloads folder we all the file packages can be set.
res = downloadFile(gameFile, mProgress, downloadPath);
}
step++;
mProgress = (game*numSteps+step)*ratio;
// TODO: Now the downloaded stuff must be extracted to the games directory
// At this point the file should be available
const std::string destDir = JoinPaths(gamesPath,gameName);
if( IsFileAvailable(downloadGamePath) )
{
// Create subdirectory
CreateRecDir( destDir );
unzipFile(downloadGamePath.c_str(), destDir.c_str());
}
else
{
const std::string errStr = "Something went wrong with downloading \"" + gameFile + "\"!";
gLogging.ftextOut(PURPLE, errStr.c_str() );
}
mProgress = (game*numSteps+step)*ratio;
}
res = downloadFile("KEEN4Special.zip", mProgress);
mProgress = 1000;
return res;
}
/* ioapi.h -- IO base function header for compress/uncompress .zip
part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
Modifications for Zip64 support
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
For more info read MiniZip_info.txt
*/
#if defined(_WIN32) && (!(defined(_CRT_SECURE_NO_WARNINGS)))
#define _CRT_SECURE_NO_WARNINGS
#endif
#if defined(__APPLE__) || defined(IOAPI_NO_64)
// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
#define FOPEN_FUNC(filename, mode) fopen(filename, mode)
#define FTELLO_FUNC(stream) ftello(stream)
#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)
#else
#define FOPEN_FUNC(filename, mode) fopen64(filename, mode)
#define FTELLO_FUNC(stream) ftello64(stream)
#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)
#endif
#include "ioapi.h"
voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)
{
if (pfilefunc->zfile_func64.zopen64_file != NULL)
return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode);
else
{
return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode);
}
}
long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)
{
if (pfilefunc->zfile_func64.zseek64_file != NULL)
return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin);
else
{
uLong offsetTruncated = (uLong)offset;
if (offsetTruncated != offset)
return -1;
else
return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin);
}
}
ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)
{
if (pfilefunc->zfile_func64.zseek64_file != NULL)
return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream);
else
{
uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream);
if ((tell_uLong) == MAXU32)
return (ZPOS64_T)-1;
else
return tell_uLong;
}
}
void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32)
{
p_filefunc64_32->zfile_func64.zopen64_file = NULL;
p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file;
p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file;
p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file;
p_filefunc64_32->zfile_func64.ztell64_file = NULL;
p_filefunc64_32->zfile_func64.zseek64_file = NULL;
p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file;
p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque;
p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file;
p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file;
}
static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode));
static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size));
static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size));
static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream));
static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream));
static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream));
static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode)
{
FILE* file = NULL;
const char* mode_fopen = NULL;
if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
mode_fopen = "rb";
else
if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
mode_fopen = "r+b";
else
if (mode & ZLIB_FILEFUNC_MODE_CREATE)
mode_fopen = "wb";
if ((filename!=NULL) && (mode_fopen != NULL))
file = fopen(filename, mode_fopen);
return file;
}
static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode)
{
FILE* file = NULL;
const char* mode_fopen = NULL;
if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
mode_fopen = "rb";
else
if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
mode_fopen = "r+b";
else
if (mode & ZLIB_FILEFUNC_MODE_CREATE)
mode_fopen = "wb";
if ((filename!=NULL) && (mode_fopen != NULL))
file = FOPEN_FUNC((const char*)filename, mode_fopen);
return file;
}
static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size)
{
uLong ret;
ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
return ret;
}
static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size)
{
uLong ret;
ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
return ret;
}
static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream)
{
long ret;
ret = ftell((FILE *)stream);
return ret;
}
static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream)
{
ZPOS64_T ret;
ret = FTELLO_FUNC((FILE *)stream);
return ret;
}
static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin)
{
int fseek_origin=0;
long ret;
switch (origin)
{
case ZLIB_FILEFUNC_SEEK_CUR :
fseek_origin = SEEK_CUR;
break;
case ZLIB_FILEFUNC_SEEK_END :
fseek_origin = SEEK_END;
break;
case ZLIB_FILEFUNC_SEEK_SET :
fseek_origin = SEEK_SET;
break;
default: return -1;
}
ret = 0;
if (fseek((FILE *)stream, offset, fseek_origin) != 0)
ret = -1;
return ret;
}
static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)
{
int fseek_origin=0;
long ret;
switch (origin)
{
case ZLIB_FILEFUNC_SEEK_CUR :
fseek_origin = SEEK_CUR;
break;
case ZLIB_FILEFUNC_SEEK_END :
fseek_origin = SEEK_END;
break;
case ZLIB_FILEFUNC_SEEK_SET :
fseek_origin = SEEK_SET;
break;
default: return -1;
}
ret = 0;
if(FSEEKO_FUNC((FILE *)stream, offset, fseek_origin) != 0)
ret = -1;
return ret;
}
static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream)
{
int ret;
ret = fclose((FILE *)stream);
return ret;
}
static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream)
{
int ret;
ret = ferror((FILE *)stream);
return ret;
}
void fill_fopen_filefunc (pzlib_filefunc_def)
zlib_filefunc_def* pzlib_filefunc_def;
{
pzlib_filefunc_def->zopen_file = fopen_file_func;
pzlib_filefunc_def->zread_file = fread_file_func;
pzlib_filefunc_def->zwrite_file = fwrite_file_func;
pzlib_filefunc_def->ztell_file = ftell_file_func;
pzlib_filefunc_def->zseek_file = fseek_file_func;
pzlib_filefunc_def->zclose_file = fclose_file_func;
pzlib_filefunc_def->zerror_file = ferror_file_func;
pzlib_filefunc_def->opaque = NULL;
}
void fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def)
{
pzlib_filefunc_def->zopen64_file = fopen64_file_func;
pzlib_filefunc_def->zread_file = fread_file_func;
pzlib_filefunc_def->zwrite_file = fwrite_file_func;
pzlib_filefunc_def->ztell64_file = ftell64_file_func;
pzlib_filefunc_def->zseek64_file = fseek64_file_func;
pzlib_filefunc_def->zclose_file = fclose_file_func;
pzlib_filefunc_def->zerror_file = ferror_file_func;
pzlib_filefunc_def->opaque = NULL;
}
/* ioapi.h -- IO base function header for compress/uncompress .zip
part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
Modifications for Zip64 support
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
For more info read MiniZip_info.txt
Changes
Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this)
Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux.
More if/def section may be needed to support other platforms
Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows.
(but you should use iowin32.c for windows instead)
*/
#ifndef _ZLIBIOAPI64_H
#define _ZLIBIOAPI64_H
#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
// Linux needs this to support file operation on files larger then 4+GB
// But might need better if/def to select just the platforms that needs them.
#ifndef __USE_FILE_OFFSET64
#define __USE_FILE_OFFSET64
#endif
#ifndef __USE_LARGEFILE64
#define __USE_LARGEFILE64
#endif
#ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE
#endif
#ifndef _FILE_OFFSET_BIT
#define _FILE_OFFSET_BIT 64
#endif
#endif
#include <stdio.h>
#include <stdlib.h>
#include "zlib.h"
#if defined(USE_FILE32API)
#define fopen64 fopen
#define ftello64 ftell
#define fseeko64 fseek
#else
#ifdef __FreeBSD__
#define fopen64 fopen
#define ftello64 ftello
#define fseeko64 fseeko
#endif
#ifdef _MSC_VER
#define fopen64 fopen
#if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC)))
#define ftello64 _ftelli64
#define fseeko64 _fseeki64
#else // old MSC
#define ftello64 ftell
#define fseeko64 fseek
#endif
#endif
#endif
/*
#ifndef ZPOS64_T
#ifdef _WIN32
#define ZPOS64_T fpos_t
#else
#include <stdint.h>
#define ZPOS64_T uint64_t
#endif
#endif
*/
#ifdef HAVE_MINIZIP64_CONF_H
#include "mz64conf.h"
#endif
/* a type choosen by DEFINE */
#ifdef HAVE_64BIT_INT_CUSTOM
typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T;
#else
#ifdef HAS_STDINT_H
#include "stdint.h"
typedef uint64_t ZPOS64_T;
#else
/* Maximum unsigned 32-bit value used as placeholder for zip64 */
#define MAXU32 0xffffffff
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef unsigned __int64 ZPOS64_T;
#else
typedef unsigned long long int ZPOS64_T;
#endif
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define ZLIB_FILEFUNC_SEEK_CUR (1)
#define ZLIB_FILEFUNC_SEEK_END (2)
#define ZLIB_FILEFUNC_SEEK_SET (0)
#define ZLIB_FILEFUNC_MODE_READ (1)
#define ZLIB_FILEFUNC_MODE_WRITE (2)
#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
#define ZLIB_FILEFUNC_MODE_EXISTING (4)
#define ZLIB_FILEFUNC_MODE_CREATE (8)
#ifndef ZCALLBACK
#if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
#define ZCALLBACK CALLBACK
#else
#define ZCALLBACK
#endif
#endif
typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode));
typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
/* here is the "old" 32 bits structure structure */
typedef struct zlib_filefunc_def_s
{
open_file_func zopen_file;
read_file_func zread_file;
write_file_func zwrite_file;
tell_file_func ztell_file;
seek_file_func zseek_file;
close_file_func zclose_file;
testerror_file_func zerror_file;
voidpf opaque;
} zlib_filefunc_def;
typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream));
typedef long (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, const void* filename, int mode));
typedef struct zlib_filefunc64_def_s
{
open64_file_func zopen64_file;
read_file_func zread_file;
write_file_func zwrite_file;
tell64_file_func ztell64_file;
seek64_file_func zseek64_file;
close_file_func zclose_file;
testerror_file_func zerror_file;
voidpf opaque;
} zlib_filefunc64_def;
void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def));
void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
/* now internal definition, only for zip.c and unzip.h */
typedef struct zlib_filefunc64_32_def_s
{
zlib_filefunc64_def zfile_func64;
open_file_func zopen32_file;
tell_file_func ztell32_file;
seek_file_func zseek32_file;
} zlib_filefunc64_32_def;
#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream))
//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode))
#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream))
#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream))
voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode));
long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin));
ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream));
void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32);
#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode)))