├── .gitignore
├── CSGO-Toolbox.pro
├── CSGO-Toolbox.pro.user
├── CSGO-Toolbox.pro.user.a843b07
├── LICENSE
├── README.md
├── dll.qrc
├── dll
├── SolveVAC.bat
├── boiler.exe
├── libShareCodeToURL.dll
├── libShareCodeToURLcs.dll
├── quazip.dll
├── quazipd.dll
├── steam_api.dll
└── steam_appid.txt
├── img
└── Loading.png
├── lib.qrc
├── lib
├── JlCompress.cpp
├── JlCompress.h
├── crypt.h
├── ioapi.h
├── qioapi.cpp
├── quaadler32.cpp
├── quaadler32.h
├── quachecksum32.h
├── quacrc32.cpp
├── quacrc32.h
├── quagzipfile.cpp
├── quagzipfile.h
├── quaziodevice.cpp
├── quaziodevice.h
├── quazip.cpp
├── quazip.h
├── quazip.lib
├── quazip.pro
├── quazip_global.h
├── quazipd.lib
├── quazipdir.cpp
├── quazipdir.h
├── quazipfile.cpp
├── quazipfile.h
├── quazipfileinfo.cpp
├── quazipfileinfo.h
├── quazipnewinfo.cpp
├── quazipnewinfo.h
├── unzip.c
├── unzip.h
├── zip.c
└── zip.h
├── libShareCodeToURLcs.lib
├── logo.ico
├── logo.png
├── main.cpp
├── mainwindow.cpp
├── mainwindow.h
├── mainwindow.ui
├── qtconfig.qrc
└── src.qrc
/.gitignore:
--------------------------------------------------------------------------------
1 | # Prerequisites
2 | *.d
3 |
4 | # Compiled Object files
5 | *.slo
6 | *.lo
7 | *.o
8 | *.obj
9 |
10 | # Precompiled Headers
11 | *.gch
12 | *.pch
13 |
14 | # Compiled Dynamic libraries
15 | *.so
16 | *.dylib
17 | *.dll
18 |
19 | # Fortran module files
20 | *.mod
21 | *.smod
22 |
23 | # Compiled Static libraries
24 | *.lai
25 | *.la
26 | *.a
27 | *.lib
28 |
29 | # Executables
30 | *.exe
31 | *.out
32 | *.app
33 |
--------------------------------------------------------------------------------
/CSGO-Toolbox.pro:
--------------------------------------------------------------------------------
1 | QT += core gui
2 |
3 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
4 |
5 | CONFIG += c++11
6 |
7 | # The following define makes your compiler emit warnings if you use
8 | # any Qt feature that has been marked deprecated (the exact warnings
9 | # depend on your compiler). Please consult the documentation of the
10 | # deprecated API in order to know how to port your code away from it.
11 | DEFINES += QT_DEPRECATED_WARNINGS
12 |
13 | # You can also make your code fail to compile if it uses deprecated APIs.
14 | # In order to do so, uncomment the following line.
15 | # You can also select to disable deprecated APIs only up to a certain version of Qt.
16 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
17 |
18 | SOURCES += \
19 | main.cpp\
20 | MainWindow.cpp
21 |
22 | HEADERS += \
23 | MainWindow.h
24 |
25 | FORMS += \
26 | MainWindow.ui
27 |
28 | # Default rules for deployment.
29 | qnx: target.path = /tmp/$${TARGET}/bin
30 | else: unix:!android: target.path = /opt/$${TARGET}/bin
31 | !isEmpty(target.path): INSTALLS += target
32 |
33 | DISTFILES +=
34 |
35 | RESOURCES += \
36 | dll.qrc \
37 | lib.qrc \
38 | src.qrc
39 |
40 | QMAKE_CXXFLAGS+=/execution-charset:utf-8
41 |
42 | RC_CODEPAGE = 65001
43 |
44 | VERSION = 1.0.3
45 |
46 | DEFINES += APP_VERSION=\\\"$$VERSION\\\"
47 |
48 | QMAKE_TARGET_PRODUCT = "CSGO ToolBox"
49 | QMAKE_PROJECT_NAME = "CSGO工具箱"
50 |
51 | RC_ICONS = logo.ico
52 |
53 | SUBDIRS += \
54 |
55 | INCLUDEPATH += $$[QT_INSTALL_HEADERS]/QtZlib
56 | INCLUDEPATH += $$PWD/.
57 | DEPENDPATH += $$PWD/.
58 |
59 | win32:CONFIG(release, debug|release): LIBS += -L$$PWD/lib/ -lquazip
60 | else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/lib/ -lquazipd
61 | win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$PWD/lib/libquazip.a
62 | else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$PWD/lib/libquazipd.a
63 | else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$PWD/lib/quazip.lib
64 | else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$PWD/lib/quazipd.lib
65 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Purp1e
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 1. # CSGO工具箱 项目说明
2 |
3 | > Qt版项目已经搁置,正在使用Go+Wails+Vue重构。
4 |
5 | ## 一、CSGO工具箱介绍
6 |
7 | CSGO工具箱是旨在方便CSGO玩家调整、修改、保存、备份和转移设置等的工具性质的GUI程序,减少玩家在调整设置等事项上花费的时间,从而节省出更多的时间投入游戏本身。
8 |
9 | > CSGO Toolbox is dedicated to enabling CSGO players to modify their configs, game settings etc much more swiftly, thus more time is saved to put on game itself.
10 |
11 | ## 二、项目开发须知
12 |
13 | ### 1. 开发环境
14 |
15 | 本项目使用[Qt 5.14.0](http://download.qt.io/archive/qt/5.14/5.14.0/) + [MSVC 2017](ed2k://|file|en_visual_studio_community_2015_x86_dvd_6847364.iso|3965825024|6A7D8489BB2877E6BB8ACB2DD187B637|/) + [qt-vsaddin-msvc2017-2.4.3](http://download.qt.io/archive/vsaddin/2.4.3/) + Git,系统Win10 64位。如果需要参与开发,请配置好这些环境。
16 |
17 | 当前项目要用到一些外部文件,在`.dll/`中,需要手动将这些文件移动到`debug`或`release`文件夹中。
18 |
19 | ### 2. 参与开发
20 |
21 | 可联系邮箱`438518244@qq.com`,或者QQ群`759990621`,开发过程中需要用到[Git操作](https://www.jianshu.com/p/02cf41f38b6a),请提前备好相关知识。
22 |
23 | ### 3. 讨论&添加功能|特性须知
24 |
25 | 使用GitHub的[issues](https://github.com/Purple-CSGO/CSGO-Toolbox/issues)和[milestone](https://github.com/Purple-CSGO/CSGO-Toolbox/milestones)实现:
26 |
27 | 1. 有任何打算实现或者将要实现或者提议都发布在issues里,标题简述功能,内容详细说明,分成n条,管理者根据情况打上`将要实现`的标签。
28 | 2. 某功能相关建议或说明第一次提出时创建`milestone`,并将该issue加入。
29 | 3. 当开发者正在实现某功能时,标签改为`正在实现`。
30 | 4. 功能已经调试完成之后,标签改为`已实现`。
31 | 5. 功能完整加入程序中并确认无误之后,标签改为`已部署`,并关闭issue。
32 |
--------------------------------------------------------------------------------
/dll.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | dll/boiler.exe
4 | dll/libShareCodeToURL.dll
5 | dll/libShareCodeToURLcs.dll
6 | dll/steam_api.dll
7 | dll/steam_appid.txt
8 | dll/quazipd.dll
9 | dll/quazip.dll
10 |
11 |
12 |
--------------------------------------------------------------------------------
/dll/SolveVAC.bat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Purple-CSGO/CSGO-Toolbox-Qt/bf425be542e3173298e84675e41c75ab21ab1bed/dll/SolveVAC.bat
--------------------------------------------------------------------------------
/dll/boiler.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Purple-CSGO/CSGO-Toolbox-Qt/bf425be542e3173298e84675e41c75ab21ab1bed/dll/boiler.exe
--------------------------------------------------------------------------------
/dll/libShareCodeToURL.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Purple-CSGO/CSGO-Toolbox-Qt/bf425be542e3173298e84675e41c75ab21ab1bed/dll/libShareCodeToURL.dll
--------------------------------------------------------------------------------
/dll/libShareCodeToURLcs.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Purple-CSGO/CSGO-Toolbox-Qt/bf425be542e3173298e84675e41c75ab21ab1bed/dll/libShareCodeToURLcs.dll
--------------------------------------------------------------------------------
/dll/quazip.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Purple-CSGO/CSGO-Toolbox-Qt/bf425be542e3173298e84675e41c75ab21ab1bed/dll/quazip.dll
--------------------------------------------------------------------------------
/dll/quazipd.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Purple-CSGO/CSGO-Toolbox-Qt/bf425be542e3173298e84675e41c75ab21ab1bed/dll/quazipd.dll
--------------------------------------------------------------------------------
/dll/steam_api.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Purple-CSGO/CSGO-Toolbox-Qt/bf425be542e3173298e84675e41c75ab21ab1bed/dll/steam_api.dll
--------------------------------------------------------------------------------
/dll/steam_appid.txt:
--------------------------------------------------------------------------------
1 | 730
--------------------------------------------------------------------------------
/img/Loading.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Purple-CSGO/CSGO-Toolbox-Qt/bf425be542e3173298e84675e41c75ab21ab1bed/img/Loading.png
--------------------------------------------------------------------------------
/lib.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | libShareCodeToURLcs.lib
4 |
5 |
6 |
7 |
8 | lib/quazip.lib
9 | lib/quazipd.lib
10 | lib/crypt.h
11 | lib/ioapi.h
12 | lib/JlCompress.cpp
13 | lib/JlCompress.h
14 | lib/qioapi.cpp
15 | lib/quaadler32.cpp
16 | lib/quaadler32.h
17 | lib/quachecksum32.h
18 | lib/quacrc32.cpp
19 | lib/quacrc32.h
20 | lib/quagzipfile.cpp
21 | lib/quagzipfile.h
22 | lib/quaziodevice.cpp
23 | lib/quaziodevice.h
24 | lib/quazip.cpp
25 | lib/quazip.h
26 | lib/quazip.pro
27 | lib/quazip_global.h
28 | lib/quazipdir.cpp
29 | lib/quazipdir.h
30 | lib/quazipfile.cpp
31 | lib/quazipfile.h
32 | lib/quazipfileinfo.cpp
33 | lib/quazipfileinfo.h
34 | lib/quazipnewinfo.cpp
35 | lib/quazipnewinfo.h
36 | lib/unzip.c
37 | lib/unzip.h
38 | lib/zip.c
39 | lib/zip.h
40 |
41 |
42 |
--------------------------------------------------------------------------------
/lib/JlCompress.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2010 Roberto Pompermaier
3 | Copyright (C) 2005-2014 Sergey A. Tachenov
4 |
5 | This file is part of QuaZIP.
6 |
7 | QuaZIP is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU Lesser General Public License as published by
9 | the Free Software Foundation, either version 2.1 of the License, or
10 | (at your option) any later version.
11 |
12 | QuaZIP is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU Lesser General Public License for more details.
16 |
17 | You should have received a copy of the GNU Lesser General Public License
18 | along with QuaZIP. If not, see .
19 |
20 | See COPYING file for the full LGPL text.
21 |
22 | Original ZIP package is copyrighted by Gilles Vollant and contributors,
23 | see quazip/(un)zip.h files for details. Basically it's the zlib license.
24 | */
25 |
26 | #include "JlCompress.h"
27 | #include
28 |
29 | static bool copyData(QIODevice &inFile, QIODevice &outFile)
30 | {
31 | while (!inFile.atEnd()) {
32 | char buf[4096];
33 | qint64 readLen = inFile.read(buf, 4096);
34 | if (readLen <= 0)
35 | return false;
36 | if (outFile.write(buf, readLen) != readLen)
37 | return false;
38 | }
39 | return true;
40 | }
41 |
42 | bool JlCompress::compressFile(QuaZip* zip, QString fileName, QString fileDest) {
43 | // zip: oggetto dove aggiungere il file
44 | // fileName: nome del file reale
45 | // fileDest: nome del file all'interno del file compresso
46 |
47 | // Controllo l'apertura dello zip
48 | if (!zip) return false;
49 | if (zip->getMode()!=QuaZip::mdCreate &&
50 | zip->getMode()!=QuaZip::mdAppend &&
51 | zip->getMode()!=QuaZip::mdAdd) return false;
52 |
53 | // Apro il file originale
54 | QFile inFile;
55 | inFile.setFileName(fileName);
56 | if(!inFile.open(QIODevice::ReadOnly)) return false;
57 |
58 | // Apro il file risulato
59 | QuaZipFile outFile(zip);
60 | if(!outFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileDest, inFile.fileName()))) return false;
61 |
62 | // Copio i dati
63 | if (!copyData(inFile, outFile) || outFile.getZipError()!=UNZ_OK) {
64 | return false;
65 | }
66 |
67 | // Chiudo i file
68 | outFile.close();
69 | if (outFile.getZipError()!=UNZ_OK) return false;
70 | inFile.close();
71 |
72 | return true;
73 | }
74 |
75 | bool JlCompress::compressSubDir(QuaZip* zip, QString dir, QString origDir, bool recursive, QDir::Filters filters) {
76 | // zip: oggetto dove aggiungere il file
77 | // dir: cartella reale corrente
78 | // origDir: cartella reale originale
79 | // (path(dir)-path(origDir)) = path interno all'oggetto zip
80 |
81 | // Controllo l'apertura dello zip
82 | if (!zip) return false;
83 | if (zip->getMode()!=QuaZip::mdCreate &&
84 | zip->getMode()!=QuaZip::mdAppend &&
85 | zip->getMode()!=QuaZip::mdAdd) return false;
86 |
87 | // Controllo la cartella
88 | QDir directory(dir);
89 | if (!directory.exists()) return false;
90 |
91 | QDir origDirectory(origDir);
92 | if (dir != origDir) {
93 | QuaZipFile dirZipFile(zip);
94 | if (!dirZipFile.open(QIODevice::WriteOnly,
95 | QuaZipNewInfo(origDirectory.relativeFilePath(dir) + "/", dir), 0, 0, 0)) {
96 | return false;
97 | }
98 | dirZipFile.close();
99 | }
100 |
101 |
102 | // Se comprimo anche le sotto cartelle
103 | if (recursive) {
104 | // Per ogni sotto cartella
105 | QFileInfoList files = directory.entryInfoList(QDir::AllDirs|QDir::NoDotAndDotDot|filters);
106 | Q_FOREACH (QFileInfo file, files) {
107 | // Comprimo la sotto cartella
108 | if(!compressSubDir(zip,file.absoluteFilePath(),origDir,recursive,filters)) return false;
109 | }
110 | }
111 |
112 | // Per ogni file nella cartella
113 | QFileInfoList files = directory.entryInfoList(QDir::Files|filters);
114 | Q_FOREACH (QFileInfo file, files) {
115 | // Se non e un file o e il file compresso che sto creando
116 | if(!file.isFile()||file.absoluteFilePath()==zip->getZipName()) continue;
117 |
118 | // Creo il nome relativo da usare all'interno del file compresso
119 | QString filename = origDirectory.relativeFilePath(file.absoluteFilePath());
120 |
121 | // Comprimo il file
122 | if (!compressFile(zip,file.absoluteFilePath(),filename)) return false;
123 | }
124 |
125 | return true;
126 | }
127 |
128 | bool JlCompress::extractFile(QuaZip* zip, QString fileName, QString fileDest) {
129 | // zip: oggetto dove aggiungere il file
130 | // filename: nome del file reale
131 | // fileincompress: nome del file all'interno del file compresso
132 |
133 | // Controllo l'apertura dello zip
134 | if (!zip) return false;
135 | if (zip->getMode()!=QuaZip::mdUnzip) return false;
136 |
137 | // Apro il file compresso
138 | if (!fileName.isEmpty())
139 | zip->setCurrentFile(fileName);
140 | QuaZipFile inFile(zip);
141 | if(!inFile.open(QIODevice::ReadOnly) || inFile.getZipError()!=UNZ_OK) return false;
142 |
143 | // Controllo esistenza cartella file risultato
144 | QDir curDir;
145 | if (fileDest.endsWith('/')) {
146 | if (!curDir.mkpath(fileDest)) {
147 | return false;
148 | }
149 | } else {
150 | if (!curDir.mkpath(QFileInfo(fileDest).absolutePath())) {
151 | return false;
152 | }
153 | }
154 |
155 | QuaZipFileInfo64 info;
156 | if (!zip->getCurrentFileInfo(&info))
157 | return false;
158 |
159 | QFile::Permissions srcPerm = info.getPermissions();
160 | if (fileDest.endsWith('/') && QFileInfo(fileDest).isDir()) {
161 | if (srcPerm != 0) {
162 | QFile(fileDest).setPermissions(srcPerm);
163 | }
164 | return true;
165 | }
166 |
167 | // Apro il file risultato
168 | QFile outFile;
169 | outFile.setFileName(fileDest);
170 | if(!outFile.open(QIODevice::WriteOnly)) return false;
171 |
172 | // Copio i dati
173 | if (!copyData(inFile, outFile) || inFile.getZipError()!=UNZ_OK) {
174 | outFile.close();
175 | removeFile(QStringList(fileDest));
176 | return false;
177 | }
178 | outFile.close();
179 |
180 | // Chiudo i file
181 | inFile.close();
182 | if (inFile.getZipError()!=UNZ_OK) {
183 | removeFile(QStringList(fileDest));
184 | return false;
185 | }
186 |
187 | if (srcPerm != 0) {
188 | outFile.setPermissions(srcPerm);
189 | }
190 | return true;
191 | }
192 |
193 | bool JlCompress::removeFile(QStringList listFile) {
194 | bool ret = true;
195 | // Per ogni file
196 | for (int i=0; iopen(QuaZip::mdUnzip)) {
395 | delete zip;
396 | return QStringList();
397 | }
398 |
399 | // Estraggo i nomi dei file
400 | QStringList lst;
401 | QuaZipFileInfo64 info;
402 | for(bool more=zip->goToFirstFile(); more; more=zip->goToNextFile()) {
403 | if(!zip->getCurrentFileInfo(&info)) {
404 | delete zip;
405 | return QStringList();
406 | }
407 | lst << info.name;
408 | //info.name.toLocal8Bit().constData()
409 | }
410 |
411 | // Chiudo il file zip
412 | zip->close();
413 | if(zip->getZipError()!=0) {
414 | delete zip;
415 | return QStringList();
416 | }
417 | delete zip;
418 | return lst;
419 | }
420 |
421 | QStringList JlCompress::extractDir(QIODevice *ioDevice, QString dir)
422 | {
423 | QuaZip zip(ioDevice);
424 | return extractDir(zip, dir);
425 | }
426 |
427 | QStringList JlCompress::getFileList(QIODevice *ioDevice)
428 | {
429 | QuaZip *zip = new QuaZip(ioDevice);
430 | return getFileList(zip);
431 | }
432 |
433 | QString JlCompress::extractFile(QIODevice *ioDevice, QString fileName, QString fileDest)
434 | {
435 | QuaZip zip(ioDevice);
436 | return extractFile(zip, fileName, fileDest);
437 | }
438 |
439 | QStringList JlCompress::extractFiles(QIODevice *ioDevice, QStringList files, QString dir)
440 | {
441 | QuaZip zip(ioDevice);
442 | return extractFiles(zip, files, dir);
443 | }
444 |
--------------------------------------------------------------------------------
/lib/JlCompress.h:
--------------------------------------------------------------------------------
1 | #ifndef JLCOMPRESSFOLDER_H_
2 | #define JLCOMPRESSFOLDER_H_
3 |
4 | /*
5 | Copyright (C) 2010 Roberto Pompermaier
6 | Copyright (C) 2005-2016 Sergey A. Tachenov
7 |
8 | This file is part of QuaZIP.
9 |
10 | QuaZIP is free software: you can redistribute it and/or modify
11 | it under the terms of the GNU Lesser General Public License as published by
12 | the Free Software Foundation, either version 2.1 of the License, or
13 | (at your option) any later version.
14 |
15 | QuaZIP is distributed in the hope that it will be useful,
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | GNU Lesser General Public License for more details.
19 |
20 | You should have received a copy of the GNU Lesser General Public License
21 | along with QuaZIP. If not, see .
22 |
23 | See COPYING file for the full LGPL text.
24 |
25 | Original ZIP package is copyrighted by Gilles Vollant and contributors,
26 | see quazip/(un)zip.h files for details. Basically it's the zlib license.
27 | */
28 |
29 | #include "quazip.h"
30 | #include "quazipfile.h"
31 | #include "quazipfileinfo.h"
32 | #include
33 | #include
34 | #include
35 | #include
36 |
37 | /// Utility class for typical operations.
38 | /**
39 | This class contains a number of useful static functions to perform
40 | simple operations, such as mass ZIP packing or extraction.
41 | */
42 | class QUAZIP_EXPORT JlCompress {
43 | private:
44 | static QStringList extractDir(QuaZip &zip, const QString &dir);
45 | static QStringList getFileList(QuaZip *zip);
46 | static QString extractFile(QuaZip &zip, QString fileName, QString fileDest);
47 | static QStringList extractFiles(QuaZip &zip, const QStringList &files, const QString &dir);
48 | /// Compress a single file.
49 | /**
50 | \param zip Opened zip to compress the file to.
51 | \param fileName The full path to the source file.
52 | \param fileDest The full name of the file inside the archive.
53 | \return true if success, false otherwise.
54 | */
55 | static bool compressFile(QuaZip* zip, QString fileName, QString fileDest);
56 | /// Compress a subdirectory.
57 | /**
58 | \param parentZip Opened zip containing the parent directory.
59 | \param dir The full path to the directory to pack.
60 | \param parentDir The full path to the directory corresponding to
61 | the root of the ZIP.
62 | \param recursive Whether to pack sub-directories as well or only
63 | files.
64 | \return true if success, false otherwise.
65 | */
66 | static bool compressSubDir(QuaZip* parentZip, QString dir, QString parentDir, bool recursive,
67 | QDir::Filters filters);
68 | /// Extract a single file.
69 | /**
70 | \param zip The opened zip archive to extract from.
71 | \param fileName The full name of the file to extract.
72 | \param fileDest The full path to the destination file.
73 | \return true if success, false otherwise.
74 | */
75 | static bool extractFile(QuaZip* zip, QString fileName, QString fileDest);
76 | /// Remove some files.
77 | /**
78 | \param listFile The list of files to remove.
79 | \return true if success, false otherwise.
80 | */
81 | static bool removeFile(QStringList listFile);
82 |
83 | public:
84 | /// Compress a single file.
85 | /**
86 | \param fileCompressed The name of the archive.
87 | \param file The file to compress.
88 | \return true if success, false otherwise.
89 | */
90 | static bool compressFile(QString fileCompressed, QString file);
91 | /// Compress a list of files.
92 | /**
93 | \param fileCompressed The name of the archive.
94 | \param files The file list to compress.
95 | \return true if success, false otherwise.
96 | */
97 | static bool compressFiles(QString fileCompressed, QStringList files);
98 | /// Compress a whole directory.
99 | /**
100 | Does not compress hidden files. See compressDir(QString, QString, bool, QDir::Filters).
101 |
102 | \param fileCompressed The name of the archive.
103 | \param dir The directory to compress.
104 | \param recursive Whether to pack the subdirectories as well, or
105 | just regular files.
106 | \return true if success, false otherwise.
107 | */
108 | static bool compressDir(QString fileCompressed, QString dir = QString(), bool recursive = true);
109 | /**
110 | * @brief Compress a whole directory.
111 | *
112 | * Unless filters are specified explicitly, packs
113 | * only regular non-hidden files (and subdirs, if @c recursive is true).
114 | * If filters are specified, they are OR-combined with
115 | * %QDir::AllDirs|%QDir::NoDotAndDotDot when searching for dirs
116 | * and with QDir::Files when searching for files.
117 | *
118 | * @param fileCompressed path to the resulting archive
119 | * @param dir path to the directory being compressed
120 | * @param recursive if true, then the subdirectories are packed as well
121 | * @param filters what to pack, filters are applied both when searching
122 | * for subdirs (if packing recursively) and when looking for files to pack
123 | * @return true on success, false otherwise
124 | */
125 | static bool compressDir(QString fileCompressed, QString dir,
126 | bool recursive, QDir::Filters filters);
127 |
128 | public:
129 | /// Extract a single file.
130 | /**
131 | \param fileCompressed The name of the archive.
132 | \param fileName The file to extract.
133 | \param fileDest The destination file, assumed to be identical to
134 | \a file if left empty.
135 | \return The list of the full paths of the files extracted, empty on failure.
136 | */
137 | static QString extractFile(QString fileCompressed, QString fileName, QString fileDest = QString());
138 | /// Extract a list of files.
139 | /**
140 | \param fileCompressed The name of the archive.
141 | \param files The file list to extract.
142 | \param dir The directory to put the files to, the current
143 | directory if left empty.
144 | \return The list of the full paths of the files extracted, empty on failure.
145 | */
146 | static QStringList extractFiles(QString fileCompressed, QStringList files, QString dir = QString());
147 | /// Extract a whole archive.
148 | /**
149 | \param fileCompressed The name of the archive.
150 | \param dir The directory to extract to, the current directory if
151 | left empty.
152 | \return The list of the full paths of the files extracted, empty on failure.
153 | */
154 | static QStringList extractDir(QString fileCompressed, QString dir = QString());
155 | /// Get the file list.
156 | /**
157 | \return The list of the files in the archive, or, more precisely, the
158 | list of the entries, including both files and directories if they
159 | are present separately.
160 | */
161 | static QStringList getFileList(QString fileCompressed);
162 | /// Extract a single file.
163 | /**
164 | \param ioDevice pointer to device with compressed data.
165 | \param fileName The file to extract.
166 | \param fileDest The destination file, assumed to be identical to
167 | \a file if left empty.
168 | \return The list of the full paths of the files extracted, empty on failure.
169 | */
170 | static QString extractFile(QIODevice *ioDevice, QString fileName, QString fileDest = QString());
171 | /// Extract a list of files.
172 | /**
173 | \param ioDevice pointer to device with compressed data.
174 | \param files The file list to extract.
175 | \param dir The directory to put the files to, the current
176 | directory if left empty.
177 | \return The list of the full paths of the files extracted, empty on failure.
178 | */
179 | static QStringList extractFiles(QIODevice *ioDevice, QStringList files, QString dir = QString());
180 | /// Extract a whole archive.
181 | /**
182 | \param ioDevice pointer to device with compressed data.
183 | \param dir The directory to extract to, the current directory if
184 | left empty.
185 | \return The list of the full paths of the files extracted, empty on failure.
186 | */
187 | static QStringList extractDir(QIODevice *ioDevice, QString dir = QString());
188 | /// Get the file list.
189 | /**
190 | \return The list of the files in the archive, or, more precisely, the
191 | list of the entries, including both files and directories if they
192 | are present separately.
193 | */
194 | static QStringList getFileList(QIODevice *ioDevice);
195 | };
196 |
197 | #endif /* JLCOMPRESSFOLDER_H_ */
198 |
--------------------------------------------------------------------------------
/lib/crypt.h:
--------------------------------------------------------------------------------
1 | /* crypt.h -- base code for crypt/uncrypt ZIPfile
2 |
3 |
4 | Version 1.01e, February 12th, 2005
5 |
6 | Copyright (C) 1998-2005 Gilles Vollant
7 |
8 | This code is a modified version of crypting code in Infozip distribution
9 |
10 | The encryption/decryption parts of this source code (as opposed to the
11 | non-echoing password parts) were originally written in Europe. The
12 | whole source package can be freely distributed, including from the USA.
13 | (Prior to January 2000, re-export from the US was a violation of US law.)
14 |
15 | This encryption code is a direct transcription of the algorithm from
16 | Roger Schlafly, described by Phil Katz in the file appnote.txt. This
17 | file (appnote.txt) is distributed with the PKZIP program (even in the
18 | version without encryption capabilities).
19 |
20 | If you don't need crypting in your application, just define symbols
21 | NOCRYPT and NOUNCRYPT.
22 |
23 | This code support the "Traditional PKWARE Encryption".
24 |
25 | The new AES encryption added on Zip format by Winzip (see the page
26 | http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
27 | Encryption is not supported.
28 | */
29 |
30 | #include "quazip_global.h"
31 |
32 | #define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
33 |
34 | /***********************************************************************
35 | * Return the next byte in the pseudo-random sequence
36 | */
37 | static int decrypt_byte(unsigned long* pkeys, const z_crc_t FAR * pcrc_32_tab UNUSED)
38 | {
39 | //(void) pcrc_32_tab; /* avoid "unused parameter" warning */
40 | unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
41 | * unpredictable manner on 16-bit systems; not a problem
42 | * with any known compiler so far, though */
43 |
44 | temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
45 | return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
46 | }
47 |
48 | /***********************************************************************
49 | * Update the encryption keys with the next byte of plain text
50 | */
51 | static int update_keys(unsigned long* pkeys,const z_crc_t FAR * pcrc_32_tab,int c)
52 | {
53 | (*(pkeys+0)) = CRC32((*(pkeys+0)), c);
54 | (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
55 | (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
56 | {
57 | register int keyshift = (int)((*(pkeys+1)) >> 24);
58 | (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
59 | }
60 | return c;
61 | }
62 |
63 |
64 | /***********************************************************************
65 | * Initialize the encryption keys and the random header according to
66 | * the given password.
67 | */
68 | static void init_keys(const char* passwd,unsigned long* pkeys,const z_crc_t FAR * pcrc_32_tab)
69 | {
70 | *(pkeys+0) = 305419896L;
71 | *(pkeys+1) = 591751049L;
72 | *(pkeys+2) = 878082192L;
73 | while (*passwd != '\0') {
74 | update_keys(pkeys,pcrc_32_tab,(int)*passwd);
75 | passwd++;
76 | }
77 | }
78 |
79 | #define zdecode(pkeys,pcrc_32_tab,c) \
80 | (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
81 |
82 | #define zencode(pkeys,pcrc_32_tab,c,t) \
83 | (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
84 |
85 | #ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
86 |
87 | #define RAND_HEAD_LEN 12
88 | /* "last resort" source for second part of crypt seed pattern */
89 | # ifndef ZCR_SEED2
90 | # define ZCR_SEED2 3141592654UL /* use PI as default pattern */
91 | # endif
92 |
93 | static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting)
94 | const char *passwd; /* password string */
95 | unsigned char *buf; /* where to write header */
96 | int bufSize;
97 | unsigned long* pkeys;
98 | const z_crc_t FAR * pcrc_32_tab;
99 | unsigned long crcForCrypting;
100 | {
101 | int n; /* index in random header */
102 | int t; /* temporary */
103 | int c; /* random byte */
104 | unsigned char header[RAND_HEAD_LEN-2]; /* random header */
105 | static unsigned calls = 0; /* ensure different random header each time */
106 |
107 | if (bufSize> 7) & 0xff;
122 | header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
123 | }
124 | /* Encrypt random header (last two bytes is high word of crc) */
125 | init_keys(passwd, pkeys, pcrc_32_tab);
126 | for (n = 0; n < RAND_HEAD_LEN-2; n++)
127 | {
128 | buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
129 | }
130 | buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
131 | buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
132 | return n;
133 | }
134 |
135 | #endif
136 |
--------------------------------------------------------------------------------
/lib/ioapi.h:
--------------------------------------------------------------------------------
1 | /* ioapi.h -- IO base function header for compress/uncompress .zip
2 | part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
3 |
4 | Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
5 |
6 | Modifications for Zip64 support
7 | Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
8 |
9 | Modified by Sergey A. Tachenov to allow QIODevice API usage.
10 |
11 | For more info read MiniZip_info.txt
12 |
13 | Changes
14 |
15 | Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this)
16 | Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux.
17 | More if/def section may be needed to support other platforms
18 | Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows.
19 | (but you should use iowin32.c for windows instead)
20 |
21 | */
22 |
23 | #ifndef _ZLIBIOAPI64_H
24 | #define _ZLIBIOAPI64_H
25 |
26 | #if (!defined(_WIN32)) && (!defined(WIN32))
27 |
28 | // Linux needs this to support file operation on files larger then 4+GB
29 | // But might need better if/def to select just the platforms that needs them.
30 |
31 | #ifndef __USE_FILE_OFFSET64
32 | #define __USE_FILE_OFFSET64
33 | #endif
34 | #ifndef __USE_LARGEFILE64
35 | #define __USE_LARGEFILE64
36 | #endif
37 | #ifndef _LARGEFILE64_SOURCE
38 | #define _LARGEFILE64_SOURCE
39 | #endif
40 | #ifndef _FILE_OFFSET_BIT
41 | #define _FILE_OFFSET_BIT 64
42 | #endif
43 | #endif
44 |
45 | #include
46 | #include
47 | #include "zlib.h"
48 |
49 | #if defined(USE_FILE32API)
50 | #define fopen64 fopen
51 | #define ftello64 ftell
52 | #define fseeko64 fseek
53 | #else
54 | #ifdef _MSC_VER
55 | #define fopen64 fopen
56 | #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC)))
57 | #define ftello64 _ftelli64
58 | #define fseeko64 _fseeki64
59 | #else // old MSC
60 | #define ftello64 ftell
61 | #define fseeko64 fseek
62 | #endif
63 | #endif
64 | #endif
65 |
66 | /*
67 | #ifndef ZPOS64_T
68 | #ifdef _WIN32
69 | #define ZPOS64_T fpos_t
70 | #else
71 | #include
72 | #define ZPOS64_T uint64_t
73 | #endif
74 | #endif
75 | */
76 |
77 | #ifdef HAVE_MINIZIP64_CONF_H
78 | #include "mz64conf.h"
79 | #endif
80 |
81 | /* a type choosen by DEFINE */
82 | #ifdef HAVE_64BIT_INT_CUSTOM
83 | typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T;
84 | #else
85 | #ifdef HAS_STDINT_H
86 | #include "stdint.h"
87 | typedef uint64_t ZPOS64_T;
88 | #else
89 |
90 |
91 | #if defined(_MSC_VER) || defined(__BORLANDC__)
92 | typedef unsigned __int64 ZPOS64_T;
93 | #else
94 | typedef unsigned long long int ZPOS64_T;
95 | #endif
96 | #endif
97 | #endif
98 |
99 |
100 |
101 | #ifdef __cplusplus
102 | extern "C" {
103 | #endif
104 |
105 | #ifndef OF
106 | #define OF _Z_OF
107 | #endif
108 |
109 | #define ZLIB_FILEFUNC_SEEK_CUR (1)
110 | #define ZLIB_FILEFUNC_SEEK_END (2)
111 | #define ZLIB_FILEFUNC_SEEK_SET (0)
112 |
113 | #define ZLIB_FILEFUNC_MODE_READ (1)
114 | #define ZLIB_FILEFUNC_MODE_WRITE (2)
115 | #define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
116 |
117 | #define ZLIB_FILEFUNC_MODE_EXISTING (4)
118 | #define ZLIB_FILEFUNC_MODE_CREATE (8)
119 |
120 |
121 | #ifndef ZCALLBACK
122 | #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
123 | #define ZCALLBACK CALLBACK
124 | #else
125 | #define ZCALLBACK
126 | #endif
127 | #endif
128 |
129 |
130 |
131 |
132 | typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, voidpf file, int mode));
133 | typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
134 | typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
135 | typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
136 | typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
137 |
138 | typedef uLong (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
139 | typedef int (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
140 |
141 |
142 | /* here is the "old" 32 bits structure structure */
143 | typedef struct zlib_filefunc_def_s
144 | {
145 | open_file_func zopen_file;
146 | read_file_func zread_file;
147 | write_file_func zwrite_file;
148 | tell_file_func ztell_file;
149 | seek_file_func zseek_file;
150 | close_file_func zclose_file;
151 | testerror_file_func zerror_file;
152 | voidpf opaque;
153 | } zlib_filefunc_def;
154 |
155 | typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream));
156 | typedef int (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
157 | typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, voidpf file, int mode));
158 |
159 | typedef struct zlib_filefunc64_def_s
160 | {
161 | open64_file_func zopen64_file;
162 | read_file_func zread_file;
163 | write_file_func zwrite_file;
164 | tell64_file_func ztell64_file;
165 | seek64_file_func zseek64_file;
166 | close_file_func zclose_file;
167 | testerror_file_func zerror_file;
168 | voidpf opaque;
169 | close_file_func zfakeclose_file; // for no-auto-close flag
170 | } zlib_filefunc64_def;
171 |
172 | void fill_qiodevice64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def));
173 | void fill_qiodevice_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
174 |
175 | /* now internal definition, only for zip.c and unzip.h */
176 | typedef struct zlib_filefunc64_32_def_s
177 | {
178 | zlib_filefunc64_def zfile_func64;
179 | open_file_func zopen32_file;
180 | tell_file_func ztell32_file;
181 | seek_file_func zseek32_file;
182 | } zlib_filefunc64_32_def;
183 |
184 |
185 | #define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
186 | #define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
187 | //#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream))
188 | //#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode))
189 | #define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream))
190 | #define ZFAKECLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zfakeclose_file)) ((filefunc).zfile_func64.opaque,filestream))
191 | #define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream))
192 |
193 | voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf file,int mode));
194 | int call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin));
195 | ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream));
196 |
197 | void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32);
198 |
199 | #define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode)))
200 | #define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream)))
201 | #define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode)))
202 |
203 | #ifdef __cplusplus
204 | }
205 | #endif
206 |
207 | #endif
208 |
--------------------------------------------------------------------------------
/lib/qioapi.cpp:
--------------------------------------------------------------------------------
1 | /* ioapi.c -- IO base function header for compress/uncompress .zip
2 | files using zlib + zip or unzip API
3 |
4 | Version 1.01e, February 12th, 2005
5 |
6 | Copyright (C) 1998-2005 Gilles Vollant
7 |
8 | Modified by Sergey A. Tachenov to integrate with Qt.
9 | */
10 |
11 | #include
12 | #include
13 | #include
14 |
15 | #include "zlib.h"
16 | #include "ioapi.h"
17 | #include "quazip_global.h"
18 | #include
19 | #if (QT_VERSION >= 0x050100)
20 | #define QUAZIP_QSAVEFILE_BUG_WORKAROUND
21 | #endif
22 | #ifdef QUAZIP_QSAVEFILE_BUG_WORKAROUND
23 | #include
24 | #endif
25 |
26 | /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
27 |
28 | #ifndef SEEK_CUR
29 | #define SEEK_CUR 1
30 | #endif
31 |
32 | #ifndef SEEK_END
33 | #define SEEK_END 2
34 | #endif
35 |
36 | #ifndef SEEK_SET
37 | #define SEEK_SET 0
38 | #endif
39 |
40 | voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,voidpf file,int mode)
41 | {
42 | if (pfilefunc->zfile_func64.zopen64_file != NULL)
43 | return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,file,mode);
44 | else
45 | {
46 | return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,file,mode);
47 | }
48 | }
49 |
50 | int call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)
51 | {
52 | if (pfilefunc->zfile_func64.zseek64_file != NULL)
53 | return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin);
54 | else
55 | {
56 | uLong offsetTruncated = (uLong)offset;
57 | if (offsetTruncated != offset)
58 | return -1;
59 | else
60 | return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin);
61 | }
62 | }
63 |
64 | ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)
65 | {
66 | if (pfilefunc->zfile_func64.zseek64_file != NULL)
67 | return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream);
68 | else
69 | {
70 | uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream);
71 | if ((tell_uLong) == ((uLong)-1))
72 | return (ZPOS64_T)-1;
73 | else
74 | return tell_uLong;
75 | }
76 | }
77 |
78 | /// @cond internal
79 | struct QIODevice_descriptor {
80 | // Position only used for writing to sequential devices.
81 | qint64 pos;
82 | inline QIODevice_descriptor():
83 | pos(0)
84 | {}
85 | };
86 | /// @endcond
87 |
88 | voidpf ZCALLBACK qiodevice_open_file_func (
89 | voidpf opaque,
90 | voidpf file,
91 | int mode)
92 | {
93 | QIODevice_descriptor *d = reinterpret_cast(opaque);
94 | QIODevice *iodevice = reinterpret_cast(file);
95 | QIODevice::OpenMode desiredMode;
96 | if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
97 | desiredMode = QIODevice::ReadOnly;
98 | else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
99 | desiredMode = QIODevice::ReadWrite;
100 | else if (mode & ZLIB_FILEFUNC_MODE_CREATE)
101 | desiredMode = QIODevice::WriteOnly;
102 | if (iodevice->isOpen()) {
103 | if ((iodevice->openMode() & desiredMode) == desiredMode) {
104 | if (desiredMode != QIODevice::WriteOnly
105 | && iodevice->isSequential()) {
106 | // We can use sequential devices only for writing.
107 | delete d;
108 | return NULL;
109 | } else {
110 | if ((desiredMode & QIODevice::WriteOnly) != 0) {
111 | // open for writing, need to seek existing device
112 | if (!iodevice->isSequential()) {
113 | iodevice->seek(0);
114 | } else {
115 | d->pos = iodevice->pos();
116 | }
117 | }
118 | }
119 | return iodevice;
120 | } else {
121 | delete d;
122 | return NULL;
123 | }
124 | }
125 | iodevice->open(desiredMode);
126 | if (iodevice->isOpen()) {
127 | if (desiredMode != QIODevice::WriteOnly && iodevice->isSequential()) {
128 | // We can use sequential devices only for writing.
129 | iodevice->close();
130 | delete d;
131 | return NULL;
132 | } else {
133 | return iodevice;
134 | }
135 | } else {
136 | delete d;
137 | return NULL;
138 | }
139 | }
140 |
141 |
142 | uLong ZCALLBACK qiodevice_read_file_func (
143 | voidpf opaque,
144 | voidpf stream,
145 | void* buf,
146 | uLong size)
147 | {
148 | QIODevice_descriptor *d = reinterpret_cast(opaque);
149 | QIODevice *iodevice = reinterpret_cast(stream);
150 | qint64 ret64 = iodevice->read((char*)buf,size);
151 | uLong ret;
152 | ret = (uLong) ret64;
153 | if (ret64 != -1) {
154 | d->pos += ret64;
155 | }
156 | return ret;
157 | }
158 |
159 |
160 | uLong ZCALLBACK qiodevice_write_file_func (
161 | voidpf opaque,
162 | voidpf stream,
163 | const void* buf,
164 | uLong size)
165 | {
166 | QIODevice_descriptor *d = reinterpret_cast(opaque);
167 | QIODevice *iodevice = reinterpret_cast(stream);
168 | uLong ret;
169 | qint64 ret64 = iodevice->write((char*)buf,size);
170 | if (ret64 != -1) {
171 | d->pos += ret64;
172 | }
173 | ret = (uLong) ret64;
174 | return ret;
175 | }
176 |
177 | uLong ZCALLBACK qiodevice_tell_file_func (
178 | voidpf opaque,
179 | voidpf stream)
180 | {
181 | QIODevice_descriptor *d = reinterpret_cast(opaque);
182 | QIODevice *iodevice = reinterpret_cast(stream);
183 | uLong ret;
184 | qint64 ret64;
185 | if (iodevice->isSequential()) {
186 | ret64 = d->pos;
187 | } else {
188 | ret64 = iodevice->pos();
189 | }
190 | ret = static_cast(ret64);
191 | return ret;
192 | }
193 |
194 | ZPOS64_T ZCALLBACK qiodevice64_tell_file_func (
195 | voidpf opaque,
196 | voidpf stream)
197 | {
198 | QIODevice_descriptor *d = reinterpret_cast(opaque);
199 | QIODevice *iodevice = reinterpret_cast(stream);
200 | qint64 ret;
201 | if (iodevice->isSequential()) {
202 | ret = d->pos;
203 | } else {
204 | ret = iodevice->pos();
205 | }
206 | return static_cast(ret);
207 | }
208 |
209 | int ZCALLBACK qiodevice_seek_file_func (
210 | voidpf /*opaque UNUSED*/,
211 | voidpf stream,
212 | uLong offset,
213 | int origin)
214 | {
215 | QIODevice *iodevice = reinterpret_cast(stream);
216 | if (iodevice->isSequential()) {
217 | if (origin == ZLIB_FILEFUNC_SEEK_END
218 | && offset == 0) {
219 | // sequential devices are always at end (needed in mdAppend)
220 | return 0;
221 | } else {
222 | qWarning("qiodevice_seek_file_func() called for sequential device");
223 | return -1;
224 | }
225 | }
226 | uLong qiodevice_seek_result=0;
227 | int ret;
228 | switch (origin)
229 | {
230 | case ZLIB_FILEFUNC_SEEK_CUR :
231 | qiodevice_seek_result = ((QIODevice*)stream)->pos() + offset;
232 | break;
233 | case ZLIB_FILEFUNC_SEEK_END :
234 | qiodevice_seek_result = ((QIODevice*)stream)->size() - offset;
235 | break;
236 | case ZLIB_FILEFUNC_SEEK_SET :
237 | qiodevice_seek_result = offset;
238 | break;
239 | default:
240 | return -1;
241 | }
242 | ret = !iodevice->seek(qiodevice_seek_result);
243 | return ret;
244 | }
245 |
246 | int ZCALLBACK qiodevice64_seek_file_func (
247 | voidpf /*opaque UNUSED*/,
248 | voidpf stream,
249 | ZPOS64_T offset,
250 | int origin)
251 | {
252 | QIODevice *iodevice = reinterpret_cast(stream);
253 | if (iodevice->isSequential()) {
254 | if (origin == ZLIB_FILEFUNC_SEEK_END
255 | && offset == 0) {
256 | // sequential devices are always at end (needed in mdAppend)
257 | return 0;
258 | } else {
259 | qWarning("qiodevice_seek_file_func() called for sequential device");
260 | return -1;
261 | }
262 | }
263 | qint64 qiodevice_seek_result=0;
264 | int ret;
265 | switch (origin)
266 | {
267 | case ZLIB_FILEFUNC_SEEK_CUR :
268 | qiodevice_seek_result = ((QIODevice*)stream)->pos() + offset;
269 | break;
270 | case ZLIB_FILEFUNC_SEEK_END :
271 | qiodevice_seek_result = ((QIODevice*)stream)->size() - offset;
272 | break;
273 | case ZLIB_FILEFUNC_SEEK_SET :
274 | qiodevice_seek_result = offset;
275 | break;
276 | default:
277 | return -1;
278 | }
279 | ret = !iodevice->seek(qiodevice_seek_result);
280 | return ret;
281 | }
282 |
283 | int ZCALLBACK qiodevice_close_file_func (
284 | voidpf opaque,
285 | voidpf stream)
286 | {
287 | QIODevice_descriptor *d = reinterpret_cast(opaque);
288 | delete d;
289 | QIODevice *device = reinterpret_cast(stream);
290 | #ifdef QUAZIP_QSAVEFILE_BUG_WORKAROUND
291 | // QSaveFile terribly breaks the is-a idiom:
292 | // it IS a QIODevice, but it is NOT compatible with it: close() is private
293 | QSaveFile *file = qobject_cast(device);
294 | if (file != NULL) {
295 | // We have to call the ugly commit() instead:
296 | return file->commit() ? 0 : -1;
297 | }
298 | #endif
299 | device->close();
300 | return 0;
301 | }
302 |
303 | int ZCALLBACK qiodevice_fakeclose_file_func (
304 | voidpf opaque,
305 | voidpf /*stream*/)
306 | {
307 | QIODevice_descriptor *d = reinterpret_cast(opaque);
308 | delete d;
309 | return 0;
310 | }
311 |
312 | int ZCALLBACK qiodevice_error_file_func (
313 | voidpf /*opaque UNUSED*/,
314 | voidpf /*stream UNUSED*/)
315 | {
316 | // can't check for error due to the QIODevice API limitation
317 | return 0;
318 | }
319 |
320 | void fill_qiodevice_filefunc (
321 | zlib_filefunc_def* pzlib_filefunc_def)
322 | {
323 | pzlib_filefunc_def->zopen_file = qiodevice_open_file_func;
324 | pzlib_filefunc_def->zread_file = qiodevice_read_file_func;
325 | pzlib_filefunc_def->zwrite_file = qiodevice_write_file_func;
326 | pzlib_filefunc_def->ztell_file = qiodevice_tell_file_func;
327 | pzlib_filefunc_def->zseek_file = qiodevice_seek_file_func;
328 | pzlib_filefunc_def->zclose_file = qiodevice_close_file_func;
329 | pzlib_filefunc_def->zerror_file = qiodevice_error_file_func;
330 | pzlib_filefunc_def->opaque = new QIODevice_descriptor;
331 | }
332 |
333 | void fill_qiodevice64_filefunc (
334 | zlib_filefunc64_def* pzlib_filefunc_def)
335 | {
336 | // Open functions are the same for Qt.
337 | pzlib_filefunc_def->zopen64_file = qiodevice_open_file_func;
338 | pzlib_filefunc_def->zread_file = qiodevice_read_file_func;
339 | pzlib_filefunc_def->zwrite_file = qiodevice_write_file_func;
340 | pzlib_filefunc_def->ztell64_file = qiodevice64_tell_file_func;
341 | pzlib_filefunc_def->zseek64_file = qiodevice64_seek_file_func;
342 | pzlib_filefunc_def->zclose_file = qiodevice_close_file_func;
343 | pzlib_filefunc_def->zerror_file = qiodevice_error_file_func;
344 | pzlib_filefunc_def->opaque = new QIODevice_descriptor;
345 | pzlib_filefunc_def->zfakeclose_file = qiodevice_fakeclose_file_func;
346 | }
347 |
348 | void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32)
349 | {
350 | p_filefunc64_32->zfile_func64.zopen64_file = NULL;
351 | p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file;
352 | p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
353 | p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file;
354 | p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file;
355 | p_filefunc64_32->zfile_func64.ztell64_file = NULL;
356 | p_filefunc64_32->zfile_func64.zseek64_file = NULL;
357 | p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file;
358 | p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
359 | p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque;
360 | p_filefunc64_32->zfile_func64.zfakeclose_file = NULL;
361 | p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file;
362 | p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file;
363 | }
364 |
--------------------------------------------------------------------------------
/lib/quaadler32.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2010 Adam Walczak
3 | Copyright (C) 2005-2014 Sergey A. Tachenov
4 |
5 | This file is part of QuaZIP.
6 |
7 | QuaZIP is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU Lesser General Public License as published by
9 | the Free Software Foundation, either version 2.1 of the License, or
10 | (at your option) any later version.
11 |
12 | QuaZIP is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU Lesser General Public License for more details.
16 |
17 | You should have received a copy of the GNU Lesser General Public License
18 | along with QuaZIP. If not, see .
19 |
20 | See COPYING file for the full LGPL text.
21 |
22 | Original ZIP package is copyrighted by Gilles Vollant and contributors,
23 | see quazip/(un)zip.h files for details. Basically it's the zlib license.
24 | */
25 |
26 | #include "quaadler32.h"
27 |
28 | #include "zlib.h"
29 |
30 | QuaAdler32::QuaAdler32()
31 | {
32 | reset();
33 | }
34 |
35 | quint32 QuaAdler32::calculate(const QByteArray &data)
36 | {
37 | return adler32( adler32(0L, Z_NULL, 0), (const Bytef*)data.data(), data.size() );
38 | }
39 |
40 | void QuaAdler32::reset()
41 | {
42 | checksum = adler32(0L, Z_NULL, 0);
43 | }
44 |
45 | void QuaAdler32::update(const QByteArray &buf)
46 | {
47 | checksum = adler32( checksum, (const Bytef*)buf.data(), buf.size() );
48 | }
49 |
50 | quint32 QuaAdler32::value()
51 | {
52 | return checksum;
53 | }
54 |
--------------------------------------------------------------------------------
/lib/quaadler32.h:
--------------------------------------------------------------------------------
1 | #ifndef QUAADLER32_H
2 | #define QUAADLER32_H
3 |
4 | /*
5 | Copyright (C) 2010 Adam Walczak
6 | Copyright (C) 2005-2014 Sergey A. Tachenov
7 |
8 | This file is part of QuaZIP.
9 |
10 | QuaZIP is free software: you can redistribute it and/or modify
11 | it under the terms of the GNU Lesser General Public License as published by
12 | the Free Software Foundation, either version 2.1 of the License, or
13 | (at your option) any later version.
14 |
15 | QuaZIP is distributed in the hope that it will be useful,
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | GNU Lesser General Public License for more details.
19 |
20 | You should have received a copy of the GNU Lesser General Public License
21 | along with QuaZIP. If not, see .
22 |
23 | See COPYING file for the full LGPL text.
24 |
25 | Original ZIP package is copyrighted by Gilles Vollant and contributors,
26 | see quazip/(un)zip.h files for details. Basically it's the zlib license.
27 | */
28 |
29 | #include
30 |
31 | #include "quachecksum32.h"
32 |
33 | /// Adler32 checksum
34 | /** \class QuaAdler32 quaadler32.h
35 | * This class wrappers the adler32 function with the QuaChecksum32 interface.
36 | * See QuaChecksum32 for more info.
37 | */
38 | class QUAZIP_EXPORT QuaAdler32 : public QuaChecksum32
39 | {
40 |
41 | public:
42 | QuaAdler32();
43 |
44 | quint32 calculate(const QByteArray &data);
45 |
46 | void reset();
47 | void update(const QByteArray &buf);
48 | quint32 value();
49 |
50 | private:
51 | quint32 checksum;
52 | };
53 |
54 | #endif //QUAADLER32_H
55 |
--------------------------------------------------------------------------------
/lib/quachecksum32.h:
--------------------------------------------------------------------------------
1 | #ifndef QUACHECKSUM32_H
2 | #define QUACHECKSUM32_H
3 |
4 | /*
5 | Copyright (C) 2005-2014 Sergey A. Tachenov
6 |
7 | This file is part of QuaZIP.
8 |
9 | QuaZIP is free software: you can redistribute it and/or modify
10 | it under the terms of the GNU Lesser General Public License as published by
11 | the Free Software Foundation, either version 2.1 of the License, or
12 | (at your option) any later version.
13 |
14 | QuaZIP is distributed in the hope that it will be useful,
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | GNU Lesser General Public License for more details.
18 |
19 | You should have received a copy of the GNU Lesser General Public License
20 | along with QuaZIP. If not, see .
21 |
22 | See COPYING file for the full LGPL text.
23 |
24 | Original ZIP package is copyrighted by Gilles Vollant and contributors,
25 | see quazip/(un)zip.h files for details. Basically it's the zlib license.
26 | */
27 |
28 | #include
29 | #include "quazip_global.h"
30 |
31 | /// Checksum interface.
32 | /** \class QuaChecksum32 quachecksum32.h
33 | * This is an interface for 32 bit checksums.
34 | * Classes implementing this interface can calcunate a certin
35 | * checksum in a single step:
36 | * \code
37 | * QChecksum32 *crc32 = new QuaCrc32();
38 | * rasoult = crc32->calculate(data);
39 | * \endcode
40 | * or by streaming the data:
41 | * \code
42 | * QChecksum32 *crc32 = new QuaCrc32();
43 | * while(!fileA.atEnd())
44 | * crc32->update(fileA.read(bufSize));
45 | * resoultA = crc32->value();
46 | * crc32->reset();
47 | * while(!fileB.atEnd())
48 | * crc32->update(fileB.read(bufSize));
49 | * resoultB = crc32->value();
50 | * \endcode
51 | */
52 | class QUAZIP_EXPORT QuaChecksum32
53 | {
54 |
55 | public:
56 | ///Calculates the checksum for data.
57 | /** \a data source data
58 | * \return data checksum
59 | *
60 | * This function has no efect on the value returned by value().
61 | */
62 | virtual quint32 calculate(const QByteArray &data) = 0;
63 |
64 | ///Resets the calculation on a checksun for a stream.
65 | virtual void reset() = 0;
66 |
67 | ///Updates the calculated checksum for the stream
68 | /** \a buf next portion of data from the stream
69 | */
70 | virtual void update(const QByteArray &buf) = 0;
71 |
72 | ///Value of the checksum calculated for the stream passed throw update().
73 | /** \return checksum
74 | */
75 | virtual quint32 value() = 0;
76 | };
77 |
78 | #endif //QUACHECKSUM32_H
79 |
--------------------------------------------------------------------------------
/lib/quacrc32.cpp:
--------------------------------------------------------------------------------
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 .
18 |
19 | See COPYING file for the full LGPL text.
20 |
21 | Original ZIP package is copyrighted by Gilles Vollant and contributors,
22 | see quazip/(un)zip.h files for details. Basically it's the zlib license.
23 | */
24 |
25 | #include "quacrc32.h"
26 |
27 | #include "zlib.h"
28 |
29 | QuaCrc32::QuaCrc32()
30 | {
31 | reset();
32 | }
33 |
34 | quint32 QuaCrc32::calculate(const QByteArray &data)
35 | {
36 | return crc32( crc32(0L, Z_NULL, 0), (const Bytef*)data.data(), data.size() );
37 | }
38 |
39 | void QuaCrc32::reset()
40 | {
41 | checksum = crc32(0L, Z_NULL, 0);
42 | }
43 |
44 | void QuaCrc32::update(const QByteArray &buf)
45 | {
46 | checksum = crc32( checksum, (const Bytef*)buf.data(), buf.size() );
47 | }
48 |
49 | quint32 QuaCrc32::value()
50 | {
51 | return checksum;
52 | }
53 |
--------------------------------------------------------------------------------
/lib/quacrc32.h:
--------------------------------------------------------------------------------
1 | #ifndef QUACRC32_H
2 | #define QUACRC32_H
3 |
4 | /*
5 | Copyright (C) 2005-2014 Sergey A. Tachenov
6 |
7 | This file is part of QuaZIP.
8 |
9 | QuaZIP is free software: you can redistribute it and/or modify
10 | it under the terms of the GNU Lesser General Public License as published by
11 | the Free Software Foundation, either version 2.1 of the License, or
12 | (at your option) any later version.
13 |
14 | QuaZIP is distributed in the hope that it will be useful,
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | GNU Lesser General Public License for more details.
18 |
19 | You should have received a copy of the GNU Lesser General Public License
20 | along with QuaZIP. If not, see .
21 |
22 | See COPYING file for the full LGPL text.
23 |
24 | Original ZIP package is copyrighted by Gilles Vollant and contributors,
25 | see quazip/(un)zip.h files for details. Basically it's the zlib license.
26 | */
27 |
28 | #include "quachecksum32.h"
29 |
30 | ///CRC32 checksum
31 | /** \class QuaCrc32 quacrc32.h
32 | * This class wrappers the crc32 function with the QuaChecksum32 interface.
33 | * See QuaChecksum32 for more info.
34 | */
35 | class QUAZIP_EXPORT QuaCrc32 : public QuaChecksum32 {
36 |
37 | public:
38 | QuaCrc32();
39 |
40 | quint32 calculate(const QByteArray &data);
41 |
42 | void reset();
43 | void update(const QByteArray &buf);
44 | quint32 value();
45 |
46 | private:
47 | quint32 checksum;
48 | };
49 |
50 | #endif //QUACRC32_H
51 |
--------------------------------------------------------------------------------
/lib/quagzipfile.cpp:
--------------------------------------------------------------------------------
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 .
18 |
19 | See COPYING file for the full LGPL text.
20 |
21 | Original ZIP package is copyrighted by Gilles Vollant and contributors,
22 | see quazip/(un)zip.h files for details. Basically it's the zlib license.
23 | */
24 |
25 | #include
26 |
27 | #include "quagzipfile.h"
28 |
29 | /// \cond internal
30 | class QuaGzipFilePrivate {
31 | friend class QuaGzipFile;
32 | QString fileName;
33 | gzFile gzd;
34 | inline QuaGzipFilePrivate(): gzd(NULL) {}
35 | inline QuaGzipFilePrivate(const QString &fileName):
36 | fileName(fileName), gzd(NULL) {}
37 | template bool open(FileId id,
38 | QIODevice::OpenMode mode, QString &error);
39 | gzFile open(int fd, const char *modeString);
40 | gzFile open(const QString &name, const char *modeString);
41 | };
42 |
43 | gzFile QuaGzipFilePrivate::open(const QString &name, const char *modeString)
44 | {
45 | return gzopen(QFile::encodeName(name).constData(), modeString);
46 | }
47 |
48 | gzFile QuaGzipFilePrivate::open(int fd, const char *modeString)
49 | {
50 | return gzdopen(fd, modeString);
51 | }
52 |
53 | template
54 | bool QuaGzipFilePrivate::open(FileId id, QIODevice::OpenMode mode,
55 | QString &error)
56 | {
57 | char modeString[2];
58 | modeString[0] = modeString[1] = '\0';
59 | if ((mode & QIODevice::Append) != 0) {
60 | error = QuaGzipFile::trUtf8("QIODevice::Append is not "
61 | "supported for GZIP");
62 | return false;
63 | }
64 | if ((mode & QIODevice::ReadOnly) != 0
65 | && (mode & QIODevice::WriteOnly) != 0) {
66 | error = QuaGzipFile::trUtf8("Opening gzip for both reading"
67 | " and writing is not supported");
68 | return false;
69 | } else if ((mode & QIODevice::ReadOnly) != 0) {
70 | modeString[0] = 'r';
71 | } else if ((mode & QIODevice::WriteOnly) != 0) {
72 | modeString[0] = 'w';
73 | } else {
74 | error = QuaGzipFile::trUtf8("You can open a gzip either for reading"
75 | " or for writing. Which is it?");
76 | return false;
77 | }
78 | gzd = open(id, modeString);
79 | if (gzd == NULL) {
80 | error = QuaGzipFile::trUtf8("Could not gzopen() file");
81 | return false;
82 | }
83 | return true;
84 | }
85 | /// \endcond
86 |
87 | QuaGzipFile::QuaGzipFile():
88 | d(new QuaGzipFilePrivate())
89 | {
90 | }
91 |
92 | QuaGzipFile::QuaGzipFile(QObject *parent):
93 | QIODevice(parent),
94 | d(new QuaGzipFilePrivate())
95 | {
96 | }
97 |
98 | QuaGzipFile::QuaGzipFile(const QString &fileName, QObject *parent):
99 | QIODevice(parent),
100 | d(new QuaGzipFilePrivate(fileName))
101 | {
102 | }
103 |
104 | QuaGzipFile::~QuaGzipFile()
105 | {
106 | if (isOpen()) {
107 | close();
108 | }
109 | delete d;
110 | }
111 |
112 | void QuaGzipFile::setFileName(const QString& fileName)
113 | {
114 | d->fileName = fileName;
115 | }
116 |
117 | QString QuaGzipFile::getFileName() const
118 | {
119 | return d->fileName;
120 | }
121 |
122 | bool QuaGzipFile::isSequential() const
123 | {
124 | return true;
125 | }
126 |
127 | bool QuaGzipFile::open(QIODevice::OpenMode mode)
128 | {
129 | QString error;
130 | if (!d->open(d->fileName, mode, error)) {
131 | setErrorString(error);
132 | return false;
133 | }
134 | return QIODevice::open(mode);
135 | }
136 |
137 | bool QuaGzipFile::open(int fd, QIODevice::OpenMode mode)
138 | {
139 | QString error;
140 | if (!d->open(fd, mode, error)) {
141 | setErrorString(error);
142 | return false;
143 | }
144 | return QIODevice::open(mode);
145 | }
146 |
147 | bool QuaGzipFile::flush()
148 | {
149 | return gzflush(d->gzd, Z_SYNC_FLUSH) == Z_OK;
150 | }
151 |
152 | void QuaGzipFile::close()
153 | {
154 | QIODevice::close();
155 | gzclose(d->gzd);
156 | }
157 |
158 | qint64 QuaGzipFile::readData(char *data, qint64 maxSize)
159 | {
160 | return gzread(d->gzd, (voidp)data, (unsigned)maxSize);
161 | }
162 |
163 | qint64 QuaGzipFile::writeData(const char *data, qint64 maxSize)
164 | {
165 | if (maxSize == 0)
166 | return 0;
167 | int written = gzwrite(d->gzd, (voidp)data, (unsigned)maxSize);
168 | if (written == 0)
169 | return -1;
170 | else
171 | return written;
172 | }
173 |
--------------------------------------------------------------------------------
/lib/quagzipfile.h:
--------------------------------------------------------------------------------
1 | #ifndef QUAZIP_QUAGZIPFILE_H
2 | #define QUAZIP_QUAGZIPFILE_H
3 |
4 | /*
5 | Copyright (C) 2005-2014 Sergey A. Tachenov
6 |
7 | This file is part of QuaZIP.
8 |
9 | QuaZIP is free software: you can redistribute it and/or modify
10 | it under the terms of the GNU Lesser General Public License as published by
11 | the Free Software Foundation, either version 2.1 of the License, or
12 | (at your option) any later version.
13 |
14 | QuaZIP is distributed in the hope that it will be useful,
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | GNU Lesser General Public License for more details.
18 |
19 | You should have received a copy of the GNU Lesser General Public License
20 | along with QuaZIP. If not, see .
21 |
22 | See COPYING file for the full LGPL text.
23 |
24 | Original ZIP package is copyrighted by Gilles Vollant and contributors,
25 | see quazip/(un)zip.h files for details. Basically it's the zlib license.
26 | */
27 |
28 | #include
29 | #include "quazip_global.h"
30 |
31 | #include "zlib.h"
32 |
33 | class QuaGzipFilePrivate;
34 |
35 | /// GZIP file
36 | /**
37 | This class is a wrapper around GZIP file access functions in zlib. Unlike QuaZip classes, it doesn't allow reading from a GZIP file opened as QIODevice, for example, if your GZIP file is in QBuffer. It only provides QIODevice access to a GZIP file contents, but the GZIP file itself must be identified by its name on disk or by descriptor id.
38 | */
39 | class QUAZIP_EXPORT QuaGzipFile: public QIODevice {
40 | Q_OBJECT
41 | public:
42 | /// Empty constructor.
43 | /**
44 | Must call setFileName() before trying to open.
45 | */
46 | QuaGzipFile();
47 | /// Empty constructor with a parent.
48 | /**
49 | Must call setFileName() before trying to open.
50 | \param parent The parent object, as per QObject logic.
51 | */
52 | QuaGzipFile(QObject *parent);
53 | /// Constructor.
54 | /**
55 | \param fileName The name of the GZIP file.
56 | \param parent The parent object, as per QObject logic.
57 | */
58 | QuaGzipFile(const QString &fileName, QObject *parent = NULL);
59 | /// Destructor.
60 | virtual ~QuaGzipFile();
61 | /// Sets the name of the GZIP file to be opened.
62 | void setFileName(const QString& fileName);
63 | /// Returns the name of the GZIP file.
64 | QString getFileName() const;
65 | /// Returns true.
66 | /**
67 | Strictly speaking, zlib supports seeking for GZIP files, but it is
68 | poorly implemented, because there is no way to implement it
69 | properly. For reading, seeking backwards is very slow, and for
70 | writing, it is downright impossible. Therefore, QuaGzipFile does not
71 | support seeking at all.
72 | */
73 | virtual bool isSequential() const;
74 | /// Opens the file.
75 | /**
76 | \param mode Can be either QIODevice::Write or QIODevice::Read.
77 | ReadWrite and Append aren't supported.
78 | */
79 | virtual bool open(QIODevice::OpenMode mode);
80 | /// Opens the file.
81 | /**
82 | \overload
83 | \param fd The file descriptor to read/write the GZIP file from/to.
84 | \param mode Can be either QIODevice::Write or QIODevice::Read.
85 | ReadWrite and Append aren't supported.
86 | */
87 | virtual bool open(int fd, QIODevice::OpenMode mode);
88 | /// Flushes data to file.
89 | /**
90 | The data is written using Z_SYNC_FLUSH mode. Doesn't make any sense
91 | when reading.
92 | */
93 | virtual bool flush();
94 | /// Closes the file.
95 | virtual void close();
96 | protected:
97 | /// Implementation of QIODevice::readData().
98 | virtual qint64 readData(char *data, qint64 maxSize);
99 | /// Implementation of QIODevice::writeData().
100 | virtual qint64 writeData(const char *data, qint64 maxSize);
101 | private:
102 | // not implemented by design to disable copy
103 | QuaGzipFile(const QuaGzipFile &that);
104 | QuaGzipFile& operator=(const QuaGzipFile &that);
105 | QuaGzipFilePrivate *d;
106 | };
107 |
108 | #endif // QUAZIP_QUAGZIPFILE_H
109 |
--------------------------------------------------------------------------------
/lib/quaziodevice.cpp:
--------------------------------------------------------------------------------
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 .
18 |
19 | See COPYING file for the full LGPL text.
20 |
21 | Original ZIP package is copyrighted by Gilles Vollant and contributors,
22 | see quazip/(un)zip.h files for details. Basically it's the zlib license.
23 | */
24 |
25 | #include "quaziodevice.h"
26 |
27 | #define QUAZIO_INBUFSIZE 4096
28 | #define QUAZIO_OUTBUFSIZE 4096
29 |
30 | /// \cond internal
31 | class QuaZIODevicePrivate {
32 | friend class QuaZIODevice;
33 | QuaZIODevicePrivate(QIODevice *io);
34 | ~QuaZIODevicePrivate();
35 | QIODevice *io;
36 | z_stream zins;
37 | z_stream zouts;
38 | char *inBuf;
39 | int inBufPos;
40 | int inBufSize;
41 | char *outBuf;
42 | int outBufPos;
43 | int outBufSize;
44 | bool zBufError;
45 | bool atEnd;
46 | int doFlush(QString &error);
47 | };
48 |
49 | QuaZIODevicePrivate::QuaZIODevicePrivate(QIODevice *io):
50 | io(io),
51 | inBuf(NULL),
52 | inBufPos(0),
53 | inBufSize(0),
54 | outBuf(NULL),
55 | outBufPos(0),
56 | outBufSize(0),
57 | zBufError(false),
58 | atEnd(false)
59 | {
60 | zins.zalloc = (alloc_func) NULL;
61 | zins.zfree = (free_func) NULL;
62 | zins.opaque = NULL;
63 | zouts.zalloc = (alloc_func) NULL;
64 | zouts.zfree = (free_func) NULL;
65 | zouts.opaque = NULL;
66 | inBuf = new char[QUAZIO_INBUFSIZE];
67 | outBuf = new char[QUAZIO_OUTBUFSIZE];
68 | #ifdef QUAZIP_ZIODEVICE_DEBUG_OUTPUT
69 | debug.setFileName("debug.out");
70 | debug.open(QIODevice::WriteOnly);
71 | #endif
72 | #ifdef QUAZIP_ZIODEVICE_DEBUG_INPUT
73 | indebug.setFileName("debug.in");
74 | indebug.open(QIODevice::WriteOnly);
75 | #endif
76 | }
77 |
78 | QuaZIODevicePrivate::~QuaZIODevicePrivate()
79 | {
80 | #ifdef QUAZIP_ZIODEVICE_DEBUG_OUTPUT
81 | debug.close();
82 | #endif
83 | #ifdef QUAZIP_ZIODEVICE_DEBUG_INPUT
84 | indebug.close();
85 | #endif
86 | if (inBuf != NULL)
87 | delete[] inBuf;
88 | if (outBuf != NULL)
89 | delete[] outBuf;
90 | }
91 |
92 | int QuaZIODevicePrivate::doFlush(QString &error)
93 | {
94 | int flushed = 0;
95 | while (outBufPos < outBufSize) {
96 | int more = io->write(outBuf + outBufPos, outBufSize - outBufPos);
97 | if (more == -1) {
98 | error = io->errorString();
99 | return -1;
100 | }
101 | if (more == 0)
102 | break;
103 | outBufPos += more;
104 | flushed += more;
105 | }
106 | if (outBufPos == outBufSize) {
107 | outBufPos = outBufSize = 0;
108 | }
109 | return flushed;
110 | }
111 |
112 | /// \endcond
113 |
114 | // #define QUAZIP_ZIODEVICE_DEBUG_OUTPUT
115 | // #define QUAZIP_ZIODEVICE_DEBUG_INPUT
116 | #ifdef QUAZIP_ZIODEVICE_DEBUG_OUTPUT
117 | #include
118 | static QFile debug;
119 | #endif
120 | #ifdef QUAZIP_ZIODEVICE_DEBUG_INPUT
121 | #include
122 | static QFile indebug;
123 | #endif
124 |
125 | QuaZIODevice::QuaZIODevice(QIODevice *io, QObject *parent):
126 | QIODevice(parent),
127 | d(new QuaZIODevicePrivate(io))
128 | {
129 | connect(io, SIGNAL(readyRead()), SIGNAL(readyRead()));
130 | }
131 |
132 | QuaZIODevice::~QuaZIODevice()
133 | {
134 | if (isOpen())
135 | close();
136 | delete d;
137 | }
138 |
139 | QIODevice *QuaZIODevice::getIoDevice() const
140 | {
141 | return d->io;
142 | }
143 |
144 | bool QuaZIODevice::open(QIODevice::OpenMode mode)
145 | {
146 | if ((mode & QIODevice::Append) != 0) {
147 | setErrorString(trUtf8("QIODevice::Append is not supported for"
148 | " QuaZIODevice"));
149 | return false;
150 | }
151 | if ((mode & QIODevice::ReadWrite) == QIODevice::ReadWrite) {
152 | setErrorString(trUtf8("QIODevice::ReadWrite is not supported for"
153 | " QuaZIODevice"));
154 | return false;
155 | }
156 | if ((mode & QIODevice::ReadOnly) != 0) {
157 | if (inflateInit(&d->zins) != Z_OK) {
158 | setErrorString(d->zins.msg);
159 | return false;
160 | }
161 | }
162 | if ((mode & QIODevice::WriteOnly) != 0) {
163 | if (deflateInit(&d->zouts, Z_DEFAULT_COMPRESSION) != Z_OK) {
164 | setErrorString(d->zouts.msg);
165 | return false;
166 | }
167 | }
168 | return QIODevice::open(mode);
169 | }
170 |
171 | void QuaZIODevice::close()
172 | {
173 | if ((openMode() & QIODevice::ReadOnly) != 0) {
174 | if (inflateEnd(&d->zins) != Z_OK) {
175 | setErrorString(d->zins.msg);
176 | }
177 | }
178 | if ((openMode() & QIODevice::WriteOnly) != 0) {
179 | flush();
180 | if (deflateEnd(&d->zouts) != Z_OK) {
181 | setErrorString(d->zouts.msg);
182 | }
183 | }
184 | QIODevice::close();
185 | }
186 |
187 | qint64 QuaZIODevice::readData(char *data, qint64 maxSize)
188 | {
189 | int read = 0;
190 | while (read < maxSize) {
191 | if (d->inBufPos == d->inBufSize) {
192 | d->inBufPos = 0;
193 | d->inBufSize = d->io->read(d->inBuf, QUAZIO_INBUFSIZE);
194 | if (d->inBufSize == -1) {
195 | d->inBufSize = 0;
196 | setErrorString(d->io->errorString());
197 | return -1;
198 | }
199 | if (d->inBufSize == 0)
200 | break;
201 | }
202 | while (read < maxSize && d->inBufPos < d->inBufSize) {
203 | d->zins.next_in = (Bytef *) (d->inBuf + d->inBufPos);
204 | d->zins.avail_in = d->inBufSize - d->inBufPos;
205 | d->zins.next_out = (Bytef *) (data + read);
206 | d->zins.avail_out = (uInt) (maxSize - read); // hope it's less than 2GB
207 | int more = 0;
208 | switch (inflate(&d->zins, Z_SYNC_FLUSH)) {
209 | case Z_OK:
210 | read = (char *) d->zins.next_out - data;
211 | d->inBufPos = (char *) d->zins.next_in - d->inBuf;
212 | break;
213 | case Z_STREAM_END:
214 | read = (char *) d->zins.next_out - data;
215 | d->inBufPos = (char *) d->zins.next_in - d->inBuf;
216 | d->atEnd = true;
217 | return read;
218 | case Z_BUF_ERROR: // this should never happen, but just in case
219 | if (!d->zBufError) {
220 | qWarning("Z_BUF_ERROR detected with %d/%d in/out, weird",
221 | d->zins.avail_in, d->zins.avail_out);
222 | d->zBufError = true;
223 | }
224 | memmove(d->inBuf, d->inBuf + d->inBufPos, d->inBufSize - d->inBufPos);
225 | d->inBufSize -= d->inBufPos;
226 | d->inBufPos = 0;
227 | more = d->io->read(d->inBuf + d->inBufSize, QUAZIO_INBUFSIZE - d->inBufSize);
228 | if (more == -1) {
229 | setErrorString(d->io->errorString());
230 | return -1;
231 | }
232 | if (more == 0)
233 | return read;
234 | d->inBufSize += more;
235 | break;
236 | default:
237 | setErrorString(QString::fromLocal8Bit(d->zins.msg));
238 | return -1;
239 | }
240 | }
241 | }
242 | #ifdef QUAZIP_ZIODEVICE_DEBUG_INPUT
243 | indebug.write(data, read);
244 | #endif
245 | return read;
246 | }
247 |
248 | qint64 QuaZIODevice::writeData(const char *data, qint64 maxSize)
249 | {
250 | int written = 0;
251 | QString error;
252 | if (d->doFlush(error) == -1) {
253 | setErrorString(error);
254 | return -1;
255 | }
256 | while (written < maxSize) {
257 | // there is some data waiting in the output buffer
258 | if (d->outBufPos < d->outBufSize)
259 | return written;
260 | d->zouts.next_in = (Bytef *) (data + written);
261 | d->zouts.avail_in = (uInt) (maxSize - written); // hope it's less than 2GB
262 | d->zouts.next_out = (Bytef *) d->outBuf;
263 | d->zouts.avail_out = QUAZIO_OUTBUFSIZE;
264 | switch (deflate(&d->zouts, Z_NO_FLUSH)) {
265 | case Z_OK:
266 | written = (char *) d->zouts.next_in - data;
267 | d->outBufSize = (char *) d->zouts.next_out - d->outBuf;
268 | break;
269 | default:
270 | setErrorString(QString::fromLocal8Bit(d->zouts.msg));
271 | return -1;
272 | }
273 | if (d->doFlush(error) == -1) {
274 | setErrorString(error);
275 | return -1;
276 | }
277 | }
278 | #ifdef QUAZIP_ZIODEVICE_DEBUG_OUTPUT
279 | debug.write(data, written);
280 | #endif
281 | return written;
282 | }
283 |
284 | bool QuaZIODevice::flush()
285 | {
286 | QString error;
287 | if (d->doFlush(error) < 0) {
288 | setErrorString(error);
289 | return false;
290 | }
291 | // can't flush buffer, some data is still waiting
292 | if (d->outBufPos < d->outBufSize)
293 | return true;
294 | Bytef c = 0;
295 | d->zouts.next_in = &c; // fake input buffer
296 | d->zouts.avail_in = 0; // of zero size
297 | do {
298 | d->zouts.next_out = (Bytef *) d->outBuf;
299 | d->zouts.avail_out = QUAZIO_OUTBUFSIZE;
300 | switch (deflate(&d->zouts, Z_SYNC_FLUSH)) {
301 | case Z_OK:
302 | d->outBufSize = (char *) d->zouts.next_out - d->outBuf;
303 | if (d->doFlush(error) < 0) {
304 | setErrorString(error);
305 | return false;
306 | }
307 | if (d->outBufPos < d->outBufSize)
308 | return true;
309 | break;
310 | case Z_BUF_ERROR: // nothing to write?
311 | return true;
312 | default:
313 | setErrorString(QString::fromLocal8Bit(d->zouts.msg));
314 | return false;
315 | }
316 | } while (d->zouts.avail_out == 0);
317 | return true;
318 | }
319 |
320 | bool QuaZIODevice::isSequential() const
321 | {
322 | return true;
323 | }
324 |
325 | bool QuaZIODevice::atEnd() const
326 | {
327 | // Here we MUST check QIODevice::bytesAvailable() because WE
328 | // might have reached the end, but QIODevice didn't--
329 | // it could have simply pre-buffered all remaining data.
330 | return (openMode() == NotOpen) || (QIODevice::bytesAvailable() == 0 && d->atEnd);
331 | }
332 |
333 | qint64 QuaZIODevice::bytesAvailable() const
334 | {
335 | // If we haven't recevied Z_STREAM_END, it means that
336 | // we have at least one more input byte available.
337 | // Plus whatever QIODevice has buffered.
338 | return (d->atEnd ? 0 : 1) + QIODevice::bytesAvailable();
339 | }
340 |
--------------------------------------------------------------------------------
/lib/quaziodevice.h:
--------------------------------------------------------------------------------
1 | #ifndef QUAZIP_QUAZIODEVICE_H
2 | #define QUAZIP_QUAZIODEVICE_H
3 |
4 | /*
5 | Copyright (C) 2005-2014 Sergey A. Tachenov
6 |
7 | This file is part of QuaZIP.
8 |
9 | QuaZIP is free software: you can redistribute it and/or modify
10 | it under the terms of the GNU Lesser General Public License as published by
11 | the Free Software Foundation, either version 2.1 of the License, or
12 | (at your option) any later version.
13 |
14 | QuaZIP is distributed in the hope that it will be useful,
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | GNU Lesser General Public License for more details.
18 |
19 | You should have received a copy of the GNU Lesser General Public License
20 | along with QuaZIP. If not, see .
21 |
22 | See COPYING file for the full LGPL text.
23 |
24 | Original ZIP package is copyrighted by Gilles Vollant and contributors,
25 | see quazip/(un)zip.h files for details. Basically it's the zlib license.
26 | */
27 |
28 | #include
29 | #include "quazip_global.h"
30 |
31 | #include "zlib.h"
32 |
33 | class QuaZIODevicePrivate;
34 |
35 | /// A class to compress/decompress QIODevice.
36 | /**
37 | This class can be used to compress any data written to QIODevice or
38 | decompress it back. Compressing data sent over a QTcpSocket is a good
39 | example.
40 | */
41 | class QUAZIP_EXPORT QuaZIODevice: public QIODevice {
42 | Q_OBJECT
43 | public:
44 | /// Constructor.
45 | /**
46 | \param io The QIODevice to read/write.
47 | \param parent The parent object, as per QObject logic.
48 | */
49 | QuaZIODevice(QIODevice *io, QObject *parent = NULL);
50 | /// Destructor.
51 | ~QuaZIODevice();
52 | /// Flushes data waiting to be written.
53 | /**
54 | Unfortunately, as QIODevice doesn't support flush() by itself, the
55 | only thing this method does is write the compressed data into the
56 | device using Z_SYNC_FLUSH mode. If you need the compressed data to
57 | actually be flushed from the buffer of the underlying QIODevice, you
58 | need to call its flush() method as well, providing it supports it
59 | (like QTcpSocket does). Example:
60 | \code
61 | QuaZIODevice dev(&sock);
62 | dev.open(QIODevice::Write);
63 | dev.write(yourDataGoesHere);
64 | dev.flush();
65 | sock->flush(); // this actually sends data to network
66 | \endcode
67 |
68 | This may change in the future versions of QuaZIP by implementing an
69 | ugly hack: trying to cast the QIODevice using qobject_cast to known
70 | flush()-supporting subclasses, and calling flush if the resulting
71 | pointer is not zero.
72 | */
73 | virtual bool flush();
74 | /// Opens the device.
75 | /**
76 | \param mode Neither QIODevice::ReadWrite nor QIODevice::Append are
77 | not supported.
78 | */
79 | virtual bool open(QIODevice::OpenMode mode);
80 | /// Closes this device, but not the underlying one.
81 | /**
82 | The underlying QIODevice is not closed in case you want to write
83 | something else to it.
84 | */
85 | virtual void close();
86 | /// Returns the underlying device.
87 | QIODevice *getIoDevice() const;
88 | /// Returns true.
89 | virtual bool isSequential() const;
90 | /// Returns true iff the end of the compressed stream is reached.
91 | virtual bool atEnd() const;
92 | /// Returns the number of the bytes buffered.
93 | virtual qint64 bytesAvailable() const;
94 | protected:
95 | /// Implementation of QIODevice::readData().
96 | virtual qint64 readData(char *data, qint64 maxSize);
97 | /// Implementation of QIODevice::writeData().
98 | virtual qint64 writeData(const char *data, qint64 maxSize);
99 | private:
100 | QuaZIODevicePrivate *d;
101 | };
102 | #endif // QUAZIP_QUAZIODEVICE_H
103 |
--------------------------------------------------------------------------------
/lib/quazip.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Purple-CSGO/CSGO-Toolbox-Qt/bf425be542e3173298e84675e41c75ab21ab1bed/lib/quazip.lib
--------------------------------------------------------------------------------
/lib/quazip.pro:
--------------------------------------------------------------------------------
1 | TEMPLATE = lib
2 | CONFIG += qt warn_on
3 | QT -= gui
4 |
5 | # The ABI version.
6 |
7 | !win32:VERSION = 1.0.0
8 |
9 | # 1.0.0 is the first stable ABI.
10 | # The next binary incompatible change will be 2.0.0 and so on.
11 | # The existing QuaZIP policy on changing ABI requires to bump the
12 | # major version of QuaZIP itself as well. Note that there may be
13 | # other reasons for chaging the major version of QuaZIP, so
14 | # in case where there is a QuaZIP major version bump but no ABI change,
15 | # the VERSION variable will stay the same.
16 |
17 | # For example:
18 |
19 | # QuaZIP 1.0 is released after some 0.x, keeping binary compatibility.
20 | # VERSION stays 1.0.0.
21 | # Then some binary incompatible change is introduced. QuaZIP goes up to
22 | # 2.0, VERSION to 2.0.0.
23 | # And so on.
24 |
25 |
26 | # This one handles dllimport/dllexport directives.
27 | DEFINES += QUAZIP_BUILD
28 |
29 | # You'll need to define this one manually if using a build system other
30 | # than qmake or using QuaZIP sources directly in your project.
31 | CONFIG(staticlib): DEFINES += QUAZIP_STATIC
32 |
33 | # Input
34 | include(quazip.pri)
35 |
36 |
37 | CONFIG(debug, debug|release) {
38 | mac: TARGET = $$join(TARGET,,,_debug)
39 | win32: TARGET = $$join(TARGET,,,d)
40 | }
41 |
42 | unix:!symbian {
43 | headers.path=$$PREFIX/include/quazip
44 | headers.files=$$HEADERS
45 | target.path=$$PREFIX/lib/$${LIB_ARCH}
46 | INSTALLS += headers target
47 |
48 | OBJECTS_DIR=.obj
49 | MOC_DIR=.moc
50 |
51 | }
52 |
53 | win32 {
54 | headers.path=$$PREFIX/include/quazip
55 | headers.files=$$HEADERS
56 | target.path=$$PREFIX/lib
57 | INSTALLS += headers target
58 | # workaround for qdatetime.h macro bug
59 | DEFINES += NOMINMAX
60 | }
61 |
62 |
63 | symbian {
64 |
65 | # Note, on Symbian you may run into troubles with LGPL.
66 | # The point is, if your application uses some version of QuaZip,
67 | # and a newer binary compatible version of QuaZip is released, then
68 | # the users of your application must be able to relink it with the
69 | # new QuaZip version. For example, to take advantage of some QuaZip
70 | # bug fixes.
71 |
72 | # This is probably best achieved by building QuaZip as a static
73 | # library and providing linkable object files of your application,
74 | # so users can relink it.
75 |
76 | CONFIG += staticlib
77 | CONFIG += debug_and_release
78 |
79 | LIBS += -lezip
80 |
81 | #Export headers to SDK Epoc32/include directory
82 | exportheaders.sources = $$HEADERS
83 | exportheaders.path = quazip
84 | for(header, exportheaders.sources) {
85 | BLD_INF_RULES.prj_exports += "$$header $$exportheaders.path/$$basename(header)"
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/lib/quazip_global.h:
--------------------------------------------------------------------------------
1 | #ifndef QUAZIP_GLOBAL_H
2 | #define QUAZIP_GLOBAL_H
3 |
4 | /*
5 | Copyright (C) 2005-2014 Sergey A. Tachenov
6 |
7 | This file is part of QuaZIP.
8 |
9 | QuaZIP is free software: you can redistribute it and/or modify
10 | it under the terms of the GNU Lesser General Public License as published by
11 | the Free Software Foundation, either version 2.1 of the License, or
12 | (at your option) any later version.
13 |
14 | QuaZIP is distributed in the hope that it will be useful,
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | GNU Lesser General Public License for more details.
18 |
19 | You should have received a copy of the GNU Lesser General Public License
20 | along with QuaZIP. If not, see .
21 |
22 | See COPYING file for the full LGPL text.
23 |
24 | Original ZIP package is copyrighted by Gilles Vollant and contributors,
25 | see quazip/(un)zip.h files for details. Basically it's the zlib license.
26 | */
27 |
28 | #include
29 |
30 | /**
31 | This is automatically defined when building a static library, but when
32 | including QuaZip sources directly into a project, QUAZIP_STATIC should
33 | be defined explicitly to avoid possible troubles with unnecessary
34 | importing/exporting.
35 | */
36 | #ifdef QUAZIP_STATIC
37 | #define QUAZIP_EXPORT
38 | #else
39 | /**
40 | * When building a DLL with MSVC, QUAZIP_BUILD must be defined.
41 | * qglobal.h takes care of defining Q_DECL_* correctly for msvc/gcc.
42 | */
43 | #if defined(QUAZIP_BUILD)
44 | #define QUAZIP_EXPORT Q_DECL_EXPORT
45 | #else
46 | #define QUAZIP_EXPORT Q_DECL_IMPORT
47 | #endif
48 | #endif // QUAZIP_STATIC
49 |
50 | #ifdef __GNUC__
51 | #define UNUSED __attribute__((__unused__))
52 | #else
53 | #define UNUSED
54 | #endif
55 |
56 | #define QUAZIP_EXTRA_NTFS_MAGIC 0x000Au
57 | #define QUAZIP_EXTRA_NTFS_TIME_MAGIC 0x0001u
58 |
59 | #endif // QUAZIP_GLOBAL_H
60 |
--------------------------------------------------------------------------------
/lib/quazipd.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Purple-CSGO/CSGO-Toolbox-Qt/bf425be542e3173298e84675e41c75ab21ab1bed/lib/quazipd.lib
--------------------------------------------------------------------------------
/lib/quazipdir.cpp:
--------------------------------------------------------------------------------
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 .
18 |
19 | See COPYING file for the full LGPL text.
20 |
21 | Original ZIP package is copyrighted by Gilles Vollant and contributors,
22 | see quazip/(un)zip.h files for details. Basically it's the zlib license.
23 | */
24 |
25 | #include "quazipdir.h"
26 |
27 | #include
28 | #include
29 |
30 | /// \cond internal
31 | class QuaZipDirPrivate: public QSharedData {
32 | friend class QuaZipDir;
33 | private:
34 | QuaZipDirPrivate(QuaZip *zip, const QString &dir = QString()):
35 | zip(zip), dir(dir), caseSensitivity(QuaZip::csDefault),
36 | filter(QDir::NoFilter), sorting(QDir::NoSort) {}
37 | QuaZip *zip;
38 | QString dir;
39 | QuaZip::CaseSensitivity caseSensitivity;
40 | QDir::Filters filter;
41 | QStringList nameFilters;
42 | QDir::SortFlags sorting;
43 | template
44 | bool entryInfoList(QStringList nameFilters, QDir::Filters filter,
45 | QDir::SortFlags sort, TFileInfoList &result) const;
46 | inline QString simplePath() const {return QDir::cleanPath(dir);}
47 | };
48 | /// \endcond
49 |
50 | QuaZipDir::QuaZipDir(const QuaZipDir &that):
51 | d(that.d)
52 | {
53 | }
54 |
55 | QuaZipDir::QuaZipDir(QuaZip *zip, const QString &dir):
56 | d(new QuaZipDirPrivate(zip, dir))
57 | {
58 | if (d->dir.startsWith('/'))
59 | d->dir = d->dir.mid(1);
60 | }
61 |
62 | QuaZipDir::~QuaZipDir()
63 | {
64 | }
65 |
66 | bool QuaZipDir::operator==(const QuaZipDir &that)
67 | {
68 | return d->zip == that.d->zip && d->dir == that.d->dir;
69 | }
70 |
71 | QuaZipDir& QuaZipDir::operator=(const QuaZipDir &that)
72 | {
73 | this->d = that.d;
74 | return *this;
75 | }
76 |
77 | QString QuaZipDir::operator[](int pos) const
78 | {
79 | return entryList().at(pos);
80 | }
81 |
82 | QuaZip::CaseSensitivity QuaZipDir::caseSensitivity() const
83 | {
84 | return d->caseSensitivity;
85 | }
86 |
87 | bool QuaZipDir::cd(const QString &directoryName)
88 | {
89 | if (directoryName == "/") {
90 | d->dir = "";
91 | return true;
92 | }
93 | QString dirName = directoryName;
94 | if (dirName.endsWith('/'))
95 | dirName.chop(1);
96 | if (dirName.contains('/')) {
97 | QuaZipDir dir(*this);
98 | if (dirName.startsWith('/')) {
99 | #ifdef QUAZIP_QUAZIPDIR_DEBUG
100 | qDebug("QuaZipDir::cd(%s): going to /",
101 | dirName.toUtf8().constData());
102 | #endif
103 | if (!dir.cd("/"))
104 | return false;
105 | }
106 | QStringList path = dirName.split('/', QString::SkipEmptyParts);
107 | for (QStringList::const_iterator i = path.constBegin();
108 | i != path.end();
109 | ++i) {
110 | const QString &step = *i;
111 | #ifdef QUAZIP_QUAZIPDIR_DEBUG
112 | qDebug("QuaZipDir::cd(%s): going to %s",
113 | dirName.toUtf8().constData(),
114 | step.toUtf8().constData());
115 | #endif
116 | if (!dir.cd(step))
117 | return false;
118 | }
119 | d->dir = dir.path();
120 | return true;
121 | } else { // no '/'
122 | if (dirName == ".") {
123 | return true;
124 | } else if (dirName == "..") {
125 | if (isRoot()) {
126 | return false;
127 | } else {
128 | int slashPos = d->dir.lastIndexOf('/');
129 | if (slashPos == -1) {
130 | d->dir = "";
131 | } else {
132 | d->dir = d->dir.left(slashPos);
133 | }
134 | return true;
135 | }
136 | } else { // a simple subdirectory
137 | if (exists(dirName)) {
138 | if (isRoot())
139 | d->dir = dirName;
140 | else
141 | d->dir += "/" + dirName;
142 | return true;
143 | } else {
144 | return false;
145 | }
146 | }
147 | }
148 | }
149 |
150 | bool QuaZipDir::cdUp()
151 | {
152 | return cd("..");
153 | }
154 |
155 | uint QuaZipDir::count() const
156 | {
157 | return entryList().count();
158 | }
159 |
160 | QString QuaZipDir::dirName() const
161 | {
162 | return QDir(d->dir).dirName();
163 | }
164 |
165 | QuaZipFileInfo64 QuaZipDir_getFileInfo(QuaZip *zip, bool *ok,
166 | const QString &relativeName,
167 | bool isReal)
168 | {
169 | QuaZipFileInfo64 info;
170 | if (isReal) {
171 | *ok = zip->getCurrentFileInfo(&info);
172 | } else {
173 | *ok = true;
174 | info.compressedSize = 0;
175 | info.crc = 0;
176 | info.diskNumberStart = 0;
177 | info.externalAttr = 0;
178 | info.flags = 0;
179 | info.internalAttr = 0;
180 | info.method = 0;
181 | info.uncompressedSize = 0;
182 | info.versionCreated = info.versionNeeded = 0;
183 | }
184 | info.name = relativeName;
185 | return info;
186 | }
187 |
188 | static void QuaZipDir_convertInfoList(const QList &from,
189 | QList &to)
190 | {
191 | to = from;
192 | }
193 |
194 | static void QuaZipDir_convertInfoList(const QList &from,
195 | QStringList &to)
196 | {
197 | to.clear();
198 | for (QList::const_iterator i = from.constBegin();
199 | i != from.constEnd();
200 | ++i) {
201 | to.append(i->name);
202 | }
203 | }
204 |
205 | static void QuaZipDir_convertInfoList(const QList &from,
206 | QList &to)
207 | {
208 | to.clear();
209 | for (QList::const_iterator i = from.constBegin();
210 | i != from.constEnd();
211 | ++i) {
212 | QuaZipFileInfo info32;
213 | i->toQuaZipFileInfo(info32);
214 | to.append(info32);
215 | }
216 | }
217 |
218 | /// \cond internal
219 | /**
220 | An utility class to restore the current file.
221 | */
222 | class QuaZipDirRestoreCurrent {
223 | public:
224 | inline QuaZipDirRestoreCurrent(QuaZip *zip):
225 | zip(zip), currentFile(zip->getCurrentFileName()) {}
226 | inline ~QuaZipDirRestoreCurrent()
227 | {
228 | zip->setCurrentFile(currentFile);
229 | }
230 | private:
231 | QuaZip *zip;
232 | QString currentFile;
233 | };
234 | /// \endcond
235 |
236 | /// \cond internal
237 | class QuaZipDirComparator
238 | {
239 | private:
240 | QDir::SortFlags sort;
241 | static QString getExtension(const QString &name);
242 | int compareStrings(const QString &string1, const QString &string2);
243 | public:
244 | inline QuaZipDirComparator(QDir::SortFlags sort): sort(sort) {}
245 | bool operator()(const QuaZipFileInfo64 &info1, const QuaZipFileInfo64 &info2);
246 | };
247 |
248 | QString QuaZipDirComparator::getExtension(const QString &name)
249 | {
250 | if (name.endsWith('.') || name.indexOf('.', 1) == -1) {
251 | return "";
252 | } else {
253 | return name.mid(name.lastIndexOf('.') + 1);
254 | }
255 |
256 | }
257 |
258 | int QuaZipDirComparator::compareStrings(const QString &string1,
259 | const QString &string2)
260 | {
261 | if (sort & QDir::LocaleAware) {
262 | if (sort & QDir::IgnoreCase) {
263 | return string1.toLower().localeAwareCompare(string2.toLower());
264 | } else {
265 | return string1.localeAwareCompare(string2);
266 | }
267 | } else {
268 | return string1.compare(string2, (sort & QDir::IgnoreCase)
269 | ? Qt::CaseInsensitive : Qt::CaseSensitive);
270 | }
271 | }
272 |
273 | bool QuaZipDirComparator::operator()(const QuaZipFileInfo64 &info1,
274 | const QuaZipFileInfo64 &info2)
275 | {
276 | QDir::SortFlags order = sort
277 | & (QDir::Name | QDir::Time | QDir::Size | QDir::Type);
278 | if ((sort & QDir::DirsFirst) == QDir::DirsFirst
279 | || (sort & QDir::DirsLast) == QDir::DirsLast) {
280 | if (info1.name.endsWith('/') && !info2.name.endsWith('/'))
281 | return (sort & QDir::DirsFirst) == QDir::DirsFirst;
282 | else if (!info1.name.endsWith('/') && info2.name.endsWith('/'))
283 | return (sort & QDir::DirsLast) == QDir::DirsLast;
284 | }
285 | bool result;
286 | int extDiff;
287 | switch (order) {
288 | case QDir::Name:
289 | result = compareStrings(info1.name, info2.name) < 0;
290 | break;
291 | case QDir::Type:
292 | extDiff = compareStrings(getExtension(info1.name),
293 | getExtension(info2.name));
294 | if (extDiff == 0) {
295 | result = compareStrings(info1.name, info2.name) < 0;
296 | } else {
297 | result = extDiff < 0;
298 | }
299 | break;
300 | case QDir::Size:
301 | if (info1.uncompressedSize == info2.uncompressedSize) {
302 | result = compareStrings(info1.name, info2.name) < 0;
303 | } else {
304 | result = info1.uncompressedSize < info2.uncompressedSize;
305 | }
306 | break;
307 | case QDir::Time:
308 | if (info1.dateTime == info2.dateTime) {
309 | result = compareStrings(info1.name, info2.name) < 0;
310 | } else {
311 | result = info1.dateTime < info2.dateTime;
312 | }
313 | break;
314 | default:
315 | qWarning("QuaZipDirComparator(): Invalid sort mode 0x%2X",
316 | static_cast(sort));
317 | return false;
318 | }
319 | return (sort & QDir::Reversed) ? !result : result;
320 | }
321 |
322 | template
323 | bool QuaZipDirPrivate::entryInfoList(QStringList nameFilters,
324 | QDir::Filters filter, QDir::SortFlags sort, TFileInfoList &result) const
325 | {
326 | QString basePath = simplePath();
327 | if (!basePath.isEmpty())
328 | basePath += "/";
329 | int baseLength = basePath.length();
330 | result.clear();
331 | QuaZipDirRestoreCurrent saveCurrent(zip);
332 | if (!zip->goToFirstFile()) {
333 | return zip->getZipError() == UNZ_OK;
334 | }
335 | QDir::Filters fltr = filter;
336 | if (fltr == QDir::NoFilter)
337 | fltr = this->filter;
338 | if (fltr == QDir::NoFilter)
339 | fltr = QDir::AllEntries;
340 | QStringList nmfltr = nameFilters;
341 | if (nmfltr.isEmpty())
342 | nmfltr = this->nameFilters;
343 | QSet dirsFound;
344 | QList list;
345 | do {
346 | QString name = zip->getCurrentFileName();
347 | if (!name.startsWith(basePath))
348 | continue;
349 | QString relativeName = name.mid(baseLength);
350 | if (relativeName.isEmpty())
351 | continue;
352 | bool isDir = false;
353 | bool isReal = true;
354 | if (relativeName.contains('/')) {
355 | int indexOfSlash = relativeName.indexOf('/');
356 | // something like "subdir/"
357 | isReal = indexOfSlash == relativeName.length() - 1;
358 | relativeName = relativeName.left(indexOfSlash + 1);
359 | if (dirsFound.contains(relativeName))
360 | continue;
361 | isDir = true;
362 | }
363 | dirsFound.insert(relativeName);
364 | if ((fltr & QDir::Dirs) == 0 && isDir)
365 | continue;
366 | if ((fltr & QDir::Files) == 0 && !isDir)
367 | continue;
368 | if (!nmfltr.isEmpty() && !QDir::match(nmfltr, relativeName))
369 | continue;
370 | bool ok;
371 | QuaZipFileInfo64 info = QuaZipDir_getFileInfo(zip, &ok, relativeName,
372 | isReal);
373 | if (!ok) {
374 | return false;
375 | }
376 | list.append(info);
377 | } while (zip->goToNextFile());
378 | QDir::SortFlags srt = sort;
379 | if (srt == QDir::NoSort)
380 | srt = sorting;
381 | #ifdef QUAZIP_QUAZIPDIR_DEBUG
382 | qDebug("QuaZipDirPrivate::entryInfoList(): before sort:");
383 | foreach (QuaZipFileInfo64 info, list) {
384 | qDebug("%s\t%s", info.name.toUtf8().constData(),
385 | info.dateTime.toString(Qt::ISODate).toUtf8().constData());
386 | }
387 | #endif
388 | if (srt != QDir::NoSort && (srt & QDir::Unsorted) != QDir::Unsorted) {
389 | if (QuaZip::convertCaseSensitivity(caseSensitivity)
390 | == Qt::CaseInsensitive)
391 | srt |= QDir::IgnoreCase;
392 | QuaZipDirComparator lessThan(srt);
393 | qSort(list.begin(), list.end(), lessThan);
394 | }
395 | QuaZipDir_convertInfoList(list, result);
396 | return true;
397 | }
398 |
399 | /// \endcond
400 |
401 | QList QuaZipDir::entryInfoList(const QStringList &nameFilters,
402 | QDir::Filters filters, QDir::SortFlags sort) const
403 | {
404 | QList result;
405 | if (d->entryInfoList(nameFilters, filters, sort, result))
406 | return result;
407 | else
408 | return QList();
409 | }
410 |
411 | QList QuaZipDir::entryInfoList(QDir::Filters filters,
412 | QDir::SortFlags sort) const
413 | {
414 | return entryInfoList(QStringList(), filters, sort);
415 | }
416 |
417 | QList QuaZipDir::entryInfoList64(const QStringList &nameFilters,
418 | QDir::Filters filters, QDir::SortFlags sort) const
419 | {
420 | QList result;
421 | if (d->entryInfoList(nameFilters, filters, sort, result))
422 | return result;
423 | else
424 | return QList();
425 | }
426 |
427 | QList QuaZipDir::entryInfoList64(QDir::Filters filters,
428 | QDir::SortFlags sort) const
429 | {
430 | return entryInfoList64(QStringList(), filters, sort);
431 | }
432 |
433 | QStringList QuaZipDir::entryList(const QStringList &nameFilters,
434 | QDir::Filters filters, QDir::SortFlags sort) const
435 | {
436 | QStringList result;
437 | if (d->entryInfoList(nameFilters, filters, sort, result))
438 | return result;
439 | else
440 | return QStringList();
441 | }
442 |
443 | QStringList QuaZipDir::entryList(QDir::Filters filters,
444 | QDir::SortFlags sort) const
445 | {
446 | return entryList(QStringList(), filters, sort);
447 | }
448 |
449 | bool QuaZipDir::exists(const QString &filePath) const
450 | {
451 | if (filePath == "/" || filePath.isEmpty())
452 | return true;
453 | QString fileName = filePath;
454 | if (fileName.endsWith('/'))
455 | fileName.chop(1);
456 | if (fileName.contains('/')) {
457 | QFileInfo fileInfo(fileName);
458 | #ifdef QUAZIP_QUAZIPDIR_DEBUG
459 | qDebug("QuaZipDir::exists(): fileName=%s, fileInfo.fileName()=%s, "
460 | "fileInfo.path()=%s", fileName.toUtf8().constData(),
461 | fileInfo.fileName().toUtf8().constData(),
462 | fileInfo.path().toUtf8().constData());
463 | #endif
464 | QuaZipDir dir(*this);
465 | return dir.cd(fileInfo.path()) && dir.exists(fileInfo.fileName());
466 | } else {
467 | if (fileName == "..") {
468 | return !isRoot();
469 | } else if (fileName == ".") {
470 | return true;
471 | } else {
472 | QStringList entries = entryList(QDir::AllEntries, QDir::NoSort);
473 | #ifdef QUAZIP_QUAZIPDIR_DEBUG
474 | qDebug("QuaZipDir::exists(): looking for %s",
475 | fileName.toUtf8().constData());
476 | for (QStringList::const_iterator i = entries.constBegin();
477 | i != entries.constEnd();
478 | ++i) {
479 | qDebug("QuaZipDir::exists(): entry: %s",
480 | i->toUtf8().constData());
481 | }
482 | #endif
483 | Qt::CaseSensitivity cs = QuaZip::convertCaseSensitivity(
484 | d->caseSensitivity);
485 | if (filePath.endsWith('/')) {
486 | return entries.contains(filePath, cs);
487 | } else {
488 | return entries.contains(fileName, cs)
489 | || entries.contains(fileName + "/", cs);
490 | }
491 | }
492 | }
493 | }
494 |
495 | bool QuaZipDir::exists() const
496 | {
497 | return QuaZipDir(d->zip).exists(d->dir);
498 | }
499 |
500 | QString QuaZipDir::filePath(const QString &fileName) const
501 | {
502 | return QDir(d->dir).filePath(fileName);
503 | }
504 |
505 | QDir::Filters QuaZipDir::filter()
506 | {
507 | return d->filter;
508 | }
509 |
510 | bool QuaZipDir::isRoot() const
511 | {
512 | return d->simplePath().isEmpty();
513 | }
514 |
515 | QStringList QuaZipDir::nameFilters() const
516 | {
517 | return d->nameFilters;
518 | }
519 |
520 | QString QuaZipDir::path() const
521 | {
522 | return d->dir;
523 | }
524 |
525 | QString QuaZipDir::relativeFilePath(const QString &fileName) const
526 | {
527 | return QDir("/" + d->dir).relativeFilePath(fileName);
528 | }
529 |
530 | void QuaZipDir::setCaseSensitivity(QuaZip::CaseSensitivity caseSensitivity)
531 | {
532 | d->caseSensitivity = caseSensitivity;
533 | }
534 |
535 | void QuaZipDir::setFilter(QDir::Filters filters)
536 | {
537 | d->filter = filters;
538 | }
539 |
540 | void QuaZipDir::setNameFilters(const QStringList &nameFilters)
541 | {
542 | d->nameFilters = nameFilters;
543 | }
544 |
545 | void QuaZipDir::setPath(const QString &path)
546 | {
547 | QString newDir = path;
548 | if (newDir == "/") {
549 | d->dir = "";
550 | } else {
551 | if (newDir.endsWith('/'))
552 | newDir.chop(1);
553 | if (newDir.startsWith('/'))
554 | newDir = newDir.mid(1);
555 | d->dir = newDir;
556 | }
557 | }
558 |
559 | void QuaZipDir::setSorting(QDir::SortFlags sort)
560 | {
561 | d->sorting = sort;
562 | }
563 |
564 | QDir::SortFlags QuaZipDir::sorting() const
565 | {
566 | return d->sorting;
567 | }
568 |
--------------------------------------------------------------------------------
/lib/quazipdir.h:
--------------------------------------------------------------------------------
1 | #ifndef QUAZIP_QUAZIPDIR_H
2 | #define QUAZIP_QUAZIPDIR_H
3 |
4 | /*
5 | Copyright (C) 2005-2014 Sergey A. Tachenov
6 |
7 | This file is part of QuaZIP.
8 |
9 | QuaZIP is free software: you can redistribute it and/or modify
10 | it under the terms of the GNU Lesser General Public License as published by
11 | the Free Software Foundation, either version 2.1 of the License, or
12 | (at your option) any later version.
13 |
14 | QuaZIP is distributed in the hope that it will be useful,
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | GNU Lesser General Public License for more details.
18 |
19 | You should have received a copy of the GNU Lesser General Public License
20 | along with QuaZIP. If not, see .
21 |
22 | See COPYING file for the full LGPL text.
23 |
24 | Original ZIP package is copyrighted by Gilles Vollant and contributors,
25 | see quazip/(un)zip.h files for details. Basically it's the zlib license.
26 | */
27 |
28 | class QuaZipDirPrivate;
29 |
30 | #include "quazip.h"
31 | #include "quazipfileinfo.h"
32 | #include
33 | #include
34 | #include
35 |
36 | /// Provides ZIP archive navigation.
37 | /**
38 | * This class is modelled after QDir, and is designed to provide similar
39 | * features for ZIP archives.
40 | *
41 | * The only significant difference from QDir is that the root path is not
42 | * '/', but an empty string since that's how the file paths are stored in
43 | * the archive. However, QuaZipDir understands the paths starting with
44 | * '/'. It is important in a few places:
45 | *
46 | * - In the cd() function.
47 | * - In the constructor.
48 | * - In the exists() function.
49 | * - In the relativePath() function.
50 | *
51 | * Note that since ZIP uses '/' on all platforms, the '\' separator is
52 | * not supported.
53 | */
54 | class QUAZIP_EXPORT QuaZipDir {
55 | private:
56 | QSharedDataPointer d;
57 | public:
58 | /// The copy constructor.
59 | QuaZipDir(const QuaZipDir &that);
60 | /// Constructs a QuaZipDir instance pointing to the specified directory.
61 | /**
62 | If \a dir is not specified, points to the root of the archive.
63 | The same happens if the \a dir is "/".
64 | */
65 | QuaZipDir(QuaZip *zip, const QString &dir = QString());
66 | /// Destructor.
67 | ~QuaZipDir();
68 | /// The assignment operator.
69 | bool operator==(const QuaZipDir &that);
70 | /// operator!=
71 | /**
72 | \return \c true if either this and \a that use different QuaZip
73 | instances or if they point to different directories.
74 | */
75 | inline bool operator!=(const QuaZipDir &that) {return !operator==(that);}
76 | /// operator==
77 | /**
78 | \return \c true if both this and \a that use the same QuaZip
79 | instance and point to the same directory.
80 | */
81 | QuaZipDir& operator=(const QuaZipDir &that);
82 | /// Returns the name of the entry at the specified position.
83 | QString operator[](int pos) const;
84 | /// Returns the current case sensitivity mode.
85 | QuaZip::CaseSensitivity caseSensitivity() const;
86 | /// Changes the 'current' directory.
87 | /**
88 | * If the path starts with '/', it is interpreted as an absolute
89 | * path from the root of the archive. Otherwise, it is interpreted
90 | * as a path relative to the current directory as was set by the
91 | * previous cd() or the constructor.
92 | *
93 | * Note that the subsequent path() call will not return a path
94 | * starting with '/' in all cases.
95 | */
96 | bool cd(const QString &dirName);
97 | /// Goes up.
98 | bool cdUp();
99 | /// Returns the number of entries in the directory.
100 | uint count() const;
101 | /// Returns the current directory name.
102 | /**
103 | The name doesn't include the path.
104 | */
105 | QString dirName() const;
106 | /// Returns the list of the entries in the directory.
107 | /**
108 | \param nameFilters The list of file patterns to list, uses the same
109 | syntax as QDir.
110 | \param filters The entry type filters, only Files and Dirs are
111 | accepted.
112 | \param sort Sorting mode.
113 | */
114 | QList entryInfoList(const QStringList &nameFilters,
115 | QDir::Filters filters = QDir::NoFilter,
116 | QDir::SortFlags sort = QDir::NoSort) const;
117 | /// Returns the list of the entries in the directory.
118 | /**
119 | \overload
120 |
121 | The same as entryInfoList(QStringList(), filters, sort).
122 | */
123 | QList entryInfoList(QDir::Filters filters = QDir::NoFilter,
124 | QDir::SortFlags sort = QDir::NoSort) const;
125 | /// Returns the list of the entries in the directory with zip64 support.
126 | /**
127 | \param nameFilters The list of file patterns to list, uses the same
128 | syntax as QDir.
129 | \param filters The entry type filters, only Files and Dirs are
130 | accepted.
131 | \param sort Sorting mode.
132 | */
133 | QList entryInfoList64(const QStringList &nameFilters,
134 | QDir::Filters filters = QDir::NoFilter,
135 | QDir::SortFlags sort = QDir::NoSort) const;
136 | /// Returns the list of the entries in the directory with zip64 support.
137 | /**
138 | \overload
139 |
140 | The same as entryInfoList64(QStringList(), filters, sort).
141 | */
142 | QList entryInfoList64(QDir::Filters filters = QDir::NoFilter,
143 | QDir::SortFlags sort = QDir::NoSort) const;
144 | /// Returns the list of the entry names in the directory.
145 | /**
146 | The same as entryInfoList(nameFilters, filters, sort), but only
147 | returns entry names.
148 | */
149 | QStringList entryList(const QStringList &nameFilters,
150 | QDir::Filters filters = QDir::NoFilter,
151 | QDir::SortFlags sort = QDir::NoSort) const;
152 | /// Returns the list of the entry names in the directory.
153 | /**
154 | \overload
155 |
156 | The same as entryList(QStringList(), filters, sort).
157 | */
158 | QStringList entryList(QDir::Filters filters = QDir::NoFilter,
159 | QDir::SortFlags sort = QDir::NoSort) const;
160 | /// Returns \c true if the entry with the specified name exists.
161 | /**
162 | The ".." is considered to exist if the current directory
163 | is not root. The "." and "/" are considered to
164 | always exist. Paths starting with "/" are relative to
165 | the archive root, other paths are relative to the current dir.
166 | */
167 | bool exists(const QString &fileName) const;
168 | /// Return \c true if the directory pointed by this QuaZipDir exists.
169 | bool exists() const;
170 | /// Returns the full path to the specified file.
171 | /**
172 | Doesn't check if the file actually exists.
173 | */
174 | QString filePath(const QString &fileName) const;
175 | /// Returns the default filter.
176 | QDir::Filters filter();
177 | /// Returns if the QuaZipDir points to the root of the archive.
178 | /**
179 | Not that the root path is the empty string, not '/'.
180 | */
181 | bool isRoot() const;
182 | /// Return the default name filter.
183 | QStringList nameFilters() const;
184 | /// Returns the path to the current dir.
185 | /**
186 | The path never starts with '/', and the root path is an empty
187 | string.
188 | */
189 | QString path() const;
190 | /// Returns the path to the specified file relative to the current dir.
191 | /**
192 | * This function is mostly useless, provided only for the sake of
193 | * completeness.
194 | *
195 | * @param fileName The path to the file, should start with "/"
196 | * if relative to the archive root.
197 | * @return Path relative to the current dir.
198 | */
199 | QString relativeFilePath(const QString &fileName) const;
200 | /// Sets the default case sensitivity mode.
201 | void setCaseSensitivity(QuaZip::CaseSensitivity caseSensitivity);
202 | /// Sets the default filter.
203 | void setFilter(QDir::Filters filters);
204 | /// Sets the default name filter.
205 | void setNameFilters(const QStringList &nameFilters);
206 | /// Goes to the specified path.
207 | /**
208 | The difference from cd() is that this function never checks if the
209 | path actually exists and doesn't use relative paths, so it's
210 | possible to go to the root directory with setPath("").
211 |
212 | Note that this function still chops the trailing and/or leading
213 | '/' and treats a single '/' as the root path (path() will still
214 | return an empty string).
215 | */
216 | void setPath(const QString &path);
217 | /// Sets the default sorting mode.
218 | void setSorting(QDir::SortFlags sort);
219 | /// Returns the default sorting mode.
220 | QDir::SortFlags sorting() const;
221 | };
222 |
223 | #endif // QUAZIP_QUAZIPDIR_H
224 |
--------------------------------------------------------------------------------
/lib/quazipfile.cpp:
--------------------------------------------------------------------------------
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 .
18 |
19 | See COPYING file for the full LGPL text.
20 |
21 | Original ZIP package is copyrighted by Gilles Vollant, see
22 | quazip/(un)zip.h files for details, basically it's zlib license.
23 | **/
24 |
25 | #include "quazipfile.h"
26 |
27 | using namespace std;
28 |
29 | /// The implementation class for QuaZip.
30 | /**
31 | \internal
32 |
33 | This class contains all the private stuff for the QuaZipFile class, thus
34 | allowing to preserve binary compatibility between releases, the
35 | technique known as the Pimpl (private implementation) idiom.
36 | */
37 | class QuaZipFilePrivate {
38 | friend class QuaZipFile;
39 | private:
40 | Q_DISABLE_COPY(QuaZipFilePrivate)
41 | /// The pointer to the associated QuaZipFile instance.
42 | QuaZipFile *q;
43 | /// The QuaZip object to work with.
44 | QuaZip *zip;
45 | /// The file name.
46 | QString fileName;
47 | /// Case sensitivity mode.
48 | QuaZip::CaseSensitivity caseSensitivity;
49 | /// Whether this file is opened in the raw mode.
50 | bool raw;
51 | /// Write position to keep track of.
52 | /**
53 | QIODevice::pos() is broken for non-seekable devices, so we need
54 | our own position.
55 | */
56 | qint64 writePos;
57 | /// Uncompressed size to write along with a raw file.
58 | quint64 uncompressedSize;
59 | /// CRC to write along with a raw file.
60 | quint32 crc;
61 | /// Whether \ref zip points to an internal QuaZip instance.
62 | /**
63 | This is true if the archive was opened by name, rather than by
64 | supplying an existing QuaZip instance.
65 | */
66 | bool internal;
67 | /// The last error.
68 | int zipError;
69 | /// Resets \ref zipError.
70 | inline void resetZipError() const {setZipError(UNZ_OK);}
71 | /// Sets the zip error.
72 | /**
73 | This function is marked as const although it changes one field.
74 | This allows to call it from const functions that don't change
75 | anything by themselves.
76 | */
77 | void setZipError(int zipError) const;
78 | /// The constructor for the corresponding QuaZipFile constructor.
79 | inline QuaZipFilePrivate(QuaZipFile *q):
80 | q(q),
81 | zip(NULL),
82 | caseSensitivity(QuaZip::csDefault),
83 | raw(false),
84 | writePos(0),
85 | uncompressedSize(0),
86 | crc(0),
87 | internal(true),
88 | zipError(UNZ_OK) {}
89 | /// The constructor for the corresponding QuaZipFile constructor.
90 | inline QuaZipFilePrivate(QuaZipFile *q, const QString &zipName):
91 | q(q),
92 | caseSensitivity(QuaZip::csDefault),
93 | raw(false),
94 | writePos(0),
95 | uncompressedSize(0),
96 | crc(0),
97 | internal(true),
98 | zipError(UNZ_OK)
99 | {
100 | zip=new QuaZip(zipName);
101 | }
102 | /// The constructor for the corresponding QuaZipFile constructor.
103 | inline QuaZipFilePrivate(QuaZipFile *q, const QString &zipName, const QString &fileName,
104 | QuaZip::CaseSensitivity cs):
105 | q(q),
106 | raw(false),
107 | writePos(0),
108 | uncompressedSize(0),
109 | crc(0),
110 | internal(true),
111 | zipError(UNZ_OK)
112 | {
113 | zip=new QuaZip(zipName);
114 | this->fileName=fileName;
115 | if (this->fileName.startsWith('/'))
116 | this->fileName = this->fileName.mid(1);
117 | this->caseSensitivity=cs;
118 | }
119 | /// The constructor for the QuaZipFile constructor accepting a file name.
120 | inline QuaZipFilePrivate(QuaZipFile *q, QuaZip *zip):
121 | q(q),
122 | zip(zip),
123 | raw(false),
124 | writePos(0),
125 | uncompressedSize(0),
126 | crc(0),
127 | internal(false),
128 | zipError(UNZ_OK) {}
129 | /// The destructor.
130 | inline ~QuaZipFilePrivate()
131 | {
132 | if (internal)
133 | delete zip;
134 | }
135 | };
136 |
137 | QuaZipFile::QuaZipFile():
138 | p(new QuaZipFilePrivate(this))
139 | {
140 | }
141 |
142 | QuaZipFile::QuaZipFile(QObject *parent):
143 | QIODevice(parent),
144 | p(new QuaZipFilePrivate(this))
145 | {
146 | }
147 |
148 | QuaZipFile::QuaZipFile(const QString& zipName, QObject *parent):
149 | QIODevice(parent),
150 | p(new QuaZipFilePrivate(this, zipName))
151 | {
152 | }
153 |
154 | QuaZipFile::QuaZipFile(const QString& zipName, const QString& fileName,
155 | QuaZip::CaseSensitivity cs, QObject *parent):
156 | QIODevice(parent),
157 | p(new QuaZipFilePrivate(this, zipName, fileName, cs))
158 | {
159 | }
160 |
161 | QuaZipFile::QuaZipFile(QuaZip *zip, QObject *parent):
162 | QIODevice(parent),
163 | p(new QuaZipFilePrivate(this, zip))
164 | {
165 | }
166 |
167 | QuaZipFile::~QuaZipFile()
168 | {
169 | if (isOpen())
170 | close();
171 | delete p;
172 | }
173 |
174 | QString QuaZipFile::getZipName() const
175 | {
176 | return p->zip==NULL ? QString() : p->zip->getZipName();
177 | }
178 |
179 | QuaZip *QuaZipFile::getZip() const
180 | {
181 | return p->internal ? NULL : p->zip;
182 | }
183 |
184 | QString QuaZipFile::getActualFileName()const
185 | {
186 | p->setZipError(UNZ_OK);
187 | if (p->zip == NULL || (openMode() & WriteOnly))
188 | return QString();
189 | QString name=p->zip->getCurrentFileName();
190 | if(name.isNull())
191 | p->setZipError(p->zip->getZipError());
192 | return name;
193 | }
194 |
195 | void QuaZipFile::setZipName(const QString& zipName)
196 | {
197 | if(isOpen()) {
198 | qWarning("QuaZipFile::setZipName(): file is already open - can not set ZIP name");
199 | return;
200 | }
201 | if(p->zip!=NULL && p->internal)
202 | delete p->zip;
203 | p->zip=new QuaZip(zipName);
204 | p->internal=true;
205 | }
206 |
207 | void QuaZipFile::setZip(QuaZip *zip)
208 | {
209 | if(isOpen()) {
210 | qWarning("QuaZipFile::setZip(): file is already open - can not set ZIP");
211 | return;
212 | }
213 | if(p->zip!=NULL && p->internal)
214 | delete p->zip;
215 | p->zip=zip;
216 | p->fileName=QString();
217 | p->internal=false;
218 | }
219 |
220 | void QuaZipFile::setFileName(const QString& fileName, QuaZip::CaseSensitivity cs)
221 | {
222 | if(p->zip==NULL) {
223 | qWarning("QuaZipFile::setFileName(): call setZipName() first");
224 | return;
225 | }
226 | if(!p->internal) {
227 | qWarning("QuaZipFile::setFileName(): should not be used when not using internal QuaZip");
228 | return;
229 | }
230 | if(isOpen()) {
231 | qWarning("QuaZipFile::setFileName(): can not set file name for already opened file");
232 | return;
233 | }
234 | p->fileName=fileName;
235 | if (p->fileName.startsWith('/'))
236 | p->fileName = p->fileName.mid(1);
237 | p->caseSensitivity=cs;
238 | }
239 |
240 | void QuaZipFilePrivate::setZipError(int zipError) const
241 | {
242 | QuaZipFilePrivate *fakeThis = const_cast(this); // non-const
243 | fakeThis->zipError=zipError;
244 | if(zipError==UNZ_OK)
245 | q->setErrorString(QString());
246 | else
247 | q->setErrorString(QuaZipFile::tr("ZIP/UNZIP API error %1").arg(zipError));
248 | }
249 |
250 | bool QuaZipFile::open(OpenMode mode)
251 | {
252 | return open(mode, NULL);
253 | }
254 |
255 | bool QuaZipFile::open(OpenMode mode, int *method, int *level, bool raw, const char *password)
256 | {
257 | p->resetZipError();
258 | if(isOpen()) {
259 | qWarning("QuaZipFile::open(): already opened");
260 | return false;
261 | }
262 | if(mode&Unbuffered) {
263 | qWarning("QuaZipFile::open(): Unbuffered mode is not supported");
264 | return false;
265 | }
266 | if((mode&ReadOnly)&&!(mode&WriteOnly)) {
267 | if(p->internal) {
268 | if(!p->zip->open(QuaZip::mdUnzip)) {
269 | p->setZipError(p->zip->getZipError());
270 | return false;
271 | }
272 | if(!p->zip->setCurrentFile(p->fileName, p->caseSensitivity)) {
273 | p->setZipError(p->zip->getZipError());
274 | p->zip->close();
275 | return false;
276 | }
277 | } else {
278 | if(p->zip==NULL) {
279 | qWarning("QuaZipFile::open(): zip is NULL");
280 | return false;
281 | }
282 | if(p->zip->getMode()!=QuaZip::mdUnzip) {
283 | qWarning("QuaZipFile::open(): file open mode %d incompatible with ZIP open mode %d",
284 | (int)mode, (int)p->zip->getMode());
285 | return false;
286 | }
287 | if(!p->zip->hasCurrentFile()) {
288 | qWarning("QuaZipFile::open(): zip does not have current file");
289 | return false;
290 | }
291 | }
292 | p->setZipError(unzOpenCurrentFile3(p->zip->getUnzFile(), method, level, (int)raw, password));
293 | if(p->zipError==UNZ_OK) {
294 | setOpenMode(mode);
295 | p->raw=raw;
296 | return true;
297 | } else
298 | return false;
299 | }
300 | qWarning("QuaZipFile::open(): open mode %d not supported by this function", (int)mode);
301 | return false;
302 | }
303 |
304 | bool QuaZipFile::open(OpenMode mode, const QuaZipNewInfo& info,
305 | const char *password, quint32 crc,
306 | int method, int level, bool raw,
307 | int windowBits, int memLevel, int strategy)
308 | {
309 | zip_fileinfo info_z;
310 | p->resetZipError();
311 | if(isOpen()) {
312 | qWarning("QuaZipFile::open(): already opened");
313 | return false;
314 | }
315 | if((mode&WriteOnly)&&!(mode&ReadOnly)) {
316 | if(p->internal) {
317 | qWarning("QuaZipFile::open(): write mode is incompatible with internal QuaZip approach");
318 | return false;
319 | }
320 | if(p->zip==NULL) {
321 | qWarning("QuaZipFile::open(): zip is NULL");
322 | return false;
323 | }
324 | if(p->zip->getMode()!=QuaZip::mdCreate&&p->zip->getMode()!=QuaZip::mdAppend&&p->zip->getMode()!=QuaZip::mdAdd) {
325 | qWarning("QuaZipFile::open(): file open mode %d incompatible with ZIP open mode %d",
326 | (int)mode, (int)p->zip->getMode());
327 | return false;
328 | }
329 | info_z.tmz_date.tm_year=info.dateTime.date().year();
330 | info_z.tmz_date.tm_mon=info.dateTime.date().month() - 1;
331 | info_z.tmz_date.tm_mday=info.dateTime.date().day();
332 | info_z.tmz_date.tm_hour=info.dateTime.time().hour();
333 | info_z.tmz_date.tm_min=info.dateTime.time().minute();
334 | info_z.tmz_date.tm_sec=info.dateTime.time().second();
335 | info_z.dosDate = 0;
336 | info_z.internal_fa=(uLong)info.internalAttr;
337 | info_z.external_fa=(uLong)info.externalAttr;
338 | if (p->zip->isDataDescriptorWritingEnabled())
339 | zipSetFlags(p->zip->getZipFile(), ZIP_WRITE_DATA_DESCRIPTOR);
340 | else
341 | zipClearFlags(p->zip->getZipFile(), ZIP_WRITE_DATA_DESCRIPTOR);
342 | p->setZipError(zipOpenNewFileInZip3_64(p->zip->getZipFile(),
343 | p->zip->getFileNameCodec()->fromUnicode(info.name).constData(), &info_z,
344 | info.extraLocal.constData(), info.extraLocal.length(),
345 | info.extraGlobal.constData(), info.extraGlobal.length(),
346 | p->zip->getCommentCodec()->fromUnicode(info.comment).constData(),
347 | method, level, (int)raw,
348 | windowBits, memLevel, strategy,
349 | password, (uLong)crc, p->zip->isZip64Enabled()));
350 | if(p->zipError==UNZ_OK) {
351 | p->writePos=0;
352 | setOpenMode(mode);
353 | p->raw=raw;
354 | if(raw) {
355 | p->crc=crc;
356 | p->uncompressedSize=info.uncompressedSize;
357 | }
358 | return true;
359 | } else
360 | return false;
361 | }
362 | qWarning("QuaZipFile::open(): open mode %d not supported by this function", (int)mode);
363 | return false;
364 | }
365 |
366 | bool QuaZipFile::isSequential()const
367 | {
368 | return true;
369 | }
370 |
371 | qint64 QuaZipFile::pos()const
372 | {
373 | if(p->zip==NULL) {
374 | qWarning("QuaZipFile::pos(): call setZipName() or setZip() first");
375 | return -1;
376 | }
377 | if(!isOpen()) {
378 | qWarning("QuaZipFile::pos(): file is not open");
379 | return -1;
380 | }
381 | if(openMode()&ReadOnly)
382 | // QIODevice::pos() is broken for sequential devices,
383 | // but thankfully bytesAvailable() returns the number of
384 | // bytes buffered, so we know how far ahead we are.
385 | return unztell64(p->zip->getUnzFile()) - QIODevice::bytesAvailable();
386 | else
387 | return p->writePos;
388 | }
389 |
390 | bool QuaZipFile::atEnd()const
391 | {
392 | if(p->zip==NULL) {
393 | qWarning("QuaZipFile::atEnd(): call setZipName() or setZip() first");
394 | return false;
395 | }
396 | if(!isOpen()) {
397 | qWarning("QuaZipFile::atEnd(): file is not open");
398 | return false;
399 | }
400 | if(openMode()&ReadOnly)
401 | // the same problem as with pos()
402 | return QIODevice::bytesAvailable() == 0
403 | && unzeof(p->zip->getUnzFile())==1;
404 | else
405 | return true;
406 | }
407 |
408 | qint64 QuaZipFile::size()const
409 | {
410 | if(!isOpen()) {
411 | qWarning("QuaZipFile::atEnd(): file is not open");
412 | return -1;
413 | }
414 | if(openMode()&ReadOnly)
415 | return p->raw?csize():usize();
416 | else
417 | return p->writePos;
418 | }
419 |
420 | qint64 QuaZipFile::csize()const
421 | {
422 | unz_file_info64 info_z;
423 | p->setZipError(UNZ_OK);
424 | if(p->zip==NULL||p->zip->getMode()!=QuaZip::mdUnzip) return -1;
425 | p->setZipError(unzGetCurrentFileInfo64(p->zip->getUnzFile(), &info_z, NULL, 0, NULL, 0, NULL, 0));
426 | if(p->zipError!=UNZ_OK)
427 | return -1;
428 | return info_z.compressed_size;
429 | }
430 |
431 | qint64 QuaZipFile::usize()const
432 | {
433 | unz_file_info64 info_z;
434 | p->setZipError(UNZ_OK);
435 | if(p->zip==NULL||p->zip->getMode()!=QuaZip::mdUnzip) return -1;
436 | p->setZipError(unzGetCurrentFileInfo64(p->zip->getUnzFile(), &info_z, NULL, 0, NULL, 0, NULL, 0));
437 | if(p->zipError!=UNZ_OK)
438 | return -1;
439 | return info_z.uncompressed_size;
440 | }
441 |
442 | bool QuaZipFile::getFileInfo(QuaZipFileInfo *info)
443 | {
444 | QuaZipFileInfo64 info64;
445 | if (getFileInfo(&info64)) {
446 | info64.toQuaZipFileInfo(*info);
447 | return true;
448 | } else {
449 | return false;
450 | }
451 | }
452 |
453 | bool QuaZipFile::getFileInfo(QuaZipFileInfo64 *info)
454 | {
455 | if(p->zip==NULL||p->zip->getMode()!=QuaZip::mdUnzip) return false;
456 | p->zip->getCurrentFileInfo(info);
457 | p->setZipError(p->zip->getZipError());
458 | return p->zipError==UNZ_OK;
459 | }
460 |
461 | void QuaZipFile::close()
462 | {
463 | p->resetZipError();
464 | if(p->zip==NULL||!p->zip->isOpen()) return;
465 | if(!isOpen()) {
466 | qWarning("QuaZipFile::close(): file isn't open");
467 | return;
468 | }
469 | if(openMode()&ReadOnly)
470 | p->setZipError(unzCloseCurrentFile(p->zip->getUnzFile()));
471 | else if(openMode()&WriteOnly)
472 | if(isRaw()) p->setZipError(zipCloseFileInZipRaw64(p->zip->getZipFile(), p->uncompressedSize, p->crc));
473 | else p->setZipError(zipCloseFileInZip(p->zip->getZipFile()));
474 | else {
475 | qWarning("Wrong open mode: %d", (int)openMode());
476 | return;
477 | }
478 | if(p->zipError==UNZ_OK) setOpenMode(QIODevice::NotOpen);
479 | else return;
480 | if(p->internal) {
481 | p->zip->close();
482 | p->setZipError(p->zip->getZipError());
483 | }
484 | }
485 |
486 | qint64 QuaZipFile::readData(char *data, qint64 maxSize)
487 | {
488 | p->setZipError(UNZ_OK);
489 | qint64 bytesRead=unzReadCurrentFile(p->zip->getUnzFile(), data, (unsigned)maxSize);
490 | if (bytesRead < 0) {
491 | p->setZipError((int) bytesRead);
492 | return -1;
493 | }
494 | return bytesRead;
495 | }
496 |
497 | qint64 QuaZipFile::writeData(const char* data, qint64 maxSize)
498 | {
499 | p->setZipError(ZIP_OK);
500 | p->setZipError(zipWriteInFileInZip(p->zip->getZipFile(), data, (uint)maxSize));
501 | if(p->zipError!=ZIP_OK) return -1;
502 | else {
503 | p->writePos+=maxSize;
504 | return maxSize;
505 | }
506 | }
507 |
508 | QString QuaZipFile::getFileName() const
509 | {
510 | return p->fileName;
511 | }
512 |
513 | QuaZip::CaseSensitivity QuaZipFile::getCaseSensitivity() const
514 | {
515 | return p->caseSensitivity;
516 | }
517 |
518 | bool QuaZipFile::isRaw() const
519 | {
520 | return p->raw;
521 | }
522 |
523 | int QuaZipFile::getZipError() const
524 | {
525 | return p->zipError;
526 | }
527 |
528 | qint64 QuaZipFile::bytesAvailable() const
529 | {
530 | return size() - pos();
531 | }
532 |
--------------------------------------------------------------------------------
/lib/quazipfileinfo.cpp:
--------------------------------------------------------------------------------
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 .
18 |
19 | See COPYING file for the full LGPL text.
20 |
21 | Original ZIP package is copyrighted by Gilles Vollant and contributors,
22 | see quazip/(un)zip.h files for details. Basically it's the zlib license.
23 | */
24 |
25 | #include "quazipfileinfo.h"
26 |
27 | static QFile::Permissions permissionsFromExternalAttr(quint32 externalAttr) {
28 | quint32 uPerm = (externalAttr & 0xFFFF0000u) >> 16;
29 | QFile::Permissions perm = 0;
30 | if ((uPerm & 0400) != 0)
31 | perm |= QFile::ReadOwner;
32 | if ((uPerm & 0200) != 0)
33 | perm |= QFile::WriteOwner;
34 | if ((uPerm & 0100) != 0)
35 | perm |= QFile::ExeOwner;
36 | if ((uPerm & 0040) != 0)
37 | perm |= QFile::ReadGroup;
38 | if ((uPerm & 0020) != 0)
39 | perm |= QFile::WriteGroup;
40 | if ((uPerm & 0010) != 0)
41 | perm |= QFile::ExeGroup;
42 | if ((uPerm & 0004) != 0)
43 | perm |= QFile::ReadOther;
44 | if ((uPerm & 0002) != 0)
45 | perm |= QFile::WriteOther;
46 | if ((uPerm & 0001) != 0)
47 | perm |= QFile::ExeOther;
48 | return perm;
49 |
50 | }
51 |
52 | QFile::Permissions QuaZipFileInfo::getPermissions() const
53 | {
54 | return permissionsFromExternalAttr(externalAttr);
55 | }
56 |
57 | QFile::Permissions QuaZipFileInfo64::getPermissions() const
58 | {
59 | return permissionsFromExternalAttr(externalAttr);
60 | }
61 |
62 | bool QuaZipFileInfo64::toQuaZipFileInfo(QuaZipFileInfo &info) const
63 | {
64 | bool noOverflow = true;
65 | info.name = name;
66 | info.versionCreated = versionCreated;
67 | info.versionNeeded = versionNeeded;
68 | info.flags = flags;
69 | info.method = method;
70 | info.dateTime = dateTime;
71 | info.crc = crc;
72 | if (compressedSize > 0xFFFFFFFFu) {
73 | info.compressedSize = 0xFFFFFFFFu;
74 | noOverflow = false;
75 | } else {
76 | info.compressedSize = compressedSize;
77 | }
78 | if (uncompressedSize > 0xFFFFFFFFu) {
79 | info.uncompressedSize = 0xFFFFFFFFu;
80 | noOverflow = false;
81 | } else {
82 | info.uncompressedSize = uncompressedSize;
83 | }
84 | info.diskNumberStart = diskNumberStart;
85 | info.internalAttr = internalAttr;
86 | info.externalAttr = externalAttr;
87 | info.comment = comment;
88 | info.extra = extra;
89 | return noOverflow;
90 | }
91 |
92 | static QDateTime getNTFSTime(const QByteArray &extra, int position,
93 | int *fineTicks)
94 | {
95 | QDateTime dateTime;
96 | for (int i = 0; i <= extra.size() - 4; ) {
97 | unsigned type = static_cast(static_cast(
98 | extra.at(i)))
99 | | (static_cast(static_cast(
100 | extra.at(i + 1))) << 8);
101 | i += 2;
102 | unsigned length = static_cast(static_cast(
103 | extra.at(i)))
104 | | (static_cast(static_cast(
105 | extra.at(i + 1))) << 8);
106 | i += 2;
107 | if (type == QUAZIP_EXTRA_NTFS_MAGIC && length >= 32) {
108 | i += 4; // reserved
109 | while (i <= extra.size() - 4) {
110 | unsigned tag = static_cast(
111 | static_cast(extra.at(i)))
112 | | (static_cast(
113 | static_cast(extra.at(i + 1)))
114 | << 8);
115 | i += 2;
116 | int tagsize = static_cast(
117 | static_cast(extra.at(i)))
118 | | (static_cast(
119 | static_cast(extra.at(i + 1)))
120 | << 8);
121 | i += 2;
122 | if (tag == QUAZIP_EXTRA_NTFS_TIME_MAGIC
123 | && tagsize >= position + 8) {
124 | i += position;
125 | quint64 mtime = static_cast(
126 | static_cast(extra.at(i)))
127 | | (static_cast(static_cast(
128 | extra.at(i + 1))) << 8)
129 | | (static_cast(static_cast(
130 | extra.at(i + 2))) << 16)
131 | | (static_cast(static_cast(
132 | extra.at(i + 3))) << 24)
133 | | (static_cast(static_cast(
134 | extra.at(i + 4))) << 32)
135 | | (static_cast(static_cast(
136 | extra.at(i + 5))) << 40)
137 | | (static_cast(static_cast(
138 | extra.at(i + 6))) << 48)
139 | | (static_cast(static_cast(
140 | extra.at(i + 7))) << 56);
141 | // the NTFS time is measured from 1601 for whatever reason
142 | QDateTime base(QDate(1601, 1, 1), QTime(0, 0), Qt::UTC);
143 | dateTime = base.addMSecs(mtime / 10000);
144 | if (fineTicks != NULL) {
145 | *fineTicks = static_cast(mtime % 10000);
146 | }
147 | i += tagsize - position;
148 | } else {
149 | i += tagsize;
150 | }
151 |
152 | }
153 | } else {
154 | i += length;
155 | }
156 | }
157 | if (fineTicks != NULL && dateTime.isNull()) {
158 | *fineTicks = 0;
159 | }
160 | return dateTime;
161 | }
162 |
163 | QDateTime QuaZipFileInfo64::getNTFSmTime(int *fineTicks) const
164 | {
165 | return getNTFSTime(extra, 0, fineTicks);
166 | }
167 |
168 | QDateTime QuaZipFileInfo64::getNTFSaTime(int *fineTicks) const
169 | {
170 | return getNTFSTime(extra, 8, fineTicks);
171 | }
172 |
173 | QDateTime QuaZipFileInfo64::getNTFScTime(int *fineTicks) const
174 | {
175 | return getNTFSTime(extra, 16, fineTicks);
176 | }
177 |
--------------------------------------------------------------------------------
/lib/quazipfileinfo.h:
--------------------------------------------------------------------------------
1 | #ifndef QUA_ZIPFILEINFO_H
2 | #define QUA_ZIPFILEINFO_H
3 |
4 | /*
5 | Copyright (C) 2005-2014 Sergey A. Tachenov
6 |
7 | This file is part of QuaZIP.
8 |
9 | QuaZIP is free software: you can redistribute it and/or modify
10 | it under the terms of the GNU Lesser General Public License as published by
11 | the Free Software Foundation, either version 2.1 of the License, or
12 | (at your option) any later version.
13 |
14 | QuaZIP is distributed in the hope that it will be useful,
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | GNU Lesser General Public License for more details.
18 |
19 | You should have received a copy of the GNU Lesser General Public License
20 | along with QuaZIP. If not, see .
21 |
22 | See COPYING file for the full LGPL text.
23 |
24 | Original ZIP package is copyrighted by Gilles Vollant and contributors,
25 | see quazip/(un)zip.h files for details. Basically it's the zlib license.
26 | */
27 |
28 | #include
29 | #include
30 | #include
31 |
32 | #include "quazip_global.h"
33 |
34 | /// Information about a file inside archive.
35 | /**
36 | * \deprecated Use QuaZipFileInfo64 instead. Not only it supports large files,
37 | * but also more convenience methods as well.
38 | *
39 | * Call QuaZip::getCurrentFileInfo() or QuaZipFile::getFileInfo() to
40 | * fill this structure. */
41 | struct QUAZIP_EXPORT QuaZipFileInfo {
42 | /// File name.
43 | QString name;
44 | /// Version created by.
45 | quint16 versionCreated;
46 | /// Version needed to extract.
47 | quint16 versionNeeded;
48 | /// General purpose flags.
49 | quint16 flags;
50 | /// Compression method.
51 | quint16 method;
52 | /// Last modification date and time.
53 | QDateTime dateTime;
54 | /// CRC.
55 | quint32 crc;
56 | /// Compressed file size.
57 | quint32 compressedSize;
58 | /// Uncompressed file size.
59 | quint32 uncompressedSize;
60 | /// Disk number start.
61 | quint16 diskNumberStart;
62 | /// Internal file attributes.
63 | quint16 internalAttr;
64 | /// External file attributes.
65 | quint32 externalAttr;
66 | /// Comment.
67 | QString comment;
68 | /// Extra field.
69 | QByteArray extra;
70 | /// Get the file permissions.
71 | /**
72 | Returns the high 16 bits of external attributes converted to
73 | QFile::Permissions.
74 | */
75 | QFile::Permissions getPermissions() const;
76 | };
77 |
78 | /// Information about a file inside archive (with zip64 support).
79 | /** Call QuaZip::getCurrentFileInfo() or QuaZipFile::getFileInfo() to
80 | * fill this structure. */
81 | struct QUAZIP_EXPORT QuaZipFileInfo64 {
82 | /// File name.
83 | QString name;
84 | /// Version created by.
85 | quint16 versionCreated;
86 | /// Version needed to extract.
87 | quint16 versionNeeded;
88 | /// General purpose flags.
89 | quint16 flags;
90 | /// Compression method.
91 | quint16 method;
92 | /// Last modification date and time.
93 | /**
94 | * This is the time stored in the standard ZIP header. This format only allows
95 | * to store time with 2-second precision, so the seconds will always be even
96 | * and the milliseconds will always be zero. If you need more precise
97 | * date and time, you can try to call the getNTFSmTime() function or
98 | * its siblings, provided that the archive itself contains these NTFS times.
99 | */
100 | QDateTime dateTime;
101 | /// CRC.
102 | quint32 crc;
103 | /// Compressed file size.
104 | quint64 compressedSize;
105 | /// Uncompressed file size.
106 | quint64 uncompressedSize;
107 | /// Disk number start.
108 | quint16 diskNumberStart;
109 | /// Internal file attributes.
110 | quint16 internalAttr;
111 | /// External file attributes.
112 | quint32 externalAttr;
113 | /// Comment.
114 | QString comment;
115 | /// Extra field.
116 | QByteArray extra;
117 | /// Get the file permissions.
118 | /**
119 | Returns the high 16 bits of external attributes converted to
120 | QFile::Permissions.
121 | */
122 | QFile::Permissions getPermissions() const;
123 | /// Converts to QuaZipFileInfo
124 | /**
125 | If any of the fields are greater than 0xFFFFFFFFu, they are set to
126 | 0xFFFFFFFFu exactly, not just truncated. This function should be mainly used
127 | for compatibility with the old code expecting QuaZipFileInfo, in the cases
128 | when it's impossible or otherwise unadvisable (due to ABI compatibility
129 | reasons, for example) to modify that old code to use QuaZipFileInfo64.
130 |
131 | \return \c true if all fields converted correctly, \c false if an overflow
132 | occured.
133 | */
134 | bool toQuaZipFileInfo(QuaZipFileInfo &info) const;
135 | /// Returns the NTFS modification time
136 | /**
137 | * The getNTFS*Time() functions only work if there is an NTFS extra field
138 | * present. Otherwise, they all return invalid null timestamps.
139 | * @param fineTicks If not NULL, the fractional part of milliseconds returned
140 | * there, measured in 100-nanosecond ticks. Will be set to
141 | * zero if there is no NTFS extra field.
142 | * @sa dateTime
143 | * @sa getNTFSaTime()
144 | * @sa getNTFScTime()
145 | * @return The NTFS modification time, UTC
146 | */
147 | QDateTime getNTFSmTime(int *fineTicks = NULL) const;
148 | /// Returns the NTFS access time
149 | /**
150 | * The getNTFS*Time() functions only work if there is an NTFS extra field
151 | * present. Otherwise, they all return invalid null timestamps.
152 | * @param fineTicks If not NULL, the fractional part of milliseconds returned
153 | * there, measured in 100-nanosecond ticks. Will be set to
154 | * zero if there is no NTFS extra field.
155 | * @sa dateTime
156 | * @sa getNTFSmTime()
157 | * @sa getNTFScTime()
158 | * @return The NTFS access time, UTC
159 | */
160 | QDateTime getNTFSaTime(int *fineTicks = NULL) const;
161 | /// Returns the NTFS creation time
162 | /**
163 | * The getNTFS*Time() functions only work if there is an NTFS extra field
164 | * present. Otherwise, they all return invalid null timestamps.
165 | * @param fineTicks If not NULL, the fractional part of milliseconds returned
166 | * there, measured in 100-nanosecond ticks. Will be set to
167 | * zero if there is no NTFS extra field.
168 | * @sa dateTime
169 | * @sa getNTFSmTime()
170 | * @sa getNTFSaTime()
171 | * @return The NTFS creation time, UTC
172 | */
173 | QDateTime getNTFScTime(int *fineTicks = NULL) const;
174 | /// Checks whether the file is encrypted.
175 | bool isEncrypted() const {return (flags & 1) != 0;}
176 | };
177 |
178 | #endif
179 |
--------------------------------------------------------------------------------
/lib/quazipnewinfo.cpp:
--------------------------------------------------------------------------------
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 .
18 |
19 | See COPYING file for the full LGPL text.
20 |
21 | Original ZIP package is copyrighted by Gilles Vollant and contributors,
22 | see quazip/(un)zip.h files for details. Basically it's the zlib license.
23 | */
24 |
25 | #include
26 |
27 | #include "quazipnewinfo.h"
28 |
29 | #include
30 |
31 | static void QuaZipNewInfo_setPermissions(QuaZipNewInfo *info,
32 | QFile::Permissions perm, bool isDir, bool isSymLink = false)
33 | {
34 | quint32 uPerm = isDir ? 0040000 : 0100000;
35 |
36 | if ( isSymLink ) {
37 | #ifdef Q_OS_WIN
38 | uPerm = 0200000;
39 | #else
40 | uPerm = 0120000;
41 | #endif
42 | }
43 |
44 | if ((perm & QFile::ReadOwner) != 0)
45 | uPerm |= 0400;
46 | if ((perm & QFile::WriteOwner) != 0)
47 | uPerm |= 0200;
48 | if ((perm & QFile::ExeOwner) != 0)
49 | uPerm |= 0100;
50 | if ((perm & QFile::ReadGroup) != 0)
51 | uPerm |= 0040;
52 | if ((perm & QFile::WriteGroup) != 0)
53 | uPerm |= 0020;
54 | if ((perm & QFile::ExeGroup) != 0)
55 | uPerm |= 0010;
56 | if ((perm & QFile::ReadOther) != 0)
57 | uPerm |= 0004;
58 | if ((perm & QFile::WriteOther) != 0)
59 | uPerm |= 0002;
60 | if ((perm & QFile::ExeOther) != 0)
61 | uPerm |= 0001;
62 | info->externalAttr = (info->externalAttr & ~0xFFFF0000u) | (uPerm << 16);
63 | }
64 |
65 | template
66 | void QuaZipNewInfo_init(QuaZipNewInfo &self, const FileInfo &existing)
67 | {
68 | self.name = existing.name;
69 | self.dateTime = existing.dateTime;
70 | self.internalAttr = existing.internalAttr;
71 | self.externalAttr = existing.externalAttr;
72 | self.comment = existing.comment;
73 | self.extraLocal = existing.extra;
74 | self.extraGlobal = existing.extra;
75 | self.uncompressedSize = existing.uncompressedSize;
76 | }
77 |
78 | QuaZipNewInfo::QuaZipNewInfo(const QuaZipFileInfo &existing)
79 | {
80 | QuaZipNewInfo_init(*this, existing);
81 | }
82 |
83 | QuaZipNewInfo::QuaZipNewInfo(const QuaZipFileInfo64 &existing)
84 | {
85 | QuaZipNewInfo_init(*this, existing);
86 | }
87 |
88 | QuaZipNewInfo::QuaZipNewInfo(const QString& name):
89 | name(name), dateTime(QDateTime::currentDateTime()), internalAttr(0), externalAttr(0),
90 | uncompressedSize(0)
91 | {
92 | }
93 |
94 | QuaZipNewInfo::QuaZipNewInfo(const QString& name, const QString& file):
95 | name(name), internalAttr(0), externalAttr(0), uncompressedSize(0)
96 | {
97 | QFileInfo info(file);
98 | QDateTime lm = info.lastModified();
99 | if (!info.exists()) {
100 | dateTime = QDateTime::currentDateTime();
101 | } else {
102 | dateTime = lm;
103 | QuaZipNewInfo_setPermissions(this, info.permissions(), info.isDir(), info.isSymLink());
104 | }
105 | }
106 |
107 | void QuaZipNewInfo::setFileDateTime(const QString& file)
108 | {
109 | QFileInfo info(file);
110 | QDateTime lm = info.lastModified();
111 | if (info.exists())
112 | dateTime = lm;
113 | }
114 |
115 | void QuaZipNewInfo::setFilePermissions(const QString &file)
116 | {
117 | QFileInfo info = QFileInfo(file);
118 | QFile::Permissions perm = info.permissions();
119 | QuaZipNewInfo_setPermissions(this, perm, info.isDir(), info.isSymLink());
120 | }
121 |
122 | void QuaZipNewInfo::setPermissions(QFile::Permissions permissions)
123 | {
124 | QuaZipNewInfo_setPermissions(this, permissions, name.endsWith('/'));
125 | }
126 |
127 | void QuaZipNewInfo::setFileNTFSTimes(const QString &fileName)
128 | {
129 | QFileInfo fi(fileName);
130 | if (!fi.exists()) {
131 | qWarning("QuaZipNewInfo::setFileNTFSTimes(): '%s' doesn't exist",
132 | fileName.toUtf8().constData());
133 | return;
134 | }
135 | setFileNTFSmTime(fi.lastModified());
136 | setFileNTFSaTime(fi.lastRead());
137 | setFileNTFScTime(fi.created());
138 | }
139 |
140 | static void setNTFSTime(QByteArray &extra, const QDateTime &time, int position,
141 | int fineTicks) {
142 | int ntfsPos = -1, timesPos = -1;
143 | unsigned ntfsLength = 0, ntfsTimesLength = 0;
144 | for (int i = 0; i <= extra.size() - 4; ) {
145 | unsigned type = static_cast(static_cast(
146 | extra.at(i)))
147 | | (static_cast(static_cast(
148 | extra.at(i + 1))) << 8);
149 | i += 2;
150 | unsigned length = static_cast(static_cast(
151 | extra.at(i)))
152 | | (static_cast(static_cast(
153 | extra.at(i + 1))) << 8);
154 | i += 2;
155 | if (type == QUAZIP_EXTRA_NTFS_MAGIC) {
156 | ntfsPos = i - 4; // the beginning of the NTFS record
157 | ntfsLength = length;
158 | if (length <= 4) {
159 | break; // no times in the NTFS record
160 | }
161 | i += 4; // reserved
162 | while (i <= extra.size() - 4) {
163 | unsigned tag = static_cast(
164 | static_cast(extra.at(i)))
165 | | (static_cast(
166 | static_cast(extra.at(i + 1)))
167 | << 8);
168 | i += 2;
169 | unsigned tagsize = static_cast(
170 | static_cast(extra.at(i)))
171 | | (static_cast(
172 | static_cast(extra.at(i + 1)))
173 | << 8);
174 | i += 2;
175 | if (tag == QUAZIP_EXTRA_NTFS_TIME_MAGIC) {
176 | timesPos = i - 4; // the beginning of the NTFS times tag
177 | ntfsTimesLength = tagsize;
178 | break;
179 | } else {
180 | i += tagsize;
181 | }
182 | }
183 | break; // I ain't going to search for yet another NTFS record!
184 | } else {
185 | i += length;
186 | }
187 | }
188 | if (ntfsPos == -1) {
189 | // No NTFS record, need to create one.
190 | ntfsPos = extra.size();
191 | ntfsLength = 32;
192 | extra.resize(extra.size() + 4 + ntfsLength);
193 | // the NTFS record header
194 | extra[ntfsPos] = static_cast(QUAZIP_EXTRA_NTFS_MAGIC);
195 | extra[ntfsPos + 1] = static_cast(QUAZIP_EXTRA_NTFS_MAGIC >> 8);
196 | extra[ntfsPos + 2] = 32; // the 2-byte size in LittleEndian
197 | extra[ntfsPos + 3] = 0;
198 | // zero the record
199 | memset(extra.data() + ntfsPos + 4, 0, 32);
200 | timesPos = ntfsPos + 8;
201 | // now set the tag data
202 | extra[timesPos] = static_cast(QUAZIP_EXTRA_NTFS_TIME_MAGIC);
203 | extra[timesPos + 1] = static_cast(QUAZIP_EXTRA_NTFS_TIME_MAGIC
204 | >> 8);
205 | // the size:
206 | extra[timesPos + 2] = 24;
207 | extra[timesPos + 3] = 0;
208 | ntfsTimesLength = 24;
209 | }
210 | if (timesPos == -1) {
211 | // No time tag in the NTFS record, need to add one.
212 | timesPos = ntfsPos + 4 + ntfsLength;
213 | extra.resize(extra.size() + 28);
214 | // Now we need to move the rest of the field
215 | // (possibly zero bytes, but memmove() is OK with that).
216 | // 0 ......... ntfsPos .. ntfsPos + 4 ... timesPos
217 | //
218 | memmove(extra.data() + timesPos + 28, extra.data() + timesPos,
219 | extra.size() - 28 - timesPos);
220 | ntfsLength += 28;
221 | // now set the tag data
222 | extra[timesPos] = static_cast(QUAZIP_EXTRA_NTFS_TIME_MAGIC);
223 | extra[timesPos + 1] = static_cast(QUAZIP_EXTRA_NTFS_TIME_MAGIC
224 | >> 8);
225 | // the size:
226 | extra[timesPos + 2] = 24;
227 | extra[timesPos + 3] = 0;
228 | // zero the record
229 | memset(extra.data() + timesPos + 4, 0, 24);
230 | ntfsTimesLength = 24;
231 | }
232 | if (ntfsTimesLength < 24) {
233 | // Broken times field. OK, this is really unlikely, but just in case...
234 | size_t timesEnd = timesPos + 4 + ntfsTimesLength;
235 | extra.resize(extra.size() + (24 - ntfsTimesLength));
236 | // Move it!
237 | // 0 ......... timesPos .... timesPos + 4 .. timesEnd
238 | //