summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorShane Kearns <shane.kearns@accenture.com>2010-10-18 14:15:39 (GMT)
committerShane Kearns <shane.kearns@accenture.com>2010-10-19 08:36:18 (GMT)
commit366d2ed09ebf5aa27171a46d723497e5aaa5dd06 (patch)
treecacb6df98c2f147fe720e6ac37f95259da9f1788 /src
parent2e35e9c1eabe667798572457c61e1d1d1f373317 (diff)
downloadQt-366d2ed09ebf5aa27171a46d723497e5aaa5dd06.zip
Qt-366d2ed09ebf5aa27171a46d723497e5aaa5dd06.tar.gz
Qt-366d2ed09ebf5aa27171a46d723497e5aaa5dd06.tar.bz2
Implement seek beyond end of file for symbian
On Symbian, the Seek() function clamps to the end of file position if a position beyond the end of file is given. Also the write functions which take a position silently append at the end of file position if asked to write to a start position beyond EOF. To avoid this behaviour, we don't use seek but rather maintain our own cursor position. When writing, we check if the cursor is beyond EOF and if so extend the file using SetSize() before writing. Reviewed-By: joao
Diffstat (limited to 'src')
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp51
1 files changed, 26 insertions, 25 deletions
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp
index caf5f4c..96946d6 100644
--- a/src/corelib/io/qfsfileengine_unix.cpp
+++ b/src/corelib/io/qfsfileengine_unix.cpp
@@ -382,12 +382,13 @@ qint64 QFSFileEnginePrivate::nativeRead(char *data, qint64 len)
return -1;
}
TPtr8 ptr(reinterpret_cast<TUint8*>(data), static_cast<TInt>(len));
- TInt r = symbianFile.Read(ptr);
+ TInt r = symbianFile.Read(symbianFilePos, ptr);
if (r != KErrNone)
{
q->setError(QFile::ReadError, QSystemError(r, QSystemError::NativeError).toString());
return -1;
}
+ symbianFilePos += ptr.Length();
return qint64(ptr.Length());
}
#endif
@@ -467,12 +468,28 @@ qint64 QFSFileEnginePrivate::nativeWrite(const char *data, qint64 len)
return -1;
}
const TPtrC8 ptr(reinterpret_cast<const TUint8*>(data), static_cast<TInt>(len));
- TInt r = symbianFile.Write(ptr);
- if (r != KErrNone)
- {
+#ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
+ TInt64 eofpos = 0;
+#else
+ TInt eofpos = 0;
+#endif
+ //The end of file position is not cached because QFile is read/write sharable, therefore another
+ //process may have altered the file size.
+ TInt r = symbianFile.Seek(ESeekEnd, eofpos);
+ if (r == KErrNone && symbianFilePos > eofpos) {
+ //seek position is beyond end of file so file needs to be extended before write.
+ //note that SetSize does not zero-initialise (c.f. posix lseek)
+ r = symbianFile.SetSize(symbianFilePos);
+ }
+ if (r == KErrNone) {
+ //write to specific position in the file (i.e. use our own cursor rather than calling seek)
+ r = symbianFile.Write(symbianFilePos, ptr);
+ }
+ if (r != KErrNone) {
q->setError(QFile::WriteError, QSystemError(r, QSystemError::NativeError).toString());
return -1;
}
+ symbianFilePos += len;
return len;
}
#endif
@@ -487,17 +504,7 @@ qint64 QFSFileEnginePrivate::nativePos() const
#ifdef Q_OS_SYMBIAN
const Q_Q(QFSFileEngine);
if (symbianFile.SubSessionHandle()) {
-#ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
- qint64 pos = 0;
-#else
- TInt pos = 0;
-#endif
- TInt err = symbianFile.Seek(ESeekCurrent, pos);
- if(err != KErrNone) {
- const_cast<QFSFileEngine*>(q)->setError(QFile::PositionError, QSystemError(err, QSystemError::NativeError).toString());
- return -1;
- }
- return pos;
+ return symbianFilePos;
}
#endif
return posFdFh();
@@ -511,21 +518,13 @@ bool QFSFileEnginePrivate::nativeSeek(qint64 pos)
#ifdef Q_OS_SYMBIAN
Q_Q(QFSFileEngine);
if (symbianFile.SubSessionHandle()) {
-#ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
- TInt r = symbianFile.Seek(ESeekStart, pos);
-#else
+#ifndef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
if(pos > KMaxTInt) {
q->setError(QFile::PositionError, QLatin1String("Maximum 2GB file position on this platform"));
return false;
}
- TInt pos32(pos);
- TInt r = symbianFile.Seek(ESeekStart, pos32);
#endif
- if (r != KErrNone)
- {
- q->setError(QFile::PositionError, QSystemError(r, QSystemError::NativeError).toString());
- return false;
- }
+ symbianFilePos = pos;
return true;
}
#endif
@@ -867,6 +866,8 @@ bool QFSFileEngine::setSize(qint64 size)
if (d->symbianFile.SubSessionHandle()) {
TInt err = d->symbianFile.SetSize(size);
ret = (err == KErrNone);
+ if (ret && d->symbianFilePos > size)
+ d->symbianFilePos = size;
}
else if (d->fd != -1)
ret = QT_FTRUNCATE(d->fd, size) == 0;