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 | |
18 | namespace 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). |
28 | class 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 | |
46 | public: |
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 | |
187 | protected: |
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 | |
206 | class WorkerBasePrivate |
207 | { |
208 | public: |
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 | |