Skip to content

Commit

Permalink
add options to dir jl methods
Browse files Browse the repository at this point in the history
  • Loading branch information
cen1 committed Sep 29, 2024
1 parent 0f1f281 commit 8548c7e
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 59 deletions.
136 changes: 78 additions & 58 deletions quazip/JlCompress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ bool JlCompress::copyData(QIODevice &inFile, QIODevice &outFile)
}

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

bool JlCompress::compressFile(QuaZip* zip, QString fileName, QString fileDest, const Options& options) {
Expand Down Expand Up @@ -83,6 +83,10 @@ bool JlCompress::compressFile(QuaZip* zip, QString fileName, QString fileDest, c
}

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 @@ -97,14 +101,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.dateTime().isNull()) {
qzni = std::make_unique<QuaZipNewInfo>(origDirectory.relativeFilePath(dir) + QLatin1String("/"), dir);
}
else {
qzni = std::make_unique<QuaZipNewInfo>(origDirectory.relativeFilePath(dir) + QLatin1String("/"), dir, options.dateTime());
}
if (!dirZipFile.open(QIODevice::WriteOnly, *qzni, nullptr, 0, 0)) {
return false;
}
dirZipFile.close();
}

// Whether to compress the subfolders, recursion
if (recursive) {
Expand All @@ -114,7 +124,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 @@ -128,7 +138,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 @@ -242,33 +252,37 @@ bool JlCompress::compressFile(QString fileCompressed, QString file, const Option
}

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 @@ -278,28 +292,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
39 changes: 39 additions & 0 deletions quazip/JlCompress.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,18 @@ 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
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 Down Expand Up @@ -132,6 +144,14 @@ class QUAZIP_EXPORT JlCompress {
\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 Additional options such as fixed last modified time, encryption (tbd)
\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 @@ -161,6 +181,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 Additional options such as fixed last modified time, encryption (tbd)
* @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
2 changes: 1 addition & 1 deletion quazip/quazipnewinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ struct QUAZIP_EXPORT QuaZipNewInfo {
* is inaccessible (e. g. you do not have read permission for the
* directory file in), uses current time and zero permissions. Other attributes are
* initialized with zeros, comment and extra field with null values.
*
*
* \sa setFileDateTime()
**/
QuaZipNewInfo(const QString& name, const QString& file);
Expand Down
60 changes: 60 additions & 0 deletions qztest/testjlcompress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,66 @@ void TestJlCompress::compressDir()
curDir.remove(zipName);
}

void TestJlCompress::compressDirOptions_data()
{
QTest::addColumn<QString>("zipName");
QTest::addColumn<QStringList>("fileNames");
QTest::addColumn<QStringList>("expected");
QTest::addColumn<QDateTime>("dateTime");
QTest::addColumn<QString>("sha256sum");
QTest::newRow("simple") << "jldir.zip"
<< (QStringList() << "test0.txt" << "testdir1/test1.txt"
<< "testdir2/test2.txt" << "testdir2/subdir/test2sub.txt")
<< (QStringList() << "test0.txt"
<< "testdir1/" << "testdir1/test1.txt"
<< "testdir2/" << "testdir2/test2.txt"
<< "testdir2/subdir/" << "testdir2/subdir/test2sub.txt")
<< QDateTime(QDate(2024, 9, 19), QTime(21, 0, 0), QTimeZone::utc())
<< "ed0d5921b2fc11b6b4cb214b3e43ea3ea28987d6ff8080faab54c4756de30af6";
}

void TestJlCompress::compressDirOptions()
{
QFETCH(QString, zipName);
QFETCH(QStringList, fileNames);
QFETCH(QStringList, expected);
QFETCH(QDateTime, dateTime);
QFETCH(QString, sha256sum);
QDir curDir;
if (curDir.exists(zipName)) {
if (!curDir.remove(zipName))
QFAIL("Can't remove zip file");
}
if (!createTestFiles(fileNames, -1, "compressDir_tmp")) {
QFAIL("Can't create test files");
}
#ifdef Q_OS_WIN
for (int i = 0; i < fileNames.size(); ++i) {
if (fileNames.at(i).startsWith(".")) {
QString fn = "compressDir_tmp\\" + fileNames.at(i);
SetFileAttributesW(reinterpret_cast<LPCWSTR>(fn.utf16()),
FILE_ATTRIBUTE_HIDDEN);
}
}
#endif
const JlCompress::Options options(dateTime);
QVERIFY(JlCompress::compressDir(zipName, "compressDir_tmp", true, QDir::Hidden, options));
// get the file list and check it
QStringList fileList = JlCompress::getFileList(zipName);
fileList.sort();
expected.sort();
QCOMPARE(fileList, expected);
QFile zipFile(curDir.absoluteFilePath(zipName));
if (!zipFile.open(QIODevice::ReadOnly)) {
QFAIL("Can't read output zip file");
}
QString hash = QCryptographicHash::hash(zipFile.readAll(), QCryptographicHash::Sha256).toHex();
QCOMPARE(sha256sum, hash);
zipFile.close();
removeTestFiles(fileNames, "compressDir_tmp");
curDir.remove(zipName);
}

void TestJlCompress::extractFile_data()
{
QTest::addColumn<QString>("zipName");
Expand Down
2 changes: 2 additions & 0 deletions qztest/testjlcompress.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ private slots:
void compressFiles();
void compressDir_data();
void compressDir();
void compressDirOptions_data();
void compressDirOptions();
void extractFile_data();
void extractFile();
void extractFiles_data();
Expand Down

0 comments on commit 8548c7e

Please sign in to comment.