summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Trotsenko <alex1973tr@gmail.com>2021-07-02 17:31:26 +0300
committerAlex Trotsenko <alex1973tr@gmail.com>2021-07-08 16:14:11 +0300
commit1a57a4974be9dbdeedef6f5c6eb4332eecf6f0c9 (patch)
tree383496919e92f6fe57e87d157a6d34bc5b29641c
parent82499f81478032911d8f788aa28e8d780b31c973 (diff)
QLocalSocket/Win: reimplement skipData() function
The base implementation discards the data by reading into a dummy buffer, which is slower than necessary. Change-Id: Iabf0c4a25746af6cac5b61d7bda66d89501c808c Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
-rw-r--r--src/corelib/io/qwindowspipereader.cpp19
-rw-r--r--src/corelib/io/qwindowspipereader_p.h1
-rw-r--r--src/network/socket/qlocalsocket_win.cpp7
-rw-r--r--tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp55
4 files changed, 81 insertions, 1 deletions
diff --git a/src/corelib/io/qwindowspipereader.cpp b/src/corelib/io/qwindowspipereader.cpp
index c3ac51df94..5415ad7830 100644
--- a/src/corelib/io/qwindowspipereader.cpp
+++ b/src/corelib/io/qwindowspipereader.cpp
@@ -233,6 +233,25 @@ qint64 QWindowsPipeReader::readLine(char *data, qint64 maxlen)
}
/*!
+ Skips up to \c{maxlen} bytes from the internal read buffer.
+ */
+qint64 QWindowsPipeReader::skip(qint64 maxlen)
+{
+ QMutexLocker locker(&mutex);
+
+ const qint64 skippedSoFar = readBuffer.skip(qMin(actualReadBufferSize, maxlen));
+ actualReadBufferSize -= skippedSoFar;
+
+ if (!pipeBroken) {
+ startAsyncReadHelper(&locker);
+ if (skippedSoFar == 0)
+ return -2; // signal EWOULDBLOCK
+ }
+
+ return skippedSoFar;
+}
+
+/*!
Returns \c true if a complete line of data can be read from the buffer.
*/
bool QWindowsPipeReader::canReadLine() const
diff --git a/src/corelib/io/qwindowspipereader_p.h b/src/corelib/io/qwindowspipereader_p.h
index e2190d67d9..5eb62cb393 100644
--- a/src/corelib/io/qwindowspipereader_p.h
+++ b/src/corelib/io/qwindowspipereader_p.h
@@ -79,6 +79,7 @@ public:
qint64 bytesAvailable() const;
qint64 read(char *data, qint64 maxlen);
qint64 readLine(char *data, qint64 maxlen);
+ qint64 skip(qint64 maxlen);
bool canReadLine() const;
DWORD checkPipeState();
bool checkForReadyRead() { return consumePendingAndEmit(false); }
diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp
index 89901533af..e430f642db 100644
--- a/src/network/socket/qlocalsocket_win.cpp
+++ b/src/network/socket/qlocalsocket_win.cpp
@@ -277,7 +277,12 @@ qint64 QLocalSocket::readLineData(char *data, qint64 maxSize)
qint64 QLocalSocket::skipData(qint64 maxSize)
{
- return QIODevice::skipData(maxSize);
+ Q_D(QLocalSocket);
+
+ if (!maxSize)
+ return 0;
+
+ return transformPipeReaderResult(d->pipeReader->skip(maxSize));
}
qint64 QLocalSocket::writeData(const char *data, qint64 len)
diff --git a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp
index 8ec41a760a..cec783985d 100644
--- a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp
+++ b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp
@@ -95,6 +95,9 @@ private slots:
void readLine_data();
void readLine();
+ void skip_data();
+ void skip();
+
void readBufferOverflow();
void simpleCommandProtocol1();
@@ -806,6 +809,58 @@ void tst_QLocalSocket::readLine()
QCOMPARE(result, output);
}
+void tst_QLocalSocket::skip_data()
+{
+ QTest::addColumn<QByteArray>("data");
+ QTest::addColumn<int>("read");
+ QTest::addColumn<int>("skip");
+ QTest::addColumn<int>("skipped");
+ QTest::addColumn<char>("expect");
+
+ QByteArray bigData;
+ bigData.fill('a', 20000);
+ bigData[10001] = 'x';
+
+ QTest::newRow("small_data") << QByteArray("abcdefghij") << 3 << 6 << 6 << 'j';
+ QTest::newRow("big_data") << bigData << 1 << 10000 << 10000 << 'x';
+ QTest::newRow("beyond_the_end") << bigData << 1 << 20000 << 19999 << '\0';
+}
+
+void tst_QLocalSocket::skip()
+{
+ QFETCH(QByteArray, data);
+ QFETCH(int, read);
+ QFETCH(int, skip);
+ QFETCH(int, skipped);
+ QFETCH(char, expect);
+ char lastChar = '\0';
+
+ const QString serverName = QLatin1String("tst_localsocket");
+ LocalServer server;
+ QVERIFY(server.listen(serverName));
+
+ LocalSocket client;
+ client.connectToServer(serverName);
+ QVERIFY(server.waitForNewConnection());
+ QLocalSocket *serverSocket = server.nextPendingConnection();
+ QVERIFY(serverSocket);
+ QCOMPARE(client.state(), QLocalSocket::ConnectedState);
+
+ QCOMPARE(serverSocket->write(data), data.size());
+ while (serverSocket->waitForBytesWritten())
+ QVERIFY(client.waitForReadyRead());
+ QCOMPARE(serverSocket->bytesToWrite(), qint64(0));
+ serverSocket->close();
+ QVERIFY(client.waitForDisconnected());
+
+ for (int i = 0; i < read; ++i)
+ client.getChar(nullptr);
+
+ QCOMPARE(client.skip(skip), skipped);
+ client.getChar(&lastChar);
+ QCOMPARE(lastChar, expect);
+}
+
void tst_QLocalSocket::readBufferOverflow()
{
const int readBufferSize = 128;