summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
authorMarkus Goetz <Markus.Goetz@nokia.com>2010-07-28 08:36:33 (GMT)
committerMarkus Goetz <Markus.Goetz@nokia.com>2010-10-05 11:36:32 (GMT)
commit5e2796c35fb829aae3e9870ac1d738a296b08a6e (patch)
tree04fa1fb711613f16ae3d8cb59671762c509ad79f /src/network
parentbbaf34b1f5ac4e6d425eab183112b504b9ed4e83 (diff)
downloadQt-5e2796c35fb829aae3e9870ac1d738a296b08a6e.zip
Qt-5e2796c35fb829aae3e9870ac1d738a296b08a6e.tar.gz
Qt-5e2796c35fb829aae3e9870ac1d738a296b08a6e.tar.bz2
QNAM: New specialized QNetworkReply for data: URLs
Implement a QNetworkReplyDataImpl for data: URLs. This avoids having the overhead of a special backend class of QNetworkReplyImpl. Also move the instantiation to the begin of QNAM::createRequest() so no network sesssion is needed. Reviewed-by: Thiago Macieira Reviewed-by: Peter Hartmann
Diffstat (limited to 'src/network')
-rw-r--r--src/network/access/access.pri2
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp6
-rw-r--r--src/network/access/qnetworkreplydataimpl.cpp146
-rw-r--r--src/network/access/qnetworkreplydataimpl_p.h98
4 files changed, 252 insertions, 0 deletions
diff --git a/src/network/access/access.pri b/src/network/access/access.pri
index e255a0d..9cd2096 100644
--- a/src/network/access/access.pri
+++ b/src/network/access/access.pri
@@ -27,6 +27,7 @@ HEADERS += \
access/qnetworkreply.h \
access/qnetworkreply_p.h \
access/qnetworkreplyimpl_p.h \
+ access/qnetworkreplydataimpl_p.h \
access/qnetworkreplyfileimpl_p.h \
access/qabstractnetworkcache_p.h \
access/qabstractnetworkcache.h \
@@ -55,6 +56,7 @@ SOURCES += \
access/qnetworkrequest.cpp \
access/qnetworkreply.cpp \
access/qnetworkreplyimpl.cpp \
+ access/qnetworkreplydataimpl.cpp \
access/qnetworkreplyfileimpl.cpp \
access/qabstractnetworkcache.cpp \
access/qnetworkdiskcache.cpp
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 9738a4f..add75bf 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -54,6 +54,7 @@
#include "qnetworkaccessfilebackend_p.h"
#include "qnetworkaccessdatabackend_p.h"
#include "qnetworkaccessdebugpipebackend_p.h"
+#include "qnetworkreplydataimpl_p.h"
#include "qnetworkreplyfileimpl_p.h"
#include "QtCore/qbuffer.h"
@@ -955,6 +956,11 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
return new QNetworkReplyFileImpl(this, req, op);
}
+ if ((op == QNetworkAccessManager::GetOperation || op == QNetworkAccessManager::HeadOperation)
+ && req.url().scheme().toLower() == QLatin1String("data")) {
+ return new QNetworkReplyDataImpl(this, req, op);
+ }
+
#ifndef QT_NO_BEARERMANAGEMENT
// Return a disabled network reply if network access is disabled.
// Except if the scheme is empty or file://.
diff --git a/src/network/access/qnetworkreplydataimpl.cpp b/src/network/access/qnetworkreplydataimpl.cpp
new file mode 100644
index 0000000..9e74a21
--- /dev/null
+++ b/src/network/access/qnetworkreplydataimpl.cpp
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnetworkreplydataimpl_p.h"
+#include "private/qdataurl_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QNetworkReplyDataImplPrivate::QNetworkReplyDataImplPrivate()
+ : QNetworkReplyPrivate()
+{
+}
+
+QNetworkReplyDataImplPrivate::~QNetworkReplyDataImplPrivate()
+{
+}
+
+QNetworkReplyDataImpl::~QNetworkReplyDataImpl()
+{
+}
+
+QNetworkReplyDataImpl::QNetworkReplyDataImpl(QObject *parent, const QNetworkRequest &req, const QNetworkAccessManager::Operation op)
+ : QNetworkReply(*new QNetworkReplyDataImplPrivate(), parent)
+{
+ Q_D(QNetworkReplyDataImpl);
+ setRequest(req);
+ setUrl(req.url());
+ setOperation(op);
+ setFinished(true);
+ QNetworkReply::open(QIODevice::ReadOnly);
+
+ QUrl url = req.url();
+
+ // FIXME qDecodeDataUrl should instead be rewritten to have the QByteArray
+ // and the mime type as an output parameter and return a bool instead
+ d->decodeDataUrlResult = qDecodeDataUrl(url);
+
+ if (! d->decodeDataUrlResult.first.isNull()) {
+ QString &mimeType = d->decodeDataUrlResult.first;
+ qint64 size = d->decodeDataUrlResult.second.size();
+ setHeader(QNetworkRequest::ContentTypeHeader, mimeType);
+ setHeader(QNetworkRequest::ContentLengthHeader, size);
+ QMetaObject::invokeMethod(this, "metaDataChanged", Qt::QueuedConnection);
+
+ d->decodedData.setBuffer(&d->decodeDataUrlResult.second);
+ d->decodedData.open(QIODevice::ReadOnly);
+
+ QMetaObject::invokeMethod(this, "downloadProgress", Qt::QueuedConnection,
+ Q_ARG(qint64,size), Q_ARG(qint64, size));
+ QMetaObject::invokeMethod(this, "readyRead", Qt::QueuedConnection);
+ QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
+ } else {
+ // something wrong with this URI
+ const QString msg = QCoreApplication::translate("QNetworkAccessDataBackend",
+ "Invalid URI: %1").arg(url.toString());
+ setError(QNetworkReply::ProtocolFailure, msg);
+ QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
+ Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ProtocolFailure));
+ QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
+ }
+}
+
+void QNetworkReplyDataImpl::close()
+{
+ QNetworkReply::close();
+}
+
+void QNetworkReplyDataImpl::abort()
+{
+ QNetworkReply::close();
+}
+
+qint64 QNetworkReplyDataImpl::bytesAvailable() const
+{
+ Q_D(const QNetworkReplyDataImpl);
+ return QNetworkReply::bytesAvailable() + d->decodedData.bytesAvailable();
+}
+
+bool QNetworkReplyDataImpl::isSequential () const
+{
+ return true;
+}
+
+qint64 QNetworkReplyDataImpl::size() const
+{
+ Q_D(const QNetworkReplyDataImpl);
+ return d->decodedData.size();
+}
+
+/*!
+ \internal
+*/
+qint64 QNetworkReplyDataImpl::readData(char *data, qint64 maxlen)
+{
+ Q_D(QNetworkReplyDataImpl);
+
+ // TODO idea:
+ // Instead of decoding the whole data into new memory, we could decode on demand.
+ // Note that this might be tricky to do.
+
+ return d->decodedData.read(data, maxlen);
+}
+
+
+QT_END_NAMESPACE
+
+#include "moc_qnetworkreplydataimpl_p.cpp"
+
diff --git a/src/network/access/qnetworkreplydataimpl_p.h b/src/network/access/qnetworkreplydataimpl_p.h
new file mode 100644
index 0000000..6c62d28
--- /dev/null
+++ b/src/network/access/qnetworkreplydataimpl_p.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNETWORKREPLYDATAIMPL_H
+#define QNETWORKREPLYDATAIMPL_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the Network Access API. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qnetworkreply.h"
+#include "qnetworkreply_p.h"
+#include "qnetworkaccessmanager.h"
+#include <QBuffer>
+
+QT_BEGIN_NAMESPACE
+
+
+class QNetworkReplyDataImplPrivate;
+class QNetworkReplyDataImpl: public QNetworkReply
+{
+ Q_OBJECT
+public:
+ QNetworkReplyDataImpl(QObject *parent, const QNetworkRequest &req, const QNetworkAccessManager::Operation op);
+ ~QNetworkReplyDataImpl();
+ virtual void abort();
+
+ // reimplemented from QNetworkReply
+ virtual void close();
+ virtual qint64 bytesAvailable() const;
+ virtual bool isSequential () const;
+ qint64 size() const;
+
+ virtual qint64 readData(char *data, qint64 maxlen);
+
+ Q_DECLARE_PRIVATE(QNetworkReplyDataImpl)
+};
+
+class QNetworkReplyDataImplPrivate: public QNetworkReplyPrivate
+{
+public:
+ QNetworkReplyDataImplPrivate();
+ ~QNetworkReplyDataImplPrivate();
+
+ QPair<QString, QByteArray> decodeDataUrlResult;
+ QBuffer decodedData;
+
+ Q_DECLARE_PUBLIC(QNetworkReplyDataImpl)
+};
+
+QT_END_NAMESPACE
+
+#endif // QNETWORKREPLYDATAIMPL_H