Exemplo n.º 1
0
// 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) {
        initCacheSaveDevice();
    }

    qint64 bytesWritten = 0;
    for (int i = 0; i < data.bufferCount(); i++) {
        QByteArray const &item = data[i];

        if (cacheSaveDevice)
            cacheSaveDevice->write(item.constData(), item.size());
        readBuffer.append(item);

        bytesWritten += item.size();
    }
    data.clear();

    bytesDownloaded += bytesWritten;
    lastBytesDownloaded = bytesDownloaded;

    appendDownstreamDataSignalEmissions();
}
bool QNetworkAccessFileBackend::readMoreFromFile()
{
    qint64 wantToRead;
    while ((wantToRead = nextDownstreamBlockSize()) > 0) {
        // ### FIXME!!
        // Obtain a pointer from the ringbuffer!
        // Avoid extra copy
        QByteArray data;
        data.reserve(wantToRead);
        qint64 actuallyRead = file.read(data.data(), wantToRead);
        if (actuallyRead <= 0) {
            // EOF or error
            if (file.error() != QFile::NoError) {
                QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Read error reading from %1: %2")
                              .arg(url().toString(), file.errorString());
                error(QNetworkReply::ProtocolFailure, msg);

                finished();
                return false;
            }

            finished();
            return true;
        }

        data.resize(actuallyRead);
        totalBytes += actuallyRead;

        QByteDataBuffer list;
        list.append(data);
        data.clear(); // important because of implicit sharing!
        writeDownstreamData(list);
    }
    return true;
}
void QNetworkAccessDebugPipeBackend::pushFromSocketToDownstream()
{
    QByteArray buffer;

    if (socket.state() == QAbstractSocket::ConnectingState) {
        return;
    }

    forever {
        if (hasDownloadFinished)
            return;

        buffer.resize(ReadBufferSize);
        qint64 haveRead = socket.read(buffer.data(), ReadBufferSize);
        
        if (haveRead == -1) {
            hasDownloadFinished = true;
            // this ensures a good last downloadProgress is emitted
            setHeader(QNetworkRequest::ContentLengthHeader, QVariant());
            possiblyFinish();
            break;
        } else if (haveRead == 0) {
            break;
        } else {
            // have read something
            buffer.resize(haveRead);
            bytesDownloaded += haveRead;

            QByteDataBuffer list;
            list.append(buffer);
            buffer.clear(); // important because of implicit sharing!
            writeDownstreamData(list);
        }
    }
}
Exemplo n.º 4
0
void QHttpNetworkReplyPrivate::appendCompressedReplyData(QByteDataBuffer &data)
{
    // Work in progress: Later we will directly use a list of QByteArray or a QRingBuffer
    // instead of one QByteArray.
    for(int i = 0; i < data.bufferCount(); i++) {
        QByteArray &byteData = data[i];
        compressedData.append(byteData.constData(), byteData.size());
    }
    data.clear();
}
Exemplo n.º 5
0
void QHttpNetworkReplyPrivate::appendUncompressedReplyData(QByteDataBuffer &data)
{
    responseData.append(data);

    // clear the original! helps with implicit sharing and
    // avoiding memcpy when the user is reading the data
    data.clear();
}
Exemplo n.º 6
0
void QNetworkAccessHttpBackend::readFromHttp()
{
    if (!httpReply)
        return;

    // We read possibly more than nextDownstreamBlockSize(), but
    // this is not a critical thing since it is already in the
    // memory anyway

    QByteDataBuffer list;

    while (httpReply->bytesAvailable() != 0 && nextDownstreamBlockSize() != 0 && nextDownstreamBlockSize() > list.byteAmount()) {
        list.append(httpReply->readAny());
    }

    if (!list.isEmpty())
      writeDownstreamData(list);
}
void QNetworkAccessDataBackend::open()
{
    QUrl uri = request().url();

    if (operation() != QNetworkAccessManager::GetOperation &&
        operation() != QNetworkAccessManager::HeadOperation) {
        // data: doesn't support anything but GET
        const QString msg = QCoreApplication::translate("QNetworkAccessDataBackend",
                                                        "Operation not supported on %1")
                      .arg(uri.toString());
        error(QNetworkReply::ContentOperationNotPermittedError, msg);
        finished();
        return;
    }

    QPair<QString, QByteArray> decoded = qDecodeDataUrl(uri);

    if (! decoded.first.isNull()) {
        setHeader(QNetworkRequest::ContentTypeHeader, decoded.first);
        setHeader(QNetworkRequest::ContentLengthHeader, decoded.second.size());
        emit metaDataChanged();

        QByteDataBuffer list;
        list.append(decoded.second);
        decoded.second.clear(); // important because of implicit sharing!
        writeDownstreamData(list);

        finished();
        return;
    }

    // something wrong with this URI
    const QString msg = QCoreApplication::translate("QNetworkAccessDataBackend",
                                                    "Invalid URI: %1").arg(uri.toString());
    error(QNetworkReply::ProtocolFailure, msg);
    finished();
}
Exemplo n.º 8
0
// 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);
    }
}