summaryrefslogtreecommitdiff
path: root/src/common/file_util.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/file_util.cpp')
-rw-r--r--src/common/file_util.cpp194
1 files changed, 117 insertions, 77 deletions
diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp
index b6ff2e40b..35da07306 100644
--- a/src/common/file_util.cpp
+++ b/src/common/file_util.cpp
@@ -4,9 +4,7 @@
4 4
5 5
6#include "common/common.h" 6#include "common/common.h"
7#include "common/common_paths.h"
8#include "common/file_util.h" 7#include "common/file_util.h"
9#include "common/string_util.h"
10 8
11#ifdef _WIN32 9#ifdef _WIN32
12#include <windows.h> 10#include <windows.h>
@@ -15,11 +13,9 @@
15#include <commdlg.h> // for GetSaveFileName 13#include <commdlg.h> // for GetSaveFileName
16#include <io.h> 14#include <io.h>
17#include <direct.h> // getcwd 15#include <direct.h> // getcwd
16#include <tchar.h>
18#else 17#else
19#include <cerrno>
20#include <cstdlib>
21#include <sys/param.h> 18#include <sys/param.h>
22#include <sys/types.h>
23#include <dirent.h> 19#include <dirent.h>
24#endif 20#endif
25 21
@@ -32,8 +28,6 @@
32#include <algorithm> 28#include <algorithm>
33#include <sys/stat.h> 29#include <sys/stat.h>
34 30
35#include "common/string_util.h"
36
37#ifndef S_ISDIR 31#ifndef S_ISDIR
38#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) 32#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR)
39#endif 33#endif
@@ -46,7 +40,7 @@
46// This namespace has various generic functions related to files and paths. 40// This namespace has various generic functions related to files and paths.
47// The code still needs a ton of cleanup. 41// The code still needs a ton of cleanup.
48// REMEMBER: strdup considered harmful! 42// REMEMBER: strdup considered harmful!
49namespace File 43namespace FileUtil
50{ 44{
51 45
52// Remove any ending forward slashes from directory paths 46// Remove any ending forward slashes from directory paths
@@ -71,7 +65,7 @@ bool Exists(const std::string &filename)
71 StripTailDirSlashes(copy); 65 StripTailDirSlashes(copy);
72 66
73#ifdef _WIN32 67#ifdef _WIN32
74 int result = _tstat64(UTF8ToTStr(copy).c_str(), &file_info); 68 int result = _tstat64(Common::UTF8ToTStr(copy).c_str(), &file_info);
75#else 69#else
76 int result = stat64(copy.c_str(), &file_info); 70 int result = stat64(copy.c_str(), &file_info);
77#endif 71#endif
@@ -88,7 +82,7 @@ bool IsDirectory(const std::string &filename)
88 StripTailDirSlashes(copy); 82 StripTailDirSlashes(copy);
89 83
90#ifdef _WIN32 84#ifdef _WIN32
91 int result = _tstat64(UTF8ToTStr(copy).c_str(), &file_info); 85 int result = _tstat64(Common::UTF8ToTStr(copy).c_str(), &file_info);
92#else 86#else
93 int result = stat64(copy.c_str(), &file_info); 87 int result = stat64(copy.c_str(), &file_info);
94#endif 88#endif
@@ -124,7 +118,7 @@ bool Delete(const std::string &filename)
124 } 118 }
125 119
126#ifdef _WIN32 120#ifdef _WIN32
127 if (!DeleteFile(UTF8ToTStr(filename).c_str())) 121 if (!DeleteFile(Common::UTF8ToTStr(filename).c_str()))
128 { 122 {
129 WARN_LOG(COMMON, "Delete: DeleteFile failed on %s: %s", 123 WARN_LOG(COMMON, "Delete: DeleteFile failed on %s: %s",
130 filename.c_str(), GetLastErrorMsg()); 124 filename.c_str(), GetLastErrorMsg());
@@ -146,7 +140,7 @@ bool CreateDir(const std::string &path)
146{ 140{
147 INFO_LOG(COMMON, "CreateDir: directory %s", path.c_str()); 141 INFO_LOG(COMMON, "CreateDir: directory %s", path.c_str());
148#ifdef _WIN32 142#ifdef _WIN32
149 if (::CreateDirectory(UTF8ToTStr(path).c_str(), NULL)) 143 if (::CreateDirectory(Common::UTF8ToTStr(path).c_str(), NULL))
150 return true; 144 return true;
151 DWORD error = GetLastError(); 145 DWORD error = GetLastError();
152 if (error == ERROR_ALREADY_EXISTS) 146 if (error == ERROR_ALREADY_EXISTS)
@@ -179,7 +173,7 @@ bool CreateFullPath(const std::string &fullPath)
179 int panicCounter = 100; 173 int panicCounter = 100;
180 INFO_LOG(COMMON, "CreateFullPath: path %s", fullPath.c_str()); 174 INFO_LOG(COMMON, "CreateFullPath: path %s", fullPath.c_str());
181 175
182 if (File::Exists(fullPath)) 176 if (FileUtil::Exists(fullPath))
183 { 177 {
184 INFO_LOG(COMMON, "CreateFullPath: path exists %s", fullPath.c_str()); 178 INFO_LOG(COMMON, "CreateFullPath: path exists %s", fullPath.c_str());
185 return true; 179 return true;
@@ -197,8 +191,10 @@ bool CreateFullPath(const std::string &fullPath)
197 191
198 // Include the '/' so the first call is CreateDir("/") rather than CreateDir("") 192 // Include the '/' so the first call is CreateDir("/") rather than CreateDir("")
199 std::string const subPath(fullPath.substr(0, position + 1)); 193 std::string const subPath(fullPath.substr(0, position + 1));
200 if (!File::IsDirectory(subPath)) 194 if (!FileUtil::IsDirectory(subPath) && !FileUtil::CreateDir(subPath)) {
201 File::CreateDir(subPath); 195 ERROR_LOG(COMMON, "CreateFullPath: directory creation failed");
196 return false;
197 }
202 198
203 // A safety check 199 // A safety check
204 panicCounter--; 200 panicCounter--;
@@ -218,14 +214,14 @@ bool DeleteDir(const std::string &filename)
218 INFO_LOG(COMMON, "DeleteDir: directory %s", filename.c_str()); 214 INFO_LOG(COMMON, "DeleteDir: directory %s", filename.c_str());
219 215
220 // check if a directory 216 // check if a directory
221 if (!File::IsDirectory(filename)) 217 if (!FileUtil::IsDirectory(filename))
222 { 218 {
223 ERROR_LOG(COMMON, "DeleteDir: Not a directory %s", filename.c_str()); 219 ERROR_LOG(COMMON, "DeleteDir: Not a directory %s", filename.c_str());
224 return false; 220 return false;
225 } 221 }
226 222
227#ifdef _WIN32 223#ifdef _WIN32
228 if (::RemoveDirectory(UTF8ToTStr(filename).c_str())) 224 if (::RemoveDirectory(Common::UTF8ToTStr(filename).c_str()))
229 return true; 225 return true;
230#else 226#else
231 if (rmdir(filename.c_str()) == 0) 227 if (rmdir(filename.c_str()) == 0)
@@ -254,7 +250,7 @@ bool Copy(const std::string &srcFilename, const std::string &destFilename)
254 INFO_LOG(COMMON, "Copy: %s --> %s", 250 INFO_LOG(COMMON, "Copy: %s --> %s",
255 srcFilename.c_str(), destFilename.c_str()); 251 srcFilename.c_str(), destFilename.c_str());
256#ifdef _WIN32 252#ifdef _WIN32
257 if (CopyFile(UTF8ToTStr(srcFilename).c_str(), UTF8ToTStr(destFilename).c_str(), FALSE)) 253 if (CopyFile(Common::UTF8ToTStr(srcFilename).c_str(), Common::UTF8ToTStr(destFilename).c_str(), FALSE))
258 return true; 254 return true;
259 255
260 ERROR_LOG(COMMON, "Copy: failed %s --> %s: %s", 256 ERROR_LOG(COMMON, "Copy: failed %s --> %s: %s",
@@ -342,7 +338,7 @@ u64 GetSize(const std::string &filename)
342 338
343 struct stat64 buf; 339 struct stat64 buf;
344#ifdef _WIN32 340#ifdef _WIN32
345 if (_tstat64(UTF8ToTStr(filename).c_str(), &buf) == 0) 341 if (_tstat64(Common::UTF8ToTStr(filename).c_str(), &buf) == 0)
346#else 342#else
347 if (stat64(filename.c_str(), &buf) == 0) 343 if (stat64(filename.c_str(), &buf) == 0)
348#endif 344#endif
@@ -393,7 +389,7 @@ bool CreateEmptyFile(const std::string &filename)
393{ 389{
394 INFO_LOG(COMMON, "CreateEmptyFile: %s", filename.c_str()); 390 INFO_LOG(COMMON, "CreateEmptyFile: %s", filename.c_str());
395 391
396 if (!File::IOFile(filename, "wb")) 392 if (!FileUtil::IOFile(filename, "wb"))
397 { 393 {
398 ERROR_LOG(COMMON, "CreateEmptyFile: failed %s: %s", 394 ERROR_LOG(COMMON, "CreateEmptyFile: failed %s: %s",
399 filename.c_str(), GetLastErrorMsg()); 395 filename.c_str(), GetLastErrorMsg());
@@ -415,7 +411,7 @@ u32 ScanDirectoryTree(const std::string &directory, FSTEntry& parentEntry)
415 // Find the first file in the directory. 411 // Find the first file in the directory.
416 WIN32_FIND_DATA ffd; 412 WIN32_FIND_DATA ffd;
417 413
418 HANDLE hFind = FindFirstFile(UTF8ToTStr(directory + "\\*").c_str(), &ffd); 414 HANDLE hFind = FindFirstFile(Common::UTF8ToTStr(directory + "\\*").c_str(), &ffd);
419 if (hFind == INVALID_HANDLE_VALUE) 415 if (hFind == INVALID_HANDLE_VALUE)
420 { 416 {
421 FindClose(hFind); 417 FindClose(hFind);
@@ -425,7 +421,7 @@ u32 ScanDirectoryTree(const std::string &directory, FSTEntry& parentEntry)
425 do 421 do
426 { 422 {
427 FSTEntry entry; 423 FSTEntry entry;
428 const std::string virtualName(TStrToUTF8(ffd.cFileName)); 424 const std::string virtualName(Common::TStrToUTF8(ffd.cFileName));
429#else 425#else
430 struct dirent dirent, *result = NULL; 426 struct dirent dirent, *result = NULL;
431 427
@@ -482,7 +478,7 @@ bool DeleteDirRecursively(const std::string &directory)
482#ifdef _WIN32 478#ifdef _WIN32
483 // Find the first file in the directory. 479 // Find the first file in the directory.
484 WIN32_FIND_DATA ffd; 480 WIN32_FIND_DATA ffd;
485 HANDLE hFind = FindFirstFile(UTF8ToTStr(directory + "\\*").c_str(), &ffd); 481 HANDLE hFind = FindFirstFile(Common::UTF8ToTStr(directory + "\\*").c_str(), &ffd);
486 482
487 if (hFind == INVALID_HANDLE_VALUE) 483 if (hFind == INVALID_HANDLE_VALUE)
488 { 484 {
@@ -493,7 +489,7 @@ bool DeleteDirRecursively(const std::string &directory)
493 // windows loop 489 // windows loop
494 do 490 do
495 { 491 {
496 const std::string virtualName(TStrToUTF8(ffd.cFileName)); 492 const std::string virtualName(Common::TStrToUTF8(ffd.cFileName));
497#else 493#else
498 struct dirent dirent, *result = NULL; 494 struct dirent dirent, *result = NULL;
499 DIR *dirp = opendir(directory.c_str()); 495 DIR *dirp = opendir(directory.c_str());
@@ -526,7 +522,7 @@ bool DeleteDirRecursively(const std::string &directory)
526 } 522 }
527 else 523 else
528 { 524 {
529 if (!File::Delete(newPath)) 525 if (!FileUtil::Delete(newPath))
530 { 526 {
531 #ifndef _WIN32 527 #ifndef _WIN32
532 closedir(dirp); 528 closedir(dirp);
@@ -543,7 +539,7 @@ bool DeleteDirRecursively(const std::string &directory)
543 } 539 }
544 closedir(dirp); 540 closedir(dirp);
545#endif 541#endif
546 File::DeleteDir(directory); 542 FileUtil::DeleteDir(directory);
547 543
548 return true; 544 return true;
549} 545}
@@ -553,8 +549,8 @@ void CopyDir(const std::string &source_path, const std::string &dest_path)
553{ 549{
554#ifndef _WIN32 550#ifndef _WIN32
555 if (source_path == dest_path) return; 551 if (source_path == dest_path) return;
556 if (!File::Exists(source_path)) return; 552 if (!FileUtil::Exists(source_path)) return;
557 if (!File::Exists(dest_path)) File::CreateFullPath(dest_path); 553 if (!FileUtil::Exists(dest_path)) FileUtil::CreateFullPath(dest_path);
558 554
559 struct dirent dirent, *result = NULL; 555 struct dirent dirent, *result = NULL;
560 DIR *dirp = opendir(source_path.c_str()); 556 DIR *dirp = opendir(source_path.c_str());
@@ -576,10 +572,10 @@ void CopyDir(const std::string &source_path, const std::string &dest_path)
576 { 572 {
577 source += '/'; 573 source += '/';
578 dest += '/'; 574 dest += '/';
579 if (!File::Exists(dest)) File::CreateFullPath(dest); 575 if (!FileUtil::Exists(dest)) FileUtil::CreateFullPath(dest);
580 CopyDir(source, dest); 576 CopyDir(source, dest);
581 } 577 }
582 else if (!File::Exists(dest)) File::Copy(source, dest); 578 else if (!FileUtil::Exists(dest)) FileUtil::Copy(source, dest);
583 } 579 }
584 closedir(dirp); 580 closedir(dirp);
585#endif 581#endif
@@ -631,7 +627,7 @@ std::string& GetExeDirectory()
631 { 627 {
632 TCHAR Dolphin_exe_Path[2048]; 628 TCHAR Dolphin_exe_Path[2048];
633 GetModuleFileName(NULL, Dolphin_exe_Path, 2048); 629 GetModuleFileName(NULL, Dolphin_exe_Path, 2048);
634 DolphinPath = TStrToUTF8(Dolphin_exe_Path); 630 DolphinPath = Common::TStrToUTF8(Dolphin_exe_Path);
635 DolphinPath = DolphinPath.substr(0, DolphinPath.find_last_of('\\')); 631 DolphinPath = DolphinPath.substr(0, DolphinPath.find_last_of('\\'));
636 } 632 }
637 return DolphinPath; 633 return DolphinPath;
@@ -655,7 +651,7 @@ std::string GetSysDirectory()
655 return sysDir; 651 return sysDir;
656} 652}
657 653
658// Returns a string with a Dolphin data dir or file in the user's home 654// Returns a string with a Citra data dir or file in the user's home
659// directory. To be used in "multi-user" mode (that is, installed). 655// directory. To be used in "multi-user" mode (that is, installed).
660const std::string& GetUserPath(const unsigned int DirIDX, const std::string &newPath) 656const std::string& GetUserPath(const unsigned int DirIDX, const std::string &newPath)
661{ 657{
@@ -667,7 +663,7 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string &new
667#ifdef _WIN32 663#ifdef _WIN32
668 paths[D_USER_IDX] = GetExeDirectory() + DIR_SEP USERDATA_DIR DIR_SEP; 664 paths[D_USER_IDX] = GetExeDirectory() + DIR_SEP USERDATA_DIR DIR_SEP;
669#else 665#else
670 if (File::Exists(ROOT_DIR DIR_SEP USERDATA_DIR)) 666 if (FileUtil::Exists(ROOT_DIR DIR_SEP USERDATA_DIR))
671 paths[D_USER_IDX] = ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP; 667 paths[D_USER_IDX] = ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP;
672 else 668 else
673 paths[D_USER_IDX] = std::string(getenv("HOME") ? 669 paths[D_USER_IDX] = std::string(getenv("HOME") ?
@@ -675,27 +671,28 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string &new
675 getenv("PWD") : "") + DIR_SEP EMU_DATA_DIR DIR_SEP; 671 getenv("PWD") : "") + DIR_SEP EMU_DATA_DIR DIR_SEP;
676#endif 672#endif
677 673
678 paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; 674 paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP;
679 paths[D_GAMECONFIG_IDX] = paths[D_USER_IDX] + GAMECONFIG_DIR DIR_SEP; 675 paths[D_GAMECONFIG_IDX] = paths[D_USER_IDX] + GAMECONFIG_DIR DIR_SEP;
680 paths[D_MAPS_IDX] = paths[D_USER_IDX] + MAPS_DIR DIR_SEP; 676 paths[D_MAPS_IDX] = paths[D_USER_IDX] + MAPS_DIR DIR_SEP;
681 paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; 677 paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP;
678 paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP;
682 paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP; 679 paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP;
683 paths[D_SHADERS_IDX] = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP; 680 paths[D_SHADERS_IDX] = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP;
684 paths[D_STATESAVES_IDX] = paths[D_USER_IDX] + STATESAVES_DIR DIR_SEP; 681 paths[D_STATESAVES_IDX] = paths[D_USER_IDX] + STATESAVES_DIR DIR_SEP;
685 paths[D_SCREENSHOTS_IDX] = paths[D_USER_IDX] + SCREENSHOTS_DIR DIR_SEP; 682 paths[D_SCREENSHOTS_IDX] = paths[D_USER_IDX] + SCREENSHOTS_DIR DIR_SEP;
686 paths[D_DUMP_IDX] = paths[D_USER_IDX] + DUMP_DIR DIR_SEP; 683 paths[D_DUMP_IDX] = paths[D_USER_IDX] + DUMP_DIR DIR_SEP;
687 paths[D_DUMPFRAMES_IDX] = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP; 684 paths[D_DUMPFRAMES_IDX] = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP;
688 paths[D_DUMPAUDIO_IDX] = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP; 685 paths[D_DUMPAUDIO_IDX] = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP;
689 paths[D_DUMPTEXTURES_IDX] = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP; 686 paths[D_DUMPTEXTURES_IDX] = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP;
690 paths[D_LOGS_IDX] = paths[D_USER_IDX] + LOGS_DIR DIR_SEP; 687 paths[D_LOGS_IDX] = paths[D_USER_IDX] + LOGS_DIR DIR_SEP;
691 paths[F_DEBUGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + DEBUGGER_CONFIG; 688 paths[F_DEBUGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + DEBUGGER_CONFIG;
692 paths[F_LOGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + LOGGER_CONFIG; 689 paths[F_LOGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + LOGGER_CONFIG;
693 paths[F_MAINLOG_IDX] = paths[D_LOGS_IDX] + MAIN_LOG; 690 paths[F_MAINLOG_IDX] = paths[D_LOGS_IDX] + MAIN_LOG;
694 } 691 }
695 692
696 if (!newPath.empty()) 693 if (!newPath.empty())
697 { 694 {
698 if (!File::IsDirectory(newPath)) 695 if (!FileUtil::IsDirectory(newPath))
699 { 696 {
700 WARN_LOG(COMMON, "Invalid path specified %s", newPath.c_str()); 697 WARN_LOG(COMMON, "Invalid path specified %s", newPath.c_str());
701 return paths[DirIDX]; 698 return paths[DirIDX];
@@ -708,43 +705,44 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string &new
708 switch (DirIDX) 705 switch (DirIDX)
709 { 706 {
710 case D_ROOT_IDX: 707 case D_ROOT_IDX:
711 paths[D_USER_IDX] = paths[D_ROOT_IDX] + DIR_SEP; 708 paths[D_USER_IDX] = paths[D_ROOT_IDX] + DIR_SEP;
712 paths[D_SYSCONF_IDX] = paths[D_USER_IDX] + SYSCONF_DIR + DIR_SEP; 709 paths[D_SYSCONF_IDX] = paths[D_USER_IDX] + SYSCONF_DIR + DIR_SEP;
713 paths[F_SYSCONF_IDX] = paths[D_SYSCONF_IDX] + SYSCONF; 710 paths[F_SYSCONF_IDX] = paths[D_SYSCONF_IDX] + SYSCONF;
714 break; 711 break;
715 712
716 case D_USER_IDX: 713 case D_USER_IDX:
717 paths[D_USER_IDX] = paths[D_ROOT_IDX] + DIR_SEP; 714 paths[D_USER_IDX] = paths[D_ROOT_IDX] + DIR_SEP;
718 paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; 715 paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP;
719 paths[D_GAMECONFIG_IDX] = paths[D_USER_IDX] + GAMECONFIG_DIR DIR_SEP; 716 paths[D_GAMECONFIG_IDX] = paths[D_USER_IDX] + GAMECONFIG_DIR DIR_SEP;
720 paths[D_MAPS_IDX] = paths[D_USER_IDX] + MAPS_DIR DIR_SEP; 717 paths[D_MAPS_IDX] = paths[D_USER_IDX] + MAPS_DIR DIR_SEP;
721 paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; 718 paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP;
719 paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP;
722 paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP; 720 paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP;
723 paths[D_SHADERS_IDX] = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP; 721 paths[D_SHADERS_IDX] = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP;
724 paths[D_STATESAVES_IDX] = paths[D_USER_IDX] + STATESAVES_DIR DIR_SEP; 722 paths[D_STATESAVES_IDX] = paths[D_USER_IDX] + STATESAVES_DIR DIR_SEP;
725 paths[D_SCREENSHOTS_IDX] = paths[D_USER_IDX] + SCREENSHOTS_DIR DIR_SEP; 723 paths[D_SCREENSHOTS_IDX] = paths[D_USER_IDX] + SCREENSHOTS_DIR DIR_SEP;
726 paths[D_DUMP_IDX] = paths[D_USER_IDX] + DUMP_DIR DIR_SEP; 724 paths[D_DUMP_IDX] = paths[D_USER_IDX] + DUMP_DIR DIR_SEP;
727 paths[D_DUMPFRAMES_IDX] = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP; 725 paths[D_DUMPFRAMES_IDX] = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP;
728 paths[D_DUMPAUDIO_IDX] = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP; 726 paths[D_DUMPAUDIO_IDX] = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP;
729 paths[D_DUMPTEXTURES_IDX] = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP; 727 paths[D_DUMPTEXTURES_IDX] = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP;
730 paths[D_LOGS_IDX] = paths[D_USER_IDX] + LOGS_DIR DIR_SEP; 728 paths[D_LOGS_IDX] = paths[D_USER_IDX] + LOGS_DIR DIR_SEP;
731 paths[D_SYSCONF_IDX] = paths[D_USER_IDX] + SYSCONF_DIR DIR_SEP; 729 paths[D_SYSCONF_IDX] = paths[D_USER_IDX] + SYSCONF_DIR DIR_SEP;
732 paths[F_EMUCONFIG_IDX] = paths[D_CONFIG_IDX] + EMU_CONFIG; 730 paths[F_EMUCONFIG_IDX] = paths[D_CONFIG_IDX] + EMU_CONFIG;
733 paths[F_DEBUGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + DEBUGGER_CONFIG; 731 paths[F_DEBUGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + DEBUGGER_CONFIG;
734 paths[F_LOGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + LOGGER_CONFIG; 732 paths[F_LOGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + LOGGER_CONFIG;
735 paths[F_MAINLOG_IDX] = paths[D_LOGS_IDX] + MAIN_LOG; 733 paths[F_MAINLOG_IDX] = paths[D_LOGS_IDX] + MAIN_LOG;
736 break; 734 break;
737 735
738 case D_CONFIG_IDX: 736 case D_CONFIG_IDX:
739 paths[F_EMUCONFIG_IDX] = paths[D_CONFIG_IDX] + EMU_CONFIG; 737 paths[F_EMUCONFIG_IDX] = paths[D_CONFIG_IDX] + EMU_CONFIG;
740 paths[F_DEBUGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + DEBUGGER_CONFIG; 738 paths[F_DEBUGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + DEBUGGER_CONFIG;
741 paths[F_LOGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + LOGGER_CONFIG; 739 paths[F_LOGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + LOGGER_CONFIG;
742 break; 740 break;
743 741
744 case D_DUMP_IDX: 742 case D_DUMP_IDX:
745 paths[D_DUMPFRAMES_IDX] = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP; 743 paths[D_DUMPFRAMES_IDX] = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP;
746 paths[D_DUMPAUDIO_IDX] = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP; 744 paths[D_DUMPAUDIO_IDX] = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP;
747 paths[D_DUMPTEXTURES_IDX] = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP; 745 paths[D_DUMPTEXTURES_IDX] = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP;
748 break; 746 break;
749 747
750 case D_LOGS_IDX: 748 case D_LOGS_IDX:
@@ -757,25 +755,25 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string &new
757 755
758//std::string GetThemeDir(const std::string& theme_name) 756//std::string GetThemeDir(const std::string& theme_name)
759//{ 757//{
760// std::string dir = File::GetUserPath(D_THEMES_IDX) + theme_name + "/"; 758// std::string dir = FileUtil::GetUserPath(D_THEMES_IDX) + theme_name + "/";
761// 759//
762//#if !defined(_WIN32) 760//#if !defined(_WIN32)
763// // If theme does not exist in user's dir load from shared directory 761// // If theme does not exist in user's dir load from shared directory
764// if (!File::Exists(dir)) 762// if (!FileUtil::Exists(dir))
765// dir = SHARED_USER_DIR THEMES_DIR "/" + theme_name + "/"; 763// dir = SHARED_USER_DIR THEMES_DIR "/" + theme_name + "/";
766//#endif 764//#endif
767// 765//
768// return dir; 766// return dir;
769//} 767//}
770 768
771bool WriteStringToFile(bool text_file, const std::string &str, const char *filename) 769size_t WriteStringToFile(bool text_file, const std::string &str, const char *filename)
772{ 770{
773 return File::IOFile(filename, text_file ? "w" : "wb").WriteBytes(str.data(), str.size()); 771 return FileUtil::IOFile(filename, text_file ? "w" : "wb").WriteBytes(str.data(), str.size());
774} 772}
775 773
776bool ReadFileToString(bool text_file, const char *filename, std::string &str) 774size_t ReadFileToString(bool text_file, const char *filename, std::string &str)
777{ 775{
778 File::IOFile file(filename, text_file ? "r" : "rb"); 776 FileUtil::IOFile file(filename, text_file ? "r" : "rb");
779 auto const f = file.GetHandle(); 777 auto const f = file.GetHandle();
780 778
781 if (!f) 779 if (!f)
@@ -785,6 +783,48 @@ bool ReadFileToString(bool text_file, const char *filename, std::string &str)
785 return file.ReadArray(&str[0], str.size()); 783 return file.ReadArray(&str[0], str.size());
786} 784}
787 785
786/**
787 * Splits the filename into 8.3 format
788 * Loosely implemented following https://en.wikipedia.org/wiki/8.3_filename
789 * @param filename The normal filename to use
790 * @param short_name A 9-char array in which the short name will be written
791 * @param extension A 4-char array in which the extension will be written
792 */
793void SplitFilename83(const std::string& filename, std::array<char, 9>& short_name,
794 std::array<char, 4>& extension) {
795 const std::string forbidden_characters = ".\"/\\[]:;=, ";
796
797 // On a FAT32 partition, 8.3 names are stored as a 11 bytes array, filled with spaces.
798 short_name = {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '\0'};
799 extension = {' ', ' ', ' ', '\0'};
800
801 std::string::size_type point = filename.rfind('.');
802 if (point == filename.size() - 1)
803 point = filename.rfind('.', point);
804
805 // Get short name.
806 int j = 0;
807 for (char letter : filename.substr(0, point)) {
808 if (forbidden_characters.find(letter, 0) != std::string::npos)
809 continue;
810 if (j == 8) {
811 // TODO(Link Mauve): also do that for filenames containing a space.
812 // TODO(Link Mauve): handle multiple files having the same short name.
813 short_name[6] = '~';
814 short_name[7] = '1';
815 break;
816 }
817 short_name[j++] = toupper(letter);
818 }
819
820 // Get extension.
821 if (point != std::string::npos) {
822 j = 0;
823 for (char letter : filename.substr(point + 1, 3))
824 extension[j++] = toupper(letter);
825 }
826}
827
788IOFile::IOFile() 828IOFile::IOFile()
789 : m_file(NULL), m_good(true) 829 : m_file(NULL), m_good(true)
790{} 830{}
@@ -826,7 +866,7 @@ bool IOFile::Open(const std::string& filename, const char openmode[])
826{ 866{
827 Close(); 867 Close();
828#ifdef _WIN32 868#ifdef _WIN32
829 _tfopen_s(&m_file, UTF8ToTStr(filename).c_str(), UTF8ToTStr(openmode).c_str()); 869 _tfopen_s(&m_file, Common::UTF8ToTStr(filename).c_str(), Common::UTF8ToTStr(openmode).c_str());
830#else 870#else
831 m_file = fopen(filename.c_str(), openmode); 871 m_file = fopen(filename.c_str(), openmode);
832#endif 872#endif
@@ -861,7 +901,7 @@ void IOFile::SetHandle(std::FILE* file)
861u64 IOFile::GetSize() 901u64 IOFile::GetSize()
862{ 902{
863 if (IsOpen()) 903 if (IsOpen())
864 return File::GetSize(m_file); 904 return FileUtil::GetSize(m_file);
865 else 905 else
866 return 0; 906 return 0;
867} 907}