Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/jlcompress options #203

Merged
merged 9 commits into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,12 @@ jobs:
strategy:
fail-fast: false
matrix:
macos_version: [11, 12]
macos_version: [14, 13]
qt_version: [5.15.2, 6.6.2]
shared: [ON, OFF]
exclude:
- macos_version: 14
qt_version: 5.15.2 #Not available on macos-14 due to ARM arch

steps:
- name: Checkout
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/qt-zlib.yml
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ jobs:
- name: Run tests
shell: cmd
working-directory: ${{github.workspace}}/build
run: ctest --verbose -C Release
run: ctest --verbose --output-on-failure -C Release

use-qt5-zlib-windows:
if: true
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/doc
/build
/build_release
/build_debug
/lib
*.tags
*.user
Expand Down
3 changes: 2 additions & 1 deletion cmake/windeployqt.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ function(windeployqt target)
add_custom_command(TARGET ${target} POST_BUILD
COMMAND "${_qt_bin_dir}/windeployqt.exe"
--verbose 1
--release
$<$<CONFIG:Debug>:--debug>
$<$<CONFIG:Release>:--release>
--no-plugins
--no-translations
--no-system-d3d-compiler
Expand Down
152 changes: 93 additions & 59 deletions quazip/JlCompress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ see quazip/(un)zip.h files for details. Basically it's the zlib license.
*/

#include "JlCompress.h"
#include <memory>

bool JlCompress::copyData(QIODevice &inFile, QIODevice &outFile)
{
Expand All @@ -39,6 +40,10 @@ bool JlCompress::copyData(QIODevice &inFile, QIODevice &outFile)
}

bool JlCompress::compressFile(QuaZip* zip, QString fileName, QString fileDest) {
return compressFile(zip, fileName, fileDest, Options());
}

bool JlCompress::compressFile(QuaZip* zip, QString fileName, QString fileDest, const Options& options) {
// zip: object where to add the file
// fileName: real file name
// fileDest: file name inside the zip object
Expand All @@ -49,7 +54,12 @@ bool JlCompress::compressFile(QuaZip* zip, QString fileName, QString fileDest) {
zip->getMode()!=QuaZip::mdAdd) return false;

QuaZipFile outFile(zip);
if(!outFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileDest, fileName))) return false;
if (options.getDateTime().isNull()) {
if(!outFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileDest, fileName))) return false;
}
else {
if(!outFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileDest, fileName, options.getDateTime()))) return false;
}

QFileInfo input(fileName);
if (quazip_is_symlink(input)) {
Expand All @@ -74,6 +84,10 @@ bool JlCompress::compressFile(QuaZip* zip, QString fileName, QString fileDest) {
}

bool JlCompress::compressSubDir(QuaZip* zip, QString dir, QString origDir, bool recursive, QDir::Filters filters) {
return compressSubDir(zip, dir, origDir, recursive, filters, Options());
}

bool JlCompress::compressSubDir(QuaZip* zip, QString dir, QString origDir, bool recursive, QDir::Filters filters, const Options& options) {
// zip: object where to add the file
// dir: current real directory
// origDir: original real directory
Expand All @@ -88,14 +102,20 @@ bool JlCompress::compressSubDir(QuaZip* zip, QString dir, QString origDir, bool
if (!directory.exists()) return false;

QDir origDirectory(origDir);
if (dir != origDir) {
QuaZipFile dirZipFile(zip);
if (!dirZipFile.open(QIODevice::WriteOnly,
QuaZipNewInfo(origDirectory.relativeFilePath(dir) + QLatin1String("/"), dir), nullptr, 0, 0)) {
return false;
}
dirZipFile.close();
}
if (dir != origDir) {
QuaZipFile dirZipFile(zip);
std::unique_ptr<QuaZipNewInfo> qzni;
if (options.getDateTime().isNull()) {
qzni = std::make_unique<QuaZipNewInfo>(origDirectory.relativeFilePath(dir) + QLatin1String("/"), dir);
}
else {
qzni = std::make_unique<QuaZipNewInfo>(origDirectory.relativeFilePath(dir) + QLatin1String("/"), dir, options.getDateTime());
}
if (!dirZipFile.open(QIODevice::WriteOnly, *qzni, nullptr, 0, 0)) {
return false;
}
dirZipFile.close();
}

// Whether to compress the subfolders, recursion
if (recursive) {
Expand All @@ -105,7 +125,7 @@ bool JlCompress::compressSubDir(QuaZip* zip, QString dir, QString origDir, bool
if (!file.isDir()) // needed for Qt < 4.7 because it doesn't understand AllDirs
continue;
// Compress subdirectory
if(!compressSubDir(zip,file.absoluteFilePath(),origDir,recursive,filters)) return false;
if(!compressSubDir(zip,file.absoluteFilePath(),origDir,recursive,filters, options)) return false;
}
}

Expand All @@ -119,7 +139,7 @@ bool JlCompress::compressSubDir(QuaZip* zip, QString dir, QString origDir, bool
QString filename = origDirectory.relativeFilePath(file.absoluteFilePath());

// Compress the file
if (!compressFile(zip,file.absoluteFilePath(),filename)) return false;
if (!compressFile(zip,file.absoluteFilePath(),filename, options)) return false;
}

return true;
Expand Down Expand Up @@ -204,6 +224,10 @@ bool JlCompress::removeFile(QStringList listFile) {
}

bool JlCompress::compressFile(QString fileCompressed, QString file) {
return compressFile(fileCompressed, file, JlCompress::Options());
}

bool JlCompress::compressFile(QString fileCompressed, QString file, const Options& options) {
// Create zip
QuaZip zip(fileCompressed);
QDir().mkpath(QFileInfo(fileCompressed).absolutePath());
Expand All @@ -213,7 +237,7 @@ bool JlCompress::compressFile(QString fileCompressed, QString file) {
}

// Add file
if (!compressFile(&zip,file,QFileInfo(file).fileName())) {
if (!compressFile(&zip,file,QFileInfo(file).fileName(), options)) {
QFile::remove(fileCompressed);
return false;
}
Expand All @@ -229,33 +253,37 @@ bool JlCompress::compressFile(QString fileCompressed, QString file) {
}

bool JlCompress::compressFiles(QString fileCompressed, QStringList files) {
// Create zip
QuaZip zip(fileCompressed);
QDir().mkpath(QFileInfo(fileCompressed).absolutePath());
if(!zip.open(QuaZip::mdCreate)) {
QFile::remove(fileCompressed);
return false;
}

// Compress files
QFileInfo info;
for (int index = 0; index < files.size(); ++index ) {
const QString & file( files.at( index ) );
info.setFile(file);
if (!info.exists() || !compressFile(&zip,file,info.fileName())) {
QFile::remove(fileCompressed);
return false;
}
}

// Close zip
zip.close();
if(zip.getZipError()!=0) {
QFile::remove(fileCompressed);
return false;
}
return compressFiles(fileCompressed, files, Options());
}

return true;
bool JlCompress::compressFiles(QString fileCompressed, QStringList files, const Options& options) {
// Create zip
QuaZip zip(fileCompressed);
QDir().mkpath(QFileInfo(fileCompressed).absolutePath());
if(!zip.open(QuaZip::mdCreate)) {
QFile::remove(fileCompressed);
return false;
}

// Compress files
QFileInfo info;
for (int index = 0; index < files.size(); ++index ) {
const QString & file( files.at( index ) );
info.setFile(file);
if (!info.exists() || !compressFile(&zip,file,info.fileName(), options)) {
QFile::remove(fileCompressed);
return false;
}
}

// Close zip
zip.close();
if(zip.getZipError()!=0) {
QFile::remove(fileCompressed);
return false;
}

return true;
}

bool JlCompress::compressDir(QString fileCompressed, QString dir, bool recursive) {
Expand All @@ -265,28 +293,34 @@ bool JlCompress::compressDir(QString fileCompressed, QString dir, bool recursive
bool JlCompress::compressDir(QString fileCompressed, QString dir,
bool recursive, QDir::Filters filters)
{
// Create zip
QuaZip zip(fileCompressed);
QDir().mkpath(QFileInfo(fileCompressed).absolutePath());
if(!zip.open(QuaZip::mdCreate)) {
QFile::remove(fileCompressed);
return false;
}

// Add the files and subdirectories
if (!compressSubDir(&zip,dir,dir,recursive, filters)) {
QFile::remove(fileCompressed);
return false;
}

// Close zip
zip.close();
if(zip.getZipError()!=0) {
QFile::remove(fileCompressed);
return false;
}
return compressDir(fileCompressed, dir, recursive, filters, Options());
}

return true;
bool JlCompress::compressDir(QString fileCompressed, QString dir,
bool recursive, QDir::Filters filters, const Options& options)
{
// Create zip
QuaZip zip(fileCompressed);
QDir().mkpath(QFileInfo(fileCompressed).absolutePath());
if(!zip.open(QuaZip::mdCreate)) {
QFile::remove(fileCompressed);
return false;
}

// Add the files and subdirectories
if (!compressSubDir(&zip,dir,dir,recursive, filters, options)) {
QFile::remove(fileCompressed);
return false;
}

// Close zip
zip.close();
if(zip.getZipError()!=0) {
QFile::remove(fileCompressed);
return false;
}

return true;
}

QString JlCompress::extractFile(QString fileCompressed, QString fileName, QString fileDest) {
Expand Down
78 changes: 78 additions & 0 deletions quazip/JlCompress.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,25 @@ see quazip/(un)zip.h files for details. Basically it's the zlib license.
*/
class QUAZIP_EXPORT JlCompress {
public:
class Options {
public:
explicit Options(const QDateTime& dateTime = QDateTime())
: m_dateTime(dateTime) {}

QDateTime getDateTime() const {
return m_dateTime;
}

void setDateTime(const QDateTime &dateTime) {
m_dateTime = dateTime;
}

private:
// If set, used as last modified on file inside the archive.
// If compressing a directory, used for all files.
QDateTime m_dateTime;
};

static bool copyData(QIODevice &inFile, QIODevice &outFile);
static QStringList extractDir(QuaZip &zip, const QString &dir);
static QStringList getFileList(QuaZip *zip);
Expand All @@ -55,6 +74,15 @@ class QUAZIP_EXPORT JlCompress {
\return true if success, false otherwise.
*/
static bool compressFile(QuaZip* zip, QString fileName, QString fileDest);
/// Compress a single file.
/**
\param zip Opened zip to compress the file to.
\param fileName The full path to the source file.
\param fileDest The full name of the file inside the archive.
\param options Options for fixed file timestamp, compression level, encryption..
\return true if success, false otherwise.
*/
static bool compressFile(QuaZip* zip, QString fileName, QString fileDest, const Options& options);
/// Compress a subdirectory.
/**
\param parentZip Opened zip containing the parent directory.
Expand All @@ -67,6 +95,21 @@ class QUAZIP_EXPORT JlCompress {
*/
static bool compressSubDir(QuaZip* parentZip, QString dir, QString parentDir, bool recursive,
QDir::Filters filters);
/// 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
\param filters what to pack, filters are applied both when searching
* for subdirs (if packing recursively) and when looking for files to pack
\param options Options for fixed file timestamp, compression level, encryption..
files.
\return true if success, false otherwise.
*/
static bool compressSubDir(QuaZip* parentZip, QString dir, QString parentDir, bool recursive,
QDir::Filters filters, const Options& options);
/// Extract a single file.
/**
\param zip The opened zip archive to extract from.
Expand All @@ -89,13 +132,29 @@ class QUAZIP_EXPORT JlCompress {
\return true if success, false otherwise.
*/
static bool compressFile(QString fileCompressed, QString file);
/// Compress a single file with advanced options.
/**
\param fileCompressed The name of the archive.
\param file The file to compress.
\param options Options for fixed file timestamp, compression level, encryption..
\return true if success, false otherwise.
*/
static bool compressFile(QString fileCompressed, QString file, const Options& options);
/// Compress a list of files.
/**
\param fileCompressed The name of the archive.
\param files The file list to compress.
\return true if success, false otherwise.
*/
static bool compressFiles(QString fileCompressed, QStringList files);
/// Compress a list of files.
/**
\param fileCompressed The name of the archive.
\param files The file list to compress.
\param options Options for fixed file timestamp, compression level, encryption..
\return true if success, false otherwise.
*/
static bool compressFiles(QString fileCompressed, QStringList files, const Options& options);
/// Compress a whole directory.
/**
Does not compress hidden files. See compressDir(QString, QString, bool, QDir::Filters).
Expand Down Expand Up @@ -125,6 +184,25 @@ class QUAZIP_EXPORT JlCompress {
*/
static bool compressDir(QString fileCompressed, QString dir,
bool recursive, QDir::Filters filters);
/**
* @brief Compress a whole directory.
*
* Unless filters are specified explicitly, packs
* only regular non-hidden files (and subdirs, if @c recursive is true).
* If filters are specified, they are OR-combined with
* <tt>%QDir::AllDirs|%QDir::NoDotAndDotDot</tt> when searching for dirs
* and with <tt>QDir::Files</tt> when searching for files.
*
* @param fileCompressed path to the resulting archive
* @param dir path to the directory being compressed
* @param recursive if true, then the subdirectories are packed as well
* @param filters what to pack, filters are applied both when searching
* for subdirs (if packing recursively) and when looking for files to pack
* @param options Options for fixed file timestamp, compression level, encryption..
* @return true on success, false otherwise
*/
static bool compressDir(QString fileCompressed, QString dir,
bool recursive, QDir::Filters filters, const Options& options);

/// Extract a single file.
/**
Expand Down
Loading