/*************************************************************************** * Copyright (C) 2010 by Ilya Kotov * * forkotov02@hotmail.ru * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program 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 General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include "downloader.h" Downloader::Downloader(QObject *parent, const QString &url) : QThread(parent) { m_url = url; m_handle = 0; m_aborted = false; QSettings settings(Qmmp::configFile(), QSettings::IniFormat); m_prebuf_size = settings.value("MMS/buffer_size",128).toInt() * 1024; m_buffer_size = m_prebuf_size; m_buffer = (char *)malloc(m_buffer_size); m_ready = false; m_buffer_at = 0; } Downloader::~Downloader() { abort(); free(m_buffer); m_buffer = 0; m_buffer_at = 0; m_buffer_size = 0; } qint64 Downloader::read(char* data, qint64 maxlen) { m_mutex.lock(); qint64 len = qMin(m_buffer_at, maxlen); memmove(data, m_buffer, len); m_buffer_at -= len; memmove(m_buffer, m_buffer + len, m_buffer_at); m_mutex.unlock(); return len; } QMutex *Downloader::mutex() { return &m_mutex; } QString Downloader::contentType() { return "audio/x-ms-wma"; } void Downloader::abort() { m_mutex.lock(); if (m_aborted) { m_mutex.unlock(); return; } m_aborted = true; m_ready = false; m_mutex.unlock(); wait(); if (m_handle) mms_close(m_handle); m_handle = 0; } qint64 Downloader::bytesAvailable() { m_mutex.lock(); qint64 b = m_buffer_at; m_mutex.unlock(); return b; } void Downloader::run() { m_handle = mms_connect (0, 0, m_url.toLocal8Bit().constData(), 128 * 1024); if(!m_handle) { qWarning("Downloader: connection failed"); return; } m_mutex.lock(); if(m_aborted) { m_mutex.unlock(); qDebug("Downloader: aborted"); return; } m_mutex.unlock(); qint64 len = 0; forever { m_mutex.lock(); int to_read = 1024; if(m_buffer_at + to_read > m_buffer_size) { m_buffer_size = m_buffer_at + to_read; m_buffer = (char *)realloc(m_buffer, m_buffer_size); } len = mms_read (0, m_handle, m_buffer + m_buffer_at, to_read); if(len < 0) { qWarning("Downloader: error: %s", strerror(len)); m_mutex.unlock(); break; } m_buffer_at += len; if(!m_ready) checkBuffer(); m_mutex.unlock(); if(m_aborted) break; usleep(5000); } } void Downloader::checkBuffer() { if (m_buffer_at > m_prebuf_size && !m_ready) { m_ready = true; qDebug("Downloader: ready"); QMap metaData; metaData.insert(Qmmp::URL, m_url); StateHandler::instance()->dispatch(metaData); emit readyRead(); } else if (!m_ready) { StateHandler::instance()->dispatchBuffer(100 * m_buffer_at / m_buffer_size); qApp->processEvents(); } } bool Downloader::isReady() { return m_ready; }