| Line | Source Code | Coverage |
|---|
| 1 | /**************************************************************************** | - |
| 2 | ** | - |
| 3 | ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). | - |
| 4 | ** Contact: http://www.qt-project.org/legal | - |
| 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 Digia. For licensing terms and | - |
| 14 | ** conditions see http://qt.digia.com/licensing. For further information | - |
| 15 | ** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software | - |
| 20 | ** Foundation and appearing in the file LICENSE.LGPL included in the | - |
| 21 | ** packaging of this file. Please review the following information to | - |
| 22 | ** ensure the GNU Lesser General Public License version 2.1 requirements | - |
| 23 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. | - |
| 24 | ** | - |
| 25 | ** In addition, as a special exception, Digia gives you certain additional | - |
| 26 | ** rights. These rights are described in the Digia Qt LGPL Exception | - |
| 27 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | - |
| 28 | ** | - |
| 29 | ** GNU General Public License Usage | - |
| 30 | ** Alternatively, this file may be used under the terms of the GNU | - |
| 31 | ** General Public License version 3.0 as published by the Free Software | - |
| 32 | ** Foundation and appearing in the file LICENSE.GPL included in the | - |
| 33 | ** packaging of this file. Please review the following information to | - |
| 34 | ** ensure the GNU General Public License version 3.0 requirements will be | - |
| 35 | ** met: http://www.gnu.org/copyleft/gpl.html. | - |
| 36 | ** | - |
| 37 | ** | - |
| 38 | ** $QT_END_LICENSE$ | - |
| 39 | ** | - |
| 40 | ****************************************************************************/ | - |
| 41 | | - |
| 42 | #include "qnetworkaccessfilebackend_p.h" | - |
| 43 | #include "qfileinfo.h" | - |
| 44 | #include "qurlinfo_p.h" | - |
| 45 | #include "qdir.h" | - |
| 46 | #include "private/qnoncontiguousbytedevice_p.h" | - |
| 47 | | - |
| 48 | #include <QtCore/QCoreApplication> | - |
| 49 | | - |
| 50 | QT_BEGIN_NAMESPACE | - |
| 51 | | - |
| 52 | QNetworkAccessBackend * | - |
| 53 | QNetworkAccessFileBackendFactory::create(QNetworkAccessManager::Operation op, | - |
| 54 | const QNetworkRequest &request) const | - |
| 55 | { | - |
| 56 | // is it an operation we know of? | - |
| 57 | switch (op) { | - |
| 58 | case QNetworkAccessManager::GetOperation: | - |
| 59 | case QNetworkAccessManager::PutOperation: | - |
| 60 | break; executed: break;Execution Count:47 | 47 |
| 61 | | - |
| 62 | default: | - |
| 63 | // no, we can't handle this operation | - |
| 64 | return 0; never executed: return 0; | 0 |
| 65 | } | - |
| 66 | | - |
| 67 | QUrl url = request.url(); executed (the execution status of this line is deduced): QUrl url = request.url(); | - |
| 68 | if (url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0 || url.isLocalFile()) { partially evaluated: url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0| no Evaluation Count:0 | yes Evaluation Count:47 |
evaluated: url.isLocalFile()| yes Evaluation Count:39 | yes Evaluation Count:8 |
| 0-47 |
| 69 | return new QNetworkAccessFileBackend; executed: return new QNetworkAccessFileBackend;Execution Count:39 | 39 |
| 70 | } else if (!url.scheme().isEmpty() && url.authority().isEmpty() && (url.scheme().length() > 1)) { evaluated: !url.scheme().isEmpty()| yes Evaluation Count:5 | yes Evaluation Count:3 |
evaluated: url.authority().isEmpty()| yes Evaluation Count:4 | yes Evaluation Count:1 |
partially evaluated: (url.scheme().length() > 1)| yes Evaluation Count:4 | no Evaluation Count:0 |
| 0-5 |
| 71 | // check if QFile could, in theory, open this URL via the file engines | - |
| 72 | // it has to be in the format: | - |
| 73 | // prefix:path/to/file | - |
| 74 | // or prefix:/path/to/file | - |
| 75 | // | - |
| 76 | // this construct here must match the one below in open() | - |
| 77 | QFileInfo fi(url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery)); executed (the execution status of this line is deduced): QFileInfo fi(url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery)); | - |
| 78 | if (fi.exists() || (op == QNetworkAccessManager::PutOperation && fi.dir().exists())) partially evaluated: fi.exists()| yes Evaluation Count:4 | no Evaluation Count:0 |
never evaluated: op == QNetworkAccessManager::PutOperation never evaluated: fi.dir().exists() | 0-4 |
| 79 | return new QNetworkAccessFileBackend; executed: return new QNetworkAccessFileBackend;Execution Count:4 | 4 |
| 80 | } | 0 |
| 81 | | - |
| 82 | return 0; executed: return 0;Execution Count:4 | 4 |
| 83 | } | - |
| 84 | | - |
| 85 | QNetworkAccessFileBackend::QNetworkAccessFileBackend() | - |
| 86 | : uploadByteDevice(0), totalBytes(0), hasUploadFinished(false) | - |
| 87 | { | - |
| 88 | } executed: }Execution Count:43 | 43 |
| 89 | | - |
| 90 | QNetworkAccessFileBackend::~QNetworkAccessFileBackend() | - |
| 91 | { | - |
| 92 | } | - |
| 93 | | - |
| 94 | void QNetworkAccessFileBackend::open() | - |
| 95 | { | - |
| 96 | QUrl url = this->url(); executed (the execution status of this line is deduced): QUrl url = this->url(); | - |
| 97 | | - |
| 98 | if (url.host() == QLatin1String("localhost")) partially evaluated: url.host() == QLatin1String("localhost")| no Evaluation Count:0 | yes Evaluation Count:43 |
| 0-43 |
| 99 | url.setHost(QString()); never executed: url.setHost(QString()); | 0 |
| 100 | #if !defined(Q_OS_WIN) | - |
| 101 | // do not allow UNC paths on Unix | - |
| 102 | if (!url.host().isEmpty()) { partially evaluated: !url.host().isEmpty()| no Evaluation Count:0 | yes Evaluation Count:43 |
| 0-43 |
| 103 | // we handle only local files | - |
| 104 | error(QNetworkReply::ProtocolInvalidOperationError, never executed (the execution status of this line is deduced): error(QNetworkReply::ProtocolInvalidOperationError, | - |
| 105 | QCoreApplication::translate("QNetworkAccessFileBackend", "Request for opening non-local file %1").arg(url.toString())); never executed (the execution status of this line is deduced): QCoreApplication::translate("QNetworkAccessFileBackend", "Request for opening non-local file %1").arg(url.toString())); | - |
| 106 | finished(); never executed (the execution status of this line is deduced): finished(); | - |
| 107 | return; | 0 |
| 108 | } | - |
| 109 | #endif // !defined(Q_OS_WIN) | - |
| 110 | if (url.path().isEmpty()) partially evaluated: url.path().isEmpty()| no Evaluation Count:0 | yes Evaluation Count:43 |
| 0-43 |
| 111 | url.setPath(QLatin1String("/")); never executed: url.setPath(QLatin1String("/")); | 0 |
| 112 | setUrl(url); executed (the execution status of this line is deduced): setUrl(url); | - |
| 113 | | - |
| 114 | QString fileName = url.toLocalFile(); executed (the execution status of this line is deduced): QString fileName = url.toLocalFile(); | - |
| 115 | if (fileName.isEmpty()) { evaluated: fileName.isEmpty()| yes Evaluation Count:4 | yes Evaluation Count:39 |
| 4-39 |
| 116 | if (url.scheme() == QLatin1String("qrc")) partially evaluated: url.scheme() == QLatin1String("qrc")| no Evaluation Count:0 | yes Evaluation Count:4 |
| 0-4 |
| 117 | fileName = QLatin1Char(':') + url.path(); never executed: fileName = QLatin1Char(':') + url.path(); | 0 |
| 118 | else | - |
| 119 | fileName = url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery); executed: fileName = url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery);Execution Count:4 | 4 |
| 120 | } | - |
| 121 | file.setFileName(fileName); executed (the execution status of this line is deduced): file.setFileName(fileName); | - |
| 122 | | - |
| 123 | if (operation() == QNetworkAccessManager::GetOperation) { evaluated: operation() == QNetworkAccessManager::GetOperation| yes Evaluation Count:4 | yes Evaluation Count:39 |
| 4-39 |
| 124 | if (!loadFileInfo()) partially evaluated: !loadFileInfo()| no Evaluation Count:0 | yes Evaluation Count:4 |
| 0-4 |
| 125 | return; | 0 |
| 126 | } executed: }Execution Count:4 | 4 |
| 127 | | - |
| 128 | QIODevice::OpenMode mode; executed (the execution status of this line is deduced): QIODevice::OpenMode mode; | - |
| 129 | switch (operation()) { | - |
| 130 | case QNetworkAccessManager::GetOperation: | - |
| 131 | mode = QIODevice::ReadOnly; executed (the execution status of this line is deduced): mode = QIODevice::ReadOnly; | - |
| 132 | break; executed: break;Execution Count:4 | 4 |
| 133 | case QNetworkAccessManager::PutOperation: | - |
| 134 | mode = QIODevice::WriteOnly | QIODevice::Truncate; executed (the execution status of this line is deduced): mode = QIODevice::WriteOnly | QIODevice::Truncate; | - |
| 135 | uploadByteDevice = createUploadByteDevice(); executed (the execution status of this line is deduced): uploadByteDevice = createUploadByteDevice(); | - |
| 136 | QObject::connect(uploadByteDevice, SIGNAL(readyRead()), this, SLOT(uploadReadyReadSlot())); executed (the execution status of this line is deduced): QObject::connect(uploadByteDevice, "2""readyRead()", this, "1""uploadReadyReadSlot()"); | - |
| 137 | QMetaObject::invokeMethod(this, "uploadReadyReadSlot", Qt::QueuedConnection); executed (the execution status of this line is deduced): QMetaObject::invokeMethod(this, "uploadReadyReadSlot", Qt::QueuedConnection); | - |
| 138 | break; executed: break;Execution Count:39 | 39 |
| 139 | default: | - |
| 140 | Q_ASSERT_X(false, "QNetworkAccessFileBackend::open", never executed (the execution status of this line is deduced): qt_noop(); | - |
| 141 | "Got a request operation I cannot handle!!"); | - |
| 142 | return; | 0 |
| 143 | } | - |
| 144 | | - |
| 145 | mode |= QIODevice::Unbuffered; executed (the execution status of this line is deduced): mode |= QIODevice::Unbuffered; | - |
| 146 | bool opened = file.open(mode); executed (the execution status of this line is deduced): bool opened = file.open(mode); | - |
| 147 | | - |
| 148 | // could we open the file? | - |
| 149 | if (!opened) { partially evaluated: !opened| no Evaluation Count:0 | yes Evaluation Count:43 |
| 0-43 |
| 150 | QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Error opening %1: %2") never executed (the execution status of this line is deduced): QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Error opening %1: %2") | - |
| 151 | .arg(this->url().toString(), file.errorString()); never executed (the execution status of this line is deduced): .arg(this->url().toString(), file.errorString()); | - |
| 152 | | - |
| 153 | // why couldn't we open the file? | - |
| 154 | // if we're opening for reading, either it doesn't exist, or it's access denied | - |
| 155 | // if we're opening for writing, not existing means it's access denied too | - |
| 156 | if (file.exists() || operation() == QNetworkAccessManager::PutOperation) never evaluated: file.exists() never evaluated: operation() == QNetworkAccessManager::PutOperation | 0 |
| 157 | error(QNetworkReply::ContentAccessDenied, msg); never executed: error(QNetworkReply::ContentAccessDenied, msg); | 0 |
| 158 | else | - |
| 159 | error(QNetworkReply::ContentNotFoundError, msg); never executed: error(QNetworkReply::ContentNotFoundError, msg); | 0 |
| 160 | finished(); never executed (the execution status of this line is deduced): finished(); | - |
| 161 | } | 0 |
| 162 | } executed: }Execution Count:43 | 43 |
| 163 | | - |
| 164 | void QNetworkAccessFileBackend::uploadReadyReadSlot() | - |
| 165 | { | - |
| 166 | if (hasUploadFinished) evaluated: hasUploadFinished| yes Evaluation Count:2 | yes Evaluation Count:148 |
| 2-148 |
| 167 | return; executed: return;Execution Count:2 | 2 |
| 168 | | - |
| 169 | forever { executed (the execution status of this line is deduced): for(;;) { | - |
| 170 | qint64 haveRead; executed (the execution status of this line is deduced): qint64 haveRead; | - |
| 171 | const char *readPointer = uploadByteDevice->readPointer(-1, haveRead); executed (the execution status of this line is deduced): const char *readPointer = uploadByteDevice->readPointer(-1, haveRead); | - |
| 172 | if (haveRead == -1) { evaluated: haveRead == -1| yes Evaluation Count:39 | yes Evaluation Count:692 |
| 39-692 |
| 173 | // EOF | - |
| 174 | hasUploadFinished = true; executed (the execution status of this line is deduced): hasUploadFinished = true; | - |
| 175 | file.flush(); executed (the execution status of this line is deduced): file.flush(); | - |
| 176 | file.close(); executed (the execution status of this line is deduced): file.close(); | - |
| 177 | finished(); executed (the execution status of this line is deduced): finished(); | - |
| 178 | break; executed: break;Execution Count:39 | 39 |
| 179 | } else if (haveRead == 0 || readPointer == 0) { evaluated: haveRead == 0| yes Evaluation Count:109 | yes Evaluation Count:583 |
partially evaluated: readPointer == 0| no Evaluation Count:0 | yes Evaluation Count:583 |
| 0-583 |
| 180 | // nothing to read right now, we will be called again later | - |
| 181 | break; executed: break;Execution Count:109 | 109 |
| 182 | } else { | - |
| 183 | qint64 haveWritten; executed (the execution status of this line is deduced): qint64 haveWritten; | - |
| 184 | haveWritten = file.write(readPointer, haveRead); executed (the execution status of this line is deduced): haveWritten = file.write(readPointer, haveRead); | - |
| 185 | | - |
| 186 | if (haveWritten < 0) { partially evaluated: haveWritten < 0| no Evaluation Count:0 | yes Evaluation Count:583 |
| 0-583 |
| 187 | // write error! | - |
| 188 | QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Write error writing to %1: %2") never executed (the execution status of this line is deduced): QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Write error writing to %1: %2") | - |
| 189 | .arg(url().toString(), file.errorString()); never executed (the execution status of this line is deduced): .arg(url().toString(), file.errorString()); | - |
| 190 | error(QNetworkReply::ProtocolFailure, msg); never executed (the execution status of this line is deduced): error(QNetworkReply::ProtocolFailure, msg); | - |
| 191 | | - |
| 192 | finished(); never executed (the execution status of this line is deduced): finished(); | - |
| 193 | return; | 0 |
| 194 | } else { | - |
| 195 | uploadByteDevice->advanceReadPointer(haveWritten); executed (the execution status of this line is deduced): uploadByteDevice->advanceReadPointer(haveWritten); | - |
| 196 | } executed: }Execution Count:583 | 583 |
| 197 | | - |
| 198 | | - |
| 199 | file.flush(); executed (the execution status of this line is deduced): file.flush(); | - |
| 200 | } executed: }Execution Count:583 | 583 |
| 201 | } | - |
| 202 | } executed: }Execution Count:148 | 148 |
| 203 | | - |
| 204 | void QNetworkAccessFileBackend::closeDownstreamChannel() | - |
| 205 | { | - |
| 206 | if (operation() == QNetworkAccessManager::GetOperation) { never evaluated: operation() == QNetworkAccessManager::GetOperation | 0 |
| 207 | file.close(); never executed (the execution status of this line is deduced): file.close(); | - |
| 208 | } | 0 |
| 209 | } | 0 |
| 210 | | - |
| 211 | void QNetworkAccessFileBackend::downstreamReadyWrite() | - |
| 212 | { | - |
| 213 | Q_ASSERT_X(operation() == QNetworkAccessManager::GetOperation, "QNetworkAccessFileBackend", executed (the execution status of this line is deduced): qt_noop(); | - |
| 214 | "We're being told to download data but operation isn't GET!"); | - |
| 215 | | - |
| 216 | readMoreFromFile(); executed (the execution status of this line is deduced): readMoreFromFile(); | - |
| 217 | } executed: }Execution Count:4 | 4 |
| 218 | | - |
| 219 | bool QNetworkAccessFileBackend::loadFileInfo() | - |
| 220 | { | - |
| 221 | QFileInfo fi(file); executed (the execution status of this line is deduced): QFileInfo fi(file); | - |
| 222 | setHeader(QNetworkRequest::LastModifiedHeader, fi.lastModified()); executed (the execution status of this line is deduced): setHeader(QNetworkRequest::LastModifiedHeader, fi.lastModified()); | - |
| 223 | setHeader(QNetworkRequest::ContentLengthHeader, fi.size()); executed (the execution status of this line is deduced): setHeader(QNetworkRequest::ContentLengthHeader, fi.size()); | - |
| 224 | | - |
| 225 | // signal we're open | - |
| 226 | metaDataChanged(); executed (the execution status of this line is deduced): metaDataChanged(); | - |
| 227 | | - |
| 228 | if (fi.isDir()) { partially evaluated: fi.isDir()| no Evaluation Count:0 | yes Evaluation Count:4 |
| 0-4 |
| 229 | error(QNetworkReply::ContentOperationNotPermittedError, never executed (the execution status of this line is deduced): error(QNetworkReply::ContentOperationNotPermittedError, | - |
| 230 | QCoreApplication::translate("QNetworkAccessFileBackend", "Cannot open %1: Path is a directory").arg(url().toString())); never executed (the execution status of this line is deduced): QCoreApplication::translate("QNetworkAccessFileBackend", "Cannot open %1: Path is a directory").arg(url().toString())); | - |
| 231 | finished(); never executed (the execution status of this line is deduced): finished(); | - |
| 232 | return false; never executed: return false; | 0 |
| 233 | } | - |
| 234 | | - |
| 235 | return true; executed: return true;Execution Count:4 | 4 |
| 236 | } | - |
| 237 | | - |
| 238 | bool QNetworkAccessFileBackend::readMoreFromFile() | - |
| 239 | { | - |
| 240 | qint64 wantToRead; executed (the execution status of this line is deduced): qint64 wantToRead; | - |
| 241 | while ((wantToRead = nextDownstreamBlockSize()) > 0) { partially evaluated: (wantToRead = nextDownstreamBlockSize()) > 0| yes Evaluation Count:38 | no Evaluation Count:0 |
| 0-38 |
| 242 | // ### FIXME!! | - |
| 243 | // Obtain a pointer from the ringbuffer! | - |
| 244 | // Avoid extra copy | - |
| 245 | QByteArray data; executed (the execution status of this line is deduced): QByteArray data; | - |
| 246 | data.reserve(wantToRead); executed (the execution status of this line is deduced): data.reserve(wantToRead); | - |
| 247 | qint64 actuallyRead = file.read(data.data(), wantToRead); executed (the execution status of this line is deduced): qint64 actuallyRead = file.read(data.data(), wantToRead); | - |
| 248 | if (actuallyRead <= 0) { evaluated: actuallyRead <= 0| yes Evaluation Count:4 | yes Evaluation Count:34 |
| 4-34 |
| 249 | // EOF or error | - |
| 250 | if (file.error() != QFile::NoError) { partially evaluated: file.error() != QFile::NoError| no Evaluation Count:0 | yes Evaluation Count:4 |
| 0-4 |
| 251 | QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Read error reading from %1: %2") never executed (the execution status of this line is deduced): QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Read error reading from %1: %2") | - |
| 252 | .arg(url().toString(), file.errorString()); never executed (the execution status of this line is deduced): .arg(url().toString(), file.errorString()); | - |
| 253 | error(QNetworkReply::ProtocolFailure, msg); never executed (the execution status of this line is deduced): error(QNetworkReply::ProtocolFailure, msg); | - |
| 254 | | - |
| 255 | finished(); never executed (the execution status of this line is deduced): finished(); | - |
| 256 | return false; never executed: return false; | 0 |
| 257 | } | - |
| 258 | | - |
| 259 | finished(); executed (the execution status of this line is deduced): finished(); | - |
| 260 | return true; executed: return true;Execution Count:4 | 4 |
| 261 | } | - |
| 262 | | - |
| 263 | data.resize(actuallyRead); executed (the execution status of this line is deduced): data.resize(actuallyRead); | - |
| 264 | totalBytes += actuallyRead; executed (the execution status of this line is deduced): totalBytes += actuallyRead; | - |
| 265 | | - |
| 266 | QByteDataBuffer list; executed (the execution status of this line is deduced): QByteDataBuffer list; | - |
| 267 | list.append(data); executed (the execution status of this line is deduced): list.append(data); | - |
| 268 | data.clear(); // important because of implicit sharing! executed (the execution status of this line is deduced): data.clear(); | - |
| 269 | writeDownstreamData(list); executed (the execution status of this line is deduced): writeDownstreamData(list); | - |
| 270 | } executed: }Execution Count:34 | 34 |
| 271 | return true; never executed: return true; | 0 |
| 272 | } | - |
| 273 | | - |
| 274 | QT_END_NAMESPACE | - |
| 275 | | - |
| | |