summaryrefslogtreecommitdiff
path: root/src/tangara/database/file_gatherer.cpp
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2024-05-02 19:12:26 +1000
committerjacqueline <me@jacqueline.id.au>2024-05-02 19:12:26 +1000
commit1573a8c4cde1cd9528b422b2dcc598e37ffe94a7 (patch)
treed162822b8fd7054f81bace0c7a65ab4d5e6f93ef /src/tangara/database/file_gatherer.cpp
parenta231fd1c8afedbeb14b0bc77d76bad61db986059 (diff)
downloadtangara-fw-1573a8c4cde1cd9528b422b2dcc598e37ffe94a7.tar.gz
WIP merge cyclically dependent components into one big component
Diffstat (limited to 'src/tangara/database/file_gatherer.cpp')
-rw-r--r--src/tangara/database/file_gatherer.cpp80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/tangara/database/file_gatherer.cpp b/src/tangara/database/file_gatherer.cpp
new file mode 100644
index 00000000..b7b7271e
--- /dev/null
+++ b/src/tangara/database/file_gatherer.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2023 jacqueline <me@jacqueline.id.au>
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#include "file_gatherer.hpp"
+
+#include <deque>
+#include <functional>
+#include <sstream>
+#include <string>
+
+#include "ff.h"
+
+#include "memory_resource.hpp"
+#include "spi.hpp"
+
+namespace database {
+
+static_assert(sizeof(TCHAR) == sizeof(char), "TCHAR must be CHAR");
+
+auto FileGathererImpl::FindFiles(
+ const std::string& root,
+ std::function<void(std::string_view, const FILINFO&)> cb) -> void {
+ std::pmr::deque<std::pmr::string> to_explore{&memory::kSpiRamResource};
+ to_explore.push_back({root.data(), root.size()});
+
+ while (!to_explore.empty()) {
+ auto next_path_str = to_explore.front();
+ to_explore.pop_front();
+
+ const TCHAR* next_path = static_cast<const TCHAR*>(next_path_str.c_str());
+
+ FF_DIR dir;
+ FRESULT res;
+ {
+ auto lock = drivers::acquire_spi();
+ res = f_opendir(&dir, next_path);
+ }
+ if (res != FR_OK) {
+ // TODO: log.
+ continue;
+ }
+
+ for (;;) {
+ FILINFO info;
+ {
+ auto lock = drivers::acquire_spi();
+ res = f_readdir(&dir, &info);
+ }
+ if (res != FR_OK || info.fname[0] == 0) {
+ // No more files in the directory.
+ break;
+ } else if (info.fattrib & (AM_HID | AM_SYS) || info.fname[0] == '.') {
+ // System or hidden file. Ignore it and move on.
+ continue;
+ } else {
+ std::pmr::string full_path{&memory::kSpiRamResource};
+ full_path += next_path_str;
+ full_path += "/";
+ full_path += info.fname;
+
+ if (info.fattrib & AM_DIR) {
+ // This is a directory. Add it to the explore queue.
+ to_explore.push_back(full_path);
+ } else {
+ // This is a file! Let the callback know about it.
+ // std::invoke(cb, full_path.str(), info);
+ std::invoke(cb, full_path, info);
+ }
+ }
+ }
+
+ auto lock = drivers::acquire_spi();
+ f_closedir(&dir);
+ }
+}
+
+} // namespace database