return true;
}
-bool FileSystem::openFileSharedRead(QFile* file, QString* error)
+bool FileSystem::openAndSeekFileSharedRead(QFile* file, QString* errorOrNull, qint64 seek)
{
- bool ok = false;
- if (error) {
- error->clear();
- }
+ QString errorDummy;
+ // avoid many if (errorOrNull) later.
+ QString& error = errorOrNull ? *errorOrNull : errorDummy;
+ error.clear();
#ifdef Q_OS_WIN
//
// Bail out on error.
if (fileHandle == INVALID_HANDLE_VALUE) {
- if (error) {
- *error = qt_error_string();
- }
+ error = qt_error_string();
return false;
}
// the fd the handle will be closed too.
int fd = _open_osfhandle((intptr_t)fileHandle, _O_RDONLY);
if (fd == -1) {
- if (error) {
- *error = "could not make fd from handle";
- }
+ error = "could not make fd from handle";
+ return false;
+ }
+ if (!file->open(fd, QIODevice::ReadOnly, QFile::AutoCloseHandle)) {
+ error = file->errorString();
+ return false;
+ }
+
+ // Seek to the right spot
+ LARGE_INTEGER *li = reinterpret_cast<LARGE_INTEGER*>(&seek);
+ DWORD newFilePointer = SetFilePointer(fileHandle, li->LowPart, &li->HighPart, FILE_BEGIN);
+ if (newFilePointer == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
+ error = qt_error_string();
return false;
}
- ok = file->open(fd, QIODevice::ReadOnly, QFile::AutoCloseHandle);
+
+ return true;
#else
- ok = file->open(QFile::ReadOnly);
-#endif
- if (! ok && error) {
- *error = file->errorString();
+ if (!file->open(QFile::ReadOnly)) {
+ error = file->errorString();
+ return false;
}
- return ok;
+ if (!file->seek(seek)) {
+ error = file->errorString();
+ return false;
+ }
+ return true;
+#endif
}
#ifdef Q_OS_WIN
QString *errorString);
/**
- * Replacement for QFile::open(ReadOnly) that sets a more permissive sharing mode
- * on Windows.
+ * Replacement for QFile::open(ReadOnly) followed by a seek().
+ * This version sets a more permissive sharing mode on Windows.
*
* Warning: The resuting file may have an empty fileName and be unsuitable for use
- * with QFileInfo!
+ * with QFileInfo! Calling seek() on the QFile with >32bit signed values will fail!
*/
-bool openFileSharedRead(QFile* file, QString* error);
+bool openAndSeekFileSharedRead(QFile* file, QString* error, qint64 seek);
#ifdef Q_OS_WIN
/**
QFile file(fileName);
QString openError;
- if (!FileSystem::openFileSharedRead(&file, &openError)) {
+ if (!FileSystem::openAndSeekFileSharedRead(&file, &openError, start)) {
setErrorString(openError);
return false;
}
- size = qMin(FileSystem::getSize(fileName), size);
+ size = qBound(0ll, size, FileSystem::getSize(fileName) - start);
_data.resize(size);
- if (!file.seek(start)) {
- setErrorString(file.errorString());
- return false;
- }
auto read = file.read(_data.data(), size);
if (read != size) {
setErrorString(file.errorString());