mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-08-23 15:23:44 +02:00

This allows more flexibility when loading games in libretro builds, since we can now load games either from a directory or from a ZIP or 7Z archive. Also, the path cache is now active for all filesystem calls made from inside Ruby.
109 lines
2.6 KiB
C++
109 lines
2.6 KiB
C++
//
|
|
// filesystemImpl.cpp
|
|
// Player
|
|
//
|
|
// Created by ゾロアーク on 11/21/20.
|
|
//
|
|
|
|
#include <SDL_filesystem.h>
|
|
|
|
#include "filesystemImpl.h"
|
|
#include "util/exception.h"
|
|
#include "util/debugwriter.h"
|
|
|
|
#ifdef MKXPZ_EXP_FS
|
|
#include <experimental/filesystem>
|
|
namespace fs = std::experimental::filesystem;
|
|
#else
|
|
#include "ghc/filesystem.hpp"
|
|
namespace fs = ghc::filesystem;
|
|
#endif
|
|
|
|
#include <fstream>
|
|
|
|
// https://stackoverflow.com/questions/12774207/fastest-way-to-check-if-a-file-exist-using-standard-c-c11-c
|
|
bool filesystemImpl::fileExists(const char *path) {
|
|
fs::path stdPath(path);
|
|
return (fs::exists(stdPath) && !fs::is_directory(stdPath));
|
|
}
|
|
|
|
|
|
// https://stackoverflow.com/questions/2912520/read-file-contents-into-a-string-in-c
|
|
std::string filesystemImpl::contentsOfFileAsString(const char *path) {
|
|
std::string ret;
|
|
try {
|
|
std::ifstream ifs(path);
|
|
ret = std::string ( (std::istreambuf_iterator<char>(ifs) ),
|
|
(std::istreambuf_iterator<char>() ) );
|
|
} catch (...) {
|
|
throw Exception(Exception::NoFileError, "Failed to read file at %s", path);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
// chdir and getcwd do not support unicode on Windows
|
|
bool filesystemImpl::setCurrentDirectory(const char *path) {
|
|
fs::path stdPath(path);
|
|
fs::current_path(stdPath);
|
|
bool ret;
|
|
|
|
try {
|
|
ret = fs::equivalent(fs::current_path(), stdPath);
|
|
} catch (...) {
|
|
Debug() << "Failed to check current path." << path;
|
|
ret = false;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
std::string filesystemImpl::getCurrentDirectory() {
|
|
std::string ret;
|
|
try {
|
|
ret = std::string(fs::current_path().string());
|
|
} catch (...) {
|
|
throw Exception(Exception::MKXPError, "Failed to retrieve current path");
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
std::string filesystemImpl::normalizePath(const char *path, bool preferred, bool absolute) {
|
|
fs::path stdPath(path);
|
|
|
|
if (!stdPath.is_absolute() && absolute)
|
|
stdPath = fs::current_path() / stdPath;
|
|
|
|
stdPath = stdPath.lexically_normal();
|
|
std::string ret(stdPath);
|
|
for (size_t i = 0; i < ret.length(); i++) {
|
|
char sep;
|
|
char sep_alt;
|
|
#if !defined(MKXPZ_RETRO) && defined(__WIN32__)
|
|
if (preferred) {
|
|
sep = '\\';
|
|
sep_alt = '/';
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
sep = '/';
|
|
sep_alt = '\\';
|
|
}
|
|
|
|
if (ret[i] == sep_alt)
|
|
ret[i] = sep;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
std::string filesystemImpl::getDefaultGameRoot() {
|
|
#ifdef MKXPZ_RETRO
|
|
return "/"; // TODO: implement
|
|
#else
|
|
char *p = SDL_GetBasePath();
|
|
std::string ret(p);
|
|
SDL_free(p);
|
|
return ret;
|
|
#endif // MKXPZ_RETRO
|
|
}
|