1/* This file is part of the KDE libraries
2 SPDX-FileCopyrightText: 2000 David Faure <faure@kde.org>
3 SPDX-FileCopyrightText: 2011 Mario Bensi <mbensi@ipsquad.net>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7#ifndef __kcompressiondevice_h
8#define __kcompressiondevice_h
9
10#include <karchive_export.h>
11
12#include <QFileDevice>
13#include <QIODevice>
14#include <QMetaType>
15#include <QString>
16
17class KCompressionDevicePrivate;
18
19class KFilterBase;
20
21/*!
22 * \class KCompressionDevice
23 * \inmodule KArchive
24 *
25 * A class for reading and writing compressed data onto a device
26 * (e.g. file, but other usages are possible, like a buffer or a socket).
27 *
28 * Use this class to read/write compressed files.
29 */
30
31class KARCHIVE_EXPORT KCompressionDevice : public QIODevice // KF7 TODO: consider inheriting from QFileDevice, so apps can use error() generically ?
32{
33 Q_OBJECT
34public:
35 /*!
36 * \value GZip
37 * \value BZip2
38 * \value Xz
39 * \value None
40 * \value[since 5.82] Zstd
41 * \value[since 6.15] Lz
42 */
43 enum CompressionType {
44 GZip,
45 BZip2,
46 Xz,
47 None,
48 Zstd,
49 Lz,
50 };
51
52 /*!
53 * Constructs a KCompressionDevice for a given CompressionType (e.g. GZip, BZip2 etc.).
54 *
55 * \a inputDevice input device.
56 *
57 * \a autoDeleteInputDevice if true, \a inputDevice will be deleted automatically
58 *
59 * \a type the CompressionType to use.
60 */
61 KCompressionDevice(QIODevice *inputDevice, bool autoDeleteInputDevice, CompressionType type);
62
63 /*!
64 * Constructs a KCompressionDevice for a given CompressionType (e.g. GZip, BZip2 etc.).
65 *
66 * \a fileName the name of the file to filter.
67 *
68 * \a type the CompressionType to use.
69 */
70 KCompressionDevice(const QString &fileName, CompressionType type);
71
72 /*!
73 * Constructs a KCompressionDevice for a given \a fileName.
74 *
75 * \a fileName the name of the file to filter.
76 *
77 * \since 5.85
78 */
79 explicit KCompressionDevice(const QString &fileName);
80
81 /*!
82 * Constructs a KCompressionDevice for a given CompressionType (e.g. GZip, BZip2 etc.).
83 *
84 * \a inputDevice input device.
85 *
86 * \a type the CompressionType to use.
87 *
88 * \a size the size we know the inputDevice with CompressionType type has. If we know it.
89 *
90 * \since 6.16
91 */
92 KCompressionDevice(std::unique_ptr<QIODevice> inputDevice, CompressionType type, std::optional<qint64> size = {});
93
94 /*!
95 * Destructs the KCompressionDevice.
96 *
97 * Calls close() if the filter device is still open.
98 */
99 ~KCompressionDevice() override;
100
101 /*!
102 * The compression actually used by this device.
103 *
104 * If the support for the compression requested in the constructor
105 * is not available, then the device will use None.
106 */
107 CompressionType compressionType() const;
108
109 bool open(QIODevice::OpenMode mode) override;
110
111 void close() override;
112
113 qint64 size() const override;
114
115 /*!
116 * For writing gzip compressed files only:
117 * set the name of the original file, to be used in the gzip header.
118 *
119 * \a fileName the name of the original file
120 */
121 void setOrigFileName(const QByteArray &fileName);
122
123 /*!
124 * Call this let this device skip the gzip headers when reading/writing.
125 * This way KCompressionDevice (with gzip filter) can be used as a direct wrapper
126 * around zlib - this is used by KZip.
127 */
128 void setSkipHeaders();
129
130 /*!
131 * \reimp
132 * That one can be quite slow, when going back. Use with care.
133 */
134 bool seek(qint64) override;
135
136 bool atEnd() const override;
137
138 /*!
139 * Call this to create the appropriate filter for the CompressionType
140 * named \a type.
141 *
142 * \a type the type of the compression filter
143 *
144 * Returns the filter for the \a type, or 0 if not found
145 */
146 static KFilterBase *filterForCompressionType(CompressionType type);
147
148 /*!
149 * Returns the compression type for the given MIME type, if possible. Otherwise returns None.
150 *
151 * This handles simple cases like application/gzip, but also application/x-compressed-tar, and inheritance.
152 * \since 5.85
153 */
154 static CompressionType compressionTypeForMimeType(const QString &mimetype);
155
156 /*!
157 * Returns the error code from the last failing operation.
158 * This is especially useful after calling close(), which unfortunately returns void
159 * (see https://bugreports.qt.io/browse/QTBUG-70033), to see if the flushing done by close
160 * was able to write all the data to disk.
161 */
162 QFileDevice::FileError error() const;
163
164protected:
165 friend class K7Zip;
166
167 qint64 readData(char *data, qint64 maxlen) override;
168 qint64 writeData(const char *data, qint64 len) override;
169
170 KFilterBase *filterBase();
171
172private:
173 friend KCompressionDevicePrivate;
174 KCompressionDevicePrivate *const d;
175};
176
177Q_DECLARE_METATYPE(KCompressionDevice::CompressionType)
178
179#endif
180

source code of karchive/src/kcompressiondevice.h