| # arts Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# kioinputstream_impl.cpp

    00001     /*
    00002
    00003     Copyright (C) 2001 Nikolas Zimmermann <wildfox@kde.org>
    00004
    00005     This library is free software; you can redistribute it and/or
    00006     modify it under the terms of the GNU Library General Public
    00007     License as published by the Free Software Foundation; either
    00008     version 2 of the License, or (at your option) any later version.
    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., 59 Temple Place - Suite 330,
    00018     Boston, MA 02111-1307, USA.
    00019
    00020     */
    00021
    00022 /*
    00023  * How does it work?
    00024  * -----------------
    00025  *
    00026  * First the buffer has to be filled. When it reaches a defined size the outdata
    00027  * stream has to start pulling packets. If the buffer reaches a size of zero the
    00028  * stream has to stop. If the buffer gets to big the job has to be suspended
    00029  * until the buffer is small enough again.
    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     // prevent kill/reconnect
    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     //kdDebug( 400 ) << "STREAMING: buffersize = " << m_data.size() << " bytes" << endl;
    00135
    00136     processQueue();
    00137 }
    00138
    00139 void KIOInputStream_impl::slotResult(KIO::Job *job)
    00140 {
    00141     // jobs delete themselves after emitting their result
    00142     m_finished = true;
    00143     m_streamStarted = false;
    00144     m_job = 0;
    00145
    00146     if(job->error()) {
    00147         // break out of the event loop in case of
    00148         // connection error
    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);

This file is part of the documentation for arts Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:27:55 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003