File indexing completed on 2025-01-26 04:24:52
0001 /* 0002 Copyright (C) 2010 Roberto Pompermaier 0003 Copyright (C) 2005-2014 Sergey A. Tachenov 0004 0005 This file is part of QuaZIP. 0006 0007 QuaZIP is free software: you can redistribute it and/or modify 0008 it under the terms of the GNU Lesser General Public License as published by 0009 the Free Software Foundation, either version 2.1 of the License, or 0010 (at your option) any later version. 0011 0012 QuaZIP is distributed in the hope that it will be useful, 0013 but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0015 GNU Lesser General Public License for more details. 0016 0017 You should have received a copy of the GNU Lesser General Public License 0018 along with QuaZIP. If not, see <http://www.gnu.org/licenses/>. 0019 0020 See COPYING file for the full LGPL text. 0021 0022 Original ZIP package is copyrighted by Gilles Vollant and contributors, 0023 see quazip/(un)zip.h files for details. Basically it's the zlib license. 0024 */ 0025 0026 #include "JlCompress.h" 0027 #include <QDebug> 0028 0029 static bool copyData(QIODevice &inFile, QIODevice &outFile) 0030 { 0031 while (!inFile.atEnd()) { 0032 char buf[4096]; 0033 qint64 readLen = inFile.read(buf, 4096); 0034 if (readLen <= 0) 0035 return false; 0036 if (outFile.write(buf, readLen) != readLen) 0037 return false; 0038 } 0039 return true; 0040 } 0041 0042 bool JlCompress::compressFile(QuaZip* zip, QString fileName, QString fileDest) { 0043 // zip: oggetto dove aggiungere il file 0044 // fileName: nome del file reale 0045 // fileDest: nome del file all'interno del file compresso 0046 0047 // Controllo l'apertura dello zip 0048 if (!zip) return false; 0049 if (zip->getMode()!=QuaZip::mdCreate && 0050 zip->getMode()!=QuaZip::mdAppend && 0051 zip->getMode()!=QuaZip::mdAdd) return false; 0052 0053 // Apro il file originale 0054 QFile inFile; 0055 inFile.setFileName(fileName); 0056 if(!inFile.open(QIODevice::ReadOnly)) return false; 0057 0058 // Apro il file risulato 0059 QuaZipFile outFile(zip); 0060 if(!outFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileDest, inFile.fileName()))) return false; 0061 0062 // Copio i dati 0063 if (!copyData(inFile, outFile) || outFile.getZipError()!=UNZ_OK) { 0064 return false; 0065 } 0066 0067 // Chiudo i file 0068 outFile.close(); 0069 if (outFile.getZipError()!=UNZ_OK) return false; 0070 inFile.close(); 0071 0072 return true; 0073 } 0074 0075 bool JlCompress::compressSubDir(QuaZip* zip, QString dir, QString origDir, bool recursive, QDir::Filters filters) { 0076 // zip: oggetto dove aggiungere il file 0077 // dir: cartella reale corrente 0078 // origDir: cartella reale originale 0079 // (path(dir)-path(origDir)) = path interno all'oggetto zip 0080 0081 // Controllo l'apertura dello zip 0082 if (!zip) return false; 0083 if (zip->getMode()!=QuaZip::mdCreate && 0084 zip->getMode()!=QuaZip::mdAppend && 0085 zip->getMode()!=QuaZip::mdAdd) return false; 0086 0087 // Controllo la cartella 0088 QDir directory(dir); 0089 if (!directory.exists()) return false; 0090 0091 QDir origDirectory(origDir); 0092 if (dir != origDir) { 0093 QuaZipFile dirZipFile(zip); 0094 if (!dirZipFile.open(QIODevice::WriteOnly, 0095 QuaZipNewInfo(origDirectory.relativeFilePath(dir) + "/", dir), 0, 0, 0)) { 0096 return false; 0097 } 0098 dirZipFile.close(); 0099 } 0100 0101 0102 // Se comprimo anche le sotto cartelle 0103 if (recursive) { 0104 // Per ogni sotto cartella 0105 QFileInfoList files = directory.entryInfoList(QDir::AllDirs|QDir::NoDotAndDotDot|filters); 0106 Q_FOREACH (QFileInfo file, files) { 0107 // Comprimo la sotto cartella 0108 if(!compressSubDir(zip,file.absoluteFilePath(),origDir,recursive,filters)) return false; 0109 } 0110 } 0111 0112 // Per ogni file nella cartella 0113 QFileInfoList files = directory.entryInfoList(QDir::Files|filters); 0114 Q_FOREACH (QFileInfo file, files) { 0115 // Se non e un file o e il file compresso che sto creando 0116 if(!file.isFile()||file.absoluteFilePath()==zip->getZipName()) continue; 0117 0118 // Creo il nome relativo da usare all'interno del file compresso 0119 QString filename = origDirectory.relativeFilePath(file.absoluteFilePath()); 0120 0121 // Comprimo il file 0122 if (!compressFile(zip,file.absoluteFilePath(),filename)) return false; 0123 } 0124 0125 return true; 0126 } 0127 0128 bool JlCompress::extractFile(QuaZip* zip, QString fileName, QString fileDest) { 0129 // zip: oggetto dove aggiungere il file 0130 // filename: nome del file reale 0131 // fileincompress: nome del file all'interno del file compresso 0132 0133 // Controllo l'apertura dello zip 0134 if (!zip) return false; 0135 if (zip->getMode()!=QuaZip::mdUnzip) return false; 0136 0137 // Apro il file compresso 0138 if (!fileName.isEmpty()) 0139 zip->setCurrentFile(fileName); 0140 QuaZipFile inFile(zip); 0141 if(!inFile.open(QIODevice::ReadOnly) || inFile.getZipError()!=UNZ_OK) return false; 0142 0143 // Controllo esistenza cartella file risultato 0144 QDir curDir; 0145 if (fileDest.endsWith('/')) { 0146 if (!curDir.mkpath(fileDest)) { 0147 return false; 0148 } 0149 } else { 0150 if (!curDir.mkpath(QFileInfo(fileDest).absolutePath())) { 0151 return false; 0152 } 0153 } 0154 0155 QuaZipFileInfo64 info; 0156 if (!zip->getCurrentFileInfo(&info)) 0157 return false; 0158 0159 QFile::Permissions srcPerm = info.getPermissions(); 0160 if (fileDest.endsWith('/') && QFileInfo(fileDest).isDir()) { 0161 if (srcPerm != 0) { 0162 QFile(fileDest).setPermissions(srcPerm); 0163 } 0164 return true; 0165 } 0166 0167 // Apro il file risultato 0168 QFile outFile; 0169 outFile.setFileName(fileDest); 0170 if(!outFile.open(QIODevice::WriteOnly)) return false; 0171 0172 // Copio i dati 0173 if (!copyData(inFile, outFile) || inFile.getZipError()!=UNZ_OK) { 0174 outFile.close(); 0175 removeFile(QStringList(fileDest)); 0176 return false; 0177 } 0178 outFile.close(); 0179 0180 // Chiudo i file 0181 inFile.close(); 0182 if (inFile.getZipError()!=UNZ_OK) { 0183 removeFile(QStringList(fileDest)); 0184 return false; 0185 } 0186 0187 if (srcPerm != 0) { 0188 outFile.setPermissions(srcPerm); 0189 } 0190 return true; 0191 } 0192 0193 bool JlCompress::removeFile(QStringList listFile) { 0194 bool ret = true; 0195 // Per ogni file 0196 for (int i=0; i<listFile.count(); i++) { 0197 // Lo elimino 0198 ret = ret && QFile::remove(listFile.at(i)); 0199 } 0200 return ret; 0201 } 0202 0203 bool JlCompress::compressFile(QString fileCompressed, QString file) { 0204 // Creo lo zip 0205 QuaZip zip(fileCompressed); 0206 QDir().mkpath(QFileInfo(fileCompressed).absolutePath()); 0207 if(!zip.open(QuaZip::mdCreate)) { 0208 QFile::remove(fileCompressed); 0209 return false; 0210 } 0211 0212 // Aggiungo il file 0213 if (!compressFile(&zip,file,QFileInfo(file).fileName())) { 0214 QFile::remove(fileCompressed); 0215 return false; 0216 } 0217 0218 // Chiudo il file zip 0219 zip.close(); 0220 if(zip.getZipError()!=0) { 0221 QFile::remove(fileCompressed); 0222 return false; 0223 } 0224 0225 return true; 0226 } 0227 0228 bool JlCompress::compressFiles(QString fileCompressed, QStringList files) { 0229 // Creo lo zip 0230 QuaZip zip(fileCompressed); 0231 QDir().mkpath(QFileInfo(fileCompressed).absolutePath()); 0232 if(!zip.open(QuaZip::mdCreate)) { 0233 QFile::remove(fileCompressed); 0234 return false; 0235 } 0236 0237 // Comprimo i file 0238 QFileInfo info; 0239 Q_FOREACH (QString file, files) { 0240 info.setFile(file); 0241 if (!info.exists() || !compressFile(&zip,file,info.fileName())) { 0242 QFile::remove(fileCompressed); 0243 return false; 0244 } 0245 } 0246 0247 // Chiudo il file zip 0248 zip.close(); 0249 if(zip.getZipError()!=0) { 0250 QFile::remove(fileCompressed); 0251 return false; 0252 } 0253 0254 return true; 0255 } 0256 0257 bool JlCompress::compressDir(QString fileCompressed, QString dir, bool recursive) { 0258 return compressDir(fileCompressed, dir, recursive, 0); 0259 } 0260 0261 bool JlCompress::compressDir(QString fileCompressed, QString dir, 0262 bool recursive, QDir::Filters filters) 0263 { 0264 // Creo lo zip 0265 QuaZip zip(fileCompressed); 0266 QDir().mkpath(QFileInfo(fileCompressed).absolutePath()); 0267 if(!zip.open(QuaZip::mdCreate)) { 0268 QFile::remove(fileCompressed); 0269 return false; 0270 } 0271 0272 // Aggiungo i file e le sotto cartelle 0273 if (!compressSubDir(&zip,dir,dir,recursive, filters)) { 0274 QFile::remove(fileCompressed); 0275 return false; 0276 } 0277 0278 // Chiudo il file zip 0279 zip.close(); 0280 if(zip.getZipError()!=0) { 0281 QFile::remove(fileCompressed); 0282 return false; 0283 } 0284 0285 return true; 0286 } 0287 0288 QString JlCompress::extractFile(QString fileCompressed, QString fileName, QString fileDest) { 0289 // Apro lo zip 0290 QuaZip zip(fileCompressed); 0291 return extractFile(zip, fileName, fileDest); 0292 } 0293 0294 QString JlCompress::extractFile(QuaZip &zip, QString fileName, QString fileDest) 0295 { 0296 if(!zip.open(QuaZip::mdUnzip)) { 0297 return QString(); 0298 } 0299 0300 // Estraggo il file 0301 if (fileDest.isEmpty()) 0302 fileDest = fileName; 0303 if (!extractFile(&zip,fileName,fileDest)) { 0304 return QString(); 0305 } 0306 0307 // Chiudo il file zip 0308 zip.close(); 0309 if(zip.getZipError()!=0) { 0310 removeFile(QStringList(fileDest)); 0311 return QString(); 0312 } 0313 return QFileInfo(fileDest).absoluteFilePath(); 0314 } 0315 0316 QStringList JlCompress::extractFiles(QString fileCompressed, QStringList files, QString dir) { 0317 // Creo lo zip 0318 QuaZip zip(fileCompressed); 0319 return extractFiles(zip, files, dir); 0320 } 0321 0322 QStringList JlCompress::extractFiles(QuaZip &zip, const QStringList &files, const QString &dir) 0323 { 0324 if(!zip.open(QuaZip::mdUnzip)) { 0325 return QStringList(); 0326 } 0327 0328 // Estraggo i file 0329 QStringList extracted; 0330 for (int i=0; i<files.count(); i++) { 0331 QString absPath = QDir(dir).absoluteFilePath(files.at(i)); 0332 if (!extractFile(&zip, files.at(i), absPath)) { 0333 removeFile(extracted); 0334 return QStringList(); 0335 } 0336 extracted.append(absPath); 0337 } 0338 0339 // Chiudo il file zip 0340 zip.close(); 0341 if(zip.getZipError()!=0) { 0342 removeFile(extracted); 0343 return QStringList(); 0344 } 0345 0346 return extracted; 0347 } 0348 0349 QStringList JlCompress::extractDir(QString fileCompressed, QString dir) { 0350 // Apro lo zip 0351 QuaZip zip(fileCompressed); 0352 return extractDir(zip, dir); 0353 } 0354 0355 QStringList JlCompress::extractDir(QuaZip &zip, const QString &dir) 0356 { 0357 if(!zip.open(QuaZip::mdUnzip)) { 0358 return QStringList(); 0359 } 0360 0361 QDir directory(dir); 0362 QStringList extracted; 0363 if (!zip.goToFirstFile()) { 0364 return QStringList(); 0365 } 0366 do { 0367 QString name = zip.getCurrentFileName(); 0368 QString absFilePath = directory.absoluteFilePath(name); 0369 if (!extractFile(&zip, "", absFilePath)) { 0370 removeFile(extracted); 0371 return QStringList(); 0372 } 0373 extracted.append(absFilePath); 0374 } while (zip.goToNextFile()); 0375 0376 // Chiudo il file zip 0377 zip.close(); 0378 if(zip.getZipError()!=0) { 0379 removeFile(extracted); 0380 return QStringList(); 0381 } 0382 0383 return extracted; 0384 } 0385 0386 QStringList JlCompress::getFileList(QString fileCompressed) { 0387 // Apro lo zip 0388 QuaZip* zip = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath()); 0389 return getFileList(zip); 0390 } 0391 0392 QStringList JlCompress::getFileList(QuaZip *zip) 0393 { 0394 if(!zip->open(QuaZip::mdUnzip)) { 0395 delete zip; 0396 return QStringList(); 0397 } 0398 0399 // Estraggo i nomi dei file 0400 QStringList lst; 0401 QuaZipFileInfo64 info; 0402 for(bool more=zip->goToFirstFile(); more; more=zip->goToNextFile()) { 0403 if(!zip->getCurrentFileInfo(&info)) { 0404 delete zip; 0405 return QStringList(); 0406 } 0407 lst << info.name; 0408 //info.name.toLocal8Bit().constData() 0409 } 0410 0411 // Chiudo il file zip 0412 zip->close(); 0413 if(zip->getZipError()!=0) { 0414 delete zip; 0415 return QStringList(); 0416 } 0417 delete zip; 0418 return lst; 0419 } 0420 0421 QStringList JlCompress::extractDir(QIODevice *ioDevice, QString dir) 0422 { 0423 QuaZip zip(ioDevice); 0424 return extractDir(zip, dir); 0425 } 0426 0427 QStringList JlCompress::getFileList(QIODevice *ioDevice) 0428 { 0429 QuaZip *zip = new QuaZip(ioDevice); 0430 return getFileList(zip); 0431 } 0432 0433 QString JlCompress::extractFile(QIODevice *ioDevice, QString fileName, QString fileDest) 0434 { 0435 QuaZip zip(ioDevice); 0436 return extractFile(zip, fileName, fileDest); 0437 } 0438 0439 QStringList JlCompress::extractFiles(QIODevice *ioDevice, QStringList files, QString dir) 0440 { 0441 QuaZip zip(ioDevice); 0442 return extractFiles(zip, files, dir); 0443 }