mirror of https://github.com/AxioDL/metaforce.git
142 lines
3.8 KiB
C++
142 lines
3.8 KiB
C++
#include "ExtractZip.hpp"
|
|
#include <QDir>
|
|
#include <quazip.h>
|
|
#include <quazipfile.h>
|
|
|
|
/**
|
|
* Modified JICompress utilities to operate on in-memory zip.
|
|
* Only contains directory extraction functionality.
|
|
*/
|
|
|
|
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;
|
|
}
|
|
|
|
QStringList ExtractZip::getFileList(QuaZip& zip) {
|
|
// Estraggo i nomi dei file
|
|
QStringList lst;
|
|
QuaZipFileInfo64 info;
|
|
for (bool more = zip.goToFirstFile(); more; more = zip.goToNextFile()) {
|
|
if (!zip.getCurrentFileInfo(&info))
|
|
return {};
|
|
lst << info.name;
|
|
// info.name.toLocal8Bit().constData()
|
|
}
|
|
|
|
return lst;
|
|
}
|
|
|
|
/**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 ExtractZip::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.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(QLatin1Char{'/'})) {
|
|
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(QLatin1Char{'/'}) && 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();
|
|
return false;
|
|
}
|
|
outFile.close();
|
|
|
|
// Chiudo i file
|
|
inFile.close();
|
|
if (inFile.getZipError() != UNZ_OK) {
|
|
return false;
|
|
}
|
|
|
|
if (srcPerm != 0) {
|
|
outFile.setPermissions(srcPerm);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**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;
|
|
*/
|
|
bool ExtractZip::extractDir(QuaZip& zip, QString dir) {
|
|
const QDir directory(dir);
|
|
if (!zip.goToFirstFile()) {
|
|
return false;
|
|
}
|
|
do {
|
|
const QString name = zip.getCurrentFileName();
|
|
const QString absFilePath = directory.absoluteFilePath(name);
|
|
if (!extractFile(zip, {}, absFilePath)) {
|
|
return false;
|
|
}
|
|
} while (zip.goToNextFile());
|
|
|
|
return true;
|
|
}
|