From 5336e1838a95d97d34863b668ff797582c226e79 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Wed, 24 Nov 2010 19:50:09 +0100 Subject: QDeclarativeDebug: Move networking code out of QDeclarativeDebugServer Move socket handling code out of QDeclarativeDebugServer into a QDeclarativeDebugServer(Tcp)Connection class. Reviewed-by: Christiaan Janssen --- src/declarative/debugger/debugger.pri | 8 +- .../debugger/qdeclarativedebugserver.cpp | 131 ++++++----------- .../debugger/qdeclarativedebugserver_p.h | 13 +- .../debugger/qdeclarativedebugserverconnection_p.h | 68 +++++++++ .../debugger/qdeclarativedebugserverplugin_p.h | 0 .../qdeclarativedebugservertcpconnection.cpp | 163 +++++++++++++++++++++ .../qdeclarativedebugservertcpconnection_p.h | 86 +++++++++++ src/declarative/debugger/qpacketprotocol.cpp | 8 + src/declarative/debugger/qpacketprotocol_p.h | 1 + 9 files changed, 383 insertions(+), 95 deletions(-) create mode 100644 src/declarative/debugger/qdeclarativedebugserverconnection_p.h create mode 100644 src/declarative/debugger/qdeclarativedebugserverplugin_p.h create mode 100644 src/declarative/debugger/qdeclarativedebugservertcpconnection.cpp create mode 100644 src/declarative/debugger/qdeclarativedebugservertcpconnection_p.h diff --git a/src/declarative/debugger/debugger.pri b/src/declarative/debugger/debugger.pri index 144d896..e7354dc 100644 --- a/src/declarative/debugger/debugger.pri +++ b/src/declarative/debugger/debugger.pri @@ -8,7 +8,8 @@ SOURCES += \ $$PWD/qdeclarativedebug.cpp \ $$PWD/qdeclarativedebugtrace.cpp \ $$PWD/qdeclarativedebughelper.cpp \ - $$PWD/qdeclarativedebugserver.cpp + $$PWD/qdeclarativedebugserver.cpp \ + $$PWD/qdeclarativedebugservertcpconnection.cpp HEADERS += \ $$PWD/qdeclarativedebuggerstatus_p.h \ @@ -19,4 +20,7 @@ HEADERS += \ $$PWD/qdeclarativedebug_p.h \ $$PWD/qdeclarativedebugtrace_p.h \ $$PWD/qdeclarativedebughelper_p.h \ - $$PWD/qdeclarativedebugserver_p.h + $$PWD/qdeclarativedebugserverplugin_p.h \ + $$PWD/qdeclarativedebugserver_p.h \ + $$PWD/qdeclarativedebugservertcpconnection_p.h \ + debugger/qdeclarativedebugserverconnection_p.h diff --git a/src/declarative/debugger/qdeclarativedebugserver.cpp b/src/declarative/debugger/qdeclarativedebugserver.cpp index 4bb4e2c..6085e3e 100644 --- a/src/declarative/debugger/qdeclarativedebugserver.cpp +++ b/src/declarative/debugger/qdeclarativedebugserver.cpp @@ -42,15 +42,11 @@ #include "private/qdeclarativedebugserver_p.h" #include "private/qdeclarativedebugservice_p.h" #include "private/qdeclarativedebugservice_p_p.h" +#include "private/qdeclarativedebugservertcpconnection_p.h" #include "private/qdeclarativeengine_p.h" -#include "private/qpacketprotocol_p.h" - #include -#include -#include - #include #include @@ -89,73 +85,36 @@ public: void advertisePlugins(); - int port; - QTcpSocket *connection; - QPacketProtocol *protocol; + QDeclarativeDebugServerConnection *connection; QHash plugins; QStringList clientPlugins; - QTcpServer *tcpServer; bool gotHello; }; -QDeclarativeDebugServerPrivate::QDeclarativeDebugServerPrivate() -: connection(0), protocol(0), gotHello(false) +QDeclarativeDebugServerPrivate::QDeclarativeDebugServerPrivate() : + connection(0), + gotHello(false) { } void QDeclarativeDebugServerPrivate::advertisePlugins() { - if (!connection - || connection->state() != QTcpSocket::ConnectedState - || !gotHello) + if (!gotHello) return; - QPacket pack; - pack << QString(QLatin1String("QDeclarativeDebugClient")) << 1 << plugins.keys(); - protocol->send(pack); - connection->flush(); -} - -void QDeclarativeDebugServer::listen() -{ - Q_D(QDeclarativeDebugServer); - - d->tcpServer = new QTcpServer(this); - QObject::connect(d->tcpServer, SIGNAL(newConnection()), this, SLOT(newConnection())); - if (d->tcpServer->listen(QHostAddress::Any, d->port)) - qWarning("QDeclarativeDebugServer: Waiting for connection on port %d...", d->port); - else - qWarning("QDeclarativeDebugServer: Unable to listen on port %d", d->port); -} - -void QDeclarativeDebugServer::waitForConnection() -{ - Q_D(QDeclarativeDebugServer); - d->tcpServer->waitForNewConnection(-1); -} - -void QDeclarativeDebugServer::newConnection() -{ - Q_D(QDeclarativeDebugServer); - - if (d->connection) { - qWarning("QDeclarativeDebugServer error: another client is already connected"); - QTcpSocket *faultyConnection = d->tcpServer->nextPendingConnection(); - delete faultyConnection; - return; + QByteArray message; + { + QDataStream out(&message, QIODevice::WriteOnly); + out << QString(QLatin1String("QDeclarativeDebugClient")) << 1 << plugins.keys(); } - - d->connection = d->tcpServer->nextPendingConnection(); - d->connection->setParent(this); - d->protocol = new QPacketProtocol(d->connection, this); - QObject::connect(d->protocol, SIGNAL(readyRead()), this, SLOT(readyRead())); + connection->send(message); } bool QDeclarativeDebugServer::hasDebuggingClient() const { Q_D(const QDeclarativeDebugServer); return d->connection - && (d->connection->state() == QTcpSocket::ConnectedState) + && d->connection->isConnected() && d->gotHello; } @@ -192,11 +151,17 @@ QDeclarativeDebugServer *QDeclarativeDebugServer::instance() block = appD->qmljsDebugArgumentsString().contains(QLatin1String("block")); if (ok) { - server = new QDeclarativeDebugServer(port); - server->listen(); + server = new QDeclarativeDebugServer(); + + QDeclarativeDebugServerTcpConnection *tcpConnection + = new QDeclarativeDebugServerTcpConnection(port, server); + + tcpConnection->listen(); if (block) { - server->waitForConnection(); + tcpConnection->waitForConnection(); } + + server->d_func()->connection = tcpConnection; } else { qWarning(QString::fromAscii("QDeclarativeDebugServer: Ignoring \"-qmljsdebugger=%1\". " "Format is -qmljsdebugger=port:[,block]").arg( @@ -209,37 +174,31 @@ QDeclarativeDebugServer *QDeclarativeDebugServer::instance() return server; } -QDeclarativeDebugServer::QDeclarativeDebugServer(int port) +QDeclarativeDebugServer::QDeclarativeDebugServer() : QObject(*(new QDeclarativeDebugServerPrivate)) { - Q_D(QDeclarativeDebugServer); - d->port = port; } -void QDeclarativeDebugServer::readyRead() +void QDeclarativeDebugServer::receiveMessage(const QByteArray &message) { Q_D(QDeclarativeDebugServer); + QDataStream in(message); if (!d->gotHello) { - QPacket hello = d->protocol->read(); QString name; int op; - hello >> name >> op; + in >> name >> op; if (name != QLatin1String("QDeclarativeDebugServer") || op != 0) { qWarning("QDeclarativeDebugServer: Invalid hello message"); - QObject::disconnect(d->protocol, SIGNAL(readyRead()), this, SLOT(readyRead())); - d->protocol->deleteLater(); - d->protocol = 0; - d->connection->deleteLater(); - d->connection = 0; + d->connection->disconnect(); return; } int version; - hello >> version >> d->clientPlugins; + in >> version >> d->clientPlugins; QHash::Iterator iter = d->plugins.begin(); for (; iter != d->plugins.end(); ++iter) { @@ -250,31 +209,30 @@ void QDeclarativeDebugServer::readyRead() iter.value()->statusChanged(newStatus); } - QPacket helloAnswer; - helloAnswer << QString(QLatin1String("QDeclarativeDebugClient")) << 0 << protocolVersion << d->plugins.keys(); - d->protocol->send(helloAnswer); - d->connection->flush(); + QByteArray helloAnswer; + { + QDataStream out(&helloAnswer, QIODevice::WriteOnly); + out << QString(QLatin1String("QDeclarativeDebugClient")) << 0 << protocolVersion << d->plugins.keys(); + } + d->connection->send(helloAnswer); d->gotHello = true; qWarning("QDeclarativeDebugServer: Connection established"); - } + } else { - QString debugServer(QLatin1String("QDeclarativeDebugServer")); - - while (d->protocol->packetsAvailable()) { - QPacket pack = d->protocol->read(); + QString debugServer(QLatin1String("QDeclarativeDebugServer")); QString name; - pack >> name; + in >> name; if (name == debugServer) { int op = -1; - pack >> op; + in >> op; if (op == 1) { // Service Discovery QStringList oldClientPlugins = d->clientPlugins; - pack >> d->clientPlugins; + in >> d->clientPlugins; QHash::Iterator iter = d->plugins.begin(); for (; iter != d->plugins.end(); ++iter) { @@ -294,7 +252,7 @@ void QDeclarativeDebugServer::readyRead() } } else { QByteArray message; - pack >> message; + in >> message; QHash::Iterator iter = d->plugins.find(name); @@ -307,7 +265,6 @@ void QDeclarativeDebugServer::readyRead() } } - QList QDeclarativeDebugServer::services() const { const Q_D(QDeclarativeDebugServer); @@ -357,10 +314,12 @@ void QDeclarativeDebugServer::sendMessage(QDeclarativeDebugService *service, const QByteArray &message) { Q_D(QDeclarativeDebugServer); - QPacket pack; - pack << service->name() << message; - d->protocol->send(pack); - d->connection->flush(); + QByteArray msg; + { + QDataStream out(&msg, QIODevice::WriteOnly); + out << service->name() << message; + } + d->connection->send(msg); } QT_END_NAMESPACE diff --git a/src/declarative/debugger/qdeclarativedebugserver_p.h b/src/declarative/debugger/qdeclarativedebugserver_p.h index 6840d63..93ab10b 100644 --- a/src/declarative/debugger/qdeclarativedebugserver_p.h +++ b/src/declarative/debugger/qdeclarativedebugserver_p.h @@ -43,6 +43,7 @@ #define QDECLARATIVEDEBUGSERVER_H #include +#include QT_BEGIN_HEADER @@ -60,8 +61,9 @@ class QDeclarativeDebugServer : public QObject Q_DISABLE_COPY(QDeclarativeDebugServer) public: static QDeclarativeDebugServer *instance(); - void listen(); - void waitForConnection(); + + void setConnection(QDeclarativeDebugServerConnection *connection); + bool hasDebuggingClient() const; QList services() const; @@ -71,15 +73,12 @@ public: bool removeService(QDeclarativeDebugService *service); void sendMessage(QDeclarativeDebugService *service, const QByteArray &message); - -private Q_SLOTS: - void readyRead(); - void newConnection(); + void receiveMessage(const QByteArray &message); private: friend class QDeclarativeDebugService; friend class QDeclarativeDebugServicePrivate; - QDeclarativeDebugServer(int); + QDeclarativeDebugServer(); }; QT_END_NAMESPACE diff --git a/src/declarative/debugger/qdeclarativedebugserverconnection_p.h b/src/declarative/debugger/qdeclarativedebugserverconnection_p.h new file mode 100644 index 0000000..4175126 --- /dev/null +++ b/src/declarative/debugger/qdeclarativedebugserverconnection_p.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDECLARATIVEDEBUGSERVERCONNECTION_H +#define QDECLARATIVEDEBUGSERVERCONNECTION_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QDeclarativeDebugServerConnection +{ +public: + QDeclarativeDebugServerConnection() {} + virtual ~QDeclarativeDebugServerConnection() {} + + virtual bool isConnected() const = 0; + virtual void send(const QByteArray &message) = 0; + virtual void disconnect() = 0; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QDECLARATIVEDEBUGSERVERCONNECTION_H diff --git a/src/declarative/debugger/qdeclarativedebugserverplugin_p.h b/src/declarative/debugger/qdeclarativedebugserverplugin_p.h new file mode 100644 index 0000000..e69de29 diff --git a/src/declarative/debugger/qdeclarativedebugservertcpconnection.cpp b/src/declarative/debugger/qdeclarativedebugservertcpconnection.cpp new file mode 100644 index 0000000..223c875 --- /dev/null +++ b/src/declarative/debugger/qdeclarativedebugservertcpconnection.cpp @@ -0,0 +1,163 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdeclarativedebugservertcpconnection_p.h" + +#include "qdeclarativedebugserver_p.h" +#include "private/qpacketprotocol_p.h" + +#include +#include + + +QT_BEGIN_NAMESPACE + +class QDeclarativeDebugServerTcpConnectionPrivate { +public: + QDeclarativeDebugServerTcpConnectionPrivate(); + + int port; + QTcpSocket *socket; + QPacketProtocol *protocol; + QTcpServer *tcpServer; + + QDeclarativeDebugServer *debugServer; +}; + +QDeclarativeDebugServerTcpConnectionPrivate::QDeclarativeDebugServerTcpConnectionPrivate() : + port(0), + socket(0), + protocol(0), + tcpServer(0), + debugServer(0) +{ +} + +QDeclarativeDebugServerTcpConnection::QDeclarativeDebugServerTcpConnection(int port, QDeclarativeDebugServer *server) : + QObject(server), + d_ptr(new QDeclarativeDebugServerTcpConnectionPrivate) +{ + Q_D(QDeclarativeDebugServerTcpConnection); + d->port = port; + d->debugServer = server; +} + +QDeclarativeDebugServerTcpConnection::~QDeclarativeDebugServerTcpConnection() +{ + delete d_ptr; +} + +bool QDeclarativeDebugServerTcpConnection::isConnected() const +{ + Q_D(const QDeclarativeDebugServerTcpConnection); + return d->socket && d->socket->state() == QTcpSocket::ConnectedState; +} + +void QDeclarativeDebugServerTcpConnection::send(const QByteArray &message) +{ + Q_D(QDeclarativeDebugServerTcpConnection); + + if (!isConnected()) + return; + + QPacket pack; + pack.writeRawData(message.data(), message.length()); + + d->protocol->send(pack); + d->socket->flush(); +} + +void QDeclarativeDebugServerTcpConnection::disconnect() +{ + Q_D(QDeclarativeDebugServerTcpConnection); + + delete d->protocol; + d->protocol = 0; + delete d->socket; + d->socket = 0; +} + +void QDeclarativeDebugServerTcpConnection::listen() +{ + Q_D(QDeclarativeDebugServerTcpConnection); + + d->tcpServer = new QTcpServer(this); + QObject::connect(d->tcpServer, SIGNAL(newConnection()), this, SLOT(newConnection())); + if (d->tcpServer->listen(QHostAddress::Any, d->port)) + qWarning("QDeclarativeDebugServer: Waiting for connection on port %d...", d->port); + else + qWarning("QDeclarativeDebugServer: Unable to listen on port %d", d->port); +} + +void QDeclarativeDebugServerTcpConnection::waitForConnection() +{ + Q_D(QDeclarativeDebugServerTcpConnection); + d->tcpServer->waitForNewConnection(-1); +} + +void QDeclarativeDebugServerTcpConnection::readyRead() +{ + Q_D(QDeclarativeDebugServerTcpConnection); + QPacket packet = d->protocol->read(); + + QByteArray content = packet.data(); + d->debugServer->receiveMessage(content); +} + +void QDeclarativeDebugServerTcpConnection::newConnection() +{ + Q_D(QDeclarativeDebugServerTcpConnection); + + if (d->socket) { + qWarning("QDeclarativeDebugServer error: another client is already connected"); + QTcpSocket *faultyConnection = d->tcpServer->nextPendingConnection(); + delete faultyConnection; + return; + } + + d->socket = d->tcpServer->nextPendingConnection(); + d->socket->setParent(this); + d->protocol = new QPacketProtocol(d->socket, this); + QObject::connect(d->protocol, SIGNAL(readyRead()), this, SLOT(readyRead())); +} + + +QT_END_NAMESPACE diff --git a/src/declarative/debugger/qdeclarativedebugservertcpconnection_p.h b/src/declarative/debugger/qdeclarativedebugservertcpconnection_p.h new file mode 100644 index 0000000..f1c749ef --- /dev/null +++ b/src/declarative/debugger/qdeclarativedebugservertcpconnection_p.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDECLARATIVEDEBUGSERVERTCPCONNECTION_H +#define QDECLARATIVEDEBUGSERVERTCPCONNECTION_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +#include + +class QDeclarativeDebugServer; +class QDeclarativeDebugServerTcpConnectionPrivate; +class QDeclarativeDebugServerTcpConnection : public QObject, public QDeclarativeDebugServerConnection +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QDeclarativeDebugServerTcpConnection) + Q_DISABLE_COPY(QDeclarativeDebugServerTcpConnection) + +public: + QDeclarativeDebugServerTcpConnection(int port, QDeclarativeDebugServer *server); + ~QDeclarativeDebugServerTcpConnection(); + + bool isConnected() const; + void send(const QByteArray &message); + void disconnect(); + + void listen(); + void waitForConnection(); + +private Q_SLOTS: + void readyRead(); + void newConnection(); + +private: + QDeclarativeDebugServerTcpConnectionPrivate *d_ptr; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QDECLARATIVEDEBUGSERVERTCPCONNECTION_H diff --git a/src/declarative/debugger/qpacketprotocol.cpp b/src/declarative/debugger/qpacketprotocol.cpp index c2f7709..ad1e767 100644 --- a/src/declarative/debugger/qpacketprotocol.cpp +++ b/src/declarative/debugger/qpacketprotocol.cpp @@ -452,6 +452,14 @@ bool QPacket::isEmpty() const } /*! + Returns raw packet data. + */ +QByteArray QPacket::data() const +{ + return b; +} + +/*! Clears data in the packet. This is useful for reusing one writable packet. For example \code diff --git a/src/declarative/debugger/qpacketprotocol_p.h b/src/declarative/debugger/qpacketprotocol_p.h index d153833..99fded5 100644 --- a/src/declarative/debugger/qpacketprotocol_p.h +++ b/src/declarative/debugger/qpacketprotocol_p.h @@ -98,6 +98,7 @@ public: void clear(); bool isEmpty() const; + QByteArray data() const; protected: friend class QPacketProtocol; -- cgit v0.12