mirror of
https://github.com/citra-emu/citra.git
synced 2024-12-18 17:20:10 +00:00
Add missing changes from yuzu file_util
This commit is contained in:
parent
4e9ec4efd0
commit
be52d3a7d0
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <sstream>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/common_funcs.h"
|
#include "common/common_funcs.h"
|
||||||
@ -355,12 +356,12 @@ u64 GetSize(FILE* f) {
|
|||||||
// can't use off_t here because it can be 32-bit
|
// can't use off_t here because it can be 32-bit
|
||||||
u64 pos = ftello(f);
|
u64 pos = ftello(f);
|
||||||
if (fseeko(f, 0, SEEK_END) != 0) {
|
if (fseeko(f, 0, SEEK_END) != 0) {
|
||||||
LOG_ERROR(Common_Filesystem, "GetSize: seek failed {}: {}", (void*)f, GetLastErrorMsg());
|
LOG_ERROR(Common_Filesystem, "GetSize: seek failed {}: {}", fmt::ptr(f), GetLastErrorMsg());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
u64 size = ftello(f);
|
u64 size = ftello(f);
|
||||||
if ((size != pos) && (fseeko(f, pos, SEEK_SET) != 0)) {
|
if ((size != pos) && (fseeko(f, pos, SEEK_SET) != 0)) {
|
||||||
LOG_ERROR(Common_Filesystem, "GetSize: seek failed {}: {}", (void*)f, GetLastErrorMsg());
|
LOG_ERROR(Common_Filesystem, "GetSize: seek failed {}: {}", fmt::ptr(f), GetLastErrorMsg());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
@ -369,7 +370,7 @@ u64 GetSize(FILE* f) {
|
|||||||
bool CreateEmptyFile(const std::string& filename) {
|
bool CreateEmptyFile(const std::string& filename) {
|
||||||
LOG_TRACE(Common_Filesystem, "{}", filename);
|
LOG_TRACE(Common_Filesystem, "{}", filename);
|
||||||
|
|
||||||
if (!FileUtil::IOFile(filename, "wb")) {
|
if (!FileUtil::IOFile(filename, "wb").IsOpen()) {
|
||||||
LOG_ERROR(Common_Filesystem, "failed {}: {}", filename, GetLastErrorMsg());
|
LOG_ERROR(Common_Filesystem, "failed {}: {}", filename, GetLastErrorMsg());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -541,12 +542,11 @@ std::optional<std::string> GetCurrentDir() {
|
|||||||
// Get the current working directory (getcwd uses malloc)
|
// Get the current working directory (getcwd uses malloc)
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
wchar_t* dir;
|
wchar_t* dir;
|
||||||
if (!(dir = _wgetcwd(nullptr, 0)))
|
if (!(dir = _wgetcwd(nullptr, 0))) {
|
||||||
#else
|
#else
|
||||||
char* dir;
|
char* dir;
|
||||||
if (!(dir = getcwd(nullptr, 0)))
|
if (!(dir = getcwd(nullptr, 0))) {
|
||||||
#endif
|
#endif
|
||||||
{
|
|
||||||
LOG_ERROR(Common_Filesystem, "GetCurrentDirectory failed: {}", GetLastErrorMsg());
|
LOG_ERROR(Common_Filesystem, "GetCurrentDirectory failed: {}", GetLastErrorMsg());
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -557,7 +557,7 @@ std::optional<std::string> GetCurrentDir() {
|
|||||||
#endif
|
#endif
|
||||||
free(dir);
|
free(dir);
|
||||||
return strDir;
|
return strDir;
|
||||||
}
|
} // namespace FileUtil
|
||||||
|
|
||||||
bool SetCurrentDir(const std::string& directory) {
|
bool SetCurrentDir(const std::string& directory) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@ -733,7 +733,6 @@ const std::string& GetUserPath(UserPath path) {
|
|||||||
SetUserPath();
|
SetUserPath();
|
||||||
return g_paths[path];
|
return g_paths[path];
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t WriteStringToFile(bool text_file, const std::string& filename, std::string_view str) {
|
std::size_t WriteStringToFile(bool text_file, const std::string& filename, std::string_view str) {
|
||||||
return IOFile(filename, text_file ? "w" : "wb").WriteString(str);
|
return IOFile(filename, text_file ? "w" : "wb").WriteString(str);
|
||||||
}
|
}
|
||||||
@ -741,8 +740,8 @@ std::size_t WriteStringToFile(bool text_file, const std::string& filename, std::
|
|||||||
std::size_t ReadFileToString(bool text_file, const std::string& filename, std::string& str) {
|
std::size_t ReadFileToString(bool text_file, const std::string& filename, std::string& str) {
|
||||||
IOFile file(filename, text_file ? "r" : "rb");
|
IOFile file(filename, text_file ? "r" : "rb");
|
||||||
|
|
||||||
if (!file)
|
if (!file.IsOpen())
|
||||||
return false;
|
return 0;
|
||||||
|
|
||||||
str.resize(static_cast<u32>(file.GetSize()));
|
str.resize(static_cast<u32>(file.GetSize()));
|
||||||
return file.ReadArray(&str[0], str.size());
|
return file.ReadArray(&str[0], str.size());
|
||||||
@ -783,6 +782,103 @@ void SplitFilename83(const std::string& filename, std::array<char, 9>& short_nam
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> SplitPathComponents(std::string_view filename) {
|
||||||
|
std::string copy(filename);
|
||||||
|
std::replace(copy.begin(), copy.end(), '\\', '/');
|
||||||
|
std::vector<std::string> out;
|
||||||
|
|
||||||
|
std::stringstream stream(copy);
|
||||||
|
std::string item;
|
||||||
|
while (std::getline(stream, item, '/')) {
|
||||||
|
out.push_back(std::move(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string_view GetParentPath(std::string_view path) {
|
||||||
|
const auto name_bck_index = path.rfind('\\');
|
||||||
|
const auto name_fwd_index = path.rfind('/');
|
||||||
|
std::size_t name_index;
|
||||||
|
|
||||||
|
if (name_bck_index == std::string_view::npos || name_fwd_index == std::string_view::npos) {
|
||||||
|
name_index = std::min(name_bck_index, name_fwd_index);
|
||||||
|
} else {
|
||||||
|
name_index = std::max(name_bck_index, name_fwd_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
return path.substr(0, name_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string_view GetPathWithoutTop(std::string_view path) {
|
||||||
|
if (path.empty()) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (path[0] == '\\' || path[0] == '/') {
|
||||||
|
path.remove_prefix(1);
|
||||||
|
if (path.empty()) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto name_bck_index = path.find('\\');
|
||||||
|
const auto name_fwd_index = path.find('/');
|
||||||
|
return path.substr(std::min(name_bck_index, name_fwd_index) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string_view GetFilename(std::string_view path) {
|
||||||
|
const auto name_index = path.find_last_of("\\/");
|
||||||
|
|
||||||
|
if (name_index == std::string_view::npos) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return path.substr(name_index + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string_view GetExtensionFromFilename(std::string_view name) {
|
||||||
|
const std::size_t index = name.rfind('.');
|
||||||
|
|
||||||
|
if (index == std::string_view::npos) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return name.substr(index + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string_view RemoveTrailingSlash(std::string_view path) {
|
||||||
|
if (path.empty()) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.back() == '\\' || path.back() == '/') {
|
||||||
|
path.remove_suffix(1);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SanitizePath(std::string_view path_, DirectorySeparator directory_separator) {
|
||||||
|
std::string path(path_);
|
||||||
|
char type1 = directory_separator == DirectorySeparator::BackwardSlash ? '/' : '\\';
|
||||||
|
char type2 = directory_separator == DirectorySeparator::BackwardSlash ? '\\' : '/';
|
||||||
|
|
||||||
|
if (directory_separator == DirectorySeparator::PlatformDefault) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
type1 = '/';
|
||||||
|
type2 = '\\';
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
std::replace(path.begin(), path.end(), type1, type2);
|
||||||
|
path.erase(std::unique(path.begin(), path.end(),
|
||||||
|
[type2](char c1, char c2) { return c1 == type2 && c2 == type2; }),
|
||||||
|
path.end());
|
||||||
|
return std::string(RemoveTrailingSlash(path));
|
||||||
|
}
|
||||||
|
|
||||||
IOFile::IOFile() {}
|
IOFile::IOFile() {}
|
||||||
|
|
||||||
IOFile::IOFile(const std::string& filename, const char openmode[], int flags) {
|
IOFile::IOFile(const std::string& filename, const char openmode[], int flags) {
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <limits>
|
#include <limits>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
@ -166,6 +167,41 @@ std::size_t ReadFileToString(bool text_file, const std::string& filename, std::s
|
|||||||
void SplitFilename83(const std::string& filename, std::array<char, 9>& short_name,
|
void SplitFilename83(const std::string& filename, std::array<char, 9>& short_name,
|
||||||
std::array<char, 4>& extension);
|
std::array<char, 4>& extension);
|
||||||
|
|
||||||
|
// Splits the path on '/' or '\' and put the components into a vector
|
||||||
|
// i.e. "C:\Users\Yuzu\Documents\save.bin" becomes {"C:", "Users", "Yuzu", "Documents", "save.bin" }
|
||||||
|
std::vector<std::string> SplitPathComponents(std::string_view filename);
|
||||||
|
|
||||||
|
// Gets all of the text up to the last '/' or '\' in the path.
|
||||||
|
std::string_view GetParentPath(std::string_view path);
|
||||||
|
|
||||||
|
// Gets all of the text after the first '/' or '\' in the path.
|
||||||
|
std::string_view GetPathWithoutTop(std::string_view path);
|
||||||
|
|
||||||
|
// Gets the filename of the path
|
||||||
|
std::string_view GetFilename(std::string_view path);
|
||||||
|
|
||||||
|
// Gets the extension of the filename
|
||||||
|
std::string_view GetExtensionFromFilename(std::string_view name);
|
||||||
|
|
||||||
|
// Removes the final '/' or '\' if one exists
|
||||||
|
std::string_view RemoveTrailingSlash(std::string_view path);
|
||||||
|
|
||||||
|
// Creates a new vector containing indices [first, last) from the original.
|
||||||
|
template <typename T>
|
||||||
|
std::vector<T> SliceVector(const std::vector<T>& vector, std::size_t first, std::size_t last) {
|
||||||
|
if (first >= last)
|
||||||
|
return {};
|
||||||
|
last = std::min<std::size_t>(last, vector.size());
|
||||||
|
return std::vector<T>(vector.begin() + first, vector.begin() + first + last);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class DirectorySeparator { ForwardSlash, BackwardSlash, PlatformDefault };
|
||||||
|
|
||||||
|
// Removes trailing slash, makes all '\\' into '/', and removes duplicate '/'. Makes '/' into '\\'
|
||||||
|
// depending if directory_separator is BackwardSlash or PlatformDefault and running on windows
|
||||||
|
std::string SanitizePath(std::string_view path,
|
||||||
|
DirectorySeparator directory_separator = DirectorySeparator::ForwardSlash);
|
||||||
|
|
||||||
// simple wrapper for cstdlib file functions to
|
// simple wrapper for cstdlib file functions to
|
||||||
// hopefully will make error checking easier
|
// hopefully will make error checking easier
|
||||||
// and make forgetting an fclose() harder
|
// and make forgetting an fclose() harder
|
||||||
|
Loading…
Reference in New Issue
Block a user