summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar archshift2015-08-31 18:29:23 -0700
committerGravatar archshift2015-09-30 21:04:47 -0700
commit7134a17fc6cb7ab8ae46dae04f005bb72e0af88e (patch)
treea7276d2efdbeae8ea1fd84e81eca3bfa6a34e7df /src
parentExpose loader helper functions for identifying files. (diff)
downloadyuzu-7134a17fc6cb7ab8ae46dae04f005bb72e0af88e.tar.gz
yuzu-7134a17fc6cb7ab8ae46dae04f005bb72e0af88e.tar.xz
yuzu-7134a17fc6cb7ab8ae46dae04f005bb72e0af88e.zip
Split up FileUtil::ScanDirectoryTree to be able to use callbacks for custom behavior
Converted FileUtil::ScanDirectoryTree and FileUtil::DeleteDirRecursively to use the new ScanDirectoryTreeAndCallback function internally.
Diffstat (limited to 'src')
-rw-r--r--src/common/file_util.cpp160
-rw-r--r--src/common/file_util.h26
2 files changed, 83 insertions, 103 deletions
diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp
index 836b58d52..2fbb0f260 100644
--- a/src/common/file_util.cpp
+++ b/src/common/file_util.cpp
@@ -420,28 +420,23 @@ bool CreateEmptyFile(const std::string &filename)
420} 420}
421 421
422 422
423// Scans the directory tree gets, starting from _Directory and adds the 423int ScanDirectoryTreeAndCallback(const std::string &directory, std::function<int(const std::string&, const std::string&)> callback)
424// results into parentEntry. Returns the number of files+directories found
425u32 ScanDirectoryTree(const std::string &directory, FSTEntry& parentEntry)
426{ 424{
427 LOG_TRACE(Common_Filesystem, "directory %s", directory.c_str()); 425 LOG_TRACE(Common_Filesystem, "directory %s", directory.c_str());
428 // How many files + directories we found 426 // How many files + directories we found
429 u32 foundEntries = 0; 427 int found_entries = 0;
430#ifdef _WIN32 428#ifdef _WIN32
431 // Find the first file in the directory. 429 // Find the first file in the directory.
432 WIN32_FIND_DATA ffd; 430 WIN32_FIND_DATA ffd;
433 431
434 HANDLE hFind = FindFirstFile(Common::UTF8ToTStr(directory + "\\*").c_str(), &ffd); 432 HANDLE handle_find = FindFirstFile(Common::UTF8ToTStr(directory + "\\*").c_str(), &ffd);
435 if (hFind == INVALID_HANDLE_VALUE) 433 if (handle_find == INVALID_HANDLE_VALUE) {
436 { 434 FindClose(handle_find);
437 FindClose(hFind); 435 return found_entries;
438 return foundEntries;
439 } 436 }
440 // windows loop 437 // windows loop
441 do 438 do {
442 { 439 const std::string virtual_name(Common::TStrToUTF8(ffd.cFileName));
443 FSTEntry entry;
444 const std::string virtualName(Common::TStrToUTF8(ffd.cFileName));
445#else 440#else
446 struct dirent dirent, *result = nullptr; 441 struct dirent dirent, *result = nullptr;
447 442
@@ -450,115 +445,80 @@ u32 ScanDirectoryTree(const std::string &directory, FSTEntry& parentEntry)
450 return 0; 445 return 0;
451 446
452 // non windows loop 447 // non windows loop
453 while (!readdir_r(dirp, &dirent, &result) && result) 448 while (!readdir_r(dirp, &dirent, &result) && result) {
454 { 449 const std::string virtual_name(result->d_name);
455 FSTEntry entry;
456 const std::string virtualName(result->d_name);
457#endif 450#endif
458 // check for "." and ".." 451 // check for "." and ".."
459 if (((virtualName[0] == '.') && (virtualName[1] == '\0')) || 452 if (((virtual_name[0] == '.') && (virtual_name[1] == '\0')) ||
460 ((virtualName[0] == '.') && (virtualName[1] == '.') && 453 ((virtual_name[0] == '.') && (virtual_name[1] == '.') &&
461 (virtualName[2] == '\0'))) 454 (virtual_name[2] == '\0')))
462 continue; 455 continue;
463 entry.virtualName = virtualName;
464 entry.physicalName = directory;
465 entry.physicalName += DIR_SEP + entry.virtualName;
466 456
467 if (IsDirectory(entry.physicalName.c_str())) 457 int ret = callback(directory, virtual_name);
468 { 458 if (ret < 0) {
469 entry.isDirectory = true; 459 if (ret != -1)
470 // is a directory, lets go inside 460 found_entries = ret;
471 entry.size = ScanDirectoryTree(entry.physicalName, entry); 461 break;
472 foundEntries += (u32)entry.size;
473 }
474 else
475 { // is a file
476 entry.isDirectory = false;
477 entry.size = GetSize(entry.physicalName.c_str());
478 } 462 }
479 ++foundEntries; 463 found_entries += ret;
480 // Push into the tree 464
481 parentEntry.children.push_back(entry);
482#ifdef _WIN32 465#ifdef _WIN32
483 } while (FindNextFile(hFind, &ffd) != 0); 466 } while (FindNextFile(handle_find, &ffd) != 0);
484 FindClose(hFind); 467 FindClose(handle_find);
485#else 468#else
486 } 469 }
487 closedir(dirp); 470 closedir(dirp);
488#endif 471#endif
489 // Return number of entries found. 472 // Return number of entries found.
490 return foundEntries; 473 return found_entries;
491} 474}
492 475
493 476int ScanDirectoryTree(const std::string &directory, FSTEntry& parent_entry)
494// Deletes the given directory and anything under it. Returns true on success.
495bool DeleteDirRecursively(const std::string &directory)
496{ 477{
497 LOG_TRACE(Common_Filesystem, "%s", directory.c_str()); 478 const auto callback = [&parent_entry](const std::string& directory,
498#ifdef _WIN32 479 const std::string& virtual_name) -> int {
499 // Find the first file in the directory. 480 FSTEntry entry;
500 WIN32_FIND_DATA ffd; 481 int found_entries = 0;
501 HANDLE hFind = FindFirstFile(Common::UTF8ToTStr(directory + "\\*").c_str(), &ffd); 482 entry.virtualName = virtual_name;
502 483 entry.physicalName = directory + DIR_SEP + virtual_name;
503 if (hFind == INVALID_HANDLE_VALUE)
504 {
505 FindClose(hFind);
506 return false;
507 }
508
509 // windows loop
510 do
511 {
512 const std::string virtualName(Common::TStrToUTF8(ffd.cFileName));
513#else
514 struct dirent dirent, *result = nullptr;
515 DIR *dirp = opendir(directory.c_str());
516 if (!dirp)
517 return false;
518
519 // non windows loop
520 while (!readdir_r(dirp, &dirent, &result) && result)
521 {
522 const std::string virtualName = result->d_name;
523#endif
524 484
525 // check for "." and ".." 485 if (IsDirectory(entry.physicalName)) {
526 if (((virtualName[0] == '.') && (virtualName[1] == '\0')) || 486 entry.isDirectory = true;
527 ((virtualName[0] == '.') && (virtualName[1] == '.') && 487 // is a directory, lets go inside
528 (virtualName[2] == '\0'))) 488 entry.size = ScanDirectoryTree(entry.physicalName, entry);
529 continue; 489 found_entries += (int)entry.size;
490 } else { // is a file
491 entry.isDirectory = false;
492 entry.size = GetSize(entry.physicalName);
493 }
494 ++found_entries;
495 // Push into the tree
496 parent_entry.children.push_back(entry);
497 return found_entries;
498 };
530 499
531 std::string newPath = directory + DIR_SEP_CHR + virtualName; 500 return ScanDirectoryTreeAndCallback(directory, callback);
532 if (IsDirectory(newPath)) 501}
533 {
534 if (!DeleteDirRecursively(newPath))
535 {
536 #ifndef _WIN32
537 closedir(dirp);
538 #endif
539 502
540 return false;
541 }
542 }
543 else
544 {
545 if (!FileUtil::Delete(newPath))
546 {
547 #ifndef _WIN32
548 closedir(dirp);
549 #endif
550 503
551 return false; 504bool DeleteDirRecursively(const std::string &directory)
505{
506 const static auto callback = [](const std::string& directory,
507 const std::string& virtual_name) -> int {
508 std::string new_path = directory + DIR_SEP_CHR + virtual_name;
509 if (IsDirectory(new_path)) {
510 if (!DeleteDirRecursively(new_path)) {
511 return -2;
552 } 512 }
513 } else if (!Delete(new_path)) {
514 return -2;
553 } 515 }
516 return 0;
517 };
554 518
555#ifdef _WIN32 519 if (ScanDirectoryTreeAndCallback(directory, callback) == -2) {
556 } while (FindNextFile(hFind, &ffd) != 0); 520 return false;
557 FindClose(hFind);
558#else
559 } 521 }
560 closedir(dirp);
561#endif
562 FileUtil::DeleteDir(directory); 522 FileUtil::DeleteDir(directory);
563 523
564 return true; 524 return true;
diff --git a/src/common/file_util.h b/src/common/file_util.h
index e71a9b2fa..3d617f573 100644
--- a/src/common/file_util.h
+++ b/src/common/file_util.h
@@ -6,6 +6,7 @@
6 6
7#include <array> 7#include <array>
8#include <fstream> 8#include <fstream>
9#include <functional>
9#include <cstddef> 10#include <cstddef>
10#include <cstdio> 11#include <cstdio>
11#include <string> 12#include <string>
@@ -96,9 +97,28 @@ bool Copy(const std::string &srcFilename, const std::string &destFilename);
96// creates an empty file filename, returns true on success 97// creates an empty file filename, returns true on success
97bool CreateEmptyFile(const std::string &filename); 98bool CreateEmptyFile(const std::string &filename);
98 99
99// Scans the directory tree gets, starting from _Directory and adds the 100/**
100// results into parentEntry. Returns the number of files+directories found 101 * Scans the directory tree, calling the callback for each file/directory found.
101u32 ScanDirectoryTree(const std::string &directory, FSTEntry& parentEntry); 102 * The callback must return the number of files and directories which the provided path contains.
103 * If the callback's return value is -1, the callback loop is broken immediately.
104 * If the callback's return value is otherwise negative, the callback loop is broken immediately
105 * and the callback's return value is returned from this function (to allow for error handling).
106 * @param directory the parent directory to start scanning from
107 * @param callback The callback which will be called for each file/directory. It is called
108 * with the arguments (const std::string& directory, const std::string& virtual_name).
109 * The `directory `parameter is the path to the directory which contains the file/directory.
110 * The `virtual_name` parameter is the incomplete file path, without any directory info.
111 * @return the total number of files/directories found
112 */
113int ScanDirectoryTreeAndCallback(const std::string &directory, std::function<int(const std::string&, const std::string&)> callback);
114
115/**
116 * Scans the directory tree, storing the results.
117 * @param directory the parent directory to start scanning from
118 * @param parent_entry FSTEntry where the filesystem tree results will be stored.
119 * @return the total number of files/directories found
120 */
121int ScanDirectoryTree(const std::string &directory, FSTEntry& parent_entry);
102 122
103// deletes the given directory and anything under it. Returns true on success. 123// deletes the given directory and anything under it. Returns true on success.
104bool DeleteDirRecursively(const std::string &directory); 124bool DeleteDirRecursively(const std::string &directory);