qnetworkaccessfilebackend.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/network/access/qnetworkaccessfilebackend.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
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 "qnetworkaccessfilebackend_p.h"-
41#include "qfileinfo.h"-
42#include "qurlinfo_p.h"-
43#include "qdir.h"-
44#include "private/qnoncontiguousbytedevice_p.h"-
45-
46#include <QtCore/QCoreApplication>-
47-
48QT_BEGIN_NAMESPACE-
49-
50QStringList QNetworkAccessFileBackendFactory::supportedSchemes() const-
51{-
52 QStringList schemes;-
53 schemes << QStringLiteral("file")
never executed: return qstring_literal_temp;
0
54 << QStringLiteral("qrc");
never executed: return qstring_literal_temp;
0
55#if defined(Q_OS_ANDROID)-
56 schemes << QStringLiteral("assets");-
57#endif-
58 return schemes;
never executed: return schemes;
0
59}-
60-
61QNetworkAccessBackend *-
62QNetworkAccessFileBackendFactory::create(QNetworkAccessManager::Operation op,-
63 const QNetworkRequest &request) const-
64{-
65 // is it an operation we know of?-
66 switch (op) {-
67 case QNetworkAccessManager::GetOperation:
executed 8 times by 1 test: case QNetworkAccessManager::GetOperation:
Executed by:
  • tst_QNetworkReply
8
68 case QNetworkAccessManager::PutOperation:
executed 39 times by 1 test: case QNetworkAccessManager::PutOperation:
Executed by:
  • tst_QNetworkReply
39
69 break;
executed 47 times by 1 test: break;
Executed by:
  • tst_QNetworkReply
47
70-
71 default:
never executed: default:
0
72 // no, we can't handle this operation-
73 return 0;
never executed: return 0;
0
74 }-
75-
76 QUrl url = request.url();-
77 if (url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0
url.scheme().c...ensitive) == 0Description
TRUEnever evaluated
FALSEevaluated 47 times by 1 test
Evaluated by:
  • tst_QNetworkReply
0-47
78#if defined(Q_OS_ANDROID)-
79 || url.scheme().compare(QLatin1String("assets"), Qt::CaseInsensitive) == 0-
80#endif-
81 || url.isLocalFile()) {
url.isLocalFile()Description
TRUEevaluated 39 times by 1 test
Evaluated by:
  • tst_QNetworkReply
FALSEevaluated 8 times by 1 test
Evaluated by:
  • tst_QNetworkReply
8-39
82 return new QNetworkAccessFileBackend;
executed 39 times by 1 test: return new QNetworkAccessFileBackend;
Executed by:
  • tst_QNetworkReply
39
83 } else if (!url.scheme().isEmpty() && url.authority().isEmpty() && (url.scheme().length() > 1)) {
!url.scheme().isEmpty()Description
TRUEevaluated 5 times by 1 test
Evaluated by:
  • tst_QNetworkReply
FALSEevaluated 3 times by 1 test
Evaluated by:
  • tst_QNetworkReply
url.authority().isEmpty()Description
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tst_QNetworkReply
FALSEevaluated 1 time by 1 test
Evaluated by:
  • tst_QNetworkReply
(url.scheme().length() > 1)Description
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tst_QNetworkReply
FALSEnever evaluated
0-5
84 // check if QFile could, in theory, open this URL via the file engines-
85 // it has to be in the format:-
86 // prefix:path/to/file-
87 // or prefix:/path/to/file-
88 //-
89 // this construct here must match the one below in open()-
90 QFileInfo fi(url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery));-
91 if (fi.exists() || (op == QNetworkAccessManager::PutOperation && fi.dir().exists()))
fi.exists()Description
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tst_QNetworkReply
FALSEnever evaluated
op == QNetwork...::PutOperationDescription
TRUEnever evaluated
FALSEnever evaluated
fi.dir().exists()Description
TRUEnever evaluated
FALSEnever evaluated
0-4
92 return new QNetworkAccessFileBackend;
executed 4 times by 1 test: return new QNetworkAccessFileBackend;
Executed by:
  • tst_QNetworkReply
4
93 }
never executed: end of block
0
94-
95 return 0;
executed 4 times by 1 test: return 0;
Executed by:
  • tst_QNetworkReply
4
96}-
97-
98QNetworkAccessFileBackend::QNetworkAccessFileBackend()-
99 : uploadByteDevice(0), totalBytes(0), hasUploadFinished(false)-
100{-
101}
executed 43 times by 1 test: end of block
Executed by:
  • tst_QNetworkReply
43
102-
103QNetworkAccessFileBackend::~QNetworkAccessFileBackend()-
104{-
105}-
106-
107void QNetworkAccessFileBackend::open()-
108{-
109 QUrl url = this->url();-
110-
111 if (url.host() == QLatin1String("localhost"))
url.host() == ...g("localhost")Description
TRUEnever evaluated
FALSEevaluated 43 times by 1 test
Evaluated by:
  • tst_QNetworkReply
0-43
112 url.setHost(QString());
never executed: url.setHost(QString());
0
113#if !defined(Q_OS_WIN)-
114 // do not allow UNC paths on Unix-
115 if (!url.host().isEmpty()) {
!url.host().isEmpty()Description
TRUEnever evaluated
FALSEevaluated 43 times by 1 test
Evaluated by:
  • tst_QNetworkReply
0-43
116 // we handle only local files-
117 error(QNetworkReply::ProtocolInvalidOperationError,-
118 QCoreApplication::translate("QNetworkAccessFileBackend", "Request for opening non-local file %1").arg(url.toString()));-
119 finished();-
120 return;
never executed: return;
0
121 }-
122#endif // !defined(Q_OS_WIN)-
123 if (url.path().isEmpty())
url.path().isEmpty()Description
TRUEnever evaluated
FALSEevaluated 43 times by 1 test
Evaluated by:
  • tst_QNetworkReply
0-43
124 url.setPath(QLatin1String("/"));
never executed: url.setPath(QLatin1String("/"));
0
125 setUrl(url);-
126-
127 QString fileName = url.toLocalFile();-
128 if (fileName.isEmpty()) {
fileName.isEmpty()Description
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tst_QNetworkReply
FALSEevaluated 39 times by 1 test
Evaluated by:
  • tst_QNetworkReply
4-39
129 if (url.scheme() == QLatin1String("qrc")) {
url.scheme() =...1String("qrc")Description
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tst_QNetworkReply
0-4
130 fileName = QLatin1Char(':') + url.path();-
131 } else {
never executed: end of block
0
132#if defined(Q_OS_ANDROID)-
133 if (url.scheme() == QLatin1String("assets"))-
134 fileName = QLatin1String("assets:") + url.path();-
135 else-
136#endif-
137 fileName = url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery);-
138 }
executed 4 times by 1 test: end of block
Executed by:
  • tst_QNetworkReply
4
139 }-
140 file.setFileName(fileName);-
141-
142 if (operation() == QNetworkAccessManager::GetOperation) {
operation() ==...::GetOperationDescription
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tst_QNetworkReply
FALSEevaluated 39 times by 1 test
Evaluated by:
  • tst_QNetworkReply
4-39
143 if (!loadFileInfo())
!loadFileInfo()Description
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tst_QNetworkReply
0-4
144 return;
never executed: return;
0
145 }
executed 4 times by 1 test: end of block
Executed by:
  • tst_QNetworkReply
4
146-
147 QIODevice::OpenMode mode;-
148 switch (operation()) {-
149 case QNetworkAccessManager::GetOperation:
executed 4 times by 1 test: case QNetworkAccessManager::GetOperation:
Executed by:
  • tst_QNetworkReply
4
150 mode = QIODevice::ReadOnly;-
151 break;
executed 4 times by 1 test: break;
Executed by:
  • tst_QNetworkReply
4
152 case QNetworkAccessManager::PutOperation:
executed 39 times by 1 test: case QNetworkAccessManager::PutOperation:
Executed by:
  • tst_QNetworkReply
39
153 mode = QIODevice::WriteOnly | QIODevice::Truncate;-
154 uploadByteDevice = createUploadByteDevice();-
155 QObject::connect(uploadByteDevice, SIGNAL(readyRead()), this, SLOT(uploadReadyReadSlot()));-
156 QMetaObject::invokeMethod(this, "uploadReadyReadSlot", Qt::QueuedConnection);-
157 break;
executed 39 times by 1 test: break;
Executed by:
  • tst_QNetworkReply
39
158 default:
never executed: default:
0
159 Q_ASSERT_X(false, "QNetworkAccessFileBackend::open",-
160 "Got a request operation I cannot handle!!");-
161 return;
never executed: return;
0
162 }-
163-
164 mode |= QIODevice::Unbuffered;-
165 bool opened = file.open(mode);-
166-
167 // could we open the file?-
168 if (!opened) {
!openedDescription
TRUEnever evaluated
FALSEevaluated 43 times by 1 test
Evaluated by:
  • tst_QNetworkReply
0-43
169 QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Error opening %1: %2")-
170 .arg(this->url().toString(), file.errorString());-
171-
172 // why couldn't we open the file?-
173 // if we're opening for reading, either it doesn't exist, or it's access denied-
174 // if we're opening for writing, not existing means it's access denied too-
175 if (file.exists() || operation() == QNetworkAccessManager::PutOperation)
file.exists()Description
TRUEnever evaluated
FALSEnever evaluated
operation() ==...::PutOperationDescription
TRUEnever evaluated
FALSEnever evaluated
0
176 error(QNetworkReply::ContentAccessDenied, msg);
never executed: error(QNetworkReply::ContentAccessDenied, msg);
0
177 else-
178 error(QNetworkReply::ContentNotFoundError, msg);
never executed: error(QNetworkReply::ContentNotFoundError, msg);
0
179 finished();-
180 }
never executed: end of block
0
181}
executed 43 times by 1 test: end of block
Executed by:
  • tst_QNetworkReply
43
182-
183void QNetworkAccessFileBackend::uploadReadyReadSlot()-
184{-
185 if (hasUploadFinished)
hasUploadFinishedDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • tst_QNetworkReply
FALSEevaluated 124 times by 1 test
Evaluated by:
  • tst_QNetworkReply
2-124
186 return;
executed 2 times by 1 test: return;
Executed by:
  • tst_QNetworkReply
2
187-
188 forever {-
189 qint64 haveRead;-
190 const char *readPointer = uploadByteDevice->readPointer(-1, haveRead);-
191 if (haveRead == -1) {
haveRead == -1Description
TRUEevaluated 39 times by 1 test
Evaluated by:
  • tst_QNetworkReply
FALSEevaluated 672 times by 1 test
Evaluated by:
  • tst_QNetworkReply
39-672
192 // EOF-
193 hasUploadFinished = true;-
194 file.flush();-
195 file.close();-
196 finished();-
197 break;
executed 39 times by 1 test: break;
Executed by:
  • tst_QNetworkReply
39
198 } else if (haveRead == 0 || readPointer == 0) {
haveRead == 0Description
TRUEevaluated 85 times by 1 test
Evaluated by:
  • tst_QNetworkReply
FALSEevaluated 587 times by 1 test
Evaluated by:
  • tst_QNetworkReply
readPointer == 0Description
TRUEnever evaluated
FALSEevaluated 587 times by 1 test
Evaluated by:
  • tst_QNetworkReply
0-587
199 // nothing to read right now, we will be called again later-
200 break;
executed 85 times by 1 test: break;
Executed by:
  • tst_QNetworkReply
85
201 } else {-
202 qint64 haveWritten;-
203 haveWritten = file.write(readPointer, haveRead);-
204-
205 if (haveWritten < 0) {
haveWritten < 0Description
TRUEnever evaluated
FALSEevaluated 587 times by 1 test
Evaluated by:
  • tst_QNetworkReply
0-587
206 // write error!-
207 QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Write error writing to %1: %2")-
208 .arg(url().toString(), file.errorString());-
209 error(QNetworkReply::ProtocolFailure, msg);-
210-
211 finished();-
212 return;
never executed: return;
0
213 } else {-
214 uploadByteDevice->advanceReadPointer(haveWritten);-
215 }
executed 587 times by 1 test: end of block
Executed by:
  • tst_QNetworkReply
587
216-
217-
218 file.flush();-
219 }
executed 587 times by 1 test: end of block
Executed by:
  • tst_QNetworkReply
587
220 }-
221}
executed 124 times by 1 test: end of block
Executed by:
  • tst_QNetworkReply
124
222-
223void QNetworkAccessFileBackend::closeDownstreamChannel()-
224{-
225 if (operation() == QNetworkAccessManager::GetOperation) {
operation() ==...::GetOperationDescription
TRUEnever evaluated
FALSEnever evaluated
0
226 file.close();-
227 }
never executed: end of block
0
228}
never executed: end of block
0
229-
230void QNetworkAccessFileBackend::downstreamReadyWrite()-
231{-
232 Q_ASSERT_X(operation() == QNetworkAccessManager::GetOperation, "QNetworkAccessFileBackend",-
233 "We're being told to download data but operation isn't GET!");-
234-
235 readMoreFromFile();-
236}
executed 4 times by 1 test: end of block
Executed by:
  • tst_QNetworkReply
4
237-
238bool QNetworkAccessFileBackend::loadFileInfo()-
239{-
240 QFileInfo fi(file);-
241 setHeader(QNetworkRequest::LastModifiedHeader, fi.lastModified());-
242 setHeader(QNetworkRequest::ContentLengthHeader, fi.size());-
243-
244 // signal we're open-
245 metaDataChanged();-
246-
247 if (fi.isDir()) {
fi.isDir()Description
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tst_QNetworkReply
0-4
248 error(QNetworkReply::ContentOperationNotPermittedError,-
249 QCoreApplication::translate("QNetworkAccessFileBackend", "Cannot open %1: Path is a directory").arg(url().toString()));-
250 finished();-
251 return false;
never executed: return false;
0
252 }-
253-
254 return true;
executed 4 times by 1 test: return true;
Executed by:
  • tst_QNetworkReply
4
255}-
256-
257bool QNetworkAccessFileBackend::readMoreFromFile()-
258{-
259 qint64 wantToRead;-
260 while ((wantToRead = nextDownstreamBlockSize()) > 0) {
(wantToRead = ...ockSize()) > 0Description
TRUEevaluated 38 times by 1 test
Evaluated by:
  • tst_QNetworkReply
FALSEnever evaluated
0-38
261 // ### FIXME!!-
262 // Obtain a pointer from the ringbuffer!-
263 // Avoid extra copy-
264 QByteArray data;-
265 data.reserve(wantToRead);-
266 qint64 actuallyRead = file.read(data.data(), wantToRead);-
267 if (actuallyRead <= 0) {
actuallyRead <= 0Description
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tst_QNetworkReply
FALSEevaluated 34 times by 1 test
Evaluated by:
  • tst_QNetworkReply
4-34
268 // EOF or error-
269 if (file.error() != QFile::NoError) {
file.error() != QFile::NoErrorDescription
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tst_QNetworkReply
0-4
270 QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Read error reading from %1: %2")-
271 .arg(url().toString(), file.errorString());-
272 error(QNetworkReply::ProtocolFailure, msg);-
273-
274 finished();-
275 return false;
never executed: return false;
0
276 }-
277-
278 finished();-
279 return true;
executed 4 times by 1 test: return true;
Executed by:
  • tst_QNetworkReply
4
280 }-
281-
282 data.resize(actuallyRead);-
283 totalBytes += actuallyRead;-
284-
285 QByteDataBuffer list;-
286 list.append(data);-
287 data.clear(); // important because of implicit sharing!-
288 writeDownstreamData(list);-
289 }
executed 34 times by 1 test: end of block
Executed by:
  • tst_QNetworkReply
34
290 return true;
never executed: return true;
0
291}-
292-
293QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9