File indexing completed on 2024-04-21 03:52:32

0001 /* This file is part of the KDE libraries
0002    SPDX-FileCopyrightText: 2000 David Faure <faure@kde.org>
0003    SPDX-FileCopyrightText: 2011 Mario Bensi <mbensi@ipsquad.net>
0004 
0005    SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 #ifndef __kcompressiondevice_h
0008 #define __kcompressiondevice_h
0009 
0010 #include <karchive_export.h>
0011 
0012 #include <QFileDevice>
0013 #include <QIODevice>
0014 #include <QMetaType>
0015 #include <QString>
0016 
0017 class KCompressionDevicePrivate;
0018 
0019 class KFilterBase;
0020 
0021 /**
0022  * @class KCompressionDevice kcompressiondevice.h KCompressionDevice
0023  *
0024  * A class for reading and writing compressed data onto a device
0025  * (e.g. file, but other usages are possible, like a buffer or a socket).
0026  *
0027  * Use this class to read/write compressed files.
0028  */
0029 
0030 class KARCHIVE_EXPORT KCompressionDevice : public QIODevice // KF6 TODO: consider inheriting from QFileDevice, so apps can use error() generically ?
0031 {
0032     Q_OBJECT
0033 public:
0034     enum CompressionType {
0035         GZip,
0036         BZip2,
0037         Xz,
0038         None,
0039         Zstd, ///< @since 5.82
0040     };
0041 
0042     /**
0043      * Constructs a KCompressionDevice for a given CompressionType (e.g. GZip, BZip2 etc.).
0044      * @param inputDevice input device.
0045      * @param autoDeleteInputDevice if true, @p inputDevice will be deleted automatically
0046      * @param type the CompressionType to use.
0047      */
0048     KCompressionDevice(QIODevice *inputDevice, bool autoDeleteInputDevice, CompressionType type);
0049 
0050     /**
0051      * Constructs a KCompressionDevice for a given CompressionType (e.g. GZip, BZip2 etc.).
0052      * @param fileName the name of the file to filter.
0053      * @param type the CompressionType to use.
0054      */
0055     KCompressionDevice(const QString &fileName, CompressionType type);
0056 
0057     /**
0058      * Constructs a KCompressionDevice for a given @p fileName.
0059      * @param fileName the name of the file to filter.
0060      * @since 5.85
0061      */
0062     explicit KCompressionDevice(const QString &fileName);
0063 
0064     /**
0065      * Destructs the KCompressionDevice.
0066      * Calls close() if the filter device is still open.
0067      */
0068     ~KCompressionDevice() override;
0069 
0070     /**
0071      * The compression actually used by this device.
0072      * If the support for the compression requested in the constructor
0073      * is not available, then the device will use None.
0074      */
0075     CompressionType compressionType() const;
0076 
0077     /**
0078      * Open for reading or writing.
0079      */
0080     bool open(QIODevice::OpenMode mode) override;
0081 
0082     /**
0083      * Close after reading or writing.
0084      */
0085     void close() override;
0086 
0087     /**
0088      * For writing gzip compressed files only:
0089      * set the name of the original file, to be used in the gzip header.
0090      * @param fileName the name of the original file
0091      */
0092     void setOrigFileName(const QByteArray &fileName);
0093 
0094     /**
0095      * Call this let this device skip the gzip headers when reading/writing.
0096      * This way KCompressionDevice (with gzip filter) can be used as a direct wrapper
0097      * around zlib - this is used by KZip.
0098      */
0099     void setSkipHeaders();
0100 
0101     /**
0102      * That one can be quite slow, when going back. Use with care.
0103      */
0104     bool seek(qint64) override;
0105 
0106     bool atEnd() const override;
0107 
0108     /**
0109      * Call this to create the appropriate filter for the CompressionType
0110      * named @p type.
0111      * @param type the type of the compression filter
0112      * @return the filter for the @p type, or 0 if not found
0113      */
0114     static KFilterBase *filterForCompressionType(CompressionType type);
0115 
0116     /**
0117      * Returns the compression type for the given MIME type, if possible. Otherwise returns None.
0118      * This handles simple cases like application/gzip, but also application/x-compressed-tar, and inheritance.
0119      * @since 5.85
0120      */
0121     static CompressionType compressionTypeForMimeType(const QString &mimetype);
0122 
0123     /**
0124      * Returns the error code from the last failing operation.
0125      * This is especially useful after calling close(), which unfortunately returns void
0126      * (see https://bugreports.qt.io/browse/QTBUG-70033), to see if the flushing done by close
0127      * was able to write all the data to disk.
0128      */
0129     QFileDevice::FileError error() const;
0130 
0131 protected:
0132     friend class K7Zip;
0133 
0134     qint64 readData(char *data, qint64 maxlen) override;
0135     qint64 writeData(const char *data, qint64 len) override;
0136 
0137     KFilterBase *filterBase();
0138 
0139 private:
0140     friend KCompressionDevicePrivate;
0141     KCompressionDevicePrivate *const d;
0142 };
0143 
0144 Q_DECLARE_METATYPE(KCompressionDevice::CompressionType)
0145 
0146 #endif