source: s10k/CommonLibs/quazip-0.7.2/quazip/quazip.cpp @ 1096

Last change on this file since 1096 was 1096, checked in by s10k, 19 months ago

Added zlib, quazip, basicxmlsyntaxhighlighter, conditionalsemaphore and linenumberdisplay libraries. zlib and quazip are pre-compiled, but you can compile them yourself, just delete the dll files (or equivalent binary files to your OS)

File size: 22.0 KB
Line 
1/*
2Copyright (C) 2005-2014 Sergey A. Tachenov
3
4This file is part of QuaZIP.
5
6QuaZIP is free software: you can redistribute it and/or modify
7it under the terms of the GNU Lesser General Public License as published by
8the Free Software Foundation, either version 2.1 of the License, or
9(at your option) any later version.
10
11QuaZIP is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14GNU Lesser General Public License for more details.
15
16You should have received a copy of the GNU Lesser General Public License
17along with QuaZIP.  If not, see <http://www.gnu.org/licenses/>.
18
19See COPYING file for the full LGPL text.
20
21Original ZIP package is copyrighted by Gilles Vollant, see
22quazip/(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  */
39class 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 *q):
83      q(q),
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 *q, const QString &zipName):
101      q(q),
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 *q, QIODevice *ioDevice):
120        q(q),
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
150QTextCodec *QuaZipPrivate::defaultFileNameCodec = NULL;
151
152void QuaZipPrivate::clearDirectoryMap()
153{
154    directoryCaseInsensitive.clear();
155    directoryCaseSensitive.clear();
156    lastMappedDirectoryEntry.num_of_file = 0;
157    lastMappedDirectoryEntry.pos_in_zip_directory = 0;
158}
159
160void 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
179bool 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
200QuaZip::QuaZip():
201  p(new QuaZipPrivate(this))
202{
203}
204
205QuaZip::QuaZip(const QString& zipName):
206  p(new QuaZipPrivate(this, zipName))
207{
208}
209
210QuaZip::QuaZip(QIODevice *ioDevice):
211  p(new QuaZipPrivate(this, ioDevice))
212{
213}
214
215QuaZip::~QuaZip()
216{
217  if(isOpen())
218    close();
219  delete p;
220}
221
222bool 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
331void 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
362void 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
372void 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
382int 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
396QString 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
415bool 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
473bool 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
485bool 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
499bool 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
513bool 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
558QString 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
579void QuaZip::setFileNameCodec(QTextCodec *fileNameCodec)
580{
581  p->fileNameCodec=fileNameCodec;
582}
583
584void QuaZip::setFileNameCodec(const char *fileNameCodecName)
585{
586  p->fileNameCodec=QTextCodec::codecForName(fileNameCodecName);
587}
588
589QTextCodec *QuaZip::getFileNameCodec()const
590{
591  return p->fileNameCodec;
592}
593
594void QuaZip::setCommentCodec(QTextCodec *commentCodec)
595{
596  p->commentCodec=commentCodec;
597}
598
599void QuaZip::setCommentCodec(const char *commentCodecName)
600{
601  p->commentCodec=QTextCodec::codecForName(commentCodecName);
602}
603
604QTextCodec *QuaZip::getCommentCodec()const
605{
606  return p->commentCodec;
607}
608
609QString QuaZip::getZipName() const
610{
611  return p->zipName;
612}
613
614QIODevice *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
621QuaZip::Mode QuaZip::getMode()const
622{
623  return p->mode;
624}
625
626bool QuaZip::isOpen()const
627{
628  return p->mode!=mdNotOpen;
629}
630
631int QuaZip::getZipError() const
632{
633  return p->zipError;
634}
635
636void QuaZip::setComment(const QString& comment)
637{
638  p->comment=comment;
639}
640
641bool QuaZip::hasCurrentFile()const
642{
643  return p->hasCurrentFile_f;
644}
645
646unzFile QuaZip::getUnzFile()
647{
648  return p->unzFile_f;
649}
650
651zipFile QuaZip::getZipFile()
652{
653  return p->zipFile_f;
654}
655
656void QuaZip::setDataDescriptorWritingEnabled(bool enabled)
657{
658    p->dataDescriptorWritingEnabled = enabled;
659}
660
661bool QuaZip::isDataDescriptorWritingEnabled() const
662{
663    return p->dataDescriptorWritingEnabled;
664}
665
666template<typename TFileInfo>
667TFileInfo QuaZip_getFileInfo(QuaZip *zip, bool *ok);
668
669template<>
670QuaZipFileInfo QuaZip_getFileInfo(QuaZip *zip, bool *ok)
671{
672    QuaZipFileInfo info;
673    *ok = zip->getCurrentFileInfo(&info);
674    return info;
675}
676
677template<>
678QuaZipFileInfo64 QuaZip_getFileInfo(QuaZip *zip, bool *ok)
679{
680    QuaZipFileInfo64 info;
681    *ok = zip->getCurrentFileInfo(&info);
682    return info;
683}
684
685template<>
686QString QuaZip_getFileInfo(QuaZip *zip, bool *ok)
687{
688    QString name = zip->getCurrentFileName();
689    *ok = !name.isEmpty();
690    return name;
691}
692
693template<typename TFileInfo>
694bool 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
727QStringList QuaZip::getFileNameList() const
728{
729    QStringList list;
730    if (p->getFileInfoList(&list))
731        return list;
732    else
733        return QStringList();
734}
735
736QList<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
745QList<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
754Qt::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
767void QuaZip::setDefaultFileNameCodec(QTextCodec *codec)
768{
769    QuaZipPrivate::defaultFileNameCodec = codec;
770}
771
772void QuaZip::setDefaultFileNameCodec(const char *codecName)
773{
774    setDefaultFileNameCodec(QTextCodec::codecForName(codecName));
775}
776
777void QuaZip::setZip64Enabled(bool zip64)
778{
779    p->zip64 = zip64;
780}
781
782bool QuaZip::isZip64Enabled() const
783{
784    return p->zip64;
785}
786
787bool QuaZip::isAutoClose() const
788{
789    return p->autoClose;
790}
791
792void QuaZip::setAutoClose(bool autoClose) const
793{
794    p->autoClose = autoClose;
795}
Note: See TracBrowser for help on using the repository browser.