Changeset View
Changeset View
Standalone View
Standalone View
src/widgets/accessmanagerreply_p.cpp
Show All 26 Lines | |||||
27 | #include "job.h" | 27 | #include "job.h" | ||
28 | #include "scheduler.h" | 28 | #include "scheduler.h" | ||
29 | #include "kio_widgets_debug.h" | 29 | #include "kio_widgets_debug.h" | ||
30 | 30 | | |||
31 | #include <kurlauthorized.h> | 31 | #include <kurlauthorized.h> | ||
32 | #include <kprotocolinfo.h> | 32 | #include <kprotocolinfo.h> | ||
33 | #include <qmimedatabase.h> | 33 | #include <qmimedatabase.h> | ||
34 | 34 | | |||
35 | #include <QtMath> | ||||
35 | #include <QSslConfiguration> | 36 | #include <QSslConfiguration> | ||
36 | 37 | | |||
37 | #define QL1S(x) QLatin1String(x) | 38 | #define QL1S(x) QLatin1String(x) | ||
38 | #define QL1C(x) QLatin1Char(x) | 39 | #define QL1C(x) QLatin1Char(x) | ||
39 | 40 | | |||
40 | namespace KDEPrivate | 41 | namespace KDEPrivate | ||
41 | { | 42 | { | ||
42 | 43 | | |||
43 | AccessManagerReply::AccessManagerReply(const QNetworkAccessManager::Operation op, | 44 | AccessManagerReply::AccessManagerReply(const QNetworkAccessManager::Operation op, | ||
44 | const QNetworkRequest &request, | 45 | const QNetworkRequest &request, | ||
45 | KIO::SimpleJob *kioJob, | 46 | KIO::SimpleJob *kioJob, | ||
46 | bool emitReadyReadOnMetaDataChange, | 47 | bool emitReadyReadOnMetaDataChange, | ||
47 | QObject *parent) | 48 | QObject *parent) | ||
48 | : QNetworkReply(parent), | 49 | : QNetworkReply(parent), | ||
50 | m_offset(0), | ||||
49 | m_metaDataRead(false), | 51 | m_metaDataRead(false), | ||
50 | m_ignoreContentDisposition(false), | 52 | m_ignoreContentDisposition(false), | ||
51 | m_emitReadyReadOnMetaDataChange(emitReadyReadOnMetaDataChange), | 53 | m_emitReadyReadOnMetaDataChange(emitReadyReadOnMetaDataChange), | ||
52 | m_kioJob(kioJob) | 54 | m_kioJob(kioJob) | ||
53 | 55 | | |||
54 | { | 56 | { | ||
55 | setRequest(request); | 57 | setRequest(request); | ||
56 | setOpenMode(QIODevice::ReadOnly); | 58 | setOpenMode(QIODevice::ReadOnly); | ||
Show All 22 Lines | |||||
79 | AccessManagerReply::AccessManagerReply(const QNetworkAccessManager::Operation op, | 81 | AccessManagerReply::AccessManagerReply(const QNetworkAccessManager::Operation op, | ||
80 | const QNetworkRequest &request, | 82 | const QNetworkRequest &request, | ||
81 | const QByteArray &data, | 83 | const QByteArray &data, | ||
82 | const QUrl &url, | 84 | const QUrl &url, | ||
83 | const KIO::MetaData &metaData, | 85 | const KIO::MetaData &metaData, | ||
84 | QObject *parent) | 86 | QObject *parent) | ||
85 | : QNetworkReply(parent), | 87 | : QNetworkReply(parent), | ||
86 | m_data(data), | 88 | m_data(data), | ||
89 | m_offset(0), | ||||
87 | m_ignoreContentDisposition(false), | 90 | m_ignoreContentDisposition(false), | ||
88 | m_emitReadyReadOnMetaDataChange(false) | 91 | m_emitReadyReadOnMetaDataChange(false) | ||
89 | { | 92 | { | ||
90 | setRequest(request); | 93 | setRequest(request); | ||
91 | setOpenMode(QIODevice::ReadOnly); | 94 | setOpenMode(QIODevice::ReadOnly); | ||
92 | setUrl((url.isValid() ? url : request.url())); | 95 | setUrl((url.isValid() ? url : request.url())); | ||
93 | setOperation(op); | 96 | setOperation(op); | ||
94 | setHeaderFromMetaData(metaData); | 97 | setHeaderFromMetaData(metaData); | ||
95 | 98 | | |||
96 | if (!request.sslConfiguration().isNull()) { | 99 | if (!request.sslConfiguration().isNull()) { | ||
97 | setSslConfiguration(request.sslConfiguration()); | 100 | setSslConfiguration(request.sslConfiguration()); | ||
98 | } | 101 | } | ||
99 | 102 | | |||
100 | setError(NoError, QString()); | 103 | setError(NoError, QString()); | ||
101 | emitFinished(true, Qt::QueuedConnection); | 104 | emitFinished(true, Qt::QueuedConnection); | ||
102 | } | 105 | } | ||
103 | 106 | | |||
104 | AccessManagerReply::AccessManagerReply(const QNetworkAccessManager::Operation op, | 107 | AccessManagerReply::AccessManagerReply(const QNetworkAccessManager::Operation op, | ||
105 | const QNetworkRequest &request, | 108 | const QNetworkRequest &request, | ||
106 | QNetworkReply::NetworkError errorCode, | 109 | QNetworkReply::NetworkError errorCode, | ||
107 | const QString &errorMessage, | 110 | const QString &errorMessage, | ||
108 | QObject *parent) | 111 | QObject *parent) | ||
109 | : QNetworkReply(parent) | 112 | : QNetworkReply(parent), | ||
113 | m_offset(0) | ||||
110 | { | 114 | { | ||
111 | setRequest(request); | 115 | setRequest(request); | ||
112 | setOpenMode(QIODevice::ReadOnly); | 116 | setOpenMode(QIODevice::ReadOnly); | ||
113 | setUrl(request.url()); | 117 | setUrl(request.url()); | ||
114 | setOperation(op); | 118 | setOperation(op); | ||
115 | setError(static_cast<QNetworkReply::NetworkError>(errorCode), errorMessage); | 119 | setError(static_cast<QNetworkReply::NetworkError>(errorCode), errorMessage); | ||
116 | if (error() != QNetworkReply::NoError) { | 120 | if (error() != QNetworkReply::NoError) { | ||
117 | QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, Q_ARG(QNetworkReply::NetworkError, error())); | 121 | QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, Q_ARG(QNetworkReply::NetworkError, error())); | ||
118 | } | 122 | } | ||
119 | 123 | | |||
120 | emitFinished(true, Qt::QueuedConnection); | 124 | emitFinished(true, Qt::QueuedConnection); | ||
121 | } | 125 | } | ||
122 | 126 | | |||
123 | AccessManagerReply::~AccessManagerReply() | 127 | AccessManagerReply::~AccessManagerReply() | ||
124 | { | 128 | { | ||
125 | } | 129 | } | ||
126 | 130 | | |||
127 | void AccessManagerReply::abort() | 131 | void AccessManagerReply::abort() | ||
128 | { | 132 | { | ||
129 | if (m_kioJob) { | 133 | if (m_kioJob) { | ||
130 | m_kioJob.data()->disconnect(this); | 134 | m_kioJob.data()->disconnect(this); | ||
131 | } | 135 | } | ||
132 | m_kioJob.clear(); | 136 | m_kioJob.clear(); | ||
133 | m_data.clear(); | 137 | m_data.clear(); | ||
138 | m_offset = 0; | ||||
134 | m_metaDataRead = false; | 139 | m_metaDataRead = false; | ||
135 | } | 140 | } | ||
136 | 141 | | |||
137 | qint64 AccessManagerReply::bytesAvailable() const | 142 | qint64 AccessManagerReply::bytesAvailable() const | ||
138 | { | 143 | { | ||
139 | return (QNetworkReply::bytesAvailable() + m_data.length()); | 144 | return (QNetworkReply::bytesAvailable() + m_data.length() - m_offset); | ||
140 | } | 145 | } | ||
141 | 146 | | |||
142 | qint64 AccessManagerReply::readData(char *data, qint64 maxSize) | 147 | qint64 AccessManagerReply::readData(char *data, qint64 maxSize) | ||
143 | { | 148 | { | ||
144 | const qint64 length = qMin(qint64(m_data.length()), maxSize); | 149 | const qint64 length = qMin(qint64(m_data.length() - m_offset), maxSize); | ||
145 | 150 | | |||
146 | if (length) { | 151 | if (length <= 0) { | ||
147 | memcpy(data, m_data.constData(), length); | 152 | return 0; | ||
148 | m_data.remove(0, length); | 153 | } | ||
154 | | ||||
155 | memcpy(data, m_data.constData() + m_offset, length); | ||||
156 | m_offset += length; | ||||
157 | | ||||
158 | if (m_data.length() == m_offset) { | ||||
159 | m_data.clear(); | ||||
160 | m_offset = 0; | ||||
bruns: Wouldn't it be better to trim the buffer in slotData, at least in the non-trivial case? | |||||
For the non-trivial case it shouldn't make a difference really. For the trivial one it does, as otherwise it would never empty m_data. So to avoid code duplication, it's only done here. fvogt: For the non-trivial case it shouldn't make a difference really. For the trivial one it does, as… | |||||
149 | } | 161 | } | ||
150 | 162 | | |||
151 | return length; | 163 | return length; | ||
152 | } | 164 | } | ||
153 | 165 | | |||
154 | bool AccessManagerReply::ignoreContentDisposition(const KIO::MetaData &metaData) | 166 | bool AccessManagerReply::ignoreContentDisposition(const KIO::MetaData &metaData) | ||
155 | { | 167 | { | ||
156 | if (m_ignoreContentDisposition) { | 168 | if (m_ignoreContentDisposition) { | ||
▲ Show 20 Lines • Show All 233 Lines • ▼ Show 20 Line(s) | 333 | { | |||
390 | } | 402 | } | ||
391 | 403 | | |||
392 | return errCode; | 404 | return errCode; | ||
393 | } | 405 | } | ||
394 | 406 | | |||
395 | void AccessManagerReply::slotData(KIO::Job *kioJob, const QByteArray &data) | 407 | void AccessManagerReply::slotData(KIO::Job *kioJob, const QByteArray &data) | ||
396 | { | 408 | { | ||
397 | Q_UNUSED(kioJob); | 409 | Q_UNUSED(kioJob); | ||
410 | if (data.isEmpty()) { | ||||
411 | return; | ||||
412 | } | ||||
413 | | ||||
414 | qint64 newSizeWithOffset = m_data.size() + data.size(); | ||||
415 | if (newSizeWithOffset <= m_data.capacity()) { | ||||
416 | // Already enough space | ||||
417 | } else if (newSizeWithOffset - m_offset <= m_data.capacity()) { | ||||
418 | // We get enough space with ::remove. | ||||
419 | m_data.remove(0, m_offset); | ||||
420 | m_offset = 0; | ||||
421 | } else { | ||||
422 | // We have to resize the array, which implies an expensive memmove. | ||||
423 | // Do it ourselves to save m_offset bytes. | ||||
424 | QByteArray newData; | ||||
425 | // Leave some free space to avoid that every slotData call results in | ||||
426 | // a reallocation. qNextPowerOfTwo is what QByteArray does internally. | ||||
427 | newData.reserve(qNextPowerOfTwo(newSizeWithOffset - m_offset)); | ||||
428 | newData.append(m_data.constData() + m_offset, m_data.size() - m_offset); | ||||
429 | m_data = newData; | ||||
430 | m_offset = 0; | ||||
431 | } | ||||
if you swap these two lines (i.e. append to m_data), you have m_data += data in all three branches, and you can move it to the bottom. bruns: if you swap these two lines (i.e. append to m_data), you have `m_data += data` in all three… | |||||
432 | | ||||
398 | m_data += data; | 433 | m_data += data; | ||
399 | if (!data.isEmpty()) { | 434 | | ||
400 | emit readyRead(); | 435 | emit readyRead(); | ||
401 | } | 436 | } | ||
402 | } | | |||
403 | 437 | | |||
404 | void AccessManagerReply::slotMimeType(KIO::Job *kioJob, const QString &mimeType) | 438 | void AccessManagerReply::slotMimeType(KIO::Job *kioJob, const QString &mimeType) | ||
405 | { | 439 | { | ||
406 | //qDebug() << kioJob << mimeType; | 440 | //qDebug() << kioJob << mimeType; | ||
407 | setHeader(QNetworkRequest::ContentTypeHeader, mimeType.toUtf8()); | 441 | setHeader(QNetworkRequest::ContentTypeHeader, mimeType.toUtf8()); | ||
408 | readHttpResponseHeaders(kioJob); | 442 | readHttpResponseHeaders(kioJob); | ||
409 | if (m_emitReadyReadOnMetaDataChange) { | 443 | if (m_emitReadyReadOnMetaDataChange) { | ||
410 | emit readyRead(); | 444 | emit readyRead(); | ||
▲ Show 20 Lines • Show All 81 Lines • Show Last 20 Lines |
Wouldn't it be better to trim the buffer in slotData, at least in the non-trivial case?