KArchive

karchive.h
1 /* This file is part of the KDE libraries
2  SPDX-FileCopyrightText: 2000-2005 David Faure <[email protected]>
3  SPDX-FileCopyrightText: 2003 Leo Savernik <[email protected]>
4 
5  Moved from ktar.h by Roberto Teixeira <[email protected]>
6 
7  SPDX-License-Identifier: LGPL-2.0-or-later
8 */
9 #ifndef KARCHIVE_H
10 #define KARCHIVE_H
11 
12 #include <sys/stat.h>
13 #include <sys/types.h>
14 
15 #include <QCoreApplication>
16 #include <QDate>
17 #include <QHash>
18 #include <QIODevice>
19 #include <QString>
20 #include <QStringList>
21 
22 #include <karchive_export.h>
23 
24 #ifdef Q_OS_WIN
25 #include <qplatformdefs.h> // mode_t
26 #endif
27 
28 class KArchiveDirectory;
29 class KArchiveFile;
30 
31 class KArchivePrivate;
32 /**
33  * @class KArchive karchive.h KArchive
34  *
35  * KArchive is a base class for reading and writing archives.
36  * @short generic class for reading/writing archives
37  * @author David Faure <[email protected]>
38  */
39 class KARCHIVE_EXPORT KArchive
40 {
41  Q_DECLARE_TR_FUNCTIONS(KArchive)
42 
43 protected:
44  /**
45  * Base constructor (protected since this is a pure virtual class).
46  * @param fileName is a local path (e.g. "/tmp/myfile.ext"),
47  * from which the archive will be read from, or into which the archive
48  * will be written, depending on the mode given to open().
49  */
50  KArchive(const QString &fileName);
51 
52  /**
53  * Base constructor (protected since this is a pure virtual class).
54  * @param dev the I/O device where the archive reads its data
55  * Note that this can be a file, but also a data buffer, a compression filter, etc.
56  * For a file in writing mode it is better to use the other constructor
57  * though, to benefit from the use of QSaveFile when saving.
58  */
59  KArchive(QIODevice *dev);
60 
61 public:
62  virtual ~KArchive();
63 
64  /**
65  * Opens the archive for reading or writing.
66  * Inherited classes might want to reimplement openArchive instead.
67  * @param mode may be QIODevice::ReadOnly or QIODevice::WriteOnly
68  * @see close
69  */
70  virtual bool open(QIODevice::OpenMode mode);
71 
72  /**
73  * Closes the archive.
74  * Inherited classes might want to reimplement closeArchive instead.
75  *
76  * @return true if close succeeded without problems
77  * @see open
78  */
79  virtual bool close();
80 
81  /**
82  * Returns a description of the last error
83  * @since 5.29
84  */
85  QString errorString() const;
86 
87  /**
88  * Checks whether the archive is open.
89  * @return true if the archive is opened
90  */
91  bool isOpen() const;
92 
93  /**
94  * Returns the mode in which the archive was opened
95  * @return the mode in which the archive was opened (QIODevice::ReadOnly or QIODevice::WriteOnly)
96  * @see open()
97  */
98  QIODevice::OpenMode mode() const;
99 
100  /**
101  * The underlying device.
102  * @return the underlying device.
103  */
104  QIODevice *device() const;
105 
106  /**
107  * The name of the archive file, as passed to the constructor that takes a
108  * fileName, or an empty string if you used the QIODevice constructor.
109  * @return the name of the file, or QString() if unknown
110  */
111  QString fileName() const;
112 
113  /**
114  * If an archive is opened for reading, then the contents
115  * of the archive can be accessed via this function.
116  * @return the directory of the archive
117  */
118  const KArchiveDirectory *directory() const;
119 
120  /**
121  * Writes a local file into the archive. The main difference with writeFile,
122  * is that this method minimizes memory usage, by not loading the whole file
123  * into memory in one go.
124  *
125  * If @p fileName is a symbolic link, it will be written as is, i. e.
126  * it will not be resolved before.
127  * @param fileName full path to an existing local file, to be added to the archive.
128  * @param destName the resulting name (or relative path) of the file in the archive.
129  */
130  bool addLocalFile(const QString &fileName, const QString &destName);
131 
132  /**
133  * Writes a local directory into the archive, including all its contents, recursively.
134  * Calls addLocalFile for each file to be added.
135  *
136  * It will also add a @p path that is a symbolic link to a
137  * directory. The symbolic link will be dereferenced and the content of the
138  * directory it is pointing to added recursively. However, symbolic links
139  * *under* @p path will be stored as is.
140  * @param path full path to an existing local directory, to be added to the archive.
141  * @param destName the resulting name (or relative path) of the file in the archive.
142  */
143  bool addLocalDirectory(const QString &path, const QString &destName);
144 
145  /**
146  * If an archive is opened for writing then you can add new directories
147  * using this function. KArchive won't write one directory twice.
148  *
149  * This method also allows some file metadata to be set.
150  * However, depending on the archive type not all metadata might be regarded.
151  *
152  * @param name the name of the directory
153  * @param user the user that owns the directory
154  * @param group the group that owns the directory
155  * @param perm permissions of the directory
156  * @param atime time the file was last accessed
157  * @param mtime modification time of the file
158  * @param ctime time of last status change
159  */
160  bool writeDir(const QString &name,
161  const QString &user = QString(),
162  const QString &group = QString(),
163  mode_t perm = 040755,
164  const QDateTime &atime = QDateTime(),
165  const QDateTime &mtime = QDateTime(),
166  const QDateTime &ctime = QDateTime());
167 
168  /**
169  * Writes a symbolic link to the archive if supported.
170  * The archive must be opened for writing.
171  *
172  * @param name name of symbolic link
173  * @param target target of symbolic link
174  * @param user the user that owns the directory
175  * @param group the group that owns the directory
176  * @param perm permissions of the directory
177  * @param atime time the file was last accessed
178  * @param mtime modification time of the file
179  * @param ctime time of last status change
180  */
181  bool writeSymLink(const QString &name,
182  const QString &target,
183  const QString &user = QString(),
184  const QString &group = QString(),
185  mode_t perm = 0120755,
186  const QDateTime &atime = QDateTime(),
187  const QDateTime &mtime = QDateTime(),
188  const QDateTime &ctime = QDateTime());
189 
190 #if KARCHIVE_ENABLE_DEPRECATED_SINCE(5, 0)
191  /**
192  * @deprecated since 5.0, use writeFile(const QString&, const QByteArray&, mode_t, const QString&, const QString&, const QDateTime&, const QDateTime&, const
193  * QDateTime&)
194  */
195  KARCHIVE_DEPRECATED_VERSION(5,
196  0,
197  "Use KArchive::writeFile(const QString&, const QByteArray&, mode_t, const QString&, const QString&, const QDateTime&, const "
198  "QDateTime&, const QDateTime&)")
199  bool writeFile(const QString &name,
200  const QString &user,
201  const QString &group,
202  const char *data,
203  qint64 size,
204  mode_t perm = 0100644,
205  const QDateTime &atime = QDateTime(),
206  const QDateTime &mtime = QDateTime(),
207  const QDateTime &ctime = QDateTime())
208  {
209  QByteArray array(data, size);
210  return writeFile(name, array, perm, user, group, atime, mtime, ctime);
211  }
212  // The above can lead to ambiguous calls when using "..." for the first 4 arguments,
213  // but that's good, better than unexpected behavior due to the signature change.
214 #endif
215 
216  /**
217  * Writes a new file into the archive.
218  *
219  * The archive must be opened for writing first.
220  *
221  * The necessary parent directories are created automatically
222  * if needed. For instance, writing "mydir/test1" does not
223  * require creating the directory "mydir" first.
224  *
225  * This method also allows some file metadata to be
226  * set. However, depending on the archive type not all metadata might be
227  * written out.
228  *
229  * @param name the name of the file
230  * @param data the data to write
231  * @param perm permissions of the file
232  * @param user the user that owns the file
233  * @param group the group that owns the file
234  * @param atime time the file was last accessed
235  * @param mtime modification time of the file
236  * @param ctime time of last status change
237  */
238  bool writeFile(const QString &name,
239  const QByteArray &data,
240  mode_t perm = 0100644,
241  const QString &user = QString(),
242  const QString &group = QString(),
243  const QDateTime &atime = QDateTime(),
244  const QDateTime &mtime = QDateTime(),
245  const QDateTime &ctime = QDateTime());
246 
247  /**
248  * Here's another way of writing a file into an archive:
249  * Call prepareWriting(), then call writeData()
250  * as many times as wanted then call finishWriting( totalSize ).
251  * For tar.gz files, you need to know the size before hand, it is needed in the header!
252  * For zip files, size isn't used.
253  *
254  * This method also allows some file metadata to be
255  * set. However, depending on the archive type not all metadata might be
256  * regarded.
257  * @param name the name of the file
258  * @param user the user that owns the file
259  * @param group the group that owns the file
260  * @param size the size of the file
261  * @param perm permissions of the file
262  * @param atime time the file was last accessed
263  * @param mtime modification time of the file
264  * @param ctime time of last status change
265  */
266  bool prepareWriting(const QString &name,
267  const QString &user,
268  const QString &group,
269  qint64 size,
270  mode_t perm = 0100644,
271  const QDateTime &atime = QDateTime(),
272  const QDateTime &mtime = QDateTime(),
273  const QDateTime &ctime = QDateTime());
274 
275  /**
276  * Write data into the current file - to be called after calling prepareWriting
277  */
278  virtual bool writeData(const char *data, qint64 size);
279 
280  /**
281  * Call finishWriting after writing the data.
282  * @param size the size of the file
283  * @see prepareWriting()
284  */
285  bool finishWriting(qint64 size);
286 
287 protected:
288  /**
289  * Opens an archive for reading or writing.
290  * Called by open.
291  * @param mode may be QIODevice::ReadOnly or QIODevice::WriteOnly
292  */
293  virtual bool openArchive(QIODevice::OpenMode mode) = 0;
294 
295  /**
296  * Closes the archive.
297  * Called by close.
298  */
299  virtual bool closeArchive() = 0;
300 
301  /**
302  * Sets error description
303  * @param errorStr error description
304  * @since 5.29
305  */
306  void setErrorString(const QString &errorStr);
307 
308  /**
309  * Retrieves or create the root directory.
310  * The default implementation assumes that openArchive() did the parsing,
311  * so it creates a dummy rootdir if none was set (write mode, or no '/' in the archive).
312  * Reimplement this to provide parsing/listing on demand.
313  * @return the root directory
314  */
315  virtual KArchiveDirectory *rootDir();
316 
317  /**
318  * Write a directory to the archive.
319  * This virtual method must be implemented by subclasses.
320  *
321  * Depending on the archive type not all metadata might be used.
322  *
323  * @param name the name of the directory
324  * @param user the user that owns the directory
325  * @param group the group that owns the directory
326  * @param perm permissions of the directory. Use 040755 if you don't have any other information.
327  * @param atime time the file was last accessed
328  * @param mtime modification time of the file
329  * @param ctime time of last status change
330  * @see writeDir
331  */
332  virtual bool doWriteDir(const QString &name,
333  const QString &user,
334  const QString &group,
335  mode_t perm,
336  const QDateTime &atime,
337  const QDateTime &mtime,
338  const QDateTime &ctime) = 0;
339 
340  /**
341  * Writes a symbolic link to the archive.
342  * This virtual method must be implemented by subclasses.
343  *
344  * @param name name of symbolic link
345  * @param target target of symbolic link
346  * @param user the user that owns the directory
347  * @param group the group that owns the directory
348  * @param perm permissions of the directory
349  * @param atime time the file was last accessed
350  * @param mtime modification time of the file
351  * @param ctime time of last status change
352  * @see writeSymLink
353  */
354  virtual bool doWriteSymLink(const QString &name,
355  const QString &target,
356  const QString &user,
357  const QString &group,
358  mode_t perm,
359  const QDateTime &atime,
360  const QDateTime &mtime,
361  const QDateTime &ctime) = 0;
362 
363  /**
364  * This virtual method must be implemented by subclasses.
365  *
366  * Depending on the archive type not all metadata might be used.
367  *
368  * @param name the name of the file
369  * @param user the user that owns the file
370  * @param group the group that owns the file
371  * @param size the size of the file
372  * @param perm permissions of the file. Use 0100644 if you don't have any more specific permissions to set.
373  * @param atime time the file was last accessed
374  * @param mtime modification time of the file
375  * @param ctime time of last status change
376  * @see prepareWriting
377  */
378  virtual bool doPrepareWriting(const QString &name,
379  const QString &user,
380  const QString &group,
381  qint64 size,
382  mode_t perm,
383  const QDateTime &atime,
384  const QDateTime &mtime,
385  const QDateTime &ctime) = 0;
386 
387  /**
388  * Called after writing the data.
389  * This virtual method must be implemented by subclasses.
390  *
391  * @param size the size of the file
392  * @see finishWriting()
393  */
394  virtual bool doFinishWriting(qint64 size) = 0;
395 
396  /**
397  * Ensures that @p path exists, create otherwise.
398  * This handles e.g. tar files missing directory entries, like mico-2.3.0.tar.gz :)
399  * @param path the path of the directory
400  * @return the directory with the given @p path
401  */
402  KArchiveDirectory *findOrCreate(const QString &path);
403 
404  /**
405  * Can be reimplemented in order to change the creation of the device
406  * (when using the fileName constructor). By default this method uses
407  * QSaveFile when saving, and a simple QFile on reading.
408  * This method is called by open().
409  */
410  virtual bool createDevice(QIODevice::OpenMode mode);
411 
412  /**
413  * Can be called by derived classes in order to set the underlying device.
414  * Note that KArchive will -not- own the device, it must be deleted by the derived class.
415  */
416  void setDevice(QIODevice *dev);
417 
418  /**
419  * Derived classes call setRootDir from openArchive,
420  * to set the root directory after parsing an existing archive.
421  */
422  void setRootDir(KArchiveDirectory *rootDir);
423 
424 protected:
425  virtual void virtual_hook(int id, void *data);
426 
427 private:
428  friend class KArchivePrivate;
429  KArchivePrivate *const d;
430 };
431 
432 // for source compat
433 #include "karchivedirectory.h"
434 #include "karchivefile.h"
435 
436 #endif
typedef OpenMode
A directory in an archive.
generic class for reading/writing archives
Definition: karchive.h:39
A file in an archive.
Definition: karchivefile.h:24
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Fri Mar 24 2023 03:59:19 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.