1 | /*
|
---|
2 | Copyright (C) 2005-2014 Sergey A. Tachenov
|
---|
3 |
|
---|
4 | This file is part of QuaZIP.
|
---|
5 |
|
---|
6 | QuaZIP is free software: you can redistribute it and/or modify
|
---|
7 | it under the terms of the GNU Lesser General Public License as published by
|
---|
8 | the Free Software Foundation, either version 2.1 of the License, or
|
---|
9 | (at your option) any later version.
|
---|
10 |
|
---|
11 | QuaZIP is distributed in the hope that it will be useful,
|
---|
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
14 | GNU Lesser General Public License for more details.
|
---|
15 |
|
---|
16 | You should have received a copy of the GNU Lesser General Public License
|
---|
17 | along with QuaZIP. If not, see <http://www.gnu.org/licenses/>.
|
---|
18 |
|
---|
19 | See COPYING file for the full LGPL text.
|
---|
20 |
|
---|
21 | Original ZIP package is copyrighted by Gilles Vollant and contributors,
|
---|
22 | see quazip/(un)zip.h files for details. Basically it's the zlib license.
|
---|
23 | */
|
---|
24 |
|
---|
25 | #include <QFile>
|
---|
26 |
|
---|
27 | #include "quagzipfile.h"
|
---|
28 |
|
---|
29 | /// \cond internal
|
---|
30 | class QuaGzipFilePrivate {
|
---|
31 | friend class QuaGzipFile;
|
---|
32 | QString fileName;
|
---|
33 | gzFile gzd;
|
---|
34 | inline QuaGzipFilePrivate(): gzd(NULL) {}
|
---|
35 | inline QuaGzipFilePrivate(const QString &fileName):
|
---|
36 | fileName(fileName), gzd(NULL) {}
|
---|
37 | template<typename FileId> bool open(FileId id,
|
---|
38 | QIODevice::OpenMode mode, QString &error);
|
---|
39 | gzFile open(int fd, const char *modeString);
|
---|
40 | gzFile open(const QString &name, const char *modeString);
|
---|
41 | };
|
---|
42 |
|
---|
43 | gzFile QuaGzipFilePrivate::open(const QString &name, const char *modeString)
|
---|
44 | {
|
---|
45 | return gzopen(QFile::encodeName(name).constData(), modeString);
|
---|
46 | }
|
---|
47 |
|
---|
48 | gzFile QuaGzipFilePrivate::open(int fd, const char *modeString)
|
---|
49 | {
|
---|
50 | return gzdopen(fd, modeString);
|
---|
51 | }
|
---|
52 |
|
---|
53 | template<typename FileId>
|
---|
54 | bool QuaGzipFilePrivate::open(FileId id, QIODevice::OpenMode mode,
|
---|
55 | QString &error)
|
---|
56 | {
|
---|
57 | char modeString[2];
|
---|
58 | modeString[0] = modeString[1] = '\0';
|
---|
59 | if ((mode & QIODevice::Append) != 0) {
|
---|
60 | error = QuaGzipFile::trUtf8("QIODevice::Append is not "
|
---|
61 | "supported for GZIP");
|
---|
62 | return false;
|
---|
63 | }
|
---|
64 | if ((mode & QIODevice::ReadOnly) != 0
|
---|
65 | && (mode & QIODevice::WriteOnly) != 0) {
|
---|
66 | error = QuaGzipFile::trUtf8("Opening gzip for both reading"
|
---|
67 | " and writing is not supported");
|
---|
68 | return false;
|
---|
69 | } else if ((mode & QIODevice::ReadOnly) != 0) {
|
---|
70 | modeString[0] = 'r';
|
---|
71 | } else if ((mode & QIODevice::WriteOnly) != 0) {
|
---|
72 | modeString[0] = 'w';
|
---|
73 | } else {
|
---|
74 | error = QuaGzipFile::trUtf8("You can open a gzip either for reading"
|
---|
75 | " or for writing. Which is it?");
|
---|
76 | return false;
|
---|
77 | }
|
---|
78 | gzd = open(id, modeString);
|
---|
79 | if (gzd == NULL) {
|
---|
80 | error = QuaGzipFile::trUtf8("Could not gzopen() file");
|
---|
81 | return false;
|
---|
82 | }
|
---|
83 | return true;
|
---|
84 | }
|
---|
85 | /// \endcond
|
---|
86 |
|
---|
87 | QuaGzipFile::QuaGzipFile():
|
---|
88 | d(new QuaGzipFilePrivate())
|
---|
89 | {
|
---|
90 | }
|
---|
91 |
|
---|
92 | QuaGzipFile::QuaGzipFile(QObject *parent):
|
---|
93 | QIODevice(parent),
|
---|
94 | d(new QuaGzipFilePrivate())
|
---|
95 | {
|
---|
96 | }
|
---|
97 |
|
---|
98 | QuaGzipFile::QuaGzipFile(const QString &fileName, QObject *parent):
|
---|
99 | QIODevice(parent),
|
---|
100 | d(new QuaGzipFilePrivate(fileName))
|
---|
101 | {
|
---|
102 | }
|
---|
103 |
|
---|
104 | QuaGzipFile::~QuaGzipFile()
|
---|
105 | {
|
---|
106 | if (isOpen()) {
|
---|
107 | close();
|
---|
108 | }
|
---|
109 | delete d;
|
---|
110 | }
|
---|
111 |
|
---|
112 | void QuaGzipFile::setFileName(const QString& fileName)
|
---|
113 | {
|
---|
114 | d->fileName = fileName;
|
---|
115 | }
|
---|
116 |
|
---|
117 | QString QuaGzipFile::getFileName() const
|
---|
118 | {
|
---|
119 | return d->fileName;
|
---|
120 | }
|
---|
121 |
|
---|
122 | bool QuaGzipFile::isSequential() const
|
---|
123 | {
|
---|
124 | return true;
|
---|
125 | }
|
---|
126 |
|
---|
127 | bool QuaGzipFile::open(QIODevice::OpenMode mode)
|
---|
128 | {
|
---|
129 | QString error;
|
---|
130 | if (!d->open(d->fileName, mode, error)) {
|
---|
131 | setErrorString(error);
|
---|
132 | return false;
|
---|
133 | }
|
---|
134 | return QIODevice::open(mode);
|
---|
135 | }
|
---|
136 |
|
---|
137 | bool QuaGzipFile::open(int fd, QIODevice::OpenMode mode)
|
---|
138 | {
|
---|
139 | QString error;
|
---|
140 | if (!d->open(fd, mode, error)) {
|
---|
141 | setErrorString(error);
|
---|
142 | return false;
|
---|
143 | }
|
---|
144 | return QIODevice::open(mode);
|
---|
145 | }
|
---|
146 |
|
---|
147 | bool QuaGzipFile::flush()
|
---|
148 | {
|
---|
149 | return gzflush(d->gzd, Z_SYNC_FLUSH) == Z_OK;
|
---|
150 | }
|
---|
151 |
|
---|
152 | void QuaGzipFile::close()
|
---|
153 | {
|
---|
154 | QIODevice::close();
|
---|
155 | gzclose(d->gzd);
|
---|
156 | }
|
---|
157 |
|
---|
158 | qint64 QuaGzipFile::readData(char *data, qint64 maxSize)
|
---|
159 | {
|
---|
160 | return gzread(d->gzd, (voidp)data, (unsigned)maxSize);
|
---|
161 | }
|
---|
162 |
|
---|
163 | qint64 QuaGzipFile::writeData(const char *data, qint64 maxSize)
|
---|
164 | {
|
---|
165 | if (maxSize == 0)
|
---|
166 | return 0;
|
---|
167 | int written = gzwrite(d->gzd, (voidp)data, (unsigned)maxSize);
|
---|
168 | if (written == 0)
|
---|
169 | return -1;
|
---|
170 | else
|
---|
171 | return written;
|
---|
172 | }
|
---|