QNonContiguousByteDevice* QNetworkAccessBackend::createUploadByteDevice()
{
    QNonContiguousByteDevice* device = 0;

    if (reply->outgoingDataBuffer)
        device = QNonContiguousByteDeviceFactory::create(reply->outgoingDataBuffer);
    else if (reply->outgoingData) {
        device = QNonContiguousByteDeviceFactory::create(reply->outgoingData);
    } else {
        return 0;
    }

    bool bufferDisallowed =
            reply->request.attribute(QNetworkRequest::DoNotBufferUploadDataAttribute,
                          QVariant(false)) == QVariant(true);
    if (bufferDisallowed)
        device->disableReset();

    // make sure we delete this later
    device->setParent(this);

    connect(device, SIGNAL(readProgress(qint64,qint64)), this, SLOT(emitReplyUploadProgress(qint64,qint64)));

    return device;
}
void QNetworkAccessDebugPipeBackend::pushFromUpstreamToSocket()
{
    // FIXME
    if (operation() == QNetworkAccessManager::PutOperation) {
        if (hasUploadFinished)
            return;

        forever {
            if (socket.bytesToWrite() >= WriteBufferSize)
                return;

            qint64 haveRead;
            const char *readPointer = uploadByteDevice->readPointer(WriteBufferSize, haveRead);
            if (haveRead == -1) {
                // EOF
                hasUploadFinished = true;
                emitReplyUploadProgress(bytesUploaded, bytesUploaded);
                possiblyFinish();
                break;
            } else if (haveRead == 0 || readPointer == 0) {
                // nothing to read right now, we will be called again later
                break;
            } else {
                qint64 haveWritten;
                haveWritten = socket.write(readPointer, haveRead);

                if (haveWritten < 0) {
                    // write error!
                    QString msg = QCoreApplication::translate("QNetworkAccessDebugPipeBackend", "Write error writing to %1: %2")
                                  .arg(url().toString(), socket.errorString());
                    error(QNetworkReply::ProtocolFailure, msg);
                    finished();
                    return;
                } else {
                    uploadByteDevice->advanceReadPointer(haveWritten);
                    bytesUploaded += haveWritten;
                    emitReplyUploadProgress(bytesUploaded, -1);
                }

                //QCoreApplication::processEvents();

            }
        }
    }
}
QNonContiguousByteDevice* QNetworkAccessBackend::createUploadByteDevice()
{
    if (reply->outgoingDataBuffer)
        uploadByteDevice = QNonContiguousByteDeviceFactory::createShared(reply->outgoingDataBuffer);
    else if (reply->outgoingData) {
        uploadByteDevice = QNonContiguousByteDeviceFactory::createShared(reply->outgoingData);
    } else {
        return 0;
    }

    // We want signal emissions only for normal asynchronous uploads
    if (!isSynchronous())
        connect(uploadByteDevice.data(), SIGNAL(readProgress(qint64,qint64)), this, SLOT(emitReplyUploadProgress(qint64,qint64)));

    return uploadByteDevice.data();
}
QNonContiguousByteDevice* QNetworkAccessBackend::createUploadByteDevice()
{
    if (reply->outgoingDataBuffer)
        uploadByteDevice = QSharedPointer<QNonContiguousByteDevice>(QNonContiguousByteDeviceFactory::create(reply->outgoingDataBuffer));
    else if (reply->outgoingData) {
        uploadByteDevice = QSharedPointer<QNonContiguousByteDevice>(QNonContiguousByteDeviceFactory::create(reply->outgoingData));
    } else {
        return 0;
    }

    bool bufferDisallowed =
            reply->request.attribute(QNetworkRequest::DoNotBufferUploadDataAttribute,
                          QVariant(false)) == QVariant(true);
    if (bufferDisallowed)
        uploadByteDevice->disableReset();

    // We want signal emissions only for normal asynchronous uploads
    if (!isSynchronous())
        connect(uploadByteDevice.data(), SIGNAL(readProgress(qint64,qint64)), this, SLOT(emitReplyUploadProgress(qint64,qint64)));

    return uploadByteDevice.data();
}