00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
#include <kapplication.h>
00033
#include <kdebug.h>
00034
#include <kio/job.h>
00035
#include <kio/kmimetype.h>
00036
#include <kio/jobclasses.h>
00037
#include <qtimer.h>
00038
#include <qdatastream.h>
00039
#include "artsversion.h"
00040
#include "kioinputstream_impl.moc"
00041
00042
using namespace Arts;
00043
00044
const unsigned int KIOInputStream_impl::PACKET_COUNT = 10;
00045
00046 KIOInputStream_impl::KIOInputStream_impl() : m_packetSize(2048)
00047 {
00048 m_job = 0;
00049 m_finished =
false;
00050 m_firstBuffer =
false;
00051 m_packetBuffer = 16;
00052 m_streamStarted =
false;
00053 m_streamSuspended =
false;
00054 m_streamPulled =
false;
00055 m_size = 0;
00056 }
00057
00058 KIOInputStream_impl::~KIOInputStream_impl()
00059 {
00060
if(m_job != 0)
00061 m_job->kill();
00062 }
00063
00064
void KIOInputStream_impl::streamStart()
00065 {
00066
00067
if (m_streamStarted) {
00068
kdDebug( 400 ) <<
"not restarting stream!\n";
00069
if (m_job->isSuspended())
00070 m_job->resume();
00071
return;
00072 }
00073
00074
kdDebug( 400 ) <<
"(re)starting stream\n";
00075
00076
if(m_job != 0)
00077 m_job->kill();
00078 m_job =
KIO::get(m_url,
false,
false);
00079
00080 m_job->addMetaData(
"accept",
"audio/x-mp3, video/mpeg, application/ogg");
00081 m_job->addMetaData(
"UserAgent", QString::fromLatin1(
"aRts/") + QString::fromLatin1(ARTS_VERSION));
00082
00083 QObject::connect(m_job, SIGNAL(
data(
KIO::Job *,
const QByteArray &)),
00084
this, SLOT(slotData(
KIO::Job *,
const QByteArray &)));
00085 QObject::connect(m_job, SIGNAL(result(
KIO::Job *)),
00086
this, SLOT(slotResult(
KIO::Job *)));
00087 QObject::connect(m_job, SIGNAL(
mimetype(
KIO::Job *,
const QString &)),
00088
this, SLOT(slotScanMimeType(
KIO::Job *,
const QString &)));
00089 QObject::connect(m_job, SIGNAL(totalSize(
KIO::Job *,
KIO::filesize_t)),
00090
this, SLOT(slotTotalSize(
KIO::Job *,
KIO::filesize_t)));
00091
00092 m_streamStarted =
true;
00093 }
00094
00095
void KIOInputStream_impl::streamEnd()
00096 {
00097
kdDebug( 400 ) <<
"streamEnd()\n";
00098
00099
if(m_job != 0)
00100 {
00101 QObject::disconnect(m_job, SIGNAL(
data(
KIO::Job *,
const QByteArray &)),
00102
this, SLOT(slotData(
KIO::Job *,
const QByteArray &)));
00103 QObject::disconnect(m_job, SIGNAL(result(
KIO::Job *)),
00104
this, SLOT(slotResult(
KIO::Job *)));
00105 QObject::disconnect(m_job, SIGNAL(
mimetype(
KIO::Job *,
const QString &)),
00106
this, SLOT(slotScanMimeType(
KIO::Job *,
const QString &)));
00107 QObject::disconnect(m_job, SIGNAL(totalSize(
KIO::Job *,
KIO::filesize_t)),
00108
this, SLOT(slotTotalSize(
KIO::Job *,
KIO::filesize_t)));
00109
00110
if ( m_streamPulled )
00111 outdata.endPull();
00112
00113 m_job->kill();
00114 m_job = 0;
00115 }
00116
00117 m_streamStarted =
false;
00118 }
00119
00120
bool KIOInputStream_impl::openURL(
const std::string& url)
00121 {
00122 m_url =
KURL(url.c_str());
00123 m_size = 0;
00124
return true;
00125 }
00126
00127
void KIOInputStream_impl::slotData(
KIO::Job *,
const QByteArray &data)
00128 {
00129
if(m_finished)
00130 m_finished =
false;
00131
00132
QDataStream dataStream(m_data, IO_WriteOnly | IO_Append);
00133 dataStream.writeRawBytes(data.data(), data.size());
00134
00135
00136 processQueue();
00137 }
00138
00139
void KIOInputStream_impl::slotResult(
KIO::Job *job)
00140 {
00141
00142 m_finished =
true;
00143 m_streamStarted =
false;
00144 m_job = 0;
00145
00146
if(job->
error()) {
00147
00148
00149 emit mimeTypeFound(
"application/x-zerosize");
00150 job->
showErrorDialog();
00151 }
00152 }
00153
00154
void KIOInputStream_impl::slotScanMimeType(
KIO::Job *,
const QString &mimetype)
00155 {
00156
kdDebug( 400 ) <<
"got mimetype: " <<
mimetype <<
endl;
00157 emit mimeTypeFound(mimetype);
00158 }
00159
00160
void KIOInputStream_impl::slotTotalSize(
KIO::Job *,
KIO::filesize_t size)
00161 {
00162 m_size = size;
00163 }
00164
00165
bool KIOInputStream_impl::eof()
00166 {
00167
return (m_finished && m_data.size() == 0);
00168 }
00169
00170
bool KIOInputStream_impl::seekOk()
00171 {
00172
return false;
00173 }
00174
00175
long KIOInputStream_impl::size()
00176 {
00177
return m_size ? m_size : m_data.size();
00178 }
00179
00180
long KIOInputStream_impl::seek(
long)
00181 {
00182
return -1;
00183 }
00184
00185
void KIOInputStream_impl::processQueue()
00186 {
00187
if(m_job != 0)
00188 {
00189
if(m_data.size() > (m_packetBuffer * m_packetSize * 2) && !m_job->isSuspended())
00190 {
00191
kdDebug( 400 ) <<
"STREAMING: suspend job" <<
endl;
00192 m_job->suspend();
00193 }
00194
else if(m_data.size() < (m_packetBuffer * m_packetSize) && m_job->isSuspended())
00195 {
00196
kdDebug( 400 ) <<
"STREAMING: resume job" <<
endl;
00197 m_job->resume();
00198 }
00199 }
00200
00201
if (!m_firstBuffer) {
00202
if(m_data.size() < (m_packetBuffer * m_packetSize * 2) ) {
00203
kdDebug( 400 ) <<
"STREAMING: Buffering in progress... (Needed bytes before it starts to play: " << ((m_packetBuffer * m_packetSize * 2) - m_data.size()) <<
")" <<
endl;
00204
return;
00205 }
else {
00206 m_firstBuffer =
true;
00207 m_streamPulled =
true;
00208 outdata.setPull(PACKET_COUNT, m_packetSize);
00209 }
00210 }
00211 }
00212
00213
void KIOInputStream_impl::request_outdata(DataPacket<mcopbyte> *packet)
00214 {
00215 processQueue();
00216 packet->size = std::min(m_packetSize, m_data.size());
00217
kdDebug( 400 ) <<
"STREAMING: Filling one DataPacket with " << packet->size <<
" bytes of the stream!" <<
endl;
00218
00219
if (!m_finished) {
00220
if( (
unsigned)packet->size < m_packetSize || ! m_firstBuffer) {
00221 m_firstBuffer =
false;
00222 packet->size = 0;
00223 outdata.endPull();
00224 }
00225 }
00226
00227
if (packet->size > 0)
00228 {
00229 memcpy(packet->contents, m_data.data(), packet->size);
00230 memmove(m_data.data(), m_data.data() + packet->size, m_data.size() - packet->size);
00231 m_data.resize(m_data.size() - packet->size);
00232 }
00233 packet->send();
00234 }
00235
00236 REGISTER_IMPLEMENTATION(KIOInputStream_impl);