1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
|
// 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"
#include <functional>
#include <memory>
#include <typeindex>
#include <variant>
#include <QFuture>
#include <QMimeType>
#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;
Result result() const;
Q_SIGNAL void finished();
private:
QXmppFileUpload();
void reportFinished();
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;
Result result() const;
Q_SIGNAL void finished();
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
{
public:
struct MetadataThumbnail
{
uint32_t width;
uint32_t height;
QByteArray data;
QMimeType mimeType;
};
struct MetadataGeneratorResult
{
std::optional<QSize> dimensions;
std::optional<uint32_t> length;
QVector<MetadataThumbnail> thumbnails;
std::unique_ptr<QIODevice> dataDevice;
};
using MetadataGenerator = std::function<QFuture<std::shared_ptr<MetadataGeneratorResult>>(std::unique_ptr<QIODevice>)>;
QXmppFileSharingManager();
~QXmppFileSharingManager();
void setMetadataGenerator(MetadataGenerator &&generator);
///
/// \brief Register a provider for automatic downloads
/// \param manager A shared_ptr to a QXmppFileSharingProvider subclass
/// The provider must define SourceType to the type of the accepted file source.
///
template<typename ProviderType>
void registerProvider(std::shared_ptr<ProviderType> manager)
{
std::type_index index(typeid(typename ProviderType::SourceType));
internalRegisterProvider(index, manager);
}
std::shared_ptr<QXmppFileUpload> uploadFile(std::shared_ptr<QXmppFileSharingProvider> provider,
const QString &filePath,
const std::optional<QString> &description = {});
std::shared_ptr<QXmppFileDownload> downloadFile(const QXmppFileShare &fileShare,
std::unique_ptr<QIODevice> output);
private:
friend class QXmppEncryptedFileSharingProvider;
void internalRegisterProvider(std::type_index, std::shared_ptr<QXmppFileSharingProvider> provider);
std::shared_ptr<QXmppFileSharingProvider> providerForSource(const std::any &source) const;
std::unique_ptr<QXmppFileSharingManagerPrivate> d;
};
#endif // QXMPPFILESHARINGMANAGER_H
|