1 | // Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "qdownloadhelperservice_p.h" |
5 | #include "qdownloadnetworkworker_p.h" |
6 | |
7 | #include <QNetworkAccessManager> |
8 | #include <QNetworkRequest> |
9 | #include <QNetworkReply> |
10 | #include <QDataStream> |
11 | |
12 | QT_BEGIN_NAMESPACE |
13 | |
14 | namespace Qt3DCore { |
15 | |
16 | QDownloadNetworkWorker::QDownloadNetworkWorker(QObject *parent) |
17 | : QObject(parent) |
18 | , m_networkManager(nullptr) |
19 | { |
20 | connect(sender: this, signal: &QDownloadNetworkWorker::submitRequest, |
21 | context: this, slot: &QDownloadNetworkWorker::onRequestSubmited); |
22 | connect(sender: this, signal: &QDownloadNetworkWorker::cancelRequest, |
23 | context: this, slot: &QDownloadNetworkWorker::onRequestCancelled); |
24 | connect(sender: this, signal: &QDownloadNetworkWorker::cancelAllRequests, |
25 | context: this, slot: &QDownloadNetworkWorker::onAllRequestsCancelled); |
26 | } |
27 | |
28 | void QDownloadNetworkWorker::onRequestSubmited(const QDownloadRequestPtr &request) |
29 | { |
30 | QMutexLocker l(&m_mutex); |
31 | if (!m_networkManager) { |
32 | m_networkManager = new QNetworkAccessManager(this); |
33 | connect(sender: m_networkManager, signal: &QNetworkAccessManager::finished, |
34 | context: this, slot: &QDownloadNetworkWorker::onRequestFinished); |
35 | } |
36 | auto reply = m_networkManager->get(request: QNetworkRequest(request->url())); |
37 | m_requests << QPair<QDownloadRequestPtr, QNetworkReply *>(request, reply); |
38 | connect(sender: reply, signal: &QNetworkReply::downloadProgress, context: this, slot: &QDownloadNetworkWorker::onDownloadProgressed); |
39 | } |
40 | |
41 | void QDownloadNetworkWorker::onRequestCancelled(const QDownloadRequestPtr &request) |
42 | { |
43 | QMutexLocker l(&m_mutex); |
44 | auto it = std::find_if(first: m_requests.begin(), last: m_requests.end(), |
45 | pred: [request](QPair<QDownloadRequestPtr, QNetworkReply *> e) { |
46 | return e.first == request; |
47 | }); |
48 | if (it == m_requests.end()) |
49 | return; |
50 | |
51 | (*it).first->m_cancelled = true; |
52 | (*it).second->abort(); |
53 | } |
54 | |
55 | void QDownloadNetworkWorker::onAllRequestsCancelled() |
56 | { |
57 | QMutexLocker l(&m_mutex); |
58 | for (auto &e: std::as_const(t&: m_requests)) { |
59 | e.first->m_cancelled = true; |
60 | e.second->abort(); |
61 | } |
62 | m_requests.clear(); |
63 | } |
64 | |
65 | void QDownloadNetworkWorker::onRequestFinished(QNetworkReply *reply) |
66 | { |
67 | QMutexLocker l(&m_mutex); |
68 | auto it = std::find_if(first: m_requests.begin(), last: m_requests.end(), |
69 | pred: [reply](QPair<QDownloadRequestPtr, QNetworkReply *> e) { |
70 | return e.second == reply; |
71 | }); |
72 | if (it == m_requests.end()) |
73 | return; |
74 | |
75 | auto request = (*it).first; |
76 | if (reply->error() == QNetworkReply::NoError) { |
77 | request->m_succeeded = true; |
78 | } |
79 | request->onDownloaded(); |
80 | emit requestDownloaded(request); |
81 | |
82 | m_requests.erase(pos: it); |
83 | } |
84 | |
85 | void QDownloadNetworkWorker::onDownloadProgressed(qint64 bytesReceived, qint64 bytesTotal) |
86 | { |
87 | Q_UNUSED(bytesReceived); |
88 | Q_UNUSED(bytesTotal); |
89 | // TODO forward progress details somewhere |
90 | |
91 | QNetworkReply *reply = qobject_cast<QNetworkReply *>(object: sender()); |
92 | if (!reply) |
93 | return; |
94 | |
95 | QMutexLocker l(&m_mutex); |
96 | auto it = std::find_if(first: m_requests.begin(), last: m_requests.end(), |
97 | pred: [reply](QPair<QDownloadRequestPtr, QNetworkReply *> e) { |
98 | return e.second == reply; |
99 | }); |
100 | if (it == m_requests.end()) |
101 | return; |
102 | |
103 | auto request = (*it).first; |
104 | QDataStream stream(&request->m_data, QIODevice::Append); |
105 | QByteArray data = reply->readAll(); |
106 | stream.writeRawData(data.data(), len: data.size()); |
107 | } |
108 | |
109 | } // namespace Qt3DCore |
110 | |
111 | QT_END_NAMESPACE |
112 | |
113 | #include "moc_qdownloadnetworkworker_p.cpp" |
114 | |
115 | |