#include "ExtractZip.hpp" #include #include #include /** * 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; }