ViewVC Help
View File | Revision Log | View Changeset | Root Listing
root/Oni2/s10k/CommonLibs/quazip-0.7.2/quazip/quaziodevice.cpp
Revision: 1096
Committed: Sat Dec 30 14:40:33 2017 UTC (7 years, 9 months ago) by s10k
Content type: text/x-c++src
File size: 9580 byte(s)
Log Message:
Added zlib, quazip, basicxmlsyntaxhighlighter, conditionalsemaphore and linenumberdisplay libraries. zlib and quazip are pre-compiled, but you can compile them yourself, just delete the dll files (or equivalent binary files to your OS)

File Contents

# Content
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 "quaziodevice.h"
26
27 #define QUAZIO_INBUFSIZE 4096
28 #define QUAZIO_OUTBUFSIZE 4096
29
30 /// \cond internal
31 class QuaZIODevicePrivate {
32 friend class QuaZIODevice;
33 QuaZIODevicePrivate(QIODevice *io);
34 ~QuaZIODevicePrivate();
35 QIODevice *io;
36 z_stream zins;
37 z_stream zouts;
38 char *inBuf;
39 int inBufPos;
40 int inBufSize;
41 char *outBuf;
42 int outBufPos;
43 int outBufSize;
44 bool zBufError;
45 bool atEnd;
46 int doFlush(QString &error);
47 };
48
49 QuaZIODevicePrivate::QuaZIODevicePrivate(QIODevice *io):
50 io(io),
51 inBuf(NULL),
52 inBufPos(0),
53 inBufSize(0),
54 outBuf(NULL),
55 outBufPos(0),
56 outBufSize(0),
57 zBufError(false),
58 atEnd(false)
59 {
60 zins.zalloc = (alloc_func) NULL;
61 zins.zfree = (free_func) NULL;
62 zins.opaque = NULL;
63 zouts.zalloc = (alloc_func) NULL;
64 zouts.zfree = (free_func) NULL;
65 zouts.opaque = NULL;
66 inBuf = new char[QUAZIO_INBUFSIZE];
67 outBuf = new char[QUAZIO_OUTBUFSIZE];
68 #ifdef QUAZIP_ZIODEVICE_DEBUG_OUTPUT
69 debug.setFileName("debug.out");
70 debug.open(QIODevice::WriteOnly);
71 #endif
72 #ifdef QUAZIP_ZIODEVICE_DEBUG_INPUT
73 indebug.setFileName("debug.in");
74 indebug.open(QIODevice::WriteOnly);
75 #endif
76 }
77
78 QuaZIODevicePrivate::~QuaZIODevicePrivate()
79 {
80 #ifdef QUAZIP_ZIODEVICE_DEBUG_OUTPUT
81 debug.close();
82 #endif
83 #ifdef QUAZIP_ZIODEVICE_DEBUG_INPUT
84 indebug.close();
85 #endif
86 if (inBuf != NULL)
87 delete[] inBuf;
88 if (outBuf != NULL)
89 delete[] outBuf;
90 }
91
92 int QuaZIODevicePrivate::doFlush(QString &error)
93 {
94 int flushed = 0;
95 while (outBufPos < outBufSize) {
96 int more = io->write(outBuf + outBufPos, outBufSize - outBufPos);
97 if (more == -1) {
98 error = io->errorString();
99 return -1;
100 }
101 if (more == 0)
102 break;
103 outBufPos += more;
104 flushed += more;
105 }
106 if (outBufPos == outBufSize) {
107 outBufPos = outBufSize = 0;
108 }
109 return flushed;
110 }
111
112 /// \endcond
113
114 // #define QUAZIP_ZIODEVICE_DEBUG_OUTPUT
115 // #define QUAZIP_ZIODEVICE_DEBUG_INPUT
116 #ifdef QUAZIP_ZIODEVICE_DEBUG_OUTPUT
117 #include <QFile>
118 static QFile debug;
119 #endif
120 #ifdef QUAZIP_ZIODEVICE_DEBUG_INPUT
121 #include <QFile>
122 static QFile indebug;
123 #endif
124
125 QuaZIODevice::QuaZIODevice(QIODevice *io, QObject *parent):
126 QIODevice(parent),
127 d(new QuaZIODevicePrivate(io))
128 {
129 connect(io, SIGNAL(readyRead()), SIGNAL(readyRead()));
130 }
131
132 QuaZIODevice::~QuaZIODevice()
133 {
134 if (isOpen())
135 close();
136 delete d;
137 }
138
139 QIODevice *QuaZIODevice::getIoDevice() const
140 {
141 return d->io;
142 }
143
144 bool QuaZIODevice::open(QIODevice::OpenMode mode)
145 {
146 if ((mode & QIODevice::Append) != 0) {
147 setErrorString(trUtf8("QIODevice::Append is not supported for"
148 " QuaZIODevice"));
149 return false;
150 }
151 if ((mode & QIODevice::ReadWrite) == QIODevice::ReadWrite) {
152 setErrorString(trUtf8("QIODevice::ReadWrite is not supported for"
153 " QuaZIODevice"));
154 return false;
155 }
156 if ((mode & QIODevice::ReadOnly) != 0) {
157 if (inflateInit(&d->zins) != Z_OK) {
158 setErrorString(d->zins.msg);
159 return false;
160 }
161 }
162 if ((mode & QIODevice::WriteOnly) != 0) {
163 if (deflateInit(&d->zouts, Z_DEFAULT_COMPRESSION) != Z_OK) {
164 setErrorString(d->zouts.msg);
165 return false;
166 }
167 }
168 return QIODevice::open(mode);
169 }
170
171 void QuaZIODevice::close()
172 {
173 if ((openMode() & QIODevice::ReadOnly) != 0) {
174 if (inflateEnd(&d->zins) != Z_OK) {
175 setErrorString(d->zins.msg);
176 }
177 }
178 if ((openMode() & QIODevice::WriteOnly) != 0) {
179 flush();
180 if (deflateEnd(&d->zouts) != Z_OK) {
181 setErrorString(d->zouts.msg);
182 }
183 }
184 QIODevice::close();
185 }
186
187 qint64 QuaZIODevice::readData(char *data, qint64 maxSize)
188 {
189 int read = 0;
190 while (read < maxSize) {
191 if (d->inBufPos == d->inBufSize) {
192 d->inBufPos = 0;
193 d->inBufSize = d->io->read(d->inBuf, QUAZIO_INBUFSIZE);
194 if (d->inBufSize == -1) {
195 d->inBufSize = 0;
196 setErrorString(d->io->errorString());
197 return -1;
198 }
199 if (d->inBufSize == 0)
200 break;
201 }
202 while (read < maxSize && d->inBufPos < d->inBufSize) {
203 d->zins.next_in = (Bytef *) (d->inBuf + d->inBufPos);
204 d->zins.avail_in = d->inBufSize - d->inBufPos;
205 d->zins.next_out = (Bytef *) (data + read);
206 d->zins.avail_out = (uInt) (maxSize - read); // hope it's less than 2GB
207 int more = 0;
208 switch (inflate(&d->zins, Z_SYNC_FLUSH)) {
209 case Z_OK:
210 read = (char *) d->zins.next_out - data;
211 d->inBufPos = (char *) d->zins.next_in - d->inBuf;
212 break;
213 case Z_STREAM_END:
214 read = (char *) d->zins.next_out - data;
215 d->inBufPos = (char *) d->zins.next_in - d->inBuf;
216 d->atEnd = true;
217 return read;
218 case Z_BUF_ERROR: // this should never happen, but just in case
219 if (!d->zBufError) {
220 qWarning("Z_BUF_ERROR detected with %d/%d in/out, weird",
221 d->zins.avail_in, d->zins.avail_out);
222 d->zBufError = true;
223 }
224 memmove(d->inBuf, d->inBuf + d->inBufPos, d->inBufSize - d->inBufPos);
225 d->inBufSize -= d->inBufPos;
226 d->inBufPos = 0;
227 more = d->io->read(d->inBuf + d->inBufSize, QUAZIO_INBUFSIZE - d->inBufSize);
228 if (more == -1) {
229 setErrorString(d->io->errorString());
230 return -1;
231 }
232 if (more == 0)
233 return read;
234 d->inBufSize += more;
235 break;
236 default:
237 setErrorString(QString::fromLocal8Bit(d->zins.msg));
238 return -1;
239 }
240 }
241 }
242 #ifdef QUAZIP_ZIODEVICE_DEBUG_INPUT
243 indebug.write(data, read);
244 #endif
245 return read;
246 }
247
248 qint64 QuaZIODevice::writeData(const char *data, qint64 maxSize)
249 {
250 int written = 0;
251 QString error;
252 if (d->doFlush(error) == -1) {
253 setErrorString(error);
254 return -1;
255 }
256 while (written < maxSize) {
257 // there is some data waiting in the output buffer
258 if (d->outBufPos < d->outBufSize)
259 return written;
260 d->zouts.next_in = (Bytef *) (data + written);
261 d->zouts.avail_in = (uInt) (maxSize - written); // hope it's less than 2GB
262 d->zouts.next_out = (Bytef *) d->outBuf;
263 d->zouts.avail_out = QUAZIO_OUTBUFSIZE;
264 switch (deflate(&d->zouts, Z_NO_FLUSH)) {
265 case Z_OK:
266 written = (char *) d->zouts.next_in - data;
267 d->outBufSize = (char *) d->zouts.next_out - d->outBuf;
268 break;
269 default:
270 setErrorString(QString::fromLocal8Bit(d->zouts.msg));
271 return -1;
272 }
273 if (d->doFlush(error) == -1) {
274 setErrorString(error);
275 return -1;
276 }
277 }
278 #ifdef QUAZIP_ZIODEVICE_DEBUG_OUTPUT
279 debug.write(data, written);
280 #endif
281 return written;
282 }
283
284 bool QuaZIODevice::flush()
285 {
286 QString error;
287 if (d->doFlush(error) < 0) {
288 setErrorString(error);
289 return false;
290 }
291 // can't flush buffer, some data is still waiting
292 if (d->outBufPos < d->outBufSize)
293 return true;
294 Bytef c = 0;
295 d->zouts.next_in = &c; // fake input buffer
296 d->zouts.avail_in = 0; // of zero size
297 do {
298 d->zouts.next_out = (Bytef *) d->outBuf;
299 d->zouts.avail_out = QUAZIO_OUTBUFSIZE;
300 switch (deflate(&d->zouts, Z_SYNC_FLUSH)) {
301 case Z_OK:
302 d->outBufSize = (char *) d->zouts.next_out - d->outBuf;
303 if (d->doFlush(error) < 0) {
304 setErrorString(error);
305 return false;
306 }
307 if (d->outBufPos < d->outBufSize)
308 return true;
309 break;
310 case Z_BUF_ERROR: // nothing to write?
311 return true;
312 default:
313 setErrorString(QString::fromLocal8Bit(d->zouts.msg));
314 return false;
315 }
316 } while (d->zouts.avail_out == 0);
317 return true;
318 }
319
320 bool QuaZIODevice::isSequential() const
321 {
322 return true;
323 }
324
325 bool QuaZIODevice::atEnd() const
326 {
327 // Here we MUST check QIODevice::bytesAvailable() because WE
328 // might have reached the end, but QIODevice didn't--
329 // it could have simply pre-buffered all remaining data.
330 return (openMode() == NotOpen) || (QIODevice::bytesAvailable() == 0 && d->atEnd);
331 }
332
333 qint64 QuaZIODevice::bytesAvailable() const
334 {
335 // If we haven't recevied Z_STREAM_END, it means that
336 // we have at least one more input byte available.
337 // Plus whatever QIODevice has buffered.
338 return (d->atEnd ? 0 : 1) + QIODevice::bytesAvailable();
339 }