diff options
Diffstat (limited to 'installer/quazip/JlCompress.cpp')
| -rw-r--r-- | installer/quazip/JlCompress.cpp | 454 |
1 files changed, 454 insertions, 0 deletions
diff --git a/installer/quazip/JlCompress.cpp b/installer/quazip/JlCompress.cpp new file mode 100644 index 0000000..40978b1 --- /dev/null +++ b/installer/quazip/JlCompress.cpp @@ -0,0 +1,454 @@ +/* +Copyright (C) 2010 Roberto Pompermaier +Copyright (C) 2005-2014 Sergey A. Tachenov + +This file is part of QuaZIP. + +QuaZIP is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 2.1 of the License, or +(at your option) any later version. + +QuaZIP is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with QuaZIP. If not, see <http://www.gnu.org/licenses/>. + +See COPYING file for the full LGPL text. + +Original ZIP package is copyrighted by Gilles Vollant and contributors, +see quazip/(un)zip.h files for details. Basically it's the zlib license. +*/ + +#include "JlCompress.h" +#include <QDebug> + +static bool copyData(QIODevice &inFile, QIODevice &outFile) +{ + while (!inFile.atEnd()) { + char buf[4096]; + qint64 readLen = inFile.read(buf, 4096); + if (readLen <= 0) + return false; + if (outFile.write(buf, readLen) != readLen) + return false; + } + return true; +} + +bool JlCompress::compressFile(QuaZip* zip, QString fileName, QString fileDest) { + // zip: oggetto dove aggiungere il file + // fileName: nome del file reale + // fileDest: nome del file all'interno del file compresso + + // Controllo l'apertura dello zip + if (!zip) return false; + if (zip->getMode()!=QuaZip::mdCreate && + zip->getMode()!=QuaZip::mdAppend && + zip->getMode()!=QuaZip::mdAdd) return false; + + // Apro il file originale + QFile inFile; + inFile.setFileName(fileName); + if(!inFile.open(QIODevice::ReadOnly)) return false; + + // Apro il file risulato + QuaZipFile outFile(zip); + if(!outFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileDest, inFile.fileName()))) return false; + + // Copio i dati + if (!copyData(inFile, outFile) || outFile.getZipError()!=UNZ_OK) { + return false; + } + + // Chiudo i file + outFile.close(); + if (outFile.getZipError()!=UNZ_OK) return false; + inFile.close(); + + return true; +} + +bool JlCompress::compressSubDir(QuaZip* zip, QString dir, QString origDir, bool recursive, QDir::Filters filters) { + // zip: oggetto dove aggiungere il file + // dir: cartella reale corrente + // origDir: cartella reale originale + // (path(dir)-path(origDir)) = path interno all'oggetto zip + + // Controllo l'apertura dello zip + if (!zip) return false; + if (zip->getMode()!=QuaZip::mdCreate && + zip->getMode()!=QuaZip::mdAppend && + zip->getMode()!=QuaZip::mdAdd) return false; + + // Controllo la cartella + QDir directory(dir); + if (!directory.exists()) return false; + + QDir origDirectory(origDir); + if (dir != origDir) { + QuaZipFile dirZipFile(zip); + if (!dirZipFile.open(QIODevice::WriteOnly, + QuaZipNewInfo(origDirectory.relativeFilePath(dir) + "/", dir), 0, 0, 0)) { + return false; + } + dirZipFile.close(); + } + + + // Se comprimo anche le sotto cartelle + if (recursive) { + // Per ogni sotto cartella + QFileInfoList files = directory.entryInfoList(QDir::AllDirs|QDir::NoDotAndDotDot|filters); + for (int index = 0; index < files.size(); ++index ) { + const QFileInfo & file( files.at( index ) ); +#if QT_VERSION < QT_VERSION_CHECK(4, 7, 4) + if (!file.isDir()) + continue; +#endif + // Comprimo la sotto cartella + if(!compressSubDir(zip,file.absoluteFilePath(),origDir,recursive,filters)) return false; + } + } + + // Per ogni file nella cartella + QFileInfoList files = directory.entryInfoList(QDir::Files|filters); + for (int index = 0; index < files.size(); ++index ) { + const QFileInfo & file( files.at( index ) ); + // Se non e un file o e il file compresso che sto creando + if(!file.isFile()||file.absoluteFilePath()==zip->getZipName()) continue; + + // Creo il nome relativo da usare all'interno del file compresso + QString filename = origDirectory.relativeFilePath(file.absoluteFilePath()); + + // Comprimo il file + if (!compressFile(zip,file.absoluteFilePath(),filename)) return false; + } + + return true; +} + +bool JlCompress::extractFile(QuaZip* zip, QString fileName, QString fileDest) { + // zip: oggetto dove aggiungere il file + // filename: nome del file reale + // fileincompress: nome del file all'interno del file compresso + + // Controllo l'apertura dello zip + if (!zip) return false; + if (zip->getMode()!=QuaZip::mdUnzip) return false; + + // Apro il file compresso + if (!fileName.isEmpty()) + zip->setCurrentFile(fileName); + QuaZipFile inFile(zip); + if(!inFile.open(QIODevice::ReadOnly) || inFile.getZipError()!=UNZ_OK) return false; + + // Controllo esistenza cartella file risultato + QDir curDir; + if (fileDest.endsWith('/')) { + if (!curDir.mkpath(fileDest)) { + return false; + } + } else { + if (!curDir.mkpath(QFileInfo(fileDest).absolutePath())) { + return false; + } + } + + QuaZipFileInfo64 info; + if (!zip->getCurrentFileInfo(&info)) + return false; + + QFile::Permissions srcPerm = info.getPermissions(); + if (fileDest.endsWith('/') && QFileInfo(fileDest).isDir()) { + if (srcPerm != 0) { + QFile(fileDest).setPermissions(srcPerm); + } + return true; + } + + // Apro il file risultato + QFile outFile; + outFile.setFileName(fileDest); + if(!outFile.open(QIODevice::WriteOnly)) return false; + + // Copio i dati + if (!copyData(inFile, outFile) || inFile.getZipError()!=UNZ_OK) { + outFile.close(); + removeFile(QStringList(fileDest)); + return false; + } + outFile.close(); + + // Chiudo i file + inFile.close(); + if (inFile.getZipError()!=UNZ_OK) { + removeFile(QStringList(fileDest)); + return false; + } + + if (srcPerm != 0) { + outFile.setPermissions(srcPerm); + } + return true; +} + +bool JlCompress::removeFile(QStringList listFile) { + bool ret = true; + // Per ogni file + for (int i=0; i<listFile.count(); i++) { + // Lo elimino + ret = ret && QFile::remove(listFile.at(i)); + } + return ret; +} + +bool JlCompress::compressFile(QString fileCompressed, QString file) { + // Creo lo zip + QuaZip zip(fileCompressed); + QDir().mkpath(QFileInfo(fileCompressed).absolutePath()); + if(!zip.open(QuaZip::mdCreate)) { + QFile::remove(fileCompressed); + return false; + } + + // Aggiungo il file + if (!compressFile(&zip,file,QFileInfo(file).fileName())) { + QFile::remove(fileCompressed); + return false; + } + + // Chiudo il file zip + zip.close(); + if(zip.getZipError()!=0) { + QFile::remove(fileCompressed); + return false; + } + + return true; +} + +bool JlCompress::compressFiles(QString fileCompressed, QStringList files) { + // Creo lo zip + QuaZip zip(fileCompressed); + QDir().mkpath(QFileInfo(fileCompressed).absolutePath()); + if(!zip.open(QuaZip::mdCreate)) { + QFile::remove(fileCompressed); + return false; + } + + // Comprimo i file + QFileInfo info; + for (int index = 0; index < files.size(); ++index ) { + const QString & file( files.at( index ) ); + info.setFile(file); + if (!info.exists() || !compressFile(&zip,file,info.fileName())) { + QFile::remove(fileCompressed); + return false; + } + } + + // Chiudo il file zip + zip.close(); + if(zip.getZipError()!=0) { + QFile::remove(fileCompressed); + return false; + } + + return true; +} + +bool JlCompress::compressDir(QString fileCompressed, QString dir, bool recursive) { + return compressDir(fileCompressed, dir, recursive, 0); +} + +bool JlCompress::compressDir(QString fileCompressed, QString dir, + bool recursive, QDir::Filters filters) +{ + // Creo lo zip + QuaZip zip(fileCompressed); + QDir().mkpath(QFileInfo(fileCompressed).absolutePath()); + if(!zip.open(QuaZip::mdCreate)) { + QFile::remove(fileCompressed); + return false; + } + + // Aggiungo i file e le sotto cartelle + if (!compressSubDir(&zip,dir,dir,recursive, filters)) { + QFile::remove(fileCompressed); + return false; + } + + // Chiudo il file zip + zip.close(); + if(zip.getZipError()!=0) { + QFile::remove(fileCompressed); + return false; + } + + return true; +} + +QString JlCompress::extractFile(QString fileCompressed, QString fileName, QString fileDest) { + // Apro lo zip + QuaZip zip(fileCompressed); + return extractFile(zip, fileName, fileDest); +} + +QString JlCompress::extractFile(QuaZip &zip, QString fileName, QString fileDest) +{ + if(!zip.open(QuaZip::mdUnzip)) { + return QString(); + } + + // Estraggo il file + if (fileDest.isEmpty()) + fileDest = fileName; + if (!extractFile(&zip,fileName,fileDest)) { + return QString(); + } + + // Chiudo il file zip + zip.close(); + if(zip.getZipError()!=0) { + removeFile(QStringList(fileDest)); + return QString(); + } + return QFileInfo(fileDest).absoluteFilePath(); +} + +QStringList JlCompress::extractFiles(QString fileCompressed, QStringList files, QString dir) { + // Creo lo zip + QuaZip zip(fileCompressed); + return extractFiles(zip, files, dir); +} + +QStringList JlCompress::extractFiles(QuaZip &zip, const QStringList &files, const QString &dir) +{ + if(!zip.open(QuaZip::mdUnzip)) { + return QStringList(); + } + + // Estraggo i file + QStringList extracted; + for (int i=0; i<files.count(); i++) { + QString absPath = QDir(dir).absoluteFilePath(files.at(i)); + if (!extractFile(&zip, files.at(i), absPath)) { + removeFile(extracted); + return QStringList(); + } + extracted.append(absPath); + } + + // Chiudo il file zip + zip.close(); + if(zip.getZipError()!=0) { + removeFile(extracted); + return QStringList(); + } + + return extracted; +} + +QStringList JlCompress::extractDir(QString fileCompressed, QString dir) { + // Apro lo zip + QuaZip zip(fileCompressed); + return extractDir(zip, dir); +} + +QStringList JlCompress::extractDir(QuaZip &zip, const QString &dir) +{ + if(!zip.open(QuaZip::mdUnzip)) { + return QStringList(); + } + QString cleanDir = QDir::cleanPath(dir); + QDir directory(cleanDir); + QString absCleanDir = directory.absolutePath(); + QStringList extracted; + if (!zip.goToFirstFile()) { + return QStringList(); + } + do { + QString name = zip.getCurrentFileName(); + QString absFilePath = directory.absoluteFilePath(name); + QString absCleanPath = QDir::cleanPath(absFilePath); + if (!absCleanPath.startsWith(absCleanDir + "/")) + continue; + if (!extractFile(&zip, "", absFilePath)) { + removeFile(extracted); + return QStringList(); + } + extracted.append(absFilePath); + } while (zip.goToNextFile()); + + // Chiudo il file zip + zip.close(); + if(zip.getZipError()!=0) { + removeFile(extracted); + return QStringList(); + } + + return extracted; +} + +QStringList JlCompress::getFileList(QString fileCompressed) { + // Apro lo zip + QuaZip* zip = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath()); + return getFileList(zip); +} + +QStringList JlCompress::getFileList(QuaZip *zip) +{ + if(!zip->open(QuaZip::mdUnzip)) { + delete zip; + return QStringList(); + } + + // Estraggo i nomi dei file + QStringList lst; + QuaZipFileInfo64 info; + for(bool more=zip->goToFirstFile(); more; more=zip->goToNextFile()) { + if(!zip->getCurrentFileInfo(&info)) { + delete zip; + return QStringList(); + } + lst << info.name; + //info.name.toLocal8Bit().constData() + } + + // Chiudo il file zip + zip->close(); + if(zip->getZipError()!=0) { + delete zip; + return QStringList(); + } + delete zip; + return lst; +} + +QStringList JlCompress::extractDir(QIODevice *ioDevice, QString dir) +{ + QuaZip zip(ioDevice); + return extractDir(zip, dir); +} + +QStringList JlCompress::getFileList(QIODevice *ioDevice) +{ + QuaZip *zip = new QuaZip(ioDevice); + return getFileList(zip); +} + +QString JlCompress::extractFile(QIODevice *ioDevice, QString fileName, QString fileDest) +{ + QuaZip zip(ioDevice); + return extractFile(zip, fileName, fileDest); +} + +QStringList JlCompress::extractFiles(QIODevice *ioDevice, QStringList files, QString dir) +{ + QuaZip zip(ioDevice); + return extractFiles(zip, files, dir); +} |
