QIODevice: do not change the 'pos' member for sequential devices
Concept of 'current position' exists only for random-access devices. As documented, for sequential devices QIODevice::pos() must always return 0. Prevent a modification of the internal 'pos' member in QIODevice::readAll() method to follow this rule. Change-Id: Ida2ee6a629ccfc3068d62f95ab1064ada13fdda5 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
6dcbaa487d
commit
f40cf77b0f
@ -972,6 +972,7 @@ QByteArray QIODevice::readAll()
|
|||||||
|
|
||||||
QByteArray result;
|
QByteArray result;
|
||||||
qint64 readBytes = 0;
|
qint64 readBytes = 0;
|
||||||
|
const bool sequential = d->isSequential();
|
||||||
|
|
||||||
// flush internal read buffer
|
// flush internal read buffer
|
||||||
if (!(d->openMode & Text) && !d->buffer.isEmpty()) {
|
if (!(d->openMode & Text) && !d->buffer.isEmpty()) {
|
||||||
@ -979,11 +980,12 @@ QByteArray QIODevice::readAll()
|
|||||||
return QByteArray();
|
return QByteArray();
|
||||||
result = d->buffer.readAll();
|
result = d->buffer.readAll();
|
||||||
readBytes = result.size();
|
readBytes = result.size();
|
||||||
d->pos += readBytes;
|
if (!sequential)
|
||||||
|
d->pos += readBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 theSize;
|
qint64 theSize;
|
||||||
if (d->isSequential() || (theSize = size()) == 0) {
|
if (sequential || (theSize = size()) == 0) {
|
||||||
// Size is unknown, read incrementally.
|
// Size is unknown, read incrementally.
|
||||||
qint64 readResult;
|
qint64 readResult;
|
||||||
do {
|
do {
|
||||||
|
@ -58,6 +58,7 @@ private slots:
|
|||||||
void readLine2();
|
void readLine2();
|
||||||
|
|
||||||
void peekBug();
|
void peekBug();
|
||||||
|
void readAllKeepPosition();
|
||||||
};
|
};
|
||||||
|
|
||||||
void tst_QIODevice::initTestCase()
|
void tst_QIODevice::initTestCase()
|
||||||
@ -584,5 +585,48 @@ void tst_QIODevice::peekBug()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SequentialReadBuffer : public QIODevice
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SequentialReadBuffer(const char *data) : QIODevice(), buf(data), offset(0) { }
|
||||||
|
|
||||||
|
bool isSequential() const Q_DECL_OVERRIDE { return true; }
|
||||||
|
const QByteArray &buffer() const { return buf; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
qint64 readData(char *data, qint64 maxSize) Q_DECL_OVERRIDE
|
||||||
|
{
|
||||||
|
maxSize = qMin(maxSize, qint64(buf.size() - offset));
|
||||||
|
memcpy(data, buf.constData() + offset, maxSize);
|
||||||
|
offset += maxSize;
|
||||||
|
return maxSize;
|
||||||
|
}
|
||||||
|
qint64 writeData(const char * /* data */, qint64 /* maxSize */) Q_DECL_OVERRIDE
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QByteArray buf;
|
||||||
|
int offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Test readAll() on position change for sequential device
|
||||||
|
void tst_QIODevice::readAllKeepPosition()
|
||||||
|
{
|
||||||
|
SequentialReadBuffer buffer("Hello world!");
|
||||||
|
buffer.open(QIODevice::ReadOnly);
|
||||||
|
char c;
|
||||||
|
|
||||||
|
QVERIFY(buffer.getChar(&c));
|
||||||
|
QCOMPARE(buffer.pos(), qint64(0));
|
||||||
|
buffer.ungetChar(c);
|
||||||
|
QCOMPARE(buffer.pos(), qint64(0));
|
||||||
|
|
||||||
|
QByteArray resultArray = buffer.readAll();
|
||||||
|
QCOMPARE(buffer.pos(), qint64(0));
|
||||||
|
QCOMPARE(resultArray, buffer.buffer());
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_QIODevice)
|
QTEST_MAIN(tst_QIODevice)
|
||||||
#include "tst_qiodevice.moc"
|
#include "tst_qiodevice.moc"
|
||||||
|
Loading…
Reference in New Issue
Block a user