1 | // Copyright (C) 2016 The Qt Company Ltd. |
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 "qnetworkreplydataimpl_p.h" |
5 | #include "private/qdataurl_p.h" |
6 | #include <QtCore/QCoreApplication> |
7 | #include <QtCore/QMetaObject> |
8 | |
9 | QT_BEGIN_NAMESPACE |
10 | |
11 | QNetworkReplyDataImplPrivate::QNetworkReplyDataImplPrivate() |
12 | : QNetworkReplyPrivate() |
13 | { |
14 | } |
15 | |
16 | QNetworkReplyDataImplPrivate::~QNetworkReplyDataImplPrivate() |
17 | { |
18 | } |
19 | |
20 | QNetworkReplyDataImpl::~QNetworkReplyDataImpl() |
21 | { |
22 | } |
23 | |
24 | QNetworkReplyDataImpl::QNetworkReplyDataImpl(QObject *parent, const QNetworkRequest &req, const QNetworkAccessManager::Operation op) |
25 | : QNetworkReply(*new QNetworkReplyDataImplPrivate(), parent) |
26 | { |
27 | Q_D(QNetworkReplyDataImpl); |
28 | setRequest(req); |
29 | setUrl(req.url()); |
30 | setOperation(op); |
31 | setFinished(true); |
32 | QNetworkReply::open(mode: QIODevice::ReadOnly); |
33 | |
34 | QUrl url = req.url(); |
35 | QString mimeType; |
36 | QByteArray payload; |
37 | if (qDecodeDataUrl(url, mimeType, payload)) { |
38 | qint64 size = payload.size(); |
39 | auto h = headers(); |
40 | h.replaceOrAppend(name: QHttpHeaders::WellKnownHeader::ContentType, newValue: mimeType); |
41 | h.replaceOrAppend(name: QHttpHeaders::WellKnownHeader::ContentLength, newValue: QByteArray::number(size)); |
42 | setHeaders(std::move(h)); |
43 | |
44 | QMetaObject::invokeMethod(obj: this, member: "metaDataChanged" , c: Qt::QueuedConnection); |
45 | |
46 | d->decodedData.setData(payload); |
47 | d->decodedData.open(openMode: QIODevice::ReadOnly); |
48 | |
49 | QMetaObject::invokeMethod(obj: this, member: "downloadProgress" , c: Qt::QueuedConnection, |
50 | Q_ARG(qint64,size), Q_ARG(qint64, size)); |
51 | QMetaObject::invokeMethod(obj: this, member: "readyRead" , c: Qt::QueuedConnection); |
52 | QMetaObject::invokeMethod(obj: this, member: "finished" , c: Qt::QueuedConnection); |
53 | } else { |
54 | // something wrong with this URI |
55 | const QString msg = QCoreApplication::translate(context: "QNetworkAccessDataBackend" , |
56 | key: "Invalid URI: %1" ).arg(a: url.toString()); |
57 | setError(errorCode: QNetworkReply::ProtocolFailure, errorString: msg); |
58 | QMetaObject::invokeMethod(obj: this, member: "errorOccurred" , c: Qt::QueuedConnection, |
59 | Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ProtocolFailure)); |
60 | QMetaObject::invokeMethod(obj: this, member: "finished" , c: Qt::QueuedConnection); |
61 | } |
62 | } |
63 | |
64 | void QNetworkReplyDataImpl::close() |
65 | { |
66 | QNetworkReply::close(); |
67 | } |
68 | |
69 | void QNetworkReplyDataImpl::abort() |
70 | { |
71 | QNetworkReply::close(); |
72 | } |
73 | |
74 | qint64 QNetworkReplyDataImpl::bytesAvailable() const |
75 | { |
76 | Q_D(const QNetworkReplyDataImpl); |
77 | return QNetworkReply::bytesAvailable() + d->decodedData.bytesAvailable(); |
78 | } |
79 | |
80 | bool QNetworkReplyDataImpl::isSequential () const |
81 | { |
82 | return true; |
83 | } |
84 | |
85 | qint64 QNetworkReplyDataImpl::size() const |
86 | { |
87 | Q_D(const QNetworkReplyDataImpl); |
88 | return d->decodedData.size(); |
89 | } |
90 | |
91 | /*! |
92 | \internal |
93 | */ |
94 | qint64 QNetworkReplyDataImpl::readData(char *data, qint64 maxlen) |
95 | { |
96 | Q_D(QNetworkReplyDataImpl); |
97 | |
98 | // TODO idea: |
99 | // Instead of decoding the whole data into new memory, we could decode on demand. |
100 | // Note that this might be tricky to do. |
101 | |
102 | return d->decodedData.read(data, maxlen); |
103 | } |
104 | |
105 | |
106 | QT_END_NAMESPACE |
107 | |
108 | #include "moc_qnetworkreplydataimpl_p.cpp" |
109 | |
110 | |