summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qiodevice.cpp
diff options
context:
space:
mode:
authorAlex Trotsenko <alex1973tr@gmail.com>2015-05-18 17:58:49 +0300
committerAlex Trotsenko <alex1973tr@gmail.com>2015-06-20 08:56:14 +0000
commit5c0ff27d9b7553f3584a93d672b0cc48b110c1ad (patch)
tree51217ff7dff6565917640873d85bba36078dda4f /src/corelib/io/qiodevice.cpp
parent657e8ffb9ecdf451b9db85dd5dfbc820d2ac3ca5 (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.cpp35
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)