summaryrefslogtreecommitdiffstats
path: root/quazip/JlCompress.cpp
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2013-01-11 02:25:40 +0100
committerPetr Mrázek <peterix@gmail.com>2013-01-11 02:25:40 +0100
commitb1d00fce8da901b31fa52ea59b4bc3c8edb9d9cc (patch)
treef7c909b4080e6d1868e601609741450330dc9a1e /quazip/JlCompress.cpp
parentd6d5c86a736537828a59ddc6389d5d0490942f8c (diff)
downloadMultiMC-b1d00fce8da901b31fa52ea59b4bc3c8edb9d9cc.tar
MultiMC-b1d00fce8da901b31fa52ea59b4bc3c8edb9d9cc.tar.gz
MultiMC-b1d00fce8da901b31fa52ea59b4bc3c8edb9d9cc.tar.lz
MultiMC-b1d00fce8da901b31fa52ea59b4bc3c8edb9d9cc.tar.xz
MultiMC-b1d00fce8da901b31fa52ea59b4bc3c8edb9d9cc.zip
CMake build system, big pile of libs: bspatch, quazip, java, the launcher
Diffstat (limited to 'quazip/JlCompress.cpp')
-rw-r--r--quazip/JlCompress.cpp469
1 files changed, 469 insertions, 0 deletions
diff --git a/quazip/JlCompress.cpp b/quazip/JlCompress.cpp
new file mode 100644
index 00000000..411645e1
--- /dev/null
+++ b/quazip/JlCompress.cpp
@@ -0,0 +1,469 @@
+#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;
+}
+
+/**OK
+ * Comprime il file fileName, nell'oggetto zip, con il nome fileDest.
+ *
+ * La funzione fallisce se:
+ * * zip==NULL;
+ * * l'oggetto zip e stato aperto in una modalita non compatibile con l'aggiunta di file;
+ * * non e possibile aprire il file d'origine;
+ * * non e possibile creare il file all'interno dell'oggetto zip;
+ * * si e rilevato un errore nella copia dei dati;
+ * * non e stato possibile chiudere il file all'interno dell'oggetto zip;
+ */
+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;
+}
+
+/**OK
+ * Comprime la cartella dir nel file fileCompressed, se recursive e true allora
+ * comprime anche le sotto cartelle. I nomi dei file preceduti dal path creato
+ * togliendo il pat della cartella origDir al path della cartella dir.
+ * Se la funzione fallisce restituisce false e cancella il file che si e tentato
+ * di creare.
+ *
+ * La funzione fallisce se:
+ * * zip==NULL;
+ * * l'oggetto zip e stato aperto in una modalita non compatibile con l'aggiunta di file;
+ * * la cartella dir non esiste;
+ * * la compressione di una sotto cartella fallisce (1);
+ * * la compressione di un file fallisce;
+ * (1) La funzione si richiama in maniera ricorsiva per comprimere le sotto cartelle
+ * dunque gli errori di compressione di una sotto cartella sono gli stessi di questa
+ * funzione.
+ */
+bool JlCompress::compressSubDir(QuaZip* zip, QString dir, QString origDir, bool recursive) {
+ // 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;
+
+ // Se comprimo anche le sotto cartelle
+ if (recursive) {
+ // Per ogni sotto cartella
+ QFileInfoList files = directory.entryInfoList(QDir::AllDirs|QDir::NoDotAndDotDot);
+ Q_FOREACH (QFileInfo file, files) {
+ // Comprimo la sotto cartella
+ if(!compressSubDir(zip,file.absoluteFilePath(),origDir,recursive)) return false;
+ }
+ }
+
+ // Per ogni file nella cartella
+ QFileInfoList files = directory.entryInfoList(QDir::Files);
+ QDir origDirectory(origDir);
+ Q_FOREACH (QFileInfo file, files) {
+ // 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;
+}
+
+/**OK
+ * Estrae il file fileName, contenuto nell'oggetto zip, con il nome fileDest.
+ * Se la funzione fallisce restituisce false e cancella il file che si e tentato di estrarre.
+ *
+ * La funzione fallisce se:
+ * * zip==NULL;
+ * * l'oggetto zip e stato aperto in una modalita non compatibile con l'estrazione di file;
+ * * non e possibile aprire il file all'interno dell'oggetto zip;
+ * * non e possibile creare il file estratto;
+ * * si e rilevato un errore nella copia dei dati (1);
+ * * non e stato possibile chiudere il file all'interno dell'oggetto zip (1);
+ *
+ * (1): prima di uscire dalla funzione cancella il file estratto.
+ */
+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 (!curDir.mkpath(QFileInfo(fileDest).absolutePath())) {
+ return false;
+ }
+
+ if (QFileInfo(fileDest).isDir())
+ 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;
+ }
+
+ return true;
+}
+
+/**
+ * Rimuove i file il cui nome e specificato all'interno di listFile.
+ * Restituisce true se tutti i file sono stati cancellati correttamente, attenzione
+ * perche puo restituire false anche se alcuni file non esistevano e si e tentato
+ * di cancellarli.
+ */
+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;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+/**OK
+ * Comprime il file fileName nel file fileCompressed.
+ * Se la funzione fallisce restituisce false e cancella il file che si e tentato
+ * di creare.
+ *
+ * La funzione fallisce se:
+ * * non si riesce ad aprire l'oggetto zip;
+ * * la compressione del file fallisce;
+ * * non si riesce a chiudere l'oggetto zip;
+ */
+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;
+}
+
+/**OK
+ * Comprime i file specificati in files nel file fileCompressed.
+ * Se la funzione fallisce restituisce false e cancella il file che si e tentato
+ * di creare.
+ *
+ * La funzione fallisce se:
+ * * non si riesce ad aprire l'oggetto zip;
+ * * la compressione di un file fallisce;
+ * * non si riesce a chiudere l'oggetto zip;
+ */
+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;
+ Q_FOREACH (QString file, files) {
+ 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;
+}
+
+/**OK
+ * Comprime la cartella dir nel file fileCompressed, se recursive e true allora
+ * comprime anche le sotto cartelle.
+ * Se la funzione fallisce restituisce false e cancella il file che si e tentato
+ * di creare.
+ *
+ * La funzione fallisce se:
+ * * non si riesce ad aprire l'oggetto zip;
+ * * la compressione di un file fallisce;
+ * * non si riesce a chiudere l'oggetto zip;
+ */
+bool JlCompress::compressDir(QString fileCompressed, QString dir, bool recursive) {
+ // 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)) {
+ QFile::remove(fileCompressed);
+ return false;
+ }
+
+ // Chiudo il file zip
+ zip.close();
+ if(zip.getZipError()!=0) {
+ QFile::remove(fileCompressed);
+ return false;
+ }
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+/**OK
+ * Estrae il file fileName, contenuto nel file fileCompressed, con il nome fileDest.
+ * Se fileDest = "" allora il file viene estratto con lo stesso nome con cui e
+ * stato compresso.
+ * Se la funzione fallisce cancella il file che si e tentato di estrarre.
+ * Restituisce il nome assoluto del file estratto.
+ *
+ * La funzione fallisce se:
+ * * non si riesce ad aprire l'oggetto zip;
+ * * l'estrazione del file fallisce;
+ * * non si riesce a chiudere l'oggetto zip;
+ */
+QString JlCompress::extractFile(QString fileCompressed, QString fileName, QString fileDest) {
+ // Apro lo zip
+ QuaZip zip(fileCompressed);
+ 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();
+}
+
+/**OK
+ * Estrae i file specificati in files, contenuti nel file fileCompressed, nella
+ * cartella dir. La struttura a cartelle del file compresso viene rispettata.
+ * Se dir = "" allora il file viene estratto nella cartella corrente.
+ * Se la funzione fallisce cancella i file che si e tentato di estrarre.
+ * Restituisce i nomi assoluti dei file estratti.
+ *
+ * La funzione fallisce se:
+ * * non si riesce ad aprire l'oggetto zip;
+ * * l'estrazione di un file fallisce;
+ * * non si riesce a chiudere l'oggetto zip;
+ */
+QStringList JlCompress::extractFiles(QString fileCompressed, QStringList files, QString dir) {
+ // Creo lo zip
+ QuaZip zip(fileCompressed);
+ 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;
+}
+
+/**OK
+ * Estrae il file fileCompressed nella cartella dir.
+ * Se dir = "" allora il file viene estratto nella cartella corrente.
+ * Se la funzione fallisce cancella i file che si e tentato di estrarre.
+ * Restituisce i nomi assoluti dei file estratti.
+ *
+ * La funzione fallisce se:
+ * * non si riesce ad aprire l'oggetto zip;
+ * * la compressione di un file fallisce;
+ * * non si riesce a chiudere l'oggetto zip;
+ */
+QStringList JlCompress::extractDir(QString fileCompressed, QString dir) {
+ // Apro lo zip
+ QuaZip zip(fileCompressed);
+ if(!zip.open(QuaZip::mdUnzip)) {
+ return QStringList();
+ }
+
+ QDir directory(dir);
+ QStringList extracted;
+ if (!zip.goToFirstFile()) {
+ return QStringList();
+ }
+ do {
+ QString name = zip.getCurrentFileName();
+ QString absFilePath = directory.absoluteFilePath(name);
+ 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;
+}
+
+/**OK
+ * Restituisce la lista dei file resenti nel file compresso fileCompressed.
+ * Se la funzione fallisce, restituisce un elenco vuoto.
+ *
+ * La funzione fallisce se:
+ * * non si riesce ad aprire l'oggetto zip;
+ * * la richiesta di informazioni di un file fallisce;
+ * * non si riesce a chiudere l'oggetto zip;
+ */
+QStringList JlCompress::getFileList(QString fileCompressed) {
+ // Apro lo zip
+ QuaZip* zip = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath());
+ if(!zip->open(QuaZip::mdUnzip)) {
+ delete zip;
+ return QStringList();
+ }
+
+ // Estraggo i nomi dei file
+ QStringList lst;
+ QuaZipFileInfo 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;
+}
+