1 | /* This file is part of the KDE libraries |
2 | Copyright (C) 2002 Holger Schroeder <holger-kde@holgis.net> |
3 | |
4 | This library is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU Library General Public |
6 | License version 2 as published by the Free Software Foundation. |
7 | |
8 | This library is distributed in the hope that it will be useful, |
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
11 | Library General Public License for more details. |
12 | |
13 | You should have received a copy of the GNU Library General Public License |
14 | along with this library; see the file COPYING.LIB. If not, write to |
15 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
16 | Boston, MA 02110-1301, USA. |
17 | */ |
18 | #ifndef KZIP_H |
19 | #define KZIP_H |
20 | |
21 | #include <karchive.h> |
22 | |
23 | class KZipFileEntry; |
24 | /** |
25 | * A class for reading / writing zip archives. |
26 | * |
27 | * You can use it in QIODevice::ReadOnly or in QIODevice::WriteOnly mode, and it |
28 | * behaves just as expected. |
29 | * It can also be used in QIODevice::ReadWrite mode, in this case one can |
30 | * append files to an existing zip archive. When you append new files, which |
31 | * are not yet in the zip, it works as expected, i.e. the files are appended at the end. |
32 | * When you append a file, which is already in the file, the reference to the |
33 | * old file is dropped and the new one is added to the zip - but the |
34 | * old data from the file itself is not deleted, it is still in the |
35 | * zipfile. So when you want to have a small and garbage-free zipfile, |
36 | * just read the contents of the appended zip file and write it to a new one |
37 | * in QIODevice::WriteOnly mode. This is especially important when you don't want |
38 | * to leak information of how intermediate versions of files in the zip |
39 | * were looking. |
40 | * |
41 | * For more information on the zip fileformat go to |
42 | * http://www.pkware.com/products/enterprise/white_papers/appnote.html |
43 | * @author Holger Schroeder <holger-kde@holgis.net> |
44 | */ |
45 | class KDECORE_EXPORT KZip : public KArchive |
46 | { |
47 | public: |
48 | /** |
49 | * Creates an instance that operates on the given filename. |
50 | * using the compression filter associated to given mimetype. |
51 | * |
52 | * @param filename is a local path (e.g. "/home/holger/myfile.zip") |
53 | */ |
54 | KZip( const QString& filename ); |
55 | |
56 | /** |
57 | * Creates an instance that operates on the given device. |
58 | * The device can be compressed (KFilterDev) or not (QFile, etc.). |
59 | * @warning Do not assume that giving a QFile here will decompress the file, |
60 | * in case it's compressed! |
61 | * @param dev the device to access |
62 | */ |
63 | KZip( QIODevice * dev ); |
64 | |
65 | /** |
66 | * If the zip file is still opened, then it will be |
67 | * closed automatically by the destructor. |
68 | */ |
69 | virtual ~KZip(); |
70 | |
71 | /** |
72 | * Describes the contents of the "extra field" for a given file in the Zip archive. |
73 | */ |
74 | enum { = 0, ///< No extra field |
75 | = 1, ///< Modification time ("extended timestamp" header) |
76 | = 1 |
77 | }; |
78 | |
79 | /** |
80 | * Call this before writeFile or prepareWriting, to define what the next |
81 | * file to be written should have in its extra field. |
82 | * @param ef the type of "extra field" |
83 | * @see extraField() |
84 | */ |
85 | void ( ExtraField ef ); |
86 | |
87 | /** |
88 | * The current type of "extra field" that will be used for new files. |
89 | * @return the current type of "extra field" |
90 | * @see setExtraField() |
91 | */ |
92 | ExtraField () const; |
93 | |
94 | /** |
95 | * Describes the compression type for a given file in the Zip archive. |
96 | */ |
97 | enum Compression { NoCompression = 0, ///< Uncompressed. |
98 | DeflateCompression = 1 ///< Deflate compression method. |
99 | }; |
100 | |
101 | |
102 | /** |
103 | * Call this before writeFile or prepareWriting, to define whether the next |
104 | * files to be written should be compressed or not. |
105 | * @param c the new compression mode |
106 | * @see compression() |
107 | */ |
108 | void setCompression( Compression c ); |
109 | |
110 | /** |
111 | * The current compression mode that will be used for new files. |
112 | * @return the current compression mode |
113 | * @see setCompression() |
114 | */ |
115 | Compression compression() const; |
116 | |
117 | /** |
118 | * Write data to a file that has been created using prepareWriting(). |
119 | * @param data a pointer to the data |
120 | * @param size the size of the chunk |
121 | * @return true if successful, false otherwise |
122 | */ |
123 | virtual bool writeData( const char* data, qint64 size ); |
124 | |
125 | protected: |
126 | /// Reimplemented from KArchive |
127 | virtual bool doWriteSymLink(const QString &name, const QString &target, |
128 | const QString &user, const QString &group, |
129 | mode_t perm, time_t atime, time_t mtime, time_t ctime); |
130 | /// Reimplemented from KArchive |
131 | virtual bool doPrepareWriting( const QString& name, const QString& user, |
132 | const QString& group, qint64 size, mode_t perm, |
133 | time_t atime, time_t mtime, time_t ctime ); |
134 | |
135 | /** |
136 | * Write data to a file that has been created using prepareWriting(). |
137 | * @param size the size of the file |
138 | * @return true if successful, false otherwise |
139 | */ |
140 | virtual bool doFinishWriting( qint64 size ); |
141 | |
142 | /** |
143 | * Opens the archive for reading. |
144 | * Parses the directory listing of the archive |
145 | * and creates the KArchiveDirectory/KArchiveFile entries. |
146 | * @param mode the mode of the file |
147 | */ |
148 | virtual bool openArchive( QIODevice::OpenMode mode ); |
149 | |
150 | /// Closes the archive |
151 | virtual bool closeArchive(); |
152 | |
153 | /// Reimplemented from KArchive |
154 | virtual bool doWriteDir( const QString& name, const QString& user, |
155 | const QString& group, mode_t perm, time_t atime, |
156 | time_t mtime, time_t ctime ); |
157 | |
158 | protected: |
159 | virtual void virtual_hook( int id, void* data ); |
160 | |
161 | private: |
162 | class KZipPrivate; |
163 | KZipPrivate * const d; |
164 | }; |
165 | |
166 | |
167 | /** |
168 | * A KZipFileEntry represents an file in a zip archive. |
169 | */ |
170 | class KDECORE_EXPORT KZipFileEntry : public KArchiveFile |
171 | { |
172 | public: |
173 | /** |
174 | * Creates a new zip file entry. Do not call this, KZip takes care of it. |
175 | */ |
176 | KZipFileEntry( KZip* zip, const QString& name, int access, int date, |
177 | const QString& user, const QString& group, const QString& symlink, |
178 | const QString& path, qint64 start, qint64 uncompressedSize, |
179 | int encoding, qint64 compressedSize); |
180 | |
181 | /** |
182 | * Destructor. Do not call this. |
183 | */ |
184 | ~KZipFileEntry(); |
185 | |
186 | int encoding() const; |
187 | qint64 compressedSize() const; |
188 | |
189 | /// Only used when writing |
190 | void setCompressedSize(qint64 compressedSize); |
191 | |
192 | /// Header start: only used when writing |
193 | void (qint64 ); |
194 | qint64 () const; |
195 | |
196 | /// CRC: only used when writing |
197 | unsigned long crc32() const; |
198 | void setCRC32(unsigned long crc32); |
199 | |
200 | /// Name with complete path - KArchiveFile::name() is the filename only (no path) |
201 | const QString &path() const; |
202 | |
203 | /** |
204 | * @return the content of this file. |
205 | * Call data() with care (only once per file), this data isn't cached. |
206 | */ |
207 | virtual QByteArray data() const; |
208 | |
209 | /** |
210 | * This method returns a QIODevice to read the file contents. |
211 | * This is obviously for reading only. |
212 | * Note that the ownership of the device is being transferred to the caller, |
213 | * who will have to delete it. |
214 | * The returned device auto-opens (in readonly mode), no need to open it. |
215 | */ |
216 | virtual QIODevice* createDevice() const; |
217 | |
218 | private: |
219 | class KZipFileEntryPrivate; |
220 | KZipFileEntryPrivate * const d; |
221 | }; |
222 | |
223 | #endif |
224 | |