Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FHU: Switch over win32 file operations to std::filesystem #3569

Merged
merged 1 commit into from
Apr 11, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 74 additions & 51 deletions FEXHeaderUtils/FEXHeaderUtils/Filesystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,18 @@
#include <unistd.h>

namespace FHU::Filesystem {
enum class CreateDirectoryResult {
CREATED,
EXISTS,
ERROR,
};

enum class CopyOptions {
NONE,
SKIP_EXISTING,
OVERWRITE_EXISTING,
};

/**
* @brief Check if a filepath exists.
*
Expand All @@ -34,25 +46,27 @@ namespace FHU::Filesystem {
return access(Path.c_str(), F_OK) == 0;
}

/**
* @brief Renames a file and overwrites if it already exists.
*
* @return No error on rename.
*/
[[nodiscard]] inline std::error_code RenameFile(const fextl::string &From, const fextl::string &To) {
return rename(From.c_str(), To.c_str()) == 0 ? std::error_code{} : std::make_error_code(std::errc::io_error);
}

#ifndef _WIN32
inline bool ExistsAt(int FD, const fextl::string &Path) {
return faccessat(FD, Path.c_str(), F_OK, 0) == 0;
}
#endif

enum class CreateDirectoryResult {
CREATED,
EXISTS,
ERROR,
};
/**
* @brief Creates a directory at the provided path.
*
* @param Path The path to create a directory at.
*
* @return Result enum depending.
*/
#ifndef _WIN32
inline CreateDirectoryResult CreateDirectory(const fextl::string &Path) {
auto Result = ::mkdir(Path.c_str(), 0777);
if (Result == 0) {
Expand All @@ -73,18 +87,6 @@ namespace FHU::Filesystem {
// Couldn't create, or the path that existed wasn't a folder.
return CreateDirectoryResult::ERROR;
}
#else
inline CreateDirectoryResult CreateDirectory(const fextl::string &Path) {
std::error_code ec;
if (std::filesystem::exists(Path, ec)) {
return CreateDirectoryResult::EXISTS;
}

return std::filesystem::create_directory(Path, ec) ?
CreateDirectoryResult::CREATED :
CreateDirectoryResult::ERROR;
}
#endif

/**
* @brief Creates a directory tree with the provided path.
Expand Down Expand Up @@ -160,12 +162,6 @@ namespace FHU::Filesystem {
return Path.starts_with('/');
}

enum class CopyOptions {
NONE,
SKIP_EXISTING,
OVERWRITE_EXISTING,
};

/**
* @brief Copy a file from a location to another
*
Expand All @@ -177,7 +173,6 @@ namespace FHU::Filesystem {
*
* @return True if the copy succeeded, false otherwise.
*/
#ifndef _WIN32
inline bool CopyFile(const fextl::string &From, const fextl::string &To, CopyOptions Options = CopyOptions::NONE) {
const bool DestExists = Exists(To);
if (Options == CopyOptions::SKIP_EXISTING && DestExists) {
Expand Down Expand Up @@ -225,30 +220,6 @@ namespace FHU::Filesystem {

return false;
}
#else
inline bool CopyFile(const fextl::string &From, const fextl::string &To, CopyOptions Options = CopyOptions::NONE) {
std::filesystem::copy_options options{};
if (Options == CopyOptions::SKIP_EXISTING) {
options = std::filesystem::copy_options::skip_existing;
}
else if (Options == CopyOptions::OVERWRITE_EXISTING) {
options = std::filesystem::copy_options::overwrite_existing;
}

std::error_code ec;
return std::filesystem::copy_file(From, To, options, ec);
}

#endif

/**
* @brief Renames a file and overwrites if it already exists.
*
* @return No error on rename.
*/
[[nodiscard]] inline std::error_code RenameFile(const fextl::string &From, const fextl::string &To) {
return rename(From.c_str(), To.c_str()) == 0 ? std::error_code{} : std::make_error_code(std::errc::io_error);
}

inline fextl::string LexicallyNormal(const fextl::string &Path) {
const auto PathSize = Path.size();
Expand Down Expand Up @@ -353,11 +324,63 @@ namespace FHU::Filesystem {
NeedsFinalSeparator ? "/" : "");
}

#ifndef _WIN32
inline char *Absolute(const char *Path, char Fill[PATH_MAX]) {
return realpath(Path, Fill);
}
#else
inline fextl::string PathToString(const std::filesystem::path &path) {
return path.string<char, std::char_traits<char>, fextl::FEXAlloc<char>>();
}

inline CreateDirectoryResult CreateDirectory(const fextl::string &Path) {
std::error_code ec;
if (std::filesystem::exists(Path, ec)) {
return CreateDirectoryResult::EXISTS;
}

return std::filesystem::create_directory(Path, ec) ?
CreateDirectoryResult::CREATED :
CreateDirectoryResult::ERROR;
}

inline bool CreateDirectories(const fextl::string &Path) {
std::error_code ec;
return std::filesystem::exists(Path, ec) || std::filesystem::create_directories(Path, ec);
}

inline fextl::string GetFilename(const fextl::string &Path) {
return PathToString(std::filesystem::path(Path).filename());
}

inline fextl::string ParentPath(const fextl::string &Path) {
return PathToString(std::filesystem::path(Path).parent_path());
}

inline bool IsRelative(const std::string_view Path) {
return std::filesystem::path(Path).is_relative();
}

inline bool IsAbsolute(const std::string_view Path) {
return std::filesystem::path(Path).is_absolute();
}

inline bool CopyFile(const fextl::string &From, const fextl::string &To, CopyOptions Options = CopyOptions::NONE) {
std::filesystem::copy_options options{};
if (Options == CopyOptions::SKIP_EXISTING) {
options = std::filesystem::copy_options::skip_existing;
}
else if (Options == CopyOptions::OVERWRITE_EXISTING) {
options = std::filesystem::copy_options::overwrite_existing;
}

std::error_code ec;
return std::filesystem::copy_file(From, To, options, ec);
}

inline fextl::string LexicallyNormal(const fextl::string &Path) {
return PathToString(std::filesystem::path(Path).lexically_normal());
}

inline char *Absolute(const char *Path, char Fill[PATH_MAX]) {
std::error_code ec;
const auto PathAbsolute = std::filesystem::absolute(Path, ec);
Expand Down
Loading