ckb-next  v0.2.8 at branch master
ckb-next driver for corsair devices
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
qioapi.cpp
Go to the documentation of this file.
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 
79  // Position only used for writing to sequential devices.
80  qint64 pos;
82  pos(0)
83  {}
84 };
85 
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;
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 
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 
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 
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 
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 
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  {
229  qiodevice_seek_result = ((QIODevice*)stream)->pos() + offset;
230  break;
232  qiodevice_seek_result = ((QIODevice*)stream)->size() - offset;
233  break;
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 
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  {
266  qiodevice_seek_result = ((QIODevice*)stream)->pos() + offset;
267  break;
269  qiodevice_seek_result = ((QIODevice*)stream)->size() - offset;
270  break;
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 
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 
302  voidpf opaque,
303  voidpf /*stream*/)
304 {
305  QIODevice_descriptor *d = reinterpret_cast<QIODevice_descriptor*>(opaque);
306  delete d;
307  return 0;
308 }
309 
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 
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 
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 
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 }
uLong qiodevice_read_file_func(voidpf opaque, voidpf stream, void *buf, uLong size)
Definition: qioapi.cpp:140
uLong qiodevice_write_file_func(voidpf opaque, voidpf stream, const void *buf, uLong size)
Definition: qioapi.cpp:158
seek_file_func zseek_file
Definition: ioapi.h:149
void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def *p_filefunc64_32, const zlib_filefunc_def *p_filefunc32)
Definition: qioapi.cpp:346
close_file_func zclose_file
Definition: ioapi.h:150
int qiodevice_seek_file_func(voidpf, voidpf stream, uLong offset, int origin)
Definition: qioapi.cpp:207
int qiodevice_close_file_func(voidpf opaque, voidpf stream)
Definition: qioapi.cpp:281
read_file_func zread_file
Definition: ioapi.h:146
void fill_qiodevice64_filefunc(zlib_filefunc64_def *pzlib_filefunc_def)
Definition: qioapi.cpp:331
seek64_file_func zseek64_file
Definition: ioapi.h:165
int qiodevice_error_file_func(voidpf, voidpf)
Definition: qioapi.cpp:310
testerror_file_func zerror_file
Definition: ioapi.h:167
tell64_file_func ztell64_file
Definition: ioapi.h:164
close_file_func zclose_file
Definition: ioapi.h:166
tell_file_func ztell_file
Definition: ioapi.h:148
#define ZLIB_FILEFUNC_MODE_READWRITEFILTER
Definition: ioapi.h:115
open_file_func zopen_file
Definition: ioapi.h:145
testerror_file_func zerror_file
Definition: ioapi.h:151
voidpf call_zopen64(const zlib_filefunc64_32_def *pfilefunc, voidpf file, int mode)
Definition: qioapi.cpp:40
#define ZCALLBACK
Definition: ioapi.h:125
#define ZLIB_FILEFUNC_MODE_READ
Definition: ioapi.h:113
uLong qiodevice_tell_file_func(voidpf opaque, voidpf stream)
Definition: qioapi.cpp:175
zlib_filefunc64_def zfile_func64
Definition: ioapi.h:178
tell_file_func ztell32_file
Definition: ioapi.h:180
open_file_func zopen32_file
Definition: ioapi.h:179
read_file_func zread_file
Definition: ioapi.h:162
void fill_qiodevice_filefunc(zlib_filefunc_def *pzlib_filefunc_def)
Definition: qioapi.cpp:318
#define ZLIB_FILEFUNC_SEEK_CUR
Definition: ioapi.h:109
ZPOS64_T qiodevice64_tell_file_func(voidpf opaque, voidpf stream)
Definition: qioapi.cpp:192
int qiodevice_fakeclose_file_func(voidpf opaque, voidpf)
Definition: qioapi.cpp:301
#define ZLIB_FILEFUNC_MODE_CREATE
Definition: ioapi.h:118
unsigned long long int ZPOS64_T
Definition: ioapi.h:94
write_file_func zwrite_file
Definition: ioapi.h:163
#define ZLIB_FILEFUNC_MODE_EXISTING
Definition: ioapi.h:117
write_file_func zwrite_file
Definition: ioapi.h:147
close_file_func zfakeclose_file
Definition: ioapi.h:169
voidpf qiodevice_open_file_func(voidpf opaque, voidpf file, int mode)
Definition: qioapi.cpp:86
seek_file_func zseek32_file
Definition: ioapi.h:181
ZPOS64_T call_ztell64(const zlib_filefunc64_32_def *pfilefunc, voidpf filestream)
Definition: qioapi.cpp:64
int call_zseek64(const zlib_filefunc64_32_def *pfilefunc, voidpf filestream, ZPOS64_T offset, int origin)
Definition: qioapi.cpp:50
#define ZLIB_FILEFUNC_SEEK_END
Definition: ioapi.h:110
open64_file_func zopen64_file
Definition: ioapi.h:161
#define ZLIB_FILEFUNC_SEEK_SET
Definition: ioapi.h:111
int qiodevice64_seek_file_func(voidpf, voidpf stream, ZPOS64_T offset, int origin)
Definition: qioapi.cpp:244