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

Last change on this file since 1115 was 1096, checked in by s10k, 7 years 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.