arts Library API Documentation

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);
KDE Logo
This file is part of the documentation for arts Library Version 3.3.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sun Oct 17 11:31:10 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003