summaryrefslogtreecommitdiff
path: root/src/corelib/io/qfsfileengine_unix.cpp
diff options
context:
space:
mode:
authorShane Kearns <shane.kearns@accenture.com>2010-10-18 15:15:39 +0100
committerShane Kearns <shane.kearns@accenture.com>2010-10-19 09:36:18 +0100
commit366d2ed09ebf5aa27171a46d723497e5aaa5dd06 (patch)
treecacb6df98c2f147fe720e6ac37f95259da9f1788 /src/corelib/io/qfsfileengine_unix.cpp
parent2e35e9c1eabe667798572457c61e1d1d1f373317 (diff)
downloadqt4-tools-366d2ed09ebf5aa27171a46d723497e5aaa5dd06.tar.gz
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/corelib/io/qfsfileengine_unix.cpp')
-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 caf5f4c278..96946d69a3 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;