File indexing completed on 2024-04-21 03:55:00
0001 /* 0002 This file is part of the KDE libraries 0003 SPDX-FileCopyrightText: 2003 Leo Savernik <l.savernik@aon.at> 0004 Derived from worker.cpp 0005 0006 SPDX-License-Identifier: LGPL-2.0-only 0007 */ 0008 0009 #include "commands_p.h" 0010 #include "dataprotocol_p.h" 0011 #include "dataworker_p.h" 0012 #include "workerbase.h" 0013 0014 #include <KLocalizedString> 0015 0016 #include <QDataStream> 0017 #include <QTimer> 0018 0019 using namespace KIO; 0020 0021 static constexpr int s_kioDataPollInterval = 0; 0022 0023 // don't forget to sync DISPATCH_DECL in dataworker_p.h 0024 /* clang-format off */ 0025 #define DISPATCH_IMPL(type) \ 0026 void DataWorker::dispatch_##type() \ 0027 { \ 0028 if (_suspended) { \ 0029 QueueStruct q(Queue_##type); \ 0030 q.size = -1; \ 0031 dispatchQueue.push_back(q); \ 0032 if (!timer->isActive()) { \ 0033 timer->start(s_kioDataPollInterval); \ 0034 } \ 0035 } else \ 0036 Q_EMIT type(); \ 0037 } 0038 0039 // don't forget to sync DISPATCH_DECL1 in dataworker_p.h 0040 #define DISPATCH_IMPL1(type, paramtype, paramname) \ 0041 void DataWorker::dispatch_##type(paramtype paramname) \ 0042 { \ 0043 if (_suspended) { \ 0044 QueueStruct q(Queue_##type); \ 0045 q.paramname = paramname; \ 0046 dispatchQueue.push_back(q); \ 0047 if (!timer->isActive()) { \ 0048 timer->start(s_kioDataPollInterval); \ 0049 } \ 0050 } else \ 0051 Q_EMIT type(paramname); \ 0052 } 0053 0054 DataWorker::DataWorker() 0055 : Worker(QStringLiteral("data")) 0056 { 0057 // qDebug() << this; 0058 _suspended = false; 0059 timer = new QTimer(this); 0060 connect(timer, &QTimer::timeout, this, &DataWorker::dispatchNext); 0061 } 0062 0063 DataWorker::~DataWorker() 0064 { 0065 // qDebug() << this; 0066 } 0067 0068 void DataWorker::suspend() 0069 { 0070 _suspended = true; 0071 // qDebug() << this; 0072 timer->stop(); 0073 } 0074 0075 void DataWorker::resume() 0076 { 0077 _suspended = false; 0078 // qDebug() << this; 0079 // aarrrgh! This makes the once hyper fast and efficient data protocol 0080 // implementation slow as molasses. But it wouldn't work otherwise, 0081 // and I don't want to start messing around with threads 0082 timer->start(s_kioDataPollInterval); 0083 } 0084 0085 // finished is a special case. If we emit it right away, then 0086 // TransferJob::start can delete the job even before the end of the method 0087 void DataWorker::dispatch_finished() 0088 { 0089 QueueStruct q(Queue_finished); 0090 q.size = -1; 0091 dispatchQueue.push_back(q); 0092 if (!timer->isActive()) { 0093 timer->start(s_kioDataPollInterval); 0094 } 0095 } 0096 0097 void DataWorker::dispatchNext() 0098 { 0099 if (dispatchQueue.empty()) { 0100 timer->stop(); 0101 return; 0102 } 0103 0104 const QueueStruct &q = dispatchQueue.front(); 0105 // qDebug() << this << "dispatching" << q.type << dispatchQueue.size() << "left"; 0106 switch (q.type) { 0107 case Queue_mimeType: 0108 Q_EMIT mimeType(q.s); 0109 break; 0110 case Queue_totalSize: 0111 Q_EMIT totalSize(q.size); 0112 break; 0113 case Queue_sendMetaData: 0114 sendMetaData(); 0115 break; 0116 case Queue_data: 0117 Q_EMIT data(q.ba); 0118 break; 0119 case Queue_finished: 0120 Q_EMIT finished(); 0121 break; 0122 } /*end switch*/ 0123 0124 dispatchQueue.pop_front(); 0125 } 0126 0127 void DataWorker::send(int cmd, const QByteArray &arr) 0128 { 0129 QDataStream stream(arr); 0130 0131 QUrl url; 0132 0133 switch (cmd) { 0134 case CMD_GET: { 0135 stream >> url; 0136 get(url); 0137 break; 0138 } 0139 case CMD_MIMETYPE: { 0140 stream >> url; 0141 mimetype(url); 0142 break; 0143 } 0144 // ignore these (must not emit error, otherwise SIGSEGV occurs) 0145 case CMD_REPARSECONFIGURATION: 0146 case CMD_META_DATA: 0147 break; 0148 default: 0149 Q_EMIT error(ERR_UNSUPPORTED_ACTION, unsupportedActionErrorString(QStringLiteral("data"), cmd)); 0150 } /*end switch*/ 0151 } 0152 0153 bool DataWorker::suspended() 0154 { 0155 return _suspended; 0156 } 0157 0158 void DataWorker::setHost(const QString & /*host*/, quint16 /*port*/, const QString & /*user*/, const QString & /*passwd*/) 0159 { 0160 // irrelevant -> will be ignored 0161 } 0162 0163 void DataWorker::setConfig(const MetaData & /*config*/) 0164 { 0165 // FIXME: decide to handle this directly or not at all 0166 #if 0 0167 QByteArray data; 0168 QDataStream stream(data, QIODevice::WriteOnly); 0169 stream << config; 0170 slaveconn.send(CMD_CONFIG, data); 0171 #endif 0172 } 0173 0174 void DataWorker::setAllMetaData(const MetaData &md) 0175 { 0176 meta_data = md; 0177 } 0178 0179 void DataWorker::sendMetaData() 0180 { 0181 Q_EMIT metaData(meta_data); 0182 } 0183 0184 DISPATCH_IMPL1(mimeType, const QString &, s) 0185 DISPATCH_IMPL1(totalSize, KIO::filesize_t, size) 0186 DISPATCH_IMPL(sendMetaData) 0187 DISPATCH_IMPL1(data, const QByteArray &, ba) 0188 0189 #undef DISPATCH_IMPL 0190 #undef DISPATCH_IMPL1 0191 0192 #include "moc_dataworker_p.cpp"