2015-08-11 13:44:47 +02:00
|
|
|
/*
|
|
|
|
* MinizipExtensions.cpp, part of VCMI engine
|
|
|
|
*
|
|
|
|
* Authors: listed in file AUTHORS in main folder
|
|
|
|
*
|
|
|
|
* License: GNU General Public License v2.0 or later
|
|
|
|
* Full text of license available in license.txt file, in main folder
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
#include "StdInc.h"
|
|
|
|
#include "MinizipExtensions.h"
|
|
|
|
|
2015-08-11 20:20:13 +02:00
|
|
|
#include "CMemoryBuffer.h"
|
2016-02-05 08:28:36 +02:00
|
|
|
#include "FileStream.h"
|
2015-08-11 20:20:13 +02:00
|
|
|
|
2022-07-26 15:07:42 +02:00
|
|
|
VCMI_LIB_NAMESPACE_BEGIN
|
|
|
|
|
2023-02-15 00:09:07 +02:00
|
|
|
template<class Stream>
|
|
|
|
inline uLong streamRead(voidpf opaque, voidpf stream, void * buf, uLong size)
|
2015-08-11 13:44:47 +02:00
|
|
|
{
|
|
|
|
assert(opaque != nullptr);
|
|
|
|
assert(stream != nullptr);
|
2016-02-05 08:28:36 +02:00
|
|
|
|
2023-02-15 00:09:07 +02:00
|
|
|
auto * actualStream = static_cast<Stream *>(stream);
|
2016-02-05 08:28:36 +02:00
|
|
|
|
2023-02-15 00:09:07 +02:00
|
|
|
return static_cast<uLong>(actualStream->read(static_cast<ui8 *>(buf), size));
|
2015-08-11 13:44:47 +02:00
|
|
|
}
|
|
|
|
|
2023-02-15 00:09:07 +02:00
|
|
|
template<class Stream>
|
|
|
|
inline ZPOS64_T streamTell(voidpf opaque, voidpf stream)
|
2015-08-11 13:44:47 +02:00
|
|
|
{
|
|
|
|
assert(opaque != nullptr);
|
|
|
|
assert(stream != nullptr);
|
2016-02-05 08:28:36 +02:00
|
|
|
|
2023-02-15 00:09:07 +02:00
|
|
|
auto * actualStream = static_cast<Stream *>(stream);
|
|
|
|
return actualStream->tell();
|
2015-08-11 13:44:47 +02:00
|
|
|
}
|
|
|
|
|
2023-02-15 00:09:07 +02:00
|
|
|
template<class Stream>
|
|
|
|
inline long streamSeek(voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)
|
2015-08-11 13:44:47 +02:00
|
|
|
{
|
|
|
|
assert(opaque != nullptr);
|
|
|
|
assert(stream != nullptr);
|
2016-02-05 08:28:36 +02:00
|
|
|
|
2023-02-15 00:09:07 +02:00
|
|
|
auto * actualStream = static_cast<Stream *>(stream);
|
2015-08-11 13:44:47 +02:00
|
|
|
|
2023-02-15 00:09:07 +02:00
|
|
|
long ret = 0;
|
|
|
|
switch(origin)
|
|
|
|
{
|
|
|
|
case ZLIB_FILEFUNC_SEEK_CUR:
|
|
|
|
if(actualStream->skip(offset) != offset)
|
|
|
|
ret = -1;
|
|
|
|
break;
|
|
|
|
case ZLIB_FILEFUNC_SEEK_END:
|
|
|
|
{
|
|
|
|
const si64 pos = actualStream->getSize() - offset;
|
|
|
|
if(actualStream->seek(pos) != pos)
|
|
|
|
ret = -1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ZLIB_FILEFUNC_SEEK_SET:
|
|
|
|
if(actualStream->seek(offset) != offset)
|
2015-08-13 23:16:31 +02:00
|
|
|
ret = -1;
|
2023-02-15 00:09:07 +02:00
|
|
|
break;
|
|
|
|
default:
|
2015-08-13 23:16:31 +02:00
|
|
|
ret = -1;
|
2023-02-15 00:09:07 +02:00
|
|
|
}
|
|
|
|
if(ret == -1)
|
2016-02-10 06:28:00 +02:00
|
|
|
logGlobal->error("Stream seek failed");
|
2023-04-20 17:21:37 +02:00
|
|
|
return 0;
|
2015-08-11 13:44:47 +02:00
|
|
|
}
|
|
|
|
|
2023-02-15 00:09:07 +02:00
|
|
|
template<class Stream>
|
|
|
|
inline int streamProxyClose(voidpf opaque, voidpf stream)
|
2015-08-11 13:44:47 +02:00
|
|
|
{
|
|
|
|
assert(opaque != nullptr);
|
|
|
|
assert(stream != nullptr);
|
2016-02-05 08:28:36 +02:00
|
|
|
|
2023-02-15 00:09:07 +02:00
|
|
|
auto * actualStream = static_cast<Stream *>(stream);
|
2016-02-10 06:28:00 +02:00
|
|
|
|
2017-08-10 18:39:27 +02:00
|
|
|
logGlobal->trace("Proxy stream closed");
|
2016-02-05 08:28:36 +02:00
|
|
|
|
2016-02-10 06:28:00 +02:00
|
|
|
actualStream->seek(0);
|
2016-02-05 08:28:36 +02:00
|
|
|
|
2015-08-11 13:44:47 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-02-10 06:28:00 +02:00
|
|
|
///CDefaultIOApi
|
|
|
|
|
|
|
|
zlib_filefunc64_def CDefaultIOApi::getApiStructure()
|
|
|
|
{
|
|
|
|
return * FileStream::GetMinizipFilefunc();
|
|
|
|
}
|
|
|
|
|
|
|
|
///CProxyIOApi
|
|
|
|
CProxyIOApi::CProxyIOApi(CInputOutputStream * buffer):
|
|
|
|
data(buffer)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
2023-02-15 00:09:07 +02:00
|
|
|
//must be instantiated in .cpp file for access to complete types of all member fields
|
|
|
|
CProxyIOApi::~CProxyIOApi() = default;
|
2016-02-10 06:28:00 +02:00
|
|
|
|
|
|
|
zlib_filefunc64_def CProxyIOApi::getApiStructure()
|
2015-08-11 13:44:47 +02:00
|
|
|
{
|
2015-08-11 15:56:07 +02:00
|
|
|
zlib_filefunc64_def api;
|
2016-02-10 06:28:00 +02:00
|
|
|
api.opaque = this;
|
2015-08-11 13:44:47 +02:00
|
|
|
api.zopen64_file = &openFileProxy;
|
|
|
|
api.zread_file = &readFileProxy;
|
|
|
|
api.zwrite_file = &writeFileProxy;
|
|
|
|
api.ztell64_file = &tellFileProxy;
|
|
|
|
api.zseek64_file = &seekFileProxy;
|
|
|
|
api.zclose_file = &closeFileProxy;
|
2016-02-05 08:28:36 +02:00
|
|
|
api.zerror_file = &errorFileProxy;
|
|
|
|
|
2015-08-11 15:56:07 +02:00
|
|
|
return api;
|
|
|
|
}
|
|
|
|
|
2016-02-10 06:28:00 +02:00
|
|
|
voidpf ZCALLBACK CProxyIOApi::openFileProxy(voidpf opaque, const void * filename, int mode)
|
2015-08-11 20:20:13 +02:00
|
|
|
{
|
2016-02-10 06:28:00 +02:00
|
|
|
assert(opaque != nullptr);
|
|
|
|
|
|
|
|
boost::filesystem::path path;
|
|
|
|
|
|
|
|
if(filename != nullptr)
|
|
|
|
path = static_cast<const boost::filesystem::path::value_type *>(filename);
|
|
|
|
|
2023-02-15 00:09:07 +02:00
|
|
|
return (static_cast<CProxyIOApi *>(opaque))->openFile(path, mode);
|
2015-08-11 20:20:13 +02:00
|
|
|
}
|
|
|
|
|
2016-02-10 06:28:00 +02:00
|
|
|
uLong ZCALLBACK CProxyIOApi::readFileProxy(voidpf opaque, voidpf stream, void * buf, uLong size)
|
2015-08-11 15:56:07 +02:00
|
|
|
{
|
2016-02-10 06:28:00 +02:00
|
|
|
return streamRead<CInputOutputStream>(opaque, stream, buf, size);
|
|
|
|
}
|
2016-02-05 08:28:36 +02:00
|
|
|
|
2016-02-10 06:28:00 +02:00
|
|
|
uLong ZCALLBACK CProxyIOApi::writeFileProxy(voidpf opaque, voidpf stream, const void * buf, uLong size)
|
|
|
|
{
|
|
|
|
assert(opaque != nullptr);
|
|
|
|
assert(stream != nullptr);
|
|
|
|
|
2023-02-15 00:09:07 +02:00
|
|
|
auto * actualStream = static_cast<CInputOutputStream *>(stream);
|
|
|
|
return static_cast<uLong>(actualStream->write(static_cast<const ui8 *>(buf), size));
|
2015-08-11 15:56:07 +02:00
|
|
|
}
|
|
|
|
|
2016-02-10 06:28:00 +02:00
|
|
|
ZPOS64_T ZCALLBACK CProxyIOApi::tellFileProxy(voidpf opaque, voidpf stream)
|
2015-08-11 15:56:07 +02:00
|
|
|
{
|
2016-02-10 06:28:00 +02:00
|
|
|
return streamTell<CInputOutputStream>(opaque, stream);
|
|
|
|
}
|
2016-02-05 08:28:36 +02:00
|
|
|
|
2016-02-10 06:28:00 +02:00
|
|
|
long ZCALLBACK CProxyIOApi::seekFileProxy(voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)
|
|
|
|
{
|
|
|
|
return streamSeek<CInputOutputStream>(opaque, stream, offset, origin);
|
2015-08-11 15:56:07 +02:00
|
|
|
}
|
|
|
|
|
2016-02-10 06:28:00 +02:00
|
|
|
int ZCALLBACK CProxyIOApi::closeFileProxy(voidpf opaque, voidpf stream)
|
2015-08-11 15:56:07 +02:00
|
|
|
{
|
2016-02-10 06:28:00 +02:00
|
|
|
return streamProxyClose<CInputOutputStream>(opaque, stream);
|
2015-08-11 15:56:07 +02:00
|
|
|
}
|
|
|
|
|
2016-02-10 06:28:00 +02:00
|
|
|
int ZCALLBACK CProxyIOApi::errorFileProxy(voidpf opaque, voidpf stream)
|
2015-08-11 15:56:07 +02:00
|
|
|
{
|
2016-02-10 06:28:00 +02:00
|
|
|
return 0;
|
2015-08-11 15:56:07 +02:00
|
|
|
}
|
|
|
|
|
2016-02-10 06:28:00 +02:00
|
|
|
CInputOutputStream * CProxyIOApi::openFile(const boost::filesystem::path & filename, int mode)
|
|
|
|
{
|
2017-08-11 19:03:05 +02:00
|
|
|
logGlobal->trace("CProxyIOApi: stream opened for %s with mode %d", filename.string(), mode);
|
2016-02-10 06:28:00 +02:00
|
|
|
|
|
|
|
data->seek(0);
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
///CProxyROIOApi
|
|
|
|
CProxyROIOApi::CProxyROIOApi(CInputStream * buffer):
|
2015-08-11 20:20:13 +02:00
|
|
|
data(buffer)
|
2015-08-11 15:56:07 +02:00
|
|
|
{
|
2016-02-05 08:28:36 +02:00
|
|
|
|
2015-08-11 13:44:47 +02:00
|
|
|
}
|
|
|
|
|
2023-02-15 00:09:07 +02:00
|
|
|
//must be instantiated in .cpp file for access to complete types of all member fields
|
|
|
|
CProxyROIOApi::~CProxyROIOApi() = default;
|
2016-02-10 06:28:00 +02:00
|
|
|
|
|
|
|
zlib_filefunc64_def CProxyROIOApi::getApiStructure()
|
2015-08-11 15:56:07 +02:00
|
|
|
{
|
2016-02-10 06:28:00 +02:00
|
|
|
zlib_filefunc64_def api;
|
|
|
|
api.opaque = this;
|
|
|
|
api.zopen64_file = &openFileProxy;
|
|
|
|
api.zread_file = &readFileProxy;
|
|
|
|
api.zwrite_file = &writeFileProxy;
|
|
|
|
api.ztell64_file = &tellFileProxy;
|
|
|
|
api.zseek64_file = &seekFileProxy;
|
|
|
|
api.zclose_file = &closeFileProxy;
|
|
|
|
api.zerror_file = &errorFileProxy;
|
2016-02-05 08:28:36 +02:00
|
|
|
|
2016-02-10 06:28:00 +02:00
|
|
|
return api;
|
2015-08-11 15:56:07 +02:00
|
|
|
}
|
2015-08-11 20:20:13 +02:00
|
|
|
|
2016-02-10 06:28:00 +02:00
|
|
|
CInputStream * CProxyROIOApi::openFile(const boost::filesystem::path& filename, int mode)
|
2015-08-11 20:20:13 +02:00
|
|
|
{
|
2017-08-11 19:03:05 +02:00
|
|
|
logGlobal->trace("CProxyROIOApi: stream opened for %s with mode %d", filename.string(), mode);
|
2016-02-05 08:28:36 +02:00
|
|
|
|
2015-08-11 20:20:13 +02:00
|
|
|
data->seek(0);
|
2015-08-18 00:56:16 +02:00
|
|
|
return data;
|
2015-08-11 20:20:13 +02:00
|
|
|
}
|
|
|
|
|
2016-02-10 06:28:00 +02:00
|
|
|
voidpf ZCALLBACK CProxyROIOApi::openFileProxy(voidpf opaque, const void* filename, int mode)
|
|
|
|
{
|
|
|
|
assert(opaque != nullptr);
|
|
|
|
|
|
|
|
boost::filesystem::path path;
|
|
|
|
|
|
|
|
if(filename != nullptr)
|
|
|
|
path = static_cast<const boost::filesystem::path::value_type *>(filename);
|
|
|
|
|
2023-02-15 00:09:07 +02:00
|
|
|
return (static_cast<CProxyROIOApi *>(opaque))->openFile(path, mode);
|
2016-02-10 06:28:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
uLong ZCALLBACK CProxyROIOApi::readFileProxy(voidpf opaque, voidpf stream, void * buf, uLong size)
|
|
|
|
{
|
|
|
|
return streamRead<CInputStream>(opaque, stream, buf, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
uLong ZCALLBACK CProxyROIOApi::writeFileProxy(voidpf opaque, voidpf stream, const void* buf, uLong size)
|
|
|
|
{
|
2017-08-10 18:39:27 +02:00
|
|
|
logGlobal->error("Attempt to write to read-only stream");
|
2016-02-10 06:28:00 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
ZPOS64_T ZCALLBACK CProxyROIOApi::tellFileProxy(voidpf opaque, voidpf stream)
|
|
|
|
{
|
|
|
|
return streamTell<CInputStream>(opaque, stream);
|
|
|
|
}
|
|
|
|
|
|
|
|
long ZCALLBACK CProxyROIOApi::seekFileProxy(voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)
|
|
|
|
{
|
|
|
|
return streamSeek<CInputStream>(opaque, stream, offset, origin);
|
|
|
|
}
|
|
|
|
|
|
|
|
int ZCALLBACK CProxyROIOApi::closeFileProxy(voidpf opaque, voidpf stream)
|
|
|
|
{
|
|
|
|
return streamProxyClose<CInputStream>(opaque, stream);
|
|
|
|
}
|
|
|
|
|
|
|
|
int ZCALLBACK CProxyROIOApi::errorFileProxy(voidpf opaque, voidpf stream)
|
2015-08-11 20:20:13 +02:00
|
|
|
{
|
2016-02-10 06:28:00 +02:00
|
|
|
return 0;
|
2015-08-11 20:20:13 +02:00
|
|
|
}
|
2022-07-26 15:07:42 +02:00
|
|
|
|
|
|
|
VCMI_LIB_NAMESPACE_END
|