Torque2D Reference
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Classes | Public Types | Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
ZipArchive Class Reference

Class for accessing Zip files. More...

#include <zipArchive.h>

Classes

struct  ZipEntry
 

Public Types

enum  AccessMode { Read = FileStream::Read, Write = FileStream::Write, ReadWrite = FileStream::ReadWrite }
 Access modes for zip files and files within the zip. More...
 

Public Member Functions

 ZipArchive ()
 
virtual ~ZipArchive ()
 
Miscellaneous Methods
void setFilename (const char *filename)
 Set the filename of the zip file. More...
 
const char * getFilename ()
 Get the filename of the zip file. More...
 
bool isVerbose ()
 Determine if the Zip code is in verbose mode. More...
 
void setVerbose (bool verbose)
 Turn verbose mode on or off. More...
 
Archive Access Methods
virtual bool openArchive (const char *filename, AccessMode mode=Read)
 Open a zip archive from a file. More...
 
virtual bool openArchive (Stream *stream, AccessMode mode=Read)
 Open a zip archive from a stream. More...
 
virtual void closeArchive ()
 Close the zip archive and free any resources. More...
 
Stream Based File Access Methods
virtual StreamopenFile (const char *filename, AccessMode mode=Read)
 Open a file within the zip file. More...
 
virtual void closeFile (Stream *stream)
 Close a file opened through openFile() More...
 
StreamopenFileForRead (const CentralDir *fileCD)
 Open a file within the zip file for read. More...
 
Archiver Style File Access Methods
bool addFile (const char *filename, const char *pathInZip, bool replace=true)
 Add a file to the zip. More...
 
bool extractFile (const char *pathInZip, const char *filename, bool *crcFail=NULL)
 Extract a file from the zip. More...
 
bool deleteFile (const char *filename)
 Delete a file from the zip. More...
 
Enumeration Methods
U32 numEntries () const
 Get number of entries in the central directory. More...
 
const CentralDiroperator[] (const U32 idx) const
 
CentralDirfindFileInfo (const char *filename)
 Find a file in the zip. More...
 

Protected Member Functions

bool readCentralDirectory ()
 
void insertEntry (ZipEntry *ze)
 
void removeEntry (ZipEntry *ze)
 
ZipEntryfindZipEntry (const char *filename)
 
StreamcreateNewFile (const char *filename, Compressor *method)
 
StreamcreateNewFile (const char *filename, const char *method)
 
StreamcreateNewFile (const char *filename, S32 method)
 
void updateFile (ZipTempStream *stream)
 
bool rebuildZip ()
 
bool copyFileToNewZip (CentralDir *cdir, Stream *newZipStream)
 
bool writeDirtyFileToNewZip (ZipTempStream *fileStream, Stream *zipStream)
 
U32 localTimeToDOSTime (const Platform::LocalTime &t)
 
U32 currentTimeToDOSTime ()
 

Protected Attributes

StreammStream
 
FileStreammDiskStream
 
AccessMode mMode
 
EndOfCentralDir mEOCD
 
ZipEntrymRoot
 
VectorPtr< ZipEntry * > mEntries
 
const char * mFilename
 
VectorPtr< ZipTempStream * > mTempFiles
 

Detailed Description

Class for accessing Zip files.

ZipArchive provides two interfaces for reading or writing zip files. The first is a stream based interface that should be familiar to anyone who's ever written code, and the other is an archiver interface that should be familiar to anyone who's ever used a standard Zip application.

The two interfaces are not mutually exclusive so you can use both if you wish. For example, you may want to use the stream interface to add a configuration file to a zip without having to create a temporary file and then add a number of existing files using the addFile() method.

Both interfaces have their advantages and disadvantages, which will be discussed below.

Accessing a Zip file

Before you can access any files in the zip, you first need to open the archive. This is the same regardless of which interface you use, and there are two ways to accomplish it.

Opening from a file on the file system

The simplest method of opening a zip file is to use openArchive(const char *, AccessMode) to open a file that is on the disk.

When opening a zip file on the file system, the filename is automatically set.

Opening a file from a stream

A more advanced way to open the zip file is from an arbitrary stream. The only requirements are that the stream supports seeking and was opened with the correct access mode. Use the openArchive(Stream *, AccessMode) method to do this.

Opening zip files from arbitrary streams is a very powerful feature and opens many interesting doors. For example, combined with some small changes to the resource manager and startup code, it was possible to implement a VFS that allows the entire game to run from a single executable with no external files.

Note that the filename is not automatically set when you open the zip file from a stream. The filename is used in error reporting and by the resource manager, so you may wish to set it to something meaningful.

Regardless of which method you use to open the file, the AccessMode controls what you can do with it. If you open the archive as ReadWrite, you can both write to and read from files in the zip. However, it is not possible to open files in the zip as ReadWrite.

Closing the zip file

When you are done with the zip file, call closeArchive() to free any resources and rebuild the zip file if it was open for Write.

Example

if(za.openArchive("filename.zip", ZipArchive::Read))
{
// ... do stuff ...
}

Archiver Interface

The archiver style interface allows you to add, extract and delete files in the zip in a way similar to that of an standard archiver application.

While the archiver interface is simple to use, it is blocking and thus difficult to use asynchronously. If you require zip file support and responsive UI then you should consider using the stream interface instead.

See the following method documentation for more information:

Example

if(za.openArchive("filename.zip", ZipArchive::ReadWrite))
{
// Extract a file
za.extractFile("test.txt", "test.txt");
// Add a file
za.addFile("test.txt", "test.txt");
// Delete a file
za.deleteFile("test.txt");
}

Stream Interface

The stream based interface allows you to access files within the zip in a similar way to accessing the file system through the ResourceManager.

There are a few small caveats to the stream interface:

See the following method documentation for more information:

CRC Checking

Unlike the archiver interface, there is no automatic CRC checking when reading from files using the stream interface. If you will only be reading files sequentially, see the documentation for ZipStatFilter for a useful trick to get easy CRC checking.

Example

if(za.openArchive("filename.zip", ZipArchive::Write))
{
// Write to the file
Stream *stream;
if(stream = za.openFile("test.txt", ZipArchive::Write))
{
stream->writeLine((U8 *)"Hello, Zipped World!");
za.closeFile(stream);
}
}

Compressed Files

The zip code included with stock Torque supports "stored" (uncompressed) files and deflate compressed files. The code is easily extensible to support any compression format that the Zip file format supports.

In addition to the deflate and stored formats, BZip2 is supported but not included with stock Torque. BZip2 support will be released as a resource in the future.

Encrypted Files

Preliminary support for Encrypted/Passworded files is included in TGB Pro only. Currently, only Zip 2.0 encryption is supported by the stock code. AES support exists and may be released as a resource in the future.

To set the password used for zips, you need to modify the DEFAULT_ZIP_PASSWORD define in core/zip/zipArchive.h. This password will be used for all zips that require a password. The default password is changeme. This may be used by TGB Binary users to test encrypted zips with their game. Shipping with the default password is not recommended for obvious reasons.

The intended use of encrypted zips is for preventing casual copying of your game's assets. Zip 2.0 encryption has known weaknesses that allow an attacker to decrypt the contents of the zip. AES encryption is significantly more secure, but as the password must be stored in the executable it will not stop a determined attacker.

A script accessible mechanism for setting the password does not currently exist. To use encrypted mod zips, if the password was in script then the password would be clearly visible to anyone that cared to poke around in your scripts.

Encrypted zip support will be improved in a future version. For now, a more secure method of storing the password is left as an exercise for the reader.

Accessing Zip files from script

ZipArchive is a C++ class and thus cannot be used from script. However, a wrapper is provided to allow script access to zips. See the documentation on ZipObject for more information.

More Examples

More in depth example code than that featured here can be found in the unit tests for the zip code (in the core/zip/unitTests directory) and the script code for the packaging utility.

Member Enumeration Documentation

enum AccessMode

Access modes for zip files and files within the zip.

Enumerator
Read 

Open a zip or file in a zip for reading.

Write 

Open a zip or file in a zip for writing.

ReadWrite 

Open a zip file for reading and writing. Note: Not valid for files in zips.

Constructor & Destructor Documentation

~ZipArchive ( )
virtual

Member Function Documentation

bool addFile ( const char *  filename,
const char *  pathInZip,
bool  replace = true 
)

Add a file to the zip.

If replace is false and the file already exists in the zip, this function will fail and return false. If replace is true, the existing file will be overwritten.

Parameters
filenameFilename on the local file system to add
pathInZipThe path and filename in the zip file to give this file
replacetrue to replace existing files, false otherwise
Returns
true for success, false for failure
See Also
ZipArchive::extractFile(), ZipArchive::deleteFile(), ZipArchive::isVerbose()
void closeArchive ( )
virtual
void closeFile ( Stream stream)
virtual

Close a file opened through openFile()

Parameters
streamStream to close
See Also
ZipArchive::openFile(const char *, AccessMode)
bool copyFileToNewZip ( CentralDir cdir,
Stream newZipStream 
)
protected
Stream * createNewFile ( const char *  filename,
Compressor method 
)
protected
Stream* createNewFile ( const char *  filename,
const char *  method 
)
inlineprotected
Stream* createNewFile ( const char *  filename,
S32  method 
)
inlineprotected
U32 currentTimeToDOSTime ( )
protected
bool deleteFile ( const char *  filename)

Delete a file from the zip.

Flags a file as deleted so it is removed when the zip file is rebuilt.

Parameters
filenameFilename in the zip to delete
Returns
true for success, false for failure
See Also
ZipArchive::addFile(), ZipArchive::extractFile(), ZipArchive::isVerbose()
bool extractFile ( const char *  pathInZip,
const char *  filename,
bool *  crcFail = NULL 
)

Extract a file from the zip.

The file will be created through the resource manager and so must be in a location that is writable.

The file will be CRC checked during extraction and extractFile() will return false if the CRC check failed. The CRC check is just an advisory, the output file will still exist if the CRC check failed. It is up to the caller to decide what to do in the event of a CRC failure.

You can optionally pass a pointer to a bool to determine if a CRC check failed. If extractFile() returns false and crcFail is false then the failure was not CRC related. If crcFail is true and extractFile() returns false, then the CRC check failed but the file otherwise extracted OK. You can take your chances as to whether the data is valid or not, if you wish.

In verbose mode, extractFile() will display an error in the console when a file fails the CRC check.

Parameters
pathInZipThe path and filename in the zip file to extract
filenameFilename on the local file system to extract to
crcFailPointer to a boolean that receives the result of the CRC check
Returns
true for success, false for failure
See Also
ZipArchive::addFile(), ZipArchive::deleteFile(), ZipArchive::isVerbose()
CentralDir * findFileInfo ( const char *  filename)

Find a file in the zip.

Parameters
filenamePath and filename to find
Returns
Pointer to the central directory entry
ZipArchive::ZipEntry * findZipEntry ( const char *  filename)
protected
const char* getFilename ( )
inline

Get the filename of the zip file.

Returns
Filename of the zip file, or NULL if none set
void insertEntry ( ZipEntry ze)
protected
bool isVerbose ( )

Determine if the Zip code is in verbose mode.

Verbose mode causes the Zip code to provide diagnostic error messages when things go wrong. It can be enabled or disabled through script by setting the $Pref::Zip::Verbose variable to true to enable it or false to disable it.

Verbose mode is mostly useful when tracking down issues with opening a zip file without having to resort to using a debugger.

Returns
The value of $Pref::Zip::Verbose
See Also
ZipArchive::setVerbose()
U32 localTimeToDOSTime ( const Platform::LocalTime t)
protected
U32 numEntries ( ) const
inline

Get number of entries in the central directory.

See Also
ZipArchive::findFileInfo(const char *)
bool openArchive ( const char *  filename,
AccessMode  mode = Read 
)
virtual

Open a zip archive from a file.

The archive must be closed with closeArchive() when you are done with it.

Parameters
filenameFilename of zip file to open
modeAccess mode. May be Read, Write or ReadWrite
Returns
true for success, false for failure
See Also
ZipArchive::openArchive(Stream *, AccessMode), ZipArchive::closeArchive()
bool openArchive ( Stream stream,
AccessMode  mode = Read 
)
virtual

Open a zip archive from a stream.

The stream must support seeking and must support the specified access mode. For example, if the stream is opened for Read you cannot specify Write to openArchive(). However, if the stream is open for ReadWrite then you can specify any one of Read, Write or ReadWrite as the mode argument to openArchive().

The archive must be closed with closeArchive() when you are done with it.

Parameters
streamPointer to stream to open the zip archive from
modeAccess mode. May be Read, Write or ReadWrite
Returns
true for success, false for failure
See Also
ZipArchive::openArchive(const char *, AccessMode), ZipArchive::closeArchive()
Stream * openFile ( const char *  filename,
AccessMode  mode = Read 
)
virtual

Open a file within the zip file.

The access mode can only be Read or Write. It is not possible to open a file within the zip as ReadWrite.

The returned stream must be freed with closeFile(). Do not delete it directly.

In verbose mode, openFile() will display additional error information in the console when it fails.

Parameters
filenameFilename of the file in the zip
modeAccess mode. May be Read or Write
Returns
Pointer to stream or NULL for failure
See Also
ZipArchive::closeFile(), ZipArchive::isVerbose()
Stream * openFileForRead ( const CentralDir fileCD)

Open a file within the zip file for read.

This method exists mainly for the integration with the resource manager. Unless there is good reason to use this method, it is better to use the openFile() method instead.

Parameters
fileCDPointer to central directory of the file to open
Returns
Pointer to stream or NULL for failure
See Also
ZipArchive::openFile(const char *, AccessMode), ZipArchive::closeFile()
const CentralDir& operator[] ( const U32  idx) const
inline

Get a central directory entry

bool readCentralDirectory ( )
protected
bool rebuildZip ( )
protected
void removeEntry ( ZipEntry ze)
protected
void setFilename ( const char *  filename)

Set the filename of the zip file.

The zip filename is used by the resource manager and for error reporting.

Note: The filename is set automatically when you open the file.

Parameters
filenameFilename of the zip file
void setVerbose ( bool  verbose)

Turn verbose mode on or off.

This sets the $Pref::Zip::Verbose variable.

See isVerbose() for a discussion on verbose mode.

Parameters
verboseTrue to enable verbose mode, false to disable
See Also
ZipArchive::isVerbose()
void updateFile ( ZipTempStream stream)
protected
bool writeDirtyFileToNewZip ( ZipTempStream fileStream,
Stream zipStream 
)
protected

Member Data Documentation

FileStream* mDiskStream
protected
VectorPtr<ZipEntry *> mEntries
protected
EndOfCentralDir mEOCD
protected
const char* mFilename
protected
AccessMode mMode
protected
ZipEntry* mRoot
protected
Stream* mStream
protected
VectorPtr<ZipTempStream *> mTempFiles
protected

The documentation for this class was generated from the following files: