QuaZip quazip-1-4
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// Legacy encodings are still everywhere, but the Qt team decided we
16// don't need them anymore and moved them out of Core in Qt 6.
17#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
18# include <QtCore5Compat/QTextCodec>
19#else
20# include <QtCore/QTextCodec>
21#endif
22
23// QSaveFile terribly breaks the is-a idiom (Liskov substitution principle):
24// QSaveFile is-a QIODevice, but it makes close() private and aborts
25// if you call it through the base class. Hence this ugly hack:
26#if (QT_VERSION >= 0x050100)
27#include <QtCore/QSaveFile>
28inline bool quazip_close(QIODevice *device) {
29 QSaveFile *file = qobject_cast<QSaveFile*>(device);
30 if (file != nullptr) {
31 // We have to call the ugly commit() instead:
32 return file->commit();
33 }
34 device->close();
35 return true;
36}
37#else
38inline bool quazip_close(QIODevice *device) {
39 device->close();
40 return true;
41}
42#endif
43
44// this is yet another stupid move and deprecation
45#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
46using Qt::SkipEmptyParts;
47#else
48#include <QtCore/QString>
49const auto SkipEmptyParts = QString::SplitBehavior::SkipEmptyParts;
50#endif
51
52// and yet another... (why didn't they just make qSort delegate to std::sort?)
53#include <QtCore/QList>
54#if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0))
55#include <algorithm>
56template<typename T, typename C>
57inline void quazip_sort(T begin, T end, C comparator) {
58 std::sort(begin, end, comparator);
59}
60#else
61#include <QtCore/QtAlgorithms>
62template<typename T, typename C>
63inline void quazip_sort(T begin, T end, C comparator) {
64 qSort(begin, end, comparator);
65}
66#endif
67
68// this is a stupid rename...
69#include <QtCore/QDateTime>
70#include <QtCore/QFileInfo>
71#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
72inline QDateTime quazip_ctime(const QFileInfo &fi) {
73 return fi.birthTime();
74}
75#else
76inline QDateTime quazip_ctime(const QFileInfo &fi) {
77 return fi.created();
78}
79#endif
80
81// this is just a slightly better alternative
82#include <QtCore/QFileInfo>
83#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
84inline bool quazip_is_symlink(const QFileInfo &fi) {
85 return fi.isSymbolicLink();
86}
87#else
88inline bool quazip_is_symlink(const QFileInfo &fi) {
89 // also detects *.lnk on Windows, but better than nothing
90 return fi.isSymLink();
91}
92#endif
93
94// I'm not even sure what this one is, but nevertheless
95#include <QtCore/QFileInfo>
96#if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
97inline QString quazip_symlink_target(const QFileInfo &fi) {
98 return fi.symLinkTarget();
99}
100#else
101inline QString quazip_symlink_target(const QFileInfo &fi) {
102 return fi.readLink(); // What's the difference? I've no idea.
103}
104#endif
105
106// deprecation
107#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
108#include <QtCore/QTimeZone>
109inline QDateTime quazip_since_epoch() {
110 return QDateTime(QDate(1970, 1, 1), QTime(0, 0), QTimeZone::utc());
111}
112
113inline QDateTime quazip_since_epoch_ntfs() {
114 return QDateTime(QDate(1601, 1, 1), QTime(0, 0), QTimeZone::utc());
115}
116#else
117inline QDateTime quazip_since_epoch() {
118 return QDateTime(QDate(1970, 1, 1), QTime(0, 0), Qt::UTC);
119}
120
121inline QDateTime quazip_since_epoch_ntfs() {
122 return QDateTime(QDate(1601, 1, 1), QTime(0, 0), Qt::UTC);
123}
124#endif
125
126// this is not a deprecation but an improvement, for a change
127#include <QtCore/QDateTime>
128#if (QT_VERSION >= 0x040700)
129inline quint64 quazip_ntfs_ticks(const QDateTime &time, int fineTicks) {
130 QDateTime base = quazip_since_epoch_ntfs();
131 return base.msecsTo(time) * 10000 + fineTicks;
132}
133#else
134inline quint64 quazip_ntfs_ticks(const QDateTime &time, int fineTicks) {
135 QDateTime base = quazip_since_epoch_ntfs();
136 QDateTime utc = time.toUTC();
137 return (static_cast<qint64>(base.date().daysTo(utc.date()))
138 * Q_INT64_C(86400000)
139 + static_cast<qint64>(base.time().msecsTo(utc.time())))
140 * Q_INT64_C(10000) + fineTicks;
141}
142#endif
143
144// yet another improvement...
145#include <QtCore/QDateTime>
146#if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0) // Yay! Finally a way to get time as qint64!
147inline qint64 quazip_to_time64_t(const QDateTime &time) {
148 return time.toSecsSinceEpoch();
149}
150#else
151inline qint64 quazip_to_time64_t(const QDateTime &time) {
152 return static_cast<qint64>(time.toTime_t()); // 32 bits only, but better than nothing
153}
154#endif
155
156#include <QtCore/QTextStream>
157// and another stupid move
158#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
159const auto quazip_endl = Qt::endl;
160#else
161const auto quazip_endl = endl;
162#endif
163
164#endif // QUAZIP_QT_COMPAT_H