early-access version 1681
This commit is contained in:
parent
b195744abc
commit
e076db528d
12 changed files with 198 additions and 281 deletions
|
@ -1,7 +1,7 @@
|
||||||
yuzu emulator early access
|
yuzu emulator early access
|
||||||
=============
|
=============
|
||||||
|
|
||||||
This is the source code for early-access 1680.
|
This is the source code for early-access 1681.
|
||||||
|
|
||||||
## Legal Notice
|
## Legal Notice
|
||||||
|
|
||||||
|
|
|
@ -26,51 +26,6 @@ namespace fs = std::filesystem;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts the file access mode and file type enums to a file access mode string.
|
|
||||||
*
|
|
||||||
* @param mode File access mode
|
|
||||||
* @param type File type
|
|
||||||
*
|
|
||||||
* @returns A pointer to a string representing the file access mode.
|
|
||||||
*/
|
|
||||||
[[nodiscard]] constexpr const char* AccessModeToStr(FileAccessMode mode, FileType type) {
|
|
||||||
switch (type) {
|
|
||||||
case FileType::BinaryFile:
|
|
||||||
switch (mode) {
|
|
||||||
case FileAccessMode::Read:
|
|
||||||
return "rb";
|
|
||||||
case FileAccessMode::Write:
|
|
||||||
return "wb";
|
|
||||||
case FileAccessMode::Append:
|
|
||||||
return "ab";
|
|
||||||
case FileAccessMode::ReadWrite:
|
|
||||||
return "r+b";
|
|
||||||
case FileAccessMode::ReadAppend:
|
|
||||||
return "a+b";
|
|
||||||
default:
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
case FileType::TextFile:
|
|
||||||
switch (mode) {
|
|
||||||
case FileAccessMode::Read:
|
|
||||||
return "r";
|
|
||||||
case FileAccessMode::Write:
|
|
||||||
return "w";
|
|
||||||
case FileAccessMode::Append:
|
|
||||||
return "a";
|
|
||||||
case FileAccessMode::ReadWrite:
|
|
||||||
return "r+";
|
|
||||||
case FileAccessMode::ReadAppend:
|
|
||||||
return "a+";
|
|
||||||
default:
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -95,9 +50,8 @@ namespace {
|
||||||
return L"r+b";
|
return L"r+b";
|
||||||
case FileAccessMode::ReadAppend:
|
case FileAccessMode::ReadAppend:
|
||||||
return L"a+b";
|
return L"a+b";
|
||||||
default:
|
|
||||||
return L"";
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
case FileType::TextFile:
|
case FileType::TextFile:
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case FileAccessMode::Read:
|
case FileAccessMode::Read:
|
||||||
|
@ -110,12 +64,11 @@ namespace {
|
||||||
return L"r+";
|
return L"r+";
|
||||||
case FileAccessMode::ReadAppend:
|
case FileAccessMode::ReadAppend:
|
||||||
return L"a+";
|
return L"a+";
|
||||||
default:
|
|
||||||
return L"";
|
|
||||||
}
|
}
|
||||||
default:
|
break;
|
||||||
return L"";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return L"";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -139,6 +92,51 @@ namespace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the file access mode and file type enums to a file access mode string.
|
||||||
|
*
|
||||||
|
* @param mode File access mode
|
||||||
|
* @param type File type
|
||||||
|
*
|
||||||
|
* @returns A pointer to a string representing the file access mode.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] constexpr const char* AccessModeToStr(FileAccessMode mode, FileType type) {
|
||||||
|
switch (type) {
|
||||||
|
case FileType::BinaryFile:
|
||||||
|
switch (mode) {
|
||||||
|
case FileAccessMode::Read:
|
||||||
|
return "rb";
|
||||||
|
case FileAccessMode::Write:
|
||||||
|
return "wb";
|
||||||
|
case FileAccessMode::Append:
|
||||||
|
return "ab";
|
||||||
|
case FileAccessMode::ReadWrite:
|
||||||
|
return "r+b";
|
||||||
|
case FileAccessMode::ReadAppend:
|
||||||
|
return "a+b";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FileType::TextFile:
|
||||||
|
switch (mode) {
|
||||||
|
case FileAccessMode::Read:
|
||||||
|
return "r";
|
||||||
|
case FileAccessMode::Write:
|
||||||
|
return "w";
|
||||||
|
case FileAccessMode::Append:
|
||||||
|
return "a";
|
||||||
|
case FileAccessMode::ReadWrite:
|
||||||
|
return "r+";
|
||||||
|
case FileAccessMode::ReadAppend:
|
||||||
|
return "a+";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -172,8 +170,8 @@ std::string ReadStringFromFile(const std::filesystem::path& path, FileType type)
|
||||||
return io_file.ReadString(io_file.GetSize());
|
return io_file.ReadString(io_file.GetSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t WriteStringToFile(const std::filesystem::path& path, FileType type,
|
size_t WriteStringToFile(const std::filesystem::path& path, FileType type,
|
||||||
std::string_view string) {
|
std::string_view string) {
|
||||||
if (!IsFile(path)) {
|
if (!IsFile(path)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -183,8 +181,8 @@ std::size_t WriteStringToFile(const std::filesystem::path& path, FileType type,
|
||||||
return io_file.WriteString(string);
|
return io_file.WriteString(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t AppendStringToFile(const std::filesystem::path& path, FileType type,
|
size_t AppendStringToFile(const std::filesystem::path& path, FileType type,
|
||||||
std::string_view string) {
|
std::string_view string) {
|
||||||
|
|
||||||
if (!Exists(path)) {
|
if (!Exists(path)) {
|
||||||
return WriteStringToFile(path, type, string);
|
return WriteStringToFile(path, type, string);
|
||||||
|
@ -297,19 +295,16 @@ bool IOFile::IsOpen() const {
|
||||||
return file != nullptr;
|
return file != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string IOFile::ReadString(std::size_t length) const {
|
std::string IOFile::ReadString(size_t length) const {
|
||||||
std::vector<char> string_buffer(length);
|
std::vector<char> string_buffer(length);
|
||||||
|
|
||||||
const auto chars_read = ReadSpan<char>(string_buffer);
|
const auto chars_read = ReadSpan<char>(string_buffer);
|
||||||
|
const auto string_size = chars_read != length ? chars_read : length;
|
||||||
|
|
||||||
if (chars_read != length) {
|
return std::string{string_buffer.data(), string_size};
|
||||||
return std::string{string_buffer.data(), chars_read};
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::string{string_buffer.data(), string_buffer.size()};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t IOFile::WriteString(std::span<const char> string) const {
|
size_t IOFile::WriteString(std::span<const char> string) const {
|
||||||
return WriteSpan(string);
|
return WriteSpan(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,16 +18,13 @@
|
||||||
namespace Common::FS {
|
namespace Common::FS {
|
||||||
|
|
||||||
enum class SeekOrigin {
|
enum class SeekOrigin {
|
||||||
/// Seeks from the start of the file.
|
SetOrigin, // Seeks from the start of the file.
|
||||||
SetOrigin,
|
CurrentPosition, // Seeks from the current file pointer position.
|
||||||
/// Seeks from the current file pointer position.
|
End, // Seeks from the end of the file.
|
||||||
CurrentPosition,
|
|
||||||
/// Seeks from the end of the file.
|
|
||||||
End,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens a file stream at path with a specified open mode.
|
* Opens a file stream at path with the specified open mode.
|
||||||
*
|
*
|
||||||
* @param file_stream Reference to file stream
|
* @param file_stream Reference to file stream
|
||||||
* @param path Filesystem path
|
* @param path Filesystem path
|
||||||
|
@ -43,8 +40,7 @@ void OpenFileStream(FileStream& file_stream, const std::filesystem::path& path,
|
||||||
|
|
||||||
template <typename FileStream, typename Path>
|
template <typename FileStream, typename Path>
|
||||||
void OpenFileStream(FileStream& file_stream, const Path& path, std::ios_base::openmode open_mode) {
|
void OpenFileStream(FileStream& file_stream, const Path& path, std::ios_base::openmode open_mode) {
|
||||||
using ValueType = typename Path::value_type;
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
if constexpr (IsChar<ValueType>) {
|
|
||||||
file_stream.open(ToU8String(path), open_mode);
|
file_stream.open(ToU8String(path), open_mode);
|
||||||
} else {
|
} else {
|
||||||
file_stream.open(std::filesystem::path{path}, open_mode);
|
file_stream.open(std::filesystem::path{path}, open_mode);
|
||||||
|
@ -68,8 +64,7 @@ void OpenFileStream(FileStream& file_stream, const Path& path, std::ios_base::op
|
||||||
|
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
[[nodiscard]] std::string ReadStringFromFile(const Path& path, FileType type) {
|
[[nodiscard]] std::string ReadStringFromFile(const Path& path, FileType type) {
|
||||||
using ValueType = typename Path::value_type;
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
if constexpr (IsChar<ValueType>) {
|
|
||||||
return ReadStringFromFile(ToU8String(path), type);
|
return ReadStringFromFile(ToU8String(path), type);
|
||||||
} else {
|
} else {
|
||||||
return ReadStringFromFile(std::filesystem::path{path}, type);
|
return ReadStringFromFile(std::filesystem::path{path}, type);
|
||||||
|
@ -88,16 +83,14 @@ template <typename Path>
|
||||||
*
|
*
|
||||||
* @returns Number of characters successfully written.
|
* @returns Number of characters successfully written.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] std::size_t WriteStringToFile(const std::filesystem::path& path, FileType type,
|
[[nodiscard]] size_t WriteStringToFile(const std::filesystem::path& path, FileType type,
|
||||||
std::string_view string);
|
std::string_view string);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
[[nodiscard]] std::size_t WriteStringToFile(const Path& path, FileType type,
|
[[nodiscard]] size_t WriteStringToFile(const Path& path, FileType type, std::string_view string) {
|
||||||
std::string_view string) {
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
using ValueType = typename Path::value_type;
|
|
||||||
if constexpr (IsChar<ValueType>) {
|
|
||||||
return WriteStringToFile(ToU8String(path), type, string);
|
return WriteStringToFile(ToU8String(path), type, string);
|
||||||
} else {
|
} else {
|
||||||
return WriteStringToFile(std::filesystem::path{path}, type, string);
|
return WriteStringToFile(std::filesystem::path{path}, type, string);
|
||||||
|
@ -116,16 +109,14 @@ template <typename Path>
|
||||||
*
|
*
|
||||||
* @returns Number of characters successfully written.
|
* @returns Number of characters successfully written.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] std::size_t AppendStringToFile(const std::filesystem::path& path, FileType type,
|
[[nodiscard]] size_t AppendStringToFile(const std::filesystem::path& path, FileType type,
|
||||||
std::string_view string);
|
std::string_view string);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
[[nodiscard]] std::size_t AppendStringToFile(const Path& path, FileType type,
|
[[nodiscard]] size_t AppendStringToFile(const Path& path, FileType type, std::string_view string) {
|
||||||
std::string_view string) {
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
using ValueType = typename Path::value_type;
|
|
||||||
if constexpr (IsChar<ValueType>) {
|
|
||||||
return AppendStringToFile(ToU8String(path), type, string);
|
return AppendStringToFile(ToU8String(path), type, string);
|
||||||
} else {
|
} else {
|
||||||
return AppendStringToFile(std::filesystem::path{path}, type, string);
|
return AppendStringToFile(std::filesystem::path{path}, type, string);
|
||||||
|
@ -186,7 +177,7 @@ public:
|
||||||
[[nodiscard]] FileType GetType() const;
|
[[nodiscard]] FileType GetType() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens a file at path with a specified file access mode.
|
* Opens a file at path with the specified file access mode.
|
||||||
* This function behaves differently depending on the FileAccessMode.
|
* This function behaves differently depending on the FileAccessMode.
|
||||||
* These behaviors are documented in each enum value of FileAccessMode.
|
* These behaviors are documented in each enum value of FileAccessMode.
|
||||||
*
|
*
|
||||||
|
@ -215,11 +206,11 @@ public:
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// Closes a file if it is opened.
|
/// Closes the file if it is opened.
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the file is open.
|
* Checks whether the file is open.
|
||||||
* Use this to check whether the calls to Open() or Close() succeeded.
|
* Use this to check whether the calls to Open() or Close() succeeded.
|
||||||
*
|
*
|
||||||
* @returns True if the file is open, false otherwise.
|
* @returns True if the file is open, false otherwise.
|
||||||
|
@ -241,7 +232,7 @@ public:
|
||||||
* @returns Count of T::value_type data or objects successfully read.
|
* @returns Count of T::value_type data or objects successfully read.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
[[nodiscard]] std::size_t Read(T& data) const {
|
[[nodiscard]] size_t Read(T& data) const {
|
||||||
if constexpr (IsSTLContainer<T>) {
|
if constexpr (IsSTLContainer<T>) {
|
||||||
using ContiguousType = typename T::value_type;
|
using ContiguousType = typename T::value_type;
|
||||||
static_assert(std::is_trivially_copyable_v<ContiguousType>,
|
static_assert(std::is_trivially_copyable_v<ContiguousType>,
|
||||||
|
@ -267,7 +258,7 @@ public:
|
||||||
* @returns Count of T::value_type data or objects successfully written.
|
* @returns Count of T::value_type data or objects successfully written.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
[[nodiscard]] std::size_t Write(const T& data) const {
|
[[nodiscard]] size_t Write(const T& data) const {
|
||||||
if constexpr (IsSTLContainer<T>) {
|
if constexpr (IsSTLContainer<T>) {
|
||||||
using ContiguousType = typename T::value_type;
|
using ContiguousType = typename T::value_type;
|
||||||
static_assert(std::is_trivially_copyable_v<ContiguousType>,
|
static_assert(std::is_trivially_copyable_v<ContiguousType>,
|
||||||
|
@ -296,7 +287,7 @@ public:
|
||||||
* @returns Count of T data successfully read.
|
* @returns Count of T data successfully read.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
[[nodiscard]] std::size_t ReadSpan(std::span<T> data) const {
|
[[nodiscard]] size_t ReadSpan(std::span<T> data) const {
|
||||||
static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable.");
|
static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable.");
|
||||||
|
|
||||||
if (!IsOpen()) {
|
if (!IsOpen()) {
|
||||||
|
@ -322,7 +313,7 @@ public:
|
||||||
* @returns Count of T data successfully written.
|
* @returns Count of T data successfully written.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
[[nodiscard]] std::size_t WriteSpan(std::span<const T> data) const {
|
[[nodiscard]] size_t WriteSpan(std::span<const T> data) const {
|
||||||
static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable.");
|
static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable.");
|
||||||
|
|
||||||
if (!IsOpen()) {
|
if (!IsOpen()) {
|
||||||
|
@ -397,7 +388,7 @@ public:
|
||||||
*
|
*
|
||||||
* @returns A string read from the file.
|
* @returns A string read from the file.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] std::string ReadString(std::size_t length) const;
|
[[nodiscard]] std::string ReadString(size_t length) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specialized function to write a string to a file sequentially.
|
* Specialized function to write a string to a file sequentially.
|
||||||
|
@ -408,7 +399,7 @@ public:
|
||||||
*
|
*
|
||||||
* @returns Number of characters successfully written.
|
* @returns Number of characters successfully written.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] std::size_t WriteString(std::span<const char> string) const;
|
[[nodiscard]] size_t WriteString(std::span<const char> string) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flushes any unwritten buffered data into the file.
|
* Flushes any unwritten buffered data into the file.
|
||||||
|
@ -442,7 +433,7 @@ public:
|
||||||
[[nodiscard]] u64 GetSize() const;
|
[[nodiscard]] u64 GetSize() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves the current position of the file pointer with a specified offset and seek origin.
|
* Moves the current position of the file pointer with the specified offset and seek origin.
|
||||||
*
|
*
|
||||||
* @param offset Offset from seek origin
|
* @param offset Offset from seek origin
|
||||||
* @param origin Seek origin
|
* @param origin Seek origin
|
||||||
|
@ -460,9 +451,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::filesystem::path file_path;
|
std::filesystem::path file_path;
|
||||||
|
|
||||||
FileAccessMode file_access_mode;
|
FileAccessMode file_access_mode;
|
||||||
|
|
||||||
FileType file_type;
|
FileType file_type;
|
||||||
|
|
||||||
std::FILE* file = nullptr;
|
std::FILE* file = nullptr;
|
||||||
|
|
|
@ -17,7 +17,7 @@ class IOFile;
|
||||||
// File Operations
|
// File Operations
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new file at path with a specified size.
|
* Creates a new file at path with the specified size.
|
||||||
*
|
*
|
||||||
* Failures occur when:
|
* Failures occur when:
|
||||||
* - Input path is not valid
|
* - Input path is not valid
|
||||||
|
@ -36,8 +36,7 @@ class IOFile;
|
||||||
|
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
[[nodiscard]] bool NewFile(const Path& path, u64 size = 0) {
|
[[nodiscard]] bool NewFile(const Path& path, u64 size = 0) {
|
||||||
using ValueType = typename Path::value_type;
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
if constexpr (IsChar<ValueType>) {
|
|
||||||
return NewFile(ToU8String(path), size);
|
return NewFile(ToU8String(path), size);
|
||||||
} else {
|
} else {
|
||||||
return NewFile(std::filesystem::path{path}, size);
|
return NewFile(std::filesystem::path{path}, size);
|
||||||
|
@ -64,8 +63,7 @@ template <typename Path>
|
||||||
|
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
[[nodiscard]] bool RemoveFile(const Path& path) {
|
[[nodiscard]] bool RemoveFile(const Path& path) {
|
||||||
using ValueType = typename Path::value_type;
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
if constexpr (IsChar<ValueType>) {
|
|
||||||
return RemoveFile(ToU8String(path));
|
return RemoveFile(ToU8String(path));
|
||||||
} else {
|
} else {
|
||||||
return RemoveFile(std::filesystem::path{path});
|
return RemoveFile(std::filesystem::path{path});
|
||||||
|
@ -112,7 +110,7 @@ template <typename Path1, typename Path2>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens a file at path with a specified file access mode.
|
* Opens a file at path with the specified file access mode.
|
||||||
* This function behaves differently depending on the FileAccessMode.
|
* This function behaves differently depending on the FileAccessMode.
|
||||||
* These behaviors are documented in each enum value of FileAccessMode.
|
* These behaviors are documented in each enum value of FileAccessMode.
|
||||||
*
|
*
|
||||||
|
@ -139,8 +137,7 @@ template <typename Path>
|
||||||
[[nodiscard]] std::shared_ptr<IOFile> FileOpen(const Path& path, FileAccessMode mode,
|
[[nodiscard]] std::shared_ptr<IOFile> FileOpen(const Path& path, FileAccessMode mode,
|
||||||
FileType type = FileType::BinaryFile,
|
FileType type = FileType::BinaryFile,
|
||||||
FileShareFlag flag = FileShareFlag::ShareReadOnly) {
|
FileShareFlag flag = FileShareFlag::ShareReadOnly) {
|
||||||
using ValueType = typename Path::value_type;
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
if constexpr (IsChar<ValueType>) {
|
|
||||||
return FileOpen(ToU8String(path), mode, type, flag);
|
return FileOpen(ToU8String(path), mode, type, flag);
|
||||||
} else {
|
} else {
|
||||||
return FileOpen(std::filesystem::path{path}, mode, type, flag);
|
return FileOpen(std::filesystem::path{path}, mode, type, flag);
|
||||||
|
@ -172,8 +169,7 @@ template <typename Path>
|
||||||
|
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
[[nodiscard]] bool CreateDir(const Path& path) {
|
[[nodiscard]] bool CreateDir(const Path& path) {
|
||||||
using ValueType = typename Path::value_type;
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
if constexpr (IsChar<ValueType>) {
|
|
||||||
return CreateDir(ToU8String(path));
|
return CreateDir(ToU8String(path));
|
||||||
} else {
|
} else {
|
||||||
return CreateDir(std::filesystem::path{path});
|
return CreateDir(std::filesystem::path{path});
|
||||||
|
@ -203,8 +199,7 @@ template <typename Path>
|
||||||
|
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
[[nodiscard]] bool CreateDirs(const Path& path) {
|
[[nodiscard]] bool CreateDirs(const Path& path) {
|
||||||
using ValueType = typename Path::value_type;
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
if constexpr (IsChar<ValueType>) {
|
|
||||||
return CreateDirs(ToU8String(path));
|
return CreateDirs(ToU8String(path));
|
||||||
} else {
|
} else {
|
||||||
return CreateDirs(std::filesystem::path{path});
|
return CreateDirs(std::filesystem::path{path});
|
||||||
|
@ -227,8 +222,7 @@ template <typename Path>
|
||||||
|
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
[[nodiscard]] bool CreateParentDir(const Path& path) {
|
[[nodiscard]] bool CreateParentDir(const Path& path) {
|
||||||
using ValueType = typename Path::value_type;
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
if constexpr (IsChar<ValueType>) {
|
|
||||||
return CreateParentDir(ToU8String(path));
|
return CreateParentDir(ToU8String(path));
|
||||||
} else {
|
} else {
|
||||||
return CreateParentDir(std::filesystem::path{path});
|
return CreateParentDir(std::filesystem::path{path});
|
||||||
|
@ -251,8 +245,7 @@ template <typename Path>
|
||||||
|
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
[[nodiscard]] bool CreateParentDirs(const Path& path) {
|
[[nodiscard]] bool CreateParentDirs(const Path& path) {
|
||||||
using ValueType = typename Path::value_type;
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
if constexpr (IsChar<ValueType>) {
|
|
||||||
return CreateParentDirs(ToU8String(path));
|
return CreateParentDirs(ToU8String(path));
|
||||||
} else {
|
} else {
|
||||||
return CreateParentDirs(std::filesystem::path{path});
|
return CreateParentDirs(std::filesystem::path{path});
|
||||||
|
@ -280,8 +273,7 @@ template <typename Path>
|
||||||
|
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
[[nodiscard]] bool RemoveDir(const Path& path) {
|
[[nodiscard]] bool RemoveDir(const Path& path) {
|
||||||
using ValueType = typename Path::value_type;
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
if constexpr (IsChar<ValueType>) {
|
|
||||||
return RemoveDir(ToU8String(path));
|
return RemoveDir(ToU8String(path));
|
||||||
} else {
|
} else {
|
||||||
return RemoveDir(std::filesystem::path{path});
|
return RemoveDir(std::filesystem::path{path});
|
||||||
|
@ -308,8 +300,7 @@ template <typename Path>
|
||||||
|
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
[[nodiscard]] bool RemoveDirRecursively(const Path& path) {
|
[[nodiscard]] bool RemoveDirRecursively(const Path& path) {
|
||||||
using ValueType = typename Path::value_type;
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
if constexpr (IsChar<ValueType>) {
|
|
||||||
return RemoveDirRecursively(ToU8String(path));
|
return RemoveDirRecursively(ToU8String(path));
|
||||||
} else {
|
} else {
|
||||||
return RemoveDirRecursively(std::filesystem::path{path});
|
return RemoveDirRecursively(std::filesystem::path{path});
|
||||||
|
@ -336,8 +327,7 @@ template <typename Path>
|
||||||
|
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
[[nodiscard]] bool RemoveDirContentsRecursively(const Path& path) {
|
[[nodiscard]] bool RemoveDirContentsRecursively(const Path& path) {
|
||||||
using ValueType = typename Path::value_type;
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
if constexpr (IsChar<ValueType>) {
|
|
||||||
return RemoveDirContentsRecursively(ToU8String(path));
|
return RemoveDirContentsRecursively(ToU8String(path));
|
||||||
} else {
|
} else {
|
||||||
return RemoveDirContentsRecursively(std::filesystem::path{path});
|
return RemoveDirContentsRecursively(std::filesystem::path{path});
|
||||||
|
@ -407,8 +397,7 @@ void IterateDirEntries(const std::filesystem::path& path, const DirEntryCallable
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
void IterateDirEntries(const Path& path, const DirEntryCallable& callback,
|
void IterateDirEntries(const Path& path, const DirEntryCallable& callback,
|
||||||
DirEntryFilter filter = DirEntryFilter::All) {
|
DirEntryFilter filter = DirEntryFilter::All) {
|
||||||
using ValueType = typename Path::value_type;
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
if constexpr (IsChar<ValueType>) {
|
|
||||||
IterateDirEntries(ToU8String(path), callback, filter);
|
IterateDirEntries(ToU8String(path), callback, filter);
|
||||||
} else {
|
} else {
|
||||||
IterateDirEntries(std::filesystem::path{path}, callback, filter);
|
IterateDirEntries(std::filesystem::path{path}, callback, filter);
|
||||||
|
@ -442,8 +431,7 @@ void IterateDirEntriesRecursively(const std::filesystem::path& path,
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
void IterateDirEntriesRecursively(const Path& path, const DirEntryCallable& callback,
|
void IterateDirEntriesRecursively(const Path& path, const DirEntryCallable& callback,
|
||||||
DirEntryFilter filter = DirEntryFilter::All) {
|
DirEntryFilter filter = DirEntryFilter::All) {
|
||||||
using ValueType = typename Path::value_type;
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
if constexpr (IsChar<ValueType>) {
|
|
||||||
IterateDirEntriesRecursively(ToU8String(path), callback, filter);
|
IterateDirEntriesRecursively(ToU8String(path), callback, filter);
|
||||||
} else {
|
} else {
|
||||||
IterateDirEntriesRecursively(std::filesystem::path{path}, callback, filter);
|
IterateDirEntriesRecursively(std::filesystem::path{path}, callback, filter);
|
||||||
|
@ -467,8 +455,7 @@ void IterateDirEntriesRecursively(const Path& path, const DirEntryCallable& call
|
||||||
|
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
[[nodiscard]] bool Exists(const Path& path) {
|
[[nodiscard]] bool Exists(const Path& path) {
|
||||||
using ValueType = typename Path::value_type;
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
if constexpr (IsChar<ValueType>) {
|
|
||||||
return Exists(ToU8String(path));
|
return Exists(ToU8String(path));
|
||||||
} else {
|
} else {
|
||||||
return Exists(std::filesystem::path{path});
|
return Exists(std::filesystem::path{path});
|
||||||
|
@ -490,8 +477,7 @@ template <typename Path>
|
||||||
|
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
[[nodiscard]] bool IsFile(const Path& path) {
|
[[nodiscard]] bool IsFile(const Path& path) {
|
||||||
using ValueType = typename Path::value_type;
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
if constexpr (IsChar<ValueType>) {
|
|
||||||
return IsFile(ToU8String(path));
|
return IsFile(ToU8String(path));
|
||||||
} else {
|
} else {
|
||||||
return IsFile(std::filesystem::path{path});
|
return IsFile(std::filesystem::path{path});
|
||||||
|
@ -513,8 +499,7 @@ template <typename Path>
|
||||||
|
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
[[nodiscard]] bool IsDir(const Path& path) {
|
[[nodiscard]] bool IsDir(const Path& path) {
|
||||||
using ValueType = typename Path::value_type;
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
if constexpr (IsChar<ValueType>) {
|
|
||||||
return IsDir(ToU8String(path));
|
return IsDir(ToU8String(path));
|
||||||
} else {
|
} else {
|
||||||
return IsDir(std::filesystem::path{path});
|
return IsDir(std::filesystem::path{path});
|
||||||
|
@ -541,8 +526,7 @@ template <typename Path>
|
||||||
|
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
[[nodiscard]] bool SetCurrentDir(const Path& path) {
|
[[nodiscard]] bool SetCurrentDir(const Path& path) {
|
||||||
using ValueType = typename Path::value_type;
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
if constexpr (IsChar<ValueType>) {
|
|
||||||
return SetCurrentDir(ToU8String(path));
|
return SetCurrentDir(ToU8String(path));
|
||||||
} else {
|
} else {
|
||||||
return SetCurrentDir(std::filesystem::path{path});
|
return SetCurrentDir(std::filesystem::path{path});
|
||||||
|
@ -564,8 +548,7 @@ template <typename Path>
|
||||||
|
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
[[nodiscard]] std::filesystem::file_type GetEntryType(const Path& path) {
|
[[nodiscard]] std::filesystem::file_type GetEntryType(const Path& path) {
|
||||||
using ValueType = typename Path::value_type;
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
if constexpr (IsChar<ValueType>) {
|
|
||||||
return GetEntryType(ToU8String(path));
|
return GetEntryType(ToU8String(path));
|
||||||
} else {
|
} else {
|
||||||
return GetEntryType(std::filesystem::path{path});
|
return GetEntryType(std::filesystem::path{path});
|
||||||
|
@ -587,8 +570,7 @@ template <typename Path>
|
||||||
|
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
[[nodiscard]] u64 GetSize(const Path& path) {
|
[[nodiscard]] u64 GetSize(const Path& path) {
|
||||||
using ValueType = typename Path::value_type;
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
if constexpr (IsChar<ValueType>) {
|
|
||||||
return GetSize(ToU8String(path));
|
return GetSize(ToU8String(path));
|
||||||
} else {
|
} else {
|
||||||
return GetSize(std::filesystem::path{path});
|
return GetSize(std::filesystem::path{path});
|
||||||
|
@ -610,8 +592,7 @@ template <typename Path>
|
||||||
|
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
[[nodiscard]] u64 GetFreeSpaceSize(const Path& path) {
|
[[nodiscard]] u64 GetFreeSpaceSize(const Path& path) {
|
||||||
using ValueType = typename Path::value_type;
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
if constexpr (IsChar<ValueType>) {
|
|
||||||
return GetFreeSpaceSize(ToU8String(path));
|
return GetFreeSpaceSize(ToU8String(path));
|
||||||
} else {
|
} else {
|
||||||
return GetFreeSpaceSize(std::filesystem::path{path});
|
return GetFreeSpaceSize(std::filesystem::path{path});
|
||||||
|
@ -633,8 +614,7 @@ template <typename Path>
|
||||||
|
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
[[nodiscard]] u64 GetTotalSpaceSize(const Path& path) {
|
[[nodiscard]] u64 GetTotalSpaceSize(const Path& path) {
|
||||||
using ValueType = typename Path::value_type;
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
if constexpr (IsChar<ValueType>) {
|
|
||||||
return GetTotalSpaceSize(ToU8String(path));
|
return GetTotalSpaceSize(ToU8String(path));
|
||||||
} else {
|
} else {
|
||||||
return GetTotalSpaceSize(std::filesystem::path{path});
|
return GetTotalSpaceSize(std::filesystem::path{path});
|
||||||
|
|
|
@ -47,14 +47,10 @@ enum class FileType {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class FileShareFlag {
|
enum class FileShareFlag {
|
||||||
/// Provides exclusive access to the file.
|
ShareNone, // Provides exclusive access to the file.
|
||||||
ShareNone,
|
ShareReadOnly, // Provides read only shared access to the file.
|
||||||
/// Provides read only shared access to the file.
|
ShareWriteOnly, // Provides write only shared access to the file.
|
||||||
ShareReadOnly,
|
ShareReadWrite, // Provides read and write shared access to the file.
|
||||||
/// Provides write only shared access to the file.
|
|
||||||
ShareWriteOnly,
|
|
||||||
/// Provides read and write shared access to the file.
|
|
||||||
ShareReadWrite,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class DirEntryFilter {
|
enum class DirEntryFilter {
|
||||||
|
|
|
@ -51,12 +51,6 @@ namespace Common::FS {
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
constexpr std::array<char8_t, 7> INVALID_CHARS{u':', u'*', u'?', u'"', u'<', u'>', u'|'};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The PathManagerImpl is a singleton allowing to manage the mapping of
|
* The PathManagerImpl is a singleton allowing to manage the mapping of
|
||||||
* YuzuPath enums to real filesystem paths.
|
* YuzuPath enums to real filesystem paths.
|
||||||
|
@ -167,31 +161,20 @@ bool ValidatePath(const fs::path& path) {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (const auto path_char : path.relative_path().u8string()) {
|
|
||||||
for (const auto invalid_char : INVALID_CHARS) {
|
|
||||||
if (path_char == invalid_char) {
|
|
||||||
LOG_ERROR(Common_Filesystem, "Input path contains invalid characters, path={}",
|
|
||||||
PathToUTF8String(path));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs::path ConcatPath(const fs::path& first, const fs::path& second) {
|
fs::path ConcatPath(const fs::path& first, const fs::path& second) {
|
||||||
const bool second_has_dir_sep = IsDirSeparator(second.u8string().front());
|
const bool second_has_dir_sep = IsDirSeparator(second.u8string().front());
|
||||||
|
|
||||||
if (second_has_dir_sep) {
|
if (!second_has_dir_sep) {
|
||||||
fs::path concat_path = first;
|
return (first / second).lexically_normal();
|
||||||
|
|
||||||
concat_path += second;
|
|
||||||
|
|
||||||
return concat_path.lexically_normal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (first / second).lexically_normal();
|
fs::path concat_path = first;
|
||||||
|
concat_path += second;
|
||||||
|
|
||||||
|
return concat_path.lexically_normal();
|
||||||
}
|
}
|
||||||
|
|
||||||
fs::path ConcatPathSafe(const fs::path& base, const fs::path& offset) {
|
fs::path ConcatPathSafe(const fs::path& base, const fs::path& offset) {
|
||||||
|
@ -289,14 +272,10 @@ fs::path GetAppDataRoamingDirectory() {
|
||||||
#else
|
#else
|
||||||
|
|
||||||
fs::path GetHomeDirectory() {
|
fs::path GetHomeDirectory() {
|
||||||
fs::path home_path;
|
|
||||||
|
|
||||||
const char* home_env_var = getenv("HOME");
|
const char* home_env_var = getenv("HOME");
|
||||||
|
|
||||||
if (home_env_var) {
|
if (home_env_var) {
|
||||||
home_path = fs::path{home_env_var};
|
return fs::path{home_env_var};
|
||||||
|
|
||||||
return home_path;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO(Common_Filesystem,
|
LOG_INFO(Common_Filesystem,
|
||||||
|
@ -305,35 +284,30 @@ fs::path GetHomeDirectory() {
|
||||||
|
|
||||||
const auto* pw = getpwuid(getuid());
|
const auto* pw = getpwuid(getuid());
|
||||||
|
|
||||||
if (pw) {
|
if (!pw) {
|
||||||
home_path = fs::path{pw->pw_dir};
|
|
||||||
} else {
|
|
||||||
LOG_ERROR(Common_Filesystem, "Failed to get the home path of the current user");
|
LOG_ERROR(Common_Filesystem, "Failed to get the home path of the current user");
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
return home_path;
|
return fs::path{pw->pw_dir};
|
||||||
}
|
}
|
||||||
|
|
||||||
fs::path GetDataDirectory(const std::string& env_name) {
|
fs::path GetDataDirectory(const std::string& env_name) {
|
||||||
fs::path data_path;
|
|
||||||
|
|
||||||
const char* data_env_var = getenv(env_name.c_str());
|
const char* data_env_var = getenv(env_name.c_str());
|
||||||
|
|
||||||
if (data_env_var) {
|
if (data_env_var) {
|
||||||
data_path = fs::path{data_env_var};
|
return fs::path{data_env_var};
|
||||||
|
|
||||||
return data_path;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (env_name == "XDG_DATA_HOME") {
|
if (env_name == "XDG_DATA_HOME") {
|
||||||
data_path = GetHomeDirectory() / ".local/share";
|
return GetHomeDirectory() / ".local/share";
|
||||||
} else if (env_name == "XDG_CACHE_HOME") {
|
} else if (env_name == "XDG_CACHE_HOME") {
|
||||||
data_path = GetHomeDirectory() / ".cache";
|
return GetHomeDirectory() / ".cache";
|
||||||
} else if (env_name == "XDG_CONFIG_HOME") {
|
} else if (env_name == "XDG_CONFIG_HOME") {
|
||||||
data_path = GetHomeDirectory() / ".config";
|
return GetHomeDirectory() / ".config";
|
||||||
}
|
}
|
||||||
|
|
||||||
return data_path;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -12,28 +12,17 @@
|
||||||
namespace Common::FS {
|
namespace Common::FS {
|
||||||
|
|
||||||
enum class YuzuPath {
|
enum class YuzuPath {
|
||||||
/// Where yuzu stores its data.
|
YuzuDir, // Where yuzu stores its data.
|
||||||
YuzuDir,
|
CacheDir, // Where cached filesystem data is stored.
|
||||||
/// Where cached filesystem data is stored.
|
ConfigDir, // Where config files are stored.
|
||||||
CacheDir,
|
DumpDir, // Where dumped data is stored.
|
||||||
/// Where config files are stored.
|
KeysDir, // Where key files are stored.
|
||||||
ConfigDir,
|
LoadDir, // Where cheat/mod files are stored.
|
||||||
/// Where dumped data is stored.
|
LogDir, // Where log files are stored.
|
||||||
DumpDir,
|
NANDDir, // Where the emulated NAND is stored.
|
||||||
/// Where key files are stored.
|
ScreenshotsDir, // Where yuzu screenshots are stored.
|
||||||
KeysDir,
|
SDMCDir, // Where the emulated SDMC is stored.
|
||||||
/// Where cheat/mod files are stored.
|
ShaderDir, // Where shaders are stored.
|
||||||
LoadDir,
|
|
||||||
/// Where log files are stored.
|
|
||||||
LogDir,
|
|
||||||
/// Where the emulated NAND is stored.
|
|
||||||
NANDDir,
|
|
||||||
/// Where yuzu screenshots are stored.
|
|
||||||
ScreenshotsDir,
|
|
||||||
/// Where the emulated SDMC is stored.
|
|
||||||
SDMCDir,
|
|
||||||
/// Where shaders are stored.
|
|
||||||
ShaderDir,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,8 +40,6 @@ enum class YuzuPath {
|
||||||
* A given path is valid if it meets these conditions:
|
* A given path is valid if it meets these conditions:
|
||||||
* - The path is not empty
|
* - The path is not empty
|
||||||
* - The path is not too long
|
* - The path is not too long
|
||||||
* - The path relative to the platform-specific root path does not contain
|
|
||||||
* any of the following characters: ':', '*', '?', '"', '<', '>', '|'
|
|
||||||
*
|
*
|
||||||
* @param path Filesystem path
|
* @param path Filesystem path
|
||||||
*
|
*
|
||||||
|
@ -64,8 +51,7 @@ enum class YuzuPath {
|
||||||
|
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
[[nodiscard]] bool ValidatePath(const Path& path) {
|
[[nodiscard]] bool ValidatePath(const Path& path) {
|
||||||
using ValueType = typename Path::value_type;
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
if constexpr (IsChar<ValueType>) {
|
|
||||||
return ValidatePath(ToU8String(path));
|
return ValidatePath(ToU8String(path));
|
||||||
} else {
|
} else {
|
||||||
return ValidatePath(std::filesystem::path{path});
|
return ValidatePath(std::filesystem::path{path});
|
||||||
|
@ -204,8 +190,7 @@ template <typename Path1, typename Path2>
|
||||||
|
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
[[nodiscard]] std::filesystem::path RemoveTrailingSeparators(const Path& path) {
|
[[nodiscard]] std::filesystem::path RemoveTrailingSeparators(const Path& path) {
|
||||||
using ValueType = typename Path::value_type;
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
if constexpr (IsChar<ValueType>) {
|
|
||||||
return RemoveTrailingSeparators(ToU8String(path));
|
return RemoveTrailingSeparators(ToU8String(path));
|
||||||
} else {
|
} else {
|
||||||
return RemoveTrailingSeparators(std::filesystem::path{path});
|
return RemoveTrailingSeparators(std::filesystem::path{path});
|
||||||
|
@ -245,8 +230,7 @@ void SetYuzuPath(YuzuPath yuzu_path, const std::filesystem::path& new_path);
|
||||||
|
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
[[nodiscard]] void SetYuzuPath(YuzuPath yuzu_path, const Path& new_path) {
|
[[nodiscard]] void SetYuzuPath(YuzuPath yuzu_path, const Path& new_path) {
|
||||||
using ValueType = typename Path::value_type;
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
if constexpr (IsChar<ValueType>) {
|
|
||||||
SetYuzuPath(yuzu_path, ToU8String(new_path));
|
SetYuzuPath(yuzu_path, ToU8String(new_path));
|
||||||
} else {
|
} else {
|
||||||
SetYuzuPath(yuzu_path, std::filesystem::path{new_path});
|
SetYuzuPath(yuzu_path, std::filesystem::path{new_path});
|
||||||
|
|
|
@ -86,7 +86,7 @@ VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, Mode perms) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
cache.insert_or_assign(path, backing);
|
cache.insert_or_assign(path, std::move(backing));
|
||||||
|
|
||||||
// Cannot use make_shared as RealVfsFile constructor is private
|
// Cannot use make_shared as RealVfsFile constructor is private
|
||||||
return std::shared_ptr<RealVfsFile>(new RealVfsFile(*this, backing, path, perms));
|
return std::shared_ptr<RealVfsFile>(new RealVfsFile(*this, backing, path, perms));
|
||||||
|
@ -306,16 +306,16 @@ std::vector<VirtualFile> RealVfsDirectory::IterateEntries<RealVfsFile, VfsFile>(
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<VirtualFile> out;
|
std::vector<VirtualFile> out;
|
||||||
FS::IterateDirEntries(
|
|
||||||
path,
|
|
||||||
[this, &out](const std::filesystem::path& full_path) {
|
|
||||||
const auto full_path_string = FS::PathToUTF8String(full_path);
|
|
||||||
|
|
||||||
out.emplace_back(base.OpenFile(full_path_string, perms));
|
const FS::DirEntryCallable callback = [this, &out](const std::filesystem::path& full_path) {
|
||||||
|
const auto full_path_string = FS::PathToUTF8String(full_path);
|
||||||
|
|
||||||
return true;
|
out.emplace_back(base.OpenFile(full_path_string, perms));
|
||||||
},
|
|
||||||
FS::DirEntryFilter::File);
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
FS::IterateDirEntries(path, callback, FS::DirEntryFilter::File);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -328,16 +328,15 @@ std::vector<VirtualDir> RealVfsDirectory::IterateEntries<RealVfsDirectory, VfsDi
|
||||||
|
|
||||||
std::vector<VirtualDir> out;
|
std::vector<VirtualDir> out;
|
||||||
|
|
||||||
FS::IterateDirEntries(
|
const FS::DirEntryCallable callback = [this, &out](const std::filesystem::path& full_path) {
|
||||||
path,
|
const auto full_path_string = FS::PathToUTF8String(full_path);
|
||||||
[this, &out](const std::filesystem::path& full_path) {
|
|
||||||
const auto full_path_string = FS::PathToUTF8String(full_path);
|
|
||||||
|
|
||||||
out.emplace_back(base.OpenDirectory(full_path_string, perms));
|
out.emplace_back(base.OpenDirectory(full_path_string, perms));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
},
|
};
|
||||||
FS::DirEntryFilter::Directory);
|
|
||||||
|
FS::IterateDirEntries(path, callback, FS::DirEntryFilter::Directory);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -459,18 +458,17 @@ std::map<std::string, VfsEntryType, std::less<>> RealVfsDirectory::GetEntries()
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, VfsEntryType, std::less<>> out;
|
std::map<std::string, VfsEntryType, std::less<>> out;
|
||||||
FS::IterateDirEntries(path,
|
|
||||||
[&out](const std::filesystem::path& full_path) {
|
|
||||||
const auto filename = FS::PathToUTF8String(full_path.filename());
|
|
||||||
|
|
||||||
out.insert_or_assign(filename, FS::IsDir(full_path)
|
const FS::DirEntryCallable callback = [&out](const std::filesystem::path& full_path) {
|
||||||
? VfsEntryType::Directory
|
const auto filename = FS::PathToUTF8String(full_path.filename());
|
||||||
: VfsEntryType::File);
|
|
||||||
|
|
||||||
return true;
|
out.insert_or_assign(filename,
|
||||||
}
|
FS::IsDir(full_path) ? VfsEntryType::Directory : VfsEntryType::File);
|
||||||
|
|
||||||
);
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
FS::IterateDirEntries(path, callback);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,11 +43,11 @@ PerfStats::~PerfStats() {
|
||||||
|
|
||||||
const auto path = Common::FS::GetYuzuPath(Common::FS::YuzuPath::LogDir);
|
const auto path = Common::FS::GetYuzuPath(Common::FS::YuzuPath::LogDir);
|
||||||
// %F Date format expanded is "%Y-%m-%d"
|
// %F Date format expanded is "%Y-%m-%d"
|
||||||
const auto filename =
|
const auto filename = fmt::format("{:%F-%H-%M}_{:016X}.csv", *std::localtime(&t), title_id);
|
||||||
path / fmt::format("{:%F-%H-%M}_{:016X}.csv", *std::localtime(&t), title_id);
|
const auto filepath = path / filename;
|
||||||
|
|
||||||
if (Common::FS::CreateParentDir(path)) {
|
if (Common::FS::CreateParentDir(filepath)) {
|
||||||
Common::FS::IOFile file(filename, Common::FS::FileAccessMode::Write,
|
Common::FS::IOFile file(filepath, Common::FS::FileAccessMode::Write,
|
||||||
Common::FS::FileType::TextFile);
|
Common::FS::FileType::TextFile);
|
||||||
void(file.WriteString(stream.str()));
|
void(file.WriteString(stream.str()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,12 +71,13 @@ std::pair<std::vector<u8>, std::string> GetGameListCachedObject(
|
||||||
return generator();
|
return generator();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto path1 =
|
const auto game_list_dir =
|
||||||
Common::FS::PathToUTF8String(Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) /
|
Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / "game_list";
|
||||||
"game_list" / fmt::format("{}.jpeg", filename));
|
const auto jpeg_name = fmt::format("{}.jpeg", filename);
|
||||||
const auto path2 =
|
const auto app_name = fmt::format("{}.appname.txt", filename);
|
||||||
Common::FS::PathToUTF8String(Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) /
|
|
||||||
"game_list" / fmt::format("{}.appname.txt", filename));
|
const auto path1 = Common::FS::PathToUTF8String(game_list_dir / jpeg_name);
|
||||||
|
const auto path2 = Common::FS::PathToUTF8String(game_list_dir / app_name);
|
||||||
|
|
||||||
void(Common::FS::CreateParentDirs(path1));
|
void(Common::FS::CreateParentDirs(path1));
|
||||||
|
|
||||||
|
|
|
@ -188,13 +188,11 @@ static void InitializeLogging() {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RemoveCachedContents() {
|
static void RemoveCachedContents() {
|
||||||
const auto offline_fonts = Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / "fonts";
|
const auto cache_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir);
|
||||||
const auto offline_manual =
|
const auto offline_fonts = cache_dir / "fonts";
|
||||||
Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / "offline_web_applet_manual";
|
const auto offline_manual = cache_dir / "offline_web_applet_manual";
|
||||||
const auto offline_legal_information = Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) /
|
const auto offline_legal_information = cache_dir / "offline_web_applet_legal_information";
|
||||||
"offline_web_applet_legal_information";
|
const auto offline_system_data = cache_dir / "offline_web_applet_system_data";
|
||||||
const auto offline_system_data =
|
|
||||||
Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / "offline_web_applet_system_data";
|
|
||||||
|
|
||||||
void(Common::FS::RemoveDirRecursively(offline_fonts));
|
void(Common::FS::RemoveDirRecursively(offline_fonts));
|
||||||
void(Common::FS::RemoveDirRecursively(offline_manual));
|
void(Common::FS::RemoveDirRecursively(offline_manual));
|
||||||
|
@ -1572,16 +1570,19 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
|
||||||
Service::Account::ProfileManager manager;
|
Service::Account::ProfileManager manager;
|
||||||
const auto user_id = manager.GetUser(static_cast<std::size_t>(index));
|
const auto user_id = manager.GetUser(static_cast<std::size_t>(index));
|
||||||
ASSERT(user_id);
|
ASSERT(user_id);
|
||||||
path = Common::FS::ConcatPathSafe(
|
|
||||||
nand_dir, FileSys::SaveDataFactory::GetFullPath(
|
const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath(
|
||||||
system, FileSys::SaveDataSpaceId::NandUser,
|
system, FileSys::SaveDataSpaceId::NandUser, FileSys::SaveDataType::SaveData,
|
||||||
FileSys::SaveDataType::SaveData, program_id, user_id->uuid, 0));
|
program_id, user_id->uuid, 0);
|
||||||
|
|
||||||
|
path = Common::FS::ConcatPathSafe(nand_dir, user_save_data_path);
|
||||||
} else {
|
} else {
|
||||||
// Device save data
|
// Device save data
|
||||||
path = Common::FS::ConcatPathSafe(
|
const auto device_save_data_path = FileSys::SaveDataFactory::GetFullPath(
|
||||||
nand_dir, FileSys::SaveDataFactory::GetFullPath(
|
system, FileSys::SaveDataSpaceId::NandUser, FileSys::SaveDataType::SaveData,
|
||||||
system, FileSys::SaveDataSpaceId::NandUser,
|
program_id, {}, 0);
|
||||||
FileSys::SaveDataType::SaveData, program_id, {}, 0));
|
|
||||||
|
path = Common::FS::ConcatPathSafe(nand_dir, device_save_data_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Common::FS::CreateDirs(path)) {
|
if (!Common::FS::CreateDirs(path)) {
|
||||||
|
@ -1613,8 +1614,8 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::OnTransferableShaderCacheOpenFile(u64 program_id) {
|
void GMainWindow::OnTransferableShaderCacheOpenFile(u64 program_id) {
|
||||||
const auto transferable_shader_cache_folder_path =
|
const auto shader_cache_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::ShaderDir);
|
||||||
Common::FS::GetYuzuPath(Common::FS::YuzuPath::ShaderDir) / "opengl" / "transferable";
|
const auto transferable_shader_cache_folder_path = shader_cache_dir / "opengl" / "transferable";
|
||||||
const auto transferable_shader_cache_file_path =
|
const auto transferable_shader_cache_file_path =
|
||||||
transferable_shader_cache_folder_path / fmt::format("{:016X}.bin", program_id);
|
transferable_shader_cache_folder_path / fmt::format("{:016X}.bin", program_id);
|
||||||
|
|
||||||
|
@ -1809,9 +1810,9 @@ void GMainWindow::OnGameListRemoveFile(u64 program_id, GameListRemoveTarget targ
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::RemoveTransferableShaderCache(u64 program_id) {
|
void GMainWindow::RemoveTransferableShaderCache(u64 program_id) {
|
||||||
|
const auto shader_cache_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::ShaderDir);
|
||||||
const auto transferable_shader_cache_file_path =
|
const auto transferable_shader_cache_file_path =
|
||||||
Common::FS::GetYuzuPath(Common::FS::YuzuPath::ShaderDir) / "opengl" / "transferable" /
|
shader_cache_dir / "opengl" / "transferable" / fmt::format("{:016X}.bin", program_id);
|
||||||
fmt::format("{:016X}.bin", program_id);
|
|
||||||
|
|
||||||
if (!Common::FS::Exists(transferable_shader_cache_file_path)) {
|
if (!Common::FS::Exists(transferable_shader_cache_file_path)) {
|
||||||
QMessageBox::warning(this, tr("Error Removing Transferable Shader Cache"),
|
QMessageBox::warning(this, tr("Error Removing Transferable Shader Cache"),
|
||||||
|
@ -1875,9 +1876,10 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto path =
|
const auto dump_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::DumpDir);
|
||||||
Common::FS::PathToUTF8String(Common::FS::GetYuzuPath(Common::FS::YuzuPath::DumpDir) /
|
const auto romfs_dir = fmt::format("{:016X}/romfs", *romfs_title_id);
|
||||||
fmt::format("{:016X}", *romfs_title_id) / "romfs");
|
|
||||||
|
const auto path = Common::FS::PathToUTF8String(dump_dir / romfs_dir);
|
||||||
|
|
||||||
FileSys::VirtualFile romfs;
|
FileSys::VirtualFile romfs;
|
||||||
|
|
||||||
|
@ -3263,9 +3265,8 @@ int main(int argc, char* argv[]) {
|
||||||
QCoreApplication::setApplicationName(QStringLiteral("yuzu"));
|
QCoreApplication::setApplicationName(QStringLiteral("yuzu"));
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
// Increases the maximum open file limit to 4096
|
||||||
_setmaxstdio(4096);
|
_setmaxstdio(4096);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
|
|
@ -49,8 +49,7 @@ bool Config::LoadINI(const std::string& default_contents, bool retry) {
|
||||||
void(FS::CreateParentDir(sdl2_config_loc));
|
void(FS::CreateParentDir(sdl2_config_loc));
|
||||||
void(FS::WriteStringToFile(sdl2_config_loc, FS::FileType::TextFile, default_contents));
|
void(FS::WriteStringToFile(sdl2_config_loc, FS::FileType::TextFile, default_contents));
|
||||||
|
|
||||||
sdl2_config =
|
sdl2_config = std::make_unique<INIReader>(FS::PathToUTF8String(sdl2_config_loc));
|
||||||
std::make_unique<INIReader>(FS::PathToUTF8String(sdl2_config_loc)); // Reopen file
|
|
||||||
|
|
||||||
return LoadINI(default_contents, false);
|
return LoadINI(default_contents, false);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue