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
45QT_BEGIN_NAMESPACE
46
47QNetworkReplyDataImplPrivate::QNetworkReplyDataImplPrivate()
48 : QNetworkReplyPrivate()
49{
50}
51
52QNetworkReplyDataImplPrivate::~QNetworkReplyDataImplPrivate()
53{
54}
55
56QNetworkReplyDataImpl::~QNetworkReplyDataImpl()
57{
58}
59
60QNetworkReplyDataImpl::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(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(QNetworkRequest::ContentTypeHeader, mimeType);
76 setHeader(QNetworkRequest::ContentLengthHeader, size);
77 QMetaObject::invokeMethod(this, "metaDataChanged", Qt::QueuedConnection);
78
79 d->decodedData.setData(payload);
80 d->decodedData.open(QIODevice::ReadOnly);
81
82 QMetaObject::invokeMethod(this, "downloadProgress", Qt::QueuedConnection,
83 Q_ARG(qint64,size), Q_ARG(qint64, size));
84 QMetaObject::invokeMethod(this, "readyRead", Qt::QueuedConnection);
85 QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
86 } else {
87 // something wrong with this URI
88 const QString msg = QCoreApplication::translate("QNetworkAccessDataBackend",
89 "Invalid URI: %1").arg(url.toString());
90 setError(QNetworkReply::ProtocolFailure, msg);
91 QMetaObject::invokeMethod(this, "errorOccurred", Qt::QueuedConnection,
92 Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ProtocolFailure));
93 QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
94 }
95}
96
97void QNetworkReplyDataImpl::close()
98{
99 QNetworkReply::close();
100}
101
102void QNetworkReplyDataImpl::abort()
103{
104 QNetworkReply::close();
105}
106
107qint64 QNetworkReplyDataImpl::bytesAvailable() const
108{
109 Q_D(const QNetworkReplyDataImpl);
110 return QNetworkReply::bytesAvailable() + d->decodedData.bytesAvailable();
111}
112
113bool QNetworkReplyDataImpl::isSequential () const
114{
115 return true;
116}
117
118qint64 QNetworkReplyDataImpl::size() const
119{
120 Q_D(const QNetworkReplyDataImpl);
121 return d->decodedData.size();
122}
123
124/*!
125 \internal
126*/
127qint64 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
139QT_END_NAMESPACE
140
141#include "moc_qnetworkreplydataimpl_p.cpp"
142
143