NOISSUE refactor and rearrange zip file utils

This commit is contained in:
Petr Mrázek 2015-04-12 22:50:52 +02:00
parent 1f9dd45e49
commit 4d8f068f9c
10 changed files with 404 additions and 436 deletions

View File

@ -323,7 +323,7 @@ namespace Ui {
#include <QShortcut>
#include <QFileDialog>
#include <JlCompress.h>
#include <MMCZip.h>
#include "osutils.h"
#include "userutils.h"
@ -1095,7 +1095,7 @@ void MainWindow::instanceFromZipPack(QString instName, QString instGroup, QStrin
QTemporaryDir extractTmpDir;
QDir extractDir(extractTmpDir.path());
qDebug() << "Attempting to create instance from" << archivePath;
if (JlCompress::extractDir(archivePath, extractDir.absolutePath()).isEmpty())
if (MMCZip::extractDir(archivePath, extractDir.absolutePath()).isEmpty())
{
CustomMessageBox::selectable(this, tr("Error"),
tr("Failed to extract modpack"), QMessageBox::Warning)->show();
@ -1471,92 +1471,6 @@ void MainWindow::on_actionDeleteInstance_triggered()
}
}
#include <pathutils.h>
bool compressSubDir(QuaZip* zip, QString dir, QString origDir, QString prefix)
{
if (!zip) return false;
if (zip->getMode()!=QuaZip::mdCreate && zip->getMode()!=QuaZip::mdAppend && zip->getMode()!=QuaZip::mdAdd)
{
return false;
}
QDir directory(dir);
if (!directory.exists()) return false;
QDir origDirectory(origDir);
if (dir != origDir)
{
QuaZipFile dirZipFile(zip);
auto dirPrefix = PathCombine(prefix, origDirectory.relativeFilePath(dir)) + "/";
if (!dirZipFile.open(QIODevice::WriteOnly, QuaZipNewInfo(dirPrefix, dir), 0, 0, 0))
{
return false;
}
dirZipFile.close();
}
QFileInfoList files = directory.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Hidden);
for (auto file: files)
{
if(!compressSubDir(zip,file.absoluteFilePath(),origDir, prefix))
{
return false;
}
}
files = directory.entryInfoList(QDir::Files);
for (auto file: files)
{
if(!file.isFile())
{
continue;
}
if(file.absoluteFilePath()==zip->getZipName())
{
continue;
}
QString filename = origDirectory.relativeFilePath(file.absoluteFilePath());
if(prefix.size())
{
filename = PathCombine(prefix, filename);
}
if (!JlCompress::compressFile(zip,file.absoluteFilePath(),filename))
{
return false;
}
}
return true;
}
bool compressDir(QString zipFile, QString dir, QString prefix = QString())
{
QuaZip zip(zipFile);
QDir().mkpath(QFileInfo(zipFile).absolutePath());
if(!zip.open(QuaZip::mdCreate))
{
QFile::remove(zipFile);
return false;
}
QSet<QString> added;
if (!compressSubDir(&zip,dir,dir,prefix))
{
QFile::remove(zipFile);
return false;
}
zip.close();
if(zip.getZipError()!=0)
{
QFile::remove(zipFile);
return false;
}
return true;
}
void MainWindow::on_actionExportInstance_triggered()
{
if (m_selectedInstance)
@ -1580,7 +1494,7 @@ void MainWindow::on_actionExportInstance_triggered()
}
}
if (!compressDir(output, m_selectedInstance->instanceRoot(), name))
if (!MMCZip::compressDir(output, m_selectedInstance->instanceRoot(), name))
{
QMessageBox::warning(this, tr("Error"), tr("Unable to export instance"));
}

View File

@ -15,6 +15,8 @@ SET(LOGIC_SOURCES
BaseInstance.cpp
NullInstance.h
MMCError.h
MMCZip.h
MMCZip.cpp
# WARNING: globals live here
Env.h
@ -101,8 +103,6 @@ SET(LOGIC_SOURCES
minecraft/LwjglVersionList.cpp
minecraft/SkinUtils.h
minecraft/SkinUtils.cpp
minecraft/JarUtils.h
minecraft/JarUtils.cpp
minecraft/GradleSpecifier.h
minecraft/MinecraftProfile.cpp
minecraft/MinecraftProfile.h

332
logic/MMCZip.cpp Normal file
View File

@ -0,0 +1,332 @@
/*
Copyright (C) 2010 Roberto Pompermaier
Copyright (C) 2005-2014 Sergey A. Tachenov
Parts of this file were 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)MMCZip.h files for details. Basically it's the zlib license.
*/
#include <pathutils.h>
#include <quazip.h>
#include <JlCompress.h>
#include "MMCZip.h"
#include <QDebug>
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 MMCZip::extractDir(QString fileCompressed, QString dir)
{
return JlCompress::extractDir(fileCompressed, dir);
}
bool compressFile(QuaZip *zip, QString fileName, QString fileDest)
{
if (!zip)
{
return false;
}
if (zip->getMode() != QuaZip::mdCreate && zip->getMode() != QuaZip::mdAppend &&
zip->getMode() != QuaZip::mdAdd)
{
return false;
}
QFile inFile;
inFile.setFileName(fileName);
if (!inFile.open(QIODevice::ReadOnly))
{
return false;
}
QuaZipFile outFile(zip);
if (!outFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileDest, inFile.fileName())))
{
return false;
}
if (!copyData(inFile, outFile) || outFile.getZipError() != UNZ_OK)
{
return false;
}
outFile.close();
if (outFile.getZipError() != UNZ_OK)
{
return false;
}
inFile.close();
return true;
}
bool MMCZip::compressSubDir(QuaZip* zip, QString dir, QString origDir, QSet<QString>& added, QString prefix)
{
if (!zip) return false;
if (zip->getMode()!=QuaZip::mdCreate && zip->getMode()!=QuaZip::mdAppend && zip->getMode()!=QuaZip::mdAdd)
{
return false;
}
QDir directory(dir);
if (!directory.exists())
{
return false;
}
QDir origDirectory(origDir);
if (dir != origDir)
{
QuaZipFile dirZipFile(zip);
auto dirPrefix = PathCombine(prefix, origDirectory.relativeFilePath(dir)) + "/";
if (!dirZipFile.open(QIODevice::WriteOnly, QuaZipNewInfo(dirPrefix, dir), 0, 0, 0))
{
return false;
}
dirZipFile.close();
}
QFileInfoList files = directory.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Hidden);
for (auto file: files)
{
if(!file.isDir())
{
continue;
}
if(!compressSubDir(zip,file.absoluteFilePath(),origDir, added, prefix))
{
return false;
}
}
files = directory.entryInfoList(QDir::Files);
for (auto file: files)
{
if(!file.isFile())
{
continue;
}
if(file.absoluteFilePath()==zip->getZipName())
{
continue;
}
QString filename = origDirectory.relativeFilePath(file.absoluteFilePath());
if(prefix.size())
{
filename = PathCombine(prefix, filename);
}
added.insert(filename);
if (!compressFile(zip,file.absoluteFilePath(),filename))
{
return false;
}
}
return true;
}
bool MMCZip::mergeZipFiles(QuaZip *into, QFileInfo from, QSet<QString> &contained,
std::function<bool(QString)> filter)
{
QuaZip modZip(from.filePath());
modZip.open(QuaZip::mdUnzip);
QuaZipFile fileInsideMod(&modZip);
QuaZipFile zipOutFile(into);
for (bool more = modZip.goToFirstFile(); more; more = modZip.goToNextFile())
{
QString filename = modZip.getCurrentFileName();
if (!filter(filename))
{
qDebug() << "Skipping file " << filename << " from "
<< from.fileName() << " - filtered";
continue;
}
if (contained.contains(filename))
{
qDebug() << "Skipping already contained file " << filename << " from "
<< from.fileName();
continue;
}
contained.insert(filename);
if (!fileInsideMod.open(QIODevice::ReadOnly))
{
qCritical() << "Failed to open " << filename << " from " << from.fileName();
return false;
}
QuaZipNewInfo info_out(fileInsideMod.getActualFileName());
if (!zipOutFile.open(QIODevice::WriteOnly, info_out))
{
qCritical() << "Failed to open " << filename << " in the jar";
fileInsideMod.close();
return false;
}
if (!copyData(fileInsideMod, zipOutFile))
{
zipOutFile.close();
fileInsideMod.close();
qCritical() << "Failed to copy data of " << filename << " into the jar";
return false;
}
zipOutFile.close();
fileInsideMod.close();
}
return true;
}
bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const QList<Mod>& mods)
{
QuaZip zipOut(targetJarPath);
if (!zipOut.open(QuaZip::mdCreate))
{
QFile::remove(targetJarPath);
qCritical() << "Failed to open the minecraft.jar for modding";
return false;
}
// Files already added to the jar.
// These files will be skipped.
QSet<QString> addedFiles;
// Modify the jar
QListIterator<Mod> i(mods);
i.toBack();
while (i.hasPrevious())
{
const Mod &mod = i.previous();
// do not merge disabled mods.
if (!mod.enabled())
continue;
if (mod.type() == Mod::MOD_ZIPFILE)
{
if (!mergeZipFiles(&zipOut, mod.filename(), addedFiles, noFilter))
{
zipOut.close();
QFile::remove(targetJarPath);
qCritical() << "Failed to add" << mod.filename().fileName() << "to the jar.";
return false;
}
}
else if (mod.type() == Mod::MOD_SINGLEFILE)
{
auto filename = mod.filename();
if (!compressFile(&zipOut, filename.absoluteFilePath(),
filename.fileName()))
{
zipOut.close();
QFile::remove(targetJarPath);
qCritical() << "Failed to add" << mod.filename().fileName() << "to the jar.";
return false;
}
addedFiles.insert(filename.fileName());
}
else if (mod.type() == Mod::MOD_FOLDER)
{
auto filename = mod.filename();
QString what_to_zip = filename.absoluteFilePath();
QDir dir(what_to_zip);
dir.cdUp();
QString parent_dir = dir.absolutePath();
if (!compressSubDir(&zipOut, what_to_zip, parent_dir, addedFiles))
{
zipOut.close();
QFile::remove(targetJarPath);
qCritical() << "Failed to add" << mod.filename().fileName() << "to the jar.";
return false;
}
qDebug() << "Adding folder " << filename.fileName() << " from "
<< filename.absoluteFilePath();
}
}
if (!mergeZipFiles(&zipOut, QFileInfo(sourceJarPath), addedFiles, metaInfFilter))
{
zipOut.close();
QFile::remove(targetJarPath);
qCritical() << "Failed to insert minecraft.jar contents.";
return false;
}
// Recompress the jar
zipOut.close();
if (zipOut.getZipError() != 0)
{
QFile::remove(targetJarPath);
qCritical() << "Failed to finalize minecraft.jar!";
return false;
}
return true;
}
bool MMCZip::noFilter(QString)
{
return true;
}
bool MMCZip::metaInfFilter(QString key)
{
if(key.contains("META-INF"))
{
return false;
}
return true;
}
bool MMCZip::compressDir(QString zipFile, QString dir, QString prefix)
{
QuaZip zip(zipFile);
QDir().mkpath(QFileInfo(zipFile).absolutePath());
if(!zip.open(QuaZip::mdCreate))
{
QFile::remove(zipFile);
return false;
}
QSet<QString> added;
if (!compressSubDir(&zip, dir, dir, added, prefix))
{
QFile::remove(zipFile);
return false;
}
zip.close();
if(zip.getZipError()!=0)
{
QFile::remove(zipFile);
return false;
}
return true;
}

57
logic/MMCZip.h Normal file
View File

@ -0,0 +1,57 @@
#pragma once
#include <QString>
#include <QFileInfo>
#include <QSet>
#include "minecraft/Mod.h"
#include <functional>
class QuaZip;
namespace MMCZip
{
/**
* Compress a subdirectory.
* \param parentZip Opened zip containing the parent directory.
* \param dir The full path to the directory to pack.
* \param parentDir The full path to the directory corresponding to the root of the ZIP.
* \param recursive Whether to pack sub-directories as well or only files.
* \return true if success, false otherwise.
*/
bool compressSubDir(QuaZip* zip, QString dir, QString origDir, QSet<QString>& added, QString prefix = QString());
/**
* Compress a whole directory.
* \param fileCompressed The name of the archive.
* \param dir The directory to compress.
* \param recursive Whether to pack the subdirectories as well, or just regular files.
* \return true if success, false otherwise.
*/
bool compressDir(QString zipFile, QString dir, QString prefix = QString());
/// filter function for @mergeZipFiles - passthrough
bool noFilter(QString key);
/// filter function for @mergeZipFiles - ignores METAINF
bool metaInfFilter(QString key);
/**
* Merge two zip files, using a filter function
*/
bool mergeZipFiles(QuaZip *into, QFileInfo from, QSet<QString> &contained, std::function<bool(QString)> filter);
/**
* take a source jar, add mods to it, resulting in target jar
*/
bool createModdedJar(QString sourceJarPath, QString targetJarPath, const QList<Mod>& mods);
/**
* Extract a whole archive.
*
* \param fileCompressed The name of the archive.
* \param dir The directory to extract to, the current directory if
* left empty.
* \return The list of the full paths of the files extracted, empty on failure.
*/
QStringList extractDir(QString fileCompressed, QString dir = QString());
}

View File

@ -1,158 +0,0 @@
#include "minecraft/JarUtils.h"
#include <quazip.h>
#include <quazipfile.h>
#include <JlCompress.h>
#include <QDebug>
namespace JarUtils {
bool mergeZipFiles(QuaZip *into, QFileInfo from, QSet<QString> &contained,
std::function<bool(QString)> filter)
{
QuaZip modZip(from.filePath());
modZip.open(QuaZip::mdUnzip);
QuaZipFile fileInsideMod(&modZip);
QuaZipFile zipOutFile(into);
for (bool more = modZip.goToFirstFile(); more; more = modZip.goToNextFile())
{
QString filename = modZip.getCurrentFileName();
if (!filter(filename))
{
qDebug() << "Skipping file " << filename << " from "
<< from.fileName() << " - filtered";
continue;
}
if (contained.contains(filename))
{
qDebug() << "Skipping already contained file " << filename << " from "
<< from.fileName();
continue;
}
contained.insert(filename);
if (!fileInsideMod.open(QIODevice::ReadOnly))
{
qCritical() << "Failed to open " << filename << " from " << from.fileName();
return false;
}
QuaZipNewInfo info_out(fileInsideMod.getActualFileName());
if (!zipOutFile.open(QIODevice::WriteOnly, info_out))
{
qCritical() << "Failed to open " << filename << " in the jar";
fileInsideMod.close();
return false;
}
if (!JlCompress::copyData(fileInsideMod, zipOutFile))
{
zipOutFile.close();
fileInsideMod.close();
qCritical() << "Failed to copy data of " << filename << " into the jar";
return false;
}
zipOutFile.close();
fileInsideMod.close();
}
return true;
}
bool createModdedJar(QString sourceJarPath, QString targetJarPath, const QList<Mod>& mods)
{
QuaZip zipOut(targetJarPath);
if (!zipOut.open(QuaZip::mdCreate))
{
QFile::remove(targetJarPath);
qCritical() << "Failed to open the minecraft.jar for modding";
return false;
}
// Files already added to the jar.
// These files will be skipped.
QSet<QString> addedFiles;
// Modify the jar
QListIterator<Mod> i(mods);
i.toBack();
while (i.hasPrevious())
{
const Mod &mod = i.previous();
// do not merge disabled mods.
if (!mod.enabled())
continue;
if (mod.type() == Mod::MOD_ZIPFILE)
{
if (!mergeZipFiles(&zipOut, mod.filename(), addedFiles, noFilter))
{
zipOut.close();
QFile::remove(targetJarPath);
qCritical() << "Failed to add" << mod.filename().fileName() << "to the jar.";
return false;
}
}
else if (mod.type() == Mod::MOD_SINGLEFILE)
{
auto filename = mod.filename();
if (!JlCompress::compressFile(&zipOut, filename.absoluteFilePath(),
filename.fileName()))
{
zipOut.close();
QFile::remove(targetJarPath);
qCritical() << "Failed to add" << mod.filename().fileName() << "to the jar.";
return false;
}
addedFiles.insert(filename.fileName());
}
else if (mod.type() == Mod::MOD_FOLDER)
{
auto filename = mod.filename();
QString what_to_zip = filename.absoluteFilePath();
QDir dir(what_to_zip);
dir.cdUp();
QString parent_dir = dir.absolutePath();
if (!JlCompress::compressSubDir(&zipOut, what_to_zip, parent_dir, true, addedFiles))
{
zipOut.close();
QFile::remove(targetJarPath);
qCritical() << "Failed to add" << mod.filename().fileName() << "to the jar.";
return false;
}
qDebug() << "Adding folder " << filename.fileName() << " from "
<< filename.absoluteFilePath();
}
}
if (!mergeZipFiles(&zipOut, QFileInfo(sourceJarPath), addedFiles, metaInfFilter))
{
zipOut.close();
QFile::remove(targetJarPath);
qCritical() << "Failed to insert minecraft.jar contents.";
return false;
}
// Recompress the jar
zipOut.close();
if (zipOut.getZipError() != 0)
{
QFile::remove(targetJarPath);
qCritical() << "Failed to finalize minecraft.jar!";
return false;
}
return true;
}
bool noFilter(QString)
{
return true;
}
bool metaInfFilter(QString key)
{
if(key.contains("META-INF"))
{
return false;
}
return true;
}
}

View File

@ -1,18 +0,0 @@
#pragma once
#include <QString>
#include <QFileInfo>
#include <QSet>
#include "Mod.h"
#include <functional>
class QuaZip;
namespace JarUtils
{
bool noFilter(QString);
bool metaInfFilter(QString key);
bool mergeZipFiles(QuaZip *into, QFileInfo from, QSet<QString> &contained,
std::function<bool(QString)> filter);
bool createModdedJar(QString sourceJarPath, QString targetJarPath, const QList<Mod>& mods);
}

View File

@ -17,14 +17,13 @@
#include <pathutils.h>
#include <quazip.h>
#include <quazipfile.h>
#include <JlCompress.h>
#include <QDebug>
#include "Env.h"
#include "BaseInstance.h"
#include "net/URLConstants.h"
#include "MMCZip.h"
#include "minecraft/JarUtils.h"
#include "minecraft/LegacyUpdate.h"
#include "minecraft/LwjglVersionList.h"
#include "minecraft/MinecraftVersionList.h"
@ -455,7 +454,7 @@ void LegacyUpdate::ModTheJar()
QString outputJarPath = runnableJar.filePath();
QString inputJarPath = baseJar.filePath();
if(!JarUtils::createModdedJar(inputJarPath, outputJarPath, modList))
if(!MMCZip::createModdedJar(inputJarPath, outputJarPath, modList))
{
emitFailed(tr("Failed to create the custom Minecraft jar file."));
return;

View File

@ -25,6 +25,7 @@
#include "minecraft/VersionBuildError.h"
#include "minecraft/MinecraftProcess.h"
#include "minecraft/OneSixProfileStrategy.h"
#include "MMCZip.h"
#include "minecraft/AssetsUtils.h"
#include "icons/IconList.h"

View File

@ -33,7 +33,7 @@
#include "forge/ForgeMirrors.h"
#include "net/URLConstants.h"
#include "minecraft/AssetsUtils.h"
#include "minecraft/JarUtils.h"
#include "MMCZip.h"
OneSixUpdate::OneSixUpdate(OneSixInstance *inst, QObject *parent) : Task(parent), m_inst(inst)
{
@ -320,7 +320,7 @@ void OneSixUpdate::jarlibFinished()
auto metacache = ENV.metacache();
auto entry = metacache->resolveEntry("versions", localPath);
QString fullJarPath = entry->getFullPath();
if(!JarUtils::createModdedJar(sourceJarPath, finalJarPath, jarMods))
if(!MMCZip::createModdedJar(sourceJarPath, finalJarPath, jarMods))
{
emitFailed(tr("Failed to create the custom Minecraft jar file."));
return;

View File

@ -3,9 +3,9 @@ Index: CMakeLists.txt
--- CMakeLists.txt (revision 250)
+++ CMakeLists.txt (working copy)
@@ -51,4 +51,4 @@
add_subdirectory(quazip)
-install(FILES FindQuaZip.cmake DESTINATION ${CMAKE_ROOT}/Modules)
+#install(FILES FindQuaZip.cmake DESTINATION ${CMAKE_ROOT}/Modules)
Index: quazip/CMakeLists.txt
@ -15,7 +15,7 @@ Index: quazip/CMakeLists.txt
@@ -14,10 +14,14 @@
qt_wrap_cpp(MOC_SRCS ${PUBLIC_HEADERS})
set(SRCS ${SRCS} ${MOC_SRCS})
-add_library(quazip SHARED ${SRCS})
-set_target_properties(quazip PROPERTIES VERSION 1.0.0 SOVERSION 1)
+add_library(quazip STATIC ${SRCS})
@ -27,165 +27,6 @@ Index: quazip/CMakeLists.txt
+if(WIN32)
+ add_definitions(-DZ_PREFIX)
+endif()
install(FILES ${PUBLIC_HEADERS} DESTINATION include/quazip)
install(TARGETS quazip LIBRARY DESTINATION ${LIB_DESTINATION} ARCHIVE DESTINATION ${LIB_DESTINATION} RUNTIME DESTINATION ${LIB_DESTINATION})
Index: quazip/JlCompress.cpp
===================================================================
--- quazip/JlCompress.cpp (revision 250)
+++ quazip/JlCompress.cpp (working copy)
@@ -26,7 +26,7 @@
#include "JlCompress.h"
#include <QDebug>
-static bool copyData(QIODevice &inFile, QIODevice &outFile)
+bool JlCompress::copyData(QIODevice &inFile, QIODevice &outFile)
{
while (!inFile.atEnd()) {
char buf[4096];
@@ -100,7 +100,7 @@
* 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) {
+bool JlCompress::compressSubDir(QuaZip* zip, QString dir, QString origDir, bool recursive, QSet<QString>& added) {
// zip: oggetto dove aggiungere il file
// dir: cartella reale corrente
// origDir: cartella reale originale
@@ -133,7 +133,7 @@
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;
+ if(!compressSubDir(zip,file.absoluteFilePath(),origDir,recursive,added)) return false;
}
}
@@ -148,6 +148,7 @@
// Comprimo il file
if (!compressFile(zip,file.absoluteFilePath(),filename)) return false;
+ added.insert(filename);
}
return true;
@@ -344,8 +345,9 @@
return false;
}
+ QSet<QString> added;
// Aggiungo i file e le sotto cartelle
- if (!compressSubDir(&zip,dir,dir,recursive)) {
+ if (!compressSubDir(&zip,dir,dir,recursive,added)) {
QFile::remove(fileCompressed);
return false;
}
@@ -437,6 +439,53 @@
return extracted;
}
+QStringList JlCompress::extractWithExceptions(QString fileCompressed, QString dir, QStringList exceptions)
+{
+ 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();
+ bool ok = true;
+ for(auto str: exceptions)
+ {
+ if(name.startsWith(str))
+ {
+ ok = false;
+ break;
+ }
+ }
+ if(!ok)
+ continue;
+ QString absFilePath = directory.absoluteFilePath(name);
+ if (!JlCompress::extractFile(&zip, "", absFilePath))
+ {
+ JlCompress::removeFile(extracted);
+ return QStringList();
+ }
+ extracted.append(absFilePath);
+ } while (zip.goToNextFile());
+
+ zip.close();
+ if(zip.getZipError()!=0)
+ {
+ JlCompress::removeFile(extracted);
+ return QStringList();
+ }
+
+ return extracted;
+}
+
/**OK
* Estrae il file fileCompressed nella cartella dir.
* Se dir = "" allora il file viene estratto nella cartella corrente.
Index: quazip/JlCompress.h
===================================================================
--- quazip/JlCompress.h (revision 250)
+++ quazip/JlCompress.h (working copy)
@@ -40,7 +40,7 @@
simple operations, such as mass ZIP packing or extraction.
*/
class QUAZIP_EXPORT JlCompress {
-private:
+public:
/// Compress a single file.
/**
\param zip Opened zip to compress the file to.
@@ -59,7 +59,7 @@
files.
\return true if success, false otherwise.
*/
- static bool compressSubDir(QuaZip* parentZip, QString dir, QString parentDir, bool recursive = true);
+ static bool compressSubDir(QuaZip* parentZip, QString dir, QString parentDir, bool recursive, QSet<QString>& added);
/// Extract a single file.
/**
\param zip The opened zip archive to extract from.
@@ -68,6 +68,7 @@
\return true if success, false otherwise.
*/
static bool extractFile(QuaZip* zip, QString fileName, QString fileDest);
+private:
/// Remove some files.
/**
\param listFile The list of files to remove.
@@ -76,6 +77,8 @@
static bool removeFile(QStringList listFile);
public:
+ /// copy data from inFile to outFile
+ static bool copyData(QIODevice &inFile, QIODevice &outFile);
/// Compress a single file.
/**
\param fileCompressed The name of the archive.
@@ -127,6 +130,15 @@
\return The list of the full paths of the files extracted, empty on failure.
*/
static QStringList extractDir(QString fileCompressed, QString dir = QString());
+ /// Extract a whole archive, with a list of exceptions (prefixes to ignore).
+ /**
+ \param fileCompressed The name of the archive.
+ \param dir The directory to extract to, the current directory if
+ left empty.
+ \param exceptions The list of exception prefixes
+ \return The list of the full paths of the files extracted, empty on failure.
+ */
+ static QStringList extractWithExceptions(QString fileCompressed, QString dir, QStringList exceptions);
/// Get the file list.
/**
\return The list of the files in the archive, or, more precisely, the
install(TARGETS quazip LIBRARY DESTINATION ${LIB_DESTINATION} ARCHIVE DESTINATION ${LIB_DESTINATION} RUNTIME DESTINATION ${LIB_DESTINATION})