Commit 13922740 authored by Michael Reeves's avatar Michael Reeves

fix fastFileComparison for network files

BUG: 403089
FIXED-IN:1.7.90

This fixes the handling of tempfiles created during network comparsion.
Previously these would be accessed by name alone causing an error.
Now QTemparyFile is used were needed.
Direct use of QFile for file operations is now depriated as this is
diffcualt to get right given the use of a tempFile in some cases.
*open,close, read routines created in FileAccess to currectly handle the
tempfile logic and error messages.
*Fix this issue exists within FileAccess::readFile() as well.
parent ca6b94cb
......@@ -717,49 +717,24 @@ bool DirectoryMergeWindow::DirectoryMergeWindowPrivate::fastFileComparison(
}
}
QString fileName1 = fi1.absoluteFilePath();
QString fileName2 = fi2.absoluteFilePath();
if(!fi1.createLocalCopy())
{
status = i18n("Creating temp copy of %1 failed.", fileName1);
return bEqual;
}
if(!fi2.createLocalCopy())
{
status = i18n("Creating temp copy of %1 failed.", fileName2);
return bEqual;
}
//This is what the old TempRemover class would do. Should probally get path to temp file not just the name.
if(!fi1.isLocal())
fileName1 = fi1.getTempName();
if(!fi2.isLocal())
fileName2 = fi2.getTempName();
std::vector<char> buf1(100000);
std::vector<char> buf2(buf1.size());
QFile file1(fileName1);
if(!file1.open(QIODevice::ReadOnly))
if(!fi1.open(QIODevice::ReadOnly))
{
status = i18n("Opening %1 failed. %2", fileName1, file1.errorString());
status = fi1.errorString();
return bEqual;
}
QFile file2(fileName2);
if(!file2.open(QIODevice::ReadOnly))
if(!fi2.open(QIODevice::ReadOnly))
{
status = i18n("Opening %1 failed. %2", fileName2, file2.errorString());
status = fi2.errorString();
return bEqual;
}
pp.setInformation(i18n("Comparing file..."), 0, false);
typedef qint64 t_FileSize;
t_FileSize fullSize = file1.size();
t_FileSize fullSize = fi1.size();
t_FileSize sizeLeft = fullSize;
pp.setMaxNofSteps(fullSize / buf1.size());
......@@ -767,15 +742,15 @@ bool DirectoryMergeWindow::DirectoryMergeWindowPrivate::fastFileComparison(
while(sizeLeft > 0 && !pp.wasCancelled())
{
qint64 len = std::min(sizeLeft, (t_FileSize)buf1.size());
if(len != file1.read(&buf1[0], len))
if(len != fi1.read(&buf1[0], len))
{
status = i18n("Error reading from %1", fileName1);
status = fi1.errorString();
return bEqual;
}
if(len != file2.read(&buf2[0], len))
if(len != fi2.read(&buf2[0], len))
{
status = i18n("Error reading from %1", fileName2);
status = fi2.errorString();;
return bEqual;
}
......
......@@ -14,6 +14,7 @@
#include "Utils.h"
#include <QDir>
#include <QFile>
#include <QtMath>
#include <QProcess>
#include <QRegExp>
......@@ -71,6 +72,7 @@ void FileAccess::reset()
m_pParent = nullptr;
tmpFile.clear();
tmpFile = QSharedPointer<QTemporaryFile>(new QTemporaryFile());
realFile = nullptr;
}
FileAccess::~FileAccess()
......@@ -172,6 +174,7 @@ void FileAccess::loadData()
#endif
}
realFile = QSharedPointer<QFile>::create(absoluteFilePath());
m_bValidData = true;
}
......@@ -447,7 +450,7 @@ QDateTime FileAccess::lastModified() const
return m_modificationTime;
}
bool FileAccess::interruptableReadFile(QFile& f, void* pDestBuffer, qint64 maxLength)
bool FileAccess::interruptableReadFile(void* pDestBuffer, qint64 maxLength)
{
ProgressProxy pp;
const qint64 maxChunkSize = 100000;
......@@ -456,7 +459,7 @@ bool FileAccess::interruptableReadFile(QFile& f, void* pDestBuffer, qint64 maxLe
while(i < maxLength)
{
qint64 nextLength = std::min(maxLength - i, maxChunkSize);
qint64 reallyRead = f.read((char*)pDestBuffer + i, nextLength);
qint64 reallyRead = read((char*)pDestBuffer + i, nextLength);
if(reallyRead != nextLength)
{
return false;
......@@ -476,18 +479,10 @@ bool FileAccess::readFile(void* pDestBuffer, qint64 maxLength)
if(!isNormal())
return true;
if(!m_localCopy.isEmpty())
{
QFile f(m_localCopy);
if(f.open(QIODevice::ReadOnly))
return interruptableReadFile(f, pDestBuffer, maxLength); // maxLength == f.read( (char*)pDestBuffer, maxLength );
}
else if(isLocal())
if(isLocal() || !m_localCopy.isEmpty())
{
QFile f(absoluteFilePath());
if(f.open(QIODevice::ReadOnly))
return interruptableReadFile(f, pDestBuffer, maxLength); //maxLength == f.read( (char*)pDestBuffer, maxLength );
if(open(QIODevice::ReadOnly))
return interruptableReadFile( pDestBuffer, maxLength); // maxLength == f.read( (char*)pDestBuffer, maxLength );
}
else
{
......@@ -585,6 +580,62 @@ QString FileAccess::getTempName() const
return m_localCopy;
}
const QString FileAccess::errorString() const
{
return getStatusText();
}
bool FileAccess::open(const QFile::OpenMode flags)
{
bool result;
result = createLocalCopy();
if(!result){
setStatusText(i18n("Creating temp copy of %1 failed.", absoluteFilePath()));
return result;
}
if(m_localCopy.isEmpty() && realFile != nullptr)
{
bool r = realFile->open(flags);
setStatusText(i18n("Opening %1 failed. %2", absoluteFilePath(), realFile->errorString()));
return r;
}
bool r = tmpFile->open();
setStatusText(i18n("Opening %1 failed. %2", tmpFile->fileName(), tmpFile->errorString()));
return r;
}
qint64 FileAccess::read(char *data, const qint64 maxlen)
{
qint64 len = 0;
if(m_localCopy.isEmpty() && realFile != nullptr)
{
len = realFile->read(data, maxlen);
}
else
len = tmpFile->read(data, maxlen);
if(len != maxlen)
{
setStatusText(i18n("Error reading from %1", absoluteFilePath()));
}
return len;
}
void FileAccess::close()
{
if(m_localCopy.isEmpty() && realFile != nullptr)
{
realFile->close();
}
tmpFile->close();
}
bool FileAccess::createLocalCopy()
{
if(isLocal() || !m_localCopy.isEmpty())
......@@ -665,7 +716,7 @@ qint64 FileAccess::sizeForReading()
return size();
}
QString FileAccess::getStatusText()
QString FileAccess::getStatusText() const
{
return m_statusText;
}
......
......@@ -15,6 +15,7 @@
#include "ProgressProxyExtender.h"
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QDateTime>
#include <QSharedPointer>
......@@ -90,7 +91,7 @@ public:
static bool symLink( const QString& linkTarget, const QString& linkLocation );
void addPath( const QString& txt );
QString getStatusText();
QString getStatusText() const;
FileAccess* parent() const; // !=0 for listDir-results, but only valid if the parent was not yet destroyed.
......@@ -101,6 +102,13 @@ public:
QDir getBaseDirectory() const { return m_baseDir; }
bool open(const QFile::OpenMode flags);
qint64 read(char *data, const qint64 maxlen);
void close();
const QString errorString() const;
private:
friend class FileAccessJobHandler;
void setUdsEntry(const KIO::UDSEntry& e);
......@@ -108,7 +116,7 @@ public:
void reset();
bool interruptableReadFile(QFile& f, void* pDestBuffer, qint64 maxLength);
bool interruptableReadFile(void* pDestBuffer, qint64 maxLength);
QUrl m_url;
bool m_bValidData;
......@@ -121,7 +129,8 @@ public:
QString m_linkTarget;
QString m_name;
QString m_localCopy;
QSharedPointer<QTemporaryFile> tmpFile;
QSharedPointer<QTemporaryFile> tmpFile = nullptr;
QSharedPointer<QFile> realFile = nullptr;
qint64 m_size;
QDateTime m_modificationTime;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment