File indexing completed on 2025-01-26 04:24:53

0001 /*
0002 Copyright (C) 2005-2014 Sergey A. Tachenov
0003 
0004 This file is part of QuaZIP.
0005 
0006 QuaZIP is free software: you can redistribute it and/or modify
0007 it under the terms of the GNU Lesser General Public License as published by
0008 the Free Software Foundation, either version 2.1 of the License, or
0009 (at your option) any later version.
0010 
0011 QuaZIP is distributed in the hope that it will be useful,
0012 but WITHOUT ANY WARRANTY; without even the implied warranty of
0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014 GNU Lesser General Public License for more details.
0015 
0016 You should have received a copy of the GNU Lesser General Public License
0017 along with QuaZIP.  If not, see <http://www.gnu.org/licenses/>.
0018 
0019 See COPYING file for the full LGPL text.
0020 
0021 Original ZIP package is copyrighted by Gilles Vollant and contributors,
0022 see quazip/(un)zip.h files for details. Basically it's the zlib license.
0023 */
0024 
0025 #include <QFile>
0026 
0027 #include "quagzipfile.h"
0028 
0029 /// \cond internal
0030 class QuaGzipFilePrivate {
0031     friend class QuaGzipFile;
0032     QString fileName;
0033     gzFile gzd;
0034     inline QuaGzipFilePrivate(): gzd(NULL) {}
0035     inline QuaGzipFilePrivate(const QString &fileName): 
0036         fileName(fileName), gzd(NULL) {}
0037     template<typename FileId> bool open(FileId id, 
0038         QIODevice::OpenMode mode, QString &error);
0039     gzFile open(int fd, const char *modeString);
0040     gzFile open(const QString &name, const char *modeString);
0041 };
0042 
0043 gzFile QuaGzipFilePrivate::open(const QString &name, const char *modeString)
0044 {
0045     return gzopen(QFile::encodeName(name).constData(), modeString);
0046 }
0047 
0048 gzFile QuaGzipFilePrivate::open(int fd, const char *modeString)
0049 {
0050     return gzdopen(fd, modeString);
0051 }
0052 
0053 template<typename FileId>
0054 bool QuaGzipFilePrivate::open(FileId id, QIODevice::OpenMode mode, 
0055                               QString &error)
0056 {
0057     char modeString[2];
0058     modeString[0] = modeString[1] = '\0';
0059     if ((mode & QIODevice::Append) != 0) {
0060         error = QuaGzipFile::trUtf8("QIODevice::Append is not "
0061                 "supported for GZIP");
0062         return false;
0063     }
0064     if ((mode & QIODevice::ReadOnly) != 0
0065             && (mode & QIODevice::WriteOnly) != 0) {
0066         error = QuaGzipFile::trUtf8("Opening gzip for both reading"
0067             " and writing is not supported");
0068         return false;
0069     } else if ((mode & QIODevice::ReadOnly) != 0) {
0070         modeString[0] = 'r';
0071     } else if ((mode & QIODevice::WriteOnly) != 0) {
0072         modeString[0] = 'w';
0073     } else {
0074         error = QuaGzipFile::trUtf8("You can open a gzip either for reading"
0075             " or for writing. Which is it?");
0076         return false;
0077     }
0078     gzd = open(id, modeString);
0079     if (gzd == NULL) {
0080         error = QuaGzipFile::trUtf8("Could not gzopen() file");
0081         return false;
0082     }
0083     return true;
0084 }
0085 /// \endcond
0086 
0087 QuaGzipFile::QuaGzipFile():
0088 d(new QuaGzipFilePrivate())
0089 {
0090 }
0091 
0092 QuaGzipFile::QuaGzipFile(QObject *parent):
0093 QIODevice(parent),
0094 d(new QuaGzipFilePrivate())
0095 {
0096 }
0097 
0098 QuaGzipFile::QuaGzipFile(const QString &fileName, QObject *parent):
0099   QIODevice(parent),
0100 d(new QuaGzipFilePrivate(fileName))
0101 {
0102 }
0103 
0104 QuaGzipFile::~QuaGzipFile()
0105 {
0106   if (isOpen()) {
0107     close();
0108   }
0109   delete d;
0110 }
0111 
0112 void QuaGzipFile::setFileName(const QString& fileName)
0113 {
0114     d->fileName = fileName;
0115 }
0116 
0117 QString QuaGzipFile::getFileName() const
0118 {
0119     return d->fileName;
0120 }
0121 
0122 bool QuaGzipFile::isSequential() const
0123 {
0124   return true;
0125 }
0126 
0127 bool QuaGzipFile::open(QIODevice::OpenMode mode)
0128 {
0129     QString error;
0130     if (!d->open(d->fileName, mode, error)) {
0131         setErrorString(error);
0132         return false;
0133     }
0134     return QIODevice::open(mode);
0135 }
0136 
0137 bool QuaGzipFile::open(int fd, QIODevice::OpenMode mode)
0138 {
0139     QString error;
0140     if (!d->open(fd, mode, error)) {
0141         setErrorString(error);
0142         return false;
0143     }
0144     return QIODevice::open(mode);
0145 }
0146 
0147 bool QuaGzipFile::flush()
0148 {
0149     return gzflush(d->gzd, Z_SYNC_FLUSH) == Z_OK;
0150 }
0151 
0152 void QuaGzipFile::close()
0153 {
0154   QIODevice::close();
0155   gzclose(d->gzd);
0156 }
0157 
0158 qint64 QuaGzipFile::readData(char *data, qint64 maxSize)
0159 {
0160     return gzread(d->gzd, (voidp)data, (unsigned)maxSize);
0161 }
0162 
0163 qint64 QuaGzipFile::writeData(const char *data, qint64 maxSize)
0164 {
0165     if (maxSize == 0)
0166         return 0;
0167     int written = gzwrite(d->gzd, (voidp)data, (unsigned)maxSize);
0168     if (written == 0)
0169         return -1;
0170     else
0171         return written;
0172 }