Simplify QIODevice::readAll()
The previous implementation performed reading in two steps: - flush the internal buffer - request the rest of the data by calling the read() function It would resize the result buffer separately at each step, even if its total size was known in advance. This is important for random-access devices, which may have big chunks of cached data. Also, possible failures during the second step would cause a loss of result data from the first stage. This patch eliminates the initial flush, which improves performance and prevents data loss. Change-Id: I3da4c24ee33dca6afc4ba519d078b86068de43b9 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
This commit is contained in:
parent
657e8ffb9e
commit
5c0ff27d9b
@ -992,40 +992,31 @@ QByteArray QIODevice::readAll()
|
||||
#endif
|
||||
|
||||
QByteArray result;
|
||||
qint64 readBytes = 0;
|
||||
const bool sequential = d->isSequential();
|
||||
|
||||
// flush internal read buffer
|
||||
if (!(d->openMode & Text) && !d->buffer.isEmpty()) {
|
||||
if (d->buffer.size() >= MaxByteArraySize)
|
||||
return QByteArray();
|
||||
result = d->buffer.readAll();
|
||||
readBytes = result.size();
|
||||
if (!sequential)
|
||||
d->pos += readBytes;
|
||||
}
|
||||
|
||||
qint64 theSize;
|
||||
if (sequential || (theSize = size()) == 0) {
|
||||
qint64 readBytes = (d->isSequential() ? Q_INT64_C(0) : size());
|
||||
if (readBytes == 0) {
|
||||
// Size is unknown, read incrementally.
|
||||
qint64 readChunkSize = qMax(d->buffer.size(), QIODEVICE_BUFFERSIZE);
|
||||
qint64 readResult;
|
||||
do {
|
||||
if (readBytes + QIODEVICE_BUFFERSIZE >= MaxByteArraySize) {
|
||||
if (readBytes + readChunkSize >= MaxByteArraySize) {
|
||||
// If resize would fail, don't read more, return what we have.
|
||||
break;
|
||||
}
|
||||
result.resize(readBytes + QIODEVICE_BUFFERSIZE);
|
||||
readResult = read(result.data() + readBytes, QIODEVICE_BUFFERSIZE);
|
||||
if (readResult > 0 || readBytes == 0)
|
||||
result.resize(readBytes + readChunkSize);
|
||||
readResult = read(result.data() + readBytes, readChunkSize);
|
||||
if (readResult > 0 || readBytes == 0) {
|
||||
readBytes += readResult;
|
||||
readChunkSize = QIODEVICE_BUFFERSIZE;
|
||||
}
|
||||
} while (readResult > 0);
|
||||
} else {
|
||||
// Read it all in one go.
|
||||
// If resize fails, don't read anything.
|
||||
if (readBytes + theSize - d->pos >= MaxByteArraySize)
|
||||
readBytes -= d->pos;
|
||||
if (readBytes >= MaxByteArraySize)
|
||||
return QByteArray();
|
||||
result.resize(int(readBytes + theSize - d->pos));
|
||||
readBytes += read(result.data() + readBytes, result.size() - readBytes);
|
||||
result.resize(readBytes);
|
||||
readBytes = read(result.data(), readBytes);
|
||||
}
|
||||
|
||||
if (readBytes <= 0)
|
||||
|
Loading…
x
Reference in New Issue
Block a user