// SPDX-License-Identifier: GPL-3.0-only /* * Prism Launcher - Minecraft Launcher * Copyright (c) 2023-2024 Trial97 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include #include #include "Application.h" #if defined(LAUNCHER_APPLICATION) /* PSaveFile * A class that mimics QSaveFile for Windows. * * When reading resources, we need to avoid accessing temporary files * generated by QSaveFile. If we start reading such a file, we may * inadvertently keep it open while QSaveFile is trying to remove it, * or we might detect the file just before it is removed, leading to * race conditions and errors. * * Unfortunately, QSaveFile doesn't provide a way to retrieve the * temporary file name or to set a specific template for the temporary * file name it uses. By default, QSaveFile appends a `.XXXXXX` suffix * to the original file name, where the `XXXXXX` part is dynamically * generated to ensure uniqueness. * * This class acts like a lock by adding and removing the target file * name into/from a global string set, helping to manage access to * files during critical operations. * * Note: Please do not use the `setFileName` function directly, as it * is not virtual and cannot be overridden. */ class PSaveFile : public QSaveFile { public: PSaveFile(const QString& name) : QSaveFile(name) { addPath(name); } PSaveFile(const QString& name, QObject* parent) : QSaveFile(name, parent) { addPath(name); } virtual ~PSaveFile() { if (auto app = APPLICATION_DYN) { app->removeQSavePath(m_absoluteFilePath); } } private: void addPath(const QString& path) { m_absoluteFilePath = QFileInfo(path).absoluteFilePath() + "."; // add dot for tmp files only if (auto app = APPLICATION_DYN) { app->addQSavePath(m_absoluteFilePath); } } QString m_absoluteFilePath; }; #else #define PSaveFile QSaveFile #endif