Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qnetworkreplyfileimpl.cpp
Go to the documentation of this file.
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
5
6#include "QtCore/qdatetime.h"
8#include <QtCore/QCoreApplication>
9#include <QtCore/QFileInfo>
10#include <QtCore/QThread>
11#include "qnetworkfile_p.h"
12#include "qnetworkrequest.h"
13
15
16using namespace Qt::StringLiterals;
17
19
21 : QNetworkReplyPrivate(), managerPrivate(nullptr), realFile(nullptr)
22{
23 qRegisterMetaType<QNetworkRequest::KnownHeaders>();
24 qRegisterMetaType<QNetworkReply::NetworkError>();
25}
26
28{
30 if (d->realFile) {
31 if (d->realFile->thread() == QThread::currentThread())
32 delete d->realFile;
33 else
34 QMetaObject::invokeMethod(d->realFile, "deleteLater", Qt::QueuedConnection);
35 }
36}
37
40{
41 setRequest(req);
42 setUrl(req.url());
43 setOperation(op);
45
47
48 d->managerPrivate = manager->d_func();
49
50 QUrl url = req.url();
51 if (url.host() == "localhost"_L1)
53
54#if !defined(Q_OS_WIN)
55 // do not allow UNC paths on Unix
56 if (!url.host().isEmpty()) {
57 // we handle only local files
58 QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Request for opening non-local file %1").arg(url.toString());
60 setFinished(true); // We're finished, will emit finished() after ctor is done.
63 QMetaObject::invokeMethod(this, [this](){ fileOpenFinished(false); }, Qt::QueuedConnection);
64 return;
65 }
66#endif
67 if (url.path().isEmpty())
68 url.setPath("/"_L1);
69 setUrl(url);
70
72 if (fileName.isEmpty()) {
73 const QString scheme = url.scheme();
74 if (scheme == "qrc"_L1) {
75 fileName = u':' + url.path();
76 } else {
77#if defined(Q_OS_ANDROID)
78 if (scheme == "assets"_L1)
79 fileName = "assets:"_L1 + url.path();
80 else
81#endif
83 }
84 }
85
86 if (req.attribute(QNetworkRequest::BackgroundRequestAttribute).toBool()) { // Asynchronous open
87 auto realFile = new QNetworkFile(fileName);
92 connect(realFile, SIGNAL(finished(bool)), SLOT(fileOpenFinished(bool)),
94
95 realFile->moveToThread(d->managerPrivate->createThread());
97
98 d->realFile = realFile;
99 } else { // Synch open
100 setFinished(true);
101
103 if (fi.isDir()) {
104 QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Cannot open %1: Path is a directory").arg(url.toString());
106 QMetaObject::invokeMethod(this, "errorOccurred", Qt::QueuedConnection,
109 return;
110 }
111 d->realFile = new QFile(fileName, this);
112 bool opened = d->realFile->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
113
114 // could we open the file?
115 if (!opened) {
116 QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Error opening %1: %2")
117 .arg(d->realFile->fileName(), d->realFile->errorString());
118
119 if (fi.exists()) {
121 QMetaObject::invokeMethod(this, "errorOccurred", Qt::QueuedConnection,
123 } else {
125 QMetaObject::invokeMethod(this, "errorOccurred", Qt::QueuedConnection,
127 }
129 return;
130 }
133
134 QMetaObject::invokeMethod(this, "metaDataChanged", Qt::QueuedConnection);
135 QMetaObject::invokeMethod(this, "downloadProgress", Qt::QueuedConnection,
136 Q_ARG(qint64, fi.size()), Q_ARG(qint64, fi.size()));
139 }
140}
141
143{
146 if (d->realFile) {
147 if (d->realFile->thread() == thread())
148 d->realFile->close();
149 else
151 }
152}
153
155{
156 close();
157}
158
160{
161 Q_D(const QNetworkReplyFileImpl);
162 if (!d->isFinished || !d->realFile || !d->realFile->isOpen())
164 return QNetworkReply::bytesAvailable() + d->realFile->bytesAvailable();
165}
166
168{
169 return true;
170}
171
173{
174 bool ok;
176 return ok ? size : 0;
177}
178
183{
185 if (!d->isFinished || !d->realFile || !d->realFile->isOpen())
186 return -1;
187 qint64 ret = d->realFile->read(data, maxlen);
188 if (bytesAvailable() == 0)
189 d->realFile->close();
190 if (ret == 0 && bytesAvailable() == 0)
191 return -1;
192 else {
195 return ret;
196 }
197}
198
199void QNetworkReplyFileImpl::fileOpenFinished(bool isOpen)
200{
201 setFinished(true);
202 if (isOpen) {
203 const auto fileSize = size();
205 Q_EMIT downloadProgress(fileSize, fileSize);
207 }
209}
210
212
213#include "moc_qnetworkreplyfileimpl_p.cpp"
214
static QString translate(const char *context, const char *key, const char *disambiguation=nullptr, int n=-1)
\threadsafe
\inmodule QtCore \reentrant
Definition qfileinfo.h:22
QDateTime lastModified() const
Returns the date and time when the file was last modified.
Definition qfileinfo.h:156
bool isDir() const
Returns true if this object points to a directory or to a symbolic link to a directory.
qint64 size() const
Returns the file size in bytes.
bool exists() const
Returns true if the file exists; otherwise returns false.
\inmodule QtCore
Definition qfile.h:93
virtual bool open(QIODeviceBase::OpenMode mode)
Opens the device and sets its OpenMode to mode.
void readyRead()
This signal is emitted once every time new data is available for reading from the device's current re...
bool isOpen() const
Returns true if the device is open; otherwise returns false.
virtual qint64 bytesAvailable() const
Returns the number of bytes that are available for reading.
The QNetworkAccessManager class allows the application to send network requests and receive replies.
Operation
Indicates the operation this reply is processing.
void error(QNetworkReply::NetworkError error, const QString &message)
void headerRead(QNetworkRequest::KnownHeaders header, const QVariant &value)
virtual void close() override
Closes this device for reading.
virtual qint64 readData(char *data, qint64 maxlen) override
virtual bool isSequential() const override
QNetworkReplyFileImpl(QNetworkAccessManager *manager, const QNetworkRequest &req, const QNetworkAccessManager::Operation op)
virtual qint64 bytesAvailable() const override
Returns the number of bytes that are available for reading.
virtual void abort() override
Aborts the operation immediately and close down any network connections still open.
qint64 size() const override
For open random-access devices, this function returns the size of the device.
The QNetworkReply class contains the data and headers for a request sent with QNetworkAccessManager.
QNetworkAccessManager * manager() const
Returns the QNetworkAccessManager that was used to create this QNetworkReply object.
void setError(NetworkError errorCode, const QString &errorString)
Sets the error condition to be errorCode.
virtual void close() override
Closes this device for reading.
void setOperation(QNetworkAccessManager::Operation operation)
Sets the associated operation for this object to be operation.
void metaDataChanged()
\omit FIXME: Update name? \endomit
void setUrl(const QUrl &url)
Sets the URL being processed to be url.
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
This signal is emitted to indicate the progress of the download part of this network request,...
void setAttribute(QNetworkRequest::Attribute code, const QVariant &value)
Sets the attribute code to have value value.
QVariant header(QNetworkRequest::KnownHeaders header) const
Returns the value of the known header header, if that header was sent by the remote server.
void setRequest(const QNetworkRequest &request)
Sets the associated request for this object to be request.
NetworkError
Indicates all possible error conditions found during the processing of the request.
@ ContentOperationNotPermittedError
@ ProtocolInvalidOperationError
void setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value)
Sets the known header header to be of value value.
void setFinished(bool)
void finished()
This signal is emitted when the reply has finished processing.
QUrl url() const
Returns the URL of the content downloaded or uploaded.
The QNetworkRequest class holds a request to be sent with QNetworkAccessManager.
KnownHeaders
List of known header types that QNetworkRequest parses.
QVariant attribute(Attribute code, const QVariant &defaultValue=QVariant()) const
Returns the attribute associated with the code code.
QUrl url() const
Returns the URL this network request is referring to.
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2823
QThread * thread() const
Returns the thread in which the object lives.
Definition qobject.cpp:1561
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
Definition qstring.cpp:8606
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
static QThread * currentThread()
Definition qthread.cpp:966
\inmodule QtCore
Definition qurl.h:94
QString host(ComponentFormattingOptions=FullyDecoded) const
Returns the host of the URL if it is defined; otherwise an empty string is returned.
Definition qurl.cpp:2337
QString scheme() const
Returns the scheme of the URL.
Definition qurl.cpp:1983
@ RemoveFragment
Definition qurl.h:112
@ RemoveQuery
Definition qurl.h:111
@ RemoveAuthority
Definition qurl.h:109
void setHost(const QString &host, ParsingMode mode=DecodedMode)
Sets the host of the URL to host.
Definition qurl.cpp:2286
void setPath(const QString &path, ParsingMode mode=DecodedMode)
Sets the path of the URL to path.
Definition qurl.cpp:2411
QString toString(FormattingOptions options=FormattingOptions(PrettyDecoded)) const
Returns a string representation of the URL.
Definition qurl.cpp:2828
QString toLocalFile() const
Returns the path of this URL formatted as a local file path.
Definition qurl.cpp:3411
QString path(ComponentFormattingOptions options=FullyDecoded) const
Returns the path of the URL.
Definition qurl.cpp:2465
int toInt(bool *ok=nullptr) const
Returns the variant as an int if the variant has userType() \l QMetaType::Int, \l QMetaType::Bool,...
bool toBool() const
Returns the variant as a bool if the variant has userType() Bool.
Combined button and popup list for selecting options.
@ QueuedConnection
return ret
#define QT_IMPL_METATYPE_EXTERN_TAGGED(TYPE, TAG)
Definition qmetatype.h:1363
#define SLOT(a)
Definition qobjectdefs.h:51
#define Q_ARG(Type, data)
Definition qobjectdefs.h:62
#define SIGNAL(a)
Definition qobjectdefs.h:52
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
#define Q_EMIT
long long qint64
Definition qtypes.h:55
QFileInfo fi("c:/temp/foo")
[newstuff]
QNetworkAccessManager manager
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(nullptr), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
\threadsafe This is an overloaded member function, provided for convenience. It differs from the abov...