diff options
| author | Linus Jahn <lnj@kaidan.im> | 2022-10-02 20:36:11 +0200 |
|---|---|---|
| committer | Linus Jahn <lnj@kaidan.im> | 2022-10-02 23:01:13 +0200 |
| commit | 2fe061ae4a5485201ecc79b163a2a3771d8f5be4 (patch) | |
| tree | e81733ee9eec3cb347780b45522f4e2a4ee44aab /src | |
| parent | ada1907bb5f22e0820e1d1d8004cc23f2246e74b (diff) | |
| download | qxmpp-2fe061ae4a5485201ecc79b163a2a3771d8f5be4.tar.gz | |
FileUpload/Download: Avoid unnecessary virtual functions
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 6 | ||||
| -rw-r--r-- | src/client/QXmppDownload.cpp | 45 | ||||
| -rw-r--r-- | src/client/QXmppDownload.h | 41 | ||||
| -rw-r--r-- | src/client/QXmppFileSharingManager.cpp | 372 | ||||
| -rw-r--r-- | src/client/QXmppFileSharingManager.h | 102 | ||||
| -rw-r--r-- | src/client/QXmppFileTransfer.cpp | 43 | ||||
| -rw-r--r-- | src/client/QXmppFileTransfer.h | 31 | ||||
| -rw-r--r-- | src/client/QXmppUpload.cpp | 47 | ||||
| -rw-r--r-- | src/client/QXmppUpload.h | 34 |
9 files changed, 366 insertions, 355 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7626d016..089039b7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -109,12 +109,10 @@ set(INSTALL_HEADER_FILES client/QXmppClientExtension.h client/QXmppConfiguration.h client/QXmppDiscoveryManager.h - client/QXmppDownload.h client/QXmppE2eeExtension.h client/QXmppEntityTimeManager.h client/QXmppFileSharingManager.h client/QXmppFileSharingProvider.h - client/QXmppFileTransfer.h client/QXmppHttpFileSharingProvider.h client/QXmppHttpUploadManager.h client/QXmppInvokable.h @@ -137,7 +135,6 @@ set(INSTALL_HEADER_FILES client/QXmppTrustMemoryStorage.h client/QXmppTrustSecurityPolicy.h client/QXmppTrustStorage.h - client/QXmppUpload.h client/QXmppUploadRequestManager.h client/QXmppUserTuneManager.h client/QXmppUserLocationManager.h @@ -239,12 +236,10 @@ set(SOURCE_FILES client/QXmppClient.cpp client/QXmppClientExtension.cpp client/QXmppConfiguration.cpp - client/QXmppDownload.cpp client/QXmppDiscoveryManager.cpp client/QXmppE2eeExtension.cpp client/QXmppEntityTimeManager.cpp client/QXmppFileSharingManager.cpp - client/QXmppFileTransfer.cpp client/QXmppHttpFileSharingProvider.cpp client/QXmppHttpUploadManager.cpp client/QXmppInternalClientExtension.cpp @@ -264,7 +259,6 @@ set(SOURCE_FILES client/QXmppTrustManager.cpp client/QXmppTrustMemoryStorage.cpp client/QXmppTrustStorage.cpp - client/QXmppUpload.cpp client/QXmppUploadRequestManager.cpp client/QXmppUserLocationManager.cpp client/QXmppUserTuneManager.cpp diff --git a/src/client/QXmppDownload.cpp b/src/client/QXmppDownload.cpp deleted file mode 100644 index e57b1956..00000000 --- a/src/client/QXmppDownload.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Jonah Brüchert <jbb@kaidan.im> -// SPDX-FileCopyrightText: 2022 Linus Jahn <lnj@kaidan.im> -// -// SPDX-License-Identifier: LGPL-2.1-or-later - -#include "QXmppDownload.h" - -/// -/// \class QXmppDownload -/// -/// \brief Provides progress of stateless file sharing uploads. -/// -/// \since QXmpp 1.5 -/// - -/// -/// \enum QXmppDownload::HashVerificationResult -/// -/// Describes the result of the hash verification. -/// - -/// -/// \struct QXmppDownload::Downloaded -/// -/// Indicates that the file could be downloaded. -/// - -/// -/// \var QXmppDownload::Downloaded::hashVerificationResult -/// -/// Describes the result of the hash verification. -/// - -/// -/// \typedef QXmppDownload::Result -/// -/// \brief Contains QXmpp::Success (successfully finished), QXmpp::Cancelled (manually cancelled) -/// or QXmppError (an error occured while downloading). -/// - -/// -/// \fn QXmppDownload::finished -/// -/// Emitted when the download has finished. -/// diff --git a/src/client/QXmppDownload.h b/src/client/QXmppDownload.h deleted file mode 100644 index a1dffb3d..00000000 --- a/src/client/QXmppDownload.h +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Jonah Brüchert <jbb@kaidan.im> -// SPDX-FileCopyrightText: 2022 Linus Jahn <lnj@kaidan.im> -// -// SPDX-License-Identifier: LGPL-2.1-or-later - -#ifndef QXMPPDOWNLOAD_H -#define QXMPPDOWNLOAD_H - -#include "QXmppError.h" -#include "QXmppFileTransfer.h" - -#include <variant> - -class QXMPP_EXPORT QXmppDownload : public QXmppFileTransfer -{ - Q_OBJECT -public: - enum HashVerificationResult { - /// - /// \brief File did not contain strong hashes (or no hashes at all) and no verification - /// was done. - /// - /// This value is not used when a hash value did not match. In that case the whole file - /// download returns an error. - /// - NoStrongHashes, - /// \brief The file integrity could be proved using a strong hash algorithm. - HashVerified, - }; - - struct Downloaded { - HashVerificationResult hashVerificationResult; - }; - - using Result = std::variant<Downloaded, QXmpp::Cancelled, QXmppError>; - Q_SIGNAL void finished(QXmppDownload::Result); -}; - -Q_DECLARE_METATYPE(QXmppDownload::Result); - -#endif // QXMPPDOWNLOAD_H diff --git a/src/client/QXmppFileSharingManager.cpp b/src/client/QXmppFileSharingManager.cpp index 0d4b780c..3ecb7380 100644 --- a/src/client/QXmppFileSharingManager.cpp +++ b/src/client/QXmppFileSharingManager.cpp @@ -8,13 +8,11 @@ #include "QXmppBitsOfBinaryContentId.h" #include "QXmppBitsOfBinaryData.h" #include "QXmppClient.h" -#include "QXmppDownload.h" #include "QXmppFileMetadata.h" #include "QXmppFileShare.h" #include "QXmppFutureUtils_p.h" #include "QXmppHashing_p.h" #include "QXmppThumbnail.h" -#include "QXmppUpload.h" #include "QXmppUploadRequestManager.h" #include "QXmppUtils_p.h" @@ -58,77 +56,246 @@ auto transform(T &input, Converter convert) return output; } -class UploadImpl : public QXmppUpload +class QXmppFileUploadPrivate { - Q_OBJECT public: - float progress() const override { return calculateProgress(m_bytesSent, m_bytesTotal); } - void cancel() override - { - if (m_providerUpload) { - m_providerUpload->cancel(); - } - m_metadataFuture.cancel(); - m_hashesFuture.cancel(); - } - bool isFinished() const override { return m_finished; } - quint64 bytesTransferred() const override { return m_bytesSent; } - quint64 bytesTotal() const override { return m_bytesTotal; } - - void reportFinished(Result result) - { - if (!m_finished) { - m_finished = true; - Q_EMIT finished(std::move(result)); - } - } - - std::shared_ptr<QXmppFileSharingProvider::Upload> m_providerUpload; - QFuture<std::shared_ptr<MetadataGeneratorResult>> m_metadataFuture; - QFuture<HashingResultPtr> m_hashesFuture; - QXmppFileMetadata m_metadata; - QXmppBitsOfBinaryDataList m_dataBlobs; - std::any m_source; - quint64 m_bytesSent = 0; - quint64 m_bytesTotal = 0; - bool m_finished = false; + std::shared_ptr<QXmppFileSharingProvider::Upload> providerUpload; + QFuture<std::shared_ptr<MetadataGeneratorResult>> metadataFuture; + QFuture<HashingResultPtr> hashesFuture; + QXmppFileMetadata metadata; + QXmppBitsOfBinaryDataList dataBlobs; + std::any source; + quint64 bytesSent = 0; + quint64 bytesTotal = 0; + bool finished = false; }; -class DownloadImpl : public QXmppDownload +/// +/// \class QXmppFileUpload +/// +/// \brief Provides progress of stateless file sharing uploads. +/// +/// \since QXmpp 1.5 +/// + +/// +/// \class QXmppFileUpload::FileResult +/// +/// \brief Contains QXmppFileShare of the uploaded file and possible data blobs containing +/// referenced thumbnails. +/// + +/// +/// \var QXmppFileUpload::FileResult::fileShare +/// +/// \brief File share with file metadata and file shares of the uploaded file. +/// + +/// +/// \var QXmppFileUpload::FileResult::dataBlobs +/// +/// \brief Data blobs of possibly in the metadata referenced thumbnails. +/// +/// The QXmppFileSharingManager may generate file thumbnails. +/// + +/// +/// \typedef QXmppFileUpload::Result +/// +/// \brief Contains FileResult (successfully finished), QXmpp::Cancelled (manually cancelled) +/// or QXmppError (an error occured while uploading). +/// + +QXmppFileUpload::~QXmppFileUpload() = default; + +/// +/// Returns the current progress between 0.0 and 1.0. +/// +float QXmppFileUpload::progress() const { - float progress() const override { return calculateProgress(m_bytesReceived, m_bytesTotal); } - void cancel() override - { - if (m_providerDownload) { - m_providerDownload->cancel(); - } - m_hashesFuture.cancel(); - } - bool isFinished() const override { return m_finished; } - quint64 bytesTransferred() const override { return m_bytesReceived; } - quint64 bytesTotal() const override { return m_bytesTotal; } + return calculateProgress(d->bytesSent, d->bytesTotal); +} -public: - void reportProgress(quint64 bytesReceived, quint64 bytesTotal) - { - m_bytesReceived = bytesReceived; - m_bytesTotal = bytesTotal; - Q_EMIT progressChanged(); +/// +/// \fn QXmppFileUpload::progressChanged() +/// +/// \brief Emitted when new bytes have been transferred. +/// + +/// +/// \brief Cancels the file transfer. finished() will be emitted. +/// +void QXmppFileUpload::cancel() +{ + if (d->providerUpload) { + d->providerUpload->cancel(); } - void reportFinished(Result result) - { - m_finished = true; + d->metadataFuture.cancel(); + d->hashesFuture.cancel(); +} + +/// +/// \brief Returns whether the file transfer is finished. +/// +bool QXmppFileUpload::isFinished() const +{ + return d->finished; +} + +/// +/// \brief Returns the number of bytes that have been uploaded or downloaded. +/// +quint64 QXmppFileUpload::bytesTransferred() const +{ + return d->bytesSent; +} + +/// +/// \brief Returns the number of bytes that totally need to be transferred. +/// +quint64 QXmppFileUpload::bytesTotal() const +{ + return d->bytesTotal; +} + +/// +/// \fn QXmppFileUpload::finished +/// +/// Emitted when the upload has finished. +/// + +QXmppFileUpload::QXmppFileUpload() + : d(std::make_unique<QXmppFileUploadPrivate>()) +{ +} + +void QXmppFileUpload::reportFinished(Result result) +{ + if (!d->finished) { + d->finished = true; Q_EMIT finished(std::move(result)); } +} - std::shared_ptr<QXmppFileSharingProvider::Download> m_providerDownload; - QFuture<HashVerificationResultPtr> m_hashesFuture; - QVector<QXmppHash> m_hashes; - quint64 m_bytesReceived = 0; - quint64 m_bytesTotal = 0; - bool m_finished = false; +class QXmppFileDownloadPrivate +{ +public: + std::shared_ptr<QXmppFileSharingProvider::Download> providerDownload; + QFuture<HashVerificationResultPtr> hashesFuture; + QVector<QXmppHash> hashes; + quint64 bytesReceived = 0; + quint64 bytesTotal = 0; + bool finished = false; }; +/// +/// \class QXmppFileDownload +/// +/// \brief Provides progress of stateless file sharing uploads. +/// +/// \since QXmpp 1.5 +/// + +/// +/// \enum QXmppFileDownload::HashVerificationResult +/// +/// Describes the result of the hash verification. +/// + +/// +/// \struct QXmppFileDownload::Downloaded +/// +/// Indicates that the file could be downloaded. +/// + +/// +/// \var QXmppFileDownload::Downloaded::hashVerificationResult +/// +/// Describes the result of the hash verification. +/// + +/// +/// \typedef QXmppFileDownload::Result +/// +/// \brief Contains QXmpp::Success (successfully finished), QXmpp::Cancelled (manually cancelled) +/// or QXmppError (an error occured while downloading). +/// + +QXmppFileDownload::~QXmppFileDownload() = default; + +/// +/// Returns the current progress between 0.0 and 1.0. +/// +float QXmppFileDownload::progress() const +{ + return calculateProgress(d->bytesReceived, d->bytesTotal); +} + +/// +/// \fn QXmppFileDownload::progressChanged +/// +/// \brief Emitted when new bytes have been transferred. +/// + +/// +/// \brief Cancels the file transfer. finished() will be emitted. +/// +void QXmppFileDownload::cancel() +{ + if (d->providerDownload) { + d->providerDownload->cancel(); + } + d->hashesFuture.cancel(); +} + +/// +/// \brief Returns whether the file transfer is finished. +/// +bool QXmppFileDownload::isFinished() const +{ + return d->finished; +} + +/// +/// \brief Returns the number of bytes that have been uploaded or downloaded. +/// +quint64 QXmppFileDownload::bytesTransferred() const +{ + return d->bytesReceived; +} + +/// +/// \brief Returns the number of bytes that totally need to be transferred. +/// +quint64 QXmppFileDownload::bytesTotal() const +{ + return d->bytesTotal; +} + +/// +/// \fn QXmppFileDownload::finished +/// +/// Emitted when the download has finished. +/// + +QXmppFileDownload::QXmppFileDownload() + : d(std::make_unique<QXmppFileDownloadPrivate>()) +{ +} + +void QXmppFileDownload::reportProgress(quint64 bytesReceived, quint64 bytesTotal) +{ + d->bytesReceived = bytesReceived; + d->bytesTotal = bytesTotal; + Q_EMIT progressChanged(); +} + +void QXmppFileDownload::reportFinished(Result result) +{ + d->finished = true; + Q_EMIT finished(std::move(result)); +} + class QXmppFileSharingManagerPrivate { public: @@ -192,16 +359,16 @@ void QXmppFileSharingManager::setMetadataGenerator(MetadataGenerator &&generator /// \return An object that allows to track the progress of the upload. /// Once the upload is finished, the finished signal is emitted on it. /// -std::shared_ptr<QXmppUpload> QXmppFileSharingManager::sendFile(std::shared_ptr<QXmppFileSharingProvider> provider, - const QString &filePath, - const std::optional<QString> &description) +std::shared_ptr<QXmppFileUpload> QXmppFileSharingManager::sendFile(std::shared_ptr<QXmppFileSharingProvider> provider, + const QString &filePath, + const std::optional<QString> &description) { QFileInfo fileInfo(filePath); auto metadata = QXmppFileMetadata::fromFileInfo(fileInfo); metadata.setDescription(description); - auto upload = std::make_shared<UploadImpl>(); - upload->m_metadata = std::move(metadata); + std::shared_ptr<QXmppFileUpload> upload(new QXmppFileUpload()); + upload->d->metadata = std::move(metadata); auto openFile = [=]() -> std::unique_ptr<QIODevice> { auto device = std::make_unique<QFile>(fileInfo.absoluteFilePath()); @@ -215,37 +382,37 @@ std::shared_ptr<QXmppUpload> QXmppFileSharingManager::sendFile(std::shared_ptr<Q auto hashesIoDevice = openFile(); auto uploadIoDevice = openFile(); - if (upload->m_finished) { + if (upload->d->finished) { // error occurred while opening file return upload; } - upload->m_metadataFuture = d->metadataGenerator(std::move(metadataIoDevice)); - upload->m_hashesFuture = calculateHashes(std::move(hashesIoDevice), hashAlgorithms()); + upload->d->metadataFuture = d->metadataGenerator(std::move(metadataIoDevice)); + upload->d->hashesFuture = calculateHashes(std::move(hashesIoDevice), hashAlgorithms()); auto onProgress = [upload](quint64 sent, quint64 total) { - upload->m_bytesSent = sent; - upload->m_bytesTotal = total; + upload->d->bytesSent = sent; + upload->d->bytesTotal = total; Q_EMIT upload->progressChanged(); }; auto onFinished = [this, upload](QXmppFileSharingProvider::UploadResult uploadResult) { // free memory - upload->m_providerUpload.reset(); + upload->d->providerUpload.reset(); if (std::holds_alternative<std::any>(uploadResult)) { - upload->m_source = std::get<std::any>(std::move(uploadResult)); - await(upload->m_metadataFuture, this, [this, upload](auto &&result) mutable { + upload->d->source = std::get<std::any>(std::move(uploadResult)); + await(upload->d->metadataFuture, this, [this, upload](auto &&result) mutable { if (result->dimensions) { - upload->m_metadata.setWidth(result->dimensions->width()); - upload->m_metadata.setHeight(result->dimensions->height()); + upload->d->metadata.setWidth(result->dimensions->width()); + upload->d->metadata.setHeight(result->dimensions->height()); } if (result->length) { - upload->m_metadata.setLength(*result->length); + upload->d->metadata.setLength(*result->length); } if (!result->thumbnails.empty()) { QVector<QXmppThumbnail> thumbnails; thumbnails.reserve(result->thumbnails.size()); - upload->m_dataBlobs.reserve(result->thumbnails.size()); + upload->d->dataBlobs.reserve(result->thumbnails.size()); for (const auto &metadataThumb : result->thumbnails) { auto bobData = QXmppBitsOfBinaryData::fromByteArray(metadataThumb.data); @@ -258,12 +425,12 @@ std::shared_ptr<QXmppUpload> QXmppFileSharingManager::sendFile(std::shared_ptr<Q thumbnail.setUri(bobData.cid().toCidUrl()); thumbnails.append(std::move(thumbnail)); - upload->m_dataBlobs.append(std::move(bobData)); + upload->d->dataBlobs.append(std::move(bobData)); } - upload->m_metadata.setThumbnails(thumbnails); + upload->d->metadata.setThumbnails(thumbnails); } - await(upload->m_hashesFuture, this, [upload](auto hashResult) mutable { + await(upload->d->hashesFuture, this, [upload](auto hashResult) mutable { auto &hashValue = hashResult->result; if (std::holds_alternative<std::vector<QXmppHash>>(hashValue)) { const auto &hashesVector = std::get<std::vector<QXmppHash>>(hashValue); @@ -273,13 +440,13 @@ std::shared_ptr<QXmppUpload> QXmppFileSharingManager::sendFile(std::shared_ptr<Q std::back_inserter(hashes), [](auto &&hash) { return hash; }); - upload->m_metadata.setHashes(hashes); + upload->d->metadata.setHashes(hashes); QXmppFileShare fs; - fs.setMetadata(upload->m_metadata); - fs.addSource(upload->m_source); + fs.setMetadata(upload->d->metadata); + fs.addSource(upload->d->source); - upload->reportFinished(QXmppUpload::FileResult { fs, std::move(upload->m_dataBlobs) }); + upload->reportFinished(QXmppFileUpload::FileResult { fs, std::move(upload->d->dataBlobs) }); } else if (std::holds_alternative<Cancelled>(hashValue)) { upload->reportFinished(Cancelled()); } else if (std::holds_alternative<QXmppError>(hashValue)) { @@ -294,7 +461,7 @@ std::shared_ptr<QXmppUpload> QXmppFileSharingManager::sendFile(std::shared_ptr<Q } }; - upload->m_providerUpload = provider->uploadFile(std::move(uploadIoDevice), upload->m_metadata, std::move(onProgress), std::move(onFinished)); + upload->d->providerUpload = provider->uploadFile(std::move(uploadIoDevice), upload->d->metadata, std::move(onProgress), std::move(onFinished)); return upload; } @@ -311,12 +478,12 @@ std::shared_ptr<QXmppUpload> QXmppFileSharingManager::sendFile(std::shared_ptr<Q /// In most cases, a QFile /// \return An object that allows to track the progress of the download. /// -std::shared_ptr<QXmppDownload> QXmppFileSharingManager::downloadFile( +std::shared_ptr<QXmppFileDownload> QXmppFileSharingManager::downloadFile( const QXmppFileShare &fileShare, std::unique_ptr<QIODevice> output) { - auto download = std::make_shared<DownloadImpl>(); - download->m_hashes = fileShare.metadata().hashes(); + std::shared_ptr<QXmppFileDownload> download(new QXmppFileDownload()); + download->d->hashes = fileShare.metadata().hashes(); // currently hashing does only work with QFiles auto filePath = [&]() -> QString { @@ -331,7 +498,7 @@ std::shared_ptr<QXmppDownload> QXmppFileSharingManager::downloadFile( }; auto onFinished = [this, download, filePath](QXmppFileSharingProvider::DownloadResult result) mutable { // reduce ref count - download->m_providerDownload.reset(); + download->d->providerDownload.reset(); // pass errors directly if (std::holds_alternative<Cancelled>(result)) { @@ -346,7 +513,7 @@ std::shared_ptr<QXmppDownload> QXmppFileSharingManager::downloadFile( // try to do hash verification if (filePath.isEmpty()) { warning(QStringLiteral("Can't verify hashes of other io devices than QFile!")); - download->reportFinished(QXmppDownload::Downloaded { QXmppDownload::NoStrongHashes }); + download->reportFinished(QXmppFileDownload::Downloaded { QXmppFileDownload::NoStrongHashes }); return; } @@ -356,15 +523,15 @@ std::shared_ptr<QXmppDownload> QXmppFileSharingManager::downloadFile( return; } - download->m_hashesFuture = verifyHashes( + download->d->hashesFuture = verifyHashes( std::move(file), - transform(download->m_hashes, [](auto hash) { return hash; })); + transform(download->d->hashes, [](auto hash) { return hash; })); - await(download->m_hashesFuture, this, [download = std::move(download)](HashVerificationResultPtr hashResult) { - download->reportFinished(visitForward<QXmppDownload::Result>(hashResult->result, overloaded { + await(download->d->hashesFuture, this, [download = std::move(download)](HashVerificationResultPtr hashResult) { + auto convert = overloaded { [](HashVerificationResult::NoStrongHashes) { - return QXmppDownload::Downloaded { - QXmppDownload::NoStrongHashes + return QXmppFileDownload::Downloaded { + QXmppFileDownload::NoStrongHashes }; }, [](HashVerificationResult::NotMatching) { @@ -374,17 +541,18 @@ std::shared_ptr<QXmppDownload> QXmppFileSharingManager::downloadFile( }; }, [](HashVerificationResult::Verified) { - return QXmppDownload::Downloaded { - QXmppDownload::HashVerified + return QXmppFileDownload::Downloaded { + QXmppFileDownload::HashVerified }; } - })); + }; + download->reportFinished(visitForward<QXmppFileDownload::Result>(hashResult->result, convert)); }); }; fileShare.visitSources([&](const std::any &source) { if (auto provider = providerForSource(source)) { - download->m_providerDownload = provider->downloadFile(source, std::move(output), std::move(onProgress), std::move(onFinished)); + download->d->providerDownload = provider->downloadFile(source, std::move(output), std::move(onProgress), std::move(onFinished)); return true; } return false; @@ -406,5 +574,3 @@ std::shared_ptr<QXmppFileSharingProvider> QXmppFileSharingManager::providerForSo } return {}; } - -#include "QXmppFileSharingManager.moc" diff --git a/src/client/QXmppFileSharingManager.h b/src/client/QXmppFileSharingManager.h index b59eb46b..6224cf40 100644 --- a/src/client/QXmppFileSharingManager.h +++ b/src/client/QXmppFileSharingManager.h @@ -1,11 +1,14 @@ // SPDX-FileCopyrightText: 2022 Jonah Brüchert <jbb@kaidan.im> +// SPDX-FileCopyrightText: 2022 Linus Jahn <lnj@kaidan.im> // // SPDX-License-Identifier: LGPL-2.1-or-later #ifndef QXMPPFILESHARINGMANAGER_H #define QXMPPFILESHARINGMANAGER_H +#include "QXmppBitsOfBinaryDataList.h" #include "QXmppClientExtension.h" +#include "QXmppFileShare.h" #include "QXmppFileSharingProvider.h" #include "QXmppGlobal.h" @@ -19,9 +22,98 @@ #include <QSize> class QIODevice; +class QXmppFileDownloadPrivate; class QXmppFileMetadata; class QXmppFileShare; class QXmppFileSharingManagerPrivate; +class QXmppFileUploadPrivate; + +class QXMPP_EXPORT QXmppFileUpload : public QObject +{ + Q_OBJECT + /// Progress of the file upload between 0.0 and 1.0. + Q_PROPERTY(float progress READ progress NOTIFY progressChanged) +public: + struct FileResult + { + QXmppFileShare fileShare; + QXmppBitsOfBinaryDataList dataBlobs; + }; + + using Result = std::variant<FileResult, QXmpp::Cancelled, QXmppError>; + + ~QXmppFileUpload(); + + float progress() const; + Q_SIGNAL void progressChanged(); + + void cancel(); + bool isFinished() const; + quint64 bytesTransferred() const; + quint64 bytesTotal() const; + + Q_SIGNAL void finished(QXmppFileUpload::Result); + +private: + QXmppFileUpload(); + + void reportFinished(Result); + + std::unique_ptr<QXmppFileUploadPrivate> d; + friend class QXmppFileSharingManager; +}; + +Q_DECLARE_METATYPE(QXmppFileUpload::Result); + +class QXMPP_EXPORT QXmppFileDownload : public QObject +{ + Q_OBJECT + /// Progress of the file download between 0.0 and 1.0. + Q_PROPERTY(float progress READ progress NOTIFY progressChanged) +public: + enum HashVerificationResult { + /// + /// \brief File did not contain strong hashes (or no hashes at all) and no verification + /// was done. + /// + /// This value is not used when a hash value did not match. In that case the whole file + /// download returns an error. + /// + NoStrongHashes, + /// \brief The file integrity could be proved using a strong hash algorithm. + HashVerified, + }; + + struct Downloaded + { + HashVerificationResult hashVerificationResult; + }; + + using Result = std::variant<Downloaded, QXmpp::Cancelled, QXmppError>; + + ~QXmppFileDownload(); + + float progress() const; + Q_SIGNAL void progressChanged(); + + void cancel(); + bool isFinished() const; + quint64 bytesTransferred() const; + quint64 bytesTotal() const; + + Q_SIGNAL void finished(QXmppFileDownload::Result); + +private: + QXmppFileDownload(); + + void reportProgress(quint64 bytesReceived, quint64 bytesTotal); + void reportFinished(Result); + + std::unique_ptr<QXmppFileDownloadPrivate> d; + friend class QXmppFileSharingManager; +}; + +Q_DECLARE_METATYPE(QXmppFileDownload::Result); class QXMPP_EXPORT QXmppFileSharingManager : public QXmppClientExtension { @@ -61,12 +153,12 @@ public: internalRegisterProvider(index, manager); } - std::shared_ptr<QXmppUpload> sendFile(std::shared_ptr<QXmppFileSharingProvider> provider, - const QString &filePath, - const std::optional<QString> &description = {}); + std::shared_ptr<QXmppFileUpload> sendFile(std::shared_ptr<QXmppFileSharingProvider> provider, + const QString &filePath, + const std::optional<QString> &description = {}); - std::shared_ptr<QXmppDownload> downloadFile(const QXmppFileShare &fileShare, - std::unique_ptr<QIODevice> output); + std::shared_ptr<QXmppFileDownload> downloadFile(const QXmppFileShare &fileShare, + std::unique_ptr<QIODevice> output); private: friend class QXmppEncryptedFileSharingProvider; diff --git a/src/client/QXmppFileTransfer.cpp b/src/client/QXmppFileTransfer.cpp deleted file mode 100644 index f26c3a89..00000000 --- a/src/client/QXmppFileTransfer.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Linus Jahn <lnj@kaidan.im> -// -// SPDX-License-Identifier: LGPL-2.1-or-later - -#include "QXmppFileTransfer.h" - -/// -/// \class QXmppFileTransfer -/// -/// \brief Provides progress information about ongoing file uploads and downloads. -/// -/// \since QXmpp 1.5 -/// - -/// -/// \fn QXmppFileTransfer::cancel() -/// -/// \brief Cancels the file transfer. finished() will be emitted. -/// - -/// -/// \fn QXmppFileTransfer::isFinished() -/// -/// \brief Returns whether the file transfer is finished. -/// - -/// -/// \fn QXmppFileTransfer::bytesTransferred() -/// -/// \brief Returns the number of bytes that have been uploaded or downloaded. -/// - -/// -/// \fn QXmppFileTransfer::bytesTotal() -/// -/// \brief Returns the number of bytes that totally need to be transferred. -/// - -/// -/// \fn QXmppFileTransfer::progressChanged() -/// -/// \brief Emitted when new bytes have been transferred. -/// diff --git a/src/client/QXmppFileTransfer.h b/src/client/QXmppFileTransfer.h deleted file mode 100644 index 16c12105..00000000 --- a/src/client/QXmppFileTransfer.h +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Linus Jahn <lnj@kaidan.im> -// -// SPDX-License-Identifier: LGPL-2.1-or-later - -#ifndef QXMPPFILETRANSFER_H -#define QXMPPFILETRANSFER_H - -#include "QXmppGlobal.h" - -#include <QObject> - -class QXMPP_EXPORT QXmppFileTransfer : public QObject -{ - Q_OBJECT - /// Progress of the file transfer between 0.0 and 1.0. - Q_PROPERTY(float progress READ progress NOTIFY progressChanged) - -public: - /// Returns the current progress between 0.0 and 1.0. - virtual float progress() const = 0; - virtual void cancel() = 0; - virtual bool isFinished() const = 0; - virtual quint64 bytesTransferred() const = 0; - virtual quint64 bytesTotal() const = 0; - - // TODO consider adding speed getter - - Q_SIGNAL void progressChanged(); -}; - -#endif // QXMPPFILETRANSFER_H diff --git a/src/client/QXmppUpload.cpp b/src/client/QXmppUpload.cpp deleted file mode 100644 index cd4a19e4..00000000 --- a/src/client/QXmppUpload.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Jonah Brüchert <jbb@kaidan.im> -// -// SPDX-License-Identifier: LGPL-2.1-or-later - -#include "QXmppUpload.h" - -/// -/// \class QXmppUpload -/// -/// \brief Provides progress of stateless file sharing uploads. -/// -/// \since QXmpp 1.5 -/// - -/// -/// \class QXmppUpload::FileResult -/// -/// \brief Contains QXmppFileShare of the uploaded file and possible data blobs containing -/// referenced thumbnails. -/// - -/// -/// \var QXmppUpload::FileResult::fileShare -/// -/// \brief File share with file metadata and file shares of the uploaded file. -/// - -/// -/// \var QXmppUpload::FileResult::dataBlobs -/// -/// \brief Data blobs of possibly in the metadata referenced thumbnails. -/// -/// The QXmppFileSharingManager may generate file thumbnails. -/// - -/// -/// \typedef QXmppUpload::Result -/// -/// \brief Contains FileResult (successfully finished), QXmpp::Cancelled (manually cancelled) -/// or QXmppError (an error occured while uploading). -/// - -/// -/// \fn QXmppUpload::finished -/// -/// Emitted when the upload has finished. -/// diff --git a/src/client/QXmppUpload.h b/src/client/QXmppUpload.h deleted file mode 100644 index ec423bd9..00000000 --- a/src/client/QXmppUpload.h +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Jonah Brüchert <jbb@kaidan.im> -// -// SPDX-License-Identifier: LGPL-2.1-or-later - -#ifndef QXMPPUPLOAD_H -#define QXMPPUPLOAD_H - -#include "QXmppBitsOfBinaryDataList.h" -#include "QXmppError.h" -#include "QXmppFileShare.h" -#include "QXmppFileTransfer.h" - -#include <variant> - -class QXMPP_EXPORT QXmppUpload : public QXmppFileTransfer -{ - Q_OBJECT -public: - struct FileResult - { - QXmppFileShare fileShare; - QXmppBitsOfBinaryDataList dataBlobs; - }; - - using Result = std::variant<FileResult, QXmpp::Cancelled, QXmppError>; - Q_SIGNAL void finished(QXmppUpload::Result); - -private: - friend class QXmppFileSharingManager; -}; - -Q_DECLARE_METATYPE(QXmppUpload::Result); - -#endif // QXMPPUPLOAD_H |
