/src/libtomahawk/network/MsgProcessor.cpp

http://github.com/tomahawk-player/tomahawk · C++ · 143 lines · 94 code · 22 blank · 27 comment · 12 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. #include "MsgProcessor.h"
  19. #include "network/Msg_p.h"
  20. #include "network/Servent.h"
  21. #include "utils/Json.h"
  22. #include "utils/Logger.h"
  23. #include "utils/TomahawkUtils.h"
  24. #include <QThread>
  25. #include <QFuture>
  26. #include <QFutureWatcher>
  27. #include <qtconcurrentrun.h>
  28. MsgProcessor::MsgProcessor( quint32 mode, quint32 t ) :
  29. QObject(), m_mode( mode ), m_threshold( t ), m_totmsgsize( 0 )
  30. {
  31. moveToThread( Servent::instance()->thread() );
  32. }
  33. void
  34. MsgProcessor::append( msg_ptr msg )
  35. {
  36. if( QThread::currentThread() != thread() )
  37. {
  38. qDebug() << "reinvoking msgprocessor::append in correct thread, ie not" << QThread::currentThread();
  39. QMetaObject::invokeMethod( this, "append", Qt::QueuedConnection, Q_ARG(msg_ptr, msg) );
  40. return;
  41. }
  42. m_msgs.append( msg );
  43. m_msg_ready.insert( msg.data(), false );
  44. m_totmsgsize += msg->payload().length();
  45. if( m_mode & NOTHING )
  46. {
  47. //qDebug() << "MsgProcessor::NOTHING";
  48. handleProcessedMsg( msg );
  49. return;
  50. }
  51. QFuture<msg_ptr> fut = QtConcurrent::run(&MsgProcessor::process, msg, m_mode, m_threshold);
  52. QFutureWatcher<msg_ptr> * watcher = new QFutureWatcher<msg_ptr>;
  53. connect( watcher, SIGNAL( finished() ),
  54. this, SLOT( processed() ),
  55. Qt::QueuedConnection );
  56. watcher->setFuture( fut );
  57. }
  58. void
  59. MsgProcessor::processed()
  60. {
  61. QFutureWatcher<msg_ptr> * watcher = (QFutureWatcher<msg_ptr> *) sender();
  62. msg_ptr msg = watcher->result();
  63. watcher->deleteLater();
  64. handleProcessedMsg( msg );
  65. }
  66. void
  67. MsgProcessor::handleProcessedMsg( msg_ptr msg )
  68. {
  69. Q_ASSERT( QThread::currentThread() == thread() );
  70. m_msg_ready.insert( msg.data(), true );
  71. while( !m_msgs.isEmpty() )
  72. {
  73. if( m_msg_ready.value( m_msgs.first().data() ) )
  74. {
  75. msg_ptr m = m_msgs.takeFirst();
  76. m_msg_ready.remove( m.data() );
  77. //qDebug() << Q_FUNC_INFO << "totmsgsize:" << m_totmsgsize;
  78. emit ready( m );
  79. }
  80. else
  81. {
  82. return;
  83. }
  84. }
  85. //qDebug() << Q_FUNC_INFO << "EMPTY, no msgs left.";
  86. emit empty();
  87. }
  88. /// This method is run by QtConcurrent:
  89. msg_ptr
  90. MsgProcessor::process( msg_ptr msg, quint32 mode, quint32 threshold )
  91. {
  92. // uncompress if needed
  93. if( (mode & UNCOMPRESS_ALL) && msg->is( Msg::COMPRESSED ) )
  94. {
  95. // qDebug() << "MsgProcessor::UNCOMPRESSING";
  96. msg->d_func()->payload = qUncompress( msg->payload() );
  97. msg->d_func()->length = msg->d_func()->payload.length();
  98. msg->d_func()->flags ^= Msg::COMPRESSED;
  99. }
  100. // parse json payload into qvariant if needed
  101. if( (mode & PARSE_JSON) &&
  102. msg->is( Msg::JSON ) &&
  103. msg->d_func()->json_parsed == false )
  104. {
  105. // qDebug() << "MsgProcessor::PARSING JSON";
  106. bool ok;
  107. msg->d_func()->json = TomahawkUtils::parseJson( msg->payload(), &ok );
  108. msg->d_func()->json_parsed = true;
  109. }
  110. // compress if needed
  111. if( (mode & COMPRESS_IF_LARGE) &&
  112. !msg->is( Msg::COMPRESSED )
  113. && msg->length() > threshold )
  114. {
  115. // qDebug() << "MsgProcessor::COMPRESSING";
  116. msg->d_func()->payload = qCompress( msg->payload(), 9 );
  117. msg->d_func()->length = msg->d_func()->payload.length();
  118. msg->d_func()->flags |= Msg::COMPRESSED;
  119. }
  120. return msg;
  121. }