Update quazip

This commit is contained in:
Phillip Stephens 2021-02-20 14:56:24 -08:00
parent 76966831b0
commit b52742b407
13 changed files with 2969 additions and 31 deletions

View File

@ -9,6 +9,7 @@ set(QUAZIP_LIB_VERSION ${QuaZip_VERSION})
set(QUAZIP_LIB_SOVERSION 1.0.0)
option(BUILD_SHARED_LIBS "" ON)
option(QUAZIP_INSTALL "" ON)
set(QUAZIP_QT_MAJOR_VERSION 5 CACHE STRING "Qt version to use (4 or 5), defaults to 5")
if(NOT CMAKE_BUILD_TYPE)
@ -30,7 +31,7 @@ set(QUAZIP_ENABLE_TESTS OFF)
if(QUAZIP_QT_MAJOR_VERSION EQUAL 6)
find_package(Qt6 REQUIRED COMPONENTS Core Core5Compat
OPTIONAL_COMPONENTS Network Test)
set(QUAZIP_LIB_QT_LIBRARIES Qt6::Core Qt6::Core5Compat)
set(QUAZIP_LIB_LIBRARIES Qt6::Core Qt6::Core5Compat)
set(QUAZIP_TEST_QT_LIBRARIES Qt6::Core Qt6::Core5Compat Qt6::Network Qt6::Test)
set(QUAZIP_PKGCONFIG_REQUIRES Qt6Core)
if (Qt6Network_FOUND AND Qt6Test_FOUND)
@ -39,7 +40,7 @@ if(QUAZIP_QT_MAJOR_VERSION EQUAL 6)
elseif(QUAZIP_QT_MAJOR_VERSION EQUAL 5)
find_package(Qt5 REQUIRED COMPONENTS Core
OPTIONAL_COMPONENTS Network Test)
set(QUAZIP_LIB_QT_LIBRARIES Qt5::Core)
set(QUAZIP_LIB_LIBRARIES Qt5::Core)
set(QUAZIP_TEST_QT_LIBRARIES Qt5::Core Qt5::Network Qt5::Test)
set(QUAZIP_PKGCONFIG_REQUIRES Qt5Core)
if (Qt5Network_FOUND AND Qt5Test_FOUND)
@ -48,7 +49,7 @@ elseif(QUAZIP_QT_MAJOR_VERSION EQUAL 5)
elseif(QUAZIP_QT_MAJOR_VERSION EQUAL 4)
find_package(Qt4 4.5.0 REQUIRED COMPONENTS QtCore
OPTIONAL_COMPONENTS QtNetwork QtTest)
set(QUAZIP_LIB_QT_LIBRARIES Qt4::QtCore)
set(QUAZIP_LIB_LIBRARIES Qt4::QtCore)
set(QUAZIP_TEST_QT_LIBRARIES Qt4::QtCore Qt4::QtNetwork Qt4::QtTest)
set(QUAZIP_PKGCONFIG_REQUIRES QtCore)
if (QT_QTNETWORK_FOUND AND QT_QTTEST_FOUND)
@ -58,7 +59,13 @@ else()
message(FATAL_ERROR "Qt version ${QUAZIP_QT_MAJOR_VERSION} is not supported")
endif()
find_package(ZLIB REQUIRED)
find_package(Qt${QUAZIP_QT_MAJOR_VERSION} OPTIONAL_COMPONENTS Zlib)
if (Qt${QUAZIP_QT_MAJOR_VERSION}Zlib_FOUND)
set(QUAZIP_LIB_LIBRARIES ${QUAZIP_LIB_LIBRARIES} Qt${QUAZIP_QT_MAJOR_VERSION}::Zlib)
else()
find_package(ZLIB REQUIRED)
set(QUAZIP_LIB_LIBRARIES ${QUAZIP_LIB_LIBRARIES} ZLIB::ZLIB)
endif()
add_subdirectory(quazip)

View File

@ -0,0 +1,56 @@
Fixed a bug? Implemented a new feature? Want to have it included in QuaZip?
Here's what you need to do.
0. If you don't have a GitHub account, create one. It's ridiculously easy.
1. First, open an [issue](https://github.com/stachenov/quazip/issues).
Even if you have already fixed it. It helps to track things because
instead of a commit saying “fixed this and that” you have a reference
to a full issue description.
2. Next, figure out the right branch to work on. *Usually* it's `master`,
but sometimes it's something different. For example, there was time
when new features went to `pre1.0`, and `master` was for 0.x bugfixes only.
3. Next, send a PR (pull request). There are numerous articles how to do it,
but it's not exactly intuitive, just like anything with Git, so do
some research before attempting to create a PR.
**Contribution guidelines**
To avoid spending time on something that may never be accepted, here are
some guidelines.
1. Changes should be backwards-compatible. Don't just change method names
and their signatures randomly. Don't just remove deprecated features—some
of them are there to keep compatibility with old Qt versions. Even Qt 4 is
still supported! Unless you're working on some sort of `pre2.0` branch
or something like that, you should keep ABI compatibility as well! Meaning,
no adding virtual functions, no changing parameter types, even if it's
a source-compatible change, and a lot of other things, really.
2. If your change targets some new version of Qt, it's a very good idea
to keep various `#ifs` in `quazip_qt_compat.h`, which exists for this very
purpose. Don't just throw them into the code. Don't just replace deprecated
things with their newer alternatives—it would break support of the old
Qt versions.
3. If your changes aren't limited to a small fix or a convenience method,
discussing them in the issue you just opened (if you didn't, do!) could
help to achieve some agreement on what exactly is a good idea in your case.
4. Whether you're fixing a bug or adding a new feature, it's an awesome idea
to add a new test in the `qztest` subproject. This way you make sure the
bug stays fixed and the feature keeps working. This is *not* a mandatory
requirement, however, because adding tests to a project you're not familiar
with can be challenging, and it should not stop you from sending a PR.
5. It would be nice if you also update NEWS.txt with whatever changes
you propose. Just add another line on top.
6. QuaZip doesn't really have any policies on PR commits. Just use common sense.
Generally, it's better to keep separate things separate. If you made 2 changes,
and there are 6 commits for one change and 4 for another, that's OK.
Don't squash commits just to squash them. If your branch gets outdated before PR
is accepted, merge or rebase—it doesn't really mater, as long as there are no
conflicts.

2553
hecl-gui/quazip/Doxyfile Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,9 @@
QuaZip changes
* Current
* Add CMake option to disable installation (Sebastian Rettenberger)
* Use Qt's internal zlib instead of an external one if available
* 2020-10-11 1.1
* Fixed Unix symlink handling in JlCompress compression
* Implemented Unix symlink handling in JlCompress extraction

View File

@ -0,0 +1,93 @@
**QuaZip 0.x -> 1.x migration guide**
This guide contains important information mostly for package
maintainers, although it can also be useful for developers
as well.
**TL;DR**
QuaZip 1.0 is supposed to be installed in parallel with 0.x,
**not** replace 0.x. Package maintainers should keep it in mind.
The developers should switch to 1.0 in their new releases if
they use CMake and/or want new features (although there are only few).
**What happened in 1.0**
QuaZip 1.0 introduced some important changes:
- modern CMake support was introduced;
- include paths and binary names were changed;
- qmake support was ditched completely.
This change was intended, thoroughly discussed and planned.
The reasons for this change were:
- CMake support was a mess because at that time I didn't understand
it at all, and was just blindly accepted all CMake-related PRs and
patches, which lead to numerous inconsistencies between qmake and CMake
builds;
- maintaining both qmake and CMake support in a consistent manner
would be next to impossible, as CMake installs some metadata
that is very useful, and there is no easy way to generate
it with qmake;
- old CMake style is a mess in itself, while modern CMake, even if
not at all easy to learn, at least leads to consistent, clean
and easy to use (for the users of the library) configuration
files.
It was thus impossible to make 1.0 a drop-in replacement for 0.x.
Specifically, since 0.x has this qmake/CMake inconsistency
(that even changed between versions in an unreasonable manner),
it wouldn't be possible to make 1.0 both consistent and 0.x-compatible.
Consistency was chosen over compatibility.
To avoid possible conflicts with 0.x, however, it was decided to make
1.0 co-installable with 0.x, by using different include paths and binary
names. Binary names had to be changed anyway because they were inconsistent
for qmake and CMake, and made no sense at all.
**The differences**
QuaZip 0.x uses this “scheme”:
- the includes went either to `include/quazip` or `include/quazip5`
depending both on qmake/CMake and Qt4/Qt5 usage (only the CMake+Qt5
combination would yield `quazip5`);
- the binary base name was either `quazip` or `quazip5`, again,
depending on qmake/CMake *and* Qt4/Qt5 choice;
- the CMake config files were installed only when building with CMake;
- the CMake package name was `QuaZip` (for Qt4) or `QuaZip5` (for Qt5);
- the CMake target name was the same as the binary name.
QuaZip 1.x uses this scheme:
- the includes go to `include/QuaZip-QtX-Y/quazip`, where `include` is
the installation prefix include path (`/usr/include` or something),
`X` is the major version of Qt, and `Y` is the full version of QuaZip,
e. g. `include/QuaZip-Qt5-1.0/quazip`;
- the binary base name is `quazipZ-qtX`, where `Z` is the major version of
QuaZip, e. g. `libquazip1-qt5.so.1.0.0`;
- the CMake package name is `QuaZip-QtX`, e. g. `QuaZip-Qt5`;
- the CMake target name is `QuaZip::QuaZip`.
This can't possibly conflict with any crazy 0.x setup, no matter
qmake or CMake. CMake users get the easy modern CMake way
(`find_package(QuaZip-Qt5)`, `target_link_libraries(... QuaZip::QuaZip)`)
of using QuaZip, and includes can be either in the `#include <quazipfile.h>`
or in the `#include <quazip/quazipfile.h>` style (which some qmake users
used), as both `include/QuaZip-QtX-Y` and `include/QuaZip-QtX-Y/quazip`
include paths are added by default. This ensures source
compatibility between 0.x and 1.x without any annoying search-and-replace.
**The intended use**
QuaZip 1.0 should be installed along with 0.x. Whatever applications
were built with 0.x should continue to happily use 0.x. When application
developers decide so, they should switch to QuaZip 1.0 in their new
releases (and preferably switch to CMake as well).
Package maintainers should *not* consider 1.0 an upgrade from 0.x,
but rather an independent package, pretty much the same way as Qt4 and Qt5
are separate packages. The same goes for future major
versions such as 2.0, whenever they are released. Or at least that's
the current plan.

View File

@ -59,7 +59,7 @@ target_include_directories(${QUAZIP_LIB_TARGET_NAME} PUBLIC
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${QUAZIP_DIR_NAME}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${QUAZIP_INCLUDE_PATH}>
)
target_link_libraries(${QUAZIP_LIB_TARGET_NAME} ${QUAZIP_LIB_QT_LIBRARIES} ZLIB::ZLIB)
target_link_libraries(${QUAZIP_LIB_TARGET_NAME} ${QUAZIP_LIB_LIBRARIES})
if(BUILD_SHARED_LIBS)
target_compile_definitions(${QUAZIP_LIB_TARGET_NAME} PRIVATE QUAZIP_BUILD) # dllexport
else()
@ -68,30 +68,32 @@ endif()
include(CMakePackageConfigHelpers)
if(BUILD_SHARED_LIBS)
set(Flavor Shared)
else()
set(Flavor Static)
endif()
set(QUAZIP_EXPORT_SET ${QUAZIP_PACKAGE_NAME}_${Flavor}Targets)
write_basic_package_version_file(${PROJECT_BINARY_DIR}/${QUAZIP_PACKAGE_NAME}ConfigVersion.cmake
COMPATIBILITY SameMajorVersion
)
configure_package_config_file(QuaZipConfig.cmake.in ${QUAZIP_PACKAGE_NAME}Config.cmake
INSTALL_DESTINATION ${QUAZIP_INSTALL_CONFIGDIR}/${QUAZIP_DIR_NAME}
)
install(TARGETS ${QUAZIP_LIB_TARGET_NAME}
EXPORT ${QUAZIP_EXPORT_SET}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${QUAZIP_INCLUDE_PATH}
)
install(EXPORT ${QUAZIP_EXPORT_SET}
NAMESPACE QuaZip::
DESTINATION ${QUAZIP_INSTALL_CONFIGDIR}/${QUAZIP_DIR_NAME}
)
install(FILES ${PROJECT_BINARY_DIR}/${QUAZIP_PACKAGE_NAME}Config.cmake
${PROJECT_BINARY_DIR}/${QUAZIP_PACKAGE_NAME}ConfigVersion.cmake
DESTINATION ${QUAZIP_INSTALL_CONFIGDIR}/${QUAZIP_DIR_NAME}
)
if(QUAZIP_INSTALL)
if(BUILD_SHARED_LIBS)
set(Flavor Shared)
else()
set(Flavor Static)
endif()
set(QUAZIP_EXPORT_SET ${QUAZIP_PACKAGE_NAME}_${Flavor}Targets)
write_basic_package_version_file(${PROJECT_BINARY_DIR}/${QUAZIP_PACKAGE_NAME}ConfigVersion.cmake
COMPATIBILITY SameMajorVersion
)
configure_package_config_file(QuaZipConfig.cmake.in ${QUAZIP_PACKAGE_NAME}Config.cmake
INSTALL_DESTINATION ${QUAZIP_INSTALL_CONFIGDIR}/${QUAZIP_DIR_NAME}
)
install(TARGETS ${QUAZIP_LIB_TARGET_NAME}
EXPORT ${QUAZIP_EXPORT_SET}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${QUAZIP_INCLUDE_PATH}
)
install(EXPORT ${QUAZIP_EXPORT_SET}
NAMESPACE QuaZip::
DESTINATION ${QUAZIP_INSTALL_CONFIGDIR}/${QUAZIP_DIR_NAME}
)
install(FILES ${PROJECT_BINARY_DIR}/${QUAZIP_PACKAGE_NAME}Config.cmake
${PROJECT_BINARY_DIR}/${QUAZIP_PACKAGE_NAME}ConfigVersion.cmake
DESTINATION ${QUAZIP_INSTALL_CONFIGDIR}/${QUAZIP_DIR_NAME}
)
configure_file(quazip.pc.cmakein ${QUAZIP_PKGCONFIG_NAME}.pc @ONLY)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${QUAZIP_PKGCONFIG_NAME}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
configure_file(quazip.pc.cmakein ${QUAZIP_PKGCONFIG_NAME}.pc @ONLY)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${QUAZIP_PKGCONFIG_NAME}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
endif()

View File

@ -0,0 +1,20 @@
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
find_dependency(ZLIB REQUIRED)
include("${CMAKE_CURRENT_LIST_DIR}/@QUAZIP_EXPORT_SET@.cmake")
if(@QUAZIP_QT_MAJOR_VERSION@ EQUAL 6)
find_dependency(Qt6 REQUIRED COMPONENTS Core Core5Compat)
elseif(@QUAZIP_QT_MAJOR_VERSION@ EQUAL 5)
find_dependency(Qt5 REQUIRED COMPONENTS Core)
elseif(@QUAZIP_QT_MAJOR_VERSION@ EQUAL 4)
find_dependency(Qt4 4.5.0 REQUIRED COMPONENTS QtCore)
else()
message(FATAL_ERROR "Qt version QUAZIP_QT_MAJOR_VERSION=@QUAZIP_QT_MAJOR_VERSION@ is unsupported")
endif()
set_target_properties(QuaZip::QuaZip PROPERTIES IMPORTED_GLOBAL TRUE)
check_required_components(@QUAZIP_PACKAGE_NAME@)

View File

@ -0,0 +1,5 @@
#include "quachecksum32.h"
QuaChecksum32::~QuaChecksum32()
{
}

View File

@ -0,0 +1,11 @@
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=${prefix}
libdir=${prefix}/lib@LIB_SUFFIX@
includedir=${prefix}/include
Name: QuaZip-Qt@QUAZIP_QT_MAJOR_VERSION@
Description: Minizip wrapper library for Qt @QUAZIP_QT_MAJOR_VERSION@.x
Version: @QUAZIP_LIB_VERSION@
Libs: -l@QUAZIP_LIB_FILE_NAME@ -lz
Cflags: -I${includedir}/@QUAZIP_DIR_NAME@ -I${includedir}/@QUAZIP_INCLUDE_PATH@
Requires: @QUAZIP_PKGCONFIG_REQUIRES@

View File

@ -0,0 +1,145 @@
#ifndef QUAZIP_QT_COMPAT_H
#define QUAZIP_QT_COMPAT_H
/*
* For some reason, Qt 5.14 and 5.15 introduced a whole mess of seemingly random
* moves and deprecations. To avoid populating code with #ifs,
* we handle this stuff here, as well as some other compatibility issues.
*
* Some includes are repeated just in case we want to split this file later.
*/
#include <QtCore/Qt>
#include <QtCore/QtGlobal>
// Legacy encodings are still everywhere, but the Qt team decided we
// don't need them anymore and moved them out of Core in Qt 6.
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
# include <QtCore5Compat/QTextCodec>
#else
# include <QtCore/QTextCodec>
#endif
// QSaveFile terribly breaks the is-a idiom (Liskov substitution principle):
// QSaveFile is-a QIODevice, but it makes close() private and aborts
// if you call it through the base class. Hence this ugly hack:
#if (QT_VERSION >= 0x050100)
#include <QtCore/QSaveFile>
inline bool quazip_close(QIODevice *device) {
QSaveFile *file = qobject_cast<QSaveFile*>(device);
if (file != nullptr) {
// We have to call the ugly commit() instead:
return file->commit();
} else {
device->close();
return true;
}
}
#else
inline bool quazip_close(QIODevice *device) {
device->close();
return true;
}
#endif
// this is yet another stupid move and deprecation
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
using Qt::SkipEmptyParts;
#else
#include <QtCore/QString>
const auto SkipEmptyParts = QString::SplitBehavior::SkipEmptyParts;
#endif
// and yet another... (why didn't they just make qSort delegate to std::sort?)
#include <QtCore/QList>
#if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0))
#include <algorithm>
template<typename T, typename C>
inline void quazip_sort(T begin, T end, C comparator) {
std::sort(begin, end, comparator);
}
#else
#include <QtCore/QtAlgorithms>
template<typename T, typename C>
inline void quazip_sort(T begin, T end, C comparator) {
qSort(begin, end, comparator);
}
#endif
// this is a stupid rename...
#include <QtCore/QDateTime>
#include <QtCore/QFileInfo>
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
inline QDateTime quazip_ctime(const QFileInfo &fi) {
return fi.birthTime();
}
#else
inline QDateTime quazip_ctime(const QFileInfo &fi) {
return fi.created();
}
#endif
// this is just a slightly better alternative
#include <QtCore/QFileInfo>
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
inline bool quazip_is_symlink(const QFileInfo &fi) {
return fi.isSymbolicLink();
}
#else
inline bool quazip_is_symlink(const QFileInfo &fi) {
// also detects *.lnk on Windows, but better than nothing
return fi.isSymLink();
}
#endif
// I'm not even sure what this one is, but nevertheless
#include <QtCore/QFileInfo>
#if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
inline QString quazip_symlink_target(const QFileInfo &fi) {
return fi.symLinkTarget();
}
#else
inline QString quazip_symlink_target(const QFileInfo &fi) {
return fi.readLink(); // What's the difference? I've no idea.
}
#endif
// this is not a deprecation but an improvement, for a change
#include <QtCore/QDateTime>
#if (QT_VERSION >= 0x040700)
inline quint64 quazip_ntfs_ticks(const QDateTime &time, int fineTicks) {
QDateTime base(QDate(1601, 1, 1), QTime(0, 0), Qt::UTC);
return base.msecsTo(time) * 10000 + fineTicks;
}
#else
inline quint64 quazip_ntfs_ticks(const QDateTime &time, int fineTicks) {
QDateTime base(QDate(1601, 1, 1), QTime(0, 0), Qt::UTC);
QDateTime utc = time.toUTC();
return (static_cast<qint64>(base.date().daysTo(utc.date()))
* Q_INT64_C(86400000)
+ static_cast<qint64>(base.time().msecsTo(utc.time())))
* Q_INT64_C(10000) + fineTicks;
}
#endif
// yet another improvement...
#include <QtCore/QDateTime>
#if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0) // Yay! Finally a way to get time as qint64!
inline qint64 quazip_to_time64_t(const QDateTime &time) {
return time.toSecsSinceEpoch();
}
#else
inline qint64 quazip_to_time64_t(const QDateTime &time) {
return static_cast<qint64>(time.toTime_t()); // 32 bits only, but better than nothing
}
#endif
#include <QtCore/QTextStream>
// and another stupid move
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
const auto quazip_endl = Qt::endl;
#else
const auto quazip_endl = endl;
#endif
#endif // QUAZIP_QT_COMPAT_H

View File

@ -0,0 +1,37 @@
project(qztest)
set(QZTEST_SOURCES
qztest.h
testjlcompress.h
testquachecksum32.h
testquagzipfile.h
testquaziodevice.h
testquazip.h
testquazipdir.h
testquazipfile.h
testquazipfileinfo.h
testquazipnewinfo.h
qztest.cpp
testjlcompress.cpp
testquachecksum32.cpp
testquagzipfile.cpp
testquaziodevice.cpp
testquazip.cpp
testquazipdir.cpp
testquazipfile.cpp
testquazipfileinfo.cpp
testquazipnewinfo.cpp
)
add_executable(${PROJECT_NAME} ${QZTEST_SOURCES} qztest.qrc)
set_target_properties(${PROJECT_NAME} PROPERTIES AUTORCC ON)
target_link_libraries(${PROJECT_NAME}
${QUAZIP_TEST_QT_LIBRARIES}
QuaZip::QuaZip
)
add_test(NAME qztest_test
COMMAND qztest
WORKING_DIRECTORY ${QUAZIP_BINARY_DIR}/quazip # preliminary hack to find the dll on windows
)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --verbose DEPENDS qztest)

View File

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file>test_files/issue43_cant_get_dates.zip</file>
</qresource>
</RCC>