diff options
author | Alex Trotsenko <alex1973tr@gmail.com> | 2015-05-18 17:58:49 +0300 |
---|---|---|
committer | Alex Trotsenko <alex1973tr@gmail.com> | 2015-06-20 08:56:14 +0000 |
commit | 5c0ff27d9b7553f3584a93d672b0cc48b110c1ad (patch) | |
tree | 51217ff7dff6565917640873d85bba36078dda4f /src/corelib/io/qiodevice.cpp | |
parent | 657e8ffb9ecdf451b9db85dd5dfbc820d2ac3ca5 (diff) |
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>
Diffstat (limited to 'src/corelib/io/qiodevice.cpp')
-rw-r--r-- | src/corelib/io/qiodevice.cpp | 35 |
1 files changed, 13 insertions, 22 deletions
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index 1b3c58f8f9..f0d3250cd2 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -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) |