diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2018-02-06 17:47:39 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2018-04-05 06:54:28 +0000 |
commit | feeec8daa8412219dadddfb6e7cfa17f59451a32 (patch) | |
tree | 0f7e970273a10fb00cb3b0ef1c2642d188a07272 /src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp | |
parent | fd8c3e41fc90bb431159343926dff628a860f289 (diff) |
QPacketProtocol: Add proper error handling
The device is not guaranteed to write or read all the data we ask for in
one go. Retry and check for read or write errors.
Change-Id: I640bdaf4d9eb7b900c8f7145bd42eb5d667a9cad
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp')
-rw-r--r-- | src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp | 63 |
1 files changed, 50 insertions, 13 deletions
diff --git a/src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp b/src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp index 5460d617dd..791c09810e 100644 --- a/src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp +++ b/src/plugins/qmltooling/packetprotocol/qpacketprotocol.cpp @@ -106,6 +106,9 @@ class QPacketProtocolPrivate : public QObjectPrivate public: QPacketProtocolPrivate(QIODevice *dev); + bool writeToDevice(const char *bytes, qint64 size); + bool readFromDevice(char *buffer, qint64 size); + QList<qint64> sendingPackets; QList<QByteArray> packets; QByteArray inProgress; @@ -140,15 +143,14 @@ void QPacketProtocol::send(const QByteArray &data) if (data.isEmpty()) return; // We don't send empty packets - qint64 sendSize = data.size() + sizeof(qint32); + const qint32 sendSize = data.size() + static_cast<qint32>(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()); + if (!d->writeToDevice((const char *)&sendSize, sizeof(qint32)) + || !d->writeToDevice(data.data(), data.size())) { + emit error(); + return; + } } /*! @@ -234,13 +236,14 @@ void QPacketProtocol::readyToRead() // Need to get trailing data if (-1 == d->inProgressSize) { // We need a size header of sizeof(qint32) - if (sizeof(qint32) > (uint)d->dev->bytesAvailable()) + if (static_cast<qint64>(sizeof(qint32)) > 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); + if (!d->readFromDevice((char *)&d->inProgressSize, sizeof(qint32))) { + emit error(); + return; + } // Check sizing constraints if (d->inProgressSize > MAX_PACKET_SIZE) { @@ -248,14 +251,24 @@ void QPacketProtocol::readyToRead() disconnect(d->dev, &QIODevice::aboutToClose, this, &QPacketProtocol::aboutToClose); disconnect(d->dev, &QIODevice::bytesWritten, this, &QPacketProtocol::bytesWritten); d->dev = nullptr; - emit invalidPacket(); + emit error(); return; } d->inProgressSize -= sizeof(qint32); } else { - d->inProgress.append(d->dev->read(d->inProgressSize - d->inProgress.size())); + const int bytesToRead = static_cast<int>( + qMin(d->dev->bytesAvailable(), + static_cast<qint64>(d->inProgressSize - d->inProgress.size()))); + + QByteArray toRead(bytesToRead, Qt::Uninitialized); + if (!d->readFromDevice(toRead.data(), toRead.length())) { + emit error(); + return; + } + + d->inProgress.append(toRead); if (d->inProgressSize == d->inProgress.size()) { // Packet has arrived! d->packets.append(d->inProgress); @@ -275,6 +288,30 @@ QPacketProtocolPrivate::QPacketProtocolPrivate(QIODevice *dev) : { } +bool QPacketProtocolPrivate::writeToDevice(const char *bytes, qint64 size) +{ + qint64 totalWritten = 0; + while (totalWritten < size) { + const qint64 chunkSize = dev->write(bytes + totalWritten, size - totalWritten); + if (chunkSize < 0) + return false; + totalWritten += chunkSize; + } + return totalWritten == size; +} + +bool QPacketProtocolPrivate::readFromDevice(char *buffer, qint64 size) +{ + qint64 totalRead = 0; + while (totalRead < size) { + const qint64 chunkSize = dev->read(buffer + totalRead, size - totalRead); + if (chunkSize < 0) + return false; + totalRead += chunkSize; + } + return totalRead == size; +} + /*! \fn void QPacketProtocol::readyRead() |