mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-23 13:35:58 +03:00
Checksums: Add back QIODevice api
Because the winvfs plugin needs it. But be more careful about the device's lifetime this time.
This commit is contained in:
parent
18e1098e38
commit
bade7aedc6
2 changed files with 57 additions and 7 deletions
|
@ -18,6 +18,7 @@
|
|||
#include "config.h"
|
||||
#include "filesystembase.h"
|
||||
#include "common/checksums.h"
|
||||
#include "asserts.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
#include <qtconcurrentrun.h>
|
||||
|
@ -225,21 +226,42 @@ QByteArray ComputeChecksum::checksumType() const
|
|||
void ComputeChecksum::start(const QString &filePath)
|
||||
{
|
||||
qCInfo(lcChecksums) << "Computing" << checksumType() << "checksum of" << filePath << "in a thread";
|
||||
startImpl(std::make_unique<QFile>(filePath));
|
||||
}
|
||||
|
||||
void ComputeChecksum::start(std::unique_ptr<QIODevice> device)
|
||||
{
|
||||
ENFORCE(device);
|
||||
qCInfo(lcChecksums) << "Computing" << checksumType() << "checksum of device" << device.get() << "in a thread";
|
||||
ASSERT(!device->parent());
|
||||
|
||||
startImpl(std::move(device));
|
||||
}
|
||||
|
||||
void ComputeChecksum::startImpl(std::unique_ptr<QIODevice> device)
|
||||
{
|
||||
connect(&_watcher, &QFutureWatcherBase::finished,
|
||||
this, &ComputeChecksum::slotCalculationDone,
|
||||
Qt::UniqueConnection);
|
||||
|
||||
// Capturing "file" extends its lifetime to the lifetime of the new thread.
|
||||
// We'd prefer to move the unique_ptr into the lambda, but that's
|
||||
// awkward with the C++ standard we're on
|
||||
auto sharedDevice = QSharedPointer<QIODevice>(device.release());
|
||||
|
||||
// Bug: The thread will keep running even if ComputeChecksum is deleted.
|
||||
auto type = checksumType();
|
||||
_watcher.setFuture(QtConcurrent::run([filePath, type]() {
|
||||
QFile file(filePath);
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
qCWarning(lcChecksums) << "Could not open file" << filePath << "for reading to compute a checksum" << file.errorString();
|
||||
_watcher.setFuture(QtConcurrent::run([sharedDevice, type]() {
|
||||
if (!sharedDevice->open(QIODevice::ReadOnly)) {
|
||||
if (auto file = qobject_cast<QFile *>(sharedDevice.data())) {
|
||||
qCWarning(lcChecksums) << "Could not open file" << file->fileName()
|
||||
<< "for reading to compute a checksum" << file->errorString();
|
||||
} else {
|
||||
qCWarning(lcChecksums) << "Could not open device" << sharedDevice.data()
|
||||
<< "for reading to compute a checksum" << sharedDevice->errorString();
|
||||
}
|
||||
return QByteArray();
|
||||
}
|
||||
return ComputeChecksum::computeNow(&file, type);
|
||||
return ComputeChecksum::computeNow(sharedDevice.data(), type);
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -328,6 +350,12 @@ void ValidateChecksumHeader::start(const QString &filePath, const QByteArray &ch
|
|||
calculator->start(filePath);
|
||||
}
|
||||
|
||||
void ValidateChecksumHeader::start(std::unique_ptr<QIODevice> device, const QByteArray &checksumHeader)
|
||||
{
|
||||
if (auto calculator = prepareStart(checksumHeader))
|
||||
calculator->start(std::move(device));
|
||||
}
|
||||
|
||||
void ValidateChecksumHeader::slotChecksumCalculated(const QByteArray &checksumType,
|
||||
const QByteArray &checksum)
|
||||
{
|
||||
|
|
|
@ -100,6 +100,16 @@ public:
|
|||
*/
|
||||
void start(const QString &filePath);
|
||||
|
||||
/**
|
||||
* Computes the checksum for the given device.
|
||||
*
|
||||
* done() is emitted when the calculation finishes.
|
||||
*
|
||||
* The device ownership transfers into the thread that
|
||||
* will compute the checksum. It must not have a parent.
|
||||
*/
|
||||
void start(std::unique_ptr<QIODevice> device);
|
||||
|
||||
/**
|
||||
* Computes the checksum synchronously.
|
||||
*/
|
||||
|
@ -117,6 +127,8 @@ private slots:
|
|||
void slotCalculationDone();
|
||||
|
||||
private:
|
||||
void startImpl(std::unique_ptr<QIODevice> device);
|
||||
|
||||
QByteArray _checksumType;
|
||||
|
||||
// watcher for the checksum calculation thread
|
||||
|
@ -134,7 +146,7 @@ public:
|
|||
explicit ValidateChecksumHeader(QObject *parent = nullptr);
|
||||
|
||||
/**
|
||||
* Check a device's actual checksum against the provided checksumHeader
|
||||
* Check a file's actual checksum against the provided checksumHeader
|
||||
*
|
||||
* If no checksum is there, or if a correct checksum is there, the signal validated()
|
||||
* will be emitted. In case of any kind of error, the signal validationFailed() will
|
||||
|
@ -142,6 +154,16 @@ public:
|
|||
*/
|
||||
void start(const QString &filePath, const QByteArray &checksumHeader);
|
||||
|
||||
/**
|
||||
* Check a device's actual checksum against the provided checksumHeader
|
||||
*
|
||||
* Like the other start() but works on an device.
|
||||
*
|
||||
* The device ownership transfers into the thread that
|
||||
* will compute the checksum. It must not have a parent.
|
||||
*/
|
||||
void start(std::unique_ptr<QIODevice> device, const QByteArray &checksumHeader);
|
||||
|
||||
signals:
|
||||
void validated(const QByteArray &checksumType, const QByteArray &checksum);
|
||||
void validationFailed(const QString &errMsg);
|
||||
|
|
Loading…
Reference in a new issue