refactor: tr_files::hasAnyLocalData() (#2911)

This commit is contained in:
Charles Kerr 2022-04-13 21:41:06 -05:00 committed by GitHub
parent 9f9f60f1e3
commit ec57d10954
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 29 deletions

View File

@ -86,3 +86,16 @@ std::optional<tr_files::FoundFile> tr_files::find(
return {};
}
bool tr_files::hasAnyLocalData(std::string_view const* search_paths, size_t n_paths) const
{
for (tr_file_index_t i = 0, n = size(); i < n; ++i)
{
if (find(i, search_paths, n_paths))
{
return true;
}
}
return false;
}

View File

@ -67,10 +67,8 @@ public:
size_t base_len_;
};
[[nodiscard]] std::optional<FoundFile> find(
tr_file_index_t file_index,
std::string_view const* search_paths,
size_t n_paths) const;
[[nodiscard]] std::optional<FoundFile> find(tr_file_index_t, std::string_view const* search_paths, size_t n_paths) const;
[[nodiscard]] bool hasAnyLocalData(std::string_view const* search_paths, size_t n_paths) const;
static constexpr std::string_view PartialFileSuffix = ".part";

View File

@ -594,24 +594,42 @@ void tr_torrent::setMetainfo(tr_torrent_metainfo const& tm)
this->setDirty();
}
static bool hasAnyLocalData(tr_torrent const* tor)
static size_t buildSearchPathArray(tr_torrent const* tor, std::string_view* paths)
{
for (tr_file_index_t i = 0, n = tor->fileCount(); i < n; ++i)
auto* walk = paths;
if (auto const& path = tor->downloadDir(); !std::empty(path))
{
if (tor->findFile(i))
{
return true;
}
*walk++ = path.sv();
}
return false;
if (auto const& path = tor->incompleteDir(); !std::empty(path))
{
*walk++ = path.sv();
}
return walk - paths;
}
std::optional<tr_files::FoundFile> tr_torrent::findFile(tr_file_index_t file_index) const
{
auto paths = std::array<std::string_view, 4>{};
auto const n_paths = buildSearchPathArray(this, std::data(paths));
return metainfo_.files().find(file_index, std::data(paths), n_paths);
}
bool tr_torrent::hasAnyLocalData() const
{
auto paths = std::array<std::string_view, 4>{};
auto const n_paths = buildSearchPathArray(this, std::data(paths));
return metainfo_.files().hasAnyLocalData(std::data(paths), n_paths);
}
static bool setLocalErrorIfFilesDisappeared(tr_torrent* tor, std::optional<bool> has_local_data = {})
{
if (!has_local_data)
{
has_local_data = hasAnyLocalData(tor);
has_local_data = tor->hasAnyLocalData();
}
bool const files_disappeared = tor->hasTotal() > 0 && !*has_local_data;

View File

@ -9,7 +9,6 @@
#error only libtransmission should #include this header.
#endif
#include <array>
#include <cstddef> // size_t
#include <ctime>
#include <optional>
@ -369,23 +368,9 @@ public:
metainfo_.setFileSubpath(i, subpath);
}
[[nodiscard]] auto findFile(tr_file_index_t file_index) const
{
auto n_paths = size_t{ 0U };
auto paths = std::array<std::string_view, 2>{};
[[nodiscard]] std::optional<tr_files::FoundFile> findFile(tr_file_index_t file_index) const;
if (auto const path = downloadDir(); !std::empty(path))
{
paths[n_paths++] = path.sv();
}
if (auto const path = incompleteDir(); !std::empty(path))
{
paths[n_paths++] = path.sv();
}
return metainfo_.files().find(file_index, std::data(paths), n_paths);
}
[[nodiscard]] bool hasAnyLocalData() const;
/// METAINFO - TRACKERS

View File

@ -106,3 +106,22 @@ TEST_F(FilesTest, find)
EXPECT_TRUE(tr_sys_path_remove(partial_filename));
EXPECT_FALSE(files.find(file_index, std::data(search_path), std::size(search_path)));
}
TEST_F(FilesTest, hasAnyLocalData)
{
static auto constexpr Contents = "hello"sv;
auto const filename = tr_pathbuf{ sandboxDir(), "/first_dir/hello.txt"sv };
createFileWithContents(std::string{ filename }, std::data(Contents), std::size(Contents));
auto files = tr_files{};
files.add("first_dir/hello.txt", 1024);
auto const search_path_1 = tr_pathbuf{ sandboxDir() };
auto const search_path_2 = tr_pathbuf{ "/tmp"sv };
auto search_path = std::vector<std::string_view>{ search_path_1.sv(), search_path_2.sv() };
EXPECT_TRUE(files.hasAnyLocalData(std::data(search_path), 2U));
EXPECT_TRUE(files.hasAnyLocalData(std::data(search_path), 1U));
EXPECT_FALSE(files.hasAnyLocalData(std::data(search_path) + 1, 1U));
EXPECT_FALSE(files.hasAnyLocalData(std::data(search_path), 0U));
}