QuaZip quazip-1-6
quazip_qt_compat.h
1#ifndef QUAZIP_QT_COMPAT_H
2#define QUAZIP_QT_COMPAT_H
3
4/*
5 * For some reason, Qt 5.14 and 5.15 introduced a whole mess of seemingly random
6 * moves and deprecations. To avoid populating code with #ifs,
7 * we handle this stuff here, as well as some other compatibility issues.
8 *
9 * Some includes are repeated just in case we want to split this file later.
10 */
11
12#include <QtCore/Qt>
13#include <QtCore/QtGlobal>
14
15#include "quazip_textcodec.h"
16
17// QSaveFile terribly breaks the is-a idiom (Liskov substitution principle):
18// QSaveFile is-a QIODevice, but it makes close() private and aborts
19// if you call it through the base class. Hence this ugly hack:
20#if (QT_VERSION >= 0x050100)
21#include <QtCore/QSaveFile>
22inline bool quazip_close(QIODevice *device) {
23 QSaveFile *file = qobject_cast<QSaveFile*>(device);
24 if (file != nullptr) {
25 // We have to call the ugly commit() instead:
26 return file->commit();
27 }
28 device->close();
29 return true;
30}
31#else
32inline bool quazip_close(QIODevice *device) {
33 device->close();
34 return true;
35}
36#endif
37
38// this is yet another stupid move and deprecation
39#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
40using Qt::SkipEmptyParts;
41#else
42#include <QtCore/QString>
43const auto SkipEmptyParts = QString::SplitBehavior::SkipEmptyParts;
44#endif
45
46// and yet another... (why didn't they just make qSort delegate to std::sort?)
47#include <QtCore/QList>
48#if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0))
49#include <algorithm>
50template<typename T, typename C>
51inline void quazip_sort(T begin, T end, C comparator) {
52 std::sort(begin, end, comparator);
53}
54#else
55#include <QtCore/QtAlgorithms>
56template<typename T, typename C>
57inline void quazip_sort(T begin, T end, C comparator) {
58 qSort(begin, end, comparator);
59}
60#endif
61
62// this is a stupid rename...
63#include <QtCore/QDateTime>
64#include <QtCore/QFileInfo>
65#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
66inline QDateTime quazip_ctime(const QFileInfo &fi) {
67 return fi.birthTime();
68}
69#else
70inline QDateTime quazip_ctime(const QFileInfo &fi) {
71 return fi.created();
72}
73#endif
74
75// this is just a slightly better alternative
76#include <QtCore/QFileInfo>
77#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
78inline bool quazip_is_symlink(const QFileInfo &fi) {
79 return fi.isSymbolicLink();
80}
81#else
82inline bool quazip_is_symlink(const QFileInfo &fi) {
83 // also detects *.lnk on Windows, but better than nothing
84 return fi.isSymLink();
85}
86#endif
87
88// I'm not even sure what this one is, but nevertheless
89#include <QtCore/QFileInfo>
90#if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
91inline QString quazip_symlink_target(const QFileInfo &fi) {
92 return fi.symLinkTarget();
93}
94#else
95inline QString quazip_symlink_target(const QFileInfo &fi) {
96 return fi.readLink(); // What's the difference? I've no idea.
97}
98#endif
99
100// deprecation
101#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
102#include <QtCore/QTimeZone>
103inline QDateTime quazip_since_epoch() {
104 return QDateTime(QDate(1970, 1, 1), QTime(0, 0), QTimeZone::UTC);
105}
106
107inline QDateTime quazip_since_epoch_ntfs() {
108 return QDateTime(QDate(1601, 1, 1), QTime(0, 0), QTimeZone::UTC);
109}
110#else
111inline QDateTime quazip_since_epoch() {
112 return QDateTime(QDate(1970, 1, 1), QTime(0, 0), Qt::UTC);
113}
114
115inline QDateTime quazip_since_epoch_ntfs() {
116 return QDateTime(QDate(1601, 1, 1), QTime(0, 0), Qt::UTC);
117}
118#endif
119
120// this is not a deprecation but an improvement, for a change
121#include <QtCore/QDateTime>
122#if (QT_VERSION >= 0x040700)
123inline quint64 quazip_ntfs_ticks(const QDateTime &time, int fineTicks) {
124 QDateTime base = quazip_since_epoch_ntfs();
125 return base.msecsTo(time) * 10000 + fineTicks;
126}
127#else
128inline quint64 quazip_ntfs_ticks(const QDateTime &time, int fineTicks) {
129 QDateTime base = quazip_since_epoch_ntfs();
130 QDateTime utc = time.toUTC();
131 return (static_cast<qint64>(base.date().daysTo(utc.date()))
132 * Q_INT64_C(86400000)
133 + static_cast<qint64>(base.time().msecsTo(utc.time())))
134 * Q_INT64_C(10000) + fineTicks;
135}
136#endif
137
138// yet another improvement...
139#include <QtCore/QDateTime>
140#if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0) // Yay! Finally a way to get time as qint64!
141inline qint64 quazip_to_time64_t(const QDateTime &time) {
142 return time.toSecsSinceEpoch();
143}
144#else
145inline qint64 quazip_to_time64_t(const QDateTime &time) {
146 return static_cast<qint64>(time.toTime_t()); // 32 bits only, but better than nothing
147}
148#endif
149
150#include <QtCore/QTextStream>
151// and another stupid move
152#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
153const auto quazip_endl = Qt::endl;
154#else
155const auto quazip_endl = endl;
156#endif
157
158// We want to support Qt5, Qt6 up to 6.5 and Qt 6.5+ compiled without timezone feature.
159#if QT_CONFIG(timezone)
160#include <QTimeZone>
161
162#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
163// Qt 6.5+ has QTimeZone::UTC
164#define COMPAT_UTC_TZ QTimeZone(QTimeZone::UTC)
165#else
166// Qt 5.x and Qt 6.0–6.4 use utc()
167#define COMPAT_UTC_TZ QTimeZone::utc()
168#endif
169
170#else // timezone feature disabled
171#include <QtCore/Qt>
172
173#define COMPAT_UTC_TZ Qt::UTC
174
175#endif
176
177#endif // QUAZIP_QT_COMPAT_H