summaryrefslogtreecommitdiffstats
path: root/rbutil/rbutilqt/quazip/quazipfile.h
diff options
context:
space:
mode:
Diffstat (limited to 'rbutil/rbutilqt/quazip/quazipfile.h')
-rw-r--r--rbutil/rbutilqt/quazip/quazipfile.h442
1 files changed, 442 insertions, 0 deletions
diff --git a/rbutil/rbutilqt/quazip/quazipfile.h b/rbutil/rbutilqt/quazip/quazipfile.h
new file mode 100644
index 0000000000..09af5bceca
--- /dev/null
+++ b/rbutil/rbutilqt/quazip/quazipfile.h
@@ -0,0 +1,442 @@
+#ifndef QUA_ZIPFILE_H
+#define QUA_ZIPFILE_H
+
+/*
+-- A kind of "standard" GPL license statement --
+QuaZIP - a Qt/C++ wrapper for the ZIP/UNZIP package
+Copyright (C) 2005-2008 Sergey A. Tachenov
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+-- A kind of "standard" GPL license statement ends here --
+
+See COPYING file for GPL.
+
+You are also permitted to use QuaZIP under the terms of LGPL (see
+COPYING.LGPL). You are free to choose either license, but please note
+that QuaZIP makes use of Qt, which is not licensed under LGPL. So if
+you are using Open Source edition of Qt, you therefore MUST use GPL for
+your code based on QuaZIP, since it would be also based on Qt in this
+case. If you are Qt commercial license owner, then you are free to use
+QuaZIP as long as you respect either GPL or LGPL for QuaZIP code.
+ **/
+
+#include <QIODevice>
+
+#include "quazip.h"
+#include "quazipnewinfo.h"
+
+/// A file inside ZIP archive.
+/** \class QuaZipFile quazipfile.h <quazip/quazipfile.h>
+ * This is the most interesting class. Not only it provides C++
+ * interface to the ZIP/UNZIP package, but also integrates it with Qt by
+ * subclassing QIODevice. This makes possible to access files inside ZIP
+ * archive using QTextStream or QDataStream, for example. Actually, this
+ * is the main purpose of the whole QuaZIP library.
+ *
+ * You can either use existing QuaZip instance to create instance of
+ * this class or pass ZIP archive file name to this class, in which case
+ * it will create internal QuaZip object. See constructors' descriptions
+ * for details. Writing is only possible with the existing instance.
+ *
+ * \section quazipfile-sequential Sequential or random-access?
+ *
+ * At the first thought, QuaZipFile has fixed size, the start and the
+ * end and should be therefore considered random-access device. But
+ * there is one major obstacle to making it random-access: ZIP/UNZIP API
+ * does not support seek() operation and the only way to implement it is
+ * through reopening the file and re-reading to the required position,
+ * but this is prohibitely slow.
+ *
+ * Therefore, QuaZipFile is considered to be a sequential device. This
+ * has advantage of availability of the ungetChar() operation (QIODevice
+ * does not implement it properly for non-sequential devices unless they
+ * support seek()). Disadvantage is a somewhat strange behaviour of the
+ * size() and pos() functions. This should be kept in mind while using
+ * this class.
+ *
+ **/
+class QuaZipFile: public QIODevice {
+ Q_OBJECT
+ private:
+ QuaZip *zip;
+ QString fileName;
+ QuaZip::CaseSensitivity caseSensitivity;
+ bool raw;
+ qint64 writePos;
+ // these two are for writing raw files
+ ulong uncompressedSize;
+ quint32 crc;
+ bool internal;
+ int zipError;
+ // these are not supported nor implemented
+ QuaZipFile(const QuaZipFile& that);
+ QuaZipFile& operator=(const QuaZipFile& that);
+ void resetZipError()const {setZipError(UNZ_OK);}
+ // const, but sets zipError!
+ void setZipError(int zipError)const;
+ protected:
+ /// Implementation of the QIODevice::readData().
+ qint64 readData(char *data, qint64 maxSize);
+ /// Implementation of the QIODevice::writeData().
+ qint64 writeData(const char *data, qint64 maxSize);
+ public:
+ /// Constructs a QuaZipFile instance.
+ /** You should use setZipName() and setFileName() or setZip() before
+ * trying to call open() on the constructed object.
+ **/
+ QuaZipFile();
+ /// Constructs a QuaZipFile instance.
+ /** \a parent argument specifies this object's parent object.
+ *
+ * You should use setZipName() and setFileName() or setZip() before
+ * trying to call open() on the constructed object.
+ **/
+ QuaZipFile(QObject *parent);
+ /// Constructs a QuaZipFile instance.
+ /** \a parent argument specifies this object's parent object and \a
+ * zipName specifies ZIP archive file name.
+ *
+ * You should use setFileName() before trying to call open() on the
+ * constructed object.
+ *
+ * QuaZipFile constructed by this constructor can be used for read
+ * only access. Use QuaZipFile(QuaZip*,QObject*) for writing.
+ **/
+ QuaZipFile(const QString& zipName, QObject *parent =NULL);
+ /// Constructs a QuaZipFile instance.
+ /** \a parent argument specifies this object's parent object, \a
+ * zipName specifies ZIP archive file name and \a fileName and \a cs
+ * specify a name of the file to open inside archive.
+ *
+ * QuaZipFile constructed by this constructor can be used for read
+ * only access. Use QuaZipFile(QuaZip*,QObject*) for writing.
+ *
+ * \sa QuaZip::setCurrentFile()
+ **/
+ QuaZipFile(const QString& zipName, const QString& fileName,
+ QuaZip::CaseSensitivity cs =QuaZip::csDefault, QObject *parent =NULL);
+ /// Constructs a QuaZipFile instance.
+ /** \a parent argument specifies this object's parent object.
+ *
+ * \a zip is the pointer to the existing QuaZip object. This
+ * QuaZipFile object then can be used to read current file in the
+ * \a zip or to write to the file inside it.
+ *
+ * \warning Using this constructor for reading current file can be
+ * tricky. Let's take the following example:
+ * \code
+ * QuaZip zip("archive.zip");
+ * zip.open(QuaZip::mdUnzip);
+ * zip.setCurrentFile("file-in-archive");
+ * QuaZipFile file(&zip);
+ * file.open(QIODevice::ReadOnly);
+ * // ok, now we can read from the file
+ * file.read(somewhere, some);
+ * zip.setCurrentFile("another-file-in-archive"); // oops...
+ * QuaZipFile anotherFile(&zip);
+ * anotherFile.open(QIODevice::ReadOnly);
+ * anotherFile.read(somewhere, some); // this is still ok...
+ * file.read(somewhere, some); // and this is NOT
+ * \endcode
+ * So, what exactly happens here? When we change current file in the
+ * \c zip archive, \c file that references it becomes invalid
+ * (actually, as far as I understand ZIP/UNZIP sources, it becomes
+ * closed, but QuaZipFile has no means to detect it).
+ *
+ * Summary: do not close \c zip object or change its current file as
+ * long as QuaZipFile is open. Even better - use another constructors
+ * which create internal QuaZip instances, one per object, and
+ * therefore do not cause unnecessary trouble. This constructor may
+ * be useful, though, if you already have a QuaZip instance and do
+ * not want to access several files at once. Good example:
+ * \code
+ * QuaZip zip("archive.zip");
+ * zip.open(QuaZip::mdUnzip);
+ * // first, we need some information about archive itself
+ * QByteArray comment=zip.getComment();
+ * // and now we are going to access files inside it
+ * QuaZipFile file(&zip);
+ * for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile()) {
+ * file.open(QIODevice::ReadOnly);
+ * // do something cool with file here
+ * file.close(); // do not forget to close!
+ * }
+ * zip.close();
+ * \endcode
+ **/
+ QuaZipFile(QuaZip *zip, QObject *parent =NULL);
+ /// Destroys a QuaZipFile instance.
+ /** Closes file if open, destructs internal QuaZip object (if it
+ * exists and \em is internal, of course).
+ **/
+ virtual ~QuaZipFile();
+ /// Returns the ZIP archive file name.
+ /** If this object was created by passing QuaZip pointer to the
+ * constructor, this function will return that QuaZip's file name
+ * (or null string if that object does not have file name yet).
+ *
+ * Otherwise, returns associated ZIP archive file name or null
+ * string if there are no name set yet.
+ *
+ * \sa setZipName() getFileName()
+ **/
+ QString getZipName()const;
+ /// Returns a pointer to the associated QuaZip object.
+ /** Returns \c NULL if there is no associated QuaZip or it is
+ * internal (so you will not mess with it).
+ **/
+ QuaZip* getZip()const;
+ /// Returns file name.
+ /** This function returns file name you passed to this object either
+ * by using
+ * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*)
+ * or by calling setFileName(). Real name of the file may differ in
+ * case if you used case-insensitivity.
+ *
+ * Returns null string if there is no file name set yet. This is the
+ * case when this QuaZipFile operates on the existing QuaZip object
+ * (constructor QuaZipFile(QuaZip*,QObject*) or setZip() was used).
+ *
+ * \sa getActualFileName
+ **/
+ QString getFileName()const {return fileName;}
+ /// Returns case sensitivity of the file name.
+ /** This function returns case sensitivity argument you passed to
+ * this object either by using
+ * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*)
+ * or by calling setFileName().
+ *
+ * Returns unpredictable value if getFileName() returns null string
+ * (this is the case when you did not used setFileName() or
+ * constructor above).
+ *
+ * \sa getFileName
+ **/
+ QuaZip::CaseSensitivity getCaseSensitivity()const {return caseSensitivity;}
+ /// Returns the actual file name in the archive.
+ /** This is \em not a ZIP archive file name, but a name of file inside
+ * archive. It is not necessary the same name that you have passed
+ * to the
+ * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*),
+ * setFileName() or QuaZip::setCurrentFile() - this is the real file
+ * name inside archive, so it may differ in case if the file name
+ * search was case-insensitive.
+ *
+ * Equivalent to calling getCurrentFileName() on the associated
+ * QuaZip object. Returns null string if there is no associated
+ * QuaZip object or if it does not have a current file yet. And this
+ * is the case if you called setFileName() but did not open the
+ * file yet. So this is perfectly fine:
+ * \code
+ * QuaZipFile file("somezip.zip");
+ * file.setFileName("somefile");
+ * QString name=file.getName(); // name=="somefile"
+ * QString actual=file.getActualFileName(); // actual is null string
+ * file.open(QIODevice::ReadOnly);
+ * QString actual=file.getActualFileName(); // actual can be "SoMeFiLe" on Windows
+ * \endcode
+ *
+ * \sa getZipName(), getFileName(), QuaZip::CaseSensitivity
+ **/
+ QString getActualFileName()const;
+ /// Sets the ZIP archive file name.
+ /** Automatically creates internal QuaZip object and destroys
+ * previously created internal QuaZip object, if any.
+ *
+ * Will do nothing if this file is already open. You must close() it
+ * first.
+ **/
+ void setZipName(const QString& zipName);
+ /// Returns \c true if the file was opened in raw mode.
+ /** If the file is not open, the returned value is undefined.
+ *
+ * \sa open(OpenMode,int*,int*,bool,const char*)
+ **/
+ bool isRaw()const {return raw;}
+ /// Binds to the existing QuaZip instance.
+ /** This function destroys internal QuaZip object, if any, and makes
+ * this QuaZipFile to use current file in the \a zip object for any
+ * further operations. See QuaZipFile(QuaZip*,QObject*) for the
+ * possible pitfalls.
+ *
+ * Will do nothing if the file is currently open. You must close()
+ * it first.
+ **/
+ void setZip(QuaZip *zip);
+ /// Sets the file name.
+ /** Will do nothing if at least one of the following conditions is
+ * met:
+ * - ZIP name has not been set yet (getZipName() returns null
+ * string).
+ * - This QuaZipFile is associated with external QuaZip. In this
+ * case you should call that QuaZip's setCurrentFile() function
+ * instead!
+ * - File is already open so setting the name is meaningless.
+ *
+ * \sa QuaZip::setCurrentFile
+ **/
+ void setFileName(const QString& fileName, QuaZip::CaseSensitivity cs =QuaZip::csDefault);
+ /// Opens a file for reading.
+ /** Returns \c true on success, \c false otherwise.
+ * Call getZipError() to get error code.
+ *
+ * \note Since ZIP/UNZIP API provides buffered reading only,
+ * QuaZipFile does not support unbuffered reading. So do not pass
+ * QIODevice::Unbuffered flag in \a mode, or open will fail.
+ **/
+ virtual bool open(OpenMode mode);
+ /// Opens a file for reading.
+ /** \overload
+ * Argument \a password specifies a password to decrypt the file. If
+ * it is NULL then this function behaves just like open(OpenMode).
+ **/
+ bool open(OpenMode mode, const char *password)
+ {return open(mode, NULL, NULL, false, password);}
+ /// Opens a file for reading.
+ /** \overload
+ * Argument \a password specifies a password to decrypt the file.
+ *
+ * An integers pointed by \a method and \a level will receive codes
+ * of the compression method and level used. See unzip.h.
+ *
+ * If raw is \c true then no decompression is performed.
+ *
+ * \a method should not be \c NULL. \a level can be \c NULL if you
+ * don't want to know the compression level.
+ **/
+ bool open(OpenMode mode, int *method, int *level, bool raw, const char *password =NULL);
+ /// Opens a file for writing.
+ /** \a info argument specifies information about file. It should at
+ * least specify a correct file name. Also, it is a good idea to
+ * specify correct timestamp (by default, current time will be
+ * used). See QuaZipNewInfo.
+ *
+ * Arguments \a password and \a crc provide necessary information
+ * for crypting. Note that you should specify both of them if you
+ * need crypting. If you do not, pass \c NULL as password, but you
+ * still need to specify \a crc if you are going to use raw mode
+ * (see below).
+ *
+ * Arguments \a method and \a level specify compression method and
+ * level.
+ *
+ * If \a raw is \c true, no compression is performed. In this case,
+ * \a crc and uncompressedSize field of the \a info are required.
+ *
+ * Arguments \a windowBits, \a memLevel, \a strategy provide zlib
+ * algorithms tuning. See deflateInit2() in zlib.
+ **/
+ bool open(OpenMode mode, const QuaZipNewInfo& info,
+ const char *password =NULL, quint32 crc =0,
+ int method =Z_DEFLATED, int level =Z_DEFAULT_COMPRESSION, bool raw =false,
+ int windowBits =-MAX_WBITS, int memLevel =DEF_MEM_LEVEL, int strategy =Z_DEFAULT_STRATEGY);
+ /// Returns \c true, but \ref quazipfile-sequential "beware"!
+ virtual bool isSequential()const;
+ /// Returns current position in the file.
+ /** Implementation of the QIODevice::pos(). When reading, this
+ * function is a wrapper to the ZIP/UNZIP unztell(), therefore it is
+ * unable to keep track of the ungetChar() calls (which is
+ * non-virtual and therefore is dangerous to reimplement). So if you
+ * are using ungetChar() feature of the QIODevice, this function
+ * reports incorrect value until you get back characters which you
+ * ungot.
+ *
+ * When writing, pos() returns number of bytes already written
+ * (uncompressed unless you use raw mode).
+ *
+ * \note Although
+ * \ref quazipfile-sequential "QuaZipFile is a sequential device"
+ * and therefore pos() should always return zero, it does not,
+ * because it would be misguiding. Keep this in mind.
+ *
+ * This function returns -1 if the file or archive is not open.
+ *
+ * Error code returned by getZipError() is not affected by this
+ * function call.
+ **/
+ virtual qint64 pos()const;
+ /// Returns \c true if the end of file was reached.
+ /** This function returns \c false in the case of error. This means
+ * that you called this function on either not open file, or a file
+ * in the not open archive or even on a QuaZipFile instance that
+ * does not even have QuaZip instance associated. Do not do that
+ * because there is no means to determine whether \c false is
+ * returned because of error or because end of file was reached.
+ * Well, on the other side you may interpret \c false return value
+ * as "there is no file open to check for end of file and there is
+ * no end of file therefore".
+ *
+ * When writing, this function always returns \c true (because you
+ * are always writing to the end of file).
+ *
+ * Error code returned by getZipError() is not affected by this
+ * function call.
+ **/
+ virtual bool atEnd()const;
+ /// Returns file size.
+ /** This function returns csize() if the file is open for reading in
+ * raw mode, usize() if it is open for reading in normal mode and
+ * pos() if it is open for writing.
+ *
+ * Returns -1 on error, call getZipError() to get error code.
+ *
+ * \note This function returns file size despite that
+ * \ref quazipfile-sequential "QuaZipFile is considered to be sequential device",
+ * for which size() should return bytesAvailable() instead. But its
+ * name would be very misguiding otherwise, so just keep in mind
+ * this inconsistence.
+ **/
+ virtual qint64 size()const;
+ /// Returns compressed file size.
+ /** Equivalent to calling getFileInfo() and then getting
+ * compressedSize field, but more convenient and faster.
+ *
+ * File must be open for reading before calling this function.
+ *
+ * Returns -1 on error, call getZipError() to get error code.
+ **/
+ qint64 csize()const;
+ /// Returns uncompressed file size.
+ /** Equivalent to calling getFileInfo() and then getting
+ * uncompressedSize field, but more convenient and faster. See
+ * getFileInfo() for a warning.
+ *
+ * File must be open for reading before calling this function.
+ *
+ * Returns -1 on error, call getZipError() to get error code.
+ **/
+ qint64 usize()const;
+ /// Gets information about current file.
+ /** This function does the same thing as calling
+ * QuaZip::getCurrentFileInfo() on the associated QuaZip object,
+ * but you can not call getCurrentFileInfo() if the associated
+ * QuaZip is internal (because you do not have access to it), while
+ * you still can call this function in that case.
+ *
+ * File must be open for reading before calling this function.
+ *
+ * Returns \c false in the case of an error.
+ **/
+ bool getFileInfo(QuaZipFileInfo *info);
+ /// Closes the file.
+ /** Call getZipError() to determine if the close was successful.
+ **/
+ virtual void close();
+ /// Returns the error code returned by the last ZIP/UNZIP API call.
+ int getZipError()const {return zipError;}
+};
+
+#endif