// 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 #ifndef QIOOPERATION_P_P_H #define QIOOPERATION_P_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include "qiooperation_p.h" #include "qrandomaccessasyncfile_p.h" #include #include #include #include QT_BEGIN_NAMESPACE namespace QtPrivate { class QIOOperationDataStorage { public: // When passing QSpan>, we'd better have an underlying storage // for an outer span, so that users could pass in a temporary object. // We'd use QVarLengthArray for that. Having 256 elements (the default) // seems to be unneeded for vectored IO. For now I picked 10 as a reasonable // default. But maybe even less? static constexpr qsizetype DefaultNumOfBuffers = 10; using ReadSpans = QVarLengthArray, DefaultNumOfBuffers>; using WriteSpans = QVarLengthArray, DefaultNumOfBuffers>; explicit QIOOperationDataStorage() : data(std::monostate{}) {} explicit QIOOperationDataStorage(QSpan> s) : data(ReadSpans(s.begin(), s.end())) {} explicit QIOOperationDataStorage(QSpan> s) : data(WriteSpans(s.begin(), s.end())) {} explicit QIOOperationDataStorage(const QByteArray &a) : data(a) {} explicit QIOOperationDataStorage(QByteArray &&a) : data(std::move(a)) {} bool isEmpty() const { return std::holds_alternative(data); } bool containsReadSpans() const { return std::holds_alternative(data); } bool containsWriteSpans() const { return std::holds_alternative(data); } bool containsByteArray() const { return std::holds_alternative(data); } ReadSpans &getReadSpans() { Q_ASSERT(containsReadSpans()); return *std::get_if(&data); } const ReadSpans &getReadSpans() const { Q_ASSERT(containsReadSpans()); return *std::get_if(&data); } WriteSpans &getWriteSpans() { Q_ASSERT(containsWriteSpans()); return *std::get_if(&data); } const WriteSpans &getWriteSpans() const { Q_ASSERT(containsWriteSpans()); return *std::get_if(&data); } QByteArray &getByteArray() { Q_ASSERT(containsByteArray()); return *std::get_if(&data); } const QByteArray &getByteArray() const { Q_ASSERT(containsByteArray()); return *std::get_if(&data); } // Potentially can be extended to return a QVariant::value(). template T getValue() const = delete; private: std::variant data; }; template <> inline QSpan> QIOOperationDataStorage::getValue() const { Q_ASSERT(std::holds_alternative(data)); const auto *val = std::get_if(&data); if (val) return QSpan(*val); return {}; } template <> inline QSpan> QIOOperationDataStorage::getValue() const { Q_ASSERT(std::holds_alternative(data)); const auto *val = std::get_if(&data); if (val) return QSpan(*val); return {}; } template <> inline QByteArray QIOOperationDataStorage::getValue() const { Q_ASSERT(std::holds_alternative(data)); const auto *val = std::get_if(&data); if (val) return *val; return {}; } } // namespace QtPrivate class QIOOperationPrivate : public QObjectPrivate { public: Q_DECLARE_PUBLIC(QIOOperation) enum class State : quint8 { Running, Finished, }; explicit QIOOperationPrivate(QtPrivate::QIOOperationDataStorage *storage); ~QIOOperationPrivate(); static QIOOperationPrivate *get(QIOOperation *op) { return op->d_func(); } void appendBytesProcessed(qint64 num); void operationComplete(QIOOperation::Error err); void setError(QIOOperation::Error err); QPointer file; qint64 offset = 0; qint64 processed = 0; QIOOperation::Error error = QIOOperation::Error::None; QIOOperation::Type type = QIOOperation::Type::Unknown; State state = State::Running; // takes ownership std::unique_ptr dataStorage; }; QT_END_NAMESPACE #endif // QIOOPERATION_P_P_H