From 4d8f068f9cc576c7d1fb19551cb2429282a7c449 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sun, 12 Apr 2015 22:50:52 +0200 Subject: [PATCH] NOISSUE refactor and rearrange zip file utils --- application/MainWindow.cpp | 92 +------- logic/CMakeLists.txt | 4 +- logic/MMCZip.cpp | 332 +++++++++++++++++++++++++++++ logic/MMCZip.h | 57 +++++ logic/minecraft/JarUtils.cpp | 158 -------------- logic/minecraft/JarUtils.h | 18 -- logic/minecraft/LegacyUpdate.cpp | 5 +- logic/minecraft/OneSixInstance.cpp | 1 + logic/minecraft/OneSixUpdate.cpp | 4 +- quazip.patch | 169 +-------------- 10 files changed, 404 insertions(+), 436 deletions(-) create mode 100644 logic/MMCZip.cpp create mode 100644 logic/MMCZip.h delete mode 100644 logic/minecraft/JarUtils.cpp delete mode 100644 logic/minecraft/JarUtils.h diff --git a/application/MainWindow.cpp b/application/MainWindow.cpp index 5b56ca31..1f6387be 100644 --- a/application/MainWindow.cpp +++ b/application/MainWindow.cpp @@ -323,7 +323,7 @@ namespace Ui { #include #include -#include +#include #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 - -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 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")); } diff --git a/logic/CMakeLists.txt b/logic/CMakeLists.txt index 183991af..e3b52ec5 100644 --- a/logic/CMakeLists.txt +++ b/logic/CMakeLists.txt @@ -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 diff --git a/logic/MMCZip.cpp b/logic/MMCZip.cpp new file mode 100644 index 00000000..e2c6d1f5 --- /dev/null +++ b/logic/MMCZip.cpp @@ -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 . + +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 +#include +#include +#include "MMCZip.h" + +#include + +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& 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 &contained, + std::function 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& 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 addedFiles; + + // Modify the jar + QListIterator 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 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; +} + diff --git a/logic/MMCZip.h b/logic/MMCZip.h new file mode 100644 index 00000000..e1f2ba3a --- /dev/null +++ b/logic/MMCZip.h @@ -0,0 +1,57 @@ +#pragma once + +#include +#include +#include +#include "minecraft/Mod.h" +#include + +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& 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 &contained, std::function filter); + + /** + * take a source jar, add mods to it, resulting in target jar + */ + bool createModdedJar(QString sourceJarPath, QString targetJarPath, const QList& 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()); +} \ No newline at end of file diff --git a/logic/minecraft/JarUtils.cpp b/logic/minecraft/JarUtils.cpp deleted file mode 100644 index b8fb6f0d..00000000 --- a/logic/minecraft/JarUtils.cpp +++ /dev/null @@ -1,158 +0,0 @@ -#include "minecraft/JarUtils.h" -#include -#include -#include -#include - -namespace JarUtils { - -bool mergeZipFiles(QuaZip *into, QFileInfo from, QSet &contained, - std::function 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& 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 addedFiles; - - // Modify the jar - QListIterator 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; -} - -} diff --git a/logic/minecraft/JarUtils.h b/logic/minecraft/JarUtils.h deleted file mode 100644 index 2e8bd2a7..00000000 --- a/logic/minecraft/JarUtils.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once -#include -#include -#include -#include "Mod.h" -#include - -class QuaZip; -namespace JarUtils -{ - bool noFilter(QString); - bool metaInfFilter(QString key); - - bool mergeZipFiles(QuaZip *into, QFileInfo from, QSet &contained, - std::function filter); - - bool createModdedJar(QString sourceJarPath, QString targetJarPath, const QList& mods); -} diff --git a/logic/minecraft/LegacyUpdate.cpp b/logic/minecraft/LegacyUpdate.cpp index e2fffbb3..6c0a4cdf 100644 --- a/logic/minecraft/LegacyUpdate.cpp +++ b/logic/minecraft/LegacyUpdate.cpp @@ -17,14 +17,13 @@ #include #include #include -#include #include #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; diff --git a/logic/minecraft/OneSixInstance.cpp b/logic/minecraft/OneSixInstance.cpp index 7a29c4b4..e9989f2e 100644 --- a/logic/minecraft/OneSixInstance.cpp +++ b/logic/minecraft/OneSixInstance.cpp @@ -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" diff --git a/logic/minecraft/OneSixUpdate.cpp b/logic/minecraft/OneSixUpdate.cpp index 6cea2341..8a7a1f66 100644 --- a/logic/minecraft/OneSixUpdate.cpp +++ b/logic/minecraft/OneSixUpdate.cpp @@ -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; diff --git a/quazip.patch b/quazip.patch index bbd0bb1e..deab6dab 100644 --- a/quazip.patch +++ b/quazip.patch @@ -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 - --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& 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 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& 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}) \ No newline at end of file