refactor: add tr_torrent::fileCount() (#2273)

Provide an accessor to get a torrent's file count.

This is an incremental step towards making tr_torrent's impl private.
This commit is contained in:
Charles Kerr 2021-12-06 15:26:04 -06:00 committed by GitHub
parent e2be142ad6
commit 867a131e1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 69 additions and 63 deletions

View File

@ -52,7 +52,7 @@ static int readOrWriteBytes(
int err = 0;
bool const doWrite = ioMode >= TR_IO_WRITE;
TR_ASSERT(fileIndex < tr_torrentFileCount(tor));
TR_ASSERT(fileIndex < tor->fileCount());
auto const& file = tor->info.files[fileIndex];
TR_ASSERT(file.length == 0 || fileOffset < file.length);
TR_ASSERT(fileOffset + buflen <= file.length);
@ -180,15 +180,16 @@ void tr_ioFindFileLocation(
uint64_t const offset = tr_pieceOffset(tor, pieceIndex, pieceOffset, 0);
TR_ASSERT(offset < tor->info.totalSize);
auto const n_files = tor->fileCount();
auto const* file = static_cast<tr_file const*>(
bsearch(&offset, tor->info.files, tor->info.fileCount, sizeof(tr_file), compareOffsetToFile));
bsearch(&offset, tor->info.files, n_files, sizeof(tr_file), compareOffsetToFile));
TR_ASSERT(file != nullptr);
if (file != nullptr)
{
*fileIndex = file - tor->info.files;
*fileOffset = offset - file->priv.offset;
TR_ASSERT(*fileIndex < tor->info.fileCount);
TR_ASSERT(*fileIndex < n_files);
TR_ASSERT(*fileOffset < file->length);
TR_ASSERT(tor->info.files[*fileIndex].priv.offset + *fileOffset == offset);
}

View File

@ -139,7 +139,7 @@ static uint64_t loadLabels(tr_variant* dict, tr_torrent* tor)
static void saveDND(tr_variant* dict, tr_torrent const* tor)
{
auto const n = tr_torrentFileCount(tor);
auto const n = tor->fileCount();
tr_variant* const list = tr_variantDictAddList(dict, TR_KEY_dnd, n);
for (tr_file_index_t i = 0; i < n; ++i)
@ -152,7 +152,7 @@ static uint64_t loadDND(tr_variant* dict, tr_torrent* tor)
{
uint64_t ret = 0;
tr_variant* list = nullptr;
tr_file_index_t const n = tor->info.fileCount;
auto const n = tor->fileCount();
if (tr_variantDictFindList(dict, TR_KEY_dnd, &list) && tr_variantListSize(list) == n)
{
@ -199,7 +199,7 @@ static uint64_t loadDND(tr_variant* dict, tr_torrent* tor)
static void saveFilePriorities(tr_variant* dict, tr_torrent const* tor)
{
auto const n = tr_torrentFileCount(tor);
auto const n = tor->fileCount();
tr_variant* const list = tr_variantDictAddList(dict, TR_KEY_priority, n);
for (tr_file_index_t i = 0; i < n; ++i)
@ -212,7 +212,7 @@ static uint64_t loadFilePriorities(tr_variant* dict, tr_torrent* tor)
{
auto ret = uint64_t{};
tr_file_index_t const n = tor->info.fileCount;
auto const n = tor->fileCount();
tr_variant* list = nullptr;
if (tr_variantDictFindList(dict, TR_KEY_priority, &list) && tr_variantListSize(list) == n)
{
@ -390,7 +390,7 @@ static uint64_t loadName(tr_variant* dict, tr_torrent* tor)
static void saveFilenames(tr_variant* dict, tr_torrent const* tor)
{
tr_file_index_t const n = tor->info.fileCount;
auto const n = tor->fileCount();
tr_file const* files = tor->info.files;
bool any_renamed = false;
@ -419,16 +419,17 @@ static uint64_t loadFilenames(tr_variant* dict, tr_torrent* tor)
return 0;
}
size_t const n = tr_variantListSize(list);
tr_file* files = tor->info.files;
for (size_t i = 0; i < tor->info.fileCount && i < n; ++i)
auto const n_files = tor->fileCount();
auto const n_list = tr_variantListSize(list);
for (size_t i = 0; i < n_files && i < n_list; ++i)
{
auto sv = std::string_view{};
if (tr_variantGetStrView(tr_variantListChild(list, i), &sv) && !std::empty(sv))
{
tr_free(files[i].name);
files[i].name = tr_strvDup(sv);
files[i].priv.is_renamed = true;
auto& file = tor->info.files[i];
tr_free(file.name);
file.name = tr_strvDup(sv);
file.priv.is_renamed = true;
}
}
@ -479,7 +480,7 @@ static void saveProgress(tr_variant* dict, tr_torrent* tor)
tr_variant* const prog = tr_variantDictAddDict(dict, TR_KEY_progress, 4);
// add the mtimes
size_t const n = tr_torrentFileCount(tor);
auto const n = tor->fileCount();
tr_variant* const l = tr_variantDictAddList(prog, TR_KEY_mtimes, n);
for (auto const *file = inf->files, *end = file + n; file != end; ++file)
{
@ -530,7 +531,7 @@ static uint64_t loadProgress(tr_variant* dict, tr_torrent* tor)
auto checked = tr_bitfield(inf->pieceCount);
auto mtimes = std::vector<time_t>{};
auto const n_files = tr_torrentFileCount(tor);
auto const n_files = tor->fileCount();
mtimes.reserve(n_files);
// try to load mtimes
@ -586,13 +587,13 @@ static uint64_t loadProgress(tr_variant* dict, tr_torrent* tor)
}
}
if (std::size(mtimes) != tor->info.fileCount)
if (std::size(mtimes) != n_files)
{
tr_logAddTorErr(tor, "got %zu mtimes; expected %zu", std::size(mtimes), size_t(tor->info.fileCount));
tr_logAddTorErr(tor, "got %zu mtimes; expected %zu", std::size(mtimes), size_t(n_files));
// if resizing grows the vector, we'll get 0 mtimes for the
// new items which is exactly what we want since the pieces
// in an unknown state should be treated as untested
mtimes.resize(tor->info.fileCount);
mtimes.resize(n_files);
}
tor->initCheckedPieces(checked, std::data(mtimes));

View File

@ -383,7 +383,7 @@ static void addLabels(tr_torrent const* tor, tr_variant* list)
static void addFileStats(tr_torrent const* tor, tr_variant* list)
{
for (tr_file_index_t i = 0, n = tr_torrentFileCount(tor); i < n; ++i)
for (tr_file_index_t i = 0, n = tor->fileCount(); i < n; ++i)
{
auto const file = tr_torrentFile(tor, i);
tr_variant* d = tr_variantListAddDict(list, 3);
@ -395,7 +395,7 @@ static void addFileStats(tr_torrent const* tor, tr_variant* list)
static void addFiles(tr_torrent const* tor, tr_variant* list)
{
for (tr_file_index_t i = 0, n = tr_torrentFileCount(tor); i < n; ++i)
for (tr_file_index_t i = 0, n = tor->fileCount(); i < n; ++i)
{
auto const file = tr_torrentFile(tor, i);
tr_variant* d = tr_variantListAddDict(list, 3);
@ -569,16 +569,16 @@ static void initField(
break;
case TR_KEY_file_count:
tr_variantInitInt(initme, tr_torrentFileCount(tor));
tr_variantInitInt(initme, tor->fileCount());
break;
case TR_KEY_files:
tr_variantInitList(initme, tr_torrentFileCount(tor));
tr_variantInitList(initme, tor->fileCount());
addFiles(tor, initme);
break;
case TR_KEY_fileStats:
tr_variantInitList(initme, tr_torrentFileCount(tor));
tr_variantInitList(initme, tor->fileCount());
addFileStats(tor, initme);
break;
@ -715,7 +715,7 @@ static void initField(
case TR_KEY_priorities:
{
auto const n = tr_torrentFileCount(tor);
auto const n = tor->fileCount();
tr_variantInitList(initme, n);
for (tr_file_index_t i = 0; i < n; ++i)
{
@ -825,7 +825,7 @@ static void initField(
case TR_KEY_wanted:
{
auto const n = tr_torrentFileCount(tor);
auto const n = tor->fileCount();
tr_variantInitList(initme, n);
for (tr_file_index_t i = 0; i < n; ++i)
{
@ -985,8 +985,10 @@ static char const* setLabels(tr_torrent* tor, tr_variant* list)
static char const* setFilePriorities(tr_torrent* tor, tr_priority_t priority, tr_variant* list)
{
char const* errmsg = nullptr;
auto const n_files = tor->fileCount();
auto files = std::vector<tr_file_index_t>{};
files.reserve(tr_torrentFileCount(tor));
files.reserve(n_files);
if (size_t const n = tr_variantListSize(list); n != 0)
{
@ -995,7 +997,7 @@ static char const* setFilePriorities(tr_torrent* tor, tr_priority_t priority, tr
auto tmp = int64_t{};
if (tr_variantGetInt(tr_variantListChild(list, i), &tmp))
{
if (0 <= tmp && tmp < tor->info.fileCount)
if (0 <= tmp && tmp < n_files)
{
files.push_back(tr_file_index_t(tmp));
}
@ -1008,10 +1010,8 @@ static char const* setFilePriorities(tr_torrent* tor, tr_priority_t priority, tr
}
else // if empty set, apply to all
{
for (tr_file_index_t t = 0; t < tor->info.fileCount; ++t)
{
files.push_back(t);
}
files.resize(n_files);
std::iota(std::begin(files), std::end(files), 0);
}
tor->setFilePriorities(std::data(files), std::size(files), priority);
@ -1023,7 +1023,7 @@ static char const* setFileDLs(tr_torrent* tor, bool wanted, tr_variant* list)
{
char const* errmsg = nullptr;
auto const n_files = tr_torrentFileCount(tor);
auto const n_files = tor->fileCount();
size_t const n_items = tr_variantListSize(list);
auto files = std::vector<tr_file_index_t>{};
@ -1036,7 +1036,7 @@ static char const* setFileDLs(tr_torrent* tor, bool wanted, tr_variant* list)
auto tmp = int64_t{};
if (tr_variantGetInt(tr_variantListChild(list, i), &tmp))
{
if (0 <= tmp && tmp < tor->info.fileCount)
if (0 <= tmp && tmp < n_files)
{
files.push_back(tmp);
}

View File

@ -579,16 +579,14 @@ static void onTrackerResponse(tr_torrent* tor, tr_tracker_event const* event, vo
****
***/
static void tr_torrentInitFilePieces(tr_torrent* tor)
static void tr_torrentInitFileOffsets(tr_torrent* tor)
{
uint64_t offset = 0;
tr_info* inf = &tor->info;
auto offset = uint64_t{ 0 };
/* assign the file offsets */
for (tr_file_index_t f = 0; f < inf->fileCount; ++f)
for (auto *it = tor->info.files, *end = it + tor->fileCount(); it != end; ++it)
{
inf->files[f].priv.offset = offset;
offset += inf->files[f].length;
it->priv.offset = offset;
offset += it->length;
}
}
@ -600,7 +598,7 @@ void tr_torrentGotNewInfoDict(tr_torrent* tor)
{
tor->initSizes(tor->info.totalSize, tor->info.pieceSize);
tor->completion = tr_completion{ tor, tor };
tr_torrentInitFilePieces(tor);
tr_torrentInitFileOffsets(tor);
tr_peerMgrOnTorrentGotMetainfo(tor);
@ -611,7 +609,7 @@ static bool hasAnyLocalData(tr_torrent const* tor)
{
auto filename = std::string{};
for (tr_file_index_t i = 0; i < tor->info.fileCount; ++i)
for (tr_file_index_t i = 0, n = tor->fileCount(); i < n; ++i)
{
if (tor->findFile(filename, i))
{
@ -706,7 +704,7 @@ static void torrentInit(tr_torrent* tor, tr_ctor const* ctor)
tor->initSizes(tor->info.totalSize, tor->info.pieceSize);
tor->completion = tr_completion{ tor, tor };
tr_torrentInitFilePieces(tor);
tr_torrentInitFileOffsets(tor);
// tr_torrentLoadResume() calls a lot of tr_torrentSetFoo() methods
// that set things as dirty, but... these settings being loaded are
@ -1219,7 +1217,7 @@ static uint64_t countFileBytesCompleted(tr_torrent const* tor, tr_file_index_t i
tr_file_view tr_torrentFile(tr_torrent const* torrent, tr_file_index_t i)
{
TR_ASSERT(tr_isTorrent(torrent));
TR_ASSERT(i < torrent->info.fileCount);
TR_ASSERT(i < torrent->fileCount());
auto const& file = torrent->info.files[i];
auto const* const name = file.name;
@ -1240,7 +1238,7 @@ size_t tr_torrentFileCount(tr_torrent const* torrent)
{
TR_ASSERT(tr_isTorrent(torrent));
return torrent->info.fileCount;
return torrent->fileCount();
}
/***
@ -1392,7 +1390,7 @@ static void torrentStartImpl(void* vtor)
uint64_t tr_torrentGetCurrentSizeOnDisk(tr_torrent const* tor)
{
uint64_t byte_count = 0;
tr_file_index_t const n = tor->info.fileCount;
auto const n = tor->fileCount();
for (tr_file_index_t i = 0; i < n; ++i)
{
@ -2300,7 +2298,7 @@ uint64_t tr_torrentGetBytesLeftToAllocate(tr_torrent const* tor)
uint64_t bytesLeft = 0;
for (tr_file_index_t i = 0, n = tr_torrentFileCount(tor); i < n; ++i)
for (tr_file_index_t i = 0, n = tor->fileCount(); i < n; ++i)
{
auto const file = tr_torrentFile(tor, i);
@ -2422,7 +2420,7 @@ static void deleteLocalData(tr_torrent* tor, tr_fileFunc func)
auto tmpdir = tr_strvPath(top, TR_PATH_DELIMITER_STR, tr_torrentName(tor), "__XXXXXX");
tr_sys_dir_create_temp(std::data(tmpdir), nullptr);
for (tr_file_index_t f = 0; f < tor->info.fileCount; ++f)
for (tr_file_index_t f = 0, n = tor->fileCount(); f < n; ++f)
{
/* try to find the file, looking in the partial and download dirs */
auto filename = tr_strvPath(top, tor->info.files[f].name);
@ -2495,7 +2493,7 @@ static void deleteLocalData(tr_torrent* tor, tr_fileFunc func)
***/
/* build a list of 'top's child directories that belong to this torrent */
for (tr_file_index_t f = 0; f < tor->info.fileCount; ++f)
for (tr_file_index_t f = 0, n = tor->fileCount(); f < n; ++f)
{
/* get the directory that this file goes in... */
auto const filename = tr_strvPath(top, tor->info.files[f].name);
@ -2596,7 +2594,7 @@ static void setLocationImpl(void* vdata)
/* try to move the files.
* FIXME: there are still all kinds of nasty cases, like what
* if the target directory runs out of space halfway through... */
for (tr_file_index_t i = 0; !err && i < tor->info.fileCount; ++i)
for (tr_file_index_t i = 0, n = tor->fileCount(); !err && i < n; ++i)
{
tr_file const* const f = &tor->info.files[i];
@ -2714,7 +2712,7 @@ std::string_view tr_torrentPrimaryMimeType(tr_torrent const* tor)
// NB: get_mime_type_for_filename() always returns the same ptr for a
// mime_type, so its raw pointer can be used as a key.
auto size_per_mime_type = std::unordered_map<std::string_view, size_t>{};
for (tr_file const *it = inf->files, *end = it + inf->fileCount; it != end; ++it)
for (tr_file const *it = inf->files, *end = it + tor->fileCount(); it != end; ++it)
{
auto const mime_type = tr_get_mime_type_for_filename(it->name);
size_per_mime_type[mime_type] += it->length;
@ -2837,7 +2835,7 @@ void tr_torrentGotBlock(tr_torrent* tor, tr_block_index_t block)
std::optional<tr_torrent::tr_found_file_t> tr_torrent::findFile(std::string& filename, tr_file_index_t i) const
{
TR_ASSERT(i < this->info.fileCount);
TR_ASSERT(i < this->fileCount());
tr_file const& file = info.files[i];
auto file_info = tr_sys_path_info{};
@ -3108,23 +3106,24 @@ static bool renameArgsAreValid(char const* oldpath, char const* newname)
static tr_file_index_t* renameFindAffectedFiles(tr_torrent* tor, char const* oldpath, size_t* setme_n)
{
auto n = size_t{};
tr_file_index_t* indices = tr_new0(tr_file_index_t, tor->info.fileCount);
auto const n_files = tor->fileCount();
auto n_affected_files = size_t{};
tr_file_index_t* indices = tr_new0(tr_file_index_t, n_files);
auto const oldpath_len = strlen(oldpath);
for (tr_file_index_t i = 0; i < tor->info.fileCount; ++i)
for (tr_file_index_t i = 0; i < n_files; ++i)
{
char const* name = tor->info.files[i].name;
size_t const len = strlen(name);
if ((len == oldpath_len || (len > oldpath_len && name[oldpath_len] == '/')) && memcmp(oldpath, name, oldpath_len) == 0)
{
indices[n++] = i;
indices[n_affected_files++] = i;
}
}
*setme_n = n;
*setme_n = n_affected_files;
return indices;
}
@ -3272,7 +3271,7 @@ static void torrentRenamePath(void* vdata)
}
/* update tr_info.name if user changed the toplevel */
if (n == tor->info.fileCount && strchr(oldpath, '/') == nullptr)
if (n == tor->fileCount() && strchr(oldpath, '/') == nullptr)
{
tr_free(tor->info.name);
tor->info.name = tr_strdup(newname);

View File

@ -314,7 +314,7 @@ public:
checked_pieces_ = checked;
auto filename = std::string{};
for (size_t i = 0; i < info.fileCount; ++i)
for (size_t i = 0, n = this->fileCount(); i < n; ++i)
{
auto const found = this->findFile(filename, i);
auto const mtime = found ? found->last_modified_at : 0;
@ -330,7 +330,12 @@ public:
}
}
/// FINDING FILES
/// FILES
tr_file_index_t fileCount() const
{
return info.fileCount;
}
struct tr_found_file_t : public tr_sys_path_info
{

View File

@ -1083,7 +1083,7 @@ char const* tr_torrentName(tr_torrent const*);
* when done) that gives the location of this file on disk,
* or nullptr if no file exists yet.
* @param tor the torrent whose file we're looking for
* @param fileNum the fileIndex, in [0...tr_info.fileCount)
* @param fileNum the fileIndex, in [0...tr_torrentFileCount())
*/
char* tr_torrentFindFile(tr_torrent const* tor, tr_file_index_t fileNum);

View File

@ -73,7 +73,7 @@ public:
have.setHasAll();
tr_peerUpdateProgress(tor, this);
file_urls.resize(tr_torrentInfo(tor)->fileCount);
file_urls.resize(tor->fileCount());
timer = evtimer_new(session->event_base, webseed_timer_func, this);
tr_timerAddMsec(timer, TR_IDLE_TIMER_MSEC);