File indexing completed on 2025-02-02 04:36:33
0001 /* 0002 Copyright (C) 2005-2014 Sergey A. Tachenov 0003 0004 This file is part of QuaZIP. 0005 0006 QuaZIP is free software: you can redistribute it and/or modify 0007 it under the terms of the GNU Lesser General Public License as published by 0008 the Free Software Foundation, either version 2.1 of the License, or 0009 (at your option) any later version. 0010 0011 QuaZIP is distributed in the hope that it will be useful, 0012 but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0014 GNU Lesser General Public License for more details. 0015 0016 You should have received a copy of the GNU Lesser General Public License 0017 along with QuaZIP. If not, see <http://www.gnu.org/licenses/>. 0018 0019 See COPYING file for the full LGPL text. 0020 0021 Original ZIP package is copyrighted by Gilles Vollant, see 0022 quazip/(un)zip.h files for details, basically it's zlib license. 0023 **/ 0024 0025 #include <QFile> 0026 #include <QFlags> 0027 #include <QHash> 0028 0029 #include "quazip.h" 0030 0031 /// All the internal stuff for the QuaZip class. 0032 /** 0033 \internal 0034 0035 This class keeps all the private stuff for the QuaZip class so it can 0036 be changed without breaking binary compatibility, according to the 0037 Pimpl idiom. 0038 */ 0039 class QuaZipPrivate { 0040 friend class QuaZip; 0041 private: 0042 Q_DISABLE_COPY(QuaZipPrivate) 0043 /// The pointer to the corresponding QuaZip instance. 0044 QuaZip *q; 0045 /// The codec for file names. 0046 QTextCodec *fileNameCodec; 0047 /// The codec for comments. 0048 QTextCodec *commentCodec; 0049 /// The archive file name. 0050 QString zipName; 0051 /// The device to access the archive. 0052 QIODevice *ioDevice; 0053 /// The global comment. 0054 QString comment; 0055 /// The open mode. 0056 QuaZip::Mode mode; 0057 union { 0058 /// The internal handle for UNZIP modes. 0059 unzFile unzFile_f; 0060 /// The internal handle for ZIP modes. 0061 zipFile zipFile_f; 0062 }; 0063 /// Whether a current file is set. 0064 bool hasCurrentFile_f; 0065 /// The last error. 0066 int zipError; 0067 /// Whether \ref QuaZip::setDataDescriptorWritingEnabled() "the data descriptor writing mode" is enabled. 0068 bool dataDescriptorWritingEnabled; 0069 /// The zip64 mode. 0070 bool zip64; 0071 /// The auto-close flag. 0072 bool autoClose; 0073 inline QTextCodec *getDefaultFileNameCodec() 0074 { 0075 if (defaultFileNameCodec == NULL) { 0076 return QTextCodec::codecForLocale(); 0077 } else { 0078 return defaultFileNameCodec; 0079 } 0080 } 0081 /// The constructor for the corresponding QuaZip constructor. 0082 inline QuaZipPrivate(QuaZip *q): 0083 q(q), 0084 fileNameCodec(getDefaultFileNameCodec()), 0085 commentCodec(QTextCodec::codecForLocale()), 0086 ioDevice(NULL), 0087 mode(QuaZip::mdNotOpen), 0088 hasCurrentFile_f(false), 0089 zipError(UNZ_OK), 0090 dataDescriptorWritingEnabled(true), 0091 zip64(false), 0092 autoClose(true) 0093 { 0094 unzFile_f = NULL; 0095 zipFile_f = NULL; 0096 lastMappedDirectoryEntry.num_of_file = 0; 0097 lastMappedDirectoryEntry.pos_in_zip_directory = 0; 0098 } 0099 /// The constructor for the corresponding QuaZip constructor. 0100 inline QuaZipPrivate(QuaZip *q, const QString &zipName): 0101 q(q), 0102 fileNameCodec(getDefaultFileNameCodec()), 0103 commentCodec(QTextCodec::codecForLocale()), 0104 zipName(zipName), 0105 ioDevice(NULL), 0106 mode(QuaZip::mdNotOpen), 0107 hasCurrentFile_f(false), 0108 zipError(UNZ_OK), 0109 dataDescriptorWritingEnabled(true), 0110 zip64(false), 0111 autoClose(true) 0112 { 0113 unzFile_f = NULL; 0114 zipFile_f = NULL; 0115 lastMappedDirectoryEntry.num_of_file = 0; 0116 lastMappedDirectoryEntry.pos_in_zip_directory = 0; 0117 } 0118 /// The constructor for the corresponding QuaZip constructor. 0119 inline QuaZipPrivate(QuaZip *q, QIODevice *ioDevice): 0120 q(q), 0121 fileNameCodec(getDefaultFileNameCodec()), 0122 commentCodec(QTextCodec::codecForLocale()), 0123 ioDevice(ioDevice), 0124 mode(QuaZip::mdNotOpen), 0125 hasCurrentFile_f(false), 0126 zipError(UNZ_OK), 0127 dataDescriptorWritingEnabled(true), 0128 zip64(false), 0129 autoClose(true) 0130 { 0131 unzFile_f = NULL; 0132 zipFile_f = NULL; 0133 lastMappedDirectoryEntry.num_of_file = 0; 0134 lastMappedDirectoryEntry.pos_in_zip_directory = 0; 0135 } 0136 /// Returns either a list of file names or a list of QuaZipFileInfo. 0137 template<typename TFileInfo> 0138 bool getFileInfoList(QList<TFileInfo> *result) const; 0139 0140 /// Stores map of filenames and file locations for unzipping 0141 inline void clearDirectoryMap(); 0142 inline void addCurrentFileToDirectoryMap(const QString &fileName); 0143 bool goToFirstUnmappedFile(); 0144 QHash<QString, unz64_file_pos> directoryCaseSensitive; 0145 QHash<QString, unz64_file_pos> directoryCaseInsensitive; 0146 unz64_file_pos lastMappedDirectoryEntry; 0147 static QTextCodec *defaultFileNameCodec; 0148 }; 0149 0150 QTextCodec *QuaZipPrivate::defaultFileNameCodec = NULL; 0151 0152 void QuaZipPrivate::clearDirectoryMap() 0153 { 0154 directoryCaseInsensitive.clear(); 0155 directoryCaseSensitive.clear(); 0156 lastMappedDirectoryEntry.num_of_file = 0; 0157 lastMappedDirectoryEntry.pos_in_zip_directory = 0; 0158 } 0159 0160 void QuaZipPrivate::addCurrentFileToDirectoryMap(const QString &fileName) 0161 { 0162 if (!hasCurrentFile_f || fileName.isEmpty()) { 0163 return; 0164 } 0165 // Adds current file to filename map as fileName 0166 unz64_file_pos fileDirectoryPos; 0167 unzGetFilePos64(unzFile_f, &fileDirectoryPos); 0168 directoryCaseSensitive.insert(fileName, fileDirectoryPos); 0169 // Only add lowercase to directory map if not already there 0170 // ensures only map the first one seen 0171 QString lower = fileName.toLower(); 0172 if (!directoryCaseInsensitive.contains(lower)) 0173 directoryCaseInsensitive.insert(lower, fileDirectoryPos); 0174 // Mark last one 0175 if (fileDirectoryPos.pos_in_zip_directory > lastMappedDirectoryEntry.pos_in_zip_directory) 0176 lastMappedDirectoryEntry = fileDirectoryPos; 0177 } 0178 0179 bool QuaZipPrivate::goToFirstUnmappedFile() 0180 { 0181 zipError = UNZ_OK; 0182 if (mode != QuaZip::mdUnzip) { 0183 qWarning("QuaZipPrivate::goToNextUnmappedFile(): ZIP is not open in mdUnzip mode"); 0184 return false; 0185 } 0186 // If not mapped anything, go to beginning 0187 if (lastMappedDirectoryEntry.pos_in_zip_directory == 0) { 0188 unzGoToFirstFile(unzFile_f); 0189 } else { 0190 // Goto the last one mapped, plus one 0191 unzGoToFilePos64(unzFile_f, &lastMappedDirectoryEntry); 0192 unzGoToNextFile(unzFile_f); 0193 } 0194 hasCurrentFile_f=zipError==UNZ_OK; 0195 if(zipError==UNZ_END_OF_LIST_OF_FILE) 0196 zipError=UNZ_OK; 0197 return hasCurrentFile_f; 0198 } 0199 0200 QuaZip::QuaZip(): 0201 p(new QuaZipPrivate(this)) 0202 { 0203 } 0204 0205 QuaZip::QuaZip(const QString& zipName): 0206 p(new QuaZipPrivate(this, zipName)) 0207 { 0208 } 0209 0210 QuaZip::QuaZip(QIODevice *ioDevice): 0211 p(new QuaZipPrivate(this, ioDevice)) 0212 { 0213 } 0214 0215 QuaZip::~QuaZip() 0216 { 0217 if(isOpen()) 0218 close(); 0219 delete p; 0220 } 0221 0222 bool QuaZip::open(Mode mode, zlib_filefunc_def* ioApi) 0223 { 0224 p->zipError=UNZ_OK; 0225 if(isOpen()) { 0226 qWarning("QuaZip::open(): ZIP already opened"); 0227 return false; 0228 } 0229 QIODevice *ioDevice = p->ioDevice; 0230 if (ioDevice == NULL) { 0231 if (p->zipName.isEmpty()) { 0232 qWarning("QuaZip::open(): set either ZIP file name or IO device first"); 0233 return false; 0234 } else { 0235 ioDevice = new QFile(p->zipName); 0236 } 0237 } 0238 unsigned flags = 0; 0239 switch(mode) { 0240 case mdUnzip: 0241 if (ioApi == NULL) { 0242 if (p->autoClose) 0243 flags |= UNZ_AUTO_CLOSE; 0244 p->unzFile_f=unzOpenInternal(ioDevice, NULL, 1, flags); 0245 } else { 0246 // QuaZIP pre-zip64 compatibility mode 0247 p->unzFile_f=unzOpen2(ioDevice, ioApi); 0248 if (p->unzFile_f != NULL) { 0249 if (p->autoClose) { 0250 unzSetFlags(p->unzFile_f, UNZ_AUTO_CLOSE); 0251 } else { 0252 unzClearFlags(p->unzFile_f, UNZ_AUTO_CLOSE); 0253 } 0254 } 0255 } 0256 if(p->unzFile_f!=NULL) { 0257 if (ioDevice->isSequential()) { 0258 unzClose(p->unzFile_f); 0259 if (!p->zipName.isEmpty()) 0260 delete ioDevice; 0261 qWarning("QuaZip::open(): " 0262 "only mdCreate can be used with " 0263 "sequential devices"); 0264 return false; 0265 } 0266 p->mode=mode; 0267 p->ioDevice = ioDevice; 0268 return true; 0269 } else { 0270 p->zipError=UNZ_OPENERROR; 0271 if (!p->zipName.isEmpty()) 0272 delete ioDevice; 0273 return false; 0274 } 0275 case mdCreate: 0276 case mdAppend: 0277 case mdAdd: 0278 if (ioApi == NULL) { 0279 if (p->autoClose) 0280 flags |= ZIP_AUTO_CLOSE; 0281 if (p->dataDescriptorWritingEnabled) 0282 flags |= ZIP_WRITE_DATA_DESCRIPTOR; 0283 p->zipFile_f=zipOpen3(ioDevice, 0284 mode==mdCreate?APPEND_STATUS_CREATE: 0285 mode==mdAppend?APPEND_STATUS_CREATEAFTER: 0286 APPEND_STATUS_ADDINZIP, 0287 NULL, NULL, flags); 0288 } else { 0289 // QuaZIP pre-zip64 compatibility mode 0290 p->zipFile_f=zipOpen2(ioDevice, 0291 mode==mdCreate?APPEND_STATUS_CREATE: 0292 mode==mdAppend?APPEND_STATUS_CREATEAFTER: 0293 APPEND_STATUS_ADDINZIP, 0294 NULL, 0295 ioApi); 0296 if (p->zipFile_f != NULL) { 0297 zipSetFlags(p->zipFile_f, flags); 0298 } 0299 } 0300 if(p->zipFile_f!=NULL) { 0301 if (ioDevice->isSequential()) { 0302 if (mode != mdCreate) { 0303 zipClose(p->zipFile_f, NULL); 0304 qWarning("QuaZip::open(): " 0305 "only mdCreate can be used with " 0306 "sequential devices"); 0307 if (!p->zipName.isEmpty()) 0308 delete ioDevice; 0309 return false; 0310 } 0311 zipSetFlags(p->zipFile_f, ZIP_SEQUENTIAL); 0312 } 0313 p->mode=mode; 0314 p->ioDevice = ioDevice; 0315 return true; 0316 } else { 0317 p->zipError=UNZ_OPENERROR; 0318 if (!p->zipName.isEmpty()) 0319 delete ioDevice; 0320 return false; 0321 } 0322 default: 0323 qWarning("QuaZip::open(): unknown mode: %d", (int)mode); 0324 if (!p->zipName.isEmpty()) 0325 delete ioDevice; 0326 return false; 0327 break; 0328 } 0329 } 0330 0331 void QuaZip::close() 0332 { 0333 p->zipError=UNZ_OK; 0334 switch(p->mode) { 0335 case mdNotOpen: 0336 qWarning("QuaZip::close(): ZIP is not open"); 0337 return; 0338 case mdUnzip: 0339 p->zipError=unzClose(p->unzFile_f); 0340 break; 0341 case mdCreate: 0342 case mdAppend: 0343 case mdAdd: 0344 p->zipError=zipClose(p->zipFile_f, 0345 p->comment.isNull() ? NULL 0346 : p->commentCodec->fromUnicode(p->comment).constData()); 0347 break; 0348 default: 0349 qWarning("QuaZip::close(): unknown mode: %d", (int)p->mode); 0350 return; 0351 } 0352 // opened by name, need to delete the internal IO device 0353 if (!p->zipName.isEmpty()) { 0354 delete p->ioDevice; 0355 p->ioDevice = NULL; 0356 } 0357 p->clearDirectoryMap(); 0358 if(p->zipError==UNZ_OK) 0359 p->mode=mdNotOpen; 0360 } 0361 0362 void QuaZip::setZipName(const QString& zipName) 0363 { 0364 if(isOpen()) { 0365 qWarning("QuaZip::setZipName(): ZIP is already open!"); 0366 return; 0367 } 0368 p->zipName=zipName; 0369 p->ioDevice = NULL; 0370 } 0371 0372 void QuaZip::setIoDevice(QIODevice *ioDevice) 0373 { 0374 if(isOpen()) { 0375 qWarning("QuaZip::setIoDevice(): ZIP is already open!"); 0376 return; 0377 } 0378 p->ioDevice = ioDevice; 0379 p->zipName = QString(); 0380 } 0381 0382 int QuaZip::getEntriesCount()const 0383 { 0384 QuaZip *fakeThis=(QuaZip*)this; // non-const 0385 fakeThis->p->zipError=UNZ_OK; 0386 if(p->mode!=mdUnzip) { 0387 qWarning("QuaZip::getEntriesCount(): ZIP is not open in mdUnzip mode"); 0388 return -1; 0389 } 0390 unz_global_info64 globalInfo; 0391 if((fakeThis->p->zipError=unzGetGlobalInfo64(p->unzFile_f, &globalInfo))!=UNZ_OK) 0392 return p->zipError; 0393 return (int)globalInfo.number_entry; 0394 } 0395 0396 QString QuaZip::getComment()const 0397 { 0398 QuaZip *fakeThis=(QuaZip*)this; // non-const 0399 fakeThis->p->zipError=UNZ_OK; 0400 if(p->mode!=mdUnzip) { 0401 qWarning("QuaZip::getComment(): ZIP is not open in mdUnzip mode"); 0402 return QString(); 0403 } 0404 unz_global_info64 globalInfo; 0405 QByteArray comment; 0406 if((fakeThis->p->zipError=unzGetGlobalInfo64(p->unzFile_f, &globalInfo))!=UNZ_OK) 0407 return QString(); 0408 comment.resize(globalInfo.size_comment); 0409 if((fakeThis->p->zipError=unzGetGlobalComment(p->unzFile_f, comment.data(), comment.size())) < 0) 0410 return QString(); 0411 fakeThis->p->zipError = UNZ_OK; 0412 return p->commentCodec->toUnicode(comment); 0413 } 0414 0415 bool QuaZip::setCurrentFile(const QString& fileName, CaseSensitivity cs) 0416 { 0417 p->zipError=UNZ_OK; 0418 if(p->mode!=mdUnzip) { 0419 qWarning("QuaZip::setCurrentFile(): ZIP is not open in mdUnzip mode"); 0420 return false; 0421 } 0422 if(fileName.isEmpty()) { 0423 p->hasCurrentFile_f=false; 0424 return true; 0425 } 0426 // Unicode-aware reimplementation of the unzLocateFile function 0427 if(p->unzFile_f==NULL) { 0428 p->zipError=UNZ_PARAMERROR; 0429 return false; 0430 } 0431 if(fileName.length()>MAX_FILE_NAME_LENGTH) { 0432 p->zipError=UNZ_PARAMERROR; 0433 return false; 0434 } 0435 // Find the file by name 0436 bool sens = convertCaseSensitivity(cs) == Qt::CaseSensitive; 0437 QString lower, current; 0438 if(!sens) lower=fileName.toLower(); 0439 p->hasCurrentFile_f=false; 0440 0441 // Check the appropriate Map 0442 unz64_file_pos fileDirPos; 0443 fileDirPos.pos_in_zip_directory = 0; 0444 if (sens) { 0445 if (p->directoryCaseSensitive.contains(fileName)) 0446 fileDirPos = p->directoryCaseSensitive.value(fileName); 0447 } else { 0448 if (p->directoryCaseInsensitive.contains(lower)) 0449 fileDirPos = p->directoryCaseInsensitive.value(lower); 0450 } 0451 0452 if (fileDirPos.pos_in_zip_directory != 0) { 0453 p->zipError = unzGoToFilePos64(p->unzFile_f, &fileDirPos); 0454 p->hasCurrentFile_f = p->zipError == UNZ_OK; 0455 } 0456 0457 if (p->hasCurrentFile_f) 0458 return p->hasCurrentFile_f; 0459 0460 // Not mapped yet, start from where we have got to so far 0461 for(bool more=p->goToFirstUnmappedFile(); more; more=goToNextFile()) { 0462 current=getCurrentFileName(); 0463 if(current.isEmpty()) return false; 0464 if(sens) { 0465 if(current==fileName) break; 0466 } else { 0467 if(current.toLower()==lower) break; 0468 } 0469 } 0470 return p->hasCurrentFile_f; 0471 } 0472 0473 bool QuaZip::goToFirstFile() 0474 { 0475 p->zipError=UNZ_OK; 0476 if(p->mode!=mdUnzip) { 0477 qWarning("QuaZip::goToFirstFile(): ZIP is not open in mdUnzip mode"); 0478 return false; 0479 } 0480 p->zipError=unzGoToFirstFile(p->unzFile_f); 0481 p->hasCurrentFile_f=p->zipError==UNZ_OK; 0482 return p->hasCurrentFile_f; 0483 } 0484 0485 bool QuaZip::goToNextFile() 0486 { 0487 p->zipError=UNZ_OK; 0488 if(p->mode!=mdUnzip) { 0489 qWarning("QuaZip::goToFirstFile(): ZIP is not open in mdUnzip mode"); 0490 return false; 0491 } 0492 p->zipError=unzGoToNextFile(p->unzFile_f); 0493 p->hasCurrentFile_f=p->zipError==UNZ_OK; 0494 if(p->zipError==UNZ_END_OF_LIST_OF_FILE) 0495 p->zipError=UNZ_OK; 0496 return p->hasCurrentFile_f; 0497 } 0498 0499 bool QuaZip::getCurrentFileInfo(QuaZipFileInfo *info)const 0500 { 0501 QuaZipFileInfo64 info64; 0502 if (info == NULL) { // Very unlikely because of the overloads 0503 return false; 0504 } 0505 if (getCurrentFileInfo(&info64)) { 0506 info64.toQuaZipFileInfo(*info); 0507 return true; 0508 } else { 0509 return false; 0510 } 0511 } 0512 0513 bool QuaZip::getCurrentFileInfo(QuaZipFileInfo64 *info)const 0514 { 0515 QuaZip *fakeThis=(QuaZip*)this; // non-const 0516 fakeThis->p->zipError=UNZ_OK; 0517 if(p->mode!=mdUnzip) { 0518 qWarning("QuaZip::getCurrentFileInfo(): ZIP is not open in mdUnzip mode"); 0519 return false; 0520 } 0521 unz_file_info64 info_z; 0522 QByteArray fileName; 0523 QByteArray extra; 0524 QByteArray comment; 0525 if(info==NULL) return false; 0526 if(!isOpen()||!hasCurrentFile()) return false; 0527 if((fakeThis->p->zipError=unzGetCurrentFileInfo64(p->unzFile_f, &info_z, NULL, 0, NULL, 0, NULL, 0))!=UNZ_OK) 0528 return false; 0529 fileName.resize(info_z.size_filename); 0530 extra.resize(info_z.size_file_extra); 0531 comment.resize(info_z.size_file_comment); 0532 if((fakeThis->p->zipError=unzGetCurrentFileInfo64(p->unzFile_f, NULL, 0533 fileName.data(), fileName.size(), 0534 extra.data(), extra.size(), 0535 comment.data(), comment.size()))!=UNZ_OK) 0536 return false; 0537 info->versionCreated=info_z.version; 0538 info->versionNeeded=info_z.version_needed; 0539 info->flags=info_z.flag; 0540 info->method=info_z.compression_method; 0541 info->crc=info_z.crc; 0542 info->compressedSize=info_z.compressed_size; 0543 info->uncompressedSize=info_z.uncompressed_size; 0544 info->diskNumberStart=info_z.disk_num_start; 0545 info->internalAttr=info_z.internal_fa; 0546 info->externalAttr=info_z.external_fa; 0547 info->name=p->fileNameCodec->toUnicode(fileName); 0548 info->comment=p->commentCodec->toUnicode(comment); 0549 info->extra=extra; 0550 info->dateTime=QDateTime( 0551 QDate(info_z.tmu_date.tm_year, info_z.tmu_date.tm_mon+1, info_z.tmu_date.tm_mday), 0552 QTime(info_z.tmu_date.tm_hour, info_z.tmu_date.tm_min, info_z.tmu_date.tm_sec)); 0553 // Add to directory map 0554 p->addCurrentFileToDirectoryMap(info->name); 0555 return true; 0556 } 0557 0558 QString QuaZip::getCurrentFileName()const 0559 { 0560 QuaZip *fakeThis=(QuaZip*)this; // non-const 0561 fakeThis->p->zipError=UNZ_OK; 0562 if(p->mode!=mdUnzip) { 0563 qWarning("QuaZip::getCurrentFileName(): ZIP is not open in mdUnzip mode"); 0564 return QString(); 0565 } 0566 if(!isOpen()||!hasCurrentFile()) return QString(); 0567 QByteArray fileName(MAX_FILE_NAME_LENGTH, 0); 0568 if((fakeThis->p->zipError=unzGetCurrentFileInfo64(p->unzFile_f, NULL, fileName.data(), fileName.size(), 0569 NULL, 0, NULL, 0))!=UNZ_OK) 0570 return QString(); 0571 QString result = p->fileNameCodec->toUnicode(fileName.constData()); 0572 if (result.isEmpty()) 0573 return result; 0574 // Add to directory map 0575 p->addCurrentFileToDirectoryMap(result); 0576 return result; 0577 } 0578 0579 void QuaZip::setFileNameCodec(QTextCodec *fileNameCodec) 0580 { 0581 p->fileNameCodec=fileNameCodec; 0582 } 0583 0584 void QuaZip::setFileNameCodec(const char *fileNameCodecName) 0585 { 0586 p->fileNameCodec=QTextCodec::codecForName(fileNameCodecName); 0587 } 0588 0589 QTextCodec *QuaZip::getFileNameCodec()const 0590 { 0591 return p->fileNameCodec; 0592 } 0593 0594 void QuaZip::setCommentCodec(QTextCodec *commentCodec) 0595 { 0596 p->commentCodec=commentCodec; 0597 } 0598 0599 void QuaZip::setCommentCodec(const char *commentCodecName) 0600 { 0601 p->commentCodec=QTextCodec::codecForName(commentCodecName); 0602 } 0603 0604 QTextCodec *QuaZip::getCommentCodec()const 0605 { 0606 return p->commentCodec; 0607 } 0608 0609 QString QuaZip::getZipName() const 0610 { 0611 return p->zipName; 0612 } 0613 0614 QIODevice *QuaZip::getIoDevice() const 0615 { 0616 if (!p->zipName.isEmpty()) // opened by name, using an internal QIODevice 0617 return NULL; 0618 return p->ioDevice; 0619 } 0620 0621 QuaZip::Mode QuaZip::getMode()const 0622 { 0623 return p->mode; 0624 } 0625 0626 bool QuaZip::isOpen()const 0627 { 0628 return p->mode!=mdNotOpen; 0629 } 0630 0631 int QuaZip::getZipError() const 0632 { 0633 return p->zipError; 0634 } 0635 0636 void QuaZip::setComment(const QString& comment) 0637 { 0638 p->comment=comment; 0639 } 0640 0641 bool QuaZip::hasCurrentFile()const 0642 { 0643 return p->hasCurrentFile_f; 0644 } 0645 0646 unzFile QuaZip::getUnzFile() 0647 { 0648 return p->unzFile_f; 0649 } 0650 0651 zipFile QuaZip::getZipFile() 0652 { 0653 return p->zipFile_f; 0654 } 0655 0656 void QuaZip::setDataDescriptorWritingEnabled(bool enabled) 0657 { 0658 p->dataDescriptorWritingEnabled = enabled; 0659 } 0660 0661 bool QuaZip::isDataDescriptorWritingEnabled() const 0662 { 0663 return p->dataDescriptorWritingEnabled; 0664 } 0665 0666 template<typename TFileInfo> 0667 TFileInfo QuaZip_getFileInfo(QuaZip *zip, bool *ok); 0668 0669 template<> 0670 QuaZipFileInfo QuaZip_getFileInfo(QuaZip *zip, bool *ok) 0671 { 0672 QuaZipFileInfo info; 0673 *ok = zip->getCurrentFileInfo(&info); 0674 return info; 0675 } 0676 0677 template<> 0678 QuaZipFileInfo64 QuaZip_getFileInfo(QuaZip *zip, bool *ok) 0679 { 0680 QuaZipFileInfo64 info; 0681 *ok = zip->getCurrentFileInfo(&info); 0682 return info; 0683 } 0684 0685 template<> 0686 QString QuaZip_getFileInfo(QuaZip *zip, bool *ok) 0687 { 0688 QString name = zip->getCurrentFileName(); 0689 *ok = !name.isEmpty(); 0690 return name; 0691 } 0692 0693 template<typename TFileInfo> 0694 bool QuaZipPrivate::getFileInfoList(QList<TFileInfo> *result) const 0695 { 0696 QuaZipPrivate *fakeThis=const_cast<QuaZipPrivate*>(this); 0697 fakeThis->zipError=UNZ_OK; 0698 if (mode!=QuaZip::mdUnzip) { 0699 qWarning("QuaZip::getFileNameList/getFileInfoList(): " 0700 "ZIP is not open in mdUnzip mode"); 0701 return false; 0702 } 0703 QString currentFile; 0704 if (q->hasCurrentFile()) { 0705 currentFile = q->getCurrentFileName(); 0706 } 0707 if (q->goToFirstFile()) { 0708 do { 0709 bool ok; 0710 result->append(QuaZip_getFileInfo<TFileInfo>(q, &ok)); 0711 if (!ok) 0712 return false; 0713 } while (q->goToNextFile()); 0714 } 0715 if (zipError != UNZ_OK) 0716 return false; 0717 if (currentFile.isEmpty()) { 0718 if (!q->goToFirstFile()) 0719 return false; 0720 } else { 0721 if (!q->setCurrentFile(currentFile)) 0722 return false; 0723 } 0724 return true; 0725 } 0726 0727 QStringList QuaZip::getFileNameList() const 0728 { 0729 QStringList list; 0730 if (p->getFileInfoList(&list)) 0731 return list; 0732 else 0733 return QStringList(); 0734 } 0735 0736 QList<QuaZipFileInfo> QuaZip::getFileInfoList() const 0737 { 0738 QList<QuaZipFileInfo> list; 0739 if (p->getFileInfoList(&list)) 0740 return list; 0741 else 0742 return QList<QuaZipFileInfo>(); 0743 } 0744 0745 QList<QuaZipFileInfo64> QuaZip::getFileInfoList64() const 0746 { 0747 QList<QuaZipFileInfo64> list; 0748 if (p->getFileInfoList(&list)) 0749 return list; 0750 else 0751 return QList<QuaZipFileInfo64>(); 0752 } 0753 0754 Qt::CaseSensitivity QuaZip::convertCaseSensitivity(QuaZip::CaseSensitivity cs) 0755 { 0756 if (cs == csDefault) { 0757 #ifdef Q_OS_WIN 0758 return Qt::CaseInsensitive; 0759 #else 0760 return Qt::CaseSensitive; 0761 #endif 0762 } else { 0763 return cs == csSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive; 0764 } 0765 } 0766 0767 void QuaZip::setDefaultFileNameCodec(QTextCodec *codec) 0768 { 0769 QuaZipPrivate::defaultFileNameCodec = codec; 0770 } 0771 0772 void QuaZip::setDefaultFileNameCodec(const char *codecName) 0773 { 0774 setDefaultFileNameCodec(QTextCodec::codecForName(codecName)); 0775 } 0776 0777 void QuaZip::setZip64Enabled(bool zip64) 0778 { 0779 p->zip64 = zip64; 0780 } 0781 0782 bool QuaZip::isZip64Enabled() const 0783 { 0784 return p->zip64; 0785 } 0786 0787 bool QuaZip::isAutoClose() const 0788 { 0789 return p->autoClose; 0790 } 0791 0792 void QuaZip::setAutoClose(bool autoClose) const 0793 { 0794 p->autoClose = autoClose; 0795 }