void QNetworkReplyImplPrivate::_q_copyReadyRead() { Q_Q(QNetworkReplyImpl); if (state != Working) return; if (!copyDevice || !q->isOpen()) return; // FIXME Optimize to use download buffer if it is a QBuffer. // Needs to be done where sendCacheContents() (?) of HTTP is emitting // metaDataChanged ? forever { qint64 bytesToRead = nextDownstreamBlockSize(); if (bytesToRead == 0) // we'll be called again, eventually break; bytesToRead = qBound<qint64>(1, bytesToRead, copyDevice->bytesAvailable()); QByteArray byteData; byteData.resize(bytesToRead); qint64 bytesActuallyRead = copyDevice->read(byteData.data(), byteData.size()); if (bytesActuallyRead == -1) { byteData.clear(); backendNotify(NotifyCopyFinished); break; } byteData.resize(bytesActuallyRead); readBuffer.append(byteData); if (!copyDevice->isSequential() && copyDevice->atEnd()) { backendNotify(NotifyCopyFinished); bytesDownloaded += bytesActuallyRead; break; } bytesDownloaded += bytesActuallyRead; } if (bytesDownloaded == lastBytesDownloaded) { // we didn't read anything return; } lastBytesDownloaded = bytesDownloaded; QVariant totalSize = cookedHeaders.value(QNetworkRequest::ContentLengthHeader); if (preMigrationDownloaded != Q_INT64_C(-1)) totalSize = totalSize.toLongLong() + preMigrationDownloaded; pauseNotificationHandling(); // emit readyRead before downloadProgress incase this will cause events to be // processed and we get into a recursive call (as in QProgressDialog). emit q->readyRead(); if (downloadProgressSignalChoke.elapsed() >= progressSignalInterval) { downloadProgressSignalChoke.restart(); emit q->downloadProgress(bytesDownloaded, totalSize.isNull() ? Q_INT64_C(-1) : totalSize.toLongLong()); } resumeNotificationHandling(); }
void QNetworkReplyImplPrivate::_q_copyReadyRead() { Q_Q(QNetworkReplyImpl); if (state != Working) return; if (!copyDevice || !q->isOpen()) return; forever { qint64 bytesToRead = nextDownstreamBlockSize(); if (bytesToRead == 0) // we'll be called again, eventually break; bytesToRead = qBound<qint64>(1, bytesToRead, copyDevice->bytesAvailable()); QByteArray byteData; byteData.resize(bytesToRead); qint64 bytesActuallyRead = copyDevice->read(byteData.data(), byteData.size()); if (bytesActuallyRead == -1) { byteData.clear(); backendNotify(NotifyCopyFinished); break; } byteData.resize(bytesActuallyRead); readBuffer.append(byteData); if (!copyDevice->isSequential() && copyDevice->atEnd()) { backendNotify(NotifyCopyFinished); bytesDownloaded += bytesActuallyRead; break; } bytesDownloaded += bytesActuallyRead; } if (bytesDownloaded == lastBytesDownloaded) { // we didn't read anything return; } lastBytesDownloaded = bytesDownloaded; QVariant totalSize = cookedHeaders.value(QNetworkRequest::ContentLengthHeader); if (preMigrationDownloaded != Q_INT64_C(-1)) totalSize = totalSize.toLongLong() + preMigrationDownloaded; pauseNotificationHandling(); emit q->downloadProgress(bytesDownloaded, totalSize.isNull() ? Q_INT64_C(-1) : totalSize.toLongLong()); emit q->readyRead(); resumeNotificationHandling(); }
void QNetworkReplyImplPrivate::appendDownstreamDataSignalEmissions() { Q_Q(QNetworkReplyImpl); QVariant totalSize = cookedHeaders.value(QNetworkRequest::ContentLengthHeader); if (preMigrationDownloaded != Q_INT64_C(-1)) totalSize = totalSize.toLongLong() + preMigrationDownloaded; pauseNotificationHandling(); // important: At the point of this readyRead(), the data parameter list must be empty, // else implicit sharing will trigger memcpy when the user is reading data! emit q->readyRead(); // emit readyRead before downloadProgress incase this will cause events to be // processed and we get into a recursive call (as in QProgressDialog). emit q->downloadProgress(bytesDownloaded, totalSize.isNull() ? Q_INT64_C(-1) : totalSize.toLongLong()); resumeNotificationHandling(); // do we still have room in the buffer? if (nextDownstreamBlockSize() > 0) backendNotify(QNetworkReplyImplPrivate::NotifyDownstreamReadyWrite); }
void QNetworkReplyImplPrivate::appendDownstreamDataSignalEmissions() { Q_Q(QNetworkReplyImpl); QPointer<QNetworkReplyImpl> qq = q; QVariant totalSize = cookedHeaders.value(QNetworkRequest::ContentLengthHeader); if (preMigrationDownloaded != Q_INT64_C(-1)) totalSize = totalSize.toLongLong() + preMigrationDownloaded; pauseNotificationHandling(); emit q->downloadProgress(bytesDownloaded, totalSize.isNull() ? Q_INT64_C(-1) : totalSize.toLongLong()); // important: At the point of this readyRead(), the data parameter list must be empty, // else implicit sharing will trigger memcpy when the user is reading data! emit q->readyRead(); // hopefully we haven't been deleted here if (!qq.isNull()) { resumeNotificationHandling(); // do we still have room in the buffer? if (nextDownstreamBlockSize() > 0) backendNotify(QNetworkReplyImplPrivate::NotifyDownstreamReadyWrite); } }
// we received downstream data and send this to the cache // and to our readBuffer (which in turn gets read by the user of QNetworkReply) void QNetworkReplyImplPrivate::appendDownstreamData(QByteDataBuffer &data) { Q_Q(QNetworkReplyImpl); if (!q->isOpen()) return; if (cacheEnabled && !cacheSaveDevice) { // save the meta data QNetworkCacheMetaData metaData; metaData.setUrl(url); metaData = backend->fetchCacheMetaData(metaData); // save the redirect request also in the cache QVariant redirectionTarget = q->attribute(QNetworkRequest::RedirectionTargetAttribute); if (redirectionTarget.isValid()) { QNetworkCacheMetaData::AttributesMap attributes = metaData.attributes(); attributes.insert(QNetworkRequest::RedirectionTargetAttribute, redirectionTarget); metaData.setAttributes(attributes); } cacheSaveDevice = networkCache()->prepare(metaData); if (!cacheSaveDevice || (cacheSaveDevice && !cacheSaveDevice->isOpen())) { if (cacheSaveDevice && !cacheSaveDevice->isOpen()) qCritical("QNetworkReplyImpl: network cache returned a device that is not open -- " "class %s probably needs to be fixed", networkCache()->metaObject()->className()); networkCache()->remove(url); cacheSaveDevice = 0; cacheEnabled = false; } } qint64 bytesWritten = 0; for (int i = 0; i < data.bufferCount(); i++) { QByteArray item = data[i]; if (cacheSaveDevice) cacheSaveDevice->write(item.constData(), item.size()); readBuffer.append(item); bytesWritten += item.size(); } data.clear(); bytesDownloaded += bytesWritten; lastBytesDownloaded = bytesDownloaded; QPointer<QNetworkReplyImpl> qq = q; QVariant totalSize = cookedHeaders.value(QNetworkRequest::ContentLengthHeader); if (preMigrationDownloaded != Q_INT64_C(-1)) totalSize = totalSize.toLongLong() + preMigrationDownloaded; pauseNotificationHandling(); emit q->downloadProgress(bytesDownloaded, totalSize.isNull() ? Q_INT64_C(-1) : totalSize.toLongLong()); // important: At the point of this readyRead(), the data parameter list must be empty, // else implicit sharing will trigger memcpy when the user is reading data! emit q->readyRead(); // hopefully we haven't been deleted here if (!qq.isNull()) { resumeNotificationHandling(); // do we still have room in the buffer? if (nextDownstreamBlockSize() > 0) backendNotify(QNetworkReplyImplPrivate::NotifyDownstreamReadyWrite); } }