1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the QtNetwork module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 3 requirements |
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
24 | ** |
25 | ** GNU General Public License Usage |
26 | ** Alternatively, this file may be used under the terms of the GNU |
27 | ** General Public License version 2.0 or (at your option) the GNU General |
28 | ** Public license version 3 or any later version approved by the KDE Free |
29 | ** Qt Foundation. The licenses are as published by the Free Software |
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
31 | ** included in the packaging of this file. Please review the following |
32 | ** information to ensure the GNU General Public License requirements will |
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
35 | ** |
36 | ** $QT_END_LICENSE$ |
37 | ** |
38 | ****************************************************************************/ |
39 | |
40 | #include "qnetworkreplydataimpl_p.h" |
41 | #include "private/qdataurl_p.h" |
42 | #include <QtCore/QCoreApplication> |
43 | #include <QtCore/QMetaObject> |
44 | |
45 | QT_BEGIN_NAMESPACE |
46 | |
47 | QNetworkReplyDataImplPrivate::QNetworkReplyDataImplPrivate() |
48 | : QNetworkReplyPrivate() |
49 | { |
50 | } |
51 | |
52 | QNetworkReplyDataImplPrivate::~QNetworkReplyDataImplPrivate() |
53 | { |
54 | } |
55 | |
56 | QNetworkReplyDataImpl::~QNetworkReplyDataImpl() |
57 | { |
58 | } |
59 | |
60 | QNetworkReplyDataImpl::QNetworkReplyDataImpl(QObject *parent, const QNetworkRequest &req, const QNetworkAccessManager::Operation op) |
61 | : QNetworkReply(*new QNetworkReplyDataImplPrivate(), parent) |
62 | { |
63 | Q_D(QNetworkReplyDataImpl); |
64 | setRequest(req); |
65 | setUrl(req.url()); |
66 | setOperation(op); |
67 | setFinished(true); |
68 | QNetworkReply::open(mode: QIODevice::ReadOnly); |
69 | |
70 | QUrl url = req.url(); |
71 | QString mimeType; |
72 | QByteArray payload; |
73 | if (qDecodeDataUrl(url, mimeType, payload)) { |
74 | qint64 size = payload.size(); |
75 | setHeader(header: QNetworkRequest::ContentTypeHeader, value: mimeType); |
76 | setHeader(header: QNetworkRequest::ContentLengthHeader, value: size); |
77 | QMetaObject::invokeMethod(obj: this, member: "metaDataChanged" , type: Qt::QueuedConnection); |
78 | |
79 | d->decodedData.setData(payload); |
80 | d->decodedData.open(openMode: QIODevice::ReadOnly); |
81 | |
82 | QMetaObject::invokeMethod(obj: this, member: "downloadProgress" , type: Qt::QueuedConnection, |
83 | Q_ARG(qint64,size), Q_ARG(qint64, size)); |
84 | QMetaObject::invokeMethod(obj: this, member: "readyRead" , type: Qt::QueuedConnection); |
85 | QMetaObject::invokeMethod(obj: this, member: "finished" , type: Qt::QueuedConnection); |
86 | } else { |
87 | // something wrong with this URI |
88 | const QString msg = QCoreApplication::translate(context: "QNetworkAccessDataBackend" , |
89 | key: "Invalid URI: %1" ).arg(a: url.toString()); |
90 | setError(errorCode: QNetworkReply::ProtocolFailure, errorString: msg); |
91 | QMetaObject::invokeMethod(obj: this, member: "errorOccurred" , type: Qt::QueuedConnection, |
92 | Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ProtocolFailure)); |
93 | QMetaObject::invokeMethod(obj: this, member: "finished" , type: Qt::QueuedConnection); |
94 | } |
95 | } |
96 | |
97 | void QNetworkReplyDataImpl::close() |
98 | { |
99 | QNetworkReply::close(); |
100 | } |
101 | |
102 | void QNetworkReplyDataImpl::abort() |
103 | { |
104 | QNetworkReply::close(); |
105 | } |
106 | |
107 | qint64 QNetworkReplyDataImpl::bytesAvailable() const |
108 | { |
109 | Q_D(const QNetworkReplyDataImpl); |
110 | return QNetworkReply::bytesAvailable() + d->decodedData.bytesAvailable(); |
111 | } |
112 | |
113 | bool QNetworkReplyDataImpl::isSequential () const |
114 | { |
115 | return true; |
116 | } |
117 | |
118 | qint64 QNetworkReplyDataImpl::size() const |
119 | { |
120 | Q_D(const QNetworkReplyDataImpl); |
121 | return d->decodedData.size(); |
122 | } |
123 | |
124 | /*! |
125 | \internal |
126 | */ |
127 | qint64 QNetworkReplyDataImpl::readData(char *data, qint64 maxlen) |
128 | { |
129 | Q_D(QNetworkReplyDataImpl); |
130 | |
131 | // TODO idea: |
132 | // Instead of decoding the whole data into new memory, we could decode on demand. |
133 | // Note that this might be tricky to do. |
134 | |
135 | return d->decodedData.read(data, maxlen); |
136 | } |
137 | |
138 | |
139 | QT_END_NAMESPACE |
140 | |
141 | #include "moc_qnetworkreplydataimpl_p.cpp" |
142 | |
143 | |