From b4ce49287f9f8407e89f1e4485cc166368306c77 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 11 Apr 2013 15:56:17 -0700 Subject: [PATCH] Make QBuffer::bytesAvailable() work We don't need to keep an internal QBuffer position, we can just use the one from QIODevice::pos(). It will keep track of goings ahead and backwards for us, plus it will make the default bytesAvailable() work out-of-the-box too. This error was reported on IRC. Change-Id: I8559e8ee56edaa01ca8732c1f1012082ebe3a3f2 Reviewed-by: Oswald Buddenhagen Reviewed-by: Robin Burchell --- src/corelib/io/qbuffer.cpp | 19 ++++----------- tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp | 23 ++++++++++++++++++- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/corelib/io/qbuffer.cpp b/src/corelib/io/qbuffer.cpp index 5975e01e767..4b7edd8481b 100644 --- a/src/corelib/io/qbuffer.cpp +++ b/src/corelib/io/qbuffer.cpp @@ -61,7 +61,6 @@ class QBufferPrivate : public QIODevicePrivate QByteArray *buf; QByteArray defaultBuf; - int ioIndex; virtual qint64 peek(char *data, qint64 maxSize); virtual QByteArray peek(qint64 maxSize); @@ -157,14 +156,12 @@ QBuffer::QBuffer() { Q_D(QBuffer); d->buf = &d->defaultBuf; - d->ioIndex = 0; } QBuffer::QBuffer(QByteArray *buf) : QIODevice(*new QBufferPrivate) { Q_D(QBuffer); d->buf = buf ? buf : &d->defaultBuf; - d->ioIndex = 0; d->defaultBuf.clear(); } #else @@ -180,7 +177,6 @@ QBuffer::QBuffer(QObject *parent) { Q_D(QBuffer); d->buf = &d->defaultBuf; - d->ioIndex = 0; } /*! @@ -206,7 +202,6 @@ QBuffer::QBuffer(QByteArray *byteArray, QObject *parent) Q_D(QBuffer); d->buf = byteArray ? byteArray : &d->defaultBuf; d->defaultBuf.clear(); - d->ioIndex = 0; } #endif @@ -253,7 +248,6 @@ void QBuffer::setBuffer(QByteArray *byteArray) d->buf = &d->defaultBuf; } d->defaultBuf.clear(); - d->ioIndex = 0; } /*! @@ -312,7 +306,6 @@ void QBuffer::setData(const QByteArray &data) return; } *d->buf = data; - d->ioIndex = 0; } /*! @@ -340,7 +333,6 @@ bool QBuffer::open(OpenMode flags) if ((flags & Truncate) == Truncate) d->buf->resize(0); - d->ioIndex = (flags & Append) == Append ? d->buf->size() : 0; return QIODevice::open(flags); } @@ -390,7 +382,6 @@ bool QBuffer::seek(qint64 pos) qWarning("QBuffer::seek: Invalid pos: %d", int(pos)); return false; } - d->ioIndex = int(pos); return QIODevice::seek(pos); } @@ -420,10 +411,9 @@ bool QBuffer::canReadLine() const qint64 QBuffer::readData(char *data, qint64 len) { Q_D(QBuffer); - if ((len = qMin(len, qint64(d->buf->size()) - d->ioIndex)) <= 0) + if ((len = qMin(len, qint64(d->buf->size()) - pos())) <= 0) return qint64(0); - memcpy(data, d->buf->constData() + d->ioIndex, len); - d->ioIndex += int(len); + memcpy(data, d->buf->constData() + pos(), len); return len; } @@ -433,7 +423,7 @@ qint64 QBuffer::readData(char *data, qint64 len) qint64 QBuffer::writeData(const char *data, qint64 len) { Q_D(QBuffer); - int extraBytes = d->ioIndex + len - d->buf->size(); + int extraBytes = pos() + len - d->buf->size(); if (extraBytes > 0) { // overflow int newSize = d->buf->size() + extraBytes; d->buf->resize(newSize); @@ -443,8 +433,7 @@ qint64 QBuffer::writeData(const char *data, qint64 len) } } - memcpy(d->buf->data() + d->ioIndex, (uchar *)data, int(len)); - d->ioIndex += int(len); + memcpy(d->buf->data() + pos(), (uchar *)data, int(len)); #ifndef QT_NO_QOBJECT d->writtenSinceLastEmit += len; diff --git a/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp b/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp index 4a43ea82014..3653fdb9e05 100644 --- a/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp +++ b/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp @@ -149,20 +149,25 @@ void tst_QBuffer::readBlock() const int arraySize = 10; char a[arraySize]; QBuffer b; + QCOMPARE(b.bytesAvailable(), (qint64) 0); // no data QCOMPARE(b.read(a, arraySize), (qint64) -1); // not opened QVERIFY(b.atEnd()); QByteArray ba; ba.resize(arraySize); b.setBuffer(&ba); + QCOMPARE(b.bytesAvailable(), (qint64) arraySize); b.open(QIODevice::WriteOnly); + QCOMPARE(b.bytesAvailable(), (qint64) arraySize); QTest::ignoreMessage(QtWarningMsg, "QIODevice::read: WriteOnly device"); QCOMPARE(b.read(a, arraySize), (qint64) -1); // no read access b.close(); b.open(QIODevice::ReadOnly); + QCOMPARE(b.bytesAvailable(), (qint64) arraySize); QCOMPARE(b.read(a, arraySize), (qint64) arraySize); QVERIFY(b.atEnd()); + QCOMPARE(b.bytesAvailable(), (qint64) 0); // up to 3.0.x reading beyond the end was an error while ok // this has been made consistent with other QIODevice sub classes in 3.1 @@ -172,10 +177,13 @@ void tst_QBuffer::readBlock() // read in two chunks b.close(); b.open(QIODevice::ReadOnly); + QCOMPARE(b.bytesAvailable(), (qint64) arraySize); QCOMPARE(b.read(a, arraySize/2), (qint64) arraySize/2); + QCOMPARE(b.bytesAvailable(), (qint64) arraySize/2); QCOMPARE(b.read(a + arraySize/2, arraySize - arraySize/2), (qint64)(arraySize - arraySize/2)); QVERIFY(b.atEnd()); + QCOMPARE(b.bytesAvailable(), (qint64) 0); } void tst_QBuffer::readBlockPastEnd() @@ -319,9 +327,12 @@ void tst_QBuffer::seekTest() buf.open(QIODevice::ReadWrite); QCOMPARE(buf.pos(), qint64(0)); + QCOMPARE(buf.bytesAvailable(), qint64(0)); QByteArray data = str.toLatin1(); QCOMPARE(buf.write( data.constData(), data.size() ), qint64(data.size())); + QCOMPARE(buf.bytesAvailable(), qint64(0)); // we're at the end + QCOMPARE(buf.size(), qint64(data.size())); QTest::ignoreMessage(QtWarningMsg, "QBuffer::seek: Invalid pos: -1"); DO_INVALID_SEEK(-1); @@ -336,6 +347,7 @@ void tst_QBuffer::seekTest() { char c = 'a'; QVERIFY(buf.seek(qint64(str.size()))); + QCOMPARE(buf.bytesAvailable(), qint64(0)); QCOMPARE(buf.read(&c, qint64(1)), qint64(0)); QCOMPARE(c, 'a'); QCOMPARE(buf.write(&c, qint64(1)), qint64(1)); @@ -347,6 +359,7 @@ void tst_QBuffer::seekTest() const int offset = 1; // any positive integer will do const qint64 pos = buf.size() + offset; QVERIFY(buf.seek(pos)); + QCOMPARE(buf.bytesAvailable(), qint64(0)); QCOMPARE(buf.pos(), pos); QVERIFY(!buf.getChar(&c)); QVERIFY(buf.seek(pos - 1)); @@ -533,7 +546,11 @@ void tst_QBuffer::readLineBoundaries() lineByLine.append(buffer.readLine()); buffer.seek(0); - QCOMPARE(lineByLine, buffer.readAll()); + QCOMPARE(buffer.bytesAvailable(), lineByLine.size()); + + QByteArray all = buffer.readAll(); + QCOMPARE(all.size(), lineByLine.size()); + QCOMPARE(all, lineByLine); } // Test that any character in a buffer can be read and pushed back. @@ -548,7 +565,9 @@ void tst_QBuffer::getAndUngetChar() // Take a copy of the data held in the buffer buffer.seek(0); + QCOMPARE(buffer.bytesAvailable(), buffer.size()); QByteArray data = buffer.readAll(); + QCOMPARE(buffer.bytesAvailable(), qint64(0)); // Get and unget each character in order for (qint64 i = 0; i < buffer.size(); ++i) { @@ -570,7 +589,9 @@ void tst_QBuffer::getAndUngetChar() // Verify that the state of the buffer still matches the original data. buffer.seek(0); + QCOMPARE(buffer.bytesAvailable(), data.size()); QCOMPARE(buffer.readAll(), data); + QCOMPARE(buffer.bytesAvailable(), qint64(0)); } void tst_QBuffer::writeAfterQByteArrayResize()