mirror of
https://github.com/transmission/transmission.git
synced 2025-12-20 02:18:42 +00:00
refactor: add tr_sys_dir_get_files() (#5412)
This commit is contained in:
@@ -294,25 +294,12 @@ auto parseFile(std::string_view filename)
|
||||
|
||||
auto getFilenamesInDir(std::string_view folder)
|
||||
{
|
||||
auto files = std::vector<std::string>{};
|
||||
|
||||
if (auto const odir = tr_sys_dir_open(folder); odir != TR_BAD_SYS_DIR)
|
||||
{
|
||||
char const* name = nullptr;
|
||||
auto const prefix = std::string{ folder } + '/';
|
||||
while ((name = tr_sys_dir_read_name(odir)) != nullptr)
|
||||
auto files = tr_sys_dir_get_files(folder);
|
||||
for (auto& file : files)
|
||||
{
|
||||
if (name[0] == '.') // ignore dotfiles
|
||||
{
|
||||
continue;
|
||||
file.insert(0, prefix);
|
||||
}
|
||||
|
||||
files.emplace_back(prefix + name);
|
||||
}
|
||||
|
||||
tr_sys_dir_close(odir);
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,13 +4,16 @@
|
||||
// License text can be found in the licenses/ folder.
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "libtransmission/transmission.h"
|
||||
|
||||
#include "libtransmission/error.h"
|
||||
#include "libtransmission/file.h"
|
||||
#include "libtransmission/tr-assert.h"
|
||||
#include "libtransmission/tr-strbuf.h"
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
@@ -33,3 +36,37 @@ bool tr_sys_file_write_line(tr_sys_file_t handle, std::string_view buffer, tr_er
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<std::string> tr_sys_dir_get_files(
|
||||
std::string_view folder,
|
||||
std::function<bool(std::string_view)> const& test,
|
||||
tr_error** error)
|
||||
{
|
||||
if (auto const info = tr_sys_path_get_info(folder); !info || !info->isFolder())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
auto const odir = tr_sys_dir_open(folder, error);
|
||||
if (odir == TR_BAD_SYS_DIR)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
auto filenames = std::vector<std::string>{};
|
||||
for (;;)
|
||||
{
|
||||
char const* const name = tr_sys_dir_read_name(odir, error);
|
||||
|
||||
if (name == nullptr)
|
||||
{
|
||||
tr_sys_dir_close(odir, error);
|
||||
return filenames;
|
||||
}
|
||||
|
||||
if (test(name))
|
||||
{
|
||||
filenames.emplace_back(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,9 +8,11 @@
|
||||
#include <cstddef> // size_t
|
||||
#include <cstdint> // uint64_t
|
||||
#include <ctime> // time_t
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
@@ -612,5 +614,15 @@ char const* tr_sys_dir_read_name(tr_sys_dir_t handle, struct tr_error** error =
|
||||
*/
|
||||
bool tr_sys_dir_close(tr_sys_dir_t handle, struct tr_error** error = nullptr);
|
||||
|
||||
[[nodiscard]] constexpr bool tr_basename_is_not_dotfile(std::string_view sv)
|
||||
{
|
||||
return std::empty(sv) || sv.front() != '.';
|
||||
}
|
||||
|
||||
[[nodiscard]] std::vector<std::string> tr_sys_dir_get_files(
|
||||
std::string_view folder,
|
||||
std::function<bool(std::string_view name)> const& test = tr_basename_is_not_dotfile,
|
||||
tr_error** error = nullptr);
|
||||
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
||||
@@ -86,22 +86,8 @@ void walkTree(std::string_view const top, std::string_view const subpath, std::s
|
||||
switch (info->type)
|
||||
{
|
||||
case TR_SYS_PATH_IS_DIRECTORY:
|
||||
if (tr_sys_dir_t odir = tr_sys_dir_open(path); odir != TR_BAD_SYS_DIR)
|
||||
for (auto const& name : tr_sys_dir_get_files(path))
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
char const* const name = tr_sys_dir_read_name(odir);
|
||||
|
||||
if (name == nullptr)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (name[0] == '.') // skip dotfiles
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!std::empty(subpath))
|
||||
{
|
||||
walkTree(top, tr_pathbuf{ subpath, '/', name }, files);
|
||||
@@ -111,9 +97,6 @@ void walkTree(std::string_view const top, std::string_view const subpath, std::s
|
||||
walkTree(top, name, files);
|
||||
}
|
||||
}
|
||||
|
||||
tr_sys_dir_close(odir);
|
||||
}
|
||||
break;
|
||||
|
||||
case TR_SYS_PATH_IS_FILE:
|
||||
|
||||
@@ -1336,45 +1336,12 @@ namespace
|
||||
{
|
||||
namespace load_torrents_helpers
|
||||
{
|
||||
[[nodiscard]] std::vector<std::string> get_matching_files(
|
||||
std::string const& folder,
|
||||
std::function<bool(std::string_view)> const& test)
|
||||
{
|
||||
if (auto const info = tr_sys_path_get_info(folder); !info || !info->isFolder())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
auto const odir = tr_sys_dir_open(folder);
|
||||
if (odir == TR_BAD_SYS_DIR)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
auto filenames = std::vector<std::string>{};
|
||||
for (;;)
|
||||
{
|
||||
char const* const name = tr_sys_dir_read_name(odir);
|
||||
|
||||
if (name == nullptr)
|
||||
{
|
||||
tr_sys_dir_close(odir);
|
||||
return filenames;
|
||||
}
|
||||
|
||||
if (test(name))
|
||||
{
|
||||
filenames.emplace_back(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void session_load_torrents(tr_session* session, tr_ctor* ctor, std::promise<size_t>* loaded_promise)
|
||||
{
|
||||
auto n_torrents = size_t{};
|
||||
auto const& folder = session->torrentDir();
|
||||
|
||||
for (auto const& name : get_matching_files(folder, [](auto const& name) { return tr_strvEndsWith(name, ".torrent"sv); }))
|
||||
for (auto const& name : tr_sys_dir_get_files(folder, [](auto name) { return tr_strvEndsWith(name, ".torrent"sv); }))
|
||||
{
|
||||
auto const path = tr_pathbuf{ folder, '/', name };
|
||||
|
||||
@@ -1385,7 +1352,7 @@ void session_load_torrents(tr_session* session, tr_ctor* ctor, std::promise<size
|
||||
}
|
||||
|
||||
auto buf = std::vector<char>{};
|
||||
for (auto const& name : get_matching_files(folder, [](auto const& name) { return tr_strvEndsWith(name, ".magnet"sv); }))
|
||||
for (auto const& name : tr_sys_dir_get_files(folder, [](auto name) { return tr_strvEndsWith(name, ".magnet"sv); }))
|
||||
{
|
||||
auto const path = tr_pathbuf{ folder, '/', name };
|
||||
|
||||
|
||||
@@ -110,32 +110,10 @@ void BaseWatchdir::processFile(std::string_view basename)
|
||||
void BaseWatchdir::scan()
|
||||
{
|
||||
tr_error* error = nullptr;
|
||||
auto const dir = tr_sys_dir_open(dirname_, &error);
|
||||
if (dir == TR_BAD_SYS_DIR)
|
||||
{
|
||||
tr_logAddWarn(fmt::format(
|
||||
_("Couldn't read '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", dirname()),
|
||||
fmt::arg("error", error->message),
|
||||
fmt::arg("error_code", error->code)));
|
||||
tr_error_free(error);
|
||||
return;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
for (auto const& file : tr_sys_dir_get_files(dirname_, tr_basename_is_not_dotfile, &error))
|
||||
{
|
||||
char const* const name = tr_sys_dir_read_name(dir, &error);
|
||||
if (name == nullptr)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if ("."sv == name || ".."sv == name)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
processFile(name);
|
||||
processFile(file);
|
||||
}
|
||||
|
||||
if (error != nullptr)
|
||||
@@ -147,8 +125,6 @@ void BaseWatchdir::scan()
|
||||
fmt::arg("error_code", error->code)));
|
||||
tr_error_free(error);
|
||||
}
|
||||
|
||||
tr_sys_dir_close(dir);
|
||||
}
|
||||
|
||||
} // namespace impl
|
||||
|
||||
Reference in New Issue
Block a user