dataslave.cpp
00001 /* 00002 * This file is part of the KDE libraries 00003 * Copyright (c) 2003 Leo Savernik <l.savernik@aon.at> 00004 * Derived from slave.cpp 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Library General Public 00008 * License version 2 as published by the Free Software Foundation. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Library General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Library General Public License 00016 * along with this library; see the file COPYING.LIB. If not, write to 00017 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00018 * Boston, MA 02110-1301, USA. 00019 **/ 00020 00021 #include <config.h> 00022 00023 #include "dataslave.h" 00024 #include "dataprotocol.h" 00025 00026 #include <klocale.h> 00027 #include <kdebug.h> 00028 00029 #include <tqtimer.h> 00030 00031 using namespace KIO; 00032 00033 #define KIO_DATA_POLL_INTERVAL 0 00034 00035 // don't forget to sync DISPATCH_DECL in dataslave.h 00036 #define DISPATCH_IMPL(type) \ 00037 void DataSlave::dispatch_##type() { \ 00038 if (_suspended) { \ 00039 QueueStruct q(Queue_##type); \ 00040 dispatchQueue.push_back(q); \ 00041 if (!timer->isActive()) timer->start(KIO_DATA_POLL_INTERVAL); \ 00042 } else \ 00043 type(); \ 00044 } 00045 00046 // don't forget to sync DISPATCH_DECL1 in dataslave.h 00047 #define DISPATCH_IMPL1(type, paramtype, paramname) \ 00048 void DataSlave::dispatch_##type(paramtype paramname) { \ 00049 if (_suspended) { \ 00050 QueueStruct q(Queue_##type); \ 00051 q.paramname = paramname; \ 00052 dispatchQueue.push_back(q); \ 00053 if (!timer->isActive()) timer->start(KIO_DATA_POLL_INTERVAL); \ 00054 } else \ 00055 type(paramname); \ 00056 } 00057 00058 00059 DataSlave::DataSlave() : 00060 Slave(true, 0, "data", TQString::null) 00061 { 00062 //kdDebug() << this << k_funcinfo << endl; 00063 _suspended = false; 00064 timer = new TQTimer(this); 00065 connect(timer, TQT_SIGNAL(timeout()), TQT_SLOT(dispatchNext())); 00066 } 00067 00068 DataSlave::~DataSlave() { 00069 //kdDebug() << this << k_funcinfo << endl; 00070 } 00071 00072 void DataSlave::hold(const KURL &/*url*/) { 00073 // ignored 00074 } 00075 00076 void DataSlave::suspend() { 00077 _suspended = true; 00078 //kdDebug() << this << k_funcinfo << endl; 00079 timer->stop(); 00080 } 00081 00082 void DataSlave::resume() { 00083 _suspended = false; 00084 //kdDebug() << this << k_funcinfo << endl; 00085 // aarrrgh! This makes the once hyper fast and efficient data protocol 00086 // implementation slow as molasses. But it wouldn't work otherwise, 00087 // and I don't want to start messing around with threads 00088 timer->start(KIO_DATA_POLL_INTERVAL); 00089 } 00090 00091 // finished is a special case. If we emit it right away, then 00092 // TransferJob::start can delete the job even before the end of the method 00093 void DataSlave::dispatch_finished() { 00094 QueueStruct q(Queue_finished); 00095 dispatchQueue.push_back(q); 00096 if (!timer->isActive()) timer->start(KIO_DATA_POLL_INTERVAL); 00097 } 00098 00099 void DataSlave::dispatchNext() { 00100 if (dispatchQueue.empty()) { 00101 timer->stop(); 00102 return; 00103 } 00104 00105 const QueueStruct &q = dispatchQueue.front(); 00106 //kdDebug() << this << k_funcinfo << "dispatching " << q.type << " " << dispatchQueue.size() << " left" << endl; 00107 switch (q.type) { 00108 case Queue_mimeType: mimeType(q.s); break; 00109 case Queue_totalSize: totalSize(q.size); break; 00110 case Queue_sendMetaData: sendMetaData(); break; 00111 case Queue_data: data(q.ba); break; 00112 case Queue_finished: finished(); break; 00113 }/*end switch*/ 00114 00115 dispatchQueue.pop_front(); 00116 } 00117 00118 void DataSlave::send(int cmd, const TQByteArray &arr) { 00119 TQDataStream stream(arr, IO_ReadOnly); 00120 00121 KURL url; 00122 00123 switch (cmd) { 00124 case CMD_GET: { 00125 stream >> url; 00126 get(url); 00127 break; 00128 } 00129 case CMD_MIMETYPE: { 00130 stream >> url; 00131 mimetype(url); 00132 break; 00133 } 00134 // ignore these (must not emit error, otherwise SIGSEGV occurs) 00135 case CMD_META_DATA: 00136 case CMD_SUBURL: 00137 break; 00138 default: 00139 error(ERR_UNSUPPORTED_ACTION, 00140 unsupportedActionErrorString(TQString::fromLatin1("data"),cmd)); 00141 }/*end switch*/ 00142 } 00143 00144 bool DataSlave::suspended() { 00145 return _suspended; 00146 } 00147 00148 void DataSlave::setHost(const TQString &/*host*/, int /*port*/, 00149 const TQString &/*user*/, const TQString &/*passwd*/) { 00150 // irrelevant -> will be ignored 00151 } 00152 00153 void DataSlave::setConfig(const MetaData &/*config*/) { 00154 // FIXME: decide to handle this directly or not at all 00155 #if 0 00156 TQByteArray data; 00157 TQDataStream stream( data, IO_WriteOnly ); 00158 stream << config; 00159 slaveconn.send( CMD_CONFIG, data ); 00160 #endif 00161 } 00162 00163 void DataSlave::setAllMetaData(const MetaData &md) { 00164 meta_data = md; 00165 } 00166 00167 void DataSlave::sendMetaData() { 00168 emit metaData(meta_data); 00169 } 00170 00171 void DataSlave::virtual_hook( int id, void* data ) { 00172 switch (id) { 00173 case VIRTUAL_SUSPEND: suspend(); return; 00174 case VIRTUAL_RESUME: resume(); return; 00175 case VIRTUAL_SEND: { 00176 SendParams *params = reinterpret_cast<SendParams *>(data); 00177 send(params->cmd, *params->arr); 00178 return; 00179 } 00180 case VIRTUAL_HOLD: { 00181 HoldParams *params = reinterpret_cast<HoldParams *>(data); 00182 hold(*params->url); 00183 return; 00184 } 00185 case VIRTUAL_SUSPENDED: { 00186 SuspendedParams *params = reinterpret_cast<SuspendedParams *>(data); 00187 params->retval = suspended(); 00188 return; 00189 } 00190 case VIRTUAL_SET_HOST: { 00191 SetHostParams *params = reinterpret_cast<SetHostParams *>(data); 00192 setHost(*params->host,params->port,*params->user,*params->passwd); 00193 return; 00194 } 00195 case VIRTUAL_SET_CONFIG: { 00196 SetConfigParams *params = reinterpret_cast<SetConfigParams *>(data); 00197 setConfig(*params->config); 00198 return; 00199 } 00200 default: 00201 KIO::Slave::virtual_hook( id, data ); 00202 } 00203 } 00204 00205 DISPATCH_IMPL1(mimeType, const TQString &, s) 00206 DISPATCH_IMPL1(totalSize, KIO::filesize_t, size) 00207 DISPATCH_IMPL(sendMetaData) 00208 DISPATCH_IMPL1(data, const TQByteArray &, ba) 00209 00210 #undef DISPATCH_IMPL 00211 #undef DISPATCH_IMPL1 00212 00213 #include "dataslave.moc"