From f352619a93c02b48eeb32da1192cf7a6f4bd61c2 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Wed, 27 May 2026 16:38:14 +1000 Subject: [PATCH] Qt: Move ReadFileToByteArray() to QtUtils --- src/duckstation-qt/qtutils.cpp | 47 +++++++++++++++++++++ src/duckstation-qt/qtutils.h | 7 ++++ src/duckstation-qt/themesvgiconengine.cpp | 50 +---------------------- 3 files changed, 56 insertions(+), 48 deletions(-) diff --git a/src/duckstation-qt/qtutils.cpp b/src/duckstation-qt/qtutils.cpp index aa4eacf6a..0d612bfc5 100644 --- a/src/duckstation-qt/qtutils.cpp +++ b/src/duckstation-qt/qtutils.cpp @@ -11,9 +11,11 @@ #include "util/input_manager.h" +#include "common/dynamic_library.h" #include "common/error.h" #include "common/log.h" +#include #include #include #include @@ -60,6 +62,51 @@ static constexpr const char* WINDOW_GEOMETRY_CONFIG_SECTION = "UI"; } // namespace QtUtils +bool QtUtils::ReadFileToByteArray(QIODevice* dev, DynamicHeapArray& out_data) +{ + if (qint64 size; !dev->isSequential() && (size = dev->size()) > 0) + { + out_data.resize(static_cast( + (sizeof(size_t) == sizeof(qint64)) ? size : std::min(size, std::numeric_limits::max()))); + + if (dev->read(reinterpret_cast(out_data.data()), size) != size) + { + out_data.deallocate(); + return false; + } + } + else + { + constexpr size_t chunk_size = 1048576; + size_t read_so_far = 0; + for (;;) + { + const size_t prev_size = out_data.size(); + const size_t new_size = + ((read_so_far + chunk_size) < read_so_far) ? std::numeric_limits::max() : (read_so_far + chunk_size); + const size_t space = (new_size - prev_size); + if (space > 0) + out_data.resize(new_size); + const qint64 bytes_read = + (space > 0) ? dev->read(reinterpret_cast(out_data.data() + read_so_far), static_cast(space)) : 0; + if (bytes_read < 0) + { + out_data.deallocate(); + return false; + } + else if (bytes_read == 0) + { + out_data.resize(prev_size); + break; + } + + read_so_far += static_cast(bytes_read); + } + } + + return true; +} + QFrame* QtUtils::CreateHorizontalLine(QWidget* parent) { QFrame* line = new QFrame(parent); diff --git a/src/duckstation-qt/qtutils.h b/src/duckstation-qt/qtutils.h index 338d80c0f..4486df186 100644 --- a/src/duckstation-qt/qtutils.h +++ b/src/duckstation-qt/qtutils.h @@ -23,6 +23,7 @@ class Error; class QComboBox; class QFrame; class QGridLayout; +class QIODevice; class QKeyEvent; class QLabel; class QMenu; @@ -43,8 +44,14 @@ namespace GameList { enum class EntryType : u8; } +template +class DynamicHeapArray; + namespace QtUtils { +/// Helper function to read a QFile to a DynamicHeapArray. +bool ReadFileToByteArray(QIODevice* dev, DynamicHeapArray& out_data); + /// Creates a horizontal line widget. QFrame* CreateHorizontalLine(QWidget* parent); diff --git a/src/duckstation-qt/themesvgiconengine.cpp b/src/duckstation-qt/themesvgiconengine.cpp index 77c4fd89d..61579da4d 100644 --- a/src/duckstation-qt/themesvgiconengine.cpp +++ b/src/duckstation-qt/themesvgiconengine.cpp @@ -82,52 +82,6 @@ static bool RenderSVGToPixmap(QPixmap& pm, const plutosvg_document* doc, const Q return !pm.isNull(); } -/// Helper function to read a QFile to a DynamicHeapArray. -static bool ReadFileToByteArray(QIODevice* dev, DynamicHeapArray& out_data) -{ - if (qint64 size; !dev->isSequential() && (size = dev->size()) > 0) - { - out_data.resize(static_cast( - (sizeof(size_t) == sizeof(qint64)) ? size : std::min(size, std::numeric_limits::max()))); - - if (dev->read(reinterpret_cast(out_data.data()), size) != size) - { - out_data.deallocate(); - return false; - } - } - else - { - constexpr size_t chunk_size = 1048576; - size_t read_so_far = 0; - for (;;) - { - const size_t prev_size = out_data.size(); - const size_t new_size = - ((read_so_far + chunk_size) < read_so_far) ? std::numeric_limits::max() : (read_so_far + chunk_size); - const size_t space = (new_size - prev_size); - if (space > 0) - out_data.resize(new_size); - const qint64 bytes_read = - (space > 0) ? dev->read(reinterpret_cast(out_data.data() + read_so_far), static_cast(space)) : 0; - if (bytes_read < 0) - { - out_data.deallocate(); - return false; - } - else if (bytes_read == 0) - { - out_data.resize(prev_size); - break; - } - - read_so_far += static_cast(bytes_read); - } - } - - return true; -} - ThemeSVGIconEngine::ThemeSVGIconEngine(const QString& resource_path) : m_resource_path(resource_path) { } @@ -145,7 +99,7 @@ bool ThemeSVGIconEngine::ensureLoaded() const return false; QFile file(m_resource_path); - if (!file.open(QFile::ReadOnly) || !ReadFileToByteArray(&file, m_svg_data)) + if (!file.open(QFile::ReadOnly) || !QtUtils::ReadFileToByteArray(&file, m_svg_data)) { qCritical() << "Failed to open SVG file: " << m_resource_path; m_resource_path = {}; @@ -270,7 +224,7 @@ bool PlutoSVGImageHandler::canRead() const // Read all data once and keep it alive; plutosvg_document borrows the raw pointer. QIODevice* const dev = device(); - if (!dev || !ReadFileToByteArray(dev, m_svg_data)) + if (!dev || !QtUtils::ReadFileToByteArray(dev, m_svg_data)) { qCritical() << "Failed to read SVG data from device"; return false;