diff options
Diffstat (limited to 'rbutil/rbutilqt/quazip/qioapi.cpp')
-rw-r--r-- | rbutil/rbutilqt/quazip/qioapi.cpp | 361 |
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 | |||
40 | voidpf 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 | |||
50 | int 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 | |||
64 | ZPOS64_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 | |||
78 | struct QIODevice_descriptor { | ||
79 | // Position only used for writing to sequential devices. | ||
80 | qint64 pos; | ||
81 | inline QIODevice_descriptor(): | ||
82 | pos(0) | ||
83 | {} | ||
84 | }; | ||
85 | |||
86 | voidpf 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 | |||
140 | uLong 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 | |||
158 | uLong 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 | |||
175 | uLong 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 | |||
192 | ZPOS64_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 | |||
207 | int 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 | |||
244 | int 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 | |||
281 | int 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 | |||
301 | int 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 | |||
310 | int 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 | |||
318 | void 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 | |||
331 | void 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 | |||
346 | void 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 | } | ||