File indexing completed on 2024-04-21 03:55:15

0001 /*
0002     SPDX-License-Identifier: LGPL-2.0-or-later
0003     SPDX-FileCopyrightText: 2000 Waldo Bastian <bastian@kde.org>
0004     SPDX-FileCopyrightText: 2000 David Faure <faure@kde.org>
0005     SPDX-FileCopyrightText: 2000 Stephan Kulow <coolo@kde.org>
0006     SPDX-FileCopyrightText: 2007 Thiago Macieira <thiago@kde.org>
0007     SPDX-FileCopyrightText: 2019-2022 Harald Sitter <sitter@kde.org>
0008 */
0009 
0010 #ifndef WORKERBASE_P_H
0011 #define WORKERBASE_P_H
0012 
0013 #include "workerbase.h"
0014 
0015 #include <commands_p.h>
0016 #include <slavebase.h>
0017 
0018 namespace KIO
0019 {
0020 
0021 // Bridges new worker API to legacy slave API. Overrides all SlaveBase virtual functions and redirects them at the
0022 // fronting WorkerBase implementation. The WorkerBase implementation then returns Result objects which we translate
0023 // back to the appropriate signal calls (error, finish, opened, etc.).
0024 // When starting the dispatchLoop it actually runs inside the SlaveBase, so the SlaveBase is in the driver seat
0025 // until KF6 when we can fully remove the SlaveBase in favor of the WorkerBase (means moving the dispatch and
0026 // dispatchLoop functions into the WorkerBase and handling the signaling in the dispatch function rather than
0027 // this intermediate Bridge object).
0028 class WorkerSlaveBaseBridge : public SlaveBase
0029 {
0030     void finalize(const WorkerResult &result)
0031     {
0032         if (!result.success()) {
0033             error(result.error(), result.errorString());
0034             return;
0035         }
0036         finished();
0037     }
0038 
0039     void maybeError(const WorkerResult &result)
0040     {
0041         if (!result.success()) {
0042             error(result.error(), result.errorString());
0043         }
0044     }
0045 
0046 public:
0047     using SlaveBase::SlaveBase;
0048 
0049     void setHost(const QString &host, quint16 port, const QString &user, const QString &pass) final
0050     {
0051         base->setHost(host, port, user, pass);
0052     }
0053 
0054     void openConnection() final
0055     {
0056         const WorkerResult result = base->openConnection();
0057         if (!result.success()) {
0058             error(result.error(), result.errorString());
0059             return;
0060         }
0061         connected();
0062     }
0063 
0064     void closeConnection() final
0065     {
0066         base->closeConnection(); // not allowed to error but also not finishing
0067     }
0068 
0069     void get(const QUrl &url) final
0070     {
0071         finalize(base->get(url));
0072     }
0073 
0074     void open(const QUrl &url, QIODevice::OpenMode mode) final
0075     {
0076         const WorkerResult result = base->open(url, mode);
0077         if (!result.success()) {
0078             error(result.error(), result.errorString());
0079             return;
0080         }
0081         opened();
0082     }
0083 
0084     void read(KIO::filesize_t size) final
0085     {
0086         maybeError(base->read(size));
0087     }
0088 
0089     void write(const QByteArray &data) final
0090     {
0091         maybeError(base->write(data));
0092     }
0093 
0094     void seek(KIO::filesize_t offset) final
0095     {
0096         maybeError(base->seek(offset));
0097     }
0098 
0099     void close() final
0100     {
0101         finalize(base->close());
0102     }
0103 
0104     void put(const QUrl &url, int permissions, JobFlags flags) final
0105     {
0106         finalize(base->put(url, permissions, flags));
0107     }
0108 
0109     void stat(const QUrl &url) final
0110     {
0111         finalize(base->stat(url));
0112     }
0113 
0114     void mimetype(const QUrl &url) final
0115     {
0116         finalize(base->mimetype(url));
0117     }
0118 
0119     void listDir(const QUrl &url) final
0120     {
0121         finalize(base->listDir(url));
0122     }
0123 
0124     void mkdir(const QUrl &url, int permissions) final
0125     {
0126         finalize(base->mkdir(url, permissions));
0127     }
0128 
0129     void rename(const QUrl &src, const QUrl &dest, JobFlags flags) final
0130     {
0131         finalize(base->rename(src, dest, flags));
0132     }
0133 
0134     void symlink(const QString &target, const QUrl &dest, JobFlags flags) final
0135     {
0136         finalize(base->symlink(target, dest, flags));
0137     }
0138 
0139     void chmod(const QUrl &url, int permissions) final
0140     {
0141         finalize(base->chmod(url, permissions));
0142     }
0143 
0144     void chown(const QUrl &url, const QString &owner, const QString &group) final
0145     {
0146         finalize(base->chown(url, owner, group));
0147     }
0148 
0149     void setModificationTime(const QUrl &url, const QDateTime &mtime) final
0150     {
0151         finalize(base->setModificationTime(url, mtime));
0152     }
0153 
0154     void copy(const QUrl &src, const QUrl &dest, int permissions, JobFlags flags) final
0155     {
0156         finalize(base->copy(src, dest, permissions, flags));
0157     }
0158 
0159     void del(const QUrl &url, bool isfile) final
0160     {
0161         finalize(base->del(url, isfile));
0162     }
0163 
0164     void special(const QByteArray &data) final
0165     {
0166         finalize(base->special(data));
0167     }
0168 
0169     void slave_status() final
0170     {
0171         base->worker_status(); // this only requests an update and isn't able to error or finish whatsoever
0172     }
0173 
0174     void reparseConfiguration() final
0175     {
0176         base->reparseConfiguration();
0177         SlaveBase::reparseConfiguration();
0178     }
0179 
0180     void setIncomingMetaData(const KIO::MetaData &metaData)
0181     {
0182         mIncomingMetaData = metaData;
0183     }
0184 
0185     WorkerBase *base = nullptr;
0186 
0187 protected:
0188     void virtual_hook(int id, void *data) override
0189     {
0190         switch (id) {
0191         case SlaveBase::AppConnectionMade:
0192             base->appConnectionMade();
0193             return;
0194         case SlaveBase::GetFileSystemFreeSpace:
0195             finalize(base->fileSystemFreeSpace(*static_cast<QUrl *>(data)));
0196             return;
0197         case SlaveBase::Truncate:
0198             maybeError(base->truncate(*static_cast<KIO::filesize_t *>(data)));
0199             return;
0200         }
0201 
0202         maybeError(WorkerResult::fail(ERR_UNSUPPORTED_ACTION, unsupportedActionErrorString(protocolName(), id)));
0203     }
0204 };
0205 
0206 class WorkerBasePrivate
0207 {
0208 public:
0209     WorkerBasePrivate(const QByteArray &protocol, const QByteArray &poolSocket, const QByteArray &appSocket, WorkerBase *base)
0210         : bridge(protocol, poolSocket, appSocket)
0211     {
0212         bridge.base = base;
0213     }
0214 
0215     WorkerSlaveBaseBridge bridge;
0216 
0217     inline QString protocolName() const
0218     {
0219         return bridge.protocolName();
0220     }
0221 };
0222 
0223 } // namespace KIO
0224 
0225 #endif