"Fossies" - the Fresh Open Source Software Archive

Member "tea-47.1.0/quazip.cpp" (4 May 2019, 21784 Bytes) of package /linux/privat/tea-47.1.0.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "quazip.cpp" see the Fossies "Dox" file reference documentation.

    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 <QFile>
   26 #include <QFlags>
   27 #include <QHash>
   28 
   29 #include "quazip.h"
   30 
   31 /// All the internal stuff for the QuaZip class.
   32 /**
   33   \internal
   34 
   35   This class keeps all the private stuff for the QuaZip class so it can
   36   be changed without breaking binary compatibility, according to the
   37   Pimpl idiom.
   38   */
   39 class QuaZipPrivate {
   40   friend class QuaZip;
   41   private:
   42     Q_DISABLE_COPY(QuaZipPrivate)
   43     /// The pointer to the corresponding QuaZip instance.
   44     QuaZip *q;
   45     /// The codec for file names.
   46     QTextCodec *fileNameCodec;
   47     /// The codec for comments.
   48     QTextCodec *commentCodec;
   49     /// The archive file name.
   50     QString zipName;
   51     /// The device to access the archive.
   52     QIODevice *ioDevice;
   53     /// The global comment.
   54     QString comment;
   55     /// The open mode.
   56     QuaZip::Mode mode;
   57     union {
   58       /// The internal handle for UNZIP modes.
   59       unzFile unzFile_f;
   60       /// The internal handle for ZIP modes.
   61       zipFile zipFile_f;
   62     };
   63     /// Whether a current file is set.
   64     bool hasCurrentFile_f;
   65     /// The last error.
   66     int zipError;
   67     /// Whether \ref QuaZip::setDataDescriptorWritingEnabled() "the data descriptor writing mode" is enabled.
   68     bool dataDescriptorWritingEnabled;
   69     /// The zip64 mode.
   70     bool zip64;
   71     /// The auto-close flag.
   72     bool autoClose;
   73     inline QTextCodec *getDefaultFileNameCodec()
   74     {
   75         if (defaultFileNameCodec == NULL) {
   76             return QTextCodec::codecForLocale();
   77         } else {
   78             return defaultFileNameCodec;
   79         }
   80     }
   81     /// The constructor for the corresponding QuaZip constructor.
   82     inline QuaZipPrivate(QuaZip *q1):
   83       q(q1),
   84       fileNameCodec(getDefaultFileNameCodec()),
   85       commentCodec(QTextCodec::codecForLocale()),
   86       ioDevice(NULL),
   87       mode(QuaZip::mdNotOpen),
   88       hasCurrentFile_f(false),
   89       zipError(UNZ_OK),
   90       dataDescriptorWritingEnabled(true),
   91       zip64(false),
   92       autoClose(true)
   93     {
   94         unzFile_f = NULL;
   95         zipFile_f = NULL;
   96         lastMappedDirectoryEntry.num_of_file = 0;
   97         lastMappedDirectoryEntry.pos_in_zip_directory = 0;
   98     }
   99     /// The constructor for the corresponding QuaZip constructor.
  100     inline QuaZipPrivate(QuaZip *q1, const QString &zipName):
  101       q(q1),
  102       fileNameCodec(getDefaultFileNameCodec()),
  103       commentCodec(QTextCodec::codecForLocale()),
  104       zipName(zipName),
  105       ioDevice(NULL),
  106       mode(QuaZip::mdNotOpen),
  107       hasCurrentFile_f(false),
  108       zipError(UNZ_OK),
  109       dataDescriptorWritingEnabled(true),
  110       zip64(false),
  111       autoClose(true)
  112     {
  113         unzFile_f = NULL;
  114         zipFile_f = NULL;
  115         lastMappedDirectoryEntry.num_of_file = 0;
  116         lastMappedDirectoryEntry.pos_in_zip_directory = 0;
  117     }
  118     /// The constructor for the corresponding QuaZip constructor.
  119     inline QuaZipPrivate(QuaZip *q1, QIODevice *ioDevice):
  120         q(q1),
  121       fileNameCodec(getDefaultFileNameCodec()),
  122       commentCodec(QTextCodec::codecForLocale()),
  123       ioDevice(ioDevice),
  124       mode(QuaZip::mdNotOpen),
  125       hasCurrentFile_f(false),
  126       zipError(UNZ_OK),
  127       dataDescriptorWritingEnabled(true),
  128       zip64(false),
  129       autoClose(true)
  130     {
  131         unzFile_f = NULL;
  132         zipFile_f = NULL;
  133         lastMappedDirectoryEntry.num_of_file = 0;
  134         lastMappedDirectoryEntry.pos_in_zip_directory = 0;
  135     }
  136     /// Returns either a list of file names or a list of QuaZipFileInfo.
  137     template<typename TFileInfo>
  138         bool getFileInfoList(QList<TFileInfo> *result) const;
  139 
  140     /// Stores map of filenames and file locations for unzipping
  141       inline void clearDirectoryMap();
  142       inline void addCurrentFileToDirectoryMap(const QString &fileName);
  143       bool goToFirstUnmappedFile();
  144       QHash<QString, unz64_file_pos> directoryCaseSensitive;
  145       QHash<QString, unz64_file_pos> directoryCaseInsensitive;
  146       unz64_file_pos lastMappedDirectoryEntry;
  147       static QTextCodec *defaultFileNameCodec;
  148 };
  149 
  150 QTextCodec *QuaZipPrivate::defaultFileNameCodec = NULL;
  151 
  152 void QuaZipPrivate::clearDirectoryMap()
  153 {
  154     directoryCaseInsensitive.clear();
  155     directoryCaseSensitive.clear();
  156     lastMappedDirectoryEntry.num_of_file = 0;
  157     lastMappedDirectoryEntry.pos_in_zip_directory = 0;
  158 }
  159 
  160 void QuaZipPrivate::addCurrentFileToDirectoryMap(const QString &fileName)
  161 {
  162     if (!hasCurrentFile_f || fileName.isEmpty()) {
  163         return;
  164     }
  165     // Adds current file to filename map as fileName
  166     unz64_file_pos fileDirectoryPos;
  167     unzGetFilePos64(unzFile_f, &fileDirectoryPos);
  168     directoryCaseSensitive.insert(fileName, fileDirectoryPos);
  169     // Only add lowercase to directory map if not already there
  170     // ensures only map the first one seen
  171     QString lower = fileName.toLower();
  172     if (!directoryCaseInsensitive.contains(lower))
  173         directoryCaseInsensitive.insert(lower, fileDirectoryPos);
  174     // Mark last one
  175     if (fileDirectoryPos.pos_in_zip_directory > lastMappedDirectoryEntry.pos_in_zip_directory)
  176         lastMappedDirectoryEntry = fileDirectoryPos;
  177 }
  178 
  179 bool QuaZipPrivate::goToFirstUnmappedFile()
  180 {
  181     zipError = UNZ_OK;
  182     if (mode != QuaZip::mdUnzip) {
  183         qWarning("QuaZipPrivate::goToNextUnmappedFile(): ZIP is not open in mdUnzip mode");
  184         return false;
  185     }
  186     // If not mapped anything, go to beginning
  187     if (lastMappedDirectoryEntry.pos_in_zip_directory == 0) {
  188         unzGoToFirstFile(unzFile_f);
  189     } else {
  190         // Goto the last one mapped, plus one
  191         unzGoToFilePos64(unzFile_f, &lastMappedDirectoryEntry);
  192         unzGoToNextFile(unzFile_f);
  193     }
  194     hasCurrentFile_f=zipError==UNZ_OK;
  195     if(zipError==UNZ_END_OF_LIST_OF_FILE)
  196       zipError=UNZ_OK;
  197     return hasCurrentFile_f;
  198 }
  199 
  200 QuaZip::QuaZip():
  201   p(new QuaZipPrivate(this))
  202 {
  203 }
  204 
  205 QuaZip::QuaZip(const QString& zipName):
  206   p(new QuaZipPrivate(this, zipName))
  207 {
  208 }
  209 
  210 QuaZip::QuaZip(QIODevice *ioDevice):
  211   p(new QuaZipPrivate(this, ioDevice))
  212 {
  213 }
  214 
  215 QuaZip::~QuaZip()
  216 {
  217   if(isOpen())
  218     close();
  219   delete p;
  220 }
  221 
  222 bool QuaZip::open(Mode mode, zlib_filefunc_def* ioApi)
  223 {
  224   p->zipError=UNZ_OK;
  225   if(isOpen()) {
  226     qWarning("QuaZip::open(): ZIP already opened");
  227     return false;
  228   }
  229   QIODevice *ioDevice = p->ioDevice;
  230   if (ioDevice == NULL) {
  231     if (p->zipName.isEmpty()) {
  232       qWarning("QuaZip::open(): set either ZIP file name or IO device first");
  233       return false;
  234     } else {
  235       ioDevice = new QFile(p->zipName);
  236     }
  237   }
  238   unsigned flags = 0;
  239   switch(mode) {
  240     case mdUnzip:
  241       if (ioApi == NULL) {
  242           if (p->autoClose)
  243               flags |= UNZ_AUTO_CLOSE;
  244           p->unzFile_f=unzOpenInternal(ioDevice, NULL, 1, flags);
  245       } else {
  246           // QuaZIP pre-zip64 compatibility mode
  247           p->unzFile_f=unzOpen2(ioDevice, ioApi);
  248           if (p->unzFile_f != NULL) {
  249               if (p->autoClose) {
  250                   unzSetFlags(p->unzFile_f, UNZ_AUTO_CLOSE);
  251               } else {
  252                   unzClearFlags(p->unzFile_f, UNZ_AUTO_CLOSE);
  253               }
  254           }
  255       }
  256       if(p->unzFile_f!=NULL) {
  257         if (ioDevice->isSequential()) {
  258             unzClose(p->unzFile_f);
  259             if (!p->zipName.isEmpty())
  260                 delete ioDevice;
  261             qWarning("QuaZip::open(): "
  262                      "only mdCreate can be used with "
  263                      "sequential devices");
  264             return false;
  265         }
  266         p->mode=mode;
  267         p->ioDevice = ioDevice;
  268         return true;
  269       } else {
  270         p->zipError=UNZ_OPENERROR;
  271         if (!p->zipName.isEmpty())
  272           delete ioDevice;
  273         return false;
  274       }
  275     case mdCreate:
  276     case mdAppend:
  277     case mdAdd:
  278       if (ioApi == NULL) {
  279           if (p->autoClose)
  280               flags |= ZIP_AUTO_CLOSE;
  281           if (p->dataDescriptorWritingEnabled)
  282               flags |= ZIP_WRITE_DATA_DESCRIPTOR;
  283           p->zipFile_f=zipOpen3(ioDevice,
  284               mode==mdCreate?APPEND_STATUS_CREATE:
  285               mode==mdAppend?APPEND_STATUS_CREATEAFTER:
  286               APPEND_STATUS_ADDINZIP,
  287               NULL, NULL, flags);
  288       } else {
  289           // QuaZIP pre-zip64 compatibility mode
  290           p->zipFile_f=zipOpen2(ioDevice,
  291               mode==mdCreate?APPEND_STATUS_CREATE:
  292               mode==mdAppend?APPEND_STATUS_CREATEAFTER:
  293               APPEND_STATUS_ADDINZIP,
  294               NULL,
  295               ioApi);
  296           if (p->zipFile_f != NULL) {
  297               zipSetFlags(p->zipFile_f, flags);
  298           }
  299       }
  300       if(p->zipFile_f!=NULL) {
  301         if (ioDevice->isSequential()) {
  302             if (mode != mdCreate) {
  303                 zipClose(p->zipFile_f, NULL);
  304                 qWarning("QuaZip::open(): "
  305                         "only mdCreate can be used with "
  306                          "sequential devices");
  307                 if (!p->zipName.isEmpty())
  308                     delete ioDevice;
  309                 return false;
  310             }
  311             zipSetFlags(p->zipFile_f, ZIP_SEQUENTIAL);
  312         }
  313         p->mode=mode;
  314         p->ioDevice = ioDevice;
  315         return true;
  316       } else {
  317         p->zipError=UNZ_OPENERROR;
  318         if (!p->zipName.isEmpty())
  319           delete ioDevice;
  320         return false;
  321       }
  322     default:
  323       qWarning("QuaZip::open(): unknown mode: %d", (int)mode);
  324       if (!p->zipName.isEmpty())
  325         delete ioDevice;
  326       return false;
  327       break;
  328   }
  329 }
  330 
  331 void QuaZip::close()
  332 {
  333   p->zipError=UNZ_OK;
  334   switch(p->mode) {
  335     case mdNotOpen:
  336       qWarning("QuaZip::close(): ZIP is not open");
  337       return;
  338     case mdUnzip:
  339       p->zipError=unzClose(p->unzFile_f);
  340       break;
  341     case mdCreate:
  342     case mdAppend:
  343     case mdAdd:
  344       p->zipError=zipClose(p->zipFile_f, 
  345           p->comment.isNull() ? NULL
  346           : p->commentCodec->fromUnicode(p->comment).constData());
  347       break;
  348     default:
  349       qWarning("QuaZip::close(): unknown mode: %d", (int)p->mode);
  350       return;
  351   }
  352   // opened by name, need to delete the internal IO device
  353   if (!p->zipName.isEmpty()) {
  354       delete p->ioDevice;
  355       p->ioDevice = NULL;
  356   }
  357   p->clearDirectoryMap();
  358   if(p->zipError==UNZ_OK)
  359     p->mode=mdNotOpen;
  360 }
  361 
  362 void QuaZip::setZipName(const QString& zipName)
  363 {
  364   if(isOpen()) {
  365     qWarning("QuaZip::setZipName(): ZIP is already open!");
  366     return;
  367   }
  368   p->zipName=zipName;
  369   p->ioDevice = NULL;
  370 }
  371 
  372 void QuaZip::setIoDevice(QIODevice *ioDevice)
  373 {
  374   if(isOpen()) {
  375     qWarning("QuaZip::setIoDevice(): ZIP is already open!");
  376     return;
  377   }
  378   p->ioDevice = ioDevice;
  379   p->zipName = QString();
  380 }
  381 
  382 int QuaZip::getEntriesCount()const
  383 {
  384   QuaZip *fakeThis=(QuaZip*)this; // non-const
  385   fakeThis->p->zipError=UNZ_OK;
  386   if(p->mode!=mdUnzip) {
  387     qWarning("QuaZip::getEntriesCount(): ZIP is not open in mdUnzip mode");
  388     return -1;
  389   }
  390   unz_global_info64 globalInfo;
  391   if((fakeThis->p->zipError=unzGetGlobalInfo64(p->unzFile_f, &globalInfo))!=UNZ_OK)
  392     return p->zipError;
  393   return (int)globalInfo.number_entry;
  394 }
  395 
  396 QString QuaZip::getComment()const
  397 {
  398   QuaZip *fakeThis=(QuaZip*)this; // non-const
  399   fakeThis->p->zipError=UNZ_OK;
  400   if(p->mode!=mdUnzip) {
  401     qWarning("QuaZip::getComment(): ZIP is not open in mdUnzip mode");
  402     return QString();
  403   }
  404   unz_global_info64 globalInfo;
  405   QByteArray comment;
  406   if((fakeThis->p->zipError=unzGetGlobalInfo64(p->unzFile_f, &globalInfo))!=UNZ_OK)
  407     return QString();
  408   comment.resize(globalInfo.size_comment);
  409   if((fakeThis->p->zipError=unzGetGlobalComment(p->unzFile_f, comment.data(), comment.size())) < 0)
  410     return QString();
  411   fakeThis->p->zipError = UNZ_OK;
  412   return p->commentCodec->toUnicode(comment);
  413 }
  414 
  415 bool QuaZip::setCurrentFile(const QString& fileName, CaseSensitivity cs)
  416 {
  417   p->zipError=UNZ_OK;
  418   if(p->mode!=mdUnzip) {
  419     qWarning("QuaZip::setCurrentFile(): ZIP is not open in mdUnzip mode");
  420     return false;
  421   }
  422   if(fileName.isEmpty()) {
  423     p->hasCurrentFile_f=false;
  424     return true;
  425   }
  426   // Unicode-aware reimplementation of the unzLocateFile function
  427   if(p->unzFile_f==NULL) {
  428     p->zipError=UNZ_PARAMERROR;
  429     return false;
  430   }
  431   if(fileName.length()>MAX_FILE_NAME_LENGTH) {
  432     p->zipError=UNZ_PARAMERROR;
  433     return false;
  434   }
  435   // Find the file by name
  436   bool sens = convertCaseSensitivity(cs) == Qt::CaseSensitive;
  437   QString lower, current;
  438   if(!sens) lower=fileName.toLower();
  439   p->hasCurrentFile_f=false;
  440 
  441   // Check the appropriate Map
  442   unz64_file_pos fileDirPos;
  443   fileDirPos.pos_in_zip_directory = 0;
  444   if (sens) {
  445       if (p->directoryCaseSensitive.contains(fileName))
  446           fileDirPos = p->directoryCaseSensitive.value(fileName);
  447   } else {
  448       if (p->directoryCaseInsensitive.contains(lower))
  449           fileDirPos = p->directoryCaseInsensitive.value(lower);
  450   }
  451 
  452   if (fileDirPos.pos_in_zip_directory != 0) {
  453       p->zipError = unzGoToFilePos64(p->unzFile_f, &fileDirPos);
  454       p->hasCurrentFile_f = p->zipError == UNZ_OK;
  455   }
  456 
  457   if (p->hasCurrentFile_f)
  458       return p->hasCurrentFile_f;
  459 
  460   // Not mapped yet, start from where we have got to so far
  461   for(bool more=p->goToFirstUnmappedFile(); more; more=goToNextFile()) {
  462     current=getCurrentFileName();
  463     if(current.isEmpty()) return false;
  464     if(sens) {
  465       if(current==fileName) break;
  466     } else {
  467       if(current.toLower()==lower) break;
  468     }
  469   }
  470   return p->hasCurrentFile_f;
  471 }
  472 
  473 bool QuaZip::goToFirstFile()
  474 {
  475   p->zipError=UNZ_OK;
  476   if(p->mode!=mdUnzip) {
  477     qWarning("QuaZip::goToFirstFile(): ZIP is not open in mdUnzip mode");
  478     return false;
  479   }
  480   p->zipError=unzGoToFirstFile(p->unzFile_f);
  481   p->hasCurrentFile_f=p->zipError==UNZ_OK;
  482   return p->hasCurrentFile_f;
  483 }
  484 
  485 bool QuaZip::goToNextFile()
  486 {
  487   p->zipError=UNZ_OK;
  488   if(p->mode!=mdUnzip) {
  489     qWarning("QuaZip::goToFirstFile(): ZIP is not open in mdUnzip mode");
  490     return false;
  491   }
  492   p->zipError=unzGoToNextFile(p->unzFile_f);
  493   p->hasCurrentFile_f=p->zipError==UNZ_OK;
  494   if(p->zipError==UNZ_END_OF_LIST_OF_FILE)
  495     p->zipError=UNZ_OK;
  496   return p->hasCurrentFile_f;
  497 }
  498 
  499 bool QuaZip::getCurrentFileInfo(QuaZipFileInfo *info)const
  500 {
  501     QuaZipFileInfo64 info64;
  502     if (info == NULL) { // Very unlikely because of the overloads
  503         return false;
  504     }
  505     if (getCurrentFileInfo(&info64)) {
  506         info64.toQuaZipFileInfo(*info);
  507         return true;
  508     } else {
  509         return false;
  510     }
  511 }
  512 
  513 bool QuaZip::getCurrentFileInfo(QuaZipFileInfo64 *info)const
  514 {
  515   QuaZip *fakeThis=(QuaZip*)this; // non-const
  516   fakeThis->p->zipError=UNZ_OK;
  517   if(p->mode!=mdUnzip) {
  518     qWarning("QuaZip::getCurrentFileInfo(): ZIP is not open in mdUnzip mode");
  519     return false;
  520   }
  521   unz_file_info64 info_z;
  522   QByteArray fileName;
  523   QByteArray extra;
  524   QByteArray comment;
  525   if(info==NULL) return false;
  526   if(!isOpen()||!hasCurrentFile()) return false;
  527   if((fakeThis->p->zipError=unzGetCurrentFileInfo64(p->unzFile_f, &info_z, NULL, 0, NULL, 0, NULL, 0))!=UNZ_OK)
  528     return false;
  529   fileName.resize(info_z.size_filename);
  530   extra.resize(info_z.size_file_extra);
  531   comment.resize(info_z.size_file_comment);
  532   if((fakeThis->p->zipError=unzGetCurrentFileInfo64(p->unzFile_f, NULL,
  533       fileName.data(), fileName.size(),
  534       extra.data(), extra.size(),
  535       comment.data(), comment.size()))!=UNZ_OK)
  536     return false;
  537   info->versionCreated=info_z.version;
  538   info->versionNeeded=info_z.version_needed;
  539   info->flags=info_z.flag;
  540   info->method=info_z.compression_method;
  541   info->crc=info_z.crc;
  542   info->compressedSize=info_z.compressed_size;
  543   info->uncompressedSize=info_z.uncompressed_size;
  544   info->diskNumberStart=info_z.disk_num_start;
  545   info->internalAttr=info_z.internal_fa;
  546   info->externalAttr=info_z.external_fa;
  547   info->name=p->fileNameCodec->toUnicode(fileName);
  548   info->comment=p->commentCodec->toUnicode(comment);
  549   info->extra=extra;
  550   info->dateTime=QDateTime(
  551       QDate(info_z.tmu_date.tm_year, info_z.tmu_date.tm_mon+1, info_z.tmu_date.tm_mday),
  552       QTime(info_z.tmu_date.tm_hour, info_z.tmu_date.tm_min, info_z.tmu_date.tm_sec));
  553   // Add to directory map
  554   p->addCurrentFileToDirectoryMap(info->name);
  555   return true;
  556 }
  557 
  558 QString QuaZip::getCurrentFileName()const
  559 {
  560   QuaZip *fakeThis=(QuaZip*)this; // non-const
  561   fakeThis->p->zipError=UNZ_OK;
  562   if(p->mode!=mdUnzip) {
  563     qWarning("QuaZip::getCurrentFileName(): ZIP is not open in mdUnzip mode");
  564     return QString();
  565   }
  566   if(!isOpen()||!hasCurrentFile()) return QString();
  567   QByteArray fileName(MAX_FILE_NAME_LENGTH, 0);
  568   if((fakeThis->p->zipError=unzGetCurrentFileInfo64(p->unzFile_f, NULL, fileName.data(), fileName.size(),
  569       NULL, 0, NULL, 0))!=UNZ_OK)
  570     return QString();
  571   QString result = p->fileNameCodec->toUnicode(fileName.constData());
  572   if (result.isEmpty())
  573       return result;
  574   // Add to directory map
  575   p->addCurrentFileToDirectoryMap(result);
  576   return result;
  577 }
  578 
  579 void QuaZip::setFileNameCodec(QTextCodec *fileNameCodec)
  580 {
  581   p->fileNameCodec=fileNameCodec;
  582 }
  583 
  584 void QuaZip::setFileNameCodec(const char *fileNameCodecName)
  585 {
  586   p->fileNameCodec=QTextCodec::codecForName(fileNameCodecName);
  587 }
  588 
  589 QTextCodec *QuaZip::getFileNameCodec()const
  590 {
  591   return p->fileNameCodec;
  592 }
  593 
  594 void QuaZip::setCommentCodec(QTextCodec *commentCodec)
  595 {
  596   p->commentCodec=commentCodec;
  597 }
  598 
  599 void QuaZip::setCommentCodec(const char *commentCodecName)
  600 {
  601   p->commentCodec=QTextCodec::codecForName(commentCodecName);
  602 }
  603 
  604 QTextCodec *QuaZip::getCommentCodec()const
  605 {
  606   return p->commentCodec;
  607 }
  608 
  609 QString QuaZip::getZipName() const
  610 {
  611   return p->zipName;
  612 }
  613 
  614 QIODevice *QuaZip::getIoDevice() const
  615 {
  616   if (!p->zipName.isEmpty()) // opened by name, using an internal QIODevice
  617     return NULL;
  618   return p->ioDevice;
  619 }
  620 
  621 QuaZip::Mode QuaZip::getMode()const
  622 {
  623   return p->mode;
  624 }
  625 
  626 bool QuaZip::isOpen()const
  627 {
  628   return p->mode!=mdNotOpen;
  629 }
  630 
  631 int QuaZip::getZipError() const
  632 {
  633   return p->zipError;
  634 }
  635 
  636 void QuaZip::setComment(const QString& comment)
  637 {
  638   p->comment=comment;
  639 }
  640 
  641 bool QuaZip::hasCurrentFile()const
  642 {
  643   return p->hasCurrentFile_f;
  644 }
  645 
  646 unzFile QuaZip::getUnzFile()
  647 {
  648   return p->unzFile_f;
  649 }
  650 
  651 zipFile QuaZip::getZipFile()
  652 {
  653   return p->zipFile_f;
  654 }
  655 
  656 void QuaZip::setDataDescriptorWritingEnabled(bool enabled)
  657 {
  658     p->dataDescriptorWritingEnabled = enabled;
  659 }
  660 
  661 bool QuaZip::isDataDescriptorWritingEnabled() const
  662 {
  663     return p->dataDescriptorWritingEnabled;
  664 }
  665 
  666 template<typename TFileInfo>
  667 TFileInfo QuaZip_getFileInfo(QuaZip *zip, bool *ok);
  668 
  669 template<>
  670 QuaZipFileInfo QuaZip_getFileInfo(QuaZip *zip, bool *ok)
  671 {
  672     QuaZipFileInfo info;
  673     *ok = zip->getCurrentFileInfo(&info);
  674     return info;
  675 }
  676 
  677 template<>
  678 QuaZipFileInfo64 QuaZip_getFileInfo(QuaZip *zip, bool *ok)
  679 {
  680     QuaZipFileInfo64 info;
  681     *ok = zip->getCurrentFileInfo(&info);
  682     return info;
  683 }
  684 
  685 template<>
  686 QString QuaZip_getFileInfo(QuaZip *zip, bool *ok)
  687 {
  688     QString name = zip->getCurrentFileName();
  689     *ok = !name.isEmpty();
  690     return name;
  691 }
  692 
  693 template<typename TFileInfo>
  694 bool QuaZipPrivate::getFileInfoList(QList<TFileInfo> *result) const
  695 {
  696   QuaZipPrivate *fakeThis=const_cast<QuaZipPrivate*>(this);
  697   fakeThis->zipError=UNZ_OK;
  698   if (mode!=QuaZip::mdUnzip) {
  699     qWarning("QuaZip::getFileNameList/getFileInfoList(): "
  700             "ZIP is not open in mdUnzip mode");
  701     return false;
  702   }
  703   QString currentFile;
  704   if (q->hasCurrentFile()) {
  705       currentFile = q->getCurrentFileName();
  706   }
  707   if (q->goToFirstFile()) {
  708       do {
  709           bool ok;
  710           result->append(QuaZip_getFileInfo<TFileInfo>(q, &ok));
  711           if (!ok)
  712               return false;
  713       } while (q->goToNextFile());
  714   }
  715   if (zipError != UNZ_OK)
  716       return false;
  717   if (currentFile.isEmpty()) {
  718       if (!q->goToFirstFile())
  719           return false;
  720   } else {
  721       if (!q->setCurrentFile(currentFile))
  722           return false;
  723   }
  724   return true;
  725 }
  726 
  727 QStringList QuaZip::getFileNameList() const
  728 {
  729     QStringList list;
  730     if (p->getFileInfoList(&list))
  731         return list;
  732     else
  733         return QStringList();
  734 }
  735 
  736 QList<QuaZipFileInfo> QuaZip::getFileInfoList() const
  737 {
  738     QList<QuaZipFileInfo> list;
  739     if (p->getFileInfoList(&list))
  740         return list;
  741     else
  742         return QList<QuaZipFileInfo>();
  743 }
  744 
  745 QList<QuaZipFileInfo64> QuaZip::getFileInfoList64() const
  746 {
  747     QList<QuaZipFileInfo64> list;
  748     if (p->getFileInfoList(&list))
  749         return list;
  750     else
  751         return QList<QuaZipFileInfo64>();
  752 }
  753 
  754 Qt::CaseSensitivity QuaZip::convertCaseSensitivity(QuaZip::CaseSensitivity cs)
  755 {
  756   if (cs == csDefault) {
  757 #ifdef Q_OS_WIN
  758       return Qt::CaseInsensitive;
  759 #else
  760       return Qt::CaseSensitive;
  761 #endif
  762   } else {
  763       return cs == csSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
  764   }
  765 }
  766 
  767 void QuaZip::setDefaultFileNameCodec(QTextCodec *codec)
  768 {
  769     QuaZipPrivate::defaultFileNameCodec = codec;
  770 }
  771 
  772 void QuaZip::setDefaultFileNameCodec(const char *codecName)
  773 {
  774     setDefaultFileNameCodec(QTextCodec::codecForName(codecName));
  775 }
  776 
  777 void QuaZip::setZip64Enabled(bool zip64)
  778 {
  779     p->zip64 = zip64;
  780 }
  781 
  782 bool QuaZip::isZip64Enabled() const
  783 {
  784     return p->zip64;
  785 }
  786 
  787 bool QuaZip::isAutoClose() const
  788 {
  789     return p->autoClose;
  790 }
  791 
  792 void QuaZip::setAutoClose(bool autoClose) const
  793 {
  794     p->autoClose = autoClose;
  795 }