summaryrefslogtreecommitdiff
path: root/rbutil/rbutilqt/quazip/qioapi.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'rbutil/rbutilqt/quazip/qioapi.cpp')
-rw-r--r--rbutil/rbutilqt/quazip/qioapi.cpp361
1 files changed, 361 insertions, 0 deletions
diff --git a/rbutil/rbutilqt/quazip/qioapi.cpp b/rbutil/rbutilqt/quazip/qioapi.cpp
new file mode 100644
index 0000000000..534dbdf51f
--- /dev/null
+++ b/rbutil/rbutilqt/quazip/qioapi.cpp
@@ -0,0 +1,361 @@
1/* ioapi.c -- IO base function header for compress/uncompress .zip
2 files using zlib + zip or unzip API
3
4 Version 1.01e, February 12th, 2005
5
6 Copyright (C) 1998-2005 Gilles Vollant
7
8 Modified by Sergey A. Tachenov to integrate with Qt.
9*/
10
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14
15#include "zlib.h"
16#include "ioapi.h"
17#include "quazip_global.h"
18#include <QIODevice>
19#if (QT_VERSION >= 0x050100)
20#define QUAZIP_QSAVEFILE_BUG_WORKAROUND
21#endif
22#ifdef QUAZIP_QSAVEFILE_BUG_WORKAROUND
23#include <QSaveFile>
24#endif
25
26/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
27
28#ifndef SEEK_CUR
29#define SEEK_CUR 1
30#endif
31
32#ifndef SEEK_END
33#define SEEK_END 2
34#endif
35
36#ifndef SEEK_SET
37#define SEEK_SET 0
38#endif
39
40voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,voidpf file,int mode)
41{
42 if (pfilefunc->zfile_func64.zopen64_file != NULL)
43 return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,file,mode);
44 else
45 {
46 return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,file,mode);
47 }
48}
49
50int call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)
51{
52 if (pfilefunc->zfile_func64.zseek64_file != NULL)
53 return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin);
54 else
55 {
56 uLong offsetTruncated = (uLong)offset;
57 if (offsetTruncated != offset)
58 return -1;
59 else
60 return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin);
61 }
62}
63
64ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)
65{
66 if (pfilefunc->zfile_func64.zseek64_file != NULL)
67 return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream);
68 else
69 {
70 uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream);
71 if ((tell_uLong) == ((uLong)-1))
72 return (ZPOS64_T)-1;
73 else
74 return tell_uLong;
75 }
76}
77
78struct QIODevice_descriptor {
79 // Position only used for writing to sequential devices.
80 qint64 pos;
81 inline QIODevice_descriptor():
82 pos(0)
83 {}
84};
85
86voidpf ZCALLBACK qiodevice_open_file_func (
87 voidpf opaque,
88 voidpf file,
89 int mode)
90{
91 QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque);
92 QIODevice *iodevice = reinterpret_cast<QIODevice*>(file);
93 QIODevice::OpenMode desiredMode;
94 if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
95 desiredMode = QIODevice::ReadOnly;
96 else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
97 desiredMode = QIODevice::ReadWrite;
98 else if (mode & ZLIB_FILEFUNC_MODE_CREATE)
99 desiredMode = QIODevice::WriteOnly;
100 if (iodevice->isOpen()) {
101 if ((iodevice->openMode() & desiredMode) == desiredMode) {
102 if (desiredMode != QIODevice::WriteOnly
103 && iodevice->isSequential()) {
104 // We can use sequential devices only for writing.
105 delete d;
106 return NULL;
107 } else {
108 if ((desiredMode & QIODevice::WriteOnly) != 0) {
109 // open for writing, need to seek existing device
110 if (!iodevice->isSequential()) {
111 iodevice->seek(0);
112 } else {
113 d->pos = iodevice->pos();
114 }
115 }
116 }
117 return iodevice;
118 } else {
119 delete d;
120 return NULL;
121 }
122 }
123 iodevice->open(desiredMode);
124 if (iodevice->isOpen()) {
125 if (desiredMode != QIODevice::WriteOnly && iodevice->isSequential()) {
126 // We can use sequential devices only for writing.
127 iodevice->close();
128 delete d;
129 return NULL;
130 } else {
131 return iodevice;
132 }
133 } else {
134 delete d;
135 return NULL;
136 }
137}
138
139
140uLong ZCALLBACK qiodevice_read_file_func (
141 voidpf opaque,
142 voidpf stream,
143 void* buf,
144 uLong size)
145{
146 QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque);
147 QIODevice *iodevice = reinterpret_cast<QIODevice*>(stream);
148 qint64 ret64 = iodevice->read((char*)buf,size);
149 uLong ret;
150 ret = (uLong) ret64;
151 if (ret64 != -1) {
152 d->pos += ret64;
153 }
154 return ret;
155}
156
157
158uLong ZCALLBACK qiodevice_write_file_func (
159 voidpf opaque,
160 voidpf stream,
161 const void* buf,
162 uLong size)
163{
164 QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque);
165 QIODevice *iodevice = reinterpret_cast<QIODevice*>(stream);
166 uLong ret;
167 qint64 ret64 = iodevice->write((char*)buf,size);
168 if (ret64 != -1) {
169 d->pos += ret64;
170 }
171 ret = (uLong) ret64;
172 return ret;
173}
174
175uLong ZCALLBACK qiodevice_tell_file_func (
176 voidpf opaque,
177 voidpf stream)
178{
179 QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque);
180 QIODevice *iodevice = reinterpret_cast<QIODevice*>(stream);
181 uLong ret;
182 qint64 ret64;
183 if (iodevice->isSequential()) {
184 ret64 = d->pos;
185 } else {
186 ret64 = iodevice->pos();
187 }
188 ret = static_cast<uLong>(ret64);
189 return ret;
190}
191
192ZPOS64_T ZCALLBACK qiodevice64_tell_file_func (
193 voidpf opaque,
194 voidpf stream)
195{
196 QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque);
197 QIODevice *iodevice = reinterpret_cast<QIODevice*>(stream);
198 qint64 ret;
199 if (iodevice->isSequential()) {
200 ret = d->pos;
201 } else {
202 ret = iodevice->pos();
203 }
204 return static_cast<ZPOS64_T>(ret);
205}
206
207int ZCALLBACK qiodevice_seek_file_func (
208 voidpf /*opaque UNUSED*/,
209 voidpf stream,
210 uLong offset,
211 int origin)
212{
213 QIODevice *iodevice = reinterpret_cast<QIODevice*>(stream);
214 if (iodevice->isSequential()) {
215 if (origin == ZLIB_FILEFUNC_SEEK_END
216 && offset == 0) {
217 // sequential devices are always at end (needed in mdAppend)
218 return 0;
219 } else {
220 qWarning("qiodevice_seek_file_func() called for sequential device");
221 return -1;
222 }
223 }
224 uLong qiodevice_seek_result=0;
225 int ret;
226 switch (origin)
227 {
228 case ZLIB_FILEFUNC_SEEK_CUR :
229 qiodevice_seek_result = ((QIODevice*)stream)->pos() + offset;
230 break;
231 case ZLIB_FILEFUNC_SEEK_END :
232 qiodevice_seek_result = ((QIODevice*)stream)->size() - offset;
233 break;
234 case ZLIB_FILEFUNC_SEEK_SET :
235 qiodevice_seek_result = offset;
236 break;
237 default:
238 return -1;
239 }
240 ret = !iodevice->seek(qiodevice_seek_result);
241 return ret;
242}
243
244int ZCALLBACK qiodevice64_seek_file_func (
245 voidpf /*opaque UNUSED*/,
246 voidpf stream,
247 ZPOS64_T offset,
248 int origin)
249{
250 QIODevice *iodevice = reinterpret_cast<QIODevice*>(stream);
251 if (iodevice->isSequential()) {
252 if (origin == ZLIB_FILEFUNC_SEEK_END
253 && offset == 0) {
254 // sequential devices are always at end (needed in mdAppend)
255 return 0;
256 } else {
257 qWarning("qiodevice_seek_file_func() called for sequential device");
258 return -1;
259 }
260 }
261 qint64 qiodevice_seek_result=0;
262 int ret;
263 switch (origin)
264 {
265 case ZLIB_FILEFUNC_SEEK_CUR :
266 qiodevice_seek_result = ((QIODevice*)stream)->pos() + offset;
267 break;
268 case ZLIB_FILEFUNC_SEEK_END :
269 qiodevice_seek_result = ((QIODevice*)stream)->size() - offset;
270 break;
271 case ZLIB_FILEFUNC_SEEK_SET :
272 qiodevice_seek_result = offset;
273 break;
274 default:
275 return -1;
276 }
277 ret = !iodevice->seek(qiodevice_seek_result);
278 return ret;
279}
280
281int ZCALLBACK qiodevice_close_file_func (
282 voidpf opaque,
283 voidpf stream)
284{
285 QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque);
286 delete d;
287 QIODevice *device = reinterpret_cast<QIODevice*>(stream);
288#ifdef QUAZIP_QSAVEFILE_BUG_WORKAROUND
289 // QSaveFile terribly breaks the is-a idiom:
290 // it IS a QIODevice, but it is NOT compatible with it: close() is private
291 QSaveFile *file = qobject_cast<QSaveFile*>(device);
292 if (file != NULL) {
293 // We have to call the ugly commit() instead:
294 return file->commit() ? 0 : -1;
295 }
296#endif
297 device->close();
298 return 0;
299}
300
301int ZCALLBACK qiodevice_fakeclose_file_func (
302 voidpf opaque,
303 voidpf /*stream*/)
304{
305 QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque);
306 delete d;
307 return 0;
308}
309
310int ZCALLBACK qiodevice_error_file_func (
311 voidpf /*opaque UNUSED*/,
312 voidpf /*stream UNUSED*/)
313{
314 // can't check for error due to the QIODevice API limitation
315 return 0;
316}
317
318void fill_qiodevice_filefunc (
319 zlib_filefunc_def* pzlib_filefunc_def)
320{
321 pzlib_filefunc_def->zopen_file = qiodevice_open_file_func;
322 pzlib_filefunc_def->zread_file = qiodevice_read_file_func;
323 pzlib_filefunc_def->zwrite_file = qiodevice_write_file_func;
324 pzlib_filefunc_def->ztell_file = qiodevice_tell_file_func;
325 pzlib_filefunc_def->zseek_file = qiodevice_seek_file_func;
326 pzlib_filefunc_def->zclose_file = qiodevice_close_file_func;
327 pzlib_filefunc_def->zerror_file = qiodevice_error_file_func;
328 pzlib_filefunc_def->opaque = new QIODevice_descriptor;
329}
330
331void fill_qiodevice64_filefunc (
332 zlib_filefunc64_def* pzlib_filefunc_def)
333{
334 // Open functions are the same for Qt.
335 pzlib_filefunc_def->zopen64_file = qiodevice_open_file_func;
336 pzlib_filefunc_def->zread_file = qiodevice_read_file_func;
337 pzlib_filefunc_def->zwrite_file = qiodevice_write_file_func;
338 pzlib_filefunc_def->ztell64_file = qiodevice64_tell_file_func;
339 pzlib_filefunc_def->zseek64_file = qiodevice64_seek_file_func;
340 pzlib_filefunc_def->zclose_file = qiodevice_close_file_func;
341 pzlib_filefunc_def->zerror_file = qiodevice_error_file_func;
342 pzlib_filefunc_def->opaque = new QIODevice_descriptor;
343 pzlib_filefunc_def->zfakeclose_file = qiodevice_fakeclose_file_func;
344}
345
346void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32)
347{
348 p_filefunc64_32->zfile_func64.zopen64_file = NULL;
349 p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file;
350 p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
351 p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file;
352 p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file;
353 p_filefunc64_32->zfile_func64.ztell64_file = NULL;
354 p_filefunc64_32->zfile_func64.zseek64_file = NULL;
355 p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file;
356 p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
357 p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque;
358 p_filefunc64_32->zfile_func64.zfakeclose_file = NULL;
359 p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file;
360 p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file;
361}