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
quazipfile.cpp
Go to the documentation of this file.
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, see
22 quazip/(un)zip.h files for details, basically it's zlib license.
23  **/
24 
25 #include "quazipfile.h"
26 
27 using namespace std;
28 
30 
38  friend class QuaZipFile;
39  private:
45  QString fileName;
49  bool raw;
51 
55  qint64 writePos;
59  quint32 crc;
61 
65  bool internal;
67  int zipError;
69  inline void resetZipError() const {setZipError(UNZ_OK);}
71 
76  void setZipError(int zipError) const;
79  q(q), zip(NULL), internal(true), zipError(UNZ_OK) {}
81  inline QuaZipFilePrivate(QuaZipFile *q, const QString &zipName):
82  q(q), internal(true), zipError(UNZ_OK)
83  {
84  zip=new QuaZip(zipName);
85  }
87  inline QuaZipFilePrivate(QuaZipFile *q, const QString &zipName, const QString &fileName,
89  q(q), internal(true), zipError(UNZ_OK)
90  {
91  zip=new QuaZip(zipName);
92  this->fileName=fileName;
93  if (this->fileName.startsWith('/'))
94  this->fileName = this->fileName.mid(1);
95  this->caseSensitivity=cs;
96  }
99  q(q), zip(zip), internal(false), zipError(UNZ_OK) {}
102  {
103  if (internal)
104  delete zip;
105  }
106 };
107 
109  p(new QuaZipFilePrivate(this))
110 {
111 }
112 
114  QIODevice(parent),
115  p(new QuaZipFilePrivate(this))
116 {
117 }
118 
119 QuaZipFile::QuaZipFile(const QString& zipName, QObject *parent):
120  QIODevice(parent),
121  p(new QuaZipFilePrivate(this, zipName))
122 {
123 }
124 
125 QuaZipFile::QuaZipFile(const QString& zipName, const QString& fileName,
126  QuaZip::CaseSensitivity cs, QObject *parent):
127  QIODevice(parent),
128  p(new QuaZipFilePrivate(this, zipName, fileName, cs))
129 {
130 }
131 
133  QIODevice(parent),
134  p(new QuaZipFilePrivate(this, zip))
135 {
136 }
137 
139 {
140  if (isOpen())
141  close();
142  delete p;
143 }
144 
145 QString QuaZipFile::getZipName() const
146 {
147  return p->zip==NULL ? QString() : p->zip->getZipName();
148 }
149 
151 {
152  return p->internal ? NULL : p->zip;
153 }
154 
156 {
157  p->setZipError(UNZ_OK);
158  if (p->zip == NULL || (openMode() & WriteOnly))
159  return QString();
160  QString name=p->zip->getCurrentFileName();
161  if(name.isNull())
162  p->setZipError(p->zip->getZipError());
163  return name;
164 }
165 
166 void QuaZipFile::setZipName(const QString& zipName)
167 {
168  if(isOpen()) {
169  qWarning("QuaZipFile::setZipName(): file is already open - can not set ZIP name");
170  return;
171  }
172  if(p->zip!=NULL && p->internal)
173  delete p->zip;
174  p->zip=new QuaZip(zipName);
175  p->internal=true;
176 }
177 
179 {
180  if(isOpen()) {
181  qWarning("QuaZipFile::setZip(): file is already open - can not set ZIP");
182  return;
183  }
184  if(p->zip!=NULL && p->internal)
185  delete p->zip;
186  p->zip=zip;
187  p->fileName=QString();
188  p->internal=false;
189 }
190 
191 void QuaZipFile::setFileName(const QString& fileName, QuaZip::CaseSensitivity cs)
192 {
193  if(p->zip==NULL) {
194  qWarning("QuaZipFile::setFileName(): call setZipName() first");
195  return;
196  }
197  if(!p->internal) {
198  qWarning("QuaZipFile::setFileName(): should not be used when not using internal QuaZip");
199  return;
200  }
201  if(isOpen()) {
202  qWarning("QuaZipFile::setFileName(): can not set file name for already opened file");
203  return;
204  }
205  p->fileName=fileName;
206  if (p->fileName.startsWith('/'))
207  p->fileName = p->fileName.mid(1);
208  p->caseSensitivity=cs;
209 }
210 
211 void QuaZipFilePrivate::setZipError(int zipError) const
212 {
213  QuaZipFilePrivate *fakeThis = const_cast<QuaZipFilePrivate*>(this); // non-const
214  fakeThis->zipError=zipError;
215  if(zipError==UNZ_OK)
216  q->setErrorString(QString());
217  else
218  q->setErrorString(QuaZipFile::tr("ZIP/UNZIP API error %1").arg(zipError));
219 }
220 
221 bool QuaZipFile::open(OpenMode mode)
222 {
223  return open(mode, NULL);
224 }
225 
226 bool QuaZipFile::open(OpenMode mode, int *method, int *level, bool raw, const char *password)
227 {
228  p->resetZipError();
229  if(isOpen()) {
230  qWarning("QuaZipFile::open(): already opened");
231  return false;
232  }
233  if(mode&Unbuffered) {
234  qWarning("QuaZipFile::open(): Unbuffered mode is not supported");
235  return false;
236  }
237  if((mode&ReadOnly)&&!(mode&WriteOnly)) {
238  if(p->internal) {
239  if(!p->zip->open(QuaZip::mdUnzip)) {
240  p->setZipError(p->zip->getZipError());
241  return false;
242  }
244  p->setZipError(p->zip->getZipError());
245  p->zip->close();
246  return false;
247  }
248  } else {
249  if(p->zip==NULL) {
250  qWarning("QuaZipFile::open(): zip is NULL");
251  return false;
252  }
253  if(p->zip->getMode()!=QuaZip::mdUnzip) {
254  qWarning("QuaZipFile::open(): file open mode %d incompatible with ZIP open mode %d",
255  (int)mode, (int)p->zip->getMode());
256  return false;
257  }
258  if(!p->zip->hasCurrentFile()) {
259  qWarning("QuaZipFile::open(): zip does not have current file");
260  return false;
261  }
262  }
263  p->setZipError(unzOpenCurrentFile3(p->zip->getUnzFile(), method, level, (int)raw, password));
264  if(p->zipError==UNZ_OK) {
265  setOpenMode(mode);
266  p->raw=raw;
267  return true;
268  } else
269  return false;
270  }
271  qWarning("QuaZipFile::open(): open mode %d not supported by this function", (int)mode);
272  return false;
273 }
274 
275 bool QuaZipFile::open(OpenMode mode, const QuaZipNewInfo& info,
276  const char *password, quint32 crc,
277  int method, int level, bool raw,
278  int windowBits, int memLevel, int strategy)
279 {
280  zip_fileinfo info_z;
281  p->resetZipError();
282  if(isOpen()) {
283  qWarning("QuaZipFile::open(): already opened");
284  return false;
285  }
286  if((mode&WriteOnly)&&!(mode&ReadOnly)) {
287  if(p->internal) {
288  qWarning("QuaZipFile::open(): write mode is incompatible with internal QuaZip approach");
289  return false;
290  }
291  if(p->zip==NULL) {
292  qWarning("QuaZipFile::open(): zip is NULL");
293  return false;
294  }
296  qWarning("QuaZipFile::open(): file open mode %d incompatible with ZIP open mode %d",
297  (int)mode, (int)p->zip->getMode());
298  return false;
299  }
300  info_z.tmz_date.tm_year=info.dateTime.date().year();
301  info_z.tmz_date.tm_mon=info.dateTime.date().month() - 1;
302  info_z.tmz_date.tm_mday=info.dateTime.date().day();
303  info_z.tmz_date.tm_hour=info.dateTime.time().hour();
304  info_z.tmz_date.tm_min=info.dateTime.time().minute();
305  info_z.tmz_date.tm_sec=info.dateTime.time().second();
306  info_z.dosDate = 0;
307  info_z.internal_fa=(uLong)info.internalAttr;
308  info_z.external_fa=(uLong)info.externalAttr;
311  else
314  p->zip->getFileNameCodec()->fromUnicode(info.name).constData(), &info_z,
315  info.extraLocal.constData(), info.extraLocal.length(),
316  info.extraGlobal.constData(), info.extraGlobal.length(),
317  p->zip->getCommentCodec()->fromUnicode(info.comment).constData(),
318  method, level, (int)raw,
319  windowBits, memLevel, strategy,
320  password, (uLong)crc, p->zip->isZip64Enabled()));
321  if(p->zipError==UNZ_OK) {
322  p->writePos=0;
323  setOpenMode(mode);
324  p->raw=raw;
325  if(raw) {
326  p->crc=crc;
328  }
329  return true;
330  } else
331  return false;
332  }
333  qWarning("QuaZipFile::open(): open mode %d not supported by this function", (int)mode);
334  return false;
335 }
336 
338 {
339  return true;
340 }
341 
342 qint64 QuaZipFile::pos()const
343 {
344  if(p->zip==NULL) {
345  qWarning("QuaZipFile::pos(): call setZipName() or setZip() first");
346  return -1;
347  }
348  if(!isOpen()) {
349  qWarning("QuaZipFile::pos(): file is not open");
350  return -1;
351  }
352  if(openMode()&ReadOnly)
353  // QIODevice::pos() is broken for sequential devices,
354  // but thankfully bytesAvailable() returns the number of
355  // bytes buffered, so we know how far ahead we are.
356  return unztell(p->zip->getUnzFile()) - QIODevice::bytesAvailable();
357  else
358  return p->writePos;
359 }
360 
361 bool QuaZipFile::atEnd()const
362 {
363  if(p->zip==NULL) {
364  qWarning("QuaZipFile::atEnd(): call setZipName() or setZip() first");
365  return false;
366  }
367  if(!isOpen()) {
368  qWarning("QuaZipFile::atEnd(): file is not open");
369  return false;
370  }
371  if(openMode()&ReadOnly)
372  // the same problem as with pos()
373  return QIODevice::bytesAvailable() == 0
374  && unzeof(p->zip->getUnzFile())==1;
375  else
376  return true;
377 }
378 
379 qint64 QuaZipFile::size()const
380 {
381  if(!isOpen()) {
382  qWarning("QuaZipFile::atEnd(): file is not open");
383  return -1;
384  }
385  if(openMode()&ReadOnly)
386  return p->raw?csize():usize();
387  else
388  return p->writePos;
389 }
390 
391 qint64 QuaZipFile::csize()const
392 {
393  unz_file_info64 info_z;
394  p->setZipError(UNZ_OK);
395  if(p->zip==NULL||p->zip->getMode()!=QuaZip::mdUnzip) return -1;
396  p->setZipError(unzGetCurrentFileInfo64(p->zip->getUnzFile(), &info_z, NULL, 0, NULL, 0, NULL, 0));
397  if(p->zipError!=UNZ_OK)
398  return -1;
399  return info_z.compressed_size;
400 }
401 
402 qint64 QuaZipFile::usize()const
403 {
404  unz_file_info64 info_z;
405  p->setZipError(UNZ_OK);
406  if(p->zip==NULL||p->zip->getMode()!=QuaZip::mdUnzip) return -1;
407  p->setZipError(unzGetCurrentFileInfo64(p->zip->getUnzFile(), &info_z, NULL, 0, NULL, 0, NULL, 0));
408  if(p->zipError!=UNZ_OK)
409  return -1;
410  return info_z.uncompressed_size;
411 }
412 
414 {
415  QuaZipFileInfo64 info64;
416  if (getFileInfo(&info64)) {
417  info64.toQuaZipFileInfo(*info);
418  return true;
419  } else {
420  return false;
421  }
422 }
423 
425 {
426  if(p->zip==NULL||p->zip->getMode()!=QuaZip::mdUnzip) return false;
427  p->zip->getCurrentFileInfo(info);
428  p->setZipError(p->zip->getZipError());
429  return p->zipError==UNZ_OK;
430 }
431 
433 {
434  p->resetZipError();
435  if(p->zip==NULL||!p->zip->isOpen()) return;
436  if(!isOpen()) {
437  qWarning("QuaZipFile::close(): file isn't open");
438  return;
439  }
440  if(openMode()&ReadOnly)
442  else if(openMode()&WriteOnly)
445  else {
446  qWarning("Wrong open mode: %d", (int)openMode());
447  return;
448  }
449  if(p->zipError==UNZ_OK) setOpenMode(QIODevice::NotOpen);
450  else return;
451  if(p->internal) {
452  p->zip->close();
453  p->setZipError(p->zip->getZipError());
454  }
455 }
456 
457 qint64 QuaZipFile::readData(char *data, qint64 maxSize)
458 {
459  p->setZipError(UNZ_OK);
460  qint64 bytesRead=unzReadCurrentFile(p->zip->getUnzFile(), data, (unsigned)maxSize);
461  if (bytesRead < 0) {
462  p->setZipError((int) bytesRead);
463  return -1;
464  }
465  return bytesRead;
466 }
467 
468 qint64 QuaZipFile::writeData(const char* data, qint64 maxSize)
469 {
470  p->setZipError(ZIP_OK);
471  p->setZipError(zipWriteInFileInZip(p->zip->getZipFile(), data, (uint)maxSize));
472  if(p->zipError!=ZIP_OK) return -1;
473  else {
474  p->writePos+=maxSize;
475  return maxSize;
476  }
477 }
478 
479 QString QuaZipFile::getFileName() const
480 {
481  return p->fileName;
482 }
483 
485 {
486  return p->caseSensitivity;
487 }
488 
489 bool QuaZipFile::isRaw() const
490 {
491  return p->raw;
492 }
493 
495 {
496  return p->zipError;
497 }
498 
500 {
501  return size() - pos();
502 }
quint32 crc
CRC to write along with a raw file.
Definition: quazipfile.cpp:59
#define ZIP_OK
Definition: zip.h:78
ZPOS64_T compressed_size
Definition: unzip.h:127
virtual qint64 pos() const
Returns current position in the file.
Definition: quazipfile.cpp:342
QuaZipFilePrivate * p
Definition: quazipfile.h:78
qint64 readData(char *data, qint64 maxSize)
Implementation of the QIODevice::readData().
Definition: quazipfile.cpp:457
tm_zip tmz_date
Definition: zip.h:112
bool isOpen() const
Returns true if ZIP file is open, false otherwise.
Definition: quazip.cpp:619
#define ZIP_WRITE_DATA_DESCRIPTOR
Definition: zip.h:85
virtual bool isSequential() const
Returns true, but beware!
Definition: quazipfile.cpp:337
QuaZipFilePrivate(QuaZipFile *q, const QString &zipName, const QString &fileName, QuaZip::CaseSensitivity cs)
The constructor for the corresponding QuaZipFile constructor.
Definition: quazipfile.cpp:87
int zipError
The last error.
Definition: quazipfile.cpp:67
uLong external_fa
Definition: zip.h:117
qint64 writeData(const char *data, qint64 maxSize)
Implementation of the QIODevice::writeData().
Definition: quazipfile.cpp:468
QString getActualFileName() const
Returns the actual file name in the archive.
Definition: quazipfile.cpp:155
int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_size, uLong crc32)
Definition: zip.c:1554
qint64 csize() const
Returns compressed file size.
Definition: quazipfile.cpp:391
QuaZipFile * q
The pointer to the associated QuaZipFile instance.
Definition: quazipfile.cpp:41
QString getCurrentFileName() const
Returns the current file name.
Definition: quazip.cpp:551
#define UNZ_OK
Definition: unzip.h:79
QTextCodec * getCommentCodec() const
Returns the codec used to encode/decode comments inside archive.
Definition: quazip.cpp:597
Information about a file to be created.
Definition: quazipnewinfo.h:50
quint16 internalAttr
File internal attributes.
Definition: quazipnewinfo.h:64
QByteArray extraLocal
File local extra field.
Definition: quazipnewinfo.h:77
ulong uncompressedSize
Uncompressed file size.
Definition: quazipnewinfo.h:84
QString comment
File comment.
Definition: quazipnewinfo.h:75
uInt tm_min
Definition: zip.h:103
virtual qint64 bytesAvailable() const
Returns the number of bytes available for reading.
Definition: quazipfile.cpp:499
ZIP file was opened for adding files in the archive.
Definition: quazip.h:106
Mode getMode() const
Returns the mode in which ZIP file was opened.
Definition: quazip.cpp:614
int ZEXPORT unzOpenCurrentFile3(unzFile file, int *method, int *level, int raw, const char *password)
Definition: unzip.c:1480
void setZipName(const QString &zipName)
Sets the ZIP archive file name.
Definition: quazipfile.cpp:166
ZIP file was created with open() call.
Definition: quazip.h:97
uInt tm_hour
Definition: zip.h:104
virtual void close()
Closes the file.
Definition: quazipfile.cpp:432
~QuaZipFilePrivate()
The destructor.
Definition: quazipfile.cpp:101
int getZipError() const
Returns the error code of the last operation.
Definition: quazip.cpp:624
qint64 writePos
Write position to keep track of.
Definition: quazipfile.cpp:55
int ZEXPORT unzeof(unzFile file)
Definition: unzip.c:1932
bool toQuaZipFileInfo(QuaZipFileInfo &info) const
Converts to QuaZipFileInfo.
Information about a file inside archive.
void setZip(QuaZip *zip)
Binds to the existing QuaZip instance.
Definition: quazipfile.cpp:178
QuaZip::CaseSensitivity getCaseSensitivity() const
Returns case sensitivity of the file name.
Definition: quazipfile.cpp:484
void setZipError(int zipError) const
Sets the zip error.
Definition: quazipfile.cpp:211
int ZEXPORT zipWriteInFileInZip(zipFile file, const void *buf, unsigned int len)
Definition: zip.c:1442
qint64 usize() const
Returns uncompressed file size.
Definition: quazipfile.cpp:402
uInt tm_sec
Definition: zip.h:102
int ZEXPORT zipSetFlags(zipFile file, unsigned flags)
Definition: zip.c:2077
ZPOS64_T uncompressed_size
Definition: unzip.h:128
int ZEXPORT unzReadCurrentFile(unzFile file, voidp buf, unsigned len)
Addition for GDAL : END.
Definition: unzip.c:1692
QString fileName
The file name.
Definition: quazipfile.cpp:45
zipFile getZipFile()
Returns zipFile handle.
Definition: quazip.cpp:644
QuaZipFilePrivate(QuaZipFile *q, const QString &zipName)
The constructor for the corresponding QuaZipFile constructor.
Definition: quazipfile.cpp:81
bool internal
Whether zip points to an internal QuaZip instance.
Definition: quazipfile.cpp:65
QuaZipFilePrivate(QuaZipFile *q, QuaZip *zip)
The constructor for the QuaZipFile constructor accepting a file name.
Definition: quazipfile.cpp:98
int getZipError() const
Returns the error code returned by the last ZIP/UNZIP API call.
Definition: quazipfile.cpp:494
QString getZipName() const
Returns the name of the ZIP file.
Definition: quazip.cpp:602
bool isZip64Enabled() const
Returns whether the zip64 mode is enabled.
Definition: quazip.cpp:775
int ZEXPORT unzCloseCurrentFile(unzFile file)
Definition: unzip.c:2012
uLong dosDate
Definition: zip.h:113
QDateTime dateTime
File timestamp.
Definition: quazipnewinfo.h:62
void setFileName(const QString &fileName, QuaZip::CaseSensitivity cs=QuaZip::csDefault)
Sets the file name.
Definition: quazipfile.cpp:191
QByteArray extraGlobal
File global extra field.
Definition: quazipnewinfo.h:79
Information about a file inside archive (with zip64 support).
QTextCodec * getFileNameCodec() const
Returns the codec used to encode/decode comments inside archive.
Definition: quazip.cpp:582
QuaZipFile()
Constructs a QuaZipFile instance.
Definition: quazipfile.cpp:108
bool setCurrentFile(const QString &fileName, CaseSensitivity cs=csDefault)
Sets current file by its name.
Definition: quazip.cpp:408
ZIP file is open for reading files inside it.
Definition: quazip.h:96
uInt tm_mday
Definition: zip.h:105
void close()
Closes ZIP file.
Definition: quazip.cpp:324
uInt tm_mon
Definition: zip.h:106
quint32 externalAttr
File external attributes.
Definition: quazipnewinfo.h:71
QuaZip::CaseSensitivity caseSensitivity
Case sensitivity mode.
Definition: quazipfile.cpp:47
QString name
File name.
Definition: quazipnewinfo.h:55
virtual qint64 size() const
Returns file size.
Definition: quazipfile.cpp:379
ZIP archive.
Definition: quazip.h:84
QString getZipName() const
Returns the ZIP archive file name.
Definition: quazipfile.cpp:145
int ZEXPORT unzGetCurrentFileInfo64(unzFile file, unz_file_info64 *pfile_info, char *szFileName, uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, char *szComment, uLong commentBufferSize)
Definition: unzip.c:1134
int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char *filename, const zip_fileinfo *zipfi, const void *extrafield_local, uInt size_extrafield_local, const void *extrafield_global, uInt size_extrafield_global, const char *comment, int method, int level, int raw, int windowBits, int memLevel, int strategy, const char *password, uLong crcForCrypting, int zip64)
Definition: zip.c:1336
A file inside ZIP archive.
Definition: quazipfile.h:74
unzFile getUnzFile()
Returns unzFile handle.
Definition: quazip.cpp:639
CaseSensitivity
Case sensitivity for the file names.
Definition: quazip.h:114
virtual bool open(OpenMode mode)
Opens a file for reading.
Definition: quazipfile.cpp:221
bool isDataDescriptorWritingEnabled() const
Returns the data descriptor default writing mode.
Definition: quazip.cpp:654
z_off_t ZEXPORT unztell(unzFile file)
Definition: unzip.c:1897
ZIP file was opened in append mode.
Definition: quazip.h:98
uLong internal_fa
Definition: zip.h:116
bool open(Mode mode, zlib_filefunc_def *ioApi=NULL)
Opens ZIP file.
Definition: quazip.cpp:215
bool hasCurrentFile() const
Returns true if the current file has been set.
Definition: quazip.cpp:634
The implementation class for QuaZip.
Definition: quazipfile.cpp:37
QuaZipFilePrivate(QuaZipFile *q)
The constructor for the corresponding QuaZipFile constructor.
Definition: quazipfile.cpp:78
QuaZip * zip
The QuaZip object to work with.
Definition: quazipfile.cpp:43
int ZEXPORT zipCloseFileInZip(zipFile file)
Definition: zip.c:1810
virtual ~QuaZipFile()
Destroys a QuaZipFile instance.
Definition: quazipfile.cpp:138
bool raw
Whether this file is opened in the raw mode.
Definition: quazipfile.cpp:49
bool getFileInfo(QuaZipFileInfo *info)
Gets information about current file.
Definition: quazipfile.cpp:413
QuaZip * getZip() const
Returns a pointer to the associated QuaZip object.
Definition: quazipfile.cpp:150
quint64 uncompressedSize
Uncompressed size to write along with a raw file.
Definition: quazipfile.cpp:57
QString getFileName() const
Returns file name.
Definition: quazipfile.cpp:479
int ZEXPORT zipClearFlags(zipFile file, unsigned flags)
Definition: zip.c:2091
bool getCurrentFileInfo(QuaZipFileInfo *info) const
Retrieves information about the current file.
Definition: quazip.cpp:492
bool isRaw() const
Returns true if the file was opened in raw mode.
Definition: quazipfile.cpp:489
virtual bool atEnd() const
Returns true if the end of file was reached.
Definition: quazipfile.cpp:361
void resetZipError() const
Resets zipError.
Definition: quazipfile.cpp:69
uInt tm_year
Definition: zip.h:107