diff options
| author | 2016-09-18 09:38:01 +0900 | |
|---|---|---|
| committer | 2016-09-18 09:38:01 +0900 | |
| commit | dc8479928c5aee4c6ad6fe4f59006fb604cee701 (patch) | |
| tree | 569a7f13128450bbab973236615587ff00bced5f /src/common/file_util.cpp | |
| parent | Travis: Import Dolphin’s clang-format hook. (diff) | |
| download | yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.gz yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.xz yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.zip | |
Sources: Run clang-format on everything.
Diffstat (limited to 'src/common/file_util.cpp')
| -rw-r--r-- | src/common/file_util.cpp | 515 |
1 files changed, 223 insertions, 292 deletions
diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index bc83ab737..c8723a4b3 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp | |||
| @@ -2,73 +2,70 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "common/file_util.h" | ||
| 5 | #include "common/assert.h" | 6 | #include "common/assert.h" |
| 6 | #include "common/common_funcs.h" | 7 | #include "common/common_funcs.h" |
| 7 | #include "common/common_paths.h" | 8 | #include "common/common_paths.h" |
| 8 | #include "common/file_util.h" | ||
| 9 | #include "common/logging/log.h" | 9 | #include "common/logging/log.h" |
| 10 | 10 | ||
| 11 | #ifdef _WIN32 | 11 | #ifdef _WIN32 |
| 12 | #include <windows.h> | 12 | #include <windows.h> |
| 13 | #include <shlobj.h> // for SHGetFolderPath | 13 | #include <commdlg.h> // for GetSaveFileName |
| 14 | #include <shellapi.h> | 14 | #include <direct.h> // getcwd |
| 15 | #include <commdlg.h> // for GetSaveFileName | 15 | #include <io.h> |
| 16 | #include <io.h> | 16 | #include <shellapi.h> |
| 17 | #include <direct.h> // getcwd | 17 | #include <shlobj.h> // for SHGetFolderPath |
| 18 | #include <tchar.h> | 18 | #include <tchar.h> |
| 19 | 19 | ||
| 20 | #include "common/string_util.h" | 20 | #include "common/string_util.h" |
| 21 | 21 | ||
| 22 | // 64 bit offsets for windows | 22 | // 64 bit offsets for windows |
| 23 | #define fseeko _fseeki64 | 23 | #define fseeko _fseeki64 |
| 24 | #define ftello _ftelli64 | 24 | #define ftello _ftelli64 |
| 25 | #define atoll _atoi64 | 25 | #define atoll _atoi64 |
| 26 | #define stat64 _stat64 | 26 | #define stat64 _stat64 |
| 27 | #define fstat64 _fstat64 | 27 | #define fstat64 _fstat64 |
| 28 | #define fileno _fileno | 28 | #define fileno _fileno |
| 29 | #else | 29 | #else |
| 30 | #ifdef __APPLE__ | 30 | #ifdef __APPLE__ |
| 31 | #include <sys/param.h> | 31 | #include <sys/param.h> |
| 32 | #endif | 32 | #endif |
| 33 | #include <cctype> | 33 | #include <cctype> |
| 34 | #include <cerrno> | 34 | #include <cerrno> |
| 35 | #include <cstdlib> | 35 | #include <cstdlib> |
| 36 | #include <cstring> | 36 | #include <cstring> |
| 37 | #include <dirent.h> | 37 | #include <dirent.h> |
| 38 | #include <pwd.h> | 38 | #include <pwd.h> |
| 39 | #include <unistd.h> | 39 | #include <unistd.h> |
| 40 | #endif | 40 | #endif |
| 41 | 41 | ||
| 42 | #if defined(__APPLE__) | 42 | #if defined(__APPLE__) |
| 43 | #include <CoreFoundation/CFString.h> | 43 | #include <CoreFoundation/CFBundle.h> |
| 44 | #include <CoreFoundation/CFURL.h> | 44 | #include <CoreFoundation/CFString.h> |
| 45 | #include <CoreFoundation/CFBundle.h> | 45 | #include <CoreFoundation/CFURL.h> |
| 46 | #endif | 46 | #endif |
| 47 | 47 | ||
| 48 | #include <algorithm> | 48 | #include <algorithm> |
| 49 | #include <sys/stat.h> | 49 | #include <sys/stat.h> |
| 50 | 50 | ||
| 51 | #ifndef S_ISDIR | 51 | #ifndef S_ISDIR |
| 52 | #define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) | 52 | #define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) |
| 53 | #endif | 53 | #endif |
| 54 | 54 | ||
| 55 | #ifdef BSD4_4 | 55 | #ifdef BSD4_4 |
| 56 | #define stat64 stat | 56 | #define stat64 stat |
| 57 | #define fstat64 fstat | 57 | #define fstat64 fstat |
| 58 | #endif | 58 | #endif |
| 59 | 59 | ||
| 60 | // This namespace has various generic functions related to files and paths. | 60 | // This namespace has various generic functions related to files and paths. |
| 61 | // The code still needs a ton of cleanup. | 61 | // The code still needs a ton of cleanup. |
| 62 | // REMEMBER: strdup considered harmful! | 62 | // REMEMBER: strdup considered harmful! |
| 63 | namespace FileUtil | 63 | namespace FileUtil { |
| 64 | { | ||
| 65 | 64 | ||
| 66 | // Remove any ending forward slashes from directory paths | 65 | // Remove any ending forward slashes from directory paths |
| 67 | // Modifies argument. | 66 | // Modifies argument. |
| 68 | static void StripTailDirSlashes(std::string &fname) | 67 | static void StripTailDirSlashes(std::string& fname) { |
| 69 | { | 68 | if (fname.length() > 1) { |
| 70 | if (fname.length() > 1) | ||
| 71 | { | ||
| 72 | size_t i = fname.length(); | 69 | size_t i = fname.length(); |
| 73 | while (i > 0 && fname[i - 1] == DIR_SEP_CHR) | 70 | while (i > 0 && fname[i - 1] == DIR_SEP_CHR) |
| 74 | --i; | 71 | --i; |
| @@ -78,8 +75,7 @@ static void StripTailDirSlashes(std::string &fname) | |||
| 78 | } | 75 | } |
| 79 | 76 | ||
| 80 | // Returns true if file filename exists | 77 | // Returns true if file filename exists |
| 81 | bool Exists(const std::string &filename) | 78 | bool Exists(const std::string& filename) { |
| 82 | { | ||
| 83 | struct stat64 file_info; | 79 | struct stat64 file_info; |
| 84 | 80 | ||
| 85 | std::string copy(filename); | 81 | std::string copy(filename); |
| @@ -99,8 +95,7 @@ bool Exists(const std::string &filename) | |||
| 99 | } | 95 | } |
| 100 | 96 | ||
| 101 | // Returns true if filename is a directory | 97 | // Returns true if filename is a directory |
| 102 | bool IsDirectory(const std::string &filename) | 98 | bool IsDirectory(const std::string& filename) { |
| 103 | { | ||
| 104 | struct stat64 file_info; | 99 | struct stat64 file_info; |
| 105 | 100 | ||
| 106 | std::string copy(filename); | 101 | std::string copy(filename); |
| @@ -117,8 +112,8 @@ bool IsDirectory(const std::string &filename) | |||
| 117 | #endif | 112 | #endif |
| 118 | 113 | ||
| 119 | if (result < 0) { | 114 | if (result < 0) { |
| 120 | LOG_WARNING(Common_Filesystem, "stat failed on %s: %s", | 115 | LOG_WARNING(Common_Filesystem, "stat failed on %s: %s", filename.c_str(), |
| 121 | filename.c_str(), GetLastErrorMsg()); | 116 | GetLastErrorMsg()); |
| 122 | return false; | 117 | return false; |
| 123 | } | 118 | } |
| 124 | 119 | ||
| @@ -127,36 +122,32 @@ bool IsDirectory(const std::string &filename) | |||
| 127 | 122 | ||
| 128 | // Deletes a given filename, return true on success | 123 | // Deletes a given filename, return true on success |
| 129 | // Doesn't supports deleting a directory | 124 | // Doesn't supports deleting a directory |
| 130 | bool Delete(const std::string &filename) | 125 | bool Delete(const std::string& filename) { |
| 131 | { | ||
| 132 | LOG_INFO(Common_Filesystem, "file %s", filename.c_str()); | 126 | LOG_INFO(Common_Filesystem, "file %s", filename.c_str()); |
| 133 | 127 | ||
| 134 | // Return true because we care about the file no | 128 | // Return true because we care about the file no |
| 135 | // being there, not the actual delete. | 129 | // being there, not the actual delete. |
| 136 | if (!Exists(filename)) | 130 | if (!Exists(filename)) { |
| 137 | { | ||
| 138 | LOG_WARNING(Common_Filesystem, "%s does not exist", filename.c_str()); | 131 | LOG_WARNING(Common_Filesystem, "%s does not exist", filename.c_str()); |
| 139 | return true; | 132 | return true; |
| 140 | } | 133 | } |
| 141 | 134 | ||
| 142 | // We can't delete a directory | 135 | // We can't delete a directory |
| 143 | if (IsDirectory(filename)) | 136 | if (IsDirectory(filename)) { |
| 144 | { | ||
| 145 | LOG_ERROR(Common_Filesystem, "Failed: %s is a directory", filename.c_str()); | 137 | LOG_ERROR(Common_Filesystem, "Failed: %s is a directory", filename.c_str()); |
| 146 | return false; | 138 | return false; |
| 147 | } | 139 | } |
| 148 | 140 | ||
| 149 | #ifdef _WIN32 | 141 | #ifdef _WIN32 |
| 150 | if (!DeleteFileW(Common::UTF8ToUTF16W(filename).c_str())) | 142 | if (!DeleteFileW(Common::UTF8ToUTF16W(filename).c_str())) { |
| 151 | { | 143 | LOG_ERROR(Common_Filesystem, "DeleteFile failed on %s: %s", filename.c_str(), |
| 152 | LOG_ERROR(Common_Filesystem, "DeleteFile failed on %s: %s", | 144 | GetLastErrorMsg()); |
| 153 | filename.c_str(), GetLastErrorMsg()); | ||
| 154 | return false; | 145 | return false; |
| 155 | } | 146 | } |
| 156 | #else | 147 | #else |
| 157 | if (unlink(filename.c_str()) == -1) { | 148 | if (unlink(filename.c_str()) == -1) { |
| 158 | LOG_ERROR(Common_Filesystem, "unlink failed on %s: %s", | 149 | LOG_ERROR(Common_Filesystem, "unlink failed on %s: %s", filename.c_str(), |
| 159 | filename.c_str(), GetLastErrorMsg()); | 150 | GetLastErrorMsg()); |
| 160 | return false; | 151 | return false; |
| 161 | } | 152 | } |
| 162 | #endif | 153 | #endif |
| @@ -165,16 +156,15 @@ bool Delete(const std::string &filename) | |||
| 165 | } | 156 | } |
| 166 | 157 | ||
| 167 | // Returns true if successful, or path already exists. | 158 | // Returns true if successful, or path already exists. |
| 168 | bool CreateDir(const std::string &path) | 159 | bool CreateDir(const std::string& path) { |
| 169 | { | ||
| 170 | LOG_TRACE(Common_Filesystem, "directory %s", path.c_str()); | 160 | LOG_TRACE(Common_Filesystem, "directory %s", path.c_str()); |
| 171 | #ifdef _WIN32 | 161 | #ifdef _WIN32 |
| 172 | if (::CreateDirectoryW(Common::UTF8ToUTF16W(path).c_str(), nullptr)) | 162 | if (::CreateDirectoryW(Common::UTF8ToUTF16W(path).c_str(), nullptr)) |
| 173 | return true; | 163 | return true; |
| 174 | DWORD error = GetLastError(); | 164 | DWORD error = GetLastError(); |
| 175 | if (error == ERROR_ALREADY_EXISTS) | 165 | if (error == ERROR_ALREADY_EXISTS) { |
| 176 | { | 166 | LOG_WARNING(Common_Filesystem, "CreateDirectory failed on %s: already exists", |
| 177 | LOG_WARNING(Common_Filesystem, "CreateDirectory failed on %s: already exists", path.c_str()); | 167 | path.c_str()); |
| 178 | return true; | 168 | return true; |
| 179 | } | 169 | } |
| 180 | LOG_ERROR(Common_Filesystem, "CreateDirectory failed on %s: %i", path.c_str(), error); | 170 | LOG_ERROR(Common_Filesystem, "CreateDirectory failed on %s: %i", path.c_str(), error); |
| @@ -185,8 +175,7 @@ bool CreateDir(const std::string &path) | |||
| 185 | 175 | ||
| 186 | int err = errno; | 176 | int err = errno; |
| 187 | 177 | ||
| 188 | if (err == EEXIST) | 178 | if (err == EEXIST) { |
| 189 | { | ||
| 190 | LOG_WARNING(Common_Filesystem, "mkdir failed on %s: already exists", path.c_str()); | 179 | LOG_WARNING(Common_Filesystem, "mkdir failed on %s: already exists", path.c_str()); |
| 191 | return true; | 180 | return true; |
| 192 | } | 181 | } |
| @@ -197,20 +186,17 @@ bool CreateDir(const std::string &path) | |||
| 197 | } | 186 | } |
| 198 | 187 | ||
| 199 | // Creates the full path of fullPath returns true on success | 188 | // Creates the full path of fullPath returns true on success |
| 200 | bool CreateFullPath(const std::string &fullPath) | 189 | bool CreateFullPath(const std::string& fullPath) { |
| 201 | { | ||
| 202 | int panicCounter = 100; | 190 | int panicCounter = 100; |
| 203 | LOG_TRACE(Common_Filesystem, "path %s", fullPath.c_str()); | 191 | LOG_TRACE(Common_Filesystem, "path %s", fullPath.c_str()); |
| 204 | 192 | ||
| 205 | if (FileUtil::Exists(fullPath)) | 193 | if (FileUtil::Exists(fullPath)) { |
| 206 | { | ||
| 207 | LOG_WARNING(Common_Filesystem, "path exists %s", fullPath.c_str()); | 194 | LOG_WARNING(Common_Filesystem, "path exists %s", fullPath.c_str()); |
| 208 | return true; | 195 | return true; |
| 209 | } | 196 | } |
| 210 | 197 | ||
| 211 | size_t position = 0; | 198 | size_t position = 0; |
| 212 | while (true) | 199 | while (true) { |
| 213 | { | ||
| 214 | // Find next sub path | 200 | // Find next sub path |
| 215 | position = fullPath.find(DIR_SEP_CHR, position); | 201 | position = fullPath.find(DIR_SEP_CHR, position); |
| 216 | 202 | ||
| @@ -227,8 +213,7 @@ bool CreateFullPath(const std::string &fullPath) | |||
| 227 | 213 | ||
| 228 | // A safety check | 214 | // A safety check |
| 229 | panicCounter--; | 215 | panicCounter--; |
| 230 | if (panicCounter <= 0) | 216 | if (panicCounter <= 0) { |
| 231 | { | ||
| 232 | LOG_ERROR(Common, "CreateFullPath: directory structure is too deep"); | 217 | LOG_ERROR(Common, "CreateFullPath: directory structure is too deep"); |
| 233 | return false; | 218 | return false; |
| 234 | } | 219 | } |
| @@ -236,15 +221,12 @@ bool CreateFullPath(const std::string &fullPath) | |||
| 236 | } | 221 | } |
| 237 | } | 222 | } |
| 238 | 223 | ||
| 239 | |||
| 240 | // Deletes a directory filename, returns true on success | 224 | // Deletes a directory filename, returns true on success |
| 241 | bool DeleteDir(const std::string &filename) | 225 | bool DeleteDir(const std::string& filename) { |
| 242 | { | ||
| 243 | LOG_INFO(Common_Filesystem, "directory %s", filename.c_str()); | 226 | LOG_INFO(Common_Filesystem, "directory %s", filename.c_str()); |
| 244 | 227 | ||
| 245 | // check if a directory | 228 | // check if a directory |
| 246 | if (!FileUtil::IsDirectory(filename)) | 229 | if (!FileUtil::IsDirectory(filename)) { |
| 247 | { | ||
| 248 | LOG_ERROR(Common_Filesystem, "Not a directory %s", filename.c_str()); | 230 | LOG_ERROR(Common_Filesystem, "Not a directory %s", filename.c_str()); |
| 249 | return false; | 231 | return false; |
| 250 | } | 232 | } |
| @@ -262,83 +244,73 @@ bool DeleteDir(const std::string &filename) | |||
| 262 | } | 244 | } |
| 263 | 245 | ||
| 264 | // renames file srcFilename to destFilename, returns true on success | 246 | // renames file srcFilename to destFilename, returns true on success |
| 265 | bool Rename(const std::string &srcFilename, const std::string &destFilename) | 247 | bool Rename(const std::string& srcFilename, const std::string& destFilename) { |
| 266 | { | 248 | LOG_TRACE(Common_Filesystem, "%s --> %s", srcFilename.c_str(), destFilename.c_str()); |
| 267 | LOG_TRACE(Common_Filesystem, "%s --> %s", | ||
| 268 | srcFilename.c_str(), destFilename.c_str()); | ||
| 269 | #ifdef _WIN32 | 249 | #ifdef _WIN32 |
| 270 | if (_wrename(Common::UTF8ToUTF16W(srcFilename).c_str(), Common::UTF8ToUTF16W(destFilename).c_str()) == 0) | 250 | if (_wrename(Common::UTF8ToUTF16W(srcFilename).c_str(), |
| 251 | Common::UTF8ToUTF16W(destFilename).c_str()) == 0) | ||
| 271 | return true; | 252 | return true; |
| 272 | #else | 253 | #else |
| 273 | if (rename(srcFilename.c_str(), destFilename.c_str()) == 0) | 254 | if (rename(srcFilename.c_str(), destFilename.c_str()) == 0) |
| 274 | return true; | 255 | return true; |
| 275 | #endif | 256 | #endif |
| 276 | LOG_ERROR(Common_Filesystem, "failed %s --> %s: %s", | 257 | LOG_ERROR(Common_Filesystem, "failed %s --> %s: %s", srcFilename.c_str(), destFilename.c_str(), |
| 277 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); | 258 | GetLastErrorMsg()); |
| 278 | return false; | 259 | return false; |
| 279 | } | 260 | } |
| 280 | 261 | ||
| 281 | // copies file srcFilename to destFilename, returns true on success | 262 | // copies file srcFilename to destFilename, returns true on success |
| 282 | bool Copy(const std::string &srcFilename, const std::string &destFilename) | 263 | bool Copy(const std::string& srcFilename, const std::string& destFilename) { |
| 283 | { | 264 | LOG_TRACE(Common_Filesystem, "%s --> %s", srcFilename.c_str(), destFilename.c_str()); |
| 284 | LOG_TRACE(Common_Filesystem, "%s --> %s", | ||
| 285 | srcFilename.c_str(), destFilename.c_str()); | ||
| 286 | #ifdef _WIN32 | 265 | #ifdef _WIN32 |
| 287 | if (CopyFileW(Common::UTF8ToUTF16W(srcFilename).c_str(), Common::UTF8ToUTF16W(destFilename).c_str(), FALSE)) | 266 | if (CopyFileW(Common::UTF8ToUTF16W(srcFilename).c_str(), |
| 267 | Common::UTF8ToUTF16W(destFilename).c_str(), FALSE)) | ||
| 288 | return true; | 268 | return true; |
| 289 | 269 | ||
| 290 | LOG_ERROR(Common_Filesystem, "failed %s --> %s: %s", | 270 | LOG_ERROR(Common_Filesystem, "failed %s --> %s: %s", srcFilename.c_str(), destFilename.c_str(), |
| 291 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); | 271 | GetLastErrorMsg()); |
| 292 | return false; | 272 | return false; |
| 293 | #else | 273 | #else |
| 294 | 274 | ||
| 295 | // buffer size | 275 | // buffer size |
| 296 | #define BSIZE 1024 | 276 | #define BSIZE 1024 |
| 297 | 277 | ||
| 298 | char buffer[BSIZE]; | 278 | char buffer[BSIZE]; |
| 299 | 279 | ||
| 300 | // Open input file | 280 | // Open input file |
| 301 | FILE *input = fopen(srcFilename.c_str(), "rb"); | 281 | FILE* input = fopen(srcFilename.c_str(), "rb"); |
| 302 | if (!input) | 282 | if (!input) { |
| 303 | { | 283 | LOG_ERROR(Common_Filesystem, "opening input failed %s --> %s: %s", srcFilename.c_str(), |
| 304 | LOG_ERROR(Common_Filesystem, "opening input failed %s --> %s: %s", | 284 | destFilename.c_str(), GetLastErrorMsg()); |
| 305 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); | ||
| 306 | return false; | 285 | return false; |
| 307 | } | 286 | } |
| 308 | 287 | ||
| 309 | // open output file | 288 | // open output file |
| 310 | FILE *output = fopen(destFilename.c_str(), "wb"); | 289 | FILE* output = fopen(destFilename.c_str(), "wb"); |
| 311 | if (!output) | 290 | if (!output) { |
| 312 | { | ||
| 313 | fclose(input); | 291 | fclose(input); |
| 314 | LOG_ERROR(Common_Filesystem, "opening output failed %s --> %s: %s", | 292 | LOG_ERROR(Common_Filesystem, "opening output failed %s --> %s: %s", srcFilename.c_str(), |
| 315 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); | 293 | destFilename.c_str(), GetLastErrorMsg()); |
| 316 | return false; | 294 | return false; |
| 317 | } | 295 | } |
| 318 | 296 | ||
| 319 | // copy loop | 297 | // copy loop |
| 320 | while (!feof(input)) | 298 | while (!feof(input)) { |
| 321 | { | ||
| 322 | // read input | 299 | // read input |
| 323 | int rnum = fread(buffer, sizeof(char), BSIZE, input); | 300 | int rnum = fread(buffer, sizeof(char), BSIZE, input); |
| 324 | if (rnum != BSIZE) | 301 | if (rnum != BSIZE) { |
| 325 | { | 302 | if (ferror(input) != 0) { |
| 326 | if (ferror(input) != 0) | 303 | LOG_ERROR(Common_Filesystem, "failed reading from source, %s --> %s: %s", |
| 327 | { | 304 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); |
| 328 | LOG_ERROR(Common_Filesystem, | ||
| 329 | "failed reading from source, %s --> %s: %s", | ||
| 330 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); | ||
| 331 | goto bail; | 305 | goto bail; |
| 332 | } | 306 | } |
| 333 | } | 307 | } |
| 334 | 308 | ||
| 335 | // write output | 309 | // write output |
| 336 | int wnum = fwrite(buffer, sizeof(char), rnum, output); | 310 | int wnum = fwrite(buffer, sizeof(char), rnum, output); |
| 337 | if (wnum != rnum) | 311 | if (wnum != rnum) { |
| 338 | { | 312 | LOG_ERROR(Common_Filesystem, "failed writing to output, %s --> %s: %s", |
| 339 | LOG_ERROR(Common_Filesystem, | 313 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); |
| 340 | "failed writing to output, %s --> %s: %s", | ||
| 341 | srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); | ||
| 342 | goto bail; | 314 | goto bail; |
| 343 | } | 315 | } |
| 344 | } | 316 | } |
| @@ -356,16 +328,13 @@ bail: | |||
| 356 | } | 328 | } |
| 357 | 329 | ||
| 358 | // Returns the size of filename (64bit) | 330 | // Returns the size of filename (64bit) |
| 359 | u64 GetSize(const std::string &filename) | 331 | u64 GetSize(const std::string& filename) { |
| 360 | { | 332 | if (!Exists(filename)) { |
| 361 | if (!Exists(filename)) | ||
| 362 | { | ||
| 363 | LOG_ERROR(Common_Filesystem, "failed %s: No such file", filename.c_str()); | 333 | LOG_ERROR(Common_Filesystem, "failed %s: No such file", filename.c_str()); |
| 364 | return 0; | 334 | return 0; |
| 365 | } | 335 | } |
| 366 | 336 | ||
| 367 | if (IsDirectory(filename)) | 337 | if (IsDirectory(filename)) { |
| 368 | { | ||
| 369 | LOG_ERROR(Common_Filesystem, "failed %s: is a directory", filename.c_str()); | 338 | LOG_ERROR(Common_Filesystem, "failed %s: is a directory", filename.c_str()); |
| 370 | return 0; | 339 | return 0; |
| 371 | } | 340 | } |
| @@ -377,65 +346,54 @@ u64 GetSize(const std::string &filename) | |||
| 377 | if (stat64(filename.c_str(), &buf) == 0) | 346 | if (stat64(filename.c_str(), &buf) == 0) |
| 378 | #endif | 347 | #endif |
| 379 | { | 348 | { |
| 380 | LOG_TRACE(Common_Filesystem, "%s: %lld", | 349 | LOG_TRACE(Common_Filesystem, "%s: %lld", filename.c_str(), (long long)buf.st_size); |
| 381 | filename.c_str(), (long long)buf.st_size); | ||
| 382 | return buf.st_size; | 350 | return buf.st_size; |
| 383 | } | 351 | } |
| 384 | 352 | ||
| 385 | LOG_ERROR(Common_Filesystem, "Stat failed %s: %s", | 353 | LOG_ERROR(Common_Filesystem, "Stat failed %s: %s", filename.c_str(), GetLastErrorMsg()); |
| 386 | filename.c_str(), GetLastErrorMsg()); | ||
| 387 | return 0; | 354 | return 0; |
| 388 | } | 355 | } |
| 389 | 356 | ||
| 390 | // Overloaded GetSize, accepts file descriptor | 357 | // Overloaded GetSize, accepts file descriptor |
| 391 | u64 GetSize(const int fd) | 358 | u64 GetSize(const int fd) { |
| 392 | { | ||
| 393 | struct stat64 buf; | 359 | struct stat64 buf; |
| 394 | if (fstat64(fd, &buf) != 0) { | 360 | if (fstat64(fd, &buf) != 0) { |
| 395 | LOG_ERROR(Common_Filesystem, "GetSize: stat failed %i: %s", | 361 | LOG_ERROR(Common_Filesystem, "GetSize: stat failed %i: %s", fd, GetLastErrorMsg()); |
| 396 | fd, GetLastErrorMsg()); | ||
| 397 | return 0; | 362 | return 0; |
| 398 | } | 363 | } |
| 399 | return buf.st_size; | 364 | return buf.st_size; |
| 400 | } | 365 | } |
| 401 | 366 | ||
| 402 | // Overloaded GetSize, accepts FILE* | 367 | // Overloaded GetSize, accepts FILE* |
| 403 | u64 GetSize(FILE *f) | 368 | u64 GetSize(FILE* f) { |
| 404 | { | ||
| 405 | // can't use off_t here because it can be 32-bit | 369 | // can't use off_t here because it can be 32-bit |
| 406 | u64 pos = ftello(f); | 370 | u64 pos = ftello(f); |
| 407 | if (fseeko(f, 0, SEEK_END) != 0) { | 371 | if (fseeko(f, 0, SEEK_END) != 0) { |
| 408 | LOG_ERROR(Common_Filesystem, "GetSize: seek failed %p: %s", | 372 | LOG_ERROR(Common_Filesystem, "GetSize: seek failed %p: %s", f, GetLastErrorMsg()); |
| 409 | f, GetLastErrorMsg()); | ||
| 410 | return 0; | 373 | return 0; |
| 411 | } | 374 | } |
| 412 | u64 size = ftello(f); | 375 | u64 size = ftello(f); |
| 413 | if ((size != pos) && (fseeko(f, pos, SEEK_SET) != 0)) { | 376 | if ((size != pos) && (fseeko(f, pos, SEEK_SET) != 0)) { |
| 414 | LOG_ERROR(Common_Filesystem, "GetSize: seek failed %p: %s", | 377 | LOG_ERROR(Common_Filesystem, "GetSize: seek failed %p: %s", f, GetLastErrorMsg()); |
| 415 | f, GetLastErrorMsg()); | ||
| 416 | return 0; | 378 | return 0; |
| 417 | } | 379 | } |
| 418 | return size; | 380 | return size; |
| 419 | } | 381 | } |
| 420 | 382 | ||
| 421 | // creates an empty file filename, returns true on success | 383 | // creates an empty file filename, returns true on success |
| 422 | bool CreateEmptyFile(const std::string &filename) | 384 | bool CreateEmptyFile(const std::string& filename) { |
| 423 | { | ||
| 424 | LOG_TRACE(Common_Filesystem, "%s", filename.c_str()); | 385 | LOG_TRACE(Common_Filesystem, "%s", filename.c_str()); |
| 425 | 386 | ||
| 426 | if (!FileUtil::IOFile(filename, "wb")) | 387 | if (!FileUtil::IOFile(filename, "wb")) { |
| 427 | { | 388 | LOG_ERROR(Common_Filesystem, "failed %s: %s", filename.c_str(), GetLastErrorMsg()); |
| 428 | LOG_ERROR(Common_Filesystem, "failed %s: %s", | ||
| 429 | filename.c_str(), GetLastErrorMsg()); | ||
| 430 | return false; | 389 | return false; |
| 431 | } | 390 | } |
| 432 | 391 | ||
| 433 | return true; | 392 | return true; |
| 434 | } | 393 | } |
| 435 | 394 | ||
| 436 | 395 | bool ForeachDirectoryEntry(unsigned* num_entries_out, const std::string& directory, | |
| 437 | bool ForeachDirectoryEntry(unsigned* num_entries_out, const std::string &directory, DirectoryEntryCallable callback) | 396 | DirectoryEntryCallable callback) { |
| 438 | { | ||
| 439 | LOG_TRACE(Common_Filesystem, "directory %s", directory.c_str()); | 397 | LOG_TRACE(Common_Filesystem, "directory %s", directory.c_str()); |
| 440 | 398 | ||
| 441 | // How many files + directories we found | 399 | // How many files + directories we found |
| @@ -457,7 +415,7 @@ bool ForeachDirectoryEntry(unsigned* num_entries_out, const std::string &directo | |||
| 457 | do { | 415 | do { |
| 458 | const std::string virtual_name(Common::UTF16ToUTF8(ffd.cFileName)); | 416 | const std::string virtual_name(Common::UTF16ToUTF8(ffd.cFileName)); |
| 459 | #else | 417 | #else |
| 460 | DIR *dirp = opendir(directory.c_str()); | 418 | DIR* dirp = opendir(directory.c_str()); |
| 461 | if (!dirp) | 419 | if (!dirp) |
| 462 | return false; | 420 | return false; |
| 463 | 421 | ||
| @@ -493,8 +451,8 @@ bool ForeachDirectoryEntry(unsigned* num_entries_out, const std::string &directo | |||
| 493 | return true; | 451 | return true; |
| 494 | } | 452 | } |
| 495 | 453 | ||
| 496 | unsigned ScanDirectoryTree(const std::string &directory, FSTEntry& parent_entry, unsigned int recursion) | 454 | unsigned ScanDirectoryTree(const std::string& directory, FSTEntry& parent_entry, |
| 497 | { | 455 | unsigned int recursion) { |
| 498 | const auto callback = [recursion, &parent_entry](unsigned* num_entries_out, | 456 | const auto callback = [recursion, &parent_entry](unsigned* num_entries_out, |
| 499 | const std::string& directory, | 457 | const std::string& directory, |
| 500 | const std::string& virtual_name) -> bool { | 458 | const std::string& virtual_name) -> bool { |
| @@ -526,11 +484,8 @@ unsigned ScanDirectoryTree(const std::string &directory, FSTEntry& parent_entry, | |||
| 526 | return ForeachDirectoryEntry(&num_entries, directory, callback) ? num_entries : 0; | 484 | return ForeachDirectoryEntry(&num_entries, directory, callback) ? num_entries : 0; |
| 527 | } | 485 | } |
| 528 | 486 | ||
| 529 | 487 | bool DeleteDirRecursively(const std::string& directory, unsigned int recursion) { | |
| 530 | bool DeleteDirRecursively(const std::string &directory, unsigned int recursion) | 488 | const auto callback = [recursion](unsigned* num_entries_out, const std::string& directory, |
| 531 | { | ||
| 532 | const auto callback = [recursion](unsigned* num_entries_out, | ||
| 533 | const std::string& directory, | ||
| 534 | const std::string& virtual_name) -> bool { | 489 | const std::string& virtual_name) -> bool { |
| 535 | std::string new_path = directory + DIR_SEP_CHR + virtual_name; | 490 | std::string new_path = directory + DIR_SEP_CHR + virtual_name; |
| 536 | 491 | ||
| @@ -551,53 +506,53 @@ bool DeleteDirRecursively(const std::string &directory, unsigned int recursion) | |||
| 551 | } | 506 | } |
| 552 | 507 | ||
| 553 | // Create directory and copy contents (does not overwrite existing files) | 508 | // Create directory and copy contents (does not overwrite existing files) |
| 554 | void CopyDir(const std::string &source_path, const std::string &dest_path) | 509 | void CopyDir(const std::string& source_path, const std::string& dest_path) { |
| 555 | { | ||
| 556 | #ifndef _WIN32 | 510 | #ifndef _WIN32 |
| 557 | if (source_path == dest_path) return; | 511 | if (source_path == dest_path) |
| 558 | if (!FileUtil::Exists(source_path)) return; | 512 | return; |
| 559 | if (!FileUtil::Exists(dest_path)) FileUtil::CreateFullPath(dest_path); | 513 | if (!FileUtil::Exists(source_path)) |
| 560 | 514 | return; | |
| 561 | DIR *dirp = opendir(source_path.c_str()); | 515 | if (!FileUtil::Exists(dest_path)) |
| 562 | if (!dirp) return; | 516 | FileUtil::CreateFullPath(dest_path); |
| 517 | |||
| 518 | DIR* dirp = opendir(source_path.c_str()); | ||
| 519 | if (!dirp) | ||
| 520 | return; | ||
| 563 | 521 | ||
| 564 | while (struct dirent* result = readdir(dirp)) { | 522 | while (struct dirent* result = readdir(dirp)) { |
| 565 | const std::string virtualName(result->d_name); | 523 | const std::string virtualName(result->d_name); |
| 566 | // check for "." and ".." | 524 | // check for "." and ".." |
| 567 | if (((virtualName[0] == '.') && (virtualName[1] == '\0')) || | 525 | if (((virtualName[0] == '.') && (virtualName[1] == '\0')) || |
| 568 | ((virtualName[0] == '.') && (virtualName[1] == '.') && | 526 | ((virtualName[0] == '.') && (virtualName[1] == '.') && (virtualName[2] == '\0'))) |
| 569 | (virtualName[2] == '\0'))) | ||
| 570 | continue; | 527 | continue; |
| 571 | 528 | ||
| 572 | std::string source, dest; | 529 | std::string source, dest; |
| 573 | source = source_path + virtualName; | 530 | source = source_path + virtualName; |
| 574 | dest = dest_path + virtualName; | 531 | dest = dest_path + virtualName; |
| 575 | if (IsDirectory(source)) | 532 | if (IsDirectory(source)) { |
| 576 | { | ||
| 577 | source += '/'; | 533 | source += '/'; |
| 578 | dest += '/'; | 534 | dest += '/'; |
| 579 | if (!FileUtil::Exists(dest)) FileUtil::CreateFullPath(dest); | 535 | if (!FileUtil::Exists(dest)) |
| 536 | FileUtil::CreateFullPath(dest); | ||
| 580 | CopyDir(source, dest); | 537 | CopyDir(source, dest); |
| 581 | } | 538 | } else if (!FileUtil::Exists(dest)) |
| 582 | else if (!FileUtil::Exists(dest)) FileUtil::Copy(source, dest); | 539 | FileUtil::Copy(source, dest); |
| 583 | } | 540 | } |
| 584 | closedir(dirp); | 541 | closedir(dirp); |
| 585 | #endif | 542 | #endif |
| 586 | } | 543 | } |
| 587 | 544 | ||
| 588 | // Returns the current directory | 545 | // Returns the current directory |
| 589 | std::string GetCurrentDir() | 546 | std::string GetCurrentDir() { |
| 590 | { | 547 | // Get the current working directory (getcwd uses malloc) |
| 591 | // Get the current working directory (getcwd uses malloc) | ||
| 592 | #ifdef _WIN32 | 548 | #ifdef _WIN32 |
| 593 | wchar_t *dir; | 549 | wchar_t* dir; |
| 594 | if (!(dir = _wgetcwd(nullptr, 0))) { | 550 | if (!(dir = _wgetcwd(nullptr, 0))) { |
| 595 | #else | 551 | #else |
| 596 | char *dir; | 552 | char* dir; |
| 597 | if (!(dir = getcwd(nullptr, 0))) { | 553 | if (!(dir = getcwd(nullptr, 0))) { |
| 598 | #endif | 554 | #endif |
| 599 | LOG_ERROR(Common_Filesystem, "GetCurrentDirectory failed: %s", | 555 | LOG_ERROR(Common_Filesystem, "GetCurrentDirectory failed: %s", GetLastErrorMsg()); |
| 600 | GetLastErrorMsg()); | ||
| 601 | return nullptr; | 556 | return nullptr; |
| 602 | } | 557 | } |
| 603 | #ifdef _WIN32 | 558 | #ifdef _WIN32 |
| @@ -610,8 +565,7 @@ std::string GetCurrentDir() | |||
| 610 | } | 565 | } |
| 611 | 566 | ||
| 612 | // Sets the current directory to the given directory | 567 | // Sets the current directory to the given directory |
| 613 | bool SetCurrentDir(const std::string &directory) | 568 | bool SetCurrentDir(const std::string& directory) { |
| 614 | { | ||
| 615 | #ifdef _WIN32 | 569 | #ifdef _WIN32 |
| 616 | return _wchdir(Common::UTF8ToUTF16W(directory).c_str()) == 0; | 570 | return _wchdir(Common::UTF8ToUTF16W(directory).c_str()) == 0; |
| 617 | #else | 571 | #else |
| @@ -620,8 +574,7 @@ bool SetCurrentDir(const std::string &directory) | |||
| 620 | } | 574 | } |
| 621 | 575 | ||
| 622 | #if defined(__APPLE__) | 576 | #if defined(__APPLE__) |
| 623 | std::string GetBundleDirectory() | 577 | std::string GetBundleDirectory() { |
| 624 | { | ||
| 625 | CFURLRef BundleRef; | 578 | CFURLRef BundleRef; |
| 626 | char AppBundlePath[MAXPATHLEN]; | 579 | char AppBundlePath[MAXPATHLEN]; |
| 627 | // Get the main bundle for the app | 580 | // Get the main bundle for the app |
| @@ -636,11 +589,9 @@ std::string GetBundleDirectory() | |||
| 636 | #endif | 589 | #endif |
| 637 | 590 | ||
| 638 | #ifdef _WIN32 | 591 | #ifdef _WIN32 |
| 639 | std::string& GetExeDirectory() | 592 | std::string& GetExeDirectory() { |
| 640 | { | ||
| 641 | static std::string exe_path; | 593 | static std::string exe_path; |
| 642 | if (exe_path.empty()) | 594 | if (exe_path.empty()) { |
| 643 | { | ||
| 644 | wchar_t wchar_exe_path[2048]; | 595 | wchar_t wchar_exe_path[2048]; |
| 645 | GetModuleFileNameW(nullptr, wchar_exe_path, 2048); | 596 | GetModuleFileNameW(nullptr, wchar_exe_path, 2048); |
| 646 | exe_path = Common::UTF16ToUTF8(wchar_exe_path); | 597 | exe_path = Common::UTF16ToUTF8(wchar_exe_path); |
| @@ -660,7 +611,8 @@ static const std::string& GetHomeDirectory() { | |||
| 660 | home_path = envvar; | 611 | home_path = envvar; |
| 661 | } else { | 612 | } else { |
| 662 | auto pw = getpwuid(getuid()); | 613 | auto pw = getpwuid(getuid()); |
| 663 | ASSERT_MSG(pw, "$HOME isn’t defined, and the current user can’t be found in /etc/passwd."); | 614 | ASSERT_MSG(pw, |
| 615 | "$HOME isn’t defined, and the current user can’t be found in /etc/passwd."); | ||
| 664 | home_path = pw->pw_dir; | 616 | home_path = pw->pw_dir; |
| 665 | } | 617 | } |
| 666 | } | 618 | } |
| @@ -699,11 +651,10 @@ static const std::string GetUserDirectory(const std::string& envvar) { | |||
| 699 | } | 651 | } |
| 700 | #endif | 652 | #endif |
| 701 | 653 | ||
| 702 | std::string GetSysDirectory() | 654 | std::string GetSysDirectory() { |
| 703 | { | ||
| 704 | std::string sysDir; | 655 | std::string sysDir; |
| 705 | 656 | ||
| 706 | #if defined (__APPLE__) | 657 | #if defined(__APPLE__) |
| 707 | sysDir = GetBundleDirectory(); | 658 | sysDir = GetBundleDirectory(); |
| 708 | sysDir += DIR_SEP; | 659 | sysDir += DIR_SEP; |
| 709 | sysDir += SYSDATA_DIR; | 660 | sysDir += SYSDATA_DIR; |
| @@ -718,123 +669,114 @@ std::string GetSysDirectory() | |||
| 718 | 669 | ||
| 719 | // Returns a string with a Citra data dir or file in the user's home | 670 | // Returns a string with a Citra data dir or file in the user's home |
| 720 | // directory. To be used in "multi-user" mode (that is, installed). | 671 | // directory. To be used in "multi-user" mode (that is, installed). |
| 721 | const std::string& GetUserPath(const unsigned int DirIDX, const std::string &newPath) | 672 | const std::string& GetUserPath(const unsigned int DirIDX, const std::string& newPath) { |
| 722 | { | ||
| 723 | static std::string paths[NUM_PATH_INDICES]; | 673 | static std::string paths[NUM_PATH_INDICES]; |
| 724 | 674 | ||
| 725 | // Set up all paths and files on the first run | 675 | // Set up all paths and files on the first run |
| 726 | if (paths[D_USER_IDX].empty()) | 676 | if (paths[D_USER_IDX].empty()) { |
| 727 | { | ||
| 728 | #ifdef _WIN32 | 677 | #ifdef _WIN32 |
| 729 | paths[D_USER_IDX] = GetExeDirectory() + DIR_SEP USERDATA_DIR DIR_SEP; | 678 | paths[D_USER_IDX] = GetExeDirectory() + DIR_SEP USERDATA_DIR DIR_SEP; |
| 730 | paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; | 679 | paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; |
| 731 | paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; | 680 | paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; |
| 732 | #else | 681 | #else |
| 733 | if (FileUtil::Exists(ROOT_DIR DIR_SEP USERDATA_DIR)) { | 682 | if (FileUtil::Exists(ROOT_DIR DIR_SEP USERDATA_DIR)) { |
| 734 | paths[D_USER_IDX] = ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP; | 683 | paths[D_USER_IDX] = ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP; |
| 735 | paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; | 684 | paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; |
| 736 | paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; | 685 | paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; |
| 737 | } else { | 686 | } else { |
| 738 | std::string data_dir = GetUserDirectory("XDG_DATA_HOME"); | 687 | std::string data_dir = GetUserDirectory("XDG_DATA_HOME"); |
| 739 | std::string config_dir = GetUserDirectory("XDG_CONFIG_HOME"); | 688 | std::string config_dir = GetUserDirectory("XDG_CONFIG_HOME"); |
| 740 | std::string cache_dir = GetUserDirectory("XDG_CACHE_HOME"); | 689 | std::string cache_dir = GetUserDirectory("XDG_CACHE_HOME"); |
| 741 | 690 | ||
| 742 | paths[D_USER_IDX] = data_dir + DIR_SEP EMU_DATA_DIR DIR_SEP; | 691 | paths[D_USER_IDX] = data_dir + DIR_SEP EMU_DATA_DIR DIR_SEP; |
| 743 | paths[D_CONFIG_IDX] = config_dir + DIR_SEP EMU_DATA_DIR DIR_SEP; | 692 | paths[D_CONFIG_IDX] = config_dir + DIR_SEP EMU_DATA_DIR DIR_SEP; |
| 744 | paths[D_CACHE_IDX] = cache_dir + DIR_SEP EMU_DATA_DIR DIR_SEP; | 693 | paths[D_CACHE_IDX] = cache_dir + DIR_SEP EMU_DATA_DIR DIR_SEP; |
| 745 | } | 694 | } |
| 746 | #endif | 695 | #endif |
| 747 | 696 | ||
| 748 | paths[D_GAMECONFIG_IDX] = paths[D_USER_IDX] + GAMECONFIG_DIR DIR_SEP; | 697 | paths[D_GAMECONFIG_IDX] = paths[D_USER_IDX] + GAMECONFIG_DIR DIR_SEP; |
| 749 | paths[D_MAPS_IDX] = paths[D_USER_IDX] + MAPS_DIR DIR_SEP; | 698 | paths[D_MAPS_IDX] = paths[D_USER_IDX] + MAPS_DIR DIR_SEP; |
| 750 | paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; | 699 | paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; |
| 751 | paths[D_NAND_IDX] = paths[D_USER_IDX] + NAND_DIR DIR_SEP; | 700 | paths[D_NAND_IDX] = paths[D_USER_IDX] + NAND_DIR DIR_SEP; |
| 752 | paths[D_SYSDATA_IDX] = paths[D_USER_IDX] + SYSDATA_DIR DIR_SEP; | 701 | paths[D_SYSDATA_IDX] = paths[D_USER_IDX] + SYSDATA_DIR DIR_SEP; |
| 753 | paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP; | 702 | paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP; |
| 754 | paths[D_SHADERS_IDX] = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP; | 703 | paths[D_SHADERS_IDX] = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP; |
| 755 | paths[D_STATESAVES_IDX] = paths[D_USER_IDX] + STATESAVES_DIR DIR_SEP; | 704 | paths[D_STATESAVES_IDX] = paths[D_USER_IDX] + STATESAVES_DIR DIR_SEP; |
| 756 | paths[D_SCREENSHOTS_IDX] = paths[D_USER_IDX] + SCREENSHOTS_DIR DIR_SEP; | 705 | paths[D_SCREENSHOTS_IDX] = paths[D_USER_IDX] + SCREENSHOTS_DIR DIR_SEP; |
| 757 | paths[D_DUMP_IDX] = paths[D_USER_IDX] + DUMP_DIR DIR_SEP; | 706 | paths[D_DUMP_IDX] = paths[D_USER_IDX] + DUMP_DIR DIR_SEP; |
| 758 | paths[D_DUMPFRAMES_IDX] = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP; | 707 | paths[D_DUMPFRAMES_IDX] = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP; |
| 759 | paths[D_DUMPAUDIO_IDX] = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP; | 708 | paths[D_DUMPAUDIO_IDX] = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP; |
| 760 | paths[D_DUMPTEXTURES_IDX] = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP; | 709 | paths[D_DUMPTEXTURES_IDX] = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP; |
| 761 | paths[D_LOGS_IDX] = paths[D_USER_IDX] + LOGS_DIR DIR_SEP; | 710 | paths[D_LOGS_IDX] = paths[D_USER_IDX] + LOGS_DIR DIR_SEP; |
| 762 | paths[F_DEBUGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + DEBUGGER_CONFIG; | 711 | paths[F_DEBUGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + DEBUGGER_CONFIG; |
| 763 | paths[F_LOGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + LOGGER_CONFIG; | 712 | paths[F_LOGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + LOGGER_CONFIG; |
| 764 | paths[F_MAINLOG_IDX] = paths[D_LOGS_IDX] + MAIN_LOG; | 713 | paths[F_MAINLOG_IDX] = paths[D_LOGS_IDX] + MAIN_LOG; |
| 765 | } | 714 | } |
| 766 | 715 | ||
| 767 | if (!newPath.empty()) | 716 | if (!newPath.empty()) { |
| 768 | { | 717 | if (!FileUtil::IsDirectory(newPath)) { |
| 769 | if (!FileUtil::IsDirectory(newPath)) | ||
| 770 | { | ||
| 771 | LOG_ERROR(Common_Filesystem, "Invalid path specified %s", newPath.c_str()); | 718 | LOG_ERROR(Common_Filesystem, "Invalid path specified %s", newPath.c_str()); |
| 772 | return paths[DirIDX]; | 719 | return paths[DirIDX]; |
| 773 | } | 720 | } else { |
| 774 | else | ||
| 775 | { | ||
| 776 | paths[DirIDX] = newPath; | 721 | paths[DirIDX] = newPath; |
| 777 | } | 722 | } |
| 778 | 723 | ||
| 779 | switch (DirIDX) | 724 | switch (DirIDX) { |
| 780 | { | ||
| 781 | case D_ROOT_IDX: | 725 | case D_ROOT_IDX: |
| 782 | paths[D_USER_IDX] = paths[D_ROOT_IDX] + DIR_SEP; | 726 | paths[D_USER_IDX] = paths[D_ROOT_IDX] + DIR_SEP; |
| 783 | paths[D_SYSCONF_IDX] = paths[D_USER_IDX] + SYSCONF_DIR + DIR_SEP; | 727 | paths[D_SYSCONF_IDX] = paths[D_USER_IDX] + SYSCONF_DIR + DIR_SEP; |
| 784 | paths[F_SYSCONF_IDX] = paths[D_SYSCONF_IDX] + SYSCONF; | 728 | paths[F_SYSCONF_IDX] = paths[D_SYSCONF_IDX] + SYSCONF; |
| 785 | break; | 729 | break; |
| 786 | 730 | ||
| 787 | case D_USER_IDX: | 731 | case D_USER_IDX: |
| 788 | paths[D_USER_IDX] = paths[D_ROOT_IDX] + DIR_SEP; | 732 | paths[D_USER_IDX] = paths[D_ROOT_IDX] + DIR_SEP; |
| 789 | paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; | 733 | paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; |
| 790 | paths[D_GAMECONFIG_IDX] = paths[D_USER_IDX] + GAMECONFIG_DIR DIR_SEP; | 734 | paths[D_GAMECONFIG_IDX] = paths[D_USER_IDX] + GAMECONFIG_DIR DIR_SEP; |
| 791 | paths[D_MAPS_IDX] = paths[D_USER_IDX] + MAPS_DIR DIR_SEP; | 735 | paths[D_MAPS_IDX] = paths[D_USER_IDX] + MAPS_DIR DIR_SEP; |
| 792 | paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; | 736 | paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; |
| 793 | paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; | 737 | paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; |
| 794 | paths[D_NAND_IDX] = paths[D_USER_IDX] + NAND_DIR DIR_SEP; | 738 | paths[D_NAND_IDX] = paths[D_USER_IDX] + NAND_DIR DIR_SEP; |
| 795 | paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP; | 739 | paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP; |
| 796 | paths[D_SHADERS_IDX] = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP; | 740 | paths[D_SHADERS_IDX] = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP; |
| 797 | paths[D_STATESAVES_IDX] = paths[D_USER_IDX] + STATESAVES_DIR DIR_SEP; | 741 | paths[D_STATESAVES_IDX] = paths[D_USER_IDX] + STATESAVES_DIR DIR_SEP; |
| 798 | paths[D_SCREENSHOTS_IDX] = paths[D_USER_IDX] + SCREENSHOTS_DIR DIR_SEP; | 742 | paths[D_SCREENSHOTS_IDX] = paths[D_USER_IDX] + SCREENSHOTS_DIR DIR_SEP; |
| 799 | paths[D_DUMP_IDX] = paths[D_USER_IDX] + DUMP_DIR DIR_SEP; | 743 | paths[D_DUMP_IDX] = paths[D_USER_IDX] + DUMP_DIR DIR_SEP; |
| 800 | paths[D_DUMPFRAMES_IDX] = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP; | 744 | paths[D_DUMPFRAMES_IDX] = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP; |
| 801 | paths[D_DUMPAUDIO_IDX] = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP; | 745 | paths[D_DUMPAUDIO_IDX] = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP; |
| 802 | paths[D_DUMPTEXTURES_IDX] = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP; | 746 | paths[D_DUMPTEXTURES_IDX] = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP; |
| 803 | paths[D_LOGS_IDX] = paths[D_USER_IDX] + LOGS_DIR DIR_SEP; | 747 | paths[D_LOGS_IDX] = paths[D_USER_IDX] + LOGS_DIR DIR_SEP; |
| 804 | paths[D_SYSCONF_IDX] = paths[D_USER_IDX] + SYSCONF_DIR DIR_SEP; | 748 | paths[D_SYSCONF_IDX] = paths[D_USER_IDX] + SYSCONF_DIR DIR_SEP; |
| 805 | paths[F_EMUCONFIG_IDX] = paths[D_CONFIG_IDX] + EMU_CONFIG; | 749 | paths[F_EMUCONFIG_IDX] = paths[D_CONFIG_IDX] + EMU_CONFIG; |
| 806 | paths[F_DEBUGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + DEBUGGER_CONFIG; | 750 | paths[F_DEBUGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + DEBUGGER_CONFIG; |
| 807 | paths[F_LOGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + LOGGER_CONFIG; | 751 | paths[F_LOGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + LOGGER_CONFIG; |
| 808 | paths[F_MAINLOG_IDX] = paths[D_LOGS_IDX] + MAIN_LOG; | 752 | paths[F_MAINLOG_IDX] = paths[D_LOGS_IDX] + MAIN_LOG; |
| 809 | break; | 753 | break; |
| 810 | 754 | ||
| 811 | case D_CONFIG_IDX: | 755 | case D_CONFIG_IDX: |
| 812 | paths[F_EMUCONFIG_IDX] = paths[D_CONFIG_IDX] + EMU_CONFIG; | 756 | paths[F_EMUCONFIG_IDX] = paths[D_CONFIG_IDX] + EMU_CONFIG; |
| 813 | paths[F_DEBUGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + DEBUGGER_CONFIG; | 757 | paths[F_DEBUGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + DEBUGGER_CONFIG; |
| 814 | paths[F_LOGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + LOGGER_CONFIG; | 758 | paths[F_LOGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + LOGGER_CONFIG; |
| 815 | break; | 759 | break; |
| 816 | 760 | ||
| 817 | case D_DUMP_IDX: | 761 | case D_DUMP_IDX: |
| 818 | paths[D_DUMPFRAMES_IDX] = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP; | 762 | paths[D_DUMPFRAMES_IDX] = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP; |
| 819 | paths[D_DUMPAUDIO_IDX] = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP; | 763 | paths[D_DUMPAUDIO_IDX] = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP; |
| 820 | paths[D_DUMPTEXTURES_IDX] = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP; | 764 | paths[D_DUMPTEXTURES_IDX] = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP; |
| 821 | break; | 765 | break; |
| 822 | 766 | ||
| 823 | case D_LOGS_IDX: | 767 | case D_LOGS_IDX: |
| 824 | paths[F_MAINLOG_IDX] = paths[D_LOGS_IDX] + MAIN_LOG; | 768 | paths[F_MAINLOG_IDX] = paths[D_LOGS_IDX] + MAIN_LOG; |
| 825 | } | 769 | } |
| 826 | } | 770 | } |
| 827 | 771 | ||
| 828 | return paths[DirIDX]; | 772 | return paths[DirIDX]; |
| 829 | } | 773 | } |
| 830 | 774 | ||
| 831 | size_t WriteStringToFile(bool text_file, const std::string &str, const char *filename) | 775 | size_t WriteStringToFile(bool text_file, const std::string& str, const char* filename) { |
| 832 | { | ||
| 833 | return FileUtil::IOFile(filename, text_file ? "w" : "wb").WriteBytes(str.data(), str.size()); | 776 | return FileUtil::IOFile(filename, text_file ? "w" : "wb").WriteBytes(str.data(), str.size()); |
| 834 | } | 777 | } |
| 835 | 778 | ||
| 836 | size_t ReadFileToString(bool text_file, const char *filename, std::string &str) | 779 | size_t ReadFileToString(bool text_file, const char* filename, std::string& str) { |
| 837 | { | ||
| 838 | IOFile file(filename, text_file ? "r" : "rb"); | 780 | IOFile file(filename, text_file ? "r" : "rb"); |
| 839 | 781 | ||
| 840 | if (!file) | 782 | if (!file) |
| @@ -886,42 +828,36 @@ void SplitFilename83(const std::string& filename, std::array<char, 9>& short_nam | |||
| 886 | } | 828 | } |
| 887 | } | 829 | } |
| 888 | 830 | ||
| 889 | IOFile::IOFile() | 831 | IOFile::IOFile() { |
| 890 | { | ||
| 891 | } | 832 | } |
| 892 | 833 | ||
| 893 | IOFile::IOFile(const std::string& filename, const char openmode[]) | 834 | IOFile::IOFile(const std::string& filename, const char openmode[]) { |
| 894 | { | ||
| 895 | Open(filename, openmode); | 835 | Open(filename, openmode); |
| 896 | } | 836 | } |
| 897 | 837 | ||
| 898 | IOFile::~IOFile() | 838 | IOFile::~IOFile() { |
| 899 | { | ||
| 900 | Close(); | 839 | Close(); |
| 901 | } | 840 | } |
| 902 | 841 | ||
| 903 | IOFile::IOFile(IOFile&& other) | 842 | IOFile::IOFile(IOFile&& other) { |
| 904 | { | ||
| 905 | Swap(other); | 843 | Swap(other); |
| 906 | } | 844 | } |
| 907 | 845 | ||
| 908 | IOFile& IOFile::operator=(IOFile&& other) | 846 | IOFile& IOFile::operator=(IOFile&& other) { |
| 909 | { | ||
| 910 | Swap(other); | 847 | Swap(other); |
| 911 | return *this; | 848 | return *this; |
| 912 | } | 849 | } |
| 913 | 850 | ||
| 914 | void IOFile::Swap(IOFile& other) | 851 | void IOFile::Swap(IOFile& other) { |
| 915 | { | ||
| 916 | std::swap(m_file, other.m_file); | 852 | std::swap(m_file, other.m_file); |
| 917 | std::swap(m_good, other.m_good); | 853 | std::swap(m_good, other.m_good); |
| 918 | } | 854 | } |
| 919 | 855 | ||
| 920 | bool IOFile::Open(const std::string& filename, const char openmode[]) | 856 | bool IOFile::Open(const std::string& filename, const char openmode[]) { |
| 921 | { | ||
| 922 | Close(); | 857 | Close(); |
| 923 | #ifdef _WIN32 | 858 | #ifdef _WIN32 |
| 924 | _wfopen_s(&m_file, Common::UTF8ToUTF16W(filename).c_str(), Common::UTF8ToUTF16W(openmode).c_str()); | 859 | _wfopen_s(&m_file, Common::UTF8ToUTF16W(filename).c_str(), |
| 860 | Common::UTF8ToUTF16W(openmode).c_str()); | ||
| 925 | #else | 861 | #else |
| 926 | m_file = fopen(filename.c_str(), openmode); | 862 | m_file = fopen(filename.c_str(), openmode); |
| 927 | #endif | 863 | #endif |
| @@ -930,8 +866,7 @@ bool IOFile::Open(const std::string& filename, const char openmode[]) | |||
| 930 | return m_good; | 866 | return m_good; |
| 931 | } | 867 | } |
| 932 | 868 | ||
| 933 | bool IOFile::Close() | 869 | bool IOFile::Close() { |
| 934 | { | ||
| 935 | if (!IsOpen() || 0 != std::fclose(m_file)) | 870 | if (!IsOpen() || 0 != std::fclose(m_file)) |
| 936 | m_good = false; | 871 | m_good = false; |
| 937 | 872 | ||
| @@ -939,50 +874,46 @@ bool IOFile::Close() | |||
| 939 | return m_good; | 874 | return m_good; |
| 940 | } | 875 | } |
| 941 | 876 | ||
| 942 | u64 IOFile::GetSize() const | 877 | u64 IOFile::GetSize() const { |
| 943 | { | ||
| 944 | if (IsOpen()) | 878 | if (IsOpen()) |
| 945 | return FileUtil::GetSize(m_file); | 879 | return FileUtil::GetSize(m_file); |
| 946 | 880 | ||
| 947 | return 0; | 881 | return 0; |
| 948 | } | 882 | } |
| 949 | 883 | ||
| 950 | bool IOFile::Seek(s64 off, int origin) | 884 | bool IOFile::Seek(s64 off, int origin) { |
| 951 | { | ||
| 952 | if (!IsOpen() || 0 != fseeko(m_file, off, origin)) | 885 | if (!IsOpen() || 0 != fseeko(m_file, off, origin)) |
| 953 | m_good = false; | 886 | m_good = false; |
| 954 | 887 | ||
| 955 | return m_good; | 888 | return m_good; |
| 956 | } | 889 | } |
| 957 | 890 | ||
| 958 | u64 IOFile::Tell() const | 891 | u64 IOFile::Tell() const { |
| 959 | { | ||
| 960 | if (IsOpen()) | 892 | if (IsOpen()) |
| 961 | return ftello(m_file); | 893 | return ftello(m_file); |
| 962 | 894 | ||
| 963 | return -1; | 895 | return -1; |
| 964 | } | 896 | } |
| 965 | 897 | ||
| 966 | bool IOFile::Flush() | 898 | bool IOFile::Flush() { |
| 967 | { | ||
| 968 | if (!IsOpen() || 0 != std::fflush(m_file)) | 899 | if (!IsOpen() || 0 != std::fflush(m_file)) |
| 969 | m_good = false; | 900 | m_good = false; |
| 970 | 901 | ||
| 971 | return m_good; | 902 | return m_good; |
| 972 | } | 903 | } |
| 973 | 904 | ||
| 974 | bool IOFile::Resize(u64 size) | 905 | bool IOFile::Resize(u64 size) { |
| 975 | { | 906 | if (!IsOpen() || |
| 976 | if (!IsOpen() || 0 != | 907 | 0 != |
| 977 | #ifdef _WIN32 | 908 | #ifdef _WIN32 |
| 978 | // ector: _chsize sucks, not 64-bit safe | 909 | // ector: _chsize sucks, not 64-bit safe |
| 979 | // F|RES: changed to _chsize_s. i think it is 64-bit safe | 910 | // F|RES: changed to _chsize_s. i think it is 64-bit safe |
| 980 | _chsize_s(_fileno(m_file), size) | 911 | _chsize_s(_fileno(m_file), size) |
| 981 | #else | 912 | #else |
| 982 | // TODO: handle 64bit and growing | 913 | // TODO: handle 64bit and growing |
| 983 | ftruncate(fileno(m_file), size) | 914 | ftruncate(fileno(m_file), size) |
| 984 | #endif | 915 | #endif |
| 985 | ) | 916 | ) |
| 986 | m_good = false; | 917 | m_good = false; |
| 987 | 918 | ||
| 988 | return m_good; | 919 | return m_good; |