aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/qmltooling/packetprotocol
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@theqtcompany.com>2015-11-03 14:32:25 +0100
committerUlf Hermann <ulf.hermann@theqtcompany.com>2015-11-17 18:42:07 +0000
commit0b67dd7e132d7d618fa538e8c4a275c874543342 (patch)
tree3c6c7cdf8fbae8c6a7d0d333d96c22d130413980 /src/plugins/qmltooling/packetprotocol
parente010b64d38cb8533d779ac0fe8d609f00a6793e7 (diff)
QmlDebug: Restructure QPacket and QPacketProtocol
We cannot use the same data stream version for the client and server versions of QPacket and QPacketProtocol should not deal with QPackets but with simple byte arrays because the underlying QDataStream is hard to copy. The new QQmlDebugPacket picks its data stream version from QQmlDebugConnector now, which adjusts it when connecting. As there can only ever be one QQmlDebugConnector, we can keep the version static. The clients need to query the connection for the correct version. We may connect to several different servers sequentially or we may have a server running while using a client, and we don't want to confuse the versions between those. With this in place, all remaining occurrences of QDataStream are replaced with QPacket or QQmlDebugPacket. Change-Id: I3f6ba73fcbfad5e8df917c5feb9308116738a614 Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
Diffstat (limited to 'src/plugins/qmltooling/packetprotocol')
-rw-r--r--src/plugins/qmltooling/packetprotocol/packetprotocol.pro6
-rw-r--r--src/plugins/qmltooling/packetprotocol/qpacket.cpp112
-rw-r--r--src/plugins/qmltooling/packetprotocol/qpacket_p.h67
-rw-r--r--src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp31
-rw-r--r--src/plugins/qmltooling/packetprotocol/qpacketprotocol_p.h5
5 files changed, 196 insertions, 25 deletions
diff --git a/src/plugins/qmltooling/packetprotocol/packetprotocol.pro b/src/plugins/qmltooling/packetprotocol/packetprotocol.pro
index a6b8f26bb1..383e32b54e 100644
--- a/src/plugins/qmltooling/packetprotocol/packetprotocol.pro
+++ b/src/plugins/qmltooling/packetprotocol/packetprotocol.pro
@@ -3,9 +3,11 @@ QT = core-private qml-private
CONFIG += static internal_module
HEADERS = \
- qpacketprotocol_p.h
+ qpacketprotocol_p.h \
+ qpacket_p.h
SOURCES = \
- qpacketprotocol.cpp
+ qpacketprotocol.cpp \
+ qpacket.cpp
load(qt_module)
diff --git a/src/plugins/qmltooling/packetprotocol/qpacket.cpp b/src/plugins/qmltooling/packetprotocol/qpacket.cpp
new file mode 100644
index 0000000000..1bb611ab25
--- /dev/null
+++ b/src/plugins/qmltooling/packetprotocol/qpacket.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** 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
+ int version = QDataStream::Qt_DefaultCompiledVersion;
+ QPacketProtocol protocol(...);
+
+ QPacket myPacket(version);
+ myPacket << "Hello world!" << 123;
+ protocol.send(myPacket.data());
+ \endcode
+
+ As long as both ends of the connection are using the QPacketProtocol class
+ and the same data stream version, the data within this packet will be
+ delivered unfragmented at the other end, ready for extraction.
+
+ \code
+ QByteArray greeting;
+ int count;
+
+ QPacket myPacket(version, 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
+ */
+
+
+/*!
+ Constructs an empty write-only packet.
+ */
+QPacket::QPacket(int version)
+{
+ buf.open(QIODevice::WriteOnly);
+ setDevice(&buf);
+ setVersion(version);
+}
+
+/*!
+ Constructs a read-only packet.
+ */
+QPacket::QPacket(int version, const QByteArray &data)
+{
+ buf.setData(data);
+ buf.open(QIODevice::ReadOnly);
+ setDevice(&buf);
+ setVersion(version);
+}
+
+/*!
+ Returns raw packet data.
+ */
+QByteArray QPacket::data() const
+{
+ return buf.data();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/packetprotocol/qpacket_p.h b/src/plugins/qmltooling/packetprotocol/qpacket_p.h
new file mode 100644
index 0000000000..dda152dfd1
--- /dev/null
+++ b/src/plugins/qmltooling/packetprotocol/qpacket_p.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef QPACKET_H
+#define QPACKET_H
+
+#include <QtCore/qdatastream.h>
+#include <QtCore/qbuffer.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 QPacket : public QDataStream
+{
+public:
+ QPacket(int version);
+ explicit QPacket(int version, const QByteArray &ba);
+ QByteArray data() const;
+
+private:
+ void init(QIODevice::OpenMode mode);
+ QBuffer buf;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPACKET_H
diff --git a/src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp b/src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp
index 9f9dbfee90..d576e74e53 100644
--- a/src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp
+++ b/src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp
@@ -36,7 +36,6 @@
#include <QtCore/QElapsedTimer>
#include <private/qiodevice_p.h>
#include <private/qobject_p.h>
-#include <private/qpacket_p.h>
QT_BEGIN_NAMESPACE
@@ -63,9 +62,8 @@ static const int MAX_PACKET_SIZE = 0x7FFFFFFF;
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.
+ logical "packet" is simply a QByteArray. The following example how to send
+ data using QPacketProtocol.
\code
QTcpSocket socket;
@@ -74,9 +72,9 @@ static const int MAX_PACKET_SIZE = 0x7FFFFFFF;
QPacketProtocol protocol(&socket);
// Send a packet
- QPacket packet;
+ QDataStream packet;
packet << "Hello world" << 123;
- protocol.send(packet);
+ protocol.send(packet.data());
\endcode
Likewise, the following shows how to read data from QPacketProtocol, assuming
@@ -88,16 +86,12 @@ static const int MAX_PACKET_SIZE = 0x7FFFFFFF;
int a;
QByteArray b;
- // Receive packet the quick way
- protocol.read() >> a >> b;
-
- // Receive packet the longer way
- QPacket packet = protocol.read();
+ // Receive packet
+ QDataStream packet(protocol.read());
p >> a >> b;
\endcode
\ingroup io
- \sa QPacket
*/
class QPacketProtocolPrivate : public QObjectPrivate
@@ -133,15 +127,14 @@ QPacketProtocol::QPacketProtocol(QIODevice *dev, QObject *parent)
}
/*!
- \fn void QPacketProtocol::send(const QPacket & packet)
+ \fn void QPacketProtocol::send(const QByteArray &data)
Transmit the \a packet.
*/
-void QPacketProtocol::send(const QPacket & p)
+void QPacketProtocol::send(const QByteArray &data)
{
Q_D(QPacketProtocol);
- QByteArray data = p.data();
if (data.isEmpty())
return; // We don't send empty packets
qint64 sendSize = data.size() + sizeof(qint32);
@@ -165,15 +158,13 @@ qint64 QPacketProtocol::packetsAvailable() const
}
/*!
- Return the next unread packet, or an invalid QPacket instance if no packets
+ Return the next unread packet, or an empty QByteArray if no packets
are available. This method does NOT block.
*/
-QPacket QPacketProtocol::read()
+QByteArray 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());
+ return d->packets.isEmpty() ? QByteArray() : d->packets.takeFirst();
}
/*!
diff --git a/src/plugins/qmltooling/packetprotocol/qpacketprotocol_p.h b/src/plugins/qmltooling/packetprotocol/qpacketprotocol_p.h
index 6ed803809f..20bbc66418 100644
--- a/src/plugins/qmltooling/packetprotocol/qpacketprotocol_p.h
+++ b/src/plugins/qmltooling/packetprotocol/qpacketprotocol_p.h
@@ -35,7 +35,6 @@
#define QPACKETPROTOCOL_P_H
#include <QtCore/qobject.h>
-#include <private/qpacket_p.h>
//
// W A R N I N G
@@ -60,9 +59,9 @@ class QPacketProtocol : public QObject
public:
explicit QPacketProtocol(QIODevice *dev, QObject *parent = 0);
- void send(const QPacket &);
+ void send(const QByteArray &data);
qint64 packetsAvailable() const;
- QPacket read();
+ QByteArray read();
bool waitForReadyRead(int msecs = 3000);
Q_SIGNALS: