shadPS4/src/common/path_util.cpp

87 lines
2.6 KiB
C++

// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <unordered_map>
#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<PathType, fs::path> 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