Revision control

Copy as Markdown

// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Qt-Security score:significant reason:default
#include "qiooperation_p.h"
#include "qiooperation_p_p.h"
#include <QtCore/private/qobject_p.h>
#include <QtCore/private/qrandomaccessasyncfile_p_p.h>
QT_BEGIN_NAMESPACE
QIOOperationPrivate::QIOOperationPrivate(QtPrivate::QIOOperationDataStorage *storage)
: dataStorage(storage)
{
Q_ASSERT(storage);
}
QIOOperationPrivate::~QIOOperationPrivate()
{
}
void QIOOperationPrivate::appendBytesProcessed(qint64 num)
{
processed += num;
}
void QIOOperationPrivate::operationComplete(QIOOperation::Error err)
{
Q_Q(QIOOperation);
error = err;
state = State::Finished;
if (err != QIOOperation::Error::None)
Q_EMIT q->errorOccurred(err);
Q_EMIT q->finished();
}
void QIOOperationPrivate::setError(QIOOperation::Error err)
{
Q_Q(QIOOperation);
error = err;
if (err != QIOOperation::Error::None) {
state = State::Finished;
Q_EMIT q->errorOccurred(err);
Q_EMIT q->finished();
}
}
QIOOperation::~QIOOperation()
{
ensureCompleteOrCanceled();
}
QIOOperation::Type QIOOperation::type() const
{
Q_D(const QIOOperation);
return d->type;
}
QIOOperation::Error QIOOperation::error() const
{
Q_D(const QIOOperation);
return d->error;
}
bool QIOOperation::isFinished() const
{
Q_D(const QIOOperation);
return d->state == QIOOperationPrivate::State::Finished;
}
QIOOperation::QIOOperation(QIOOperationPrivate &dd, QObject *parent)
: QObject(dd, parent)
{
if (auto file = qobject_cast<QRandomAccessAsyncFile*>(parent))
d_func()->file = file;
}
void QIOOperation::ensureCompleteOrCanceled()
{
// Block until the operation is either complete or canceled.
// Otherwise the write/read might use removed data
Q_D(QIOOperation);
if (d->state != QIOOperationPrivate::State::Finished) {
if (d->file) {
auto *filePriv = QRandomAccessAsyncFilePrivate::get(d->file);
filePriv->cancelAndWait(this);
}
}
}
QIOReadWriteOperationBase::~QIOReadWriteOperationBase()
= default;
qint64 QIOReadWriteOperationBase::offset() const
{
Q_D(const QIOOperation);
return d->offset;
}
qint64 QIOReadWriteOperationBase::numBytesProcessed() const
{
if (!isFinished())
return -1;
Q_D(const QIOOperation);
return d->processed;
}
QIOReadWriteOperationBase::QIOReadWriteOperationBase(QIOOperationPrivate &dd, QObject *parent)
: QIOOperation(dd, parent)
{
}
QIOReadOperation::~QIOReadOperation() = default;
QByteArray QIOReadOperation::data() const
{
if (!isFinished())
return {};
Q_D(const QIOOperation);
return d->dataStorage->getValue<QByteArray>();
}
QIOReadOperation::QIOReadOperation(QIOOperationPrivate &dd, QObject *parent)
: QIOReadWriteOperationBase(dd, parent)
{
Q_ASSERT(dd.type == QIOOperation::Type::Read);
Q_ASSERT(dd.dataStorage->containsByteArray());
}
QIOWriteOperation::~QIOWriteOperation() = default;
QByteArray QIOWriteOperation::data() const
{
if (!isFinished())
return {};
Q_D(const QIOOperation);
return d->dataStorage->getValue<QByteArray>();
}
QIOWriteOperation::QIOWriteOperation(QIOOperationPrivate &dd, QObject *parent)
: QIOReadWriteOperationBase(dd, parent)
{
Q_ASSERT(dd.type == QIOOperation::Type::Write);
Q_ASSERT(dd.dataStorage->containsByteArray());
}
QIOVectoredReadOperation::~QIOVectoredReadOperation() = default;
QSpan<const QSpan<std::byte>> QIOVectoredReadOperation::data() const
{
if (!isFinished())
return {};
Q_D(const QIOOperation);
return d->dataStorage->getValue<QSpan<const QSpan<std::byte>>>();
}
QIOVectoredReadOperation::QIOVectoredReadOperation(QIOOperationPrivate &dd, QObject *parent)
: QIOReadWriteOperationBase(dd, parent)
{
Q_ASSERT(dd.type == QIOOperation::Type::Read);
Q_ASSERT(dd.dataStorage->containsReadSpans());
}
QIOVectoredWriteOperation::~QIOVectoredWriteOperation() = default;
QSpan<const QSpan<const std::byte>> QIOVectoredWriteOperation::data() const
{
if (!isFinished())
return {};
Q_D(const QIOOperation);
return d->dataStorage->getValue<QSpan<const QSpan<const std::byte>>>();
}
QIOVectoredWriteOperation::QIOVectoredWriteOperation(QIOOperationPrivate &dd, QObject *parent)
: QIOReadWriteOperationBase(dd, parent)
{
Q_ASSERT(dd.type == QIOOperation::Type::Write);
Q_ASSERT(dd.dataStorage->containsWriteSpans());
}
QT_END_NAMESPACE