1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2024-11-29 22:35:45 +00:00
Aquaria/ExternalLibs/ttvfs_zip/VFSZipArchiveRef.cpp
2014-04-07 05:09:40 +02:00

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