1/*
2 SPDX-License-Identifier: LGPL-2.0-or-later
3 SPDX-FileCopyrightText: 2000 Waldo Bastian <bastian@kde.org>
4 SPDX-FileCopyrightText: 2000 David Faure <faure@kde.org>
5 SPDX-FileCopyrightText: 2000 Stephan Kulow <coolo@kde.org>
6 SPDX-FileCopyrightText: 2007 Thiago Macieira <thiago@kde.org>
7 SPDX-FileCopyrightText: 2019-2022 Harald Sitter <sitter@kde.org>
8*/
9
10#ifndef WORKERBASE_P_H
11#define WORKERBASE_P_H
12
13#include "workerbase.h"
14
15#include <commands_p.h>
16#include <slavebase.h>
17
18namespace KIO
19{
20
21// Bridges new worker API to legacy slave API. Overrides all SlaveBase virtual functions and redirects them at the
22// fronting WorkerBase implementation. The WorkerBase implementation then returns Result objects which we translate
23// back to the appropriate signal calls (error, finish, opened, etc.).
24// When starting the dispatchLoop it actually runs inside the SlaveBase, so the SlaveBase is in the driver seat
25// until KF6 when we can fully remove the SlaveBase in favor of the WorkerBase (means moving the dispatch and
26// dispatchLoop functions into the WorkerBase and handling the signaling in the dispatch function rather than
27// this intermediate Bridge object).
28class WorkerSlaveBaseBridge : public SlaveBase
29{
30 void finalize(const WorkerResult &result)
31 {
32 if (!result.success()) {
33 error(errid: result.error(), text: result.errorString());
34 return;
35 }
36 finished();
37 }
38
39 void maybeError(const WorkerResult &result)
40 {
41 if (!result.success()) {
42 error(errid: result.error(), text: result.errorString());
43 }
44 }
45
46public:
47 using SlaveBase::SlaveBase;
48
49 void setHost(const QString &host, quint16 port, const QString &user, const QString &pass) final
50 {
51 base->setHost(host, port, user, pass);
52 }
53
54 void openConnection() final
55 {
56 const WorkerResult result = base->openConnection();
57 if (!result.success()) {
58 error(errid: result.error(), text: result.errorString());
59 return;
60 }
61 connected();
62 }
63
64 void closeConnection() final
65 {
66 base->closeConnection(); // not allowed to error but also not finishing
67 }
68
69 void get(const QUrl &url) final
70 {
71 finalize(result: base->get(url));
72 }
73
74 void open(const QUrl &url, QIODevice::OpenMode mode) final
75 {
76 const WorkerResult result = base->open(url, mode);
77 if (!result.success()) {
78 error(errid: result.error(), text: result.errorString());
79 return;
80 }
81 opened();
82 }
83
84 void read(KIO::filesize_t size) final
85 {
86 maybeError(result: base->read(size));
87 }
88
89 void write(const QByteArray &data) final
90 {
91 maybeError(result: base->write(data));
92 }
93
94 void seek(KIO::filesize_t offset) final
95 {
96 maybeError(result: base->seek(offset));
97 }
98
99 void close() final
100 {
101 finalize(result: base->close());
102 }
103
104 void put(const QUrl &url, int permissions, JobFlags flags) final
105 {
106 finalize(result: base->put(url, permissions, flags));
107 }
108
109 void stat(const QUrl &url) final
110 {
111 finalize(result: base->stat(url));
112 }
113
114 void mimetype(const QUrl &url) final
115 {
116 finalize(result: base->mimetype(url));
117 }
118
119 void listDir(const QUrl &url) final
120 {
121 finalize(result: base->listDir(url));
122 }
123
124 void mkdir(const QUrl &url, int permissions) final
125 {
126 finalize(result: base->mkdir(url, permissions));
127 }
128
129 void rename(const QUrl &src, const QUrl &dest, JobFlags flags) final
130 {
131 finalize(result: base->rename(src, dest, flags));
132 }
133
134 void symlink(const QString &target, const QUrl &dest, JobFlags flags) final
135 {
136 finalize(result: base->symlink(target, dest, flags));
137 }
138
139 void chmod(const QUrl &url, int permissions) final
140 {
141 finalize(result: base->chmod(url, permissions));
142 }
143
144 void chown(const QUrl &url, const QString &owner, const QString &group) final
145 {
146 finalize(result: base->chown(url, owner, group));
147 }
148
149 void setModificationTime(const QUrl &url, const QDateTime &mtime) final
150 {
151 finalize(result: base->setModificationTime(url, mtime));
152 }
153
154 void copy(const QUrl &src, const QUrl &dest, int permissions, JobFlags flags) final
155 {
156 finalize(result: base->copy(src, dest, permissions, flags));
157 }
158
159 void del(const QUrl &url, bool isfile) final
160 {
161 finalize(result: base->del(url, isfile));
162 }
163
164 void special(const QByteArray &data) final
165 {
166 finalize(result: base->special(data));
167 }
168
169 void slave_status() final
170 {
171 base->worker_status(); // this only requests an update and isn't able to error or finish whatsoever
172 }
173
174 void reparseConfiguration() final
175 {
176 base->reparseConfiguration();
177 SlaveBase::reparseConfiguration();
178 }
179
180 void setIncomingMetaData(const KIO::MetaData &metaData)
181 {
182 mIncomingMetaData = metaData;
183 }
184
185 WorkerBase *base = nullptr;
186
187protected:
188 void virtual_hook(int id, void *data) override
189 {
190 switch (id) {
191 case SlaveBase::AppConnectionMade:
192 base->appConnectionMade();
193 return;
194 case SlaveBase::GetFileSystemFreeSpace:
195 finalize(result: base->fileSystemFreeSpace(url: *static_cast<QUrl *>(data)));
196 return;
197 case SlaveBase::Truncate:
198 maybeError(result: base->truncate(size: *static_cast<KIO::filesize_t *>(data)));
199 return;
200 }
201
202 maybeError(result: WorkerResult::fail(error: ERR_UNSUPPORTED_ACTION, errorString: unsupportedActionErrorString(protocol: protocolName(), cmd: id)));
203 }
204};
205
206class WorkerBasePrivate
207{
208public:
209 WorkerBasePrivate(const QByteArray &protocol, const QByteArray &poolSocket, const QByteArray &appSocket, WorkerBase *base)
210 : bridge(protocol, poolSocket, appSocket)
211 {
212 bridge.base = base;
213 }
214
215 WorkerSlaveBaseBridge bridge;
216
217 inline QString protocolName() const
218 {
219 return bridge.protocolName();
220 }
221};
222
223} // namespace KIO
224
225#endif
226

source code of kio/src/core/workerbase_p.h