QLocalSocket: reimplement readLineData() function
The base implementation reads data using repeated calls to getChar(), which is quite slow. Change-Id: Ie46624df63791b2cdd3c8a28fe3327427d942505 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>bb10
parent
46d2ba1ea4
commit
b3fbfcd373
|
|
@ -208,6 +208,30 @@ qint64 QWindowsPipeReader::read(char *data, qint64 maxlen)
|
|||
return readSoFar;
|
||||
}
|
||||
|
||||
/*!
|
||||
Reads a line from the internal buffer, but no more than \c{maxlen}
|
||||
characters. A terminating '\0' byte is always appended to \c{data},
|
||||
so \c{maxlen} must be larger than 1.
|
||||
*/
|
||||
qint64 QWindowsPipeReader::readLine(char *data, qint64 maxlen)
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
qint64 readSoFar = 0;
|
||||
|
||||
if (actualReadBufferSize > 0) {
|
||||
readSoFar = readBuffer.readLine(data, qMin(actualReadBufferSize + 1, maxlen));
|
||||
actualReadBufferSize -= readSoFar;
|
||||
}
|
||||
|
||||
if (!pipeBroken) {
|
||||
startAsyncReadHelper(&locker);
|
||||
if (readSoFar == 0)
|
||||
return -2; // signal EWOULDBLOCK
|
||||
}
|
||||
|
||||
return readSoFar;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns \c true if a complete line of data can be read from the buffer.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ public:
|
|||
bool isPipeClosed() const { return pipeBroken; }
|
||||
qint64 bytesAvailable() const;
|
||||
qint64 read(char *data, qint64 maxlen);
|
||||
qint64 readLine(char *data, qint64 maxlen);
|
||||
bool canReadLine() const;
|
||||
DWORD checkPipeState();
|
||||
bool checkForReadyRead() { return consumePendingAndEmit(false); }
|
||||
|
|
|
|||
|
|
@ -166,6 +166,11 @@ QT_BEGIN_NAMESPACE
|
|||
\reimp
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn qint64 QLocalSocket::readLineData(char *data, qint64 maxSize)
|
||||
\reimp
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn qint64 QLocalSocket::skipData(qint64 maxSize)
|
||||
\reimp
|
||||
|
|
|
|||
|
|
@ -139,6 +139,7 @@ Q_SIGNALS:
|
|||
|
||||
protected:
|
||||
virtual qint64 readData(char*, qint64) override;
|
||||
qint64 readLineData(char *data, qint64 maxSize) override;
|
||||
qint64 skipData(qint64 maxSize) override;
|
||||
virtual qint64 writeData(const char*, qint64) override;
|
||||
|
||||
|
|
|
|||
|
|
@ -301,6 +301,16 @@ qint64 QLocalSocket::readData(char *data, qint64 c)
|
|||
return d->tcpSocket->read(data, c);
|
||||
}
|
||||
|
||||
qint64 QLocalSocket::readLineData(char *data, qint64 maxSize)
|
||||
{
|
||||
if (!maxSize)
|
||||
return 0;
|
||||
|
||||
// QIODevice::readLine() reserves space for the trailing '\0' byte,
|
||||
// so we must read 'maxSize + 1' bytes.
|
||||
return d_func()->tcpSocket->readLine(data, maxSize + 1);
|
||||
}
|
||||
|
||||
qint64 QLocalSocket::skipData(qint64 maxSize)
|
||||
{
|
||||
return d_func()->tcpSocket->skip(maxSize);
|
||||
|
|
|
|||
|
|
@ -483,6 +483,16 @@ qint64 QLocalSocket::readData(char *data, qint64 c)
|
|||
return d->unixSocket.read(data, c);
|
||||
}
|
||||
|
||||
qint64 QLocalSocket::readLineData(char *data, qint64 maxSize)
|
||||
{
|
||||
if (!maxSize)
|
||||
return 0;
|
||||
|
||||
// QIODevice::readLine() reserves space for the trailing '\0' byte,
|
||||
// so we must read 'maxSize + 1' bytes.
|
||||
return d_func()->unixSocket.readLine(data, maxSize + 1);
|
||||
}
|
||||
|
||||
qint64 QLocalSocket::skipData(qint64 maxSize)
|
||||
{
|
||||
return d_func()->unixSocket.skip(maxSize);
|
||||
|
|
|
|||
|
|
@ -238,6 +238,20 @@ void QLocalSocket::connectToServer(OpenMode openMode)
|
|||
emit connected();
|
||||
}
|
||||
|
||||
static qint64 tranformPipeReaderResult(qint64 res)
|
||||
{
|
||||
// QWindowsPipeReader's reading functions return error codes
|
||||
// that don't match what we need.
|
||||
switch (res) {
|
||||
case 0: // EOF -> transform to error
|
||||
return -1;
|
||||
case -2: // EWOULDBLOCK -> no error, just no bytes
|
||||
return 0;
|
||||
default:
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
// This is reading from the buffer
|
||||
qint64 QLocalSocket::readData(char *data, qint64 maxSize)
|
||||
{
|
||||
|
|
@ -246,17 +260,19 @@ qint64 QLocalSocket::readData(char *data, qint64 maxSize)
|
|||
if (!maxSize)
|
||||
return 0;
|
||||
|
||||
qint64 ret = d->pipeReader->read(data, maxSize);
|
||||
return tranformPipeReaderResult(d->pipeReader->read(data, maxSize));
|
||||
}
|
||||
|
||||
// QWindowsPipeReader::read() returns error codes that don't match what we need
|
||||
switch (ret) {
|
||||
case 0: // EOF -> transform to error
|
||||
return -1;
|
||||
case -2: // EWOULDBLOCK -> no error, just no bytes
|
||||
qint64 QLocalSocket::readLineData(char *data, qint64 maxSize)
|
||||
{
|
||||
Q_D(QLocalSocket);
|
||||
|
||||
if (!maxSize)
|
||||
return 0;
|
||||
default:
|
||||
return ret;
|
||||
}
|
||||
|
||||
// QIODevice::readLine() reserves space for the trailing '\0' byte,
|
||||
// so we must read 'maxSize + 1' bytes.
|
||||
return tranformPipeReaderResult(d->pipeReader->readLine(data, maxSize + 1));
|
||||
}
|
||||
|
||||
qint64 QLocalSocket::skipData(qint64 maxSize)
|
||||
|
|
|
|||
Loading…
Reference in New Issue