diff options
Diffstat (limited to 'utils/themeeditor/quazip/quazipfile.h')
-rw-r--r-- | utils/themeeditor/quazip/quazipfile.h | 442 |
1 files changed, 442 insertions, 0 deletions
diff --git a/utils/themeeditor/quazip/quazipfile.h b/utils/themeeditor/quazip/quazipfile.h new file mode 100644 index 0000000000..09af5bceca --- /dev/null +++ b/utils/themeeditor/quazip/quazipfile.h | |||
@@ -0,0 +1,442 @@ | |||
1 | #ifndef QUA_ZIPFILE_H | ||
2 | #define QUA_ZIPFILE_H | ||
3 | |||
4 | /* | ||
5 | -- A kind of "standard" GPL license statement -- | ||
6 | QuaZIP - a Qt/C++ wrapper for the ZIP/UNZIP package | ||
7 | Copyright (C) 2005-2008 Sergey A. Tachenov | ||
8 | |||
9 | This program is free software; you can redistribute it and/or modify it | ||
10 | under the terms of the GNU General Public License as published by the | ||
11 | Free Software Foundation; either version 2 of the License, or (at your | ||
12 | option) any later version. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, but | ||
15 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General | ||
17 | Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License along | ||
20 | with this program; if not, write to the Free Software Foundation, Inc., | ||
21 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | |||
23 | -- A kind of "standard" GPL license statement ends here -- | ||
24 | |||
25 | See COPYING file for GPL. | ||
26 | |||
27 | You are also permitted to use QuaZIP under the terms of LGPL (see | ||
28 | COPYING.LGPL). You are free to choose either license, but please note | ||
29 | that QuaZIP makes use of Qt, which is not licensed under LGPL. So if | ||
30 | you are using Open Source edition of Qt, you therefore MUST use GPL for | ||
31 | your code based on QuaZIP, since it would be also based on Qt in this | ||
32 | case. If you are Qt commercial license owner, then you are free to use | ||
33 | QuaZIP as long as you respect either GPL or LGPL for QuaZIP code. | ||
34 | **/ | ||
35 | |||
36 | #include <QIODevice> | ||
37 | |||
38 | #include "quazip.h" | ||
39 | #include "quazipnewinfo.h" | ||
40 | |||
41 | /// A file inside ZIP archive. | ||
42 | /** \class QuaZipFile quazipfile.h <quazip/quazipfile.h> | ||
43 | * This is the most interesting class. Not only it provides C++ | ||
44 | * interface to the ZIP/UNZIP package, but also integrates it with Qt by | ||
45 | * subclassing QIODevice. This makes possible to access files inside ZIP | ||
46 | * archive using QTextStream or QDataStream, for example. Actually, this | ||
47 | * is the main purpose of the whole QuaZIP library. | ||
48 | * | ||
49 | * You can either use existing QuaZip instance to create instance of | ||
50 | * this class or pass ZIP archive file name to this class, in which case | ||
51 | * it will create internal QuaZip object. See constructors' descriptions | ||
52 | * for details. Writing is only possible with the existing instance. | ||
53 | * | ||
54 | * \section quazipfile-sequential Sequential or random-access? | ||
55 | * | ||
56 | * At the first thought, QuaZipFile has fixed size, the start and the | ||
57 | * end and should be therefore considered random-access device. But | ||
58 | * there is one major obstacle to making it random-access: ZIP/UNZIP API | ||
59 | * does not support seek() operation and the only way to implement it is | ||
60 | * through reopening the file and re-reading to the required position, | ||
61 | * but this is prohibitely slow. | ||
62 | * | ||
63 | * Therefore, QuaZipFile is considered to be a sequential device. This | ||
64 | * has advantage of availability of the ungetChar() operation (QIODevice | ||
65 | * does not implement it properly for non-sequential devices unless they | ||
66 | * support seek()). Disadvantage is a somewhat strange behaviour of the | ||
67 | * size() and pos() functions. This should be kept in mind while using | ||
68 | * this class. | ||
69 | * | ||
70 | **/ | ||
71 | class QuaZipFile: public QIODevice { | ||
72 | Q_OBJECT | ||
73 | private: | ||
74 | QuaZip *zip; | ||
75 | QString fileName; | ||
76 | QuaZip::CaseSensitivity caseSensitivity; | ||
77 | bool raw; | ||
78 | qint64 writePos; | ||
79 | // these two are for writing raw files | ||
80 | ulong uncompressedSize; | ||
81 | quint32 crc; | ||
82 | bool internal; | ||
83 | int zipError; | ||
84 | // these are not supported nor implemented | ||
85 | QuaZipFile(const QuaZipFile& that); | ||
86 | QuaZipFile& operator=(const QuaZipFile& that); | ||
87 | void resetZipError()const {setZipError(UNZ_OK);} | ||
88 | // const, but sets zipError! | ||
89 | void setZipError(int zipError)const; | ||
90 | protected: | ||
91 | /// Implementation of the QIODevice::readData(). | ||
92 | qint64 readData(char *data, qint64 maxSize); | ||
93 | /// Implementation of the QIODevice::writeData(). | ||
94 | qint64 writeData(const char *data, qint64 maxSize); | ||
95 | public: | ||
96 | /// Constructs a QuaZipFile instance. | ||
97 | /** You should use setZipName() and setFileName() or setZip() before | ||
98 | * trying to call open() on the constructed object. | ||
99 | **/ | ||
100 | QuaZipFile(); | ||
101 | /// Constructs a QuaZipFile instance. | ||
102 | /** \a parent argument specifies this object's parent object. | ||
103 | * | ||
104 | * You should use setZipName() and setFileName() or setZip() before | ||
105 | * trying to call open() on the constructed object. | ||
106 | **/ | ||
107 | QuaZipFile(QObject *parent); | ||
108 | /// Constructs a QuaZipFile instance. | ||
109 | /** \a parent argument specifies this object's parent object and \a | ||
110 | * zipName specifies ZIP archive file name. | ||
111 | * | ||
112 | * You should use setFileName() before trying to call open() on the | ||
113 | * constructed object. | ||
114 | * | ||
115 | * QuaZipFile constructed by this constructor can be used for read | ||
116 | * only access. Use QuaZipFile(QuaZip*,QObject*) for writing. | ||
117 | **/ | ||
118 | QuaZipFile(const QString& zipName, QObject *parent =NULL); | ||
119 | /// Constructs a QuaZipFile instance. | ||
120 | /** \a parent argument specifies this object's parent object, \a | ||
121 | * zipName specifies ZIP archive file name and \a fileName and \a cs | ||
122 | * specify a name of the file to open inside archive. | ||
123 | * | ||
124 | * QuaZipFile constructed by this constructor can be used for read | ||
125 | * only access. Use QuaZipFile(QuaZip*,QObject*) for writing. | ||
126 | * | ||
127 | * \sa QuaZip::setCurrentFile() | ||
128 | **/ | ||
129 | QuaZipFile(const QString& zipName, const QString& fileName, | ||
130 | QuaZip::CaseSensitivity cs =QuaZip::csDefault, QObject *parent =NULL); | ||
131 | /// Constructs a QuaZipFile instance. | ||
132 | /** \a parent argument specifies this object's parent object. | ||
133 | * | ||
134 | * \a zip is the pointer to the existing QuaZip object. This | ||
135 | * QuaZipFile object then can be used to read current file in the | ||
136 | * \a zip or to write to the file inside it. | ||
137 | * | ||
138 | * \warning Using this constructor for reading current file can be | ||
139 | * tricky. Let's take the following example: | ||
140 | * \code | ||
141 | * QuaZip zip("archive.zip"); | ||
142 | * zip.open(QuaZip::mdUnzip); | ||
143 | * zip.setCurrentFile("file-in-archive"); | ||
144 | * QuaZipFile file(&zip); | ||
145 | * file.open(QIODevice::ReadOnly); | ||
146 | * // ok, now we can read from the file | ||
147 | * file.read(somewhere, some); | ||
148 | * zip.setCurrentFile("another-file-in-archive"); // oops... | ||
149 | * QuaZipFile anotherFile(&zip); | ||
150 | * anotherFile.open(QIODevice::ReadOnly); | ||
151 | * anotherFile.read(somewhere, some); // this is still ok... | ||
152 | * file.read(somewhere, some); // and this is NOT | ||
153 | * \endcode | ||
154 | * So, what exactly happens here? When we change current file in the | ||
155 | * \c zip archive, \c file that references it becomes invalid | ||
156 | * (actually, as far as I understand ZIP/UNZIP sources, it becomes | ||
157 | * closed, but QuaZipFile has no means to detect it). | ||
158 | * | ||
159 | * Summary: do not close \c zip object or change its current file as | ||
160 | * long as QuaZipFile is open. Even better - use another constructors | ||
161 | * which create internal QuaZip instances, one per object, and | ||
162 | * therefore do not cause unnecessary trouble. This constructor may | ||
163 | * be useful, though, if you already have a QuaZip instance and do | ||
164 | * not want to access several files at once. Good example: | ||
165 | * \code | ||
166 | * QuaZip zip("archive.zip"); | ||
167 | * zip.open(QuaZip::mdUnzip); | ||
168 | * // first, we need some information about archive itself | ||
169 | * QByteArray comment=zip.getComment(); | ||
170 | * // and now we are going to access files inside it | ||
171 | * QuaZipFile file(&zip); | ||
172 | * for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile()) { | ||
173 | * file.open(QIODevice::ReadOnly); | ||
174 | * // do something cool with file here | ||
175 | * file.close(); // do not forget to close! | ||
176 | * } | ||
177 | * zip.close(); | ||
178 | * \endcode | ||
179 | **/ | ||
180 | QuaZipFile(QuaZip *zip, QObject *parent =NULL); | ||
181 | /// Destroys a QuaZipFile instance. | ||
182 | /** Closes file if open, destructs internal QuaZip object (if it | ||
183 | * exists and \em is internal, of course). | ||
184 | **/ | ||
185 | virtual ~QuaZipFile(); | ||
186 | /// Returns the ZIP archive file name. | ||
187 | /** If this object was created by passing QuaZip pointer to the | ||
188 | * constructor, this function will return that QuaZip's file name | ||
189 | * (or null string if that object does not have file name yet). | ||
190 | * | ||
191 | * Otherwise, returns associated ZIP archive file name or null | ||
192 | * string if there are no name set yet. | ||
193 | * | ||
194 | * \sa setZipName() getFileName() | ||
195 | **/ | ||
196 | QString getZipName()const; | ||
197 | /// Returns a pointer to the associated QuaZip object. | ||
198 | /** Returns \c NULL if there is no associated QuaZip or it is | ||
199 | * internal (so you will not mess with it). | ||
200 | **/ | ||
201 | QuaZip* getZip()const; | ||
202 | /// Returns file name. | ||
203 | /** This function returns file name you passed to this object either | ||
204 | * by using | ||
205 | * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*) | ||
206 | * or by calling setFileName(). Real name of the file may differ in | ||
207 | * case if you used case-insensitivity. | ||
208 | * | ||
209 | * Returns null string if there is no file name set yet. This is the | ||
210 | * case when this QuaZipFile operates on the existing QuaZip object | ||
211 | * (constructor QuaZipFile(QuaZip*,QObject*) or setZip() was used). | ||
212 | * | ||
213 | * \sa getActualFileName | ||
214 | **/ | ||
215 | QString getFileName()const {return fileName;} | ||
216 | /// Returns case sensitivity of the file name. | ||
217 | /** This function returns case sensitivity argument you passed to | ||
218 | * this object either by using | ||
219 | * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*) | ||
220 | * or by calling setFileName(). | ||
221 | * | ||
222 | * Returns unpredictable value if getFileName() returns null string | ||
223 | * (this is the case when you did not used setFileName() or | ||
224 | * constructor above). | ||
225 | * | ||
226 | * \sa getFileName | ||
227 | **/ | ||
228 | QuaZip::CaseSensitivity getCaseSensitivity()const {return caseSensitivity;} | ||
229 | /// Returns the actual file name in the archive. | ||
230 | /** This is \em not a ZIP archive file name, but a name of file inside | ||
231 | * archive. It is not necessary the same name that you have passed | ||
232 | * to the | ||
233 | * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*), | ||
234 | * setFileName() or QuaZip::setCurrentFile() - this is the real file | ||
235 | * name inside archive, so it may differ in case if the file name | ||
236 | * search was case-insensitive. | ||
237 | * | ||
238 | * Equivalent to calling getCurrentFileName() on the associated | ||
239 | * QuaZip object. Returns null string if there is no associated | ||
240 | * QuaZip object or if it does not have a current file yet. And this | ||
241 | * is the case if you called setFileName() but did not open the | ||
242 | * file yet. So this is perfectly fine: | ||
243 | * \code | ||
244 | * QuaZipFile file("somezip.zip"); | ||
245 | * file.setFileName("somefile"); | ||
246 | * QString name=file.getName(); // name=="somefile" | ||
247 | * QString actual=file.getActualFileName(); // actual is null string | ||
248 | * file.open(QIODevice::ReadOnly); | ||
249 | * QString actual=file.getActualFileName(); // actual can be "SoMeFiLe" on Windows | ||
250 | * \endcode | ||
251 | * | ||
252 | * \sa getZipName(), getFileName(), QuaZip::CaseSensitivity | ||
253 | **/ | ||
254 | QString getActualFileName()const; | ||
255 | /// Sets the ZIP archive file name. | ||
256 | /** Automatically creates internal QuaZip object and destroys | ||
257 | * previously created internal QuaZip object, if any. | ||
258 | * | ||
259 | * Will do nothing if this file is already open. You must close() it | ||
260 | * first. | ||
261 | **/ | ||
262 | void setZipName(const QString& zipName); | ||
263 | /// Returns \c true if the file was opened in raw mode. | ||
264 | /** If the file is not open, the returned value is undefined. | ||
265 | * | ||
266 | * \sa open(OpenMode,int*,int*,bool,const char*) | ||
267 | **/ | ||
268 | bool isRaw()const {return raw;} | ||
269 | /// Binds to the existing QuaZip instance. | ||
270 | /** This function destroys internal QuaZip object, if any, and makes | ||
271 | * this QuaZipFile to use current file in the \a zip object for any | ||
272 | * further operations. See QuaZipFile(QuaZip*,QObject*) for the | ||
273 | * possible pitfalls. | ||
274 | * | ||
275 | * Will do nothing if the file is currently open. You must close() | ||
276 | * it first. | ||
277 | **/ | ||
278 | void setZip(QuaZip *zip); | ||
279 | /// Sets the file name. | ||
280 | /** Will do nothing if at least one of the following conditions is | ||
281 | * met: | ||
282 | * - ZIP name has not been set yet (getZipName() returns null | ||
283 | * string). | ||
284 | * - This QuaZipFile is associated with external QuaZip. In this | ||
285 | * case you should call that QuaZip's setCurrentFile() function | ||
286 | * instead! | ||
287 | * - File is already open so setting the name is meaningless. | ||
288 | * | ||
289 | * \sa QuaZip::setCurrentFile | ||
290 | **/ | ||
291 | void setFileName(const QString& fileName, QuaZip::CaseSensitivity cs =QuaZip::csDefault); | ||
292 | /// Opens a file for reading. | ||
293 | /** Returns \c true on success, \c false otherwise. | ||
294 | * Call getZipError() to get error code. | ||
295 | * | ||
296 | * \note Since ZIP/UNZIP API provides buffered reading only, | ||
297 | * QuaZipFile does not support unbuffered reading. So do not pass | ||
298 | * QIODevice::Unbuffered flag in \a mode, or open will fail. | ||
299 | **/ | ||
300 | virtual bool open(OpenMode mode); | ||
301 | /// Opens a file for reading. | ||
302 | /** \overload | ||
303 | * Argument \a password specifies a password to decrypt the file. If | ||
304 | * it is NULL then this function behaves just like open(OpenMode). | ||
305 | **/ | ||
306 | bool open(OpenMode mode, const char *password) | ||
307 | {return open(mode, NULL, NULL, false, password);} | ||
308 | /// Opens a file for reading. | ||
309 | /** \overload | ||
310 | * Argument \a password specifies a password to decrypt the file. | ||
311 | * | ||
312 | * An integers pointed by \a method and \a level will receive codes | ||
313 | * of the compression method and level used. See unzip.h. | ||
314 | * | ||
315 | * If raw is \c true then no decompression is performed. | ||
316 | * | ||
317 | * \a method should not be \c NULL. \a level can be \c NULL if you | ||
318 | * don't want to know the compression level. | ||
319 | **/ | ||
320 | bool open(OpenMode mode, int *method, int *level, bool raw, const char *password =NULL); | ||
321 | /// Opens a file for writing. | ||
322 | /** \a info argument specifies information about file. It should at | ||
323 | * least specify a correct file name. Also, it is a good idea to | ||
324 | * specify correct timestamp (by default, current time will be | ||
325 | * used). See QuaZipNewInfo. | ||
326 | * | ||
327 | * Arguments \a password and \a crc provide necessary information | ||
328 | * for crypting. Note that you should specify both of them if you | ||
329 | * need crypting. If you do not, pass \c NULL as password, but you | ||
330 | * still need to specify \a crc if you are going to use raw mode | ||
331 | * (see below). | ||
332 | * | ||
333 | * Arguments \a method and \a level specify compression method and | ||
334 | * level. | ||
335 | * | ||
336 | * If \a raw is \c true, no compression is performed. In this case, | ||
337 | * \a crc and uncompressedSize field of the \a info are required. | ||
338 | * | ||
339 | * Arguments \a windowBits, \a memLevel, \a strategy provide zlib | ||
340 | * algorithms tuning. See deflateInit2() in zlib. | ||
341 | **/ | ||
342 | bool open(OpenMode mode, const QuaZipNewInfo& info, | ||
343 | const char *password =NULL, quint32 crc =0, | ||
344 | int method =Z_DEFLATED, int level =Z_DEFAULT_COMPRESSION, bool raw =false, | ||
345 | int windowBits =-MAX_WBITS, int memLevel =DEF_MEM_LEVEL, int strategy =Z_DEFAULT_STRATEGY); | ||
346 | /// Returns \c true, but \ref quazipfile-sequential "beware"! | ||
347 | virtual bool isSequential()const; | ||
348 | /// Returns current position in the file. | ||
349 | /** Implementation of the QIODevice::pos(). When reading, this | ||
350 | * function is a wrapper to the ZIP/UNZIP unztell(), therefore it is | ||
351 | * unable to keep track of the ungetChar() calls (which is | ||
352 | * non-virtual and therefore is dangerous to reimplement). So if you | ||
353 | * are using ungetChar() feature of the QIODevice, this function | ||
354 | * reports incorrect value until you get back characters which you | ||
355 | * ungot. | ||
356 | * | ||
357 | * When writing, pos() returns number of bytes already written | ||
358 | * (uncompressed unless you use raw mode). | ||
359 | * | ||
360 | * \note Although | ||
361 | * \ref quazipfile-sequential "QuaZipFile is a sequential device" | ||
362 | * and therefore pos() should always return zero, it does not, | ||
363 | * because it would be misguiding. Keep this in mind. | ||
364 | * | ||
365 | * This function returns -1 if the file or archive is not open. | ||
366 | * | ||
367 | * Error code returned by getZipError() is not affected by this | ||
368 | * function call. | ||
369 | **/ | ||
370 | virtual qint64 pos()const; | ||
371 | /// Returns \c true if the end of file was reached. | ||
372 | /** This function returns \c false in the case of error. This means | ||
373 | * that you called this function on either not open file, or a file | ||
374 | * in the not open archive or even on a QuaZipFile instance that | ||
375 | * does not even have QuaZip instance associated. Do not do that | ||
376 | * because there is no means to determine whether \c false is | ||
377 | * returned because of error or because end of file was reached. | ||
378 | * Well, on the other side you may interpret \c false return value | ||
379 | * as "there is no file open to check for end of file and there is | ||
380 | * no end of file therefore". | ||
381 | * | ||
382 | * When writing, this function always returns \c true (because you | ||
383 | * are always writing to the end of file). | ||
384 | * | ||
385 | * Error code returned by getZipError() is not affected by this | ||
386 | * function call. | ||
387 | **/ | ||
388 | virtual bool atEnd()const; | ||
389 | /// Returns file size. | ||
390 | /** This function returns csize() if the file is open for reading in | ||
391 | * raw mode, usize() if it is open for reading in normal mode and | ||
392 | * pos() if it is open for writing. | ||
393 | * | ||
394 | * Returns -1 on error, call getZipError() to get error code. | ||
395 | * | ||
396 | * \note This function returns file size despite that | ||
397 | * \ref quazipfile-sequential "QuaZipFile is considered to be sequential device", | ||
398 | * for which size() should return bytesAvailable() instead. But its | ||
399 | * name would be very misguiding otherwise, so just keep in mind | ||
400 | * this inconsistence. | ||
401 | **/ | ||
402 | virtual qint64 size()const; | ||
403 | /// Returns compressed file size. | ||
404 | /** Equivalent to calling getFileInfo() and then getting | ||
405 | * compressedSize field, but more convenient and faster. | ||
406 | * | ||
407 | * File must be open for reading before calling this function. | ||
408 | * | ||
409 | * Returns -1 on error, call getZipError() to get error code. | ||
410 | **/ | ||
411 | qint64 csize()const; | ||
412 | /// Returns uncompressed file size. | ||
413 | /** Equivalent to calling getFileInfo() and then getting | ||
414 | * uncompressedSize field, but more convenient and faster. See | ||
415 | * getFileInfo() for a warning. | ||
416 | * | ||
417 | * File must be open for reading before calling this function. | ||
418 | * | ||
419 | * Returns -1 on error, call getZipError() to get error code. | ||
420 | **/ | ||
421 | qint64 usize()const; | ||
422 | /// Gets information about current file. | ||
423 | /** This function does the same thing as calling | ||
424 | * QuaZip::getCurrentFileInfo() on the associated QuaZip object, | ||
425 | * but you can not call getCurrentFileInfo() if the associated | ||
426 | * QuaZip is internal (because you do not have access to it), while | ||
427 | * you still can call this function in that case. | ||
428 | * | ||
429 | * File must be open for reading before calling this function. | ||
430 | * | ||
431 | * Returns \c false in the case of an error. | ||
432 | **/ | ||
433 | bool getFileInfo(QuaZipFileInfo *info); | ||
434 | /// Closes the file. | ||
435 | /** Call getZipError() to determine if the close was successful. | ||
436 | **/ | ||
437 | virtual void close(); | ||
438 | /// Returns the error code returned by the last ZIP/UNZIP API call. | ||
439 | int getZipError()const {return zipError;} | ||
440 | }; | ||
441 | |||
442 | #endif | ||