src/corelib/io/qfile.cpp
changeset 19 fcece45ef507
parent 18 2f34d5167611
--- a/src/corelib/io/qfile.cpp	Fri Apr 16 15:50:13 2010 +0300
+++ b/src/corelib/io/qfile.cpp	Mon May 03 13:17:34 2010 +0300
@@ -62,21 +62,25 @@
 
 static QByteArray locale_encode(const QString &f)
 {
-#ifndef Q_OS_DARWIN
-    return f.toLocal8Bit();
-#else
+#if defined(Q_OS_DARWIN)
     // Mac always expects UTF-8... and decomposed...
     return f.normalized(QString::NormalizationForm_D).toUtf8();
+#elif defined(Q_OS_SYMBIAN)
+    return f.toUtf8();
+#else
+    return f.toLocal8Bit();
 #endif
 }
 
 static QString locale_decode(const QByteArray &f)
 {
-#ifndef Q_OS_DARWIN
-    return QString::fromLocal8Bit(f);
-#else
+#if defined(Q_OS_DARWIN)
     // Mac always gives us UTF-8 and decomposed, we want that composed...
     return QString::fromUtf8(f).normalized(QString::NormalizationForm_C);
+#elif defined(Q_OS_SYMBIAN)
+    return QString::fromUtf8(f);
+#else
+    return QString::fromLocal8Bit(f);
 #endif
 }
 
@@ -86,7 +90,8 @@
 
 QFilePrivate::QFilePrivate()
     : fileEngine(0), lastWasWrite(false),
-      writeBuffer(QFILE_WRITEBUFFER_SIZE), error(QFile::NoError)
+      writeBuffer(QFILE_WRITEBUFFER_SIZE), error(QFile::NoError),
+      cachedSize(0)
 {
 }
 
@@ -1253,8 +1258,10 @@
         seek(sz);
     if(d->fileEngine->setSize(sz)) {
         unsetError();
+        d->cachedSize = sz;
         return true;
     }
+    d->cachedSize = 0;
     d->setError(QFile::ResizeError, d->fileEngine->errorString());
     return false;
 }
@@ -1416,7 +1423,8 @@
     Q_D(const QFile);
     if (!d->ensureFlushed())
         return 0;
-    return fileEngine()->size();
+    d->cachedSize = fileEngine()->size();
+    return d->cachedSize;
 }
 
 /*!
@@ -1442,16 +1450,16 @@
 {
     Q_D(const QFile);
 
+    // If there's buffered data left, we're not at the end.
+    if (!d->buffer.isEmpty())
+        return false;
+
     if (!isOpen())
         return true;
 
     if (!d->ensureFlushed())
         return false;
 
-    // If there's buffered data left, we're not at the end.
-    if (!d->buffer.isEmpty())
-        return false;
-
     // If the file engine knows best, say what it says.
     if (d->fileEngine->supportsExtension(QAbstractFileEngine::AtEndExtension)) {
         // Check if the file engine supports AtEndExtension, and if it does,
@@ -1459,6 +1467,11 @@
         return d->fileEngine->atEnd();
     }
 
+    // if it looks like we are at the end, or if size is not cached,
+    // fall through to bytesAvailable() to make sure.
+    if (pos() < d->cachedSize)
+        return false;
+
     // Fall back to checking how much is available (will stat files).
     return bytesAvailable() == 0;
 }
@@ -1498,12 +1511,21 @@
     if (!d->ensureFlushed())
         return -1;
 
-    if (d->fileEngine->supportsExtension(QAbstractFileEngine::FastReadLineExtension))
-        return d->fileEngine->readLine(data, maxlen);
+    qint64 read;
+    if (d->fileEngine->supportsExtension(QAbstractFileEngine::FastReadLineExtension)) {
+        read = d->fileEngine->readLine(data, maxlen);
+    } else {
+        // Fall back to QIODevice's readLine implementation if the engine
+        // cannot do it faster.
+        read = QIODevice::readLineData(data, maxlen);
+    }
 
-    // Fall back to QIODevice's readLine implementation if the engine
-    // cannot do it faster.
-    return QIODevice::readLineData(data, maxlen);
+    if (read < maxlen) {
+        // failed to read all requested, may be at the end of file, stop caching size so that it's rechecked
+        d->cachedSize = 0;
+    }
+
+    return read;
 }
 
 /*!
@@ -1524,6 +1546,12 @@
             err = QFile::ReadError;
         d->setError(err, d->fileEngine->errorString());
     }
+
+    if (read < len) {
+        // failed to read all requested, may be at the end of file, stop caching size so that it's rechecked
+        d->cachedSize = 0;
+    }
+
     return read;
 }