summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Kawano <808christian@gmail.com>2011-03-01 13:12:37 +0100
committerOlivier Goffart <olivier.goffart@nokia.com>2011-03-01 13:20:33 +0100
commit17a4f332f0d416af842145f0ebc7f2ebe7f33527 (patch)
tree822b21b8f3036c28000fc90af54899dc6c0e639b
parentcb042e8dcc836a89919d7c048698154f2c423307 (diff)
downloadqt4-tools-17a4f332f0d416af842145f0ebc7f2ebe7f33527.tar.gz
Fix QTextStream::pos() causes buffer offset issues on large text files.
When reading large files that are greater in size than the TEXTSTREAM_BUFFERSIZE buffer, calling pos() caused erroneous buffer positioning. The cause of this was QTextStreamPrivate::readBufferOffset value being updated, but QTextStreamPrivate::readConverterSavedStateOffset was not. Usually, if pos() is called, it is called multiple times. Since QTextStreamPrivate::readConverterSavedStateOffset was never reset, QTextStreamPrivate::readBufferOffset would accumulate the wrong position and QTextStreamPrivate::consume() will 'discard' the wrong number of bytes from the buffer. Task-number: QTBUG-9814 Merge-request: 2569 Reviewed-by: Olivier Goffart <olivier.goffart@nokia.com>
-rw-r--r--src/corelib/io/qtextstream.cpp1
-rw-r--r--tests/auto/qtextstream/tst_qtextstream.cpp36
2 files changed, 37 insertions, 0 deletions
diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp
index b630502616..a5837cbeb5 100644
--- a/src/corelib/io/qtextstream.cpp
+++ b/src/corelib/io/qtextstream.cpp
@@ -1264,6 +1264,7 @@ qint64 QTextStream::pos() const
return qint64(-1);
}
thatd->readBufferOffset = oldReadBufferOffset;
+ thatd->readConverterSavedStateOffset = 0;
// Return the device position.
return d->device->pos();
diff --git a/tests/auto/qtextstream/tst_qtextstream.cpp b/tests/auto/qtextstream/tst_qtextstream.cpp
index 99f25563b7..2d7c24d238 100644
--- a/tests/auto/qtextstream/tst_qtextstream.cpp
+++ b/tests/auto/qtextstream/tst_qtextstream.cpp
@@ -208,6 +208,7 @@ private slots:
void seek();
void pos();
void pos2();
+ void pos3LargeFile();
void readStdin();
void readAllFromStdin();
void readLineFromStdin();
@@ -1502,6 +1503,41 @@ void tst_QTextStream::pos2()
}
// ------------------------------------------------------------------------------
+void tst_QTextStream::pos3LargeFile()
+{
+ {
+ QFile file(TestFileName);
+ file.open(QIODevice::WriteOnly | QIODevice::Text);
+ QTextStream out( &file );
+ // NOTE: The unusual spacing is to ensure non-1-character whitespace.
+ QString lineString = " 0 1 2\t3 4\t \t5 6 7 8 9 \n";
+ // Approximate 50kb text file
+ const int NbLines = (50*1024) / lineString.length() + 1;
+ for (int line = 0; line < NbLines; ++line)
+ out << lineString;
+ // File is automatically flushed and closed on destruction.
+ }
+ QFile file(TestFileName);
+ file.open(QIODevice::ReadOnly | QIODevice::Text);
+ QTextStream in( &file );
+ const int testValues[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+ int value;
+ while (true) {
+ in.pos();
+ for ( int i = 0; i < 10; ++i ) {
+ in >> value;
+ if (in.status() != QTextStream::Ok) {
+ // End case, i == 0 && eof reached.
+ QCOMPARE(i, 0);
+ QCOMPARE(in.status(), QTextStream::ReadPastEnd);
+ return;
+ }
+ QCOMPARE(value, testValues[i]);
+ }
+ }
+}
+
+// ------------------------------------------------------------------------------
void tst_QTextStream::readStdin()
{
#if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)