PageRenderTime 83ms CodeModel.GetById 40ms app.highlight 14ms RepoModel.GetById 26ms app.codeStats 0ms

/src/libtomahawk/network/MsgProcessor.cpp

http://github.com/tomahawk-player/tomahawk
C++ | 143 lines | 94 code | 22 blank | 27 comment | 11 complexity | 0c59bc7e2d95e974756c468250a3fd6d MD5 | raw file
  1/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
  2 *
  3 *   Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
  4 *
  5 *   Tomahawk is free software: you can redistribute it and/or modify
  6 *   it under the terms of the GNU General Public License as published by
  7 *   the Free Software Foundation, either version 3 of the License, or
  8 *   (at your option) any later version.
  9 *
 10 *   Tomahawk is distributed in the hope that it will be useful,
 11 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 12 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 13 *   GNU General Public License for more details.
 14 *
 15 *   You should have received a copy of the GNU General Public License
 16 *   along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
 17 */
 18
 19#include "MsgProcessor.h"
 20
 21#include "network/Msg_p.h"
 22#include "network/Servent.h"
 23#include "utils/Json.h"
 24#include "utils/Logger.h"
 25#include "utils/TomahawkUtils.h"
 26
 27#include <QThread>
 28#include <QFuture>
 29#include <QFutureWatcher>
 30#include <qtconcurrentrun.h>
 31
 32MsgProcessor::MsgProcessor( quint32 mode, quint32 t ) :
 33    QObject(), m_mode( mode ), m_threshold( t ), m_totmsgsize( 0 )
 34{
 35    moveToThread( Servent::instance()->thread() );
 36}
 37
 38
 39void
 40MsgProcessor::append( msg_ptr msg )
 41{
 42    if( QThread::currentThread() != thread() )
 43    {
 44        qDebug() << "reinvoking msgprocessor::append in correct thread, ie not" << QThread::currentThread();
 45        QMetaObject::invokeMethod( this, "append", Qt::QueuedConnection, Q_ARG(msg_ptr, msg) );
 46        return;
 47    }
 48
 49    m_msgs.append( msg );
 50    m_msg_ready.insert( msg.data(), false );
 51
 52    m_totmsgsize += msg->payload().length();
 53
 54    if( m_mode & NOTHING )
 55    {
 56        //qDebug() << "MsgProcessor::NOTHING";
 57        handleProcessedMsg( msg );
 58        return;
 59    }
 60
 61    QFuture<msg_ptr> fut = QtConcurrent::run(&MsgProcessor::process, msg, m_mode, m_threshold);
 62    QFutureWatcher<msg_ptr> * watcher = new QFutureWatcher<msg_ptr>;
 63    connect( watcher, SIGNAL( finished() ),
 64             this, SLOT( processed() ),
 65             Qt::QueuedConnection );
 66
 67    watcher->setFuture( fut );
 68}
 69
 70
 71void
 72MsgProcessor::processed()
 73{
 74    QFutureWatcher<msg_ptr> * watcher = (QFutureWatcher<msg_ptr> *) sender();
 75    msg_ptr msg = watcher->result();
 76    watcher->deleteLater();
 77    handleProcessedMsg( msg );
 78}
 79
 80
 81void
 82MsgProcessor::handleProcessedMsg( msg_ptr msg )
 83{
 84    Q_ASSERT( QThread::currentThread() == thread() );
 85
 86    m_msg_ready.insert( msg.data(), true );
 87
 88    while( !m_msgs.isEmpty() )
 89    {
 90        if( m_msg_ready.value( m_msgs.first().data() ) )
 91        {
 92            msg_ptr m = m_msgs.takeFirst();
 93            m_msg_ready.remove( m.data() );
 94            //qDebug() << Q_FUNC_INFO << "totmsgsize:" << m_totmsgsize;
 95            emit ready( m );
 96        }
 97        else
 98        {
 99            return;
100        }
101    }
102
103    //qDebug() << Q_FUNC_INFO << "EMPTY, no msgs left.";
104    emit empty();
105}
106
107
108/// This method is run by QtConcurrent:
109msg_ptr
110MsgProcessor::process( msg_ptr msg, quint32 mode, quint32 threshold )
111{
112    // uncompress if needed
113    if( (mode & UNCOMPRESS_ALL) && msg->is( Msg::COMPRESSED ) )
114    {
115//        qDebug() << "MsgProcessor::UNCOMPRESSING";
116        msg->d_func()->payload = qUncompress( msg->payload() );
117        msg->d_func()->length  = msg->d_func()->payload.length();
118        msg->d_func()->flags ^= Msg::COMPRESSED;
119    }
120
121    // parse json payload into qvariant if needed
122    if( (mode & PARSE_JSON) &&
123        msg->is( Msg::JSON ) &&
124        msg->d_func()->json_parsed == false )
125    {
126//        qDebug() << "MsgProcessor::PARSING JSON";
127        bool ok;
128        msg->d_func()->json = TomahawkUtils::parseJson( msg->payload(), &ok );
129        msg->d_func()->json_parsed = true;
130    }
131
132    // compress if needed
133    if( (mode & COMPRESS_IF_LARGE) &&
134        !msg->is( Msg::COMPRESSED )
135        && msg->length() > threshold )
136    {
137//        qDebug() << "MsgProcessor::COMPRESSING";
138        msg->d_func()->payload = qCompress( msg->payload(), 9 );
139        msg->d_func()->length  = msg->d_func()->payload.length();
140        msg->d_func()->flags |= Msg::COMPRESSED;
141    }
142    return msg;
143}