diff options
author | Chris Xiong <chirs241097@gmail.com> | 2022-09-19 02:39:03 -0400 |
---|---|---|
committer | Chris Xiong <chirs241097@gmail.com> | 2022-09-19 02:39:03 -0400 |
commit | 41e9051f2d809c42c3dfecc2eb11ad544cbd27b7 (patch) | |
tree | e370e08b0e0a45c6eef38704aa2f2b2b0e6d8033 /qdeduper/filescanner.cpp | |
parent | 4b8d314f575d9e893d8dda7431194f8b470fc888 (diff) | |
download | deduper-41e9051f2d809c42c3dfecc2eb11ad544cbd27b7.tar.xz |
You break it, you fix it!
The GUI is now working again, with scanning built-in.
Diffstat (limited to 'qdeduper/filescanner.cpp')
-rw-r--r-- | qdeduper/filescanner.cpp | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/qdeduper/filescanner.cpp b/qdeduper/filescanner.cpp new file mode 100644 index 0000000..e7e45fc --- /dev/null +++ b/qdeduper/filescanner.cpp @@ -0,0 +1,75 @@ +#include "filescanner.hpp" + +#include <cstring> +#include <algorithm> +#include <fstream> + +using std::size_t; + +FileScanner::FileScanner() : QObject(nullptr), maxmnlen(0) +{ + +} + +void FileScanner::add_magic_number(const std::string &m) +{ + mn.push_back(m); + if (m.length() > maxmnlen) + maxmnlen = m.length(); +} + +void FileScanner::add_path(const fs::path &p, bool recurse) +{ + paths.emplace_back(p, recurse); +} + +template <class T> +void dirit_foreach(T iter, std::function<void(const fs::directory_entry& p)> f) +{ + std::for_each(fs::begin(iter), fs::end(iter), f); +} + +void FileScanner::scan() +{ + size_t fcnt = 0; + auto opt = std::filesystem::directory_options::skip_permission_denied; + auto count_files = [&fcnt](const fs::directory_entry& e){ + if (e.is_regular_file()) ++fcnt; + }; + auto scan_file = [&fcnt, this](const fs::directory_entry &e) { + if (!e.is_regular_file()) return; + std::fstream fst(e.path(), std::ios::binary | std::ios::in); + std::string buf(maxmnlen, '\0'); + fst.read(buf.data(), maxmnlen); + buf.resize(fst.gcount()); + for (auto &magic : mn) + if (!memcmp(magic.data(), buf.data(), magic.length())) + { + ret.push_back(e.path()); + break; + } + Q_EMIT file_scanned(e.path(), ++fcnt); + }; + auto for_all_paths = [opt, this](std::function<void(const fs::directory_entry&)> f) { + for (auto &pe : paths) + { + fs::path p; + bool recurse; + std::tie(p, recurse) = pe; + if (recurse) + dirit_foreach(fs::recursive_directory_iterator(p, opt), f); + else + dirit_foreach(fs::directory_iterator(p, opt), f); + } + }; + for_all_paths(count_files); + Q_EMIT scan_done_prep(fcnt); + + fcnt = 0; + for_all_paths(scan_file); +} + +std::vector<fs::path> FileScanner::file_list() +{ + return ret; +} |