File indexing completed on 2025-03-09 03:38:37
0001 /* This file is part of the KDE libraries 0002 SPDX-FileCopyrightText: 2000-2005 David Faure <faure@kde.org> 0003 SPDX-FileCopyrightText: 2003 Leo Savernik <l.savernik@aon.at> 0004 0005 Moved from ktar.h by Roberto Teixeira <maragato@kde.org> 0006 0007 SPDX-License-Identifier: LGPL-2.0-or-later 0008 */ 0009 #ifndef KARCHIVE_H 0010 #define KARCHIVE_H 0011 0012 #include <sys/stat.h> 0013 #include <sys/types.h> 0014 0015 #include <QByteArrayView> 0016 #include <QCoreApplication> 0017 #include <QDate> 0018 #include <QHash> 0019 #include <QIODevice> 0020 #include <QString> 0021 #include <QStringList> 0022 0023 #include <karchive_export.h> 0024 0025 #ifdef Q_OS_WIN 0026 #include <qplatformdefs.h> // mode_t 0027 #endif 0028 0029 class KArchiveDirectory; 0030 class KArchiveFile; 0031 0032 class KArchivePrivate; 0033 /** 0034 * @class KArchive karchive.h KArchive 0035 * 0036 * KArchive is a base class for reading and writing archives. 0037 * @short generic class for reading/writing archives 0038 * @author David Faure <faure@kde.org> 0039 */ 0040 class KARCHIVE_EXPORT KArchive 0041 { 0042 Q_DECLARE_TR_FUNCTIONS(KArchive) 0043 0044 protected: 0045 /** 0046 * Base constructor (protected since this is a pure virtual class). 0047 * @param fileName is a local path (e.g. "/tmp/myfile.ext"), 0048 * from which the archive will be read from, or into which the archive 0049 * will be written, depending on the mode given to open(). 0050 */ 0051 explicit KArchive(const QString &fileName); 0052 0053 /** 0054 * Base constructor (protected since this is a pure virtual class). 0055 * @param dev the I/O device where the archive reads its data 0056 * Note that this can be a file, but also a data buffer, a compression filter, etc. 0057 * For a file in writing mode it is better to use the other constructor 0058 * though, to benefit from the use of QSaveFile when saving. 0059 */ 0060 explicit KArchive(QIODevice *dev); 0061 0062 public: 0063 virtual ~KArchive(); 0064 0065 /** 0066 * Opens the archive for reading or writing. 0067 * Inherited classes might want to reimplement openArchive instead. 0068 * @param mode may be QIODevice::ReadOnly or QIODevice::WriteOnly 0069 * @see close 0070 */ 0071 virtual bool open(QIODevice::OpenMode mode); 0072 0073 /** 0074 * Closes the archive. 0075 * Inherited classes might want to reimplement closeArchive instead. 0076 * 0077 * @return true if close succeeded without problems 0078 * @see open 0079 */ 0080 virtual bool close(); 0081 0082 /** 0083 * Returns a description of the last error 0084 * @since 5.29 0085 */ 0086 QString errorString() const; 0087 0088 /** 0089 * Checks whether the archive is open. 0090 * @return true if the archive is opened 0091 */ 0092 bool isOpen() const; 0093 0094 /** 0095 * Returns the mode in which the archive was opened 0096 * @return the mode in which the archive was opened (QIODevice::ReadOnly or QIODevice::WriteOnly) 0097 * @see open() 0098 */ 0099 QIODevice::OpenMode mode() const; 0100 0101 /** 0102 * The underlying device. 0103 * @return the underlying device. 0104 */ 0105 QIODevice *device() const; 0106 0107 /** 0108 * The name of the archive file, as passed to the constructor that takes a 0109 * fileName, or an empty string if you used the QIODevice constructor. 0110 * @return the name of the file, or QString() if unknown 0111 */ 0112 QString fileName() const; 0113 0114 /** 0115 * If an archive is opened for reading, then the contents 0116 * of the archive can be accessed via this function. 0117 * @return the directory of the archive 0118 */ 0119 const KArchiveDirectory *directory() const; 0120 0121 /** 0122 * Writes a local file into the archive. The main difference with writeFile, 0123 * is that this method minimizes memory usage, by not loading the whole file 0124 * into memory in one go. 0125 * 0126 * If @p fileName is a symbolic link, it will be written as is, i.e. 0127 * it will not be resolved before. 0128 * @param fileName full path to an existing local file, to be added to the archive. 0129 * @param destName the resulting name (or relative path) of the file in the archive. 0130 */ 0131 bool addLocalFile(const QString &fileName, const QString &destName); 0132 0133 /** 0134 * Writes a local directory into the archive, including all its contents, recursively. 0135 * Calls addLocalFile for each file to be added. 0136 * 0137 * It will also add a @p path that is a symbolic link to a 0138 * directory. The symbolic link will be dereferenced and the content of the 0139 * directory it is pointing to added recursively. However, symbolic links 0140 * *under* @p path will be stored as is. 0141 * @param path full path to an existing local directory, to be added to the archive. 0142 * @param destName the resulting name (or relative path) of the file in the archive. 0143 */ 0144 bool addLocalDirectory(const QString &path, const QString &destName); 0145 0146 /** 0147 * If an archive is opened for writing then you can add new directories 0148 * using this function. KArchive won't write one directory twice. 0149 * 0150 * This method also allows some file metadata to be set. 0151 * However, depending on the archive type not all metadata might be regarded. 0152 * 0153 * @param name the name of the directory 0154 * @param user the user that owns the directory 0155 * @param group the group that owns the directory 0156 * @param perm permissions of the directory 0157 * @param atime time the file was last accessed 0158 * @param mtime modification time of the file 0159 * @param ctime time of last status change 0160 */ 0161 bool writeDir(const QString &name, 0162 const QString &user = QString(), 0163 const QString &group = QString(), 0164 mode_t perm = 040755, 0165 const QDateTime &atime = QDateTime(), 0166 const QDateTime &mtime = QDateTime(), 0167 const QDateTime &ctime = QDateTime()); 0168 0169 /** 0170 * Writes a symbolic link to the archive if supported. 0171 * The archive must be opened for writing. 0172 * 0173 * @param name name of symbolic link 0174 * @param target target of symbolic link 0175 * @param user the user that owns the directory 0176 * @param group the group that owns the directory 0177 * @param perm permissions of the directory 0178 * @param atime time the file was last accessed 0179 * @param mtime modification time of the file 0180 * @param ctime time of last status change 0181 */ 0182 bool writeSymLink(const QString &name, 0183 const QString &target, 0184 const QString &user = QString(), 0185 const QString &group = QString(), 0186 mode_t perm = 0120755, 0187 const QDateTime &atime = QDateTime(), 0188 const QDateTime &mtime = QDateTime(), 0189 const QDateTime &ctime = QDateTime()); 0190 0191 /** 0192 * Writes a new file into the archive. 0193 * 0194 * The archive must be opened for writing first. 0195 * 0196 * The necessary parent directories are created automatically 0197 * if needed. For instance, writing "mydir/test1" does not 0198 * require creating the directory "mydir" first. 0199 * 0200 * This method also allows some file metadata to be 0201 * set. However, depending on the archive type not all metadata might be 0202 * written out. 0203 * 0204 * @param name the name of the file 0205 * @param data the data to write 0206 * @param perm permissions of the file 0207 * @param user the user that owns the file 0208 * @param group the group that owns the file 0209 * @param atime time the file was last accessed 0210 * @param mtime modification time of the file 0211 * @param ctime time of last status change 0212 * @since 6.0 0213 */ 0214 bool writeFile(const QString &name, 0215 QByteArrayView data, 0216 mode_t perm = 0100644, 0217 const QString &user = QString(), 0218 const QString &group = QString(), 0219 const QDateTime &atime = QDateTime(), 0220 const QDateTime &mtime = QDateTime(), 0221 const QDateTime &ctime = QDateTime()); 0222 0223 /** 0224 * Here's another way of writing a file into an archive: 0225 * Call prepareWriting(), then call writeData() 0226 * as many times as wanted then call finishWriting( totalSize ). 0227 * For tar.gz files, you need to know the size before hand, it is needed in the header! 0228 * For zip files, size isn't used. 0229 * 0230 * This method also allows some file metadata to be 0231 * set. However, depending on the archive type not all metadata might be 0232 * regarded. 0233 * @param name the name of the file 0234 * @param user the user that owns the file 0235 * @param group the group that owns the file 0236 * @param size the size of the file 0237 * @param perm permissions of the file 0238 * @param atime time the file was last accessed 0239 * @param mtime modification time of the file 0240 * @param ctime time of last status change 0241 */ 0242 bool prepareWriting(const QString &name, 0243 const QString &user, 0244 const QString &group, 0245 qint64 size, 0246 mode_t perm = 0100644, 0247 const QDateTime &atime = QDateTime(), 0248 const QDateTime &mtime = QDateTime(), 0249 const QDateTime &ctime = QDateTime()); 0250 0251 /** 0252 * Write data into the current file - to be called after calling prepareWriting 0253 * @param data a pointer to the data 0254 * @param size the size of the chunk 0255 * @return @c true if successful, @c false otherwise 0256 */ 0257 bool writeData(const char *data, qint64 size); 0258 0259 /** 0260 * Overload for writeData(const char *, qint64); 0261 * @since 6.0 0262 */ 0263 bool writeData(QByteArrayView data); 0264 0265 /** 0266 * Call finishWriting after writing the data. 0267 * @param size the size of the file 0268 * @see prepareWriting() 0269 */ 0270 bool finishWriting(qint64 size); 0271 0272 protected: 0273 /** 0274 * Opens an archive for reading or writing. 0275 * Called by open. 0276 * @param mode may be QIODevice::ReadOnly or QIODevice::WriteOnly 0277 */ 0278 virtual bool openArchive(QIODevice::OpenMode mode) = 0; 0279 0280 /** 0281 * Closes the archive. 0282 * Called by close. 0283 */ 0284 virtual bool closeArchive() = 0; 0285 0286 /** 0287 * Sets error description 0288 * @param errorStr error description 0289 * @since 5.29 0290 */ 0291 void setErrorString(const QString &errorStr); 0292 0293 /** 0294 * Retrieves or create the root directory. 0295 * The default implementation assumes that openArchive() did the parsing, 0296 * so it creates a dummy rootdir if none was set (write mode, or no '/' in the archive). 0297 * Reimplement this to provide parsing/listing on demand. 0298 * @return the root directory 0299 */ 0300 virtual KArchiveDirectory *rootDir(); 0301 0302 /** 0303 * Write a directory to the archive. 0304 * This virtual method must be implemented by subclasses. 0305 * 0306 * Depending on the archive type not all metadata might be used. 0307 * 0308 * @param name the name of the directory 0309 * @param user the user that owns the directory 0310 * @param group the group that owns the directory 0311 * @param perm permissions of the directory. Use 040755 if you don't have any other information. 0312 * @param atime time the file was last accessed 0313 * @param mtime modification time of the file 0314 * @param ctime time of last status change 0315 * @see writeDir 0316 */ 0317 virtual bool doWriteDir(const QString &name, 0318 const QString &user, 0319 const QString &group, 0320 mode_t perm, 0321 const QDateTime &atime, 0322 const QDateTime &mtime, 0323 const QDateTime &ctime) = 0; 0324 0325 /** 0326 * Writes a symbolic link to the archive. 0327 * This virtual method must be implemented by subclasses. 0328 * 0329 * @param name name of symbolic link 0330 * @param target target of symbolic link 0331 * @param user the user that owns the directory 0332 * @param group the group that owns the directory 0333 * @param perm permissions of the directory 0334 * @param atime time the file was last accessed 0335 * @param mtime modification time of the file 0336 * @param ctime time of last status change 0337 * @see writeSymLink 0338 */ 0339 virtual bool doWriteSymLink(const QString &name, 0340 const QString &target, 0341 const QString &user, 0342 const QString &group, 0343 mode_t perm, 0344 const QDateTime &atime, 0345 const QDateTime &mtime, 0346 const QDateTime &ctime) = 0; 0347 0348 /** 0349 * This virtual method must be implemented by subclasses. 0350 * 0351 * Depending on the archive type not all metadata might be used. 0352 * 0353 * @param name the name of the file 0354 * @param user the user that owns the file 0355 * @param group the group that owns the file 0356 * @param size the size of the file 0357 * @param perm permissions of the file. Use 0100644 if you don't have any more specific permissions to set. 0358 * @param atime time the file was last accessed 0359 * @param mtime modification time of the file 0360 * @param ctime time of last status change 0361 * @see prepareWriting 0362 */ 0363 virtual bool doPrepareWriting(const QString &name, 0364 const QString &user, 0365 const QString &group, 0366 qint64 size, 0367 mode_t perm, 0368 const QDateTime &atime, 0369 const QDateTime &mtime, 0370 const QDateTime &ctime) = 0; 0371 0372 /** 0373 * Write data into the current file. 0374 * Called by writeData. 0375 * 0376 * @param data a pointer to the data 0377 * @param size the size of the chunk 0378 * @return @c true if successful, @c false otherwise 0379 * @see writeData 0380 * @since 6.0 0381 */ 0382 virtual bool doWriteData(const char *data, qint64 size); 0383 0384 /** 0385 * Called after writing the data. 0386 * This virtual method must be implemented by subclasses. 0387 * 0388 * @param size the size of the file 0389 * @see finishWriting() 0390 */ 0391 virtual bool doFinishWriting(qint64 size) = 0; 0392 0393 /** 0394 * Ensures that @p path exists, create otherwise. 0395 * This handles e.g. tar files missing directory entries, like mico-2.3.0.tar.gz :) 0396 * @param path the path of the directory 0397 * @return the directory with the given @p path 0398 */ 0399 KArchiveDirectory *findOrCreate(const QString &path); 0400 0401 /** 0402 * Can be reimplemented in order to change the creation of the device 0403 * (when using the fileName constructor). By default this method uses 0404 * QSaveFile when saving, and a simple QFile on reading. 0405 * This method is called by open(). 0406 */ 0407 virtual bool createDevice(QIODevice::OpenMode mode); 0408 0409 /** 0410 * Can be called by derived classes in order to set the underlying device. 0411 * Note that KArchive will -not- own the device, it must be deleted by the derived class. 0412 */ 0413 void setDevice(QIODevice *dev); 0414 0415 /** 0416 * Derived classes call setRootDir from openArchive, 0417 * to set the root directory after parsing an existing archive. 0418 */ 0419 void setRootDir(KArchiveDirectory *rootDir); 0420 0421 protected: 0422 virtual void virtual_hook(int id, void *data); 0423 0424 private: 0425 friend class KArchivePrivate; 0426 KArchivePrivate *const d; 0427 }; 0428 0429 // for source compat 0430 #include "karchivedirectory.h" 0431 #include "karchivefile.h" 0432 0433 #endif