source: Vago/Libs/quazip-0.7.2/quazip/JlCompress.cpp@ 1088

Last change on this file since 1088 was 1050, checked in by s10k, 8 years ago
File size: 12.0 KB
Line 
1/*
2Copyright (C) 2010 Roberto Pompermaier
3Copyright (C) 2005-2014 Sergey A. Tachenov
4
5This file is part of QuaZIP.
6
7QuaZIP is free software: you can redistribute it and/or modify
8it under the terms of the GNU Lesser General Public License as published by
9the Free Software Foundation, either version 2.1 of the License, or
10(at your option) any later version.
11
12QuaZIP is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU Lesser General Public License for more details.
16
17You should have received a copy of the GNU Lesser General Public License
18along with QuaZIP. If not, see <http://www.gnu.org/licenses/>.
19
20See COPYING file for the full LGPL text.
21
22Original ZIP package is copyrighted by Gilles Vollant and contributors,
23see quazip/(un)zip.h files for details. Basically it's the zlib license.
24*/
25
26#include "JlCompress.h"
27#include <QDebug>
28
29static 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
42bool 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
75bool 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
128bool 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
193bool JlCompress::removeFile(QStringList listFile) {
194 bool ret = true;
195 // Per ogni file
196 for (int i=0; i<listFile.count(); i++) {
197 // Lo elimino
198 ret = ret && QFile::remove(listFile.at(i));
199 }
200 return ret;
201}
202
203bool JlCompress::compressFile(QString fileCompressed, QString file) {
204 // Creo lo zip
205 QuaZip zip(fileCompressed);
206 QDir().mkpath(QFileInfo(fileCompressed).absolutePath());
207 if(!zip.open(QuaZip::mdCreate)) {
208 QFile::remove(fileCompressed);
209 return false;
210 }
211
212 // Aggiungo il file
213 if (!compressFile(&zip,file,QFileInfo(file).fileName())) {
214 QFile::remove(fileCompressed);
215 return false;
216 }
217
218 // Chiudo il file zip
219 zip.close();
220 if(zip.getZipError()!=0) {
221 QFile::remove(fileCompressed);
222 return false;
223 }
224
225 return true;
226}
227
228bool JlCompress::compressFiles(QString fileCompressed, QStringList files) {
229 // Creo lo zip
230 QuaZip zip(fileCompressed);
231 QDir().mkpath(QFileInfo(fileCompressed).absolutePath());
232 if(!zip.open(QuaZip::mdCreate)) {
233 QFile::remove(fileCompressed);
234 return false;
235 }
236
237 // Comprimo i file
238 QFileInfo info;
239 Q_FOREACH (QString file, files) {
240 info.setFile(file);
241 if (!info.exists() || !compressFile(&zip,file,info.fileName())) {
242 QFile::remove(fileCompressed);
243 return false;
244 }
245 }
246
247 // Chiudo il file zip
248 zip.close();
249 if(zip.getZipError()!=0) {
250 QFile::remove(fileCompressed);
251 return false;
252 }
253
254 return true;
255}
256
257bool JlCompress::compressDir(QString fileCompressed, QString dir, bool recursive) {
258 return compressDir(fileCompressed, dir, recursive, 0);
259}
260
261bool JlCompress::compressDir(QString fileCompressed, QString dir,
262 bool recursive, QDir::Filters filters)
263{
264 // Creo lo zip
265 QuaZip zip(fileCompressed);
266 QDir().mkpath(QFileInfo(fileCompressed).absolutePath());
267 if(!zip.open(QuaZip::mdCreate)) {
268 QFile::remove(fileCompressed);
269 return false;
270 }
271
272 // Aggiungo i file e le sotto cartelle
273 if (!compressSubDir(&zip,dir,dir,recursive, filters)) {
274 QFile::remove(fileCompressed);
275 return false;
276 }
277
278 // Chiudo il file zip
279 zip.close();
280 if(zip.getZipError()!=0) {
281 QFile::remove(fileCompressed);
282 return false;
283 }
284
285 return true;
286}
287
288QString JlCompress::extractFile(QString fileCompressed, QString fileName, QString fileDest) {
289 // Apro lo zip
290 QuaZip zip(fileCompressed);
291 return extractFile(zip, fileName, fileDest);
292}
293
294QString JlCompress::extractFile(QuaZip &zip, QString fileName, QString fileDest)
295{
296 if(!zip.open(QuaZip::mdUnzip)) {
297 return QString();
298 }
299
300 // Estraggo il file
301 if (fileDest.isEmpty())
302 fileDest = fileName;
303 if (!extractFile(&zip,fileName,fileDest)) {
304 return QString();
305 }
306
307 // Chiudo il file zip
308 zip.close();
309 if(zip.getZipError()!=0) {
310 removeFile(QStringList(fileDest));
311 return QString();
312 }
313 return QFileInfo(fileDest).absoluteFilePath();
314}
315
316QStringList JlCompress::extractFiles(QString fileCompressed, QStringList files, QString dir) {
317 // Creo lo zip
318 QuaZip zip(fileCompressed);
319 return extractFiles(zip, files, dir);
320}
321
322QStringList JlCompress::extractFiles(QuaZip &zip, const QStringList &files, const QString &dir)
323{
324 if(!zip.open(QuaZip::mdUnzip)) {
325 return QStringList();
326 }
327
328 // Estraggo i file
329 QStringList extracted;
330 for (int i=0; i<files.count(); i++) {
331 QString absPath = QDir(dir).absoluteFilePath(files.at(i));
332 if (!extractFile(&zip, files.at(i), absPath)) {
333 removeFile(extracted);
334 return QStringList();
335 }
336 extracted.append(absPath);
337 }
338
339 // Chiudo il file zip
340 zip.close();
341 if(zip.getZipError()!=0) {
342 removeFile(extracted);
343 return QStringList();
344 }
345
346 return extracted;
347}
348
349QStringList JlCompress::extractDir(QString fileCompressed, QString dir) {
350 // Apro lo zip
351 QuaZip zip(fileCompressed);
352 return extractDir(zip, dir);
353}
354
355QStringList JlCompress::extractDir(QuaZip &zip, const QString &dir)
356{
357 if(!zip.open(QuaZip::mdUnzip)) {
358 return QStringList();
359 }
360
361 QDir directory(dir);
362 QStringList extracted;
363 if (!zip.goToFirstFile()) {
364 return QStringList();
365 }
366 do {
367 QString name = zip.getCurrentFileName();
368 QString absFilePath = directory.absoluteFilePath(name);
369 if (!extractFile(&zip, "", absFilePath)) {
370 removeFile(extracted);
371 return QStringList();
372 }
373 extracted.append(absFilePath);
374 } while (zip.goToNextFile());
375
376 // Chiudo il file zip
377 zip.close();
378 if(zip.getZipError()!=0) {
379 removeFile(extracted);
380 return QStringList();
381 }
382
383 return extracted;
384}
385
386QStringList JlCompress::getFileList(QString fileCompressed) {
387 // Apro lo zip
388 QuaZip* zip = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath());
389 return getFileList(zip);
390}
391
392QStringList JlCompress::getFileList(QuaZip *zip)
393{
394 if(!zip->open(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
421QStringList JlCompress::extractDir(QIODevice *ioDevice, QString dir)
422{
423 QuaZip zip(ioDevice);
424 return extractDir(zip, dir);
425}
426
427QStringList JlCompress::getFileList(QIODevice *ioDevice)
428{
429 QuaZip *zip = new QuaZip(ioDevice);
430 return getFileList(zip);
431}
432
433QString JlCompress::extractFile(QIODevice *ioDevice, QString fileName, QString fileDest)
434{
435 QuaZip zip(ioDevice);
436 return extractFile(zip, fileName, fileDest);
437}
438
439QStringList JlCompress::extractFiles(QIODevice *ioDevice, QStringList files, QString dir)
440{
441 QuaZip zip(ioDevice);
442 return extractFiles(zip, files, dir);
443}
Note: See TracBrowser for help on using the repository browser.