FileUtil.h 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. // Copyright 2008 Dolphin Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <cstddef>
  5. #include <filesystem>
  6. #include <fstream>
  7. #include <string>
  8. #include <string_view>
  9. #include <vector>
  10. #include <sys/stat.h>
  11. #include "Common/CommonTypes.h"
  12. #ifdef _WIN32
  13. #include "Common/StringUtil.h"
  14. #endif
  15. #ifdef ANDROID
  16. #include "Common/StringUtil.h"
  17. #include "jni/AndroidCommon/AndroidCommon.h"
  18. #endif
  19. // User directory indices for GetUserPath
  20. enum
  21. {
  22. D_USER_IDX,
  23. D_GCUSER_IDX,
  24. D_WIIROOT_IDX, // always points to User/Wii or global user-configured directory
  25. D_SESSION_WIIROOT_IDX, // may point to minimal temporary directory for determinism
  26. D_CONFIG_IDX, // global settings
  27. D_GAMESETTINGS_IDX, // user-specified settings which override both the global and the default
  28. // settings (per game)
  29. D_SKYLANDERS_IDX,
  30. D_MAPS_IDX,
  31. D_CACHE_IDX,
  32. D_COVERCACHE_IDX,
  33. D_REDUMPCACHE_IDX,
  34. D_SHADERCACHE_IDX,
  35. D_RETROACHIEVEMENTSCACHE_IDX,
  36. D_SHADERS_IDX,
  37. D_STATESAVES_IDX,
  38. D_SCREENSHOTS_IDX,
  39. D_HIRESTEXTURES_IDX,
  40. D_RIIVOLUTION_IDX,
  41. D_DUMP_IDX,
  42. D_DUMPFRAMES_IDX,
  43. D_DUMPOBJECTS_IDX,
  44. D_DUMPAUDIO_IDX,
  45. D_DUMPTEXTURES_IDX,
  46. D_DUMPDSP_IDX,
  47. D_DUMPSSL_IDX,
  48. D_DUMPDEBUG_IDX,
  49. D_DUMPDEBUG_BRANCHWATCH_IDX,
  50. D_DUMPDEBUG_JITBLOCKS_IDX,
  51. D_LOAD_IDX,
  52. D_LOGS_IDX,
  53. D_MAILLOGS_IDX,
  54. D_THEMES_IDX,
  55. D_STYLES_IDX,
  56. D_PIPES_IDX,
  57. D_MEMORYWATCHER_IDX,
  58. D_WFSROOT_IDX,
  59. D_BACKUP_IDX,
  60. D_RESOURCEPACK_IDX,
  61. D_DYNAMICINPUT_IDX,
  62. D_GRAPHICSMOD_IDX,
  63. D_GBAUSER_IDX,
  64. D_GBASAVES_IDX,
  65. D_WIISDCARDSYNCFOLDER_IDX,
  66. D_GPU_DRIVERS_EXTRACTED,
  67. D_GPU_DRIVERS_TMP,
  68. D_GPU_DRIVERS_HOOKS,
  69. D_GPU_DRIVERS_FILE_REDIRECT,
  70. D_ASM_ROOT_IDX,
  71. FIRST_FILE_USER_PATH_IDX,
  72. F_DOLPHINCONFIG_IDX = FIRST_FILE_USER_PATH_IDX,
  73. F_GCPADCONFIG_IDX,
  74. F_WIIPADCONFIG_IDX,
  75. F_GCKEYBOARDCONFIG_IDX,
  76. F_GFXCONFIG_IDX,
  77. F_LOGGERCONFIG_IDX,
  78. F_MAINLOG_IDX,
  79. F_MEM1DUMP_IDX,
  80. F_MEM2DUMP_IDX,
  81. F_ARAMDUMP_IDX,
  82. F_FAKEVMEMDUMP_IDX,
  83. F_GCSRAM_IDX,
  84. F_MEMORYWATCHERLOCATIONS_IDX,
  85. F_MEMORYWATCHERSOCKET_IDX,
  86. F_WIISDCARDIMAGE_IDX,
  87. F_DUALSHOCKUDPCLIENTCONFIG_IDX,
  88. F_FREELOOKCONFIG_IDX,
  89. F_GBABIOS_IDX,
  90. F_RETROACHIEVEMENTSCONFIG_IDX,
  91. NUM_PATH_INDICES
  92. };
  93. namespace File
  94. {
  95. // FileSystem tree node
  96. struct FSTEntry
  97. {
  98. bool isDirectory = false;
  99. u64 size = 0; // File length, or for directories, recursive count of children
  100. std::string physicalName; // Name on disk
  101. std::string virtualName; // Name in FST names table
  102. std::vector<FSTEntry> children;
  103. };
  104. // The functions in this class are functionally identical to the standalone functions
  105. // below, but if you are going to be calling more than one of the functions using the
  106. // same path, creating a single FileInfo object and calling its functions multiple
  107. // times is faster than calling standalone functions multiple times.
  108. class FileInfo final
  109. {
  110. public:
  111. explicit FileInfo(const std::string& path);
  112. explicit FileInfo(const char* path);
  113. // Returns true if the path exists
  114. bool Exists() const;
  115. // Returns true if the path exists and is a directory
  116. bool IsDirectory() const;
  117. // Returns true if the path exists and is a file
  118. bool IsFile() const;
  119. // Returns the size of a file (or returns 0 if the path doesn't refer to a file)
  120. u64 GetSize() const;
  121. private:
  122. std::filesystem::file_status m_status;
  123. std::uintmax_t m_size;
  124. bool m_exists;
  125. };
  126. // Returns true if the path exists
  127. bool Exists(const std::string& path);
  128. // Returns true if the path exists and is a directory
  129. bool IsDirectory(const std::string& path);
  130. // Returns true if the path exists and is a file
  131. bool IsFile(const std::string& path);
  132. // Returns the size of a file (or returns 0 if the path isn't a file that exists)
  133. u64 GetSize(const std::string& path);
  134. // Overloaded GetSize, accepts FILE*
  135. u64 GetSize(FILE* f);
  136. // Creates a single directory. Returns true if successful or if the path already exists.
  137. bool CreateDir(const std::string& filename);
  138. // Creates directories recursively. Returns true if successful or if the path already exists.
  139. bool CreateDirs(std::string_view filename);
  140. // Creates the full path to the file given in fullPath.
  141. // That is, for path '/a/b/c.bin', creates folders '/a' and '/a/b'.
  142. // Returns true if creation is successful or if the path already exists.
  143. bool CreateFullPath(std::string_view fullPath);
  144. enum class IfAbsentBehavior
  145. {
  146. ConsoleWarning,
  147. NoConsoleWarning
  148. };
  149. // Deletes a given filename, return true on success
  150. // Doesn't supports deleting a directory
  151. bool Delete(const std::string& filename,
  152. IfAbsentBehavior behavior = IfAbsentBehavior::ConsoleWarning);
  153. // Deletes a directory filename, returns true on success
  154. bool DeleteDir(const std::string& filename,
  155. IfAbsentBehavior behavior = IfAbsentBehavior::ConsoleWarning);
  156. // renames file srcFilename to destFilename, returns true on success
  157. bool Rename(const std::string& srcFilename, const std::string& destFilename);
  158. // ditto, but syncs the source file and, on Unix, syncs the directories after rename
  159. bool RenameSync(const std::string& srcFilename, const std::string& destFilename);
  160. // Copies a file at source_path to destination_path, as if by std::filesystem::copy_file().
  161. // If a file already exists at destination_path it is overwritten. Returns true on success.
  162. bool CopyRegularFile(std::string_view source_path, std::string_view destination_path);
  163. // creates an empty file filename, returns true on success
  164. bool CreateEmptyFile(const std::string& filename);
  165. // Recursive or non-recursive list of files and directories under directory.
  166. FSTEntry ScanDirectoryTree(std::string directory, bool recursive);
  167. // deletes the given directory and anything under it. Returns true on success.
  168. bool DeleteDirRecursively(const std::string& directory);
  169. // Returns the current directory
  170. std::string GetCurrentDir();
  171. // Copies source_path to dest_path, as if by std::filesystem::copy(). Returns true on success or if
  172. // the source and destination are already the same (as determined by std::filesystem::equivalent()).
  173. bool Copy(std::string_view source_path, std::string_view dest_path,
  174. bool overwrite_existing = false);
  175. // Moves source_path to dest_path. On success, the source_path will no longer exist, and the
  176. // dest_path will contain the data previously in source_path. Files in dest_path will be overwritten
  177. // if they match files in source_path, but files that only exist in dest_path will be kept. No
  178. // guarantee on the state is given on failure; the move may have completely failed or partially
  179. // completed.
  180. bool MoveWithOverwrite(std::string_view source_path, std::string_view dest_path);
  181. // Set the current directory to given directory
  182. bool SetCurrentDir(const std::string& directory);
  183. // Creates and returns the path to a new temporary directory.
  184. std::string CreateTempDir();
  185. // Get a filename that can hopefully be atomically renamed to the given path.
  186. std::string GetTempFilenameForAtomicWrite(std::string path);
  187. // Gets a set user directory path
  188. // Don't call prior to setting the base user directory
  189. const std::string& GetUserPath(unsigned int dir_index);
  190. // Sets a user directory path
  191. // Rebuilds internal directory structure to compensate for the new directory
  192. void SetUserPath(unsigned int dir_index, std::string path);
  193. // probably doesn't belong here
  194. std::string GetThemeDir(const std::string& theme_name);
  195. // Returns the path to where the sys file are
  196. const std::string& GetSysDirectory();
  197. #ifdef ANDROID
  198. void SetSysDirectory(const std::string& path);
  199. void SetGpuDriverDirectories(const std::string& path, const std::string& lib_path);
  200. const std::string GetGpuDriverDirectory(unsigned int dir_index);
  201. #endif
  202. #ifdef __APPLE__
  203. std::string GetBundleDirectory();
  204. #endif
  205. std::string GetExePath();
  206. std::string GetExeDirectory();
  207. bool WriteStringToFile(const std::string& filename, std::string_view str);
  208. bool ReadFileToString(const std::string& filename, std::string& str);
  209. // To deal with Windows not fully supporting UTF-8 and Android not fully supporting paths.
  210. template <typename T>
  211. void OpenFStream(T& fstream, const std::string& filename, std::ios_base::openmode openmode)
  212. {
  213. #ifdef _WIN32
  214. fstream.open(UTF8ToTStr(filename).c_str(), openmode);
  215. #else
  216. #ifdef ANDROID
  217. // Unfortunately it seems like the non-standard __open is the only way to use a file descriptor
  218. if (IsPathAndroidContent(filename))
  219. fstream.__open(OpenAndroidContent(filename, OpenModeToAndroid(openmode)), openmode);
  220. else
  221. #endif
  222. fstream.open(filename.c_str(), openmode);
  223. #endif
  224. }
  225. } // namespace File