mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2025-10-04 05:13:19 +00:00
Update ttvfs to new version
This commit is contained in:
parent
209ad526c6
commit
8026cdd905
43 changed files with 2124 additions and 2427 deletions
|
@ -6,6 +6,8 @@ set(ttvfs_zip_SRC
|
|||
VFSFileZip.h
|
||||
VFSZipArchiveLoader.cpp
|
||||
VFSZipArchiveLoader.h
|
||||
VFSZipArchiveRef.cpp
|
||||
VFSZipArchiveRef.h
|
||||
miniz.c
|
||||
miniz.h
|
||||
)
|
||||
|
|
|
@ -9,99 +9,68 @@
|
|||
VFS_NAMESPACE_START
|
||||
|
||||
|
||||
static size_t zip_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
|
||||
|
||||
ZipDir::ZipDir(ZipArchiveRef *handle, const char *fullpath, bool canLoad)
|
||||
: Dir(fullpath, NULL)
|
||||
, _archiveHandle(handle)
|
||||
, _canLoad(canLoad)
|
||||
, _couldLoad(canLoad)
|
||||
{
|
||||
VFSFile *vf = (VFSFile*)pOpaque;
|
||||
mz_int64 cur_ofs = vf->getpos();
|
||||
if((mz_int64)file_ofs < 0)
|
||||
return 0;
|
||||
if(cur_ofs != (mz_int64)file_ofs && !vf->seek((vfspos)file_ofs))
|
||||
return 0;
|
||||
return vf->read(pBuf, n);
|
||||
}
|
||||
|
||||
static bool zip_reader_init_vfsfile(mz_zip_archive *pZip, VFSFile *vf, mz_uint32 flags)
|
||||
{
|
||||
if(!(pZip || vf))
|
||||
return false;
|
||||
vf->open("rb");
|
||||
mz_uint64 file_size = vf->size();
|
||||
if(!file_size)
|
||||
{
|
||||
vf->close();
|
||||
return false;
|
||||
}
|
||||
pZip->m_pRead = zip_read_func;
|
||||
pZip->m_pIO_opaque = vf;
|
||||
if (!mz_zip_reader_init(pZip, file_size, flags))
|
||||
{
|
||||
vf->close();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
VFSDirZip::VFSDirZip(VFSFile *zf)
|
||||
: VFSDir(zf->fullname()), _zf(zf)
|
||||
{
|
||||
_zf->ref++;
|
||||
_setOrigin(this);
|
||||
memset(&_zip, 0, sizeof(_zip));
|
||||
}
|
||||
|
||||
VFSDirZip::~VFSDirZip()
|
||||
ZipDir::~ZipDir()
|
||||
{
|
||||
close();
|
||||
_zf->ref--;
|
||||
}
|
||||
|
||||
bool VFSDirZip::close(void)
|
||||
|
||||
void ZipDir::close()
|
||||
{
|
||||
mz_zip_reader_end(&_zip);
|
||||
_zf->close();
|
||||
return true;
|
||||
_archiveHandle->close();
|
||||
_canLoad = _couldLoad; // allow loading again after re-opening (in case archive was replaced)
|
||||
}
|
||||
|
||||
VFSDir *VFSDirZip::createNew(const char *dir) const
|
||||
DirBase *ZipDir::createNew(const char *fullpath) const
|
||||
{
|
||||
return VFSDir::createNew(dir); // inside a Zip file; only the base dir can be a real VFSDirZip.
|
||||
const ZipArchiveRef *czref = _archiveHandle;
|
||||
ZipArchiveRef *zref = const_cast<ZipArchiveRef*>(czref);
|
||||
return new ZipDir(zref, fullpath, false);
|
||||
}
|
||||
|
||||
unsigned int VFSDirZip::load(bool /*ignored*/)
|
||||
#define MZ ((mz_zip_archive*)_archiveHandle->mz)
|
||||
|
||||
void ZipDir::load()
|
||||
{
|
||||
close();
|
||||
if(!_canLoad)
|
||||
return;
|
||||
|
||||
if(!zip_reader_init_vfsfile(&_zip, _zf, 0))
|
||||
return 0;
|
||||
_archiveHandle->openRead();
|
||||
|
||||
unsigned int files = mz_zip_reader_get_num_files(&_zip);
|
||||
const unsigned int files = mz_zip_reader_get_num_files(MZ);
|
||||
const size_t len = fullnameLen();
|
||||
|
||||
mz_zip_archive_file_stat fs;
|
||||
for (unsigned int i = 0; i < files; ++i)
|
||||
{
|
||||
// FIXME: do we want empty dirs in the tree?
|
||||
if(mz_zip_reader_is_file_a_directory(&_zip, i))
|
||||
if(mz_zip_reader_is_file_encrypted(MZ, i))
|
||||
continue;
|
||||
if(mz_zip_reader_is_file_encrypted(&_zip, i))
|
||||
if(!mz_zip_reader_file_stat(MZ, i, &fs))
|
||||
continue;
|
||||
if(!mz_zip_reader_file_stat(&_zip, i, &fs))
|
||||
if(mz_zip_reader_is_file_a_directory(MZ, i))
|
||||
{
|
||||
getDir(fs.m_filename, true);
|
||||
continue;
|
||||
}
|
||||
if(getFile(fs.m_filename))
|
||||
continue;
|
||||
|
||||
VFSFileZip *vf = new VFSFileZip(&_zip);
|
||||
vf->_setOrigin(this);
|
||||
memcpy(vf->getZipFileStat(), &fs, sizeof(mz_zip_archive_file_stat));
|
||||
vf->_init();
|
||||
addRecursive(vf, true, VFSDir::NONE);
|
||||
vf->ref--;
|
||||
ZipFile *vf = new ZipFile(fs.m_filename, _archiveHandle, (vfspos)fs.m_uncomp_size, fs.m_file_index);
|
||||
addRecursive(vf, len);
|
||||
}
|
||||
|
||||
// Not necessary to keep open all the time, VFSFileZip will re-open the archive if needed
|
||||
//close();
|
||||
|
||||
return files;
|
||||
_canLoad = false;
|
||||
}
|
||||
|
||||
VFS_NAMESPACE_END
|
||||
|
||||
|
||||
VFS_NAMESPACE_END
|
||||
|
|
|
@ -2,31 +2,28 @@
|
|||
#define VFSDIR_ZIP_H
|
||||
|
||||
#include "VFSDir.h"
|
||||
|
||||
#include "miniz.h"
|
||||
#include "VFSZipArchiveRef.h"
|
||||
|
||||
VFS_NAMESPACE_START
|
||||
|
||||
class VFSFile;
|
||||
|
||||
class VFSDirZip : public VFSDir
|
||||
class ZipDir : public Dir
|
||||
{
|
||||
public:
|
||||
VFSDirZip(VFSFile *zf);
|
||||
virtual ~VFSDirZip();
|
||||
virtual unsigned int load(bool recusive);
|
||||
virtual VFSDir *createNew(const char *dir) const;
|
||||
virtual const char *getType() const { return "VFSDirZip"; }
|
||||
virtual bool close();
|
||||
|
||||
inline mz_zip_archive *getZip() { return &_zip; }
|
||||
ZipDir(ZipArchiveRef *handle, const char *subpath, bool canLoad);
|
||||
virtual ~ZipDir();
|
||||
virtual void load();
|
||||
virtual const char *getType() const { return "ZipDir"; }
|
||||
virtual void close();
|
||||
virtual DirBase *createNew(const char *dir) const;
|
||||
|
||||
protected:
|
||||
VFSFile *_zf;
|
||||
mz_zip_archive _zip;
|
||||
std::string zipfilename;
|
||||
CountedPtr<ZipArchiveRef> _archiveHandle;
|
||||
bool _canLoad;
|
||||
const bool _couldLoad;
|
||||
};
|
||||
|
||||
|
||||
VFS_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2,196 +2,161 @@
|
|||
#include "VFSInternal.h"
|
||||
#include "VFSTools.h"
|
||||
#include "VFSDir.h"
|
||||
#include <stdio.h>
|
||||
#include "miniz.h"
|
||||
|
||||
VFS_NAMESPACE_START
|
||||
|
||||
// From miniz.c
|
||||
//#define MZ_ZIP_MODE_READING 2
|
||||
|
||||
|
||||
static bool zip_reader_reopen_vfsfile(mz_zip_archive *pZip, mz_uint32 flags)
|
||||
ZipFile::ZipFile(const char *name, ZipArchiveRef *zref, vfspos uncompSize, unsigned int fileIdx)
|
||||
: File(joinPath(zref->fullname(), name).c_str())
|
||||
, _buf(NULL)
|
||||
, _pos(0)
|
||||
, _archiveHandle(zref)
|
||||
, _uncompSize(uncompSize)
|
||||
, _fileIdx(fileIdx)
|
||||
, _mode("rb") // binary mode by default
|
||||
{
|
||||
if(!(pZip && pZip->m_pIO_opaque && pZip->m_pRead))
|
||||
return false;
|
||||
VFSFile *vf = (VFSFile*)pZip->m_pIO_opaque;
|
||||
if(!vf->isopen())
|
||||
if(!vf->open("rb"))
|
||||
return false;
|
||||
if(pZip->m_zip_mode == MZ_ZIP_MODE_READING)
|
||||
return true;
|
||||
mz_uint64 file_size = vf->size();
|
||||
if(!file_size)
|
||||
{
|
||||
vf->close();
|
||||
return false;
|
||||
}
|
||||
if (!mz_zip_reader_init(pZip, file_size, flags))
|
||||
{
|
||||
vf->close();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ZipFile::~ZipFile()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
VFSFileZip::VFSFileZip(mz_zip_archive *zip)
|
||||
: VFSFile(NULL), _fixedStr(NULL), _zip(zip)
|
||||
bool ZipFile::open(const char *mode /* = NULL */)
|
||||
{
|
||||
_mode = "b"; // binary mode by default
|
||||
_pos = 0;
|
||||
}
|
||||
|
||||
void VFSFileZip::_init()
|
||||
{
|
||||
_setName(_zipstat.m_filename);
|
||||
}
|
||||
|
||||
VFSFileZip::~VFSFileZip()
|
||||
{
|
||||
dropBuf(true);
|
||||
}
|
||||
|
||||
bool VFSFileZip::open(const char *mode /* = NULL */)
|
||||
{
|
||||
VFS_GUARD_OPT(this);
|
||||
|
||||
_pos = 0;
|
||||
if(mode)
|
||||
if(!mode)
|
||||
mode = "rb";
|
||||
if(_mode != mode)
|
||||
{
|
||||
if(_fixedStr && _mode != mode)
|
||||
{
|
||||
delete [] _fixedStr;
|
||||
_fixedStr = NULL;
|
||||
}
|
||||
|
||||
delete [] _buf;
|
||||
_buf = NULL;
|
||||
_mode = mode;
|
||||
}
|
||||
return true; // does not have to be opened
|
||||
}
|
||||
|
||||
bool VFSFileZip::isopen(void) const
|
||||
bool ZipFile::isopen() const
|
||||
{
|
||||
return true; // is always open
|
||||
}
|
||||
|
||||
bool VFSFileZip::iseof(void) const
|
||||
bool ZipFile::iseof() const
|
||||
{
|
||||
VFS_GUARD_OPT(this);
|
||||
return _pos >= _zipstat.m_uncomp_size;
|
||||
return _pos >= _uncompSize;
|
||||
}
|
||||
|
||||
bool VFSFileZip::close(void)
|
||||
void ZipFile::close()
|
||||
{
|
||||
//return flush(); // TODO: write to zip file on close
|
||||
//flush(); // TODO: write to zip file on close
|
||||
|
||||
delete []_buf;
|
||||
_buf = NULL;
|
||||
}
|
||||
|
||||
bool ZipFile::seek(vfspos pos, int whence)
|
||||
{
|
||||
const vfspos end = 0xFFFFFFFF;
|
||||
switch(whence)
|
||||
{
|
||||
case SEEK_SET:
|
||||
if(pos >= end) // zip files have uint32 range only
|
||||
return false;
|
||||
_pos = pos;
|
||||
break;
|
||||
|
||||
case SEEK_CUR:
|
||||
if(_pos + pos >= end)
|
||||
return false;
|
||||
_pos += pos;
|
||||
break;
|
||||
|
||||
case SEEK_END:
|
||||
if(pos >= _uncompSize)
|
||||
return false;
|
||||
_pos = _uncompSize - pos;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VFSFileZip::seek(vfspos pos)
|
||||
{
|
||||
if(pos >= 0xFFFFFFFF) // zip files have uint32 range only
|
||||
return false;
|
||||
|
||||
VFS_GUARD_OPT(this);
|
||||
_pos = (unsigned int)pos;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VFSFileZip::flush(void)
|
||||
bool ZipFile::flush()
|
||||
{
|
||||
// FIXME: use this to actually write to zip file?
|
||||
return false;
|
||||
}
|
||||
|
||||
vfspos VFSFileZip::getpos(void) const
|
||||
vfspos ZipFile::getpos() const
|
||||
{
|
||||
VFS_GUARD_OPT(this);
|
||||
return _pos;
|
||||
}
|
||||
|
||||
unsigned int VFSFileZip::read(void *dst, unsigned int bytes)
|
||||
unsigned int ZipFile::read(void *dst, unsigned int bytes)
|
||||
{
|
||||
VFS_GUARD_OPT(this);
|
||||
char *mem = (char*)getBuf();
|
||||
char *startptr = mem + _pos;
|
||||
char *endptr = mem + size();
|
||||
if(!_buf && !unpack())
|
||||
return 0;
|
||||
|
||||
char *startptr = _buf + _pos;
|
||||
char *endptr = _buf + size();
|
||||
bytes = std::min((unsigned int)(endptr - startptr), bytes); // limit in case reading over buffer size
|
||||
if(_mode.find('b') == std::string::npos)
|
||||
strnNLcpy((char*)dst, (const char*)startptr, bytes); // non-binary == text mode
|
||||
else
|
||||
//if(_mode.find('b') == std::string::npos)
|
||||
// strnNLcpy((char*)dst, (const char*)startptr, bytes); // non-binary == text mode
|
||||
//else
|
||||
memcpy(dst, startptr, bytes); // binary copy
|
||||
_pos += bytes;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
unsigned int VFSFileZip::write(const void *src, unsigned int bytes)
|
||||
unsigned int ZipFile::write(const void *src, unsigned int bytes)
|
||||
{
|
||||
/*VFS_GUARD_OPT(this);
|
||||
if(getpos() + bytes >= size())
|
||||
size(getpos() + bytes); // enlarge if necessary
|
||||
// TODO: implement actually writing to the underlying Zip file.
|
||||
|
||||
memcpy(_buf + getpos(), src, bytes);
|
||||
|
||||
// TODO: implement actually writing to the Zip file.
|
||||
|
||||
return bytes;*/
|
||||
|
||||
return VFSFile::write(src, bytes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
vfspos VFSFileZip::size(void)
|
||||
vfspos ZipFile::size()
|
||||
{
|
||||
VFS_GUARD_OPT(this);
|
||||
return (vfspos)_zipstat.m_uncomp_size;
|
||||
return (vfspos)_uncompSize;
|
||||
}
|
||||
|
||||
const void *VFSFileZip::getBuf(allocator_func alloc /* = NULL */, delete_func del /* = NULL */)
|
||||
#define MZ ((mz_zip_archive*)_archiveHandle->mz)
|
||||
|
||||
bool ZipFile::unpack()
|
||||
{
|
||||
assert(!alloc == !del); // either both or none may be defined. Checked extra early to prevent possible errors later.
|
||||
delete [] _buf;
|
||||
|
||||
VFS_GUARD_OPT(this);
|
||||
// _fixedStr gets deleted on mode change, so doing this check here is fine
|
||||
if(_fixedStr)
|
||||
return _fixedStr;
|
||||
if(!_archiveHandle->openRead())
|
||||
return false; // can happen if the underlying zip file was deleted
|
||||
|
||||
// In case of text data, make sure the buffer is always terminated with '\0'.
|
||||
// Won't hurt for binary data, so just do it in all cases.
|
||||
size_t sz = (size_t)size();
|
||||
_buf = new char[sz + 1];
|
||||
if(!_buf)
|
||||
return false;
|
||||
|
||||
if(!mz_zip_reader_extract_to_mem(MZ, _fileIdx, _buf, sz, 0))
|
||||
{
|
||||
size_t sz = (size_t)size();
|
||||
_buf = allocHelperExtra(alloc, sz, 4);
|
||||
if(!_buf)
|
||||
return NULL;
|
||||
_delfunc = del;
|
||||
|
||||
if(!zip_reader_reopen_vfsfile(_zip, 0))
|
||||
return NULL; // can happen if the underlying zip file was deleted
|
||||
if(!mz_zip_reader_extract_to_mem(_zip, _zipstat.m_file_index, _buf, sz, 0))
|
||||
return NULL; // this should not happen
|
||||
|
||||
if(_mode.find("b") == std::string::npos) // text mode?
|
||||
{
|
||||
_fixedStr = allocHelperExtra(alloc, sz, 4);
|
||||
strnNLcpy(_fixedStr, (const char*)_buf);
|
||||
|
||||
// FIXME: is this really correct?
|
||||
VFSFile::dropBuf(true);
|
||||
|
||||
return _fixedStr;
|
||||
}
|
||||
|
||||
delete [] _buf;
|
||||
_buf = NULL;
|
||||
return false; // this should not happen
|
||||
}
|
||||
|
||||
return _buf;
|
||||
_buf[sz] = 0;
|
||||
if(_mode.find("b") == std::string::npos) // text mode?
|
||||
{
|
||||
_uncompSize = strnNLcpy(_buf, _buf);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void VFSFileZip::dropBuf(bool del)
|
||||
{
|
||||
VFSFile::dropBuf(del);
|
||||
|
||||
VFS_GUARD_OPT(this);
|
||||
if(del)
|
||||
delBuf(_fixedStr);
|
||||
_fixedStr = NULL;
|
||||
|
||||
}
|
||||
|
||||
VFS_NAMESPACE_END
|
||||
|
|
|
@ -2,38 +2,36 @@
|
|||
#define VFSFILE_ZIP_H
|
||||
|
||||
#include "VFSFile.h"
|
||||
#include "miniz.h"
|
||||
#include "VFSZipArchiveRef.h"
|
||||
|
||||
VFS_NAMESPACE_START
|
||||
|
||||
class VFSFileZip : public VFSFile
|
||||
class ZipFile : public File
|
||||
{
|
||||
public:
|
||||
VFSFileZip(mz_zip_archive *zip);
|
||||
virtual ~VFSFileZip();
|
||||
ZipFile(const char *name, ZipArchiveRef *zref, vfspos uncompSize, unsigned int fileIdx);
|
||||
virtual ~ZipFile();
|
||||
virtual bool open(const char *mode = NULL);
|
||||
virtual bool isopen(void) const;
|
||||
virtual bool iseof(void) const;
|
||||
virtual bool close(void);
|
||||
virtual bool seek(vfspos pos);
|
||||
virtual bool flush(void);
|
||||
virtual vfspos getpos(void) const;
|
||||
virtual bool isopen() const;
|
||||
virtual bool iseof() const;
|
||||
virtual void close();
|
||||
virtual bool seek(vfspos pos, int whence);
|
||||
virtual bool flush();
|
||||
virtual vfspos getpos() const;
|
||||
virtual unsigned int read(void *dst, unsigned int bytes);
|
||||
virtual unsigned int write(const void *src, unsigned int bytes);
|
||||
virtual vfspos size(void);
|
||||
virtual const void *getBuf(allocator_func alloc = NULL, delete_func del = NULL);
|
||||
virtual void dropBuf(bool del);
|
||||
virtual const char *getType(void) const { return "Zip"; }
|
||||
|
||||
inline mz_zip_archive_file_stat *getZipFileStat(void) { return &_zipstat; }
|
||||
void _init();
|
||||
virtual vfspos size();
|
||||
virtual const char *getType() const { return "ZipFile"; }
|
||||
|
||||
protected:
|
||||
unsigned int _pos;
|
||||
bool unpack();
|
||||
|
||||
char *_buf;
|
||||
vfspos _pos;
|
||||
CountedPtr<ZipArchiveRef> _archiveHandle;
|
||||
vfspos _uncompSize;
|
||||
unsigned int _fileIdx;
|
||||
std::string _mode;
|
||||
mz_zip_archive_file_stat _zipstat;
|
||||
mz_zip_archive *_zip;
|
||||
char *_fixedStr; // for \n fixed string in text mode. cleared when mode is changed
|
||||
};
|
||||
|
||||
VFS_NAMESPACE_END
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
#include "VFSInternal.h"
|
||||
#include "VFSZipArchiveLoader.h"
|
||||
#include "VFSDirZip.h"
|
||||
#include "VFSZipArchiveRef.h"
|
||||
|
||||
VFS_NAMESPACE_START
|
||||
|
||||
VFSDir *VFSZipArchiveLoader::Load(VFSFile *arch, VFSLoader ** /*unused*/, void * /*unused*/)
|
||||
Dir *VFSZipArchiveLoader::Load(File *arch, VFSLoader ** /*unused*/, void * /*unused*/)
|
||||
{
|
||||
VFSDirZip *vd = new VFSDirZip(arch);
|
||||
if(vd->load(true))
|
||||
return vd;
|
||||
|
||||
vd->ref--;
|
||||
return NULL;
|
||||
CountedPtr<ZipArchiveRef> zref = new ZipArchiveRef(arch);
|
||||
if(!zref->init() || !zref->openRead())
|
||||
return NULL;
|
||||
ZipDir *vd = new ZipDir(zref, arch->fullname(), true);
|
||||
vd->load();
|
||||
return vd;
|
||||
}
|
||||
|
||||
VFS_NAMESPACE_END
|
||||
|
|
|
@ -5,11 +5,12 @@
|
|||
|
||||
VFS_NAMESPACE_START
|
||||
|
||||
|
||||
class VFSZipArchiveLoader : public VFSArchiveLoader
|
||||
{
|
||||
public:
|
||||
virtual ~VFSZipArchiveLoader() {}
|
||||
virtual VFSDir *Load(VFSFile *arch, VFSLoader **ldr, void *opaque = NULL);
|
||||
virtual Dir *Load(File *arch, VFSLoader **ldr, void *opaque = NULL);
|
||||
};
|
||||
|
||||
VFS_NAMESPACE_END
|
||||
|
|
121
ExternalLibs/ttvfs_zip/VFSZipArchiveRef.cpp
Normal file
121
ExternalLibs/ttvfs_zip/VFSZipArchiveRef.cpp
Normal file
|
@ -0,0 +1,121 @@
|
|||
#include "VFSZipArchiveRef.h"
|
||||
#include "miniz.h"
|
||||
|
||||
|
||||
VFS_NAMESPACE_START
|
||||
|
||||
|
||||
static size_t zip_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
|
||||
{
|
||||
File *vf = (File*)pOpaque;
|
||||
mz_int64 cur_ofs = vf->getpos();
|
||||
if((mz_int64)file_ofs < 0)
|
||||
return 0;
|
||||
if(cur_ofs != (mz_int64)file_ofs && !vf->seek((vfspos)file_ofs, SEEK_SET))
|
||||
return 0;
|
||||
return vf->read(pBuf, n);
|
||||
}
|
||||
|
||||
static bool zip_reader_init_vfsfile(mz_zip_archive *pZip, File *vf, mz_uint32 flags)
|
||||
{
|
||||
mz_uint64 file_size = vf->size();
|
||||
if(!file_size || !vf->open("rb"))
|
||||
{
|
||||
vf->close();
|
||||
return false;
|
||||
}
|
||||
pZip->m_pRead = zip_read_func;
|
||||
pZip->m_pIO_opaque = vf;
|
||||
if (!mz_zip_reader_init(pZip, file_size, flags))
|
||||
{
|
||||
vf->close();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool zip_reader_reopen_vfsfile(mz_zip_archive *pZip, mz_uint32 flags)
|
||||
{
|
||||
if(!(pZip && pZip->m_pIO_opaque && pZip->m_pRead))
|
||||
return false;
|
||||
File *vf = (File*)pZip->m_pIO_opaque;
|
||||
mz_uint64 file_size = vf->size();
|
||||
if(!file_size)
|
||||
{
|
||||
vf->close();
|
||||
return false;
|
||||
}
|
||||
if(!vf->isopen())
|
||||
if(!vf->open("rb"))
|
||||
return false;
|
||||
if(pZip->m_zip_mode == MZ_ZIP_MODE_READING)
|
||||
return true;
|
||||
if (!mz_zip_reader_init(pZip, file_size, flags))
|
||||
{
|
||||
vf->close();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
ZipArchiveRef::ZipArchiveRef(File *file)
|
||||
: archiveFile(file)
|
||||
{
|
||||
mz = new mz_zip_archive;
|
||||
memset(mz, 0, sizeof(mz_zip_archive));
|
||||
}
|
||||
|
||||
#define MZ ((mz_zip_archive*)mz)
|
||||
|
||||
ZipArchiveRef::~ZipArchiveRef()
|
||||
{
|
||||
close();
|
||||
delete MZ;
|
||||
}
|
||||
|
||||
bool ZipArchiveRef::init()
|
||||
{
|
||||
return zip_reader_init_vfsfile(MZ, archiveFile, 0);
|
||||
}
|
||||
|
||||
bool ZipArchiveRef::openRead()
|
||||
{
|
||||
return zip_reader_reopen_vfsfile(MZ, 0);
|
||||
}
|
||||
|
||||
void ZipArchiveRef::close()
|
||||
{
|
||||
switch(MZ->m_zip_mode)
|
||||
{
|
||||
case MZ_ZIP_MODE_READING:
|
||||
mz_zip_reader_end(MZ);
|
||||
break;
|
||||
|
||||
case MZ_ZIP_MODE_WRITING:
|
||||
mz_zip_writer_finalize_archive(MZ);
|
||||
mz_zip_writer_end(MZ);
|
||||
break;
|
||||
|
||||
case MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED:
|
||||
mz_zip_writer_end(MZ);
|
||||
break;
|
||||
|
||||
case MZ_ZIP_MODE_INVALID:
|
||||
break; // nothing to do
|
||||
}
|
||||
|
||||
archiveFile->close();
|
||||
}
|
||||
|
||||
const char *ZipArchiveRef::fullname() const
|
||||
{
|
||||
return archiveFile->fullname();
|
||||
}
|
||||
|
||||
|
||||
|
||||
VFS_NAMESPACE_END
|
||||
|
28
ExternalLibs/ttvfs_zip/VFSZipArchiveRef.h
Normal file
28
ExternalLibs/ttvfs_zip/VFSZipArchiveRef.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef VFS_ZIP_ARCHIVE_REF
|
||||
#define VFS_ZIP_ARCHIVE_REF
|
||||
|
||||
#include "VFSFile.h"
|
||||
|
||||
|
||||
VFS_NAMESPACE_START
|
||||
|
||||
class ZipArchiveRef : public Refcounted
|
||||
{
|
||||
public:
|
||||
ZipArchiveRef(File *archive);
|
||||
~ZipArchiveRef();
|
||||
bool openRead();
|
||||
void close();
|
||||
bool init();
|
||||
void *mz;
|
||||
const char *fullname() const;
|
||||
|
||||
protected:
|
||||
CountedPtr<File> archiveFile;
|
||||
};
|
||||
|
||||
|
||||
VFS_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue