File indexing completed on 2024-04-21 14:53:22

0001 /* This file is part of the KDE libraries
0002    SPDX-FileCopyrightText: 2002 Holger Schroeder <holger-kde@holgis.net>
0003 
0004    SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 #ifndef KZIP_H
0007 #define KZIP_H
0008 
0009 #include <karchive.h>
0010 
0011 #include "kzipfileentry.h" // for source compat
0012 
0013 class KZipFileEntry;
0014 /**
0015  *   @class KZip zip.h KZip
0016  *
0017  *   A class for reading / writing zip archives.
0018  *
0019  *   You can use it in QIODevice::ReadOnly or in QIODevice::WriteOnly mode, and it
0020  *   behaves just as expected.
0021  *   It can also be used in QIODevice::ReadWrite mode, in this case one can
0022  *   append files to an existing zip archive. When you append new files, which
0023  *   are not yet in the zip, it works as expected, i.e. the files are appended at the end.
0024  *   When you append a file, which is already in the file, the reference to the
0025  *   old file is dropped and the new one is added to the zip - but the
0026  *   old data from the file itself is not deleted, it is still in the
0027  *   zipfile. So when you want to have a small and garbage-free zipfile,
0028  *   just read the contents of the appended zip file and write it to a new one
0029  *   in QIODevice::WriteOnly mode. This is especially important when you don't want
0030  *   to leak information of how intermediate versions of files in the zip
0031  *   were looking.
0032  *
0033  *   For more information on the zip fileformat go to
0034  *   http://www.pkware.com/products/enterprise/white_papers/appnote.html
0035  * @author Holger Schroeder <holger-kde@holgis.net>
0036  */
0037 class KARCHIVE_EXPORT KZip : public KArchive
0038 {
0039     Q_DECLARE_TR_FUNCTIONS(KZip)
0040 
0041 public:
0042     /**
0043      * Creates an instance that operates on the given filename.
0044      * using the compression filter associated to given mimetype.
0045      *
0046      * @param filename is a local path (e.g. "/home/holger/myfile.zip")
0047      */
0048     KZip(const QString &filename);
0049 
0050     /**
0051      * Creates an instance that operates on the given device.
0052      * The device can be compressed (KCompressionDevice) or not (QFile, etc.).
0053      * @warning Do not assume that giving a QFile here will decompress the file,
0054      * in case it's compressed!
0055      * @param dev the device to access
0056      */
0057     KZip(QIODevice *dev);
0058 
0059     /**
0060      * If the zip file is still opened, then it will be
0061      * closed automatically by the destructor.
0062      */
0063     ~KZip() override;
0064 
0065     /**
0066      * Describes the contents of the "extra field" for a given file in the Zip archive.
0067      */
0068     enum ExtraField {
0069         NoExtraField = 0, ///< No extra field
0070         ModificationTime = 1, ///< Modification time ("extended timestamp" header)
0071         DefaultExtraField = 1, // alias of ModificationTime
0072     };
0073 
0074     /**
0075      * Call this before writeFile or prepareWriting, to define what the next
0076      * file to be written should have in its extra field.
0077      * @param ef the type of "extra field"
0078      * @see extraField()
0079      */
0080     void setExtraField(ExtraField ef);
0081 
0082     /**
0083      * The current type of "extra field" that will be used for new files.
0084      * @return the current type of "extra field"
0085      * @see setExtraField()
0086      */
0087     ExtraField extraField() const;
0088 
0089     /**
0090      * Describes the compression type for a given file in the Zip archive.
0091      */
0092     enum Compression {
0093         NoCompression = 0, ///< Uncompressed.
0094         DeflateCompression = 1, ///< Deflate compression method.
0095     };
0096 
0097     /**
0098      * Call this before writeFile or prepareWriting, to define whether the next
0099      * files to be written should be compressed or not.
0100      * @param c the new compression mode
0101      * @see compression()
0102      */
0103     void setCompression(Compression c);
0104 
0105     /**
0106      * The current compression mode that will be used for new files.
0107      * @return the current compression mode
0108      * @see setCompression()
0109      */
0110     Compression compression() const;
0111 
0112     /**
0113      * Write data to a file that has been created using prepareWriting().
0114      * @param data a pointer to the data
0115      * @param size the size of the chunk
0116      * @return true if successful, false otherwise
0117      */
0118     bool writeData(const char *data, qint64 size) override;
0119 
0120 protected:
0121     /// Reimplemented from KArchive
0122     bool doWriteSymLink(const QString &name,
0123                         const QString &target,
0124                         const QString &user,
0125                         const QString &group,
0126                         mode_t perm,
0127                         const QDateTime &atime,
0128                         const QDateTime &mtime,
0129                         const QDateTime &ctime) override;
0130     /// Reimplemented from KArchive
0131     bool doPrepareWriting(const QString &name,
0132                           const QString &user,
0133                           const QString &group,
0134                           qint64 size,
0135                           mode_t perm,
0136                           const QDateTime &atime,
0137                           const QDateTime &mtime,
0138                           const QDateTime &creationTime) override;
0139 
0140     /**
0141      * Write data to a file that has been created using prepareWriting().
0142      * @param size the size of the file
0143      * @return true if successful, false otherwise
0144      */
0145     bool doFinishWriting(qint64 size) override;
0146 
0147     /**
0148      * Opens the archive for reading.
0149      * Parses the directory listing of the archive
0150      * and creates the KArchiveDirectory/KArchiveFile entries.
0151      * @param mode the mode of the file
0152      */
0153     bool openArchive(QIODevice::OpenMode mode) override;
0154 
0155     /// Closes the archive
0156     bool closeArchive() override;
0157 
0158     /// Reimplemented from KArchive
0159     bool doWriteDir(const QString &name,
0160                     const QString &user,
0161                     const QString &group,
0162                     mode_t perm,
0163                     const QDateTime &atime,
0164                     const QDateTime &mtime,
0165                     const QDateTime &ctime) override;
0166 
0167 protected:
0168     void virtual_hook(int id, void *data) override;
0169 
0170 private:
0171     class KZipPrivate;
0172     KZipPrivate *const d;
0173 };
0174 
0175 #endif