add more spacing
[personal-kdebase.git] / runtime / phonon / platform_kde / kiomediastream.cpp
blobd2553964fc6542f5d75711aa6c4f36e2c352e4bb
1 /* This file is part of the KDE project
2 Copyright (C) 2007 Matthias Kretz <kretz@kde.org>
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
20 #include "kiomediastream.h"
21 #include "kiomediastream_p.h"
22 #include <kdebug.h>
23 #include <kprotocolmanager.h>
24 #include <kio/filejob.h>
25 #include <kio/job.h>
26 #include <klocale.h>
28 namespace Phonon
31 KioMediaStream::KioMediaStream(const QUrl &url, QObject *parent)
32 : AbstractMediaStream(parent),
33 d_ptr(new KioMediaStreamPrivate(url))
35 d_ptr->q_ptr = this;
36 kDebug(600);
37 reset();
40 void KioMediaStream::reset()
42 kDebug(600);
43 Q_D(KioMediaStream);
44 if (d->kiojob) {
45 d->kiojob->disconnect(this);
46 d->kiojob->kill();
48 d->endOfDataSent = false;
49 d->seeking = false;
50 d->reading = false;
51 d->open = false;
52 d->seekPosition = 0;
55 if (KProtocolManager::supportsOpening(d->url)) {
56 d->kiojob = KIO::open(d->url, QIODevice::ReadOnly);
57 Q_ASSERT(d->kiojob);
58 d->open = false;
59 setStreamSeekable(true);
60 connect(d->kiojob, SIGNAL(open(KIO::Job *)), this, SLOT(_k_bytestreamFileJobOpen(KIO::Job *)));
61 connect(d->kiojob, SIGNAL(position(KIO::Job *, KIO::filesize_t)),
62 this, SLOT(_k_bytestreamSeekDone(KIO::Job *, KIO::filesize_t)));
63 } else {
64 d->kiojob = KIO::get(d->url, KIO::NoReload, KIO::HideProgressInfo);
65 Q_ASSERT(d->kiojob);
66 setStreamSeekable(false);
67 connect(d->kiojob, SIGNAL(totalSize(KJob *, qulonglong)),
68 this, SLOT(_k_bytestreamTotalSize(KJob *,qulonglong)));
69 d->kiojob->suspend();
72 d->kiojob->addMetaData("UserAgent", QLatin1String("KDE Phonon"));
73 connect(d->kiojob, SIGNAL(data(KIO::Job *,const QByteArray &)),
74 this, SLOT(_k_bytestreamData(KIO::Job *,const QByteArray &)));
75 connect(d->kiojob, SIGNAL(result(KJob *)), this, SLOT(_k_bytestreamResult(KJob *)));
78 KioMediaStream::~KioMediaStream()
80 kDebug(600);
81 Q_D(KioMediaStream);
82 if (d->kiojob) {
83 d->kiojob->disconnect(this);
84 KIO::FileJob *filejob = qobject_cast<KIO::FileJob *>(d->kiojob);
85 if (filejob) {
86 filejob->close();
88 d->kiojob->kill();
90 delete d_ptr;
93 void KioMediaStream::needData()
95 Q_D(KioMediaStream);
96 if (!d->kiojob) {
97 // no job => job is finished and endOfData was already sent
98 return;
100 KIO::FileJob *filejob = qobject_cast<KIO::FileJob *>(d->kiojob);
101 if (filejob) {
102 // while d->seeking the backend won't get any data
103 if (d->seeking || !d->open) {
104 d->reading = true;
105 } else if (!d->reading) {
106 d->reading = true;
107 QMetaObject::invokeMethod(this, "_k_read", Qt::QueuedConnection);
108 //filejob->read(32768);
110 } else {
111 // KIO::TransferJob
112 d->kiojob->resume();
116 void KioMediaStream::enoughData()
118 Q_D(KioMediaStream);
119 kDebug(600);
120 // Don't suspend when using a FileJob. The FileJob is controlled by calls to
121 // FileJob::read()
122 if (d->kiojob && !qobject_cast<KIO::FileJob *>(d->kiojob) && !d->kiojob->isSuspended()) {
123 d->kiojob->suspend();
124 } else {
125 d->reading = false;
129 void KioMediaStream::seekStream(qint64 position)
131 Q_D(KioMediaStream);
132 if (!d->kiojob || d->endOfDataSent) {
133 // no job => job is finished and endOfData was already sent
134 kDebug(600) << "no job/job finished -> recreate it";
135 reset();
137 Q_ASSERT(d->kiojob);
138 kDebug(600) << position << " = " << qulonglong(position);
139 d->seeking = true;
140 d->seekPosition = position;
141 if (d->open) {
142 KIO::FileJob *filejob = qobject_cast<KIO::FileJob *>(d->kiojob);
143 filejob->seek(position);
147 void KioMediaStreamPrivate::_k_bytestreamData(KIO::Job *, const QByteArray &data)
149 Q_Q(KioMediaStream);
150 Q_ASSERT(kiojob);
151 if (q->streamSize() == 0) {
152 q->setStreamSize(-1);
154 if (seeking) {
155 // seek doesn't block, so don't send data to the backend until it signals us
156 // that the seek is done
157 kDebug(600) << "seeking: do nothing";
158 return;
161 if (data.isEmpty()) {
162 reading = false;
163 if (!endOfDataSent) {
164 kDebug(600) << "empty data: stopping the stream";
165 endOfDataSent = true;
166 q->endOfData();
168 return;
171 //kDebug(600) << "calling writeData on the Backend ByteStream " << data.size();
172 q->writeData(data);
173 if (reading) {
174 Q_ASSERT(qobject_cast<KIO::FileJob *>(kiojob));
175 QMetaObject::invokeMethod(q, "_k_read", Qt::QueuedConnection);
179 void KioMediaStreamPrivate::_k_bytestreamResult(KJob *job)
181 Q_Q(KioMediaStream);
182 Q_ASSERT(kiojob == job);
183 if (job->error()) {
184 QString kioErrorString = job->errorString();
185 kDebug(600) << "KIO Job error: " << kioErrorString;
186 QObject::disconnect(kiojob, SIGNAL(data(KIO::Job *,const QByteArray &)),
187 q, SLOT(_k_bytestreamData(KIO::Job *,const QByteArray &)));
188 QObject::disconnect(kiojob, SIGNAL(result(KJob *)),
189 q, SLOT(_k_bytestreamResult(KJob *)));
190 KIO::FileJob *filejob = qobject_cast<KIO::FileJob *>(kiojob);
191 if (filejob) {
192 QObject::disconnect(kiojob, SIGNAL(open(KIO::Job *)),
193 q, SLOT(_k_bytestreamFileJobOpen(KIO::Job *)));
194 QObject::disconnect(kiojob, SIGNAL(position(KIO::Job *, KIO::filesize_t)),
195 q, SLOT(_k_bytestreamSeekDone(KIO::Job *, KIO::filesize_t)));
196 } else {
197 QObject::disconnect(kiojob, SIGNAL(totalSize(KJob *, qulonglong)),
198 q, SLOT(_k_bytestreamTotalSize(KJob *,qulonglong)));
200 // go to ErrorState - NormalError
201 q->error(NormalError, kioErrorString);
202 } else if (seeking) {
203 open = false;
204 kiojob = 0;
205 endOfDataSent = false;
206 reading = false;
207 q->reset();
208 return;
210 open = false;
211 kiojob = 0;
212 kDebug(600) << "KIO Job is done (will delete itself) and d->kiojob reset to 0";
213 endOfDataSent = true;
214 q->endOfData();
215 reading = false;
218 void KioMediaStreamPrivate::_k_bytestreamTotalSize(KJob *, qulonglong size)
220 Q_Q(KioMediaStream);
221 kDebug(600) << size;
222 q->setStreamSize(size > 0 ? size : -1);
225 void KioMediaStreamPrivate::_k_bytestreamFileJobOpen(KIO::Job *)
227 Q_Q(KioMediaStream);
228 Q_ASSERT(kiojob);
229 open = true;
230 endOfDataSent = false;
231 KIO::FileJob *filejob = static_cast<KIO::FileJob *>(kiojob);
232 kDebug(600) << filejob->size();
233 q->setStreamSize(filejob->size() > 0 ? filejob->size() : -1);
235 if (seeking) {
236 filejob->seek(seekPosition);
237 } else if (reading) {
238 //filejob->read(32768);
239 QMetaObject::invokeMethod(q, "_k_read", Qt::QueuedConnection);
243 void KioMediaStreamPrivate::_k_bytestreamSeekDone(KIO::Job *, KIO::filesize_t offset)
245 Q_ASSERT(kiojob);
246 kDebug(600) << offset;
247 seeking = false;
248 endOfDataSent = false;
249 if (reading) {
250 Q_Q(KioMediaStream);
251 Q_ASSERT(qobject_cast<KIO::FileJob *>(kiojob));
252 QMetaObject::invokeMethod(q, "_k_read", Qt::QueuedConnection);
256 void KioMediaStreamPrivate::_k_read()
258 KIO::FileJob *filejob = qobject_cast<KIO::FileJob *>(kiojob);
259 Q_ASSERT(filejob);
260 filejob->read(32768);
263 } // namespace Phonon
265 #include "kiomediastream.moc"
266 // vim: sw=4 sts=4 et tw=100