From bd100e777190f68c4da11d4f7a1c4bf8274211d9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= <marten.nordheim@qt.io>
Date: Tue, 10 Apr 2018 15:04:10 +0200
Subject: [PATCH] QWebSocket: Add 'bytesToWrite'

Add the well-known 'bytesToWrite' function to QWebSocket. Previously
the only way to know how many bytes were left to be written was to
make a guesstimate on the overhead your message would get and then
keep track of the amount sent using the 'bytesWritten' signal.

The tests compare using '>' because there is overhead from the headers.

[ChangeLog][QWebSocket] Added the bytesToWrite function to
QWebSocket. Call this function to see how many bytes are left to write.

Change-Id: I82f17a98b582ee3bc02f0c47597b4a6717761f12
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
---
 src/websockets/qwebsocket.cpp                       | 13 +++++++++++++
 src/websockets/qwebsocket.h                         |  2 ++
 tests/auto/websockets/qwebsocket/tst_qwebsocket.cpp |  8 ++++++++
 .../qwebsocketserver/tst_qwebsocketserver.cpp       |  8 ++++++++
 4 files changed, 31 insertions(+)

diff --git a/src/websockets/qwebsocket.cpp b/src/websockets/qwebsocket.cpp
index 1b0fc351..64d5e4c7 100644
--- a/src/websockets/qwebsocket.cpp
+++ b/src/websockets/qwebsocket.cpp
@@ -772,4 +772,17 @@ bool QWebSocket::isValid() const
     return d->isValid();
 }
 
+/*!
+    \since 5.12
+    Returns the number of bytes that are waiting to be written. The bytes are written when control
+    goes back to the event loop or when flush() is called.
+
+    \sa flush
+ */
+qint64 QWebSocket::bytesToWrite() const
+{
+    Q_D(const QWebSocket);
+    return d->m_pSocket ? d->m_pSocket->bytesToWrite() : 0;
+}
+
 QT_END_NAMESPACE
diff --git a/src/websockets/qwebsocket.h b/src/websockets/qwebsocket.h
index a80c47a3..b8742e81 100644
--- a/src/websockets/qwebsocket.h
+++ b/src/websockets/qwebsocket.h
@@ -113,6 +113,8 @@ public:
     QSslConfiguration sslConfiguration() const;
 #endif
 
+    qint64 bytesToWrite() const;
+
 public Q_SLOTS:
     void close(QWebSocketProtocol::CloseCode closeCode = QWebSocketProtocol::CloseCodeNormal,
                const QString &reason = QString());
diff --git a/tests/auto/websockets/qwebsocket/tst_qwebsocket.cpp b/tests/auto/websockets/qwebsocket/tst_qwebsocket.cpp
index ac542704..e80eeb10 100644
--- a/tests/auto/websockets/qwebsocket/tst_qwebsocket.cpp
+++ b/tests/auto/websockets/qwebsocket/tst_qwebsocket.cpp
@@ -434,9 +434,13 @@ void tst_QWebSocket::tst_sendTextMessage()
     QUrl urlConnected = arguments.at(0).toUrl();
     QCOMPARE(urlConnected, url);
 
+    QCOMPARE(socket.bytesToWrite(), 0);
     socket.sendTextMessage(QStringLiteral("Hello world!"));
+    QVERIFY(socket.bytesToWrite() > 12); // 12 + a few extra bytes for header
 
     QVERIFY(textMessageReceived.wait(500));
+    QCOMPARE(socket.bytesToWrite(), 0);
+
     QCOMPARE(textMessageReceived.count(), 1);
     QCOMPARE(binaryMessageReceived.count(), 0);
     QCOMPARE(binaryFrameReceived.count(), 0);
@@ -508,9 +512,13 @@ void tst_QWebSocket::tst_sendBinaryMessage()
     QTRY_COMPARE(socketConnectedSpy.count(), 1);
     QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
 
+    QCOMPARE(socket.bytesToWrite(), 0);
     socket.sendBinaryMessage(QByteArrayLiteral("Hello world!"));
+    QVERIFY(socket.bytesToWrite() > 12); // 12 + a few extra bytes for header
 
     QVERIFY(binaryMessageReceived.wait(500));
+    QCOMPARE(socket.bytesToWrite(), 0);
+
     QCOMPARE(textMessageReceived.count(), 0);
     QCOMPARE(textFrameReceived.count(), 0);
     QCOMPARE(binaryMessageReceived.count(), 1);
diff --git a/tests/auto/websockets/qwebsocketserver/tst_qwebsocketserver.cpp b/tests/auto/websockets/qwebsocketserver/tst_qwebsocketserver.cpp
index 8a3760d8..a2f3c150 100644
--- a/tests/auto/websockets/qwebsocketserver/tst_qwebsocketserver.cpp
+++ b/tests/auto/websockets/qwebsocketserver/tst_qwebsocketserver.cpp
@@ -640,6 +640,14 @@ void tst_QWebSocketServer::tst_handleConnection()
     QTRY_COMPARE(wsMessageReceivedSpy.count(), 1);
     QList<QVariant> arguments = wsMessageReceivedSpy.takeFirst();
     QCOMPARE(arguments.first().toString(), QString("dummy"));
+
+    QSignalSpy clientMessageReceivedSpy(&webSocket, &QWebSocket::textMessageReceived);
+    webServerSocket->sendTextMessage("hello");
+    QVERIFY(webServerSocket->bytesToWrite() > 5); // 5 + a few extra bytes for header
+    QTRY_COMPARE(webServerSocket->bytesToWrite(), 0);
+    QTRY_COMPARE(clientMessageReceivedSpy.count(), 1);
+    arguments = clientMessageReceivedSpy.takeFirst();
+    QCOMPARE(arguments.first().toString(), QString("hello"));
 }
 
 QTEST_MAIN(tst_QWebSocketServer)
-- 
GitLab