// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include #include "common/logging/log.h" #include "common/path_util.h" #ifndef MAX_PATH #ifdef _WIN32 // This is the maximum number of UTF-16 code units permissible in Windows file paths #define MAX_PATH 260 #else // This is the maximum number of UTF-8 code units permissible in all other OSes' file paths #define MAX_PATH 1024 #endif #endif namespace Common::FS { namespace fs = std::filesystem; static auto UserPaths = [] { std::unordered_map paths; const auto user_dir = std::filesystem::current_path() / PORTABLE_DIR; const auto create_path = [&](PathType shad_path, const fs::path& new_path) { std::filesystem::create_directory(new_path); paths.insert_or_assign(shad_path, new_path); }; create_path(PathType::UserDir, user_dir); create_path(PathType::LogDir, user_dir / LOG_DIR); create_path(PathType::ScreenshotsDir, user_dir / SCREENSHOTS_DIR); create_path(PathType::ShaderDir, user_dir / SHADER_DIR); create_path(PathType::PM4Dir, user_dir / PM4_DIR); create_path(PathType::SaveDataDir, user_dir / SAVEDATA_DIR); create_path(PathType::SysModuleDir, user_dir / SYSMODULES_DIR); return paths; }(); bool ValidatePath(const fs::path& path) { if (path.empty()) { LOG_ERROR(Common_Filesystem, "Input path is empty, path={}", PathToUTF8String(path)); return false; } #ifdef _WIN32 if (path.u16string().size() >= MAX_PATH) { LOG_ERROR(Common_Filesystem, "Input path is too long, path={}", PathToUTF8String(path)); return false; } #else if (path.u8string().size() >= MAX_PATH) { LOG_ERROR(Common_Filesystem, "Input path is too long, path={}", PathToUTF8String(path)); return false; } #endif return true; } std::string PathToUTF8String(const std::filesystem::path& path) { const auto u8_string = path.u8string(); return std::string{u8_string.begin(), u8_string.end()}; } const fs::path& GetUserPath(PathType shad_path) { return UserPaths.at(shad_path); } std::string GetUserPathString(PathType shad_path) { return PathToUTF8String(GetUserPath(shad_path)); } void SetUserPath(PathType shad_path, const fs::path& new_path) { if (!std::filesystem::is_directory(new_path)) { LOG_ERROR(Common_Filesystem, "Filesystem object at new_path={} is not a directory", PathToUTF8String(new_path)); return; } UserPaths.insert_or_assign(shad_path, new_path); } } // namespace Common::FS