mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	Add missing changes from yuzu file_util
This commit is contained in:
		
							parent
							
								
									4e9ec4efd0
								
							
						
					
					
						commit
						be52d3a7d0
					
				
					 2 changed files with 142 additions and 10 deletions
				
			
		|  | @ -4,6 +4,7 @@ | |||
| 
 | ||||
| #include <array> | ||||
| #include <memory> | ||||
| #include <sstream> | ||||
| #include <unordered_map> | ||||
| #include "common/assert.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
 | ||||
|     u64 pos = ftello(f); | ||||
|     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; | ||||
|     } | ||||
|     u64 size = ftello(f); | ||||
|     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 size; | ||||
|  | @ -369,7 +370,7 @@ u64 GetSize(FILE* f) { | |||
| bool CreateEmptyFile(const std::string& filename) { | ||||
|     LOG_TRACE(Common_Filesystem, "{}", filename); | ||||
| 
 | ||||
|     if (!FileUtil::IOFile(filename, "wb")) { | ||||
|     if (!FileUtil::IOFile(filename, "wb").IsOpen()) { | ||||
|         LOG_ERROR(Common_Filesystem, "failed {}: {}", filename, GetLastErrorMsg()); | ||||
|         return false; | ||||
|     } | ||||
|  | @ -541,12 +542,11 @@ std::optional<std::string> GetCurrentDir() { | |||
| // Get the current working directory (getcwd uses malloc)
 | ||||
| #ifdef _WIN32 | ||||
|     wchar_t* dir; | ||||
|     if (!(dir = _wgetcwd(nullptr, 0))) | ||||
|     if (!(dir = _wgetcwd(nullptr, 0))) { | ||||
| #else | ||||
|     char* dir; | ||||
|     if (!(dir = getcwd(nullptr, 0))) | ||||
|     if (!(dir = getcwd(nullptr, 0))) { | ||||
| #endif | ||||
|     { | ||||
|         LOG_ERROR(Common_Filesystem, "GetCurrentDirectory failed: {}", GetLastErrorMsg()); | ||||
|         return {}; | ||||
|     } | ||||
|  | @ -557,7 +557,7 @@ std::optional<std::string> GetCurrentDir() { | |||
| #endif | ||||
|     free(dir); | ||||
|     return strDir; | ||||
| } | ||||
| } // namespace FileUtil
 | ||||
| 
 | ||||
| bool SetCurrentDir(const std::string& directory) { | ||||
| #ifdef _WIN32 | ||||
|  | @ -733,7 +733,6 @@ const std::string& GetUserPath(UserPath path) { | |||
|         SetUserPath(); | ||||
|     return g_paths[path]; | ||||
| } | ||||
| 
 | ||||
| std::size_t WriteStringToFile(bool text_file, const std::string& filename, std::string_view 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) { | ||||
|     IOFile file(filename, text_file ? "r" : "rb"); | ||||
| 
 | ||||
|     if (!file) | ||||
|         return false; | ||||
|     if (!file.IsOpen()) | ||||
|         return 0; | ||||
| 
 | ||||
|     str.resize(static_cast<u32>(file.GetSize())); | ||||
|     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(const std::string& filename, const char openmode[], int flags) { | ||||
|  |  | |||
|  | @ -11,6 +11,7 @@ | |||
| #include <limits> | ||||
| #include <optional> | ||||
| #include <string> | ||||
| #include <string_view> | ||||
| #include <type_traits> | ||||
| #include <vector> | ||||
| #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, | ||||
|                      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
 | ||||
| // hopefully will make error checking easier
 | ||||
| // and make forgetting an fclose() harder
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue