--- a/src/network/access/qfilenetworkreply.cpp Tue Feb 02 00:43:10 2010 +0200
+++ b/src/network/access/qfilenetworkreply.cpp Fri Apr 16 15:50:13 2010 +0300
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
@@ -44,35 +44,37 @@
#include "QtCore/qdatetime.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QFileInfo>
+#include <QDebug>
QT_BEGIN_NAMESPACE
QFileNetworkReplyPrivate::QFileNetworkReplyPrivate()
- : QNetworkReplyPrivate(), realFileSize(0), finished(false)
+ : QNetworkReplyPrivate(), fileEngine(0), fileSize(0), filePos(0)
{
}
-QFileNetworkReply::QFileNetworkReply(QObject *parent, const QNetworkRequest &req)
- : QNetworkReply(*new QFileNetworkReplyPrivate(), parent)
+QFileNetworkReplyPrivate::~QFileNetworkReplyPrivate()
{
- setRequest(req);
- setUrl(req.url());
- setOperation(QNetworkAccessManager::GetOperation);
- QMetaObject::invokeMethod(this, "_q_startOperation", Qt::QueuedConnection);
- QNetworkReply::open(QIODevice::ReadOnly);
+ delete fileEngine;
}
QFileNetworkReply::~QFileNetworkReply()
{
}
-// This code is mostly inspired by QNetworkAccessFileBackend
-// We also use its translation context for error messages
-void QFileNetworkReplyPrivate::_q_startOperation()
+QFileNetworkReply::QFileNetworkReply(QObject *parent, const QNetworkRequest &req, const QNetworkAccessManager::Operation op)
+ : QNetworkReply(*new QFileNetworkReplyPrivate(), parent)
{
- Q_Q(QFileNetworkReply);
+ setRequest(req);
+ setUrl(req.url());
+ setOperation(op);
+ QNetworkReply::open(QIODevice::ReadOnly);
- QUrl url = q->url();
+ qRegisterMetaType<QNetworkReply::NetworkError>("QNetworkReply::NetworkError");
+
+ QFileNetworkReplyPrivate *d = (QFileNetworkReplyPrivate*) d_func();
+
+ QUrl url = req.url();
if (url.host() == QLatin1String("localhost"))
url.setHost(QString());
@@ -81,97 +83,93 @@
if (!url.host().isEmpty()) {
// we handle only local files
QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Request for opening non-local file %1").arg(url.toString());
- q->setError(QNetworkReply::ProtocolInvalidOperationError, msg);
- emit q->error(QNetworkReply::ProtocolInvalidOperationError);
- doFinished();
+ setError(QNetworkReply::ProtocolInvalidOperationError, msg);
+ QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
+ Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ProtocolInvalidOperationError));
+ QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
return;
}
#endif
if (url.path().isEmpty())
url.setPath(QLatin1String("/"));
- q->setUrl(url);
+ setUrl(url);
QString fileName = url.toLocalFile();
if (fileName.isEmpty()) {
fileName = url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery);
}
- realFile.setFileName(fileName);
- QFileInfo fi(realFile);
+ QFileInfo fi(fileName);
if (fi.isDir()) {
QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Cannot open %1: Path is a directory").arg(url.toString());
- q->setError(QNetworkReply::ContentOperationNotPermittedError, msg);
- emit q->error(QNetworkReply::ContentOperationNotPermittedError);
- doFinished();
+ setError(QNetworkReply::ContentOperationNotPermittedError, msg);
+ QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
+ Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ContentOperationNotPermittedError));
+ QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
return;
}
- bool opened = realFile.open(QIODevice::ReadOnly | QIODevice::Unbuffered);
+ d->fileEngine = QAbstractFileEngine::create(fileName);
+ bool opened = d->fileEngine->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
// could we open the file?
if (!opened) {
QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Error opening %1: %2")
- .arg(realFile.fileName(), realFile.errorString());
+ .arg(fileName, d->fileEngine->errorString());
- if (realFile.exists()) {
- q->setError(QNetworkReply::ContentAccessDenied, msg);
- emit q->error(QNetworkReply::ContentAccessDenied);
+ if (fi.exists()) {
+ setError(QNetworkReply::ContentAccessDenied, msg);
+ QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
+ Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ContentAccessDenied));
} else {
- q->setError(QNetworkReply::ContentNotFoundError, msg);
- emit q->error(QNetworkReply::ContentNotFoundError);
+ setError(QNetworkReply::ContentNotFoundError, msg);
+ QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
+ Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ContentNotFoundError));
}
- doFinished();
+ QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
return;
}
- realFileSize = fi.size();
- q->setHeader(QNetworkRequest::LastModifiedHeader, fi.lastModified());
- q->setHeader(QNetworkRequest::ContentLengthHeader, realFileSize);
+ d->fileSize = fi.size();
+ setHeader(QNetworkRequest::LastModifiedHeader, fi.lastModified());
+ setHeader(QNetworkRequest::ContentLengthHeader, d->fileSize);
- emit q->metaDataChanged();
- emit q->downloadProgress(realFileSize, realFileSize);
- emit q->readyRead();
- doFinished();
+ QMetaObject::invokeMethod(this, "metaDataChanged", Qt::QueuedConnection);
+ QMetaObject::invokeMethod(this, "downloadProgress", Qt::QueuedConnection,
+ Q_ARG(qint64, d->fileSize), Q_ARG(qint64, d->fileSize));
+ QMetaObject::invokeMethod(this, "readyRead", Qt::QueuedConnection);
+ QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
}
bool QFileNetworkReplyPrivate::isFinished() const
{
- return finished;
+ return true;
}
-void QFileNetworkReplyPrivate::doFinished()
-{
- Q_Q(QFileNetworkReply);
- finished = true;
- emit q->finished();
-}
-
-
void QFileNetworkReply::close()
{
Q_D(QFileNetworkReply);
QNetworkReply::close();
- d->realFile.close();
-
- if (!d->finished)
- d->doFinished();
+ if (d->fileEngine)
+ d->fileEngine->close();
}
void QFileNetworkReply::abort()
{
Q_D(QFileNetworkReply);
QNetworkReply::close();
- d->realFile.close();
-
- if (!d->finished)
- d->doFinished();
+ if (d->fileEngine)
+ d->fileEngine->close();
}
qint64 QFileNetworkReply::bytesAvailable() const
{
Q_D(const QFileNetworkReply);
- return QNetworkReply::bytesAvailable() + d->realFile.bytesAvailable();
+ if (!d->fileEngine)
+ return 0;
+
+ return QNetworkReply::bytesAvailable() + d->fileSize - d->filePos;
}
bool QFileNetworkReply::isSequential () const
@@ -182,7 +180,7 @@
qint64 QFileNetworkReply::size() const
{
Q_D(const QFileNetworkReply);
- return d->realFileSize;
+ return d->fileSize;
}
/*!
@@ -191,11 +189,17 @@
qint64 QFileNetworkReply::readData(char *data, qint64 maxlen)
{
Q_D(QFileNetworkReply);
- qint64 ret = d->realFile.read(data, maxlen);
- if (ret == 0 && bytesAvailable() == 0)
+ if (!d->fileEngine)
+ return -1;
+
+ qint64 ret = d->fileEngine->read(data, maxlen);
+ if (ret == 0 && bytesAvailable() == 0) {
return -1; // everything had been read
- else
- return ret;
+ } else if (ret > 0) {
+ d->filePos += ret;
+ }
+
+ return ret;
}