summaryrefslogtreecommitdiff
path: root/Source/Core/Common/FileSearch.cpp
diff options
context:
space:
mode:
authorJosJuice <josjuice@gmail.com>2020-12-28 13:25:24 +0100
committerJosJuice <josjuice@gmail.com>2020-12-28 21:00:10 +0100
commitd78277c063d43e3234fe80a38d272500f3dfce3a (patch)
treea66fd4f943abb38b4aa47f91a57d7569f0f5be29 /Source/Core/Common/FileSearch.cpp
parent01b964b01aad3f46611e5fec8c44b60ed04a9b3f (diff)
Android: Add specialized content provider implementation of DoFileSearch
Diffstat (limited to 'Source/Core/Common/FileSearch.cpp')
-rw-r--r--Source/Core/Common/FileSearch.cpp72
1 files changed, 49 insertions, 23 deletions
diff --git a/Source/Core/Common/FileSearch.cpp b/Source/Core/Common/FileSearch.cpp
index bbcdc12026..b06ef9b3a1 100644
--- a/Source/Core/Common/FileSearch.cpp
+++ b/Source/Core/Common/FileSearch.cpp
@@ -4,6 +4,7 @@
#include <algorithm>
#include <functional>
+#include <iterator>
#include "Common/CommonPaths.h"
#include "Common/FileSearch.h"
@@ -15,6 +16,10 @@
namespace fs = std::filesystem;
#define HAS_STD_FILESYSTEM
#else
+#ifdef ANDROID
+#include "jni/AndroidCommon/AndroidCommon.h"
+#endif
+
#include <cstring>
#include "Common/CommonFuncs.h"
#include "Common/FileUtil.h"
@@ -24,36 +29,30 @@ namespace Common
{
#ifndef HAS_STD_FILESYSTEM
-static std::vector<std::string>
-FileSearchWithTest(const std::vector<std::string>& directories, bool recursive,
- std::function<bool(const File::FSTEntry&)> callback)
+static void FileSearchWithTest(const std::string& directory, bool recursive,
+ std::vector<std::string>* result_out,
+ std::function<bool(const File::FSTEntry&)> callback)
{
- std::vector<std::string> result;
- for (const std::string& directory : directories)
- {
- File::FSTEntry top = File::ScanDirectoryTree(directory, recursive);
-
- std::function<void(File::FSTEntry&)> DoEntry;
- DoEntry = [&](File::FSTEntry& entry) {
- if (callback(entry))
- result.push_back(entry.physicalName);
- for (auto& child : entry.children)
- DoEntry(child);
- };
- for (auto& child : top.children)
+ File::FSTEntry top = File::ScanDirectoryTree(directory, recursive);
+
+ const std::function<void(File::FSTEntry&)> DoEntry = [&](File::FSTEntry& entry) {
+ if (callback(entry))
+ result_out->push_back(entry.physicalName);
+ for (auto& child : entry.children)
DoEntry(child);
- }
- // remove duplicates
- std::sort(result.begin(), result.end());
- result.erase(std::unique(result.begin(), result.end()), result.end());
- return result;
+ };
+
+ for (auto& child : top.children)
+ DoEntry(child);
}
std::vector<std::string> DoFileSearch(const std::vector<std::string>& directories,
const std::vector<std::string>& exts, bool recursive)
{
+ std::vector<std::string> result;
+
bool accept_all = exts.empty();
- return FileSearchWithTest(directories, recursive, [&](const File::FSTEntry& entry) {
+ const auto callback = [&exts, accept_all](const File::FSTEntry& entry) {
if (accept_all)
return true;
if (entry.isDirectory)
@@ -63,7 +62,34 @@ std::vector<std::string> DoFileSearch(const std::vector<std::string>& directorie
return name.length() >= ext.length() &&
strcasecmp(name.c_str() + name.length() - ext.length(), ext.c_str()) == 0;
});
- });
+ };
+
+ for (const std::string& directory : directories)
+ {
+#ifdef ANDROID
+ // While File::ScanDirectoryTree (which is called in FileSearchWithTest) does handle Android
+ // content correctly, having a specialized implementation of DoFileSearch for Android content
+ // provides a much needed performance boost. Also, this specialized implementation will be
+ // required if we in the future replace the use of File::ScanDirectoryTree with std::filesystem.
+ if (IsPathAndroidContent(directory))
+ {
+ const std::vector<std::string> partial_result =
+ DoFileSearchAndroidContent(directory, exts, recursive);
+
+ result.insert(result.end(), std::make_move_iterator(partial_result.begin()),
+ std::make_move_iterator(partial_result.end()));
+ }
+ else
+#endif
+ {
+ FileSearchWithTest(directory, recursive, &result, callback);
+ }
+ }
+
+ // remove duplicates
+ std::sort(result.begin(), result.end());
+ result.erase(std::unique(result.begin(), result.end()), result.end());
+ return result;
}
#else