211 lines
8.1 KiB
C++
211 lines
8.1 KiB
C++
/**************************************************************************************/
|
|
/* */
|
|
/* Visualization Library */
|
|
/* http://visualizationlibrary.org */
|
|
/* */
|
|
/* Copyright (c) 2005-2020, Michele Bosi */
|
|
/* All rights reserved. */
|
|
/* */
|
|
/* Redistribution and use in source and binary forms, with or without modification, */
|
|
/* are permitted provided that the following conditions are met: */
|
|
/* */
|
|
/* - Redistributions of source code must retain the above copyright notice, this */
|
|
/* list of conditions and the following disclaimer. */
|
|
/* */
|
|
/* - Redistributions in binary form must reproduce the above copyright notice, this */
|
|
/* list of conditions and the following disclaimer in the documentation and/or */
|
|
/* other materials provided with the distribution. */
|
|
/* */
|
|
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
|
|
/* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
|
|
/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
|
|
/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
|
|
/* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
|
|
/* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
|
|
/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
|
|
/* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
|
|
/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
|
|
/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
|
|
/* */
|
|
/**************************************************************************************/
|
|
|
|
#ifndef ZippedFile_INCLUDE_ONCE
|
|
#define ZippedFile_INCLUDE_ONCE
|
|
|
|
#include <vlCore/VirtualFile.hpp>
|
|
struct z_stream_s;
|
|
|
|
namespace vl
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
// ZippedFileInfo
|
|
//---------------------------------------------------------------------------
|
|
/**
|
|
* Collects the information about a ZippedFile.
|
|
*/
|
|
class ZippedFileInfo: public Object
|
|
{
|
|
friend class ZippedFile;
|
|
friend class ZippedDirectory;
|
|
|
|
VL_INSTRUMENT_CLASS(vl::ZippedFileInfo, Object)
|
|
|
|
public:
|
|
ZippedFileInfo()
|
|
{
|
|
mVersionNeeded = 0;
|
|
mGeneralPurposeFlag = 0;
|
|
mCompressionMethod = 0;
|
|
mCRC32 = 0;
|
|
mCompressedSize = 0;
|
|
mUncompressedSize = 0;
|
|
mFileNameLength = 0;
|
|
mExtraFieldLength = 0;
|
|
mSecond = 0;
|
|
mMinute = 0;
|
|
mHour = 0;
|
|
mDay = 0;
|
|
mMonth = 0;
|
|
mYear = 0;
|
|
mZippedFileOffset = 0;
|
|
}
|
|
|
|
public:
|
|
unsigned short versionNeeded() const { return mVersionNeeded; }
|
|
unsigned short generalPurposeFlag() const { return mGeneralPurposeFlag; }
|
|
unsigned short compressionMethod() const { return mCompressionMethod; }
|
|
unsigned int crc32() const { return mCRC32; }
|
|
unsigned int compressedSize() const { return mCompressedSize; }
|
|
unsigned int uncompressedSize() const { return mUncompressedSize; }
|
|
unsigned short fileNameLength() const { return mFileNameLength; }
|
|
unsigned short extraFieldLength() const { return mExtraFieldLength; }
|
|
int second() const { return mSecond; }
|
|
int minute() const { return mMinute; }
|
|
int hour() const { return mHour; }
|
|
int day() const { return mDay; }
|
|
int month() const { return mMonth; }
|
|
int year() const { return mYear; }
|
|
const String& path() const { return mFileName; }
|
|
// offset of the compressed data in the source zip file
|
|
unsigned int zippedFileOffset() const { return mZippedFileOffset; }
|
|
// source stream used to seek and read the compressed zip data
|
|
const VirtualFile* sourceZipFile() const { return mSourceZipFile.get(); }
|
|
VirtualFile* sourceZipFile() { return mSourceZipFile.get(); }
|
|
void setSourceZipFile(VirtualFile* file) { mSourceZipFile = file; }
|
|
|
|
public:
|
|
unsigned short mVersionNeeded;
|
|
unsigned short mGeneralPurposeFlag;
|
|
unsigned short mCompressionMethod;
|
|
unsigned int mCRC32;
|
|
unsigned int mCompressedSize;
|
|
unsigned int mUncompressedSize;
|
|
unsigned short mFileNameLength;
|
|
unsigned short mExtraFieldLength;
|
|
int mSecond;
|
|
int mMinute;
|
|
int mHour;
|
|
int mDay;
|
|
int mMonth;
|
|
int mYear;
|
|
String mFileName;
|
|
// offset of the compressed data in the zip file
|
|
unsigned int mZippedFileOffset;
|
|
// source stream used to seek and read the compressed zip data
|
|
ref<VirtualFile> mSourceZipFile;
|
|
};
|
|
//---------------------------------------------------------------------------
|
|
// ZippedFile
|
|
//---------------------------------------------------------------------------
|
|
/**
|
|
* A VirtualFile used to read a file contained in a .zip archive.
|
|
*
|
|
* \sa
|
|
* - VirtualDirectory
|
|
* - DiskDirectory
|
|
* - MemoryDirectory
|
|
* - ZippedDirectory
|
|
* - FileSystem
|
|
* - VirtualFile
|
|
* - DiskFile
|
|
* - MemoryFile
|
|
*/
|
|
class VLCORE_EXPORT ZippedFile: public VirtualFile
|
|
{
|
|
VL_INSTRUMENT_CLASS(vl::ZippedFile, VirtualFile)
|
|
|
|
// Lower this if you need to limit the amount of data allocated to the stack, for example to 16K.
|
|
static const int CHUNK_SIZE = 128*1024;
|
|
|
|
public:
|
|
|
|
ZippedFile();
|
|
~ZippedFile();
|
|
|
|
const ZippedFileInfo* zippedFileInfo() const;
|
|
|
|
ZippedFileInfo* zippedFileInfo();
|
|
|
|
void setZippedFileInfo(ZippedFileInfo* info);
|
|
|
|
//! This returns true if zippedFileInfo() has been properly set up but does not check
|
|
//! the existence of this file in the source zip file. To do so call ZippedDirectory::exists().
|
|
virtual bool exists() const;
|
|
|
|
virtual bool open(EOpenMode mode);
|
|
|
|
virtual bool isOpen() const;
|
|
|
|
virtual void close();
|
|
|
|
virtual long long size() const;
|
|
|
|
bool extract(char* destination, bool check_sum = true);
|
|
|
|
ZippedFile& operator=(const ZippedFile& other)
|
|
{
|
|
close();
|
|
super::operator=(other);
|
|
mZippedFileInfo = new ZippedFileInfo(*other.mZippedFileInfo);
|
|
if (mZippedFileInfo->sourceZipFile())
|
|
{
|
|
ref<VirtualFile> src_zip_copy = mZippedFileInfo->sourceZipFile()->clone();
|
|
mZippedFileInfo->setSourceZipFile(src_zip_copy.get());
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
virtual ref<VirtualFile> clone() const;
|
|
|
|
void resetStream();
|
|
|
|
protected:
|
|
virtual long long read_Implementation(void* buffer, long long bytes_to_read);
|
|
|
|
virtual long long write_Implementation(const void* /*buffer*/, long long /*byte_count*/) { return 0; } // not supported yet
|
|
|
|
virtual bool fillUncompressedBuffer();
|
|
|
|
virtual long long position_Implementation() const { return mReadBytes; }
|
|
|
|
virtual bool seekSet_Implementation(long long);
|
|
|
|
protected:
|
|
ref<ZippedFileInfo> mZippedFileInfo;
|
|
long long mReadBytes;
|
|
|
|
z_stream_s* mZStream;
|
|
unsigned char mZipBufferIn[CHUNK_SIZE];
|
|
unsigned char mZipBufferOut[CHUNK_SIZE];
|
|
std::vector<char> mUncompressedBuffer;
|
|
int mUncompressedBufferPtr;
|
|
};
|
|
//---------------------------------------------------------------------------
|
|
// utilty functions
|
|
bool compress(const void* data, size_t size, std::vector<unsigned char>& out, int level);
|
|
bool decompress(const void* cdata, size_t csize, void* data_out);
|
|
//---------------------------------------------------------------------------
|
|
}
|
|
|
|
#endif
|