summaryrefslogtreecommitdiffstats
path: root/arts/kde/kioinputstream_impl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'arts/kde/kioinputstream_impl.cpp')
-rw-r--r--arts/kde/kioinputstream_impl.cpp236
1 files changed, 236 insertions, 0 deletions
diff --git a/arts/kde/kioinputstream_impl.cpp b/arts/kde/kioinputstream_impl.cpp
new file mode 100644
index 000000000..b82764931
--- /dev/null
+++ b/arts/kde/kioinputstream_impl.cpp
@@ -0,0 +1,236 @@
+ /*
+
+ Copyright (C) 2001 Nikolas Zimmermann <wildfox@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ */
+
+/*
+ * How does it work?
+ * -----------------
+ *
+ * First the buffer has to be filled. When it reaches a defined size the outdata
+ * stream has to start pulling packets. If the buffer reaches a size of zero the
+ * stream has to stop. If the buffer gets to big the job has to be suspended
+ * until the buffer is small enough again.
+ */
+
+#include <kapplication.h>
+#include <kdebug.h>
+#include <kio/job.h>
+#include <kio/kmimetype.h>
+#include <kio/jobclasses.h>
+#include <qtimer.h>
+#include <qdatastream.h>
+#include "artsversion.h"
+#include "kioinputstream_impl.moc"
+
+using namespace Arts;
+
+const unsigned int KIOInputStream_impl::PACKET_COUNT = 10;
+
+KIOInputStream_impl::KIOInputStream_impl() : m_packetSize(2048)
+{
+ m_job = 0;
+ m_finished = false;
+ m_firstBuffer = false;
+ m_packetBuffer = 16;
+ m_streamStarted = false;
+ m_streamSuspended = false;
+ m_streamPulled = false;
+ m_size = 0;
+}
+
+KIOInputStream_impl::~KIOInputStream_impl()
+{
+ if(m_job != 0)
+ m_job->kill();
+}
+
+void KIOInputStream_impl::streamStart()
+{
+ // prevent kill/reconnect
+ if (m_streamStarted) {
+ kdDebug( 400 ) << "not restarting stream!\n";
+ if (m_job->isSuspended())
+ m_job->resume();
+ return;
+ }
+
+ kdDebug( 400 ) << "(re)starting stream\n";
+
+ if(m_job != 0)
+ m_job->kill();
+ m_job = KIO::get(m_url, false, false);
+
+ m_job->addMetaData("accept", "audio/x-mp3, video/mpeg, application/ogg");
+ m_job->addMetaData("UserAgent", QString::fromLatin1("aRts/") + QString::fromLatin1(ARTS_VERSION));
+
+ QObject::connect(m_job, SIGNAL(data(KIO::Job *, const QByteArray &)),
+ this, SLOT(slotData(KIO::Job *, const QByteArray &)));
+ QObject::connect(m_job, SIGNAL(result(KIO::Job *)),
+ this, SLOT(slotResult(KIO::Job *)));
+ QObject::connect(m_job, SIGNAL(mimetype(KIO::Job *, const QString &)),
+ this, SLOT(slotScanMimeType(KIO::Job *, const QString &)));
+ QObject::connect(m_job, SIGNAL(totalSize( KIO::Job *, KIO::filesize_t)),
+ this, SLOT(slotTotalSize(KIO::Job *, KIO::filesize_t)));
+
+ m_streamStarted = true;
+}
+
+void KIOInputStream_impl::streamEnd()
+{
+ kdDebug( 400 ) << "streamEnd()\n";
+
+ if(m_job != 0)
+ {
+ QObject::disconnect(m_job, SIGNAL(data(KIO::Job *, const QByteArray &)),
+ this, SLOT(slotData(KIO::Job *, const QByteArray &)));
+ QObject::disconnect(m_job, SIGNAL(result(KIO::Job *)),
+ this, SLOT(slotResult(KIO::Job *)));
+ QObject::disconnect(m_job, SIGNAL(mimetype(KIO::Job *, const QString &)),
+ this, SLOT(slotScanMimeType(KIO::Job *, const QString &)));
+ QObject::disconnect(m_job, SIGNAL(totalSize( KIO::Job *, KIO::filesize_t)),
+ this, SLOT(slotTotalSize(KIO::Job *, KIO::filesize_t)));
+
+ if ( m_streamPulled )
+ outdata.endPull();
+
+ m_job->kill();
+ m_job = 0;
+ }
+
+ m_streamStarted = false;
+}
+
+bool KIOInputStream_impl::openURL(const std::string& url)
+{
+ m_url = KURL(url.c_str());
+ m_size = 0;
+ return true;
+}
+
+void KIOInputStream_impl::slotData(KIO::Job *, const QByteArray &data)
+{
+ if(m_finished)
+ m_finished = false;
+
+ QDataStream dataStream(m_data, IO_WriteOnly | IO_Append);
+ dataStream.writeRawBytes(data.data(), data.size());
+ //kdDebug( 400 ) << "STREAMING: buffersize = " << m_data.size() << " bytes" << endl;
+
+ processQueue();
+}
+
+void KIOInputStream_impl::slotResult(KIO::Job *job)
+{
+ // jobs delete themselves after emitting their result
+ m_finished = true;
+ m_streamStarted = false;
+ m_job = 0;
+
+ if(job->error()) {
+ // break out of the event loop in case of
+ // connection error
+ emit mimeTypeFound("application/x-zerosize");
+ job->showErrorDialog();
+ }
+}
+
+void KIOInputStream_impl::slotScanMimeType(KIO::Job *, const QString &mimetype)
+{
+ kdDebug( 400 ) << "got mimetype: " << mimetype << endl;
+ emit mimeTypeFound(mimetype);
+}
+
+void KIOInputStream_impl::slotTotalSize(KIO::Job *, KIO::filesize_t size)
+{
+ m_size = size;
+}
+
+bool KIOInputStream_impl::eof()
+{
+ return (m_finished && m_data.size() == 0);
+}
+
+bool KIOInputStream_impl::seekOk()
+{
+ return false;
+}
+
+long KIOInputStream_impl::size()
+{
+ return m_size ? m_size : m_data.size();
+}
+
+long KIOInputStream_impl::seek(long)
+{
+ return -1;
+}
+
+void KIOInputStream_impl::processQueue()
+{
+ if(m_job != 0)
+ {
+ if(m_data.size() > (m_packetBuffer * m_packetSize * 2) && !m_job->isSuspended())
+ {
+ kdDebug( 400 ) << "STREAMING: suspend job" << endl;
+ m_job->suspend();
+ }
+ else if(m_data.size() < (m_packetBuffer * m_packetSize) && m_job->isSuspended())
+ {
+ kdDebug( 400 ) << "STREAMING: resume job" << endl;
+ m_job->resume();
+ }
+ }
+
+ if (!m_firstBuffer) {
+ if(m_data.size() < (m_packetBuffer * m_packetSize * 2) ) {
+ kdDebug( 400 ) << "STREAMING: Buffering in progress... (Needed bytes before it starts to play: " << ((m_packetBuffer * m_packetSize * 2) - m_data.size()) << ")" << endl;
+ return;
+ } else {
+ m_firstBuffer = true;
+ m_streamPulled = true;
+ outdata.setPull(PACKET_COUNT, m_packetSize);
+ }
+ }
+}
+
+void KIOInputStream_impl::request_outdata(DataPacket<mcopbyte> *packet)
+{
+ processQueue();
+ packet->size = std::min(m_packetSize, m_data.size());
+ kdDebug( 400 ) << "STREAMING: Filling one DataPacket with " << packet->size << " bytes of the stream!" << endl;
+
+ if (!m_finished) {
+ if( (unsigned)packet->size < m_packetSize || ! m_firstBuffer) {
+ m_firstBuffer = false;
+ packet->size = 0;
+ outdata.endPull();
+ }
+ }
+
+ if (packet->size > 0)
+ {
+ memcpy(packet->contents, m_data.data(), packet->size);
+ memmove(m_data.data(), m_data.data() + packet->size, m_data.size() - packet->size);
+ m_data.resize(m_data.size() - packet->size);
+ }
+ packet->send();
+}
+
+REGISTER_IMPLEMENTATION(KIOInputStream_impl);