aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/qmltooling/packetprotocol/packetprotocol.pro11
-rw-r--r--src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp302
-rw-r--r--src/plugins/qmltooling/packetprotocol/qpacketprotocol_p.h (renamed from tools/qmlprofiler/qpacketprotocol.h)75
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.cpp6
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp20
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp14
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.cpp23
-rw-r--r--src/plugins/qmltooling/qmldbg_local/qlocalclientconnection.cpp1
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp8
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp6
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp20
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp27
-rw-r--r--src/plugins/qmltooling/qmldbg_server/qmldbg_server.pro4
-rw-r--r--src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp33
-rw-r--r--src/plugins/qmltooling/qmltooling.pro3
-rw-r--r--src/plugins/qmltooling/shared/qpacketprotocol.cpp531
-rw-r--r--src/qml/debugger/debugger.pri6
-rw-r--r--src/qml/debugger/qpacket.cpp147
-rw-r--r--src/qml/debugger/qpacket_p.h (renamed from src/plugins/qmltooling/shared/qpacketprotocol.h)87
-rw-r--r--src/qml/debugger/qqmldebugservice.cpp26
-rw-r--r--src/qml/debugger/qqmldebugservice_p.h11
-rw-r--r--src/quick/util/qquickprofiler.cpp7
-rw-r--r--sync.profile1
-rw-r--r--tests/auto/qml/debugger/qpacketprotocol/tst_qpacketprotocol.cpp129
-rw-r--r--tests/auto/qml/debugger/shared/debugutil.pri4
-rw-r--r--tests/auto/qml/debugger/shared/qqmldebugclient.cpp8
-rw-r--r--tools/qmlprofiler/qmlprofiler.pro8
-rw-r--r--tools/qmlprofiler/qpacketprotocol.cpp527
-rw-r--r--tools/qmlprofiler/qqmldebugclient.cpp8
29 files changed, 624 insertions, 1429 deletions
diff --git a/src/plugins/qmltooling/packetprotocol/packetprotocol.pro b/src/plugins/qmltooling/packetprotocol/packetprotocol.pro
new file mode 100644
index 0000000000..a6b8f26bb1
--- /dev/null
+++ b/src/plugins/qmltooling/packetprotocol/packetprotocol.pro
@@ -0,0 +1,11 @@
+TARGET = QtPacketProtocol
+QT = core-private qml-private
+CONFIG += static internal_module
+
+HEADERS = \
+ qpacketprotocol_p.h
+
+SOURCES = \
+ qpacketprotocol.cpp
+
+load(qt_module)
diff --git a/src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp b/src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp
new file mode 100644
index 0000000000..9f9dbfee90
--- /dev/null
+++ b/src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp
@@ -0,0 +1,302 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpacketprotocol_p.h"
+
+#include <QtCore/QElapsedTimer>
+#include <private/qiodevice_p.h>
+#include <private/qobject_p.h>
+#include <private/qpacket_p.h>
+
+QT_BEGIN_NAMESPACE
+
+static const int MAX_PACKET_SIZE = 0x7FFFFFFF;
+
+/*!
+ \class QPacketProtocol
+ \internal
+
+ \brief The QPacketProtocol class encapsulates communicating discrete packets
+ across fragmented IO channels, such as TCP sockets.
+
+ QPacketProtocol makes it simple to send arbitrary sized data "packets" across
+ fragmented transports such as TCP and UDP.
+
+ As transmission boundaries are not respected, sending packets over protocols
+ like TCP frequently involves "stitching" them back together at the receiver.
+ QPacketProtocol makes this easier by performing this task for you. Packet
+ data sent using QPacketProtocol is prepended with a 4-byte size header
+ allowing the receiving QPacketProtocol to buffer the packet internally until
+ it has all been received. QPacketProtocol does not perform any sanity
+ checking on the size or on the data, so this class should only be used in
+ prototyping or trusted situations where DOS attacks are unlikely.
+
+ QPacketProtocol does not perform any communications itself. Instead it can
+ operate on any QIODevice that supports the QIODevice::readyRead() signal. A
+ logical "packet" is encapsulated by the companion QPacket class. The
+ following example shows two ways to send data using QPacketProtocol. The
+ transmitted data is equivalent in both.
+
+ \code
+ QTcpSocket socket;
+ // ... connect socket ...
+
+ QPacketProtocol protocol(&socket);
+
+ // Send a packet
+ QPacket packet;
+ packet << "Hello world" << 123;
+ protocol.send(packet);
+ \endcode
+
+ Likewise, the following shows how to read data from QPacketProtocol, assuming
+ that the QPacketProtocol::readyRead() signal has been emitted.
+
+ \code
+ // ... QPacketProtocol::readyRead() is emitted ...
+
+ int a;
+ QByteArray b;
+
+ // Receive packet the quick way
+ protocol.read() >> a >> b;
+
+ // Receive packet the longer way
+ QPacket packet = protocol.read();
+ p >> a >> b;
+ \endcode
+
+ \ingroup io
+ \sa QPacket
+*/
+
+class QPacketProtocolPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QPacketProtocol)
+public:
+ QPacketProtocolPrivate(QIODevice *dev);
+
+ QList<qint64> sendingPackets;
+ QList<QByteArray> packets;
+ QByteArray inProgress;
+ qint32 inProgressSize;
+ bool waitingForPacket;
+ QIODevice *dev;
+};
+
+/*!
+ Construct a QPacketProtocol instance that works on \a dev with the
+ specified \a parent.
+ */
+QPacketProtocol::QPacketProtocol(QIODevice *dev, QObject *parent)
+ : QObject(*(new QPacketProtocolPrivate(dev)), parent)
+{
+ Q_ASSERT(4 == sizeof(qint32));
+ Q_ASSERT(dev);
+
+ QObject::connect(dev, SIGNAL(readyRead()),
+ this, SLOT(readyToRead()));
+ QObject::connect(dev, SIGNAL(aboutToClose()),
+ this, SLOT(aboutToClose()));
+ QObject::connect(dev, SIGNAL(bytesWritten(qint64)),
+ this, SLOT(bytesWritten(qint64)));
+}
+
+/*!
+ \fn void QPacketProtocol::send(const QPacket & packet)
+
+ Transmit the \a packet.
+ */
+void QPacketProtocol::send(const QPacket & p)
+{
+ Q_D(QPacketProtocol);
+
+ QByteArray data = p.data();
+ if (data.isEmpty())
+ return; // We don't send empty packets
+ qint64 sendSize = data.size() + sizeof(qint32);
+
+ d->sendingPackets.append(sendSize);
+ qint32 sendSize32 = sendSize;
+ qint64 writeBytes = d->dev->write((char *)&sendSize32, sizeof(qint32));
+ Q_UNUSED(writeBytes);
+ Q_ASSERT(writeBytes == sizeof(qint32));
+ writeBytes = d->dev->write(data);
+ Q_ASSERT(writeBytes == data.size());
+}
+
+/*!
+ Returns the number of received packets yet to be read.
+ */
+qint64 QPacketProtocol::packetsAvailable() const
+{
+ Q_D(const QPacketProtocol);
+ return d->packets.count();
+}
+
+/*!
+ Return the next unread packet, or an invalid QPacket instance if no packets
+ are available. This method does NOT block.
+ */
+QPacket QPacketProtocol::read()
+{
+ Q_D(QPacketProtocol);
+
+ // Hope for in-place construction here, until we get move semantics for QBuffer
+ return QPacket(d->packets.isEmpty() ? QByteArray() : d->packets.takeFirst());
+}
+
+/*!
+ This function locks until a new packet is available for reading and the
+ \l{QIODevice::}{readyRead()} signal has been emitted. The function
+ will timeout after \a msecs milliseconds; the default timeout is
+ 30000 milliseconds.
+
+ The function returns true if the readyRead() signal is emitted and
+ there is new data available for reading; otherwise it returns false
+ (if an error occurred or the operation timed out).
+ */
+
+bool QPacketProtocol::waitForReadyRead(int msecs)
+{
+ Q_D(QPacketProtocol);
+ if (!d->packets.isEmpty())
+ return true;
+
+ QElapsedTimer stopWatch;
+ stopWatch.start();
+
+ d->waitingForPacket = true;
+ do {
+ if (!d->dev->waitForReadyRead(msecs))
+ return false;
+ if (!d->waitingForPacket)
+ return true;
+ msecs = qt_subtract_from_timeout(msecs, stopWatch.elapsed());
+ } while (true);
+}
+
+/*!
+ Return the QIODevice passed to the QPacketProtocol constructor.
+*/
+void QPacketProtocol::aboutToClose()
+{
+ Q_D(QPacketProtocol);
+ d->inProgress.clear();
+ d->sendingPackets.clear();
+ d->inProgressSize = -1;
+}
+
+void QPacketProtocol::bytesWritten(qint64 bytes)
+{
+ Q_D(QPacketProtocol);
+ Q_ASSERT(!d->sendingPackets.isEmpty());
+
+ while (bytes) {
+ if (d->sendingPackets.at(0) > bytes) {
+ d->sendingPackets[0] -= bytes;
+ bytes = 0;
+ } else {
+ bytes -= d->sendingPackets.at(0);
+ d->sendingPackets.removeFirst();
+ }
+ }
+}
+
+void QPacketProtocol::readyToRead()
+{
+ Q_D(QPacketProtocol);
+ while (true) {
+ // Need to get trailing data
+ if (-1 == d->inProgressSize) {
+ // We need a size header of sizeof(qint32)
+ if (sizeof(qint32) > (uint)d->dev->bytesAvailable())
+ return;
+
+ // Read size header
+ int read = d->dev->read((char *)&d->inProgressSize, sizeof(qint32));
+ Q_ASSERT(read == sizeof(qint32));
+ Q_UNUSED(read);
+
+ // Check sizing constraints
+ if (d->inProgressSize > MAX_PACKET_SIZE) {
+ QObject::disconnect(d->dev, SIGNAL(readyRead()),
+ this, SLOT(readyToRead()));
+ QObject::disconnect(d->dev, SIGNAL(aboutToClose()),
+ this, SLOT(aboutToClose()));
+ QObject::disconnect(d->dev, SIGNAL(bytesWritten(qint64)),
+ this, SLOT(bytesWritten(qint64)));
+ d->dev = 0;
+ emit invalidPacket();
+ return;
+ }
+
+ d->inProgressSize -= sizeof(qint32);
+ } else {
+ d->inProgress.append(d->dev->read(d->inProgressSize - d->inProgress.size()));
+
+ if (d->inProgressSize == d->inProgress.size()) {
+ // Packet has arrived!
+ d->packets.append(d->inProgress);
+ d->inProgressSize = -1;
+ d->inProgress.clear();
+
+ d->waitingForPacket = false;
+ emit readyRead();
+ } else
+ return;
+ }
+ }
+}
+
+QPacketProtocolPrivate::QPacketProtocolPrivate(QIODevice *dev) :
+ inProgressSize(-1), waitingForPacket(false), dev(dev)
+{
+}
+
+/*!
+ \fn void QPacketProtocol::readyRead()
+
+ Emitted whenever a new packet is received. Applications may use
+ QPacketProtocol::read() to retrieve this packet.
+ */
+
+/*!
+ \fn void QPacketProtocol::invalidPacket()
+
+ A packet larger than the maximum allowable packet size was received. The
+ packet will be discarded and, as it indicates corruption in the protocol, no
+ further packets will be received.
+ */
+
+QT_END_NAMESPACE
diff --git a/tools/qmlprofiler/qpacketprotocol.h b/src/plugins/qmltooling/packetprotocol/qpacketprotocol_p.h
index 17608033f4..6ed803809f 100644
--- a/tools/qmlprofiler/qpacketprotocol.h
+++ b/src/plugins/qmltooling/packetprotocol/qpacketprotocol_p.h
@@ -31,79 +31,50 @@
**
****************************************************************************/
-#ifndef QPACKETPROTOCOL_H
-#define QPACKETPROTOCOL_H
+#ifndef QPACKETPROTOCOL_P_H
+#define QPACKETPROTOCOL_P_H
#include <QtCore/qobject.h>
-#include <QtCore/qdatastream.h>
+#include <private/qpacket_p.h>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
QT_BEGIN_NAMESPACE
+
class QIODevice;
-class QBuffer;
-QT_END_NAMESPACE
-class QPacket;
-class QPacketAutoSend;
-class QPacketProtocolPrivate;
+class QPacketProtocolPrivate;
class QPacketProtocol : public QObject
{
Q_OBJECT
+ Q_DECLARE_PRIVATE(QPacketProtocol)
public:
explicit QPacketProtocol(QIODevice *dev, QObject *parent = 0);
- virtual ~QPacketProtocol();
-
- qint32 maximumPacketSize() const;
- qint32 setMaximumPacketSize(qint32);
- QPacketAutoSend send();
void send(const QPacket &);
-
qint64 packetsAvailable() const;
QPacket read();
-
bool waitForReadyRead(int msecs = 3000);
- void clear();
-
- QIODevice *device();
-
Q_SIGNALS:
void readyRead();
void invalidPacket();
- void packetWritten();
-private:
- QPacketProtocolPrivate *d;
+private Q_SLOTS:
+ void aboutToClose();
+ void bytesWritten(qint64 bytes);
+ void readyToRead();
};
+QT_END_NAMESPACE
-class QPacket : public QDataStream
-{
-public:
- QPacket();
- QPacket(const QPacket &);
- virtual ~QPacket();
-
- void clear();
- bool isEmpty() const;
- QByteArray data() const;
-
-protected:
- friend class QPacketProtocol;
- QPacket(const QByteArray &ba);
- QByteArray b;
- QBuffer *buf;
-};
-
-class QPacketAutoSend : public QPacket
-{
-public:
- virtual ~QPacketAutoSend();
-
-private:
- friend class QPacketProtocol;
- QPacketAutoSend(QPacketProtocol *);
- QPacketProtocol *p;
-};
-
-#endif
+#endif // QPACKETPROTOCOL_P_H
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.cpp
index ee1047d2b0..e7b9f24ae7 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qdebugmessageservice.cpp
@@ -33,6 +33,7 @@
#include "qdebugmessageservice.h"
#include <private/qqmldebugconnector_p.h>
+#include <private/qpacket_p.h>
#include <QDataStream>
@@ -63,13 +64,12 @@ void QDebugMessageServiceImpl::sendDebugMessage(QtMsgType type,
//We do not want to alter the message handling mechanism
//We just eavesdrop and forward the messages to a port
//only if a client is connected to it.
- QByteArray message;
- QQmlDebugStream ws(&message, QIODevice::WriteOnly);
+ QPacket ws;
ws << QByteArray("MESSAGE") << type << buf.toUtf8();
ws << QString::fromLatin1(ctxt.file).toUtf8();
ws << ctxt.line << QString::fromLatin1(ctxt.function).toUtf8();
- emit messageToClient(name(), message);
+ emit messageToClient(name(), ws.data());
if (oldMsgHandler)
(*oldMsgHandler)(type, ctxt, buf);
}
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
index 8f53dc6d50..09c352e8ad 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
@@ -45,6 +45,7 @@
#include <private/qqmlvaluetype_p.h>
#include <private/qqmlvmemetaobject_p.h>
#include <private/qqmlexpression_p.h>
+#include <private/qpacket_p.h>
#include <QtCore/qdebug.h>
#include <QtCore/qmetaobject.h>
@@ -440,14 +441,13 @@ QList<QObject*> QQmlEngineDebugServiceImpl::objectForLocationInfo(const QString
void QQmlEngineDebugServiceImpl::processMessage(const QByteArray &message)
{
- QQmlDebugStream ds(message);
+ QPacket ds(message);
QByteArray type;
int queryId;
ds >> type >> queryId;
- QByteArray reply;
- QQmlDebugStream rs(&reply, QIODevice::WriteOnly);
+ QPacket rs;
if (type == "LIST_ENGINES") {
rs << QByteArray("LIST_ENGINES_R");
@@ -617,7 +617,7 @@ void QQmlEngineDebugServiceImpl::processMessage(const QByteArray &message)
rs << QByteArray("SET_METHOD_BODY_R") << queryId << ok;
}
- emit messageToClient(name(), reply);
+ emit messageToClient(name(), rs.data());
}
bool QQmlEngineDebugServiceImpl::setBinding(int objectId,
@@ -769,12 +769,9 @@ bool QQmlEngineDebugServiceImpl::setMethodBody(int objectId, const QString &meth
void QQmlEngineDebugServiceImpl::propertyChanged(int id, int objectId, const QMetaProperty &property, const QVariant &value)
{
- QByteArray reply;
- QQmlDebugStream rs(&reply, QIODevice::WriteOnly);
-
+ QPacket rs;
rs << QByteArray("UPDATE_WATCH") << id << objectId << QByteArray(property.name()) << valueContents(value);
-
- emit messageToClient(name(), reply);
+ emit messageToClient(name(), rs.data());
}
void QQmlEngineDebugServiceImpl::engineAboutToBeAdded(QQmlEngine *engine)
@@ -804,12 +801,11 @@ void QQmlEngineDebugServiceImpl::objectCreated(QQmlEngine *engine, QObject *obje
int objectId = QQmlDebugService::idForObject(object);
int parentId = QQmlDebugService::idForObject(object->parent());
- QByteArray reply;
- QQmlDebugStream rs(&reply, QIODevice::WriteOnly);
+ QPacket rs;
//unique queryId -1
rs << QByteArray("OBJECT_CREATED") << -1 << engineId << objectId << parentId;
- emit messageToClient(name(), reply);
+ emit messageToClient(name(), rs.data());
}
void QQmlEngineDebugServiceImpl::setStatesDelegate(QQmlDebugStatesDelegate *delegate)
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
index bedabd0a63..14333e01f6 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
@@ -36,7 +36,7 @@
#include <private/qv4engine_p.h>
#include <private/qv4function_p.h>
#include <private/qqmldebugconnector_p.h>
-
+#include <private/qpacket_p.h>
#include <private/qv8engine_p.h>
#include <QtCore/QJsonArray>
@@ -674,7 +674,7 @@ void QV4DebugServiceImpl::messageReceived(const QByteArray &message)
{
QMutexLocker lock(&m_configMutex);
- QQmlDebugStream ms(message);
+ QPacket ms(message);
QByteArray header;
ms >> header;
@@ -715,11 +715,10 @@ void QV4DebugServiceImpl::messageReceived(const QByteArray &message)
void QV4DebugServiceImpl::sendSomethingToSomebody(const char *type, int magicNumber)
{
- QByteArray response;
- QQmlDebugStream rs(&response, QIODevice::WriteOnly);
+ QPacket rs;
rs << QByteArray(type)
<< QByteArray::number(int(version())) << QByteArray::number(magicNumber);
- emit messageToClient(name(), packMessage(type, response));
+ emit messageToClient(name(), packMessage(type, rs.data()));
}
void QV4DebugServiceImpl::handleV8Request(const QByteArray &payload)
@@ -739,11 +738,10 @@ void QV4DebugServiceImpl::handleV8Request(const QByteArray &payload)
QByteArray QV4DebugServiceImpl::packMessage(const QByteArray &command, const QByteArray &message)
{
- QByteArray reply;
- QQmlDebugStream rs(&reply, QIODevice::WriteOnly);
+ QPacket rs;
static const QByteArray cmd("V8DEBUG");
rs << cmd << command << message;
- return reply;
+ return rs.data();
}
void QV4DebugServiceImpl::send(QJsonObject v8Payload)
diff --git a/src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.cpp b/src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.cpp
index fa6dca7aca..d1bba54969 100644
--- a/src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.cpp
+++ b/src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.cpp
@@ -40,6 +40,7 @@
#include <QtCore/private/qabstractanimation_p.h>
#include <QtQml/private/qqmldebugconnector_p.h>
#include <QtQml/private/qqmlcontext_p.h>
+#include <QtQml/private/qpacket_p.h>
#include <QtGui/QMouseEvent>
#include <QtGui/QTouchEvent>
@@ -262,18 +263,16 @@ void AbstractViewInspector::onQmlObjectDestroyed(QObject *object)
QPair<int, int> ids = m_hashObjectsTobeDestroyed.take(object);
- QByteArray response;
-
- QQmlDebugStream rs(&response, QIODevice::WriteOnly);
+ QPacket rs;
rs << QByteArray(RESPONSE) << ids.first << true << ids.second;
- emit m_debugService->messageToClient(m_debugService->name(), response);
+ emit m_debugService->messageToClient(m_debugService->name(), rs.data());
}
void AbstractViewInspector::handleMessage(const QByteArray &message)
{
bool success = true;
- QQmlDebugStream ds(message);
+ QPacket ds(message);
QByteArray type;
ds >> type;
@@ -358,16 +357,14 @@ void AbstractViewInspector::handleMessage(const QByteArray &message)
}
- QByteArray response;
- QQmlDebugStream rs(&response, QIODevice::WriteOnly);
+ QPacket rs;
rs << QByteArray(RESPONSE) << requestId << success;
- emit m_debugService->messageToClient(m_debugService->name(), response);
+ emit m_debugService->messageToClient(m_debugService->name(), rs.data());
}
void AbstractViewInspector::sendCurrentObjects(const QList<QObject*> &objects)
{
- QByteArray message;
- QQmlDebugStream ds(&message, QIODevice::WriteOnly);
+ QPacket ds;
ds << QByteArray(EVENT) << m_eventId++ << QByteArray(SELECT);
@@ -377,7 +374,7 @@ void AbstractViewInspector::sendCurrentObjects(const QList<QObject*> &objects)
debugIds << QQmlDebugService::idForObject(object);
ds << debugIds;
- emit m_debugService->messageToClient(m_debugService->name(), message);
+ emit m_debugService->messageToClient(m_debugService->name(), ds.data());
}
void AbstractViewInspector::sendQmlFileReloaded(bool success)
@@ -387,10 +384,10 @@ void AbstractViewInspector::sendQmlFileReloaded(bool success)
QByteArray response;
- QQmlDebugStream rs(&response, QIODevice::WriteOnly);
+ QPacket rs;
rs << QByteArray(RESPONSE) << m_reloadEventId << success;
- emit m_debugService->messageToClient(m_debugService->name(), response);
+ emit m_debugService->messageToClient(m_debugService->name(), rs.data());
}
QString AbstractViewInspector::idStringForObject(QObject *obj) const
diff --git a/src/plugins/qmltooling/qmldbg_local/qlocalclientconnection.cpp b/src/plugins/qmltooling/qmldbg_local/qlocalclientconnection.cpp
index 057bf9523e..478cbf5514 100644
--- a/src/plugins/qmltooling/qmldbg_local/qlocalclientconnection.cpp
+++ b/src/plugins/qmltooling/qmldbg_local/qlocalclientconnection.cpp
@@ -32,7 +32,6 @@
****************************************************************************/
#include "qlocalclientconnectionfactory.h"
-#include "qpacketprotocol.h"
#include "qqmldebugserver.h"
#include <QtCore/qplugin.h>
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp
index 8f697f1571..b4dfa86e56 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp
@@ -33,6 +33,7 @@
#include "qqmlenginecontrolservice.h"
#include <QQmlEngine>
+#include <private/qpacket_p.h>
QT_BEGIN_NAMESPACE
@@ -44,7 +45,7 @@ QQmlEngineControlServiceImpl::QQmlEngineControlServiceImpl(QObject *parent) :
void QQmlEngineControlServiceImpl::messageReceived(const QByteArray &message)
{
QMutexLocker lock(&dataMutex);
- QQmlDebugStream d(message);
+ QPacket d(message);
int command;
int engineId;
d >> command >> engineId;
@@ -106,10 +107,9 @@ void QQmlEngineControlServiceImpl::engineRemoved(QQmlEngine *engine)
void QQmlEngineControlServiceImpl::sendMessage(QQmlEngineControlServiceImpl::MessageType type, QQmlEngine *engine)
{
- QByteArray message;
- QQmlDebugStream d(&message, QIODevice::WriteOnly);
+ QPacket d;
d << type << idForObject(engine);
- emit messageToClient(name(), message);
+ emit messageToClient(name(), d.data());
}
void QQmlEngineControlServiceImpl::stateChanged(State)
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp
index 245900abae..8879cc4037 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp
@@ -33,6 +33,7 @@
#include "qqmlprofileradapter.h"
#include <private/qqmldebugserviceinterfaces_p.h>
+#include <private/qpacket_p.h>
QT_BEGIN_NAMESPACE
@@ -72,7 +73,7 @@ static void qQmlProfilerDataToByteArrays(const QQmlProfilerData *d, QList<QByteA
continue;
//### using QDataStream is relatively expensive
- QQmlDebugStream ds(&data, QIODevice::WriteOnly);
+ QPacket ds;
ds << d->time << decodedMessageType << decodedDetailType;
switch (decodedMessageType) {
@@ -92,8 +93,7 @@ static void qQmlProfilerDataToByteArrays(const QQmlProfilerData *d, QList<QByteA
Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid message type.");
break;
}
- messages << data;
- data.clear();
+ messages << ds.data();
}
}
}
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp
index 65b99ef7ca..2ce5610c7e 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp
@@ -36,6 +36,7 @@
#include "qqmlprofileradapter.h"
#include "qqmlprofilerservicefactory.h"
#include <private/qqmlengine_p.h>
+#include <private/qpacket_p.h>
#include <QtCore/qdatastream.h>
#include <QtCore/qurl.h>
@@ -202,8 +203,7 @@ void QQmlProfilerServiceImpl::startProfiling(QQmlEngine *engine, quint64 feature
{
QMutexLocker lock(&m_configMutex);
- QByteArray message;
- QQmlDebugStream d(&message, QIODevice::WriteOnly);
+ QPacket d;
d << m_timer.nsecsElapsed() << (int)Event << (int)StartTrace;
bool startedAny = false;
@@ -239,7 +239,7 @@ void QQmlProfilerServiceImpl::startProfiling(QQmlEngine *engine, quint64 feature
emit startFlushTimer();
}
- emit messageToClient(name(), message);
+ emit messageToClient(name(), d.data());
}
/*!
@@ -299,10 +299,8 @@ void QQmlProfilerServiceImpl::sendMessages()
{
QList<QByteArray> messages;
- QByteArray data;
-
+ QPacket traceEnd;
if (m_waitingForStop) {
- QQmlDebugStream traceEnd(&data, QIODevice::WriteOnly);
traceEnd << m_timer.nsecsElapsed() << (int)Event << (int)EndTrace;
QSet<QQmlEngine *> seen;
@@ -331,12 +329,11 @@ void QQmlProfilerServiceImpl::sendMessages()
if (m_waitingForStop) {
//indicate completion
- messages << data;
- data.clear();
+ messages << traceEnd.data();
- QQmlDebugStream ds(&data, QIODevice::WriteOnly);
+ QPacket ds;
ds << (qint64)-1 << (int)Complete;
- messages << data;
+ messages << ds.data();
m_waitingForStop = false;
}
@@ -369,8 +366,7 @@ void QQmlProfilerServiceImpl::messageReceived(const QByteArray &message)
{
QMutexLocker lock(&m_configMutex);
- QByteArray rwData = message;
- QQmlDebugStream stream(&rwData, QIODevice::ReadOnly);
+ QPacket stream(message);
int engineId = -1;
quint64 features = std::numeric_limits<quint64>::max();
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp b/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp
index 3498555f65..991ef4b6ba 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp
@@ -34,6 +34,8 @@
#include "qv4profileradapter.h"
#include "qqmlprofilerservice.h"
+#include <private/qpacket_p.h>
+
QT_BEGIN_NAMESPACE
QV4ProfilerAdapter::QV4ProfilerAdapter(QQmlProfilerService *service, QV4::ExecutionEngine *engine) :
@@ -62,13 +64,12 @@ QV4ProfilerAdapter::QV4ProfilerAdapter(QQmlProfilerService *service, QV4::Execut
qint64 QV4ProfilerAdapter::appendMemoryEvents(qint64 until, QList<QByteArray> &messages)
{
- QByteArray message;
while (m_memoryData.length() > m_memoryPos && m_memoryData[m_memoryPos].timestamp <= until) {
- QQmlDebugStream d(&message, QIODevice::WriteOnly);
+ QPacket d;
QV4::Profiling::MemoryAllocationProperties &props = m_memoryData[m_memoryPos];
d << props.timestamp << MemoryAllocation << props.type << props.size;
++m_memoryPos;
- messages.append(message);
+ messages.append(d.data());
}
return m_memoryData.length() == m_memoryPos ? -1 : m_memoryData[m_memoryPos].timestamp;
}
@@ -94,7 +95,6 @@ qint64 QV4ProfilerAdapter::finalizeMessages(qint64 until, QList<QByteArray> &mes
qint64 QV4ProfilerAdapter::sendMessages(qint64 until, QList<QByteArray> &messages)
{
- QByteArray message;
while (true) {
while (!m_stack.isEmpty() &&
(m_functionCallPos == m_functionCallData.length() ||
@@ -103,9 +103,9 @@ qint64 QV4ProfilerAdapter::sendMessages(qint64 until, QList<QByteArray> &message
return finalizeMessages(until, messages, m_stack.top());
appendMemoryEvents(m_stack.top(), messages);
- QQmlDebugStream d(&message, QIODevice::WriteOnly);
+ QPacket d;
d << m_stack.pop() << RangeEnd << Javascript;
- messages.append(message);
+ messages.append(d.data());
}
while (m_functionCallPos != m_functionCallData.length() &&
(m_stack.empty() || m_functionCallData[m_functionCallPos].start < m_stack.top())) {
@@ -116,19 +116,16 @@ qint64 QV4ProfilerAdapter::sendMessages(qint64 until, QList<QByteArray> &message
appendMemoryEvents(props.start, messages);
- QQmlDebugStream d_start(&message, QIODevice::WriteOnly);
+ QPacket d_start;
d_start << props.start << RangeStart << Javascript;
- messages.push_back(message);
- message.clear();
- QQmlDebugStream d_location(&message, QIODevice::WriteOnly);
+ messages.push_back(d_start.data());
+ QPacket d_location;
d_location << props.start << RangeLocation << Javascript << props.file << props.line
<< props.column;
- messages.push_back(message);
- message.clear();
- QQmlDebugStream d_data(&message, QIODevice::WriteOnly);
+ messages.push_back(d_location.data());
+ QPacket d_data;
d_data << props.start << RangeData << Javascript << props.name;
- messages.push_back(message);
- message.clear();
+ messages.push_back(d_data.data());
m_stack.push(props.end);
++m_functionCallPos;
}
diff --git a/src/plugins/qmltooling/qmldbg_server/qmldbg_server.pro b/src/plugins/qmltooling/qmldbg_server/qmldbg_server.pro
index 5e2d0874df..7347a7598f 100644
--- a/src/plugins/qmltooling/qmldbg_server/qmldbg_server.pro
+++ b/src/plugins/qmltooling/qmldbg_server/qmldbg_server.pro
@@ -1,5 +1,5 @@
TARGET = qmldbg_server
-QT = qml-private core-private
+QT = qml-private packetprotocol-private
PLUGIN_TYPE = qmltooling
PLUGIN_CLASS_NAME = QQmlDebugServerFactory
@@ -7,12 +7,10 @@ load(qt_plugin)
SOURCES += \
$$PWD/qqmldebugserver.cpp \
- $$PWD/../shared/qpacketprotocol.cpp
HEADERS += \
$$PWD/qqmldebugserverfactory.h \
$$PWD/../shared/qqmldebugserver.h \
- $$PWD/../shared/qpacketprotocol.h \
$$PWD/../shared/qqmldebugserverconnection.h
INCLUDEPATH += $$PWD \
diff --git a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
index d3a8d1f0d1..bfbeef5856 100644
--- a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
+++ b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
@@ -33,7 +33,6 @@
#include "qqmldebugserver.h"
#include "qqmldebugserverfactory.h"
-#include "qpacketprotocol.h"
#include "qqmldebugserverconnection.h"
#include <private/qqmldebugservice_p.h>
@@ -41,6 +40,8 @@
#include <private/qqmlglobal_p.h>
#include <private/qqmldebugpluginmanager_p.h>
#include <private/qqmldebugserviceinterfaces_p.h>
+#include <private/qpacketprotocol_p.h>
+#include <private/qpacket_p.h>
#include <QtCore/QAtomicInt>
#include <QtCore/QDir>
@@ -48,9 +49,6 @@
#include <QtCore/QStringList>
#include <QtCore/qwaitcondition.h>
-#include <private/qobject_p.h>
-#include <private/qcoreapplication_p.h>
-
QT_BEGIN_NAMESPACE
/*
@@ -431,7 +429,7 @@ void QQmlDebugServerImpl::receiveMessage()
if (!m_protocol)
return;
- QQmlDebugStream in(m_protocol->read().data());
+ QPacket in(m_protocol->read().data());
QString name;
@@ -445,16 +443,17 @@ void QQmlDebugServerImpl::receiveMessage()
//Get the supported QDataStream version
if (!in.atEnd()) {
- in >> QQmlDebugStream::s_dataStreamVersion;
- if (QQmlDebugStream::s_dataStreamVersion > QDataStream().version())
- QQmlDebugStream::s_dataStreamVersion = QDataStream().version();
+ int dataStreamVersion;
+ in >> dataStreamVersion;
+ if (dataStreamVersion > QDataStream().version())
+ dataStreamVersion = QDataStream().version();
+ QPacket::setDataStreamVersion(dataStreamVersion);
}
// Send the hello answer immediately, since it needs to arrive before
// the plugins below start sending messages.
- QByteArray helloAnswer;
- QQmlDebugStream out(&helloAnswer, QIODevice::WriteOnly);
+ QPacket out;
QStringList pluginNames;
QList<float> pluginVersions;
const int count = m_plugins.count();
@@ -467,11 +466,9 @@ void QQmlDebugServerImpl::receiveMessage()
}
out << QString(QStringLiteral("QDeclarativeDebugClient")) << 0 << protocolVersion
- << pluginNames << pluginVersions << QQmlDebugStream::s_dataStreamVersion;
+ << pluginNames << pluginVersions << QPacket::dataStreamVersion();
- QPacket pack;
- pack.writeRawData(helloAnswer.data(), helloAnswer.length());
- m_protocol->send(pack);
+ m_protocol->send(out);
m_connection->flush();
QMutexLocker helloLock(&m_helloMutex);
@@ -653,13 +650,9 @@ bool QQmlDebugServerImpl::canSendMessage(const QString &name)
void QQmlDebugServerImpl::doSendMessage(const QString &name, const QByteArray &message)
{
- QByteArray prefixed;
- QQmlDebugStream out(&prefixed, QIODevice::WriteOnly);
+ QPacket out;
out << name << message;
-
- QPacket pack;
- pack.writeRawData(prefixed.data(), prefixed.length());
- m_protocol->send(pack);
+ m_protocol->send(out);
}
void QQmlDebugServerImpl::sendMessage(const QString &name, const QByteArray &message)
diff --git a/src/plugins/qmltooling/qmltooling.pro b/src/plugins/qmltooling/qmltooling.pro
index e00e75599b..75da89f3e8 100644
--- a/src/plugins/qmltooling/qmltooling.pro
+++ b/src/plugins/qmltooling/qmltooling.pro
@@ -8,7 +8,10 @@ SUBDIRS += \
# Services
SUBDIRS += \
+ packetprotocol \
qmldbg_debugger \
qmldbg_profiler
+qmldbg_server.depends = packetprotocol
+
qtHaveModule(quick): SUBDIRS += qmldbg_inspector
diff --git a/src/plugins/qmltooling/shared/qpacketprotocol.cpp b/src/plugins/qmltooling/shared/qpacketprotocol.cpp
deleted file mode 100644
index 9a58f803c1..0000000000
--- a/src/plugins/qmltooling/shared/qpacketprotocol.cpp
+++ /dev/null
@@ -1,531 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qpacketprotocol.h"
-
-#include <QtCore/QBuffer>
-#include <QtCore/QElapsedTimer>
-#include <private/qiodevice_p.h>
-
-QT_BEGIN_NAMESPACE
-
-static const unsigned int MAX_PACKET_SIZE = 0x7FFFFFFF;
-
-/*!
- \class QPacketProtocol
- \internal
-
- \brief The QPacketProtocol class encapsulates communicating discrete packets
- across fragmented IO channels, such as TCP sockets.
-
- QPacketProtocol makes it simple to send arbitrary sized data "packets" across
- fragmented transports such as TCP and UDP.
-
- As transmission boundaries are not respected, sending packets over protocols
- like TCP frequently involves "stitching" them back together at the receiver.
- QPacketProtocol makes this easier by performing this task for you. Packet
- data sent using QPacketProtocol is prepended with a 4-byte size header
- allowing the receiving QPacketProtocol to buffer the packet internally until
- it has all been received. QPacketProtocol does not perform any sanity
- checking on the size or on the data, so this class should only be used in
- prototyping or trusted situations where DOS attacks are unlikely.
-
- QPacketProtocol does not perform any communications itself. Instead it can
- operate on any QIODevice that supports the QIODevice::readyRead() signal. A
- logical "packet" is encapsulated by the companion QPacket class. The
- following example shows two ways to send data using QPacketProtocol. The
- transmitted data is equivalent in both.
-
- \code
- QTcpSocket socket;
- // ... connect socket ...
-
- QPacketProtocol protocol(&socket);
-
- // Send packet the quick way
- protocol.send() << "Hello world" << 123;
-
- // Send packet the longer way
- QPacket packet;
- packet << "Hello world" << 123;
- protocol.send(packet);
- \endcode
-
- Likewise, the following shows how to read data from QPacketProtocol, assuming
- that the QPacketProtocol::readyRead() signal has been emitted.
-
- \code
- // ... QPacketProtocol::readyRead() is emitted ...
-
- int a;
- QByteArray b;
-
- // Receive packet the quick way
- protocol.read() >> a >> b;
-
- // Receive packet the longer way
- QPacket packet = protocol.read();
- p >> a >> b;
- \endcode
-
- \ingroup io
- \sa QPacket
-*/
-
-class QPacketProtocolPrivate : public QObject
-{
- Q_OBJECT
-public:
- QPacketProtocolPrivate(QPacketProtocol *parent, QIODevice *_dev)
- : QObject(parent), inProgressSize(-1), maxPacketSize(MAX_PACKET_SIZE),
- waitingForPacket(false), dev(_dev)
- {
- Q_ASSERT(4 == sizeof(qint32));
-
- QObject::connect(this, SIGNAL(readyRead()),
- parent, SIGNAL(readyRead()));
- QObject::connect(this, SIGNAL(packetWritten()),
- parent, SIGNAL(packetWritten()));
- QObject::connect(this, SIGNAL(invalidPacket()),
- parent, SIGNAL(invalidPacket()));
- QObject::connect(dev, SIGNAL(readyRead()),
- this, SLOT(readyToRead()));
- QObject::connect(dev, SIGNAL(aboutToClose()),
- this, SLOT(aboutToClose()));
- QObject::connect(dev, SIGNAL(bytesWritten(qint64)),
- this, SLOT(bytesWritten(qint64)));
- }
-
-Q_SIGNALS:
- void readyRead();
- void packetWritten();
- void invalidPacket();
-
-public Q_SLOTS:
- void aboutToClose()
- {
- inProgress.clear();
- sendingPackets.clear();
- inProgressSize = -1;
- }
-
- void bytesWritten(qint64 bytes)
- {
- Q_ASSERT(!sendingPackets.isEmpty());
-
- while (bytes) {
- if (sendingPackets.at(0) > bytes) {
- sendingPackets[0] -= bytes;
- bytes = 0;
- } else {
- bytes -= sendingPackets.at(0);
- sendingPackets.removeFirst();
- emit packetWritten();
- }
- }
- }
-
- void readyToRead()
- {
- while (true) {
- // Need to get trailing data
- if (-1 == inProgressSize) {
- // We need a size header of sizeof(qint32)
- if (sizeof(qint32) > (uint)dev->bytesAvailable())
- return;
-
- // Read size header
- int read = dev->read((char *)&inProgressSize, sizeof(qint32));
- Q_ASSERT(read == sizeof(qint32));
- Q_UNUSED(read);
-
- // Check sizing constraints
- if (inProgressSize > maxPacketSize) {
- QObject::disconnect(dev, SIGNAL(readyRead()),
- this, SLOT(readyToRead()));
- QObject::disconnect(dev, SIGNAL(aboutToClose()),
- this, SLOT(aboutToClose()));
- QObject::disconnect(dev, SIGNAL(bytesWritten(qint64)),
- this, SLOT(bytesWritten(qint64)));
- dev = 0;
- emit invalidPacket();
- return;
- }
-
- inProgressSize -= sizeof(qint32);
- } else {
- inProgress.append(dev->read(inProgressSize - inProgress.size()));
-
- if (inProgressSize == inProgress.size()) {
- // Packet has arrived!
- packets.append(inProgress);
- inProgressSize = -1;
- inProgress.clear();
-
- waitingForPacket = false;
- emit readyRead();
- } else
- return;
- }
- }
- }
-
-public:
- QList<qint64> sendingPackets;
- QList<QByteArray> packets;
- QByteArray inProgress;
- qint32 inProgressSize;
- qint32 maxPacketSize;
- bool waitingForPacket;
- QIODevice *dev;
-};
-
-/*!
- Construct a QPacketProtocol instance that works on \a dev with the
- specified \a parent.
- */
-QPacketProtocol::QPacketProtocol(QIODevice *dev, QObject *parent)
- : QObject(parent), d(new QPacketProtocolPrivate(this, dev))
-{
- Q_ASSERT(dev);
-}
-
-/*!
- Destroys the QPacketProtocol instance.
- */
-QPacketProtocol::~QPacketProtocol()
-{
-}
-
-/*!
- Returns the maximum packet size allowed. By default this is
- 2,147,483,647 bytes.
-
- If a packet claiming to be larger than the maximum packet size is received,
- the QPacketProtocol::invalidPacket() signal is emitted.
-
- \sa QPacketProtocol::setMaximumPacketSize()
- */
-qint32 QPacketProtocol::maximumPacketSize() const
-{
- return d->maxPacketSize;
-}
-
-/*!
- Sets the maximum allowable packet size to \a max.
-
- \sa QPacketProtocol::maximumPacketSize()
- */
-qint32 QPacketProtocol::setMaximumPacketSize(qint32 max)
-{
- if (max > (signed)sizeof(qint32))
- d->maxPacketSize = max;
- return d->maxPacketSize;
-}
-
-/*!
- Returns a streamable object that is transmitted on destruction. For example
-
- \code
- protocol.send() << "Hello world" << 123;
- \endcode
-
- will send a packet containing "Hello world" and 123. To construct more
- complex packets, explicitly construct a QPacket instance.
- */
-QPacketAutoSend QPacketProtocol::send()
-{
- return QPacketAutoSend(this);
-}
-
-/*!
- \fn void QPacketProtocol::send(const QPacket & packet)
-
- Transmit the \a packet.
- */
-void QPacketProtocol::send(const QPacket & p)
-{
- if (p.b.isEmpty())
- return; // We don't send empty packets
-
- qint64 sendSize = p.b.size() + sizeof(qint32);
-
- d->sendingPackets.append(sendSize);
- qint32 sendSize32 = sendSize;
- qint64 writeBytes = d->dev->write((char *)&sendSize32, sizeof(qint32));
- Q_UNUSED(writeBytes);
- Q_ASSERT(writeBytes == sizeof(qint32));
- writeBytes = d->dev->write(p.b);
- Q_ASSERT(writeBytes == p.b.size());
-}
-
-/*!
- Returns the number of received packets yet to be read.
- */
-qint64 QPacketProtocol::packetsAvailable() const
-{
- return d->packets.count();
-}
-
-/*!
- Discard any unread packets.
- */
-void QPacketProtocol::clear()
-{
- d->packets.clear();
-}
-
-/*!
- Return the next unread packet, or an invalid QPacket instance if no packets
- are available. This method does NOT block.
- */
-QPacket QPacketProtocol::read()
-{
- if (0 == d->packets.count())
- return QPacket();
-
- QPacket rv(d->packets.at(0));
- d->packets.removeFirst();
- return rv;
-}
-
-/*!
- This function locks until a new packet is available for reading and the
- \l{QIODevice::}{readyRead()} signal has been emitted. The function
- will timeout after \a msecs milliseconds; the default timeout is
- 30000 milliseconds.
-
- The function returns true if the readyRead() signal is emitted and
- there is new data available for reading; otherwise it returns false
- (if an error occurred or the operation timed out).
- */
-
-bool QPacketProtocol::waitForReadyRead(int msecs)
-{
- if (!d->packets.isEmpty())
- return true;
-
- QElapsedTimer stopWatch;
- stopWatch.start();
-
- d->waitingForPacket = true;
- do {
- if (!d->dev->waitForReadyRead(msecs))
- return false;
- if (!d->waitingForPacket)
- return true;
- msecs = qt_subtract_from_timeout(msecs, stopWatch.elapsed());
- } while (true);
-}
-
-/*!
- Return the QIODevice passed to the QPacketProtocol constructor.
-*/
-QIODevice *QPacketProtocol::device()
-{
- return d->dev;
-}
-
-/*!
- \fn void QPacketProtocol::readyRead()
-
- Emitted whenever a new packet is received. Applications may use
- QPacketProtocol::read() to retrieve this packet.
- */
-
-/*!
- \fn void QPacketProtocol::invalidPacket()
-
- A packet larger than the maximum allowable packet size was received. The
- packet will be discarded and, as it indicates corruption in the protocol, no
- further packets will be received.
- */
-
-/*!
- \fn void QPacketProtocol::packetWritten()
-
- Emitted each time a packet is completing written to the device. This signal
- may be used for communications flow control.
- */
-
-/*!
- \class QPacket
- \internal
-
- \brief The QPacket class encapsulates an unfragmentable packet of data to be
- transmitted by QPacketProtocol.
-
- The QPacket class works together with QPacketProtocol to make it simple to
- send arbitrary sized data "packets" across fragmented transports such as TCP
- and UDP.
-
- QPacket provides a QDataStream interface to an unfragmentable packet.
- Applications should construct a QPacket, propagate it with data and then
- transmit it over a QPacketProtocol instance. For example:
- \code
- QPacketProtocol protocol(...);
-
- QPacket myPacket;
- myPacket << "Hello world!" << 123;
- protocol.send(myPacket);
- \endcode
-
- As long as both ends of the connection are using the QPacketProtocol class,
- the data within this packet will be delivered unfragmented at the other end,
- ready for extraction.
-
- \code
- QByteArray greeting;
- int count;
-
- QPacket myPacket = protocol.read();
-
- myPacket >> greeting >> count;
- \endcode
-
- Only packets returned from QPacketProtocol::read() may be read from. QPacket
- instances constructed by directly by applications are for transmission only
- and are considered "write only". Attempting to read data from them will
- result in undefined behavior.
-
- \ingroup io
- \sa QPacketProtocol
- */
-
-/*!
- Constructs an empty write-only packet.
- */
-QPacket::QPacket()
- : QDataStream(), buf(0)
-{
- buf = new QBuffer(&b);
- buf->open(QIODevice::WriteOnly);
- setDevice(buf);
- setVersion(QDataStream::Qt_4_7);
-}
-
-/*!
- Destroys the QPacket instance.
- */
-QPacket::~QPacket()
-{
- if (buf) {
- delete buf;
- buf = 0;
- }
-}
-
-/*!
- Creates a copy of \a other. The initial stream positions are shared, but the
- two packets are otherwise independent.
- */
-QPacket::QPacket(const QPacket & other)
- : QDataStream(), b(other.b), buf(0)
-{
- buf = new QBuffer(&b);
- buf->open(other.buf->openMode());
- setDevice(buf);
-}
-
-/*!
- \internal
- */
-QPacket::QPacket(const QByteArray & ba)
- : QDataStream(), b(ba), buf(0)
-{
- buf = new QBuffer(&b);
- buf->open(QIODevice::ReadOnly);
- setDevice(buf);
-}
-
-/*!
- Returns true if this packet is empty - that is, contains no data.
- */
-bool QPacket::isEmpty() const
-{
- return b.isEmpty();
-}
-
-/*!
- 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
- QPacketProtocol protocol(...);
-
- QPacket packet;
-
- packet << "Hello world!" << 123;
- protocol.send(packet);
-
- packet.clear();
- packet << "Goodbyte world!" << 789;
- protocol.send(packet);
- \endcode
- */
-void QPacket::clear()
-{
- QBuffer::OpenMode oldMode = buf->openMode();
- buf->close();
- b.clear();
- buf->setBuffer(&b); // reset QBuffer internals with new size of b.
- buf->open(oldMode);
-}
-
-/*!
- \class QPacketAutoSend
- \internal
-
- \internal
- */
-QPacketAutoSend::QPacketAutoSend(QPacketProtocol *_p)
- : QPacket(), p(_p)
-{
-}
-
-QPacketAutoSend::~QPacketAutoSend()
-{
- if (!b.isEmpty())
- p->send(*this);
-}
-
-QT_END_NAMESPACE
-
-#include <qpacketprotocol.moc>
diff --git a/src/qml/debugger/debugger.pri b/src/qml/debugger/debugger.pri
index 30a44eedd1..62b375f72f 100644
--- a/src/qml/debugger/debugger.pri
+++ b/src/qml/debugger/debugger.pri
@@ -6,7 +6,8 @@ SOURCES += \
$$PWD/qqmldebugservice.cpp \
$$PWD/qqmldebugserviceinterfaces.cpp \
$$PWD/qqmlabstractprofileradapter.cpp \
- $$PWD/qqmlprofiler.cpp
+ $$PWD/qqmlprofiler.cpp \
+ $$PWD/qpacket.cpp
HEADERS += \
$$PWD/qqmldebugconnector_p.h \
@@ -18,6 +19,7 @@ HEADERS += \
$$PWD/qqmldebug.h \
$$PWD/qqmlprofilerdefinitions_p.h \
$$PWD/qqmlabstractprofileradapter_p.h \
- $$PWD/qqmlprofiler_p.h
+ $$PWD/qqmlprofiler_p.h \
+ $$PWD/qpacket_p.h
INCLUDEPATH += $$PWD
diff --git a/src/qml/debugger/qpacket.cpp b/src/qml/debugger/qpacket.cpp
new file mode 100644
index 0000000000..30f2191689
--- /dev/null
+++ b/src/qml/debugger/qpacket.cpp
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpacket_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QPacket
+ \internal
+
+ \brief The QPacket class encapsulates an unfragmentable packet of data to be
+ transmitted by QPacketProtocol.
+
+ The QPacket class works together with QPacketProtocol to make it simple to
+ send arbitrary sized data "packets" across fragmented transports such as TCP
+ and UDP.
+
+ QPacket provides a QDataStream interface to an unfragmentable packet.
+ Applications should construct a QPacket, propagate it with data and then
+ transmit it over a QPacketProtocol instance. For example:
+ \code
+ QPacketProtocol protocol(...);
+
+ QPacket myPacket;
+ myPacket << "Hello world!" << 123;
+ protocol.send(myPacket);
+ \endcode
+
+ As long as both ends of the connection are using the QPacketProtocol class,
+ the data within this packet will be delivered unfragmented at the other end,
+ ready for extraction.
+
+ \code
+ QByteArray greeting;
+ int count;
+
+ QPacket myPacket = protocol.read();
+
+ myPacket >> greeting >> count;
+ \endcode
+
+ Only packets constructed from raw byte arrays may be read from. Empty QPacket
+ instances are for transmission only and are considered "write only". Attempting
+ to read data from them will result in undefined behavior.
+
+ \ingroup io
+ \sa QPacketProtocol
+ */
+
+int QPacket::s_dataStreamVersion = QDataStream::Qt_4_7;
+
+void QPacket::setDataStreamVersion(int dataStreamVersion)
+{
+ s_dataStreamVersion = dataStreamVersion;
+}
+
+int QPacket::dataStreamVersion()
+{
+ return s_dataStreamVersion;
+}
+
+/*!
+ Constructs an empty write-only packet.
+ */
+QPacket::QPacket()
+{
+ init(QIODevice::WriteOnly);
+}
+
+/*!
+ Creates a copy of \a other. The initial stream positions are shared, but the
+ two packets are otherwise independent.
+ */
+QPacket::QPacket(const QPacket &other) : QDataStream()
+{
+ assign(other);
+}
+
+QPacket &QPacket::operator=(const QPacket &other)
+{
+ if (this != &other) {
+ buf.close();
+ assign(other);
+ }
+ return *this;
+}
+
+QPacket::QPacket(const QByteArray &data)
+{
+ buf.setData(data);
+ init(QIODevice::ReadOnly);
+}
+
+/*!
+ Returns raw packet data.
+ */
+QByteArray QPacket::data() const
+{
+ return buf.data();
+}
+
+void QPacket::init(QIODevice::OpenMode mode)
+{
+ buf.open(mode);
+ setDevice(&buf);
+ setVersion(s_dataStreamVersion);
+}
+
+void QPacket::assign(const QPacket &other)
+{
+ buf.setData(other.buf.data());
+ init(other.buf.openMode());
+ buf.seek(other.buf.pos());
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/shared/qpacketprotocol.h b/src/qml/debugger/qpacket_p.h
index c571e8d2b8..759ed25145 100644
--- a/src/plugins/qmltooling/shared/qpacketprotocol.h
+++ b/src/qml/debugger/qpacket_p.h
@@ -31,81 +31,46 @@
**
****************************************************************************/
-#ifndef QPACKETPROTOCOL_H
-#define QPACKETPROTOCOL_H
+#ifndef QPACKET_P_H
+#define QPACKET_P_H
-#include <QtCore/qobject.h>
#include <QtCore/qdatastream.h>
+#include <QtCore/qbuffer.h>
+#include <QtQml/private/qtqmlglobal_p.h>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
QT_BEGIN_NAMESPACE
-class QIODevice;
-class QBuffer;
-class QPacket;
-class QPacketAutoSend;
-class QPacketProtocolPrivate;
-
-class QPacketProtocol : public QObject
-{
- Q_OBJECT
-public:
- explicit QPacketProtocol(QIODevice *dev, QObject *parent = 0);
- virtual ~QPacketProtocol();
-
- qint32 maximumPacketSize() const;
- qint32 setMaximumPacketSize(qint32);
-
- QPacketAutoSend send();
- void send(const QPacket &);
-
- qint64 packetsAvailable() const;
- QPacket read();
-
- bool waitForReadyRead(int msecs = 3000);
-
- void clear();
-
- QIODevice *device();
-
-Q_SIGNALS:
- void readyRead();
- void invalidPacket();
- void packetWritten();
-
-private:
- QPacketProtocolPrivate *d;
-};
-
-
-class QPacket : public QDataStream
+class Q_QML_PRIVATE_EXPORT QPacket : public QDataStream
{
public:
QPacket();
- QPacket(const QPacket &);
- virtual ~QPacket();
+ QPacket(const QPacket &other);
+ explicit QPacket(const QByteArray &ba);
+ QPacket &operator=(const QPacket &other);
- void clear();
- bool isEmpty() const;
QByteArray data() const;
-protected:
- friend class QPacketProtocol;
- QPacket(const QByteArray &ba);
- QByteArray b;
- QBuffer *buf;
-};
-
-class QPacketAutoSend : public QPacket
-{
-public:
- virtual ~QPacketAutoSend();
+ static int dataStreamVersion();
+ static void setDataStreamVersion(int dataStreamVersion);
private:
- friend class QPacketProtocol;
- QPacketAutoSend(QPacketProtocol *);
- QPacketProtocol *p;
+ static int s_dataStreamVersion;
+ void init(QIODevice::OpenMode mode);
+ void assign(const QPacket &other);
+ QBuffer buf;
};
QT_END_NAMESPACE
-#endif
+#endif // QPACKET_P_H
diff --git a/src/qml/debugger/qqmldebugservice.cpp b/src/qml/debugger/qqmldebugservice.cpp
index 0b07f320ec..bbcf67a54b 100644
--- a/src/qml/debugger/qqmldebugservice.cpp
+++ b/src/qml/debugger/qqmldebugservice.cpp
@@ -200,32 +200,6 @@ void QQmlDebugService::engineRemoved(QQmlEngine *)
{
}
-int QQmlDebugStream::s_dataStreamVersion = QDataStream::Qt_4_7;
-
-QQmlDebugStream::QQmlDebugStream()
- : QDataStream()
-{
- setVersion(s_dataStreamVersion);
-}
-
-QQmlDebugStream::QQmlDebugStream(QIODevice *d)
- : QDataStream(d)
-{
- setVersion(s_dataStreamVersion);
-}
-
-QQmlDebugStream::QQmlDebugStream(QByteArray *ba, QIODevice::OpenMode flags)
- : QDataStream(ba, flags)
-{
- setVersion(s_dataStreamVersion);
-}
-
-QQmlDebugStream::QQmlDebugStream(const QByteArray &ba)
- : QDataStream(ba)
-{
- setVersion(s_dataStreamVersion);
-}
-
QT_END_NAMESPACE
#include "qqmldebugservice.moc"
diff --git a/src/qml/debugger/qqmldebugservice_p.h b/src/qml/debugger/qqmldebugservice_p.h
index 3d692133cc..8b58f57349 100644
--- a/src/qml/debugger/qqmldebugservice_p.h
+++ b/src/qml/debugger/qqmldebugservice_p.h
@@ -96,17 +96,6 @@ signals:
void messagesToClient(const QString &name, const QList<QByteArray> &messages);
};
-class Q_QML_PRIVATE_EXPORT QQmlDebugStream : public QDataStream
-{
-public:
- static int s_dataStreamVersion;
-
- QQmlDebugStream();
- explicit QQmlDebugStream(QIODevice *d);
- QQmlDebugStream(QByteArray *ba, QIODevice::OpenMode flags);
- QQmlDebugStream(const QByteArray &ba);
-};
-
QT_END_NAMESPACE
#endif // QQMLDEBUGSERVICE_H
diff --git a/src/quick/util/qquickprofiler.cpp b/src/quick/util/qquickprofiler.cpp
index 77ffda474a..44fdbc5da8 100644
--- a/src/quick/util/qquickprofiler.cpp
+++ b/src/quick/util/qquickprofiler.cpp
@@ -34,6 +34,7 @@
#include "qquickprofiler_p.h"
#include <QCoreApplication>
#include <private/qqmldebugserviceinterfaces_p.h>
+#include <private/qpacket_p.h>
QT_BEGIN_NAMESPACE
@@ -46,7 +47,6 @@ quint64 QQuickProfiler::featuresEnabled = 0;
// (see tst_qqmldebugtrace::trace() benchmark)
void QQuickProfilerData::toByteArrays(QList<QByteArray> &messages) const
{
- QByteArray data;
Q_ASSERT_X(((messageType | detailType) & (1 << 31)) == 0, Q_FUNC_INFO, "You can use at most 31 message types and 31 detail types.");
for (uint decodedMessageType = 0; (messageType >> decodedMessageType) != 0; ++decodedMessageType) {
if ((messageType & (1 << decodedMessageType)) == 0)
@@ -57,7 +57,7 @@ void QQuickProfilerData::toByteArrays(QList<QByteArray> &messages) const
continue;
//### using QDataStream is relatively expensive
- QQmlDebugStream ds(&data, QIODevice::WriteOnly);
+ QPacket ds;
ds << time << decodedMessageType << decodedDetailType;
switch (decodedMessageType) {
@@ -103,8 +103,7 @@ void QQuickProfilerData::toByteArrays(QList<QByteArray> &messages) const
Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid message type.");
break;
}
- messages << data;
- data.clear();
+ messages << ds.data();
}
}
}
diff --git a/sync.profile b/sync.profile
index 28d0698da9..6695d98f27 100644
--- a/sync.profile
+++ b/sync.profile
@@ -5,6 +5,7 @@
"QtQuickParticles" => "$basedir/src/particles",
"QtQuickTest" => "$basedir/src/qmltest",
"QtQmlDevTools" => "$basedir/src/qmldevtools",
+ "QtPacketProtocol" => "$basedir/src/plugins/qmltooling/packetprotocol",
);
%moduleheaders = ( # restrict the module headers to those found in relative path
"QtQmlDevTools" => "../qml/parser;../qml/jsruntime;../qml/qml/ftw;../qml/compiler;../qml/memory;.",
diff --git a/tests/auto/qml/debugger/qpacketprotocol/tst_qpacketprotocol.cpp b/tests/auto/qml/debugger/qpacketprotocol/tst_qpacketprotocol.cpp
index db9e621d54..816ac3f278 100644
--- a/tests/auto/qml/debugger/qpacketprotocol/tst_qpacketprotocol.cpp
+++ b/tests/auto/qml/debugger/qpacketprotocol/tst_qpacketprotocol.cpp
@@ -38,7 +38,8 @@
#include <QDebug>
#include <QBuffer>
-#include "../../../../../src/plugins/qmltooling/shared/qpacketprotocol.h"
+#include <private/qpacketprotocol_p.h>
+#include <private/qpacket_p.h>
#include "debugutil_p.h"
@@ -55,18 +56,10 @@ private slots:
void init();
void cleanup();
- void maximumPacketSize();
- void setMaximumPacketSize();
- void setMaximumPacketSize_data();
void send();
- void send_data();
void packetsAvailable();
void packetsAvailable_data();
- void clear();
void read();
- void device();
-
- void tst_QPacket_clear();
};
void tst_QPacketProtocol::init()
@@ -95,48 +88,17 @@ void tst_QPacketProtocol::cleanup()
delete m_server;
}
-void tst_QPacketProtocol::maximumPacketSize()
-{
- QPacketProtocol p(m_client);
- QCOMPARE(p.maximumPacketSize(), 0x7FFFFFFF);
-}
-
-void tst_QPacketProtocol::setMaximumPacketSize()
-{
- QFETCH(qint32, size);
- QFETCH(qint32, expected);
-
- QPacketProtocol out(m_serverConn);
- QCOMPARE(out.setMaximumPacketSize(size), expected);
-}
-
-void tst_QPacketProtocol::setMaximumPacketSize_data()
-{
- QTest::addColumn<int>("size");
- QTest::addColumn<int>("expected");
-
- QTest::newRow("invalid") << qint32(sizeof(qint32) - 1) << qint32(0x7FFFFFFF);
- QTest::newRow("still invalid") << qint32(sizeof(qint32)) << qint32(0x7FFFFFFF);
- QTest::newRow("valid") << qint32(sizeof(qint32) + 1) << qint32(sizeof(qint32) + 1);
-}
-
void tst_QPacketProtocol::send()
{
- QFETCH(bool, useAutoSend);
-
QPacketProtocol in(m_client);
QPacketProtocol out(m_serverConn);
QByteArray ba;
int num;
- if (useAutoSend) {
- out.send() << "Hello world" << 123;
- } else {
- QPacket packet;
- packet << "Hello world" << 123;
- out.send(packet);
- }
+ QPacket packet;
+ packet << "Hello world" << 123;
+ out.send(packet);
QVERIFY(QQmlDebugTest::waitForSignal(&in, SIGNAL(readyRead())));
@@ -146,14 +108,6 @@ void tst_QPacketProtocol::send()
QCOMPARE(num, 123);
}
-void tst_QPacketProtocol::send_data()
-{
- QTest::addColumn<bool>("useAutoSend");
-
- QTest::newRow("auto send") << true;
- QTest::newRow("no auto send") << false;
-}
-
void tst_QPacketProtocol::packetsAvailable()
{
QFETCH(int, packetCount);
@@ -164,8 +118,11 @@ void tst_QPacketProtocol::packetsAvailable()
QCOMPARE(out.packetsAvailable(), qint64(0));
QCOMPARE(in.packetsAvailable(), qint64(0));
- for (int i=0; i<packetCount; i++)
- out.send() << "Hello";
+ for (int i=0; i<packetCount; i++) {
+ QPacket packet;
+ packet << "Hello";
+ out.send(packet);
+ }
QVERIFY(QQmlDebugTest::waitForSignal(&in, SIGNAL(readyRead())));
QCOMPARE(in.packetsAvailable(), qint64(packetCount));
@@ -180,79 +137,35 @@ void tst_QPacketProtocol::packetsAvailable_data()
QTest::newRow("10") << 10;
}
-void tst_QPacketProtocol::clear()
-{
- QPacketProtocol in(m_client);
- QPacketProtocol out(m_serverConn);
-
- out.send() << 123;
- out.send() << 456;
- QVERIFY(QQmlDebugTest::waitForSignal(&in, SIGNAL(readyRead())));
-
- in.clear();
- QVERIFY(in.read().isEmpty());
-}
-
void tst_QPacketProtocol::read()
{
QPacketProtocol in(m_client);
QPacketProtocol out(m_serverConn);
- QVERIFY(in.read().isEmpty());
+ QVERIFY(in.read().atEnd());
+
+ QPacket packet;
+ packet << 123;
+ out.send(packet);
- out.send() << 123;
- out.send() << 456;
+ QPacket packet2;
+ packet2 << 456;
+ out.send(packet2);
QVERIFY(QQmlDebugTest::waitForSignal(&in, SIGNAL(readyRead())));
int num;
QPacket p1 = in.read();
- QVERIFY(!p1.isEmpty());
+ QVERIFY(!p1.atEnd());
p1 >> num;
QCOMPARE(num, 123);
QPacket p2 = in.read();
- QVERIFY(!p2.isEmpty());
+ QVERIFY(!p2.atEnd());
p2 >> num;
QCOMPARE(num, 456);
- QVERIFY(in.read().isEmpty());
-}
-
-void tst_QPacketProtocol::device()
-{
- QPacketProtocol p(m_client);
- QCOMPARE(p.device(), m_client);
-}
-
-void tst_QPacketProtocol::tst_QPacket_clear()
-{
- QPacketProtocol protocol(m_client);
-
- QPacket packet;
-
- packet << "Hello world!" << 123;
- protocol.send(packet);
-
- packet.clear();
- QVERIFY(packet.isEmpty());
- packet << "Goodbyte world!" << 789;
- protocol.send(packet);
-
- QByteArray ba;
- int num;
- QPacketProtocol in(m_serverConn);
- QVERIFY(QQmlDebugTest::waitForSignal(&in, SIGNAL(readyRead())));
-
- QPacket p1 = in.read();
- p1 >> ba >> num;
- QCOMPARE(ba, QByteArray("Hello world!") + '\0');
- QCOMPARE(num, 123);
-
- QPacket p2 = in.read();
- p2 >> ba >> num;
- QCOMPARE(ba, QByteArray("Goodbyte world!") + '\0');
- QCOMPARE(num, 789);
+ QVERIFY(in.read().atEnd());
}
QTEST_MAIN(tst_QPacketProtocol)
diff --git a/tests/auto/qml/debugger/shared/debugutil.pri b/tests/auto/qml/debugger/shared/debugutil.pri
index cb9c761395..73ed647061 100644
--- a/tests/auto/qml/debugger/shared/debugutil.pri
+++ b/tests/auto/qml/debugger/shared/debugutil.pri
@@ -1,8 +1,8 @@
+QT += packetprotocol-private
+
HEADERS += $$PWD/debugutil_p.h \
$$PWD/qqmldebugclient.h \
- $$PWD/../../../../../src/plugins/qmltooling/shared/qpacketprotocol.h
SOURCES += $$PWD/debugutil.cpp \
$$PWD/qqmldebugclient.cpp \
- $$PWD/../../../../../src/plugins/qmltooling/shared/qpacketprotocol.cpp
diff --git a/tests/auto/qml/debugger/shared/qqmldebugclient.cpp b/tests/auto/qml/debugger/shared/qqmldebugclient.cpp
index f350614a47..00de8f9f7e 100644
--- a/tests/auto/qml/debugger/shared/qqmldebugclient.cpp
+++ b/tests/auto/qml/debugger/shared/qqmldebugclient.cpp
@@ -32,7 +32,9 @@
****************************************************************************/
#include "qqmldebugclient.h"
-#include "../../../../../src/plugins/qmltooling/shared/qpacketprotocol.h"
+
+#include <private/qpacketprotocol_p.h>
+#include <private/qpacket_p.h>
#include <QtCore/qdebug.h>
#include <QtCore/qeventloop.h>
@@ -138,7 +140,7 @@ void QQmlDebugConnectionPrivate::readyRead()
QStringList pluginNames;
QList<float> pluginVersions;
pack >> pluginNames;
- if (!pack.isEmpty())
+ if (!pack.atEnd())
pack >> pluginVersions;
const int pluginNamesSize = pluginNames.size();
@@ -192,7 +194,7 @@ void QQmlDebugConnectionPrivate::readyRead()
QStringList pluginNames;
QList<float> pluginVersions;
pack >> pluginNames;
- if (!pack.isEmpty())
+ if (!pack.atEnd())
pack >> pluginVersions;
const int pluginNamesSize = pluginNames.size();
diff --git a/tools/qmlprofiler/qmlprofiler.pro b/tools/qmlprofiler/qmlprofiler.pro
index 4fa36f5127..e38ba928e2 100644
--- a/tools/qmlprofiler/qmlprofiler.pro
+++ b/tools/qmlprofiler/qmlprofiler.pro
@@ -1,4 +1,4 @@
-QT = qml qml-private network core-private
+QT = qml qml-private network core-private packetprotocol-private
CONFIG += no_import_scan
SOURCES += main.cpp \
@@ -6,8 +6,7 @@ SOURCES += main.cpp \
commandlistener.cpp \
qqmldebugclient.cpp \
qmlprofilerdata.cpp \
- qmlprofilerclient.cpp \
- qpacketprotocol.cpp
+ qmlprofilerclient.cpp
HEADERS += \
qmlprofilerapplication.h \
@@ -16,7 +15,6 @@ HEADERS += \
qmlprofilerdata.h \
qmlprofilerclient.h \
qmlprofilereventlocation.h \
- qqmldebugclient.h \
- qpacketprotocol.h
+ qqmldebugclient.h
load(qt_tool)
diff --git a/tools/qmlprofiler/qpacketprotocol.cpp b/tools/qmlprofiler/qpacketprotocol.cpp
deleted file mode 100644
index 096bc142c5..0000000000
--- a/tools/qmlprofiler/qpacketprotocol.cpp
+++ /dev/null
@@ -1,527 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qpacketprotocol.h"
-
-#include <QtCore/QBuffer>
-#include <QtCore/QElapsedTimer>
-#include <private/qiodevice_p.h> // for qt_subtract_from_timeout
-
-static const unsigned int MAX_PACKET_SIZE = 0x7FFFFFFF;
-
-/*!
- \class QPacketProtocol
- \internal
-
- \brief The QPacketProtocol class encapsulates communicating discrete packets
- across fragmented IO channels, such as TCP sockets.
-
- QPacketProtocol makes it simple to send arbitrary sized data "packets" across
- fragmented transports such as TCP and UDP.
-
- As transmission boundaries are not respected, sending packets over protocols
- like TCP frequently involves "stitching" them back together at the receiver.
- QPacketProtocol makes this easier by performing this task for you. Packet
- data sent using QPacketProtocol is prepended with a 4-byte size header
- allowing the receiving QPacketProtocol to buffer the packet internally until
- it has all been received. QPacketProtocol does not perform any sanity
- checking on the size or on the data, so this class should only be used in
- prototyping or trusted situations where DOS attacks are unlikely.
-
- QPacketProtocol does not perform any communications itself. Instead it can
- operate on any QIODevice that supports the QIODevice::readyRead() signal. A
- logical "packet" is encapsulated by the companion QPacket class. The
- following example shows two ways to send data using QPacketProtocol. The
- transmitted data is equivalent in both.
-
- \code
- QTcpSocket socket;
- // ... connect socket ...
-
- QPacketProtocol protocol(&socket);
-
- // Send packet the quick way
- protocol.send() << "Hello world" << 123;
-
- // Send packet the longer way
- QPacket packet;
- packet << "Hello world" << 123;
- protocol.send(packet);
- \endcode
-
- Likewise, the following shows how to read data from QPacketProtocol, assuming
- that the QPacketProtocol::readyRead() signal has been emitted.
-
- \code
- // ... QPacketProtocol::readyRead() is emitted ...
-
- int a;
- QByteArray b;
-
- // Receive packet the quick way
- protocol.read() >> a >> b;
-
- // Receive packet the longer way
- QPacket packet = protocol.read();
- p >> a >> b;
- \endcode
-
- \ingroup io
- \sa QPacket
-*/
-
-class QPacketProtocolPrivate : public QObject
-{
- Q_OBJECT
-public:
- QPacketProtocolPrivate(QPacketProtocol *parent, QIODevice *_dev)
- : QObject(parent), inProgressSize(-1), maxPacketSize(MAX_PACKET_SIZE),
- waitingForPacket(false), dev(_dev)
- {
- Q_ASSERT(4 == sizeof(qint32));
-
- QObject::connect(this, SIGNAL(readyRead()),
- parent, SIGNAL(readyRead()));
- QObject::connect(this, SIGNAL(packetWritten()),
- parent, SIGNAL(packetWritten()));
- QObject::connect(this, SIGNAL(invalidPacket()),
- parent, SIGNAL(invalidPacket()));
- QObject::connect(dev, SIGNAL(readyRead()),
- this, SLOT(readyToRead()));
- QObject::connect(dev, SIGNAL(aboutToClose()),
- this, SLOT(aboutToClose()));
- QObject::connect(dev, SIGNAL(bytesWritten(qint64)),
- this, SLOT(bytesWritten(qint64)));
- }
-
-Q_SIGNALS:
- void readyRead();
- void packetWritten();
- void invalidPacket();
-
-public Q_SLOTS:
- void aboutToClose()
- {
- inProgress.clear();
- sendingPackets.clear();
- inProgressSize = -1;
- }
-
- void bytesWritten(qint64 bytes)
- {
- Q_ASSERT(!sendingPackets.isEmpty());
-
- while (bytes) {
- if (sendingPackets.at(0) > bytes) {
- sendingPackets[0] -= bytes;
- bytes = 0;
- } else {
- bytes -= sendingPackets.at(0);
- sendingPackets.removeFirst();
- emit packetWritten();
- }
- }
- }
-
- void readyToRead()
- {
- while (true) {
- // Need to get trailing data
- if (-1 == inProgressSize) {
- // We need a size header of sizeof(qint32)
- if (sizeof(qint32) > (uint)dev->bytesAvailable())
- return;
-
- // Read size header
- int read = dev->read((char *)&inProgressSize, sizeof(qint32));
- Q_ASSERT(read == sizeof(qint32));
- Q_UNUSED(read);
-
- // Check sizing constraints
- if (inProgressSize > maxPacketSize) {
- QObject::disconnect(dev, SIGNAL(readyRead()),
- this, SLOT(readyToRead()));
- QObject::disconnect(dev, SIGNAL(aboutToClose()),
- this, SLOT(aboutToClose()));
- QObject::disconnect(dev, SIGNAL(bytesWritten(qint64)),
- this, SLOT(bytesWritten(qint64)));
- dev = 0;
- emit invalidPacket();
- return;
- }
-
- inProgressSize -= sizeof(qint32);
- } else {
- inProgress.append(dev->read(inProgressSize - inProgress.size()));
-
- if (inProgressSize == inProgress.size()) {
- // Packet has arrived!
- packets.append(inProgress);
- inProgressSize = -1;
- inProgress.clear();
-
- waitingForPacket = false;
- emit readyRead();
- } else
- return;
- }
- }
- }
-
-public:
- QList<qint64> sendingPackets;
- QList<QByteArray> packets;
- QByteArray inProgress;
- qint32 inProgressSize;
- qint32 maxPacketSize;
- bool waitingForPacket;
- QIODevice *dev;
-};
-
-/*!
- Construct a QPacketProtocol instance that works on \a dev with the
- specified \a parent.
- */
-QPacketProtocol::QPacketProtocol(QIODevice *dev, QObject *parent)
- : QObject(parent), d(new QPacketProtocolPrivate(this, dev))
-{
- Q_ASSERT(dev);
-}
-
-/*!
- Destroys the QPacketProtocol instance.
- */
-QPacketProtocol::~QPacketProtocol()
-{
-}
-
-/*!
- Returns the maximum packet size allowed. By default this is
- 2,147,483,647 bytes.
-
- If a packet claiming to be larger than the maximum packet size is received,
- the QPacketProtocol::invalidPacket() signal is emitted.
-
- \sa QPacketProtocol::setMaximumPacketSize()
- */
-qint32 QPacketProtocol::maximumPacketSize() const
-{
- return d->maxPacketSize;
-}
-
-/*!
- Sets the maximum allowable packet size to \a max.
-
- \sa QPacketProtocol::maximumPacketSize()
- */
-qint32 QPacketProtocol::setMaximumPacketSize(qint32 max)
-{
- if (max > (signed)sizeof(qint32))
- d->maxPacketSize = max;
- return d->maxPacketSize;
-}
-
-/*!
- Returns a streamable object that is transmitted on destruction. For example
-
- \code
- protocol.send() << "Hello world" << 123;
- \endcode
-
- will send a packet containing "Hello world" and 123. To construct more
- complex packets, explicitly construct a QPacket instance.
- */
-QPacketAutoSend QPacketProtocol::send()
-{
- return QPacketAutoSend(this);
-}
-
-/*!
- \fn void QPacketProtocol::send(const QPacket & packet)
-
- Transmit the \a packet.
- */
-void QPacketProtocol::send(const QPacket & p)
-{
- if (p.b.isEmpty())
- return; // We don't send empty packets
-
- qint64 sendSize = p.b.size() + sizeof(qint32);
-
- d->sendingPackets.append(sendSize);
- qint32 sendSize32 = sendSize;
- qint64 writeBytes = d->dev->write((char *)&sendSize32, sizeof(qint32));
- Q_UNUSED(writeBytes);
- Q_ASSERT(writeBytes == sizeof(qint32));
- writeBytes = d->dev->write(p.b);
- Q_ASSERT(writeBytes == p.b.size());
-}
-
-/*!
- Returns the number of received packets yet to be read.
- */
-qint64 QPacketProtocol::packetsAvailable() const
-{
- return d->packets.count();
-}
-
-/*!
- Discard any unread packets.
- */
-void QPacketProtocol::clear()
-{
- d->packets.clear();
-}
-
-/*!
- Return the next unread packet, or an invalid QPacket instance if no packets
- are available. This method does NOT block.
- */
-QPacket QPacketProtocol::read()
-{
- if (0 == d->packets.count())
- return QPacket();
-
- QPacket rv(d->packets.at(0));
- d->packets.removeFirst();
- return rv;
-}
-
-/*!
- This function locks until a new packet is available for reading and the
- \l{QIODevice::}{readyRead()} signal has been emitted. The function
- will timeout after \a msecs milliseconds; the default timeout is
- 30000 milliseconds.
-
- The function returns true if the readyRead() signal is emitted and
- there is new data available for reading; otherwise it returns false
- (if an error occurred or the operation timed out).
- */
-
-bool QPacketProtocol::waitForReadyRead(int msecs)
-{
- if (!d->packets.isEmpty())
- return true;
-
- QElapsedTimer stopWatch;
- stopWatch.start();
-
- d->waitingForPacket = true;
- do {
- if (!d->dev->waitForReadyRead(msecs))
- return false;
- if (!d->waitingForPacket)
- return true;
- msecs = qt_subtract_from_timeout(msecs, stopWatch.elapsed());
- } while (true);
-}
-
-/*!
- Return the QIODevice passed to the QPacketProtocol constructor.
-*/
-QIODevice *QPacketProtocol::device()
-{
- return d->dev;
-}
-
-/*!
- \fn void QPacketProtocol::readyRead()
-
- Emitted whenever a new packet is received. Applications may use
- QPacketProtocol::read() to retrieve this packet.
- */
-
-/*!
- \fn void QPacketProtocol::invalidPacket()
-
- A packet larger than the maximum allowable packet size was received. The
- packet will be discarded and, as it indicates corruption in the protocol, no
- further packets will be received.
- */
-
-/*!
- \fn void QPacketProtocol::packetWritten()
-
- Emitted each time a packet is completing written to the device. This signal
- may be used for communications flow control.
- */
-
-/*!
- \class QPacket
- \internal
-
- \brief The QPacket class encapsulates an unfragmentable packet of data to be
- transmitted by QPacketProtocol.
-
- The QPacket class works together with QPacketProtocol to make it simple to
- send arbitrary sized data "packets" across fragmented transports such as TCP
- and UDP.
-
- QPacket provides a QDataStream interface to an unfragmentable packet.
- Applications should construct a QPacket, propagate it with data and then
- transmit it over a QPacketProtocol instance. For example:
- \code
- QPacketProtocol protocol(...);
-
- QPacket myPacket;
- myPacket << "Hello world!" << 123;
- protocol.send(myPacket);
- \endcode
-
- As long as both ends of the connection are using the QPacketProtocol class,
- the data within this packet will be delivered unfragmented at the other end,
- ready for extraction.
-
- \code
- QByteArray greeting;
- int count;
-
- QPacket myPacket = protocol.read();
-
- myPacket >> greeting >> count;
- \endcode
-
- Only packets returned from QPacketProtocol::read() may be read from. QPacket
- instances constructed by directly by applications are for transmission only
- and are considered "write only". Attempting to read data from them will
- result in undefined behavior.
-
- \ingroup io
- \sa QPacketProtocol
- */
-
-/*!
- Constructs an empty write-only packet.
- */
-QPacket::QPacket()
- : QDataStream(), buf(0)
-{
- buf = new QBuffer(&b);
- buf->open(QIODevice::WriteOnly);
- setDevice(buf);
- setVersion(QDataStream::Qt_4_7);
-}
-
-/*!
- Destroys the QPacket instance.
- */
-QPacket::~QPacket()
-{
- if (buf) {
- delete buf;
- buf = 0;
- }
-}
-
-/*!
- Creates a copy of \a other. The initial stream positions are shared, but the
- two packets are otherwise independent.
- */
-QPacket::QPacket(const QPacket & other)
- : QDataStream(), b(other.b), buf(0)
-{
- buf = new QBuffer(&b);
- buf->open(other.buf->openMode());
- setDevice(buf);
-}
-
-/*!
- \internal
- */
-QPacket::QPacket(const QByteArray & ba)
- : QDataStream(), b(ba), buf(0)
-{
- buf = new QBuffer(&b);
- buf->open(QIODevice::ReadOnly);
- setDevice(buf);
-}
-
-/*!
- Returns true if this packet is empty - that is, contains no data.
- */
-bool QPacket::isEmpty() const
-{
- return b.isEmpty();
-}
-
-/*!
- 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
- QPacketProtocol protocol(...);
-
- QPacket packet;
-
- packet << "Hello world!" << 123;
- protocol.send(packet);
-
- packet.clear();
- packet << "Goodbyte world!" << 789;
- protocol.send(packet);
- \endcode
- */
-void QPacket::clear()
-{
- QBuffer::OpenMode oldMode = buf->openMode();
- buf->close();
- b.clear();
- buf->setBuffer(&b); // reset QBuffer internals with new size of b.
- buf->open(oldMode);
-}
-
-/*!
- \class QPacketAutoSend
- \internal
-
- \internal
- */
-QPacketAutoSend::QPacketAutoSend(QPacketProtocol *_p)
- : QPacket(), p(_p)
-{
-}
-
-QPacketAutoSend::~QPacketAutoSend()
-{
- if (!b.isEmpty())
- p->send(*this);
-}
-
-#include <qpacketprotocol.moc>
diff --git a/tools/qmlprofiler/qqmldebugclient.cpp b/tools/qmlprofiler/qqmldebugclient.cpp
index f87d4b0a7c..d661c71e1c 100644
--- a/tools/qmlprofiler/qqmldebugclient.cpp
+++ b/tools/qmlprofiler/qqmldebugclient.cpp
@@ -32,7 +32,9 @@
****************************************************************************/
#include "qqmldebugclient.h"
-#include "qpacketprotocol.h"
+
+#include <private/qpacketprotocol_p.h>
+#include <private/qpacket_p.h>
#include <QtCore/qdebug.h>
#include <QtCore/qstringlist.h>
@@ -119,7 +121,7 @@ void QQmlDebugConnectionPrivate::readyRead()
QStringList pluginNames;
QList<float> pluginVersions;
pack >> pluginNames;
- if (!pack.isEmpty())
+ if (!pack.atEnd())
pack >> pluginVersions;
const int pluginNamesSize = pluginNames.size();
@@ -169,7 +171,7 @@ void QQmlDebugConnectionPrivate::readyRead()
QStringList pluginNames;
QList<float> pluginVersions;
pack >> pluginNames;
- if (!pack.isEmpty())
+ if (!pack.atEnd())
pack >> pluginVersions;
const int pluginNamesSize = pluginNames.size();