1 /* This file is part of the KDE libraries
2 Copyright (C) 2000-2005 David Faure <faure@kde.org>
3 Copyright (C) 2003 Leo Savernik <l.savernik@aon.at>
5 Moved from ktar.h by Roberto Teixeira <maragato@kde.org>
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License version 2 as published by the Free Software Foundation.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
25 #include <sys/types.h>
27 #include <QtCore/QDate>
28 #include <QtCore/QString>
29 #include <QtCore/QStringList>
30 #include <QtCore/QHash>
32 #include <kio/kio_export.h>
34 class KArchiveDirectory
;
37 class KArchivePrivate
;
39 * KArchive is a base class for reading and writing archives.
40 * @short generic class for reading/writing archives
41 * @author David Faure <faure@kde.org>
43 class KIO_EXPORT KArchive
47 * Base constructor (protected since this is a pure virtual class).
48 * @param fileName is a local path (e.g. "/tmp/myfile.ext"),
49 * from which the archive will be read from, or into which the archive
50 * will be written, depending on the mode given to open().
52 KArchive( const QString
& fileName
);
55 * Base constructor (protected since this is a pure virtual class).
56 * @param dev the I/O device where the archive reads its data
57 * Note that this can be a file, but also a data buffer, a compression filter, etc.
58 * For a file in writing mode it is better to use the other constructor
59 * though, to benefit from the use of KSaveFile when saving.
61 KArchive( QIODevice
* dev
);
67 * Opens the archive for reading or writing.
68 * Inherited classes might want to reimplement openArchive instead.
69 * @param mode may be QIODevice::ReadOnly or QIODevice::WriteOnly
72 virtual bool open( QIODevice::OpenMode mode
);
76 * Inherited classes might want to reimplement closeArchive instead.
78 * @return true if close succeeded without problems
84 * Checks whether the archive is open.
85 * @return true if the archive is opened
90 * Returns the mode in which the archive was opened
91 * @return the mode in which the archive was opened (QIODevice::ReadOnly or QIODevice::WriteOnly)
94 QIODevice::OpenMode
mode() const;
97 * The underlying device.
98 * @return the underlying device.
100 QIODevice
* device() const;
103 * The name of the archive file, as passed to the constructor that takes a
104 * fileName, or an empty string if you used the QIODevice constructor.
105 * @return the name of the file, or QString() if unknown
107 QString
fileName() const;
110 * If an archive is opened for reading, then the contents
111 * of the archive can be accessed via this function.
112 * @return the directory of the archive
114 const KArchiveDirectory
* directory() const;
117 * Writes a local file into the archive. The main difference with writeFile,
118 * is that this method minimizes memory usage, by not loading the whole file
119 * into memory in one go.
121 * If @p fileName is a symbolic link, it will be written as is, i. e.
122 * it will not be resolved before.
123 * @param fileName full path to an existing local file, to be added to the archive.
124 * @param destName the resulting name (or relative path) of the file in the archive.
126 bool addLocalFile( const QString
& fileName
, const QString
& destName
);
129 * Writes a local directory into the archive, including all its contents, recursively.
130 * Calls addLocalFile for each file to be added.
132 * Since KDE 3.2 it will also add a @p path that is a symbolic link to a
133 * directory. The symbolic link will be dereferenced and the content of the
134 * directory it is pointing to added recursively. However, symbolic links
135 * *under* @p path will be stored as is.
136 * @param path full path to an existing local directory, to be added to the archive.
137 * @param destName the resulting name (or relative path) of the file in the archive.
139 bool addLocalDirectory( const QString
& path
, const QString
& destName
);
141 enum { UnknownTime
= static_cast<time_t>( -1 ) };
144 * If an archive is opened for writing then you can add new directories
145 * using this function. KArchive won't write one directory twice.
147 * This method also allows some file metadata to be set.
148 * However, depending on the archive type not all metadata might be regarded.
150 * @param name the name of the directory
151 * @param user the user that owns the directory
152 * @param group the group that owns the directory
153 * @param perm permissions of the directory
154 * @param atime time the file was last accessed
155 * @param mtime modification time of the file
156 * @param ctime time of last status change
158 virtual bool writeDir( const QString
& name
, const QString
& user
, const QString
& group
,
159 mode_t perm
= 040755, time_t atime
= UnknownTime
,
160 time_t mtime
= UnknownTime
, time_t ctime
= UnknownTime
);
163 * Writes a symbolic link to the archive if supported.
164 * The archive must be opened for writing.
166 * @param name name of symbolic link
167 * @param target target of symbolic link
168 * @param user the user that owns the directory
169 * @param group the group that owns the directory
170 * @param perm permissions of the directory
171 * @param atime time the file was last accessed
172 * @param mtime modification time of the file
173 * @param ctime time of last status change
175 virtual bool writeSymLink(const QString
&name
, const QString
&target
,
176 const QString
&user
, const QString
&group
,
177 mode_t perm
= 0120755, time_t atime
= UnknownTime
,
178 time_t mtime
= UnknownTime
, time_t ctime
= UnknownTime
);
181 * If an archive is opened for writing then you can add a new file
182 * using this function. If the file name is for example "mydir/test1" then
183 * the directory "mydir" is automatically appended first if that did not
186 * This method also allows some file metadata to be
187 * set. However, depending on the archive type not all metadata might be
189 * @param name the name of the file
190 * @param user the user that owns the file
191 * @param group the group that owns the file
192 * @param data the data to write (@p size bytes)
193 * @param size the size of the file
194 * @param perm permissions of the file
195 * @param atime time the file was last accessed
196 * @param mtime modification time of the file
197 * @param ctime time of last status change
199 virtual bool writeFile( const QString
& name
, const QString
& user
, const QString
& group
,
200 const char* data
, qint64 size
,
201 mode_t perm
= 0100644, time_t atime
= UnknownTime
,
202 time_t mtime
= UnknownTime
, time_t ctime
= UnknownTime
);
205 * Here's another way of writing a file into an archive:
206 * Call prepareWriting(), then call writeData()
207 * as many times as wanted then call finishWriting( totalSize ).
208 * For tar.gz files, you need to know the size before hand, it is needed in the header!
209 * For zip files, size isn't used.
211 * This method also allows some file metadata to be
212 * set. However, depending on the archive type not all metadata might be
214 * @param name the name of the file
215 * @param user the user that owns the file
216 * @param group the group that owns the file
217 * @param size the size of the file
218 * @param perm permissions of the file
219 * @param atime time the file was last accessed
220 * @param mtime modification time of the file
221 * @param ctime time of last status change
223 virtual bool prepareWriting( const QString
& name
, const QString
& user
,
224 const QString
& group
, qint64 size
,
225 mode_t perm
= 0100644, time_t atime
= UnknownTime
,
226 time_t mtime
= UnknownTime
, time_t ctime
= UnknownTime
);
229 * Write data into the current file - to be called after calling prepareWriting
231 virtual bool writeData( const char* data
, qint64 size
);
234 * Call finishWriting after writing the data.
235 * @param size the size of the file
236 * @see prepareWriting()
238 virtual bool finishWriting( qint64 size
);
242 * Opens an archive for reading or writing.
244 * @param mode may be QIODevice::ReadOnly or QIODevice::WriteOnly
246 virtual bool openArchive( QIODevice::OpenMode mode
) = 0;
249 * Closes the archive.
252 virtual bool closeArchive() = 0;
255 * Retrieves or create the root directory.
256 * The default implementation assumes that openArchive() did the parsing,
257 * so it creates a dummy rootdir if none was set (write mode, or no '/' in the archive).
258 * Reimplement this to provide parsing/listing on demand.
259 * @return the root directory
261 virtual KArchiveDirectory
* rootDir();
264 * Write a directory to the archive.
265 * This virtual method must be implemented by subclasses.
267 * Depending on the archive type not all metadata might be used.
269 * @param name the name of the directory
270 * @param user the user that owns the directory
271 * @param group the group that owns the directory
272 * @param perm permissions of the directory. Use 040755 if you don't have any other information.
273 * @param atime time the file was last accessed
274 * @param mtime modification time of the file
275 * @param ctime time of last status change
278 virtual bool doWriteDir( const QString
& name
, const QString
& user
, const QString
& group
,
279 mode_t perm
, time_t atime
, time_t mtime
, time_t ctime
) = 0;
282 * Writes a symbolic link to the archive.
283 * This virtual method must be implemented by subclasses.
285 * @param name name of symbolic link
286 * @param target target of symbolic link
287 * @param user the user that owns the directory
288 * @param group the group that owns the directory
289 * @param perm permissions of the directory
290 * @param atime time the file was last accessed
291 * @param mtime modification time of the file
292 * @param ctime time of last status change
295 virtual bool doWriteSymLink(const QString
&name
, const QString
&target
,
296 const QString
&user
, const QString
&group
,
297 mode_t perm
, time_t atime
, time_t mtime
, time_t ctime
) = 0;
300 * This virtual method must be implemented by subclasses.
302 * Depending on the archive type not all metadata might be used.
304 * @param name the name of the file
305 * @param user the user that owns the file
306 * @param group the group that owns the file
307 * @param size the size of the file
308 * @param perm permissions of the file. Use 0100644 if you don't have any more specific permissions to set.
309 * @param atime time the file was last accessed
310 * @param mtime modification time of the file
311 * @param ctime time of last status change
312 * @see prepareWriting
314 virtual bool doPrepareWriting( const QString
& name
, const QString
& user
,
315 const QString
& group
, qint64 size
, mode_t perm
,
316 time_t atime
, time_t mtime
, time_t ctime
) = 0;
319 * Called after writing the data.
320 * This virtual method must be implemented by subclasses.
322 * @param size the size of the file
323 * @see finishWriting()
325 virtual bool doFinishWriting( qint64 size
) = 0;
328 * Ensures that @p path exists, create otherwise.
329 * This handles e.g. tar files missing directory entries, like mico-2.3.0.tar.gz :)
330 * @param path the path of the directory
331 * @return the directory with the given @p path
333 KArchiveDirectory
* findOrCreate( const QString
& path
);
336 * Can be reimplemented in order to change the creation of the device
337 * (when using the fileName constructor). By default this method uses
338 * KSaveFile when saving, and a simple QFile on reading.
339 * This method is called by open().
341 virtual bool createDevice( QIODevice::OpenMode mode
);
344 * Can be called by derived classes in order to set the underlying device.
345 * Note that KArchive will -not- own the device, it must be deleted by the derived class.
347 void setDevice( QIODevice
*dev
);
350 * Derived classes call setRootDir from openArchive,
351 * to set the root directory after parsing an existing archive.
353 void setRootDir( KArchiveDirectory
*rootDir
);
356 virtual void virtual_hook( int id
, void* data
);
358 KArchivePrivate
* const d
;
361 class KArchiveEntryPrivate
;
363 * A base class for entries in an KArchive.
364 * @short Base class for the archive-file's directory structure.
367 * @see KArchiveDirectory
369 class KIO_EXPORT KArchiveEntry
373 * Creates a new entry.
374 * @param archive the entries archive
375 * @param name the name of the entry
376 * @param access the permissions in unix format
377 * @param date the date (in seconds since 1970)
378 * @param user the user that owns the entry
379 * @param group the group that owns the entry
380 * @param symlink the symlink, or QString()
382 KArchiveEntry( KArchive
* archive
, const QString
& name
, int access
, int date
,
383 const QString
& user
, const QString
& group
,
384 const QString
& symlink
);
386 virtual ~KArchiveEntry();
389 * Creation date of the file.
390 * @return the creation date
392 QDateTime
datetime() const;
395 * Creation date of the file.
396 * @return the creation date in seconds since 1970
401 * Name of the file without path.
402 * @return the file name without path
404 QString
name() const;
406 * The permissions and mode flags as returned by the stat() function
408 * @return the permissions
410 mode_t
permissions() const;
412 * User who created the file.
413 * @return the owner of the file
415 QString
user() const;
417 * Group of the user who created the file.
418 * @return the group of the file
420 QString
group() const;
423 * Symlink if there is one.
424 * @return the symlink, or QString()
426 QString
symLinkTarget() const;
429 * Checks whether the entry is a file.
430 * @return true if this entry is a file
432 virtual bool isFile() const;
435 * Checks whether the entry is a directory.
436 * @return true if this entry is a directory
438 virtual bool isDirectory() const;
441 KArchive
* archive() const;
444 virtual void virtual_hook( int id
, void* data
);
446 KArchiveEntryPrivate
* const d
;
449 class KArchiveFilePrivate
;
451 * Represents a file entry in a KArchive.
452 * @short A file in an archive.
455 * @see KArchiveDirectory
457 class KIO_EXPORT KArchiveFile
: public KArchiveEntry
461 * Creates a new file entry. Do not call this, KArchive takes care of it.
462 * @param archive the entries archive
463 * @param name the name of the entry
464 * @param access the permissions in unix format
465 * @param date the date (in seconds since 1970)
466 * @param user the user that owns the entry
467 * @param group the group that owns the entry
468 * @param symlink the symlink, or QString()
469 * @param pos the position of the file in the directory
470 * @param size the size of the file
472 KArchiveFile( KArchive
* archive
, const QString
& name
, int access
, int date
,
473 const QString
& user
, const QString
& group
, const QString
&symlink
,
474 qint64 pos
, qint64 size
);
477 * Destructor. Do not call this, KArchive takes care of it.
479 virtual ~KArchiveFile();
482 * Position of the data in the [uncompressed] archive.
483 * @return the position of the file
485 qint64
position() const;
488 * @return the size of the file
492 * Set size of data, usually after writing the file.
493 * @param s the new size of the file
495 void setSize( qint64 s
);
498 * Returns the data of the file.
499 * Call data() with care (only once per file), this data isn't cached.
500 * @return the content of this file.
502 virtual QByteArray
data() const;
505 * This method returns QIODevice (internal class: KLimitedIODevice)
506 * on top of the underlying QIODevice. This is obviously for reading only.
508 * WARNING: Note that the ownership of the device is being transferred to the caller,
509 * who will have to delete it.
511 * The returned device auto-opens (in readonly mode), no need to open it.
512 * @return the QIODevice of the file
514 virtual QIODevice
*createDevice() const;
517 * Checks whether this entry is a file.
518 * @return true, since this entry is a file
520 virtual bool isFile() const;
523 * Extracts the file to the directory @p dest
524 * @param dest the directory to extract to
526 void copyTo(const QString
& dest
) const;
529 virtual void virtual_hook( int id
, void* data
);
531 KArchiveFilePrivate
* const d
;
534 class KArchiveDirectoryPrivate
;
536 * Represents a directory entry in a KArchive.
537 * @short A directory in an archive.
542 class KIO_EXPORT KArchiveDirectory
: public KArchiveEntry
546 * Creates a new directory entry.
547 * @param archive the entries archive
548 * @param name the name of the entry
549 * @param access the permissions in unix format
550 * @param date the date (in seconds since 1970)
551 * @param user the user that owns the entry
552 * @param group the group that owns the entry
553 * @param symlink the symlink, or QString()
555 KArchiveDirectory( KArchive
* archive
, const QString
& name
, int access
, int date
,
556 const QString
& user
, const QString
& group
,
557 const QString
& symlink
);
559 virtual ~KArchiveDirectory();
562 * Returns a list of sub-entries.
563 * Note that the list is not sorted, it's even in random order (due to using a hashtable).
564 * Use sort() on the result to sort the list by filename.
566 * @return the names of all entries in this directory (filenames, no path).
568 QStringList
entries() const;
570 * Returns the entry with the given name.
571 * @param name may be "test1", "mydir/test3", "mydir/mysubdir/test3", etc.
572 * @return a pointer to the entry in the directory.
574 const KArchiveEntry
* entry( const QString
& name
) const;
578 * Adds a new entry to the directory.
580 void addEntry( KArchiveEntry
* );
583 * Checks whether this entry is a directory.
584 * @return true, since this entry is a directory
586 virtual bool isDirectory() const;
589 * Extracts all entries in this archive directory to the directory
591 * @param dest the directory to extract to
592 * @param recursive if set to true, subdirectories are extracted as well
594 void copyTo(const QString
& dest
, bool recursive
= true) const;
597 virtual void virtual_hook( int id
, void* data
);
599 KArchiveDirectoryPrivate
* const d
;