fileaccess.h 6.38 KB
Newer Older
Joachim Eibl's avatar
Joachim Eibl committed
1
/***************************************************************************
2 3
 *   Copyright (C) 2003-2007 by Joachim Eibl <joachim.eibl at gmx.de>      *
 *   Copyright (C) 2018 Michael Reeves reeves.87@gmail.com                 *
Joachim Eibl's avatar
Joachim Eibl committed
4 5 6 7 8 9 10 11 12 13
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 ***************************************************************************/

#ifndef FILEACCESS_H
#define FILEACCESS_H

Michael Reeves's avatar
Michael Reeves committed
14
#include <QDir>
15
#include <QFile>
16
#include <QFileInfo>
Joachim Eibl's avatar
Joachim Eibl committed
17
#include <QDateTime>
18 19 20
#include <QSharedPointer>
#include <QTemporaryFile>
#include <QUrl>
Joachim Eibl's avatar
Joachim Eibl committed
21

22
#include <KIO/UDSEntry>
Michael Reeves's avatar
Michael Reeves committed
23
#include <KJob>
Joachim Eibl's avatar
Joachim Eibl committed
24

25
namespace KIO {
Michael Reeves's avatar
Michael Reeves committed
26
class Job;
27
}
Joachim Eibl's avatar
Joachim Eibl committed
28 29 30 31 32

class t_DirectoryList;

class FileAccess
{
Michael Reeves's avatar
Michael Reeves committed
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
  public:
    FileAccess();
    ~FileAccess();
    explicit FileAccess(const QString& name, bool bWantToWrite = false); // name: local file or dirname or url (when supported)
    void setFile(const QString& name, bool bWantToWrite = false);
    void setFile(const QUrl& url, bool bWantToWrite = false);
    void setFile(FileAccess* pParent, const QFileInfo& fi);

    void loadData();

    bool isNormal() const;
    bool isValid() const;
    bool isFile() const;
    bool isDir() const;
    bool isSymLink() const;
    bool exists() const;
    qint64 size() const;     // Size as returned by stat().
    qint64 sizeForReading(); // If the size can't be determined by stat() then the file is copied to a local temp file.
    bool isReadable() const;
    bool isWritable() const;
    bool isExecutable() const;
    bool isHidden() const;
    QString readLink() const;

    QDateTime lastModified() const;

    QString fileName(bool needTmp = false) const; // Just the name-part of the path, without parent directories
    QString fileRelPath() const;                  // The path relative to base comparison directory
    QString prettyAbsPath() const;
    QUrl url() const;
    void setUrl(const QUrl& inUrl) { m_url = inUrl; }
    QString absoluteFilePath() const;

    bool isLocal() const;

    bool readFile(void* pDestBuffer, qint64 maxLength);
    bool writeFile(const void* pSrcBuffer, qint64 length);
    bool listDir(t_DirectoryList* pDirList, bool bRecursive, bool bFindHidden,
Joachim Eibl's avatar
Joachim Eibl committed
71
                 const QString& filePattern, const QString& fileAntiPattern,
Michael Reeves's avatar
Michael Reeves committed
72 73 74
                 const QString& dirAntiPattern, bool bFollowDirLinks, bool bUseCvsIgnore);
    bool copyFile(const QString& destUrl);
    bool createBackup(const QString& bakExtension);
Joachim Eibl's avatar
Joachim Eibl committed
75

Michael Reeves's avatar
Michael Reeves committed
76 77 78 79 80 81 82 83
    QString getTempName() const;
    bool createLocalCopy();
    static void createTempFile(QTemporaryFile&);
    bool removeFile();
    static bool makeDir(const QString&);
    static bool removeDir(const QString&);
    static bool exists(const QString&);
    static QString cleanPath(const QString&);
Joachim Eibl's avatar
Joachim Eibl committed
84

Michael Reeves's avatar
Michael Reeves committed
85 86 87
    //bool chmod( const QString& );
    bool rename(const FileAccess&);
    static bool symLink(const QString& linkTarget, const QString& linkLocation);
Joachim Eibl's avatar
Joachim Eibl committed
88

Michael Reeves's avatar
Michael Reeves committed
89 90
    void addPath(const QString& txt);
    QString getStatusText() const;
91

Michael Reeves's avatar
Michael Reeves committed
92
    FileAccess* parent() const; // !=0 for listDir-results, but only valid if the parent was not yet destroyed.
Michael Reeves's avatar
Michael Reeves committed
93

Michael Reeves's avatar
Michael Reeves committed
94 95 96 97
    void doError();
    void filterList(t_DirectoryList* pDirList, const QString& filePattern,
                    const QString& fileAntiPattern, const QString& dirAntiPattern,
                    const bool bUseCvsIgnore);
98

Michael Reeves's avatar
Michael Reeves committed
99
    QDir getBaseDirectory() const { return m_baseDir; }
100

Michael Reeves's avatar
Michael Reeves committed
101
    bool open(const QFile::OpenMode flags);
102

Michael Reeves's avatar
Michael Reeves committed
103 104
    qint64 read(char* data, const qint64 maxlen);
    void close();
105

Michael Reeves's avatar
Michael Reeves committed
106
    const QString errorString() const;
107

Michael Reeves's avatar
Michael Reeves committed
108 109
  private:
    friend class FileAccessJobHandler;
110
    void setFromUdsEntry(const KIO::UDSEntry& e, FileAccess* parent = nullptr);
Michael Reeves's avatar
Michael Reeves committed
111
    void setStatusText(const QString& s);
112

Michael Reeves's avatar
Michael Reeves committed
113
    void reset();
114

Michael Reeves's avatar
Michael Reeves committed
115
    bool interruptableReadFile(void* pDestBuffer, qint64 maxLength);
116

Michael Reeves's avatar
Michael Reeves committed
117 118
    QUrl m_url;
    bool m_bValidData;
Michael Reeves's avatar
Michael Reeves committed
119

Michael Reeves's avatar
Michael Reeves committed
120
    //long m_fileType; // for testing only
121
    FileAccess* m_pParent = nullptr;
122

Michael Reeves's avatar
Michael Reeves committed
123 124 125 126 127 128 129
    QDir m_baseDir;
    QFileInfo m_fileInfo;
    QString m_linkTarget;
    QString m_name;
    QString m_localCopy;
    QSharedPointer<QTemporaryFile> tmpFile = nullptr;
    QSharedPointer<QFile> realFile = nullptr;
130

Michael Reeves's avatar
Michael Reeves committed
131 132 133 134 135 136 137 138 139 140
    qint64 m_size;
    QDateTime m_modificationTime;
    bool m_bSymLink;
    bool m_bFile;
    bool m_bDir;
    bool m_bExists;
    bool m_bWritable;
    bool m_bReadable;
    bool m_bExecutable;
    bool m_bHidden;
Michael Reeves's avatar
Michael Reeves committed
141

Michael Reeves's avatar
Michael Reeves committed
142
    QString m_statusText; // Might contain an error string, when the last operation didn't succeed.
Joachim Eibl's avatar
Joachim Eibl committed
143 144 145
};

class t_DirectoryList : public std::list<FileAccess>
Michael Reeves's avatar
Michael Reeves committed
146 147
{
};
Joachim Eibl's avatar
Joachim Eibl committed
148 149 150

class FileAccessJobHandler : public QObject
{
Michael Reeves's avatar
Michael Reeves committed
151 152 153 154 155 156 157 158 159 160
    Q_OBJECT
  public:
    explicit FileAccessJobHandler(FileAccess* pFileAccess);

    bool get(void* pDestBuffer, long maxLength);
    bool put(const void* pSrcBuffer, long maxLength, bool bOverwrite, bool bResume = false, int permissions = -1);
    bool stat(int detailLevel = 2, bool bWantToWrite = false);
    bool copyFile(const QString& dest);
    bool rename(const FileAccess& dest);
    bool listDir(t_DirectoryList* pDirList, bool bRecursive, bool bFindHidden,
Joachim Eibl's avatar
Joachim Eibl committed
161
                 const QString& filePattern, const QString& fileAntiPattern,
Michael Reeves's avatar
Michael Reeves committed
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
                 const QString& dirAntiPattern, bool bFollowDirLinks, bool bUseCvsIgnore);
    bool mkDir(const QString& dirName);
    bool rmDir(const QString& dirName);
    bool removeFile(const QUrl& fileName);
    bool symLink(const QUrl& linkTarget, const QUrl& linkLocation);

  private:
    FileAccess* m_pFileAccess;
    bool m_bSuccess;

    // Data needed during Job
    qint64 m_transferredBytes;
    char* m_pTransferBuffer = nullptr; // Needed during get or put
    qint64 m_maxLength;

    QString m_filePattern;
    QString m_fileAntiPattern;
    QString m_dirAntiPattern;
    t_DirectoryList* m_pDirList = nullptr;
    bool m_bFindHidden = false;
    bool m_bRecursive = false;
    bool m_bFollowDirLinks = false;

    bool scanLocalDirectory(const QString& dirName, t_DirectoryList* dirList);

  private Q_SLOTS:
    void slotStatResult(KJob*);
    void slotSimpleJobResult(KJob* pJob);
    void slotPutJobResult(KJob* pJob);

    void slotGetData(KJob*, const QByteArray&);
    void slotPutData(KIO::Job*, QByteArray&);

    void slotListDirProcessNewEntries(KIO::Job*, const KIO::UDSEntryList& l);
Joachim Eibl's avatar
Joachim Eibl committed
196 197 198
};

#endif