mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2024-11-16 14:50:01 +00:00
123 lines
2.4 KiB
C++
123 lines
2.4 KiB
C++
#include "VFSInternal.h"
|
|
#include "VFSZipArchiveRef.h"
|
|
#include <stdio.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
|
|
|