1/*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 2003 Leo Savernik <l.savernik@aon.at>
4 Derived from worker.cpp
5
6 SPDX-License-Identifier: LGPL-2.0-only
7*/
8
9#include "commands_p.h"
10#include "dataprotocol_p.h"
11#include "dataworker_p.h"
12#include "workerbase.h"
13
14#include <KLocalizedString>
15
16#include <QDataStream>
17#include <QTimer>
18
19using namespace KIO;
20
21static constexpr int s_kioDataPollInterval = 0;
22
23// don't forget to sync DISPATCH_DECL in dataworker_p.h
24/* clang-format off */
25#define DISPATCH_IMPL(type) \
26 void DataWorker::dispatch_##type() \
27 { \
28 if (_suspended) { \
29 QueueStruct q(Queue_##type); \
30 q.size = -1; \
31 dispatchQueue.push_back(q); \
32 if (!timer->isActive()) { \
33 timer->start(s_kioDataPollInterval); \
34 } \
35 } else \
36 Q_EMIT type(); \
37 }
38
39// don't forget to sync DISPATCH_DECL1 in dataworker_p.h
40#define DISPATCH_IMPL1(type, paramtype, paramname) \
41 void DataWorker::dispatch_##type(paramtype paramname) \
42 { \
43 if (_suspended) { \
44 QueueStruct q(Queue_##type); \
45 q.paramname = paramname; \
46 dispatchQueue.push_back(q); \
47 if (!timer->isActive()) { \
48 timer->start(s_kioDataPollInterval); \
49 } \
50 } else \
51 Q_EMIT type(paramname); \
52 }
53
54DataWorker::DataWorker()
55 : Worker(QStringLiteral("data"))
56{
57 // qDebug() << this;
58 _suspended = false;
59 timer = new QTimer(this);
60 connect(sender: timer, signal: &QTimer::timeout, context: this, slot: &DataWorker::dispatchNext);
61}
62
63DataWorker::~DataWorker()
64{
65 // qDebug() << this;
66}
67
68void DataWorker::suspend()
69{
70 _suspended = true;
71 // qDebug() << this;
72 timer->stop();
73}
74
75void DataWorker::resume()
76{
77 _suspended = false;
78 // qDebug() << this;
79 // aarrrgh! This makes the once hyper fast and efficient data protocol
80 // implementation slow as molasses. But it wouldn't work otherwise,
81 // and I don't want to start messing around with threads
82 timer->start(msec: s_kioDataPollInterval);
83}
84
85// finished is a special case. If we emit it right away, then
86// TransferJob::start can delete the job even before the end of the method
87void DataWorker::dispatch_finished()
88{
89 QueueStruct q(Queue_finished);
90 q.size = -1;
91 dispatchQueue.push_back(t: q);
92 if (!timer->isActive()) {
93 timer->start(msec: s_kioDataPollInterval);
94 }
95}
96
97void DataWorker::dispatchNext()
98{
99 if (dispatchQueue.empty()) {
100 timer->stop();
101 return;
102 }
103
104 const QueueStruct &q = dispatchQueue.front();
105 // qDebug() << this << "dispatching" << q.type << dispatchQueue.size() << "left";
106 switch (q.type) {
107 case Queue_mimeType:
108 Q_EMIT mimeType(q.s);
109 break;
110 case Queue_totalSize:
111 Q_EMIT totalSize(q.size);
112 break;
113 case Queue_sendMetaData:
114 sendMetaData();
115 break;
116 case Queue_data:
117 Q_EMIT data(q.ba);
118 break;
119 case Queue_finished:
120 Q_EMIT finished();
121 break;
122 } /*end switch*/
123
124 dispatchQueue.pop_front();
125}
126
127void DataWorker::send(int cmd, const QByteArray &arr)
128{
129 QDataStream stream(arr);
130
131 QUrl url;
132
133 switch (cmd) {
134 case CMD_GET: {
135 stream >> url;
136 get(url);
137 break;
138 }
139 case CMD_MIMETYPE: {
140 stream >> url;
141 mimetype(url);
142 break;
143 }
144 // ignore these (must not emit error, otherwise SIGSEGV occurs)
145 case CMD_REPARSECONFIGURATION:
146 case CMD_META_DATA:
147 break;
148 default:
149 Q_EMIT error(ERR_UNSUPPORTED_ACTION, unsupportedActionErrorString(QStringLiteral("data"), cmd));
150 } /*end switch*/
151}
152
153bool DataWorker::suspended()
154{
155 return _suspended;
156}
157
158void DataWorker::setHost(const QString & /*host*/, quint16 /*port*/, const QString & /*user*/, const QString & /*passwd*/)
159{
160 // irrelevant -> will be ignored
161}
162
163void DataWorker::setConfig(const MetaData & /*config*/)
164{
165 // FIXME: decide to handle this directly or not at all
166#if 0
167 QByteArray data;
168 QDataStream stream(data, QIODevice::WriteOnly);
169 stream << config;
170 slaveconn.send(CMD_CONFIG, data);
171#endif
172}
173
174void DataWorker::setAllMetaData(const MetaData &md)
175{
176 meta_data = md;
177}
178
179void DataWorker::sendMetaData()
180{
181 Q_EMIT metaData(meta_data);
182}
183
184DISPATCH_IMPL1(mimeType, const QString &, s)
185DISPATCH_IMPL1(totalSize, KIO::filesize_t, size)
186DISPATCH_IMPL(sendMetaData)
187DISPATCH_IMPL1(data, const QByteArray &, ba)
188
189#undef DISPATCH_IMPL
190#undef DISPATCH_IMPL1
191
192#include "moc_dataworker_p.cpp"
193

source code of kio/src/core/dataworker.cpp