refactor: use std::string in tr_file (#2382)

This commit is contained in:
Charles Kerr 2022-01-08 12:53:35 -06:00 committed by GitHub
parent 0c16c454ba
commit 8b65b660c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 138 additions and 146 deletions

View File

@ -53,9 +53,12 @@ void tr_file_piece_map::reset(tr_block_info const& block_info, uint64_t const* f
void tr_file_piece_map::reset(tr_info const& info) void tr_file_piece_map::reset(tr_info const& info)
{ {
tr_file_index_t const n = info.fileCount; auto const n = info.fileCount();
auto file_sizes = std::vector<uint64_t>(n); auto file_sizes = std::vector<uint64_t>(n);
std::transform(info.files, info.files + n, std::begin(file_sizes), [](tr_file const& file) { return file.length; }); for (tr_file_index_t i = 0; i < n; ++i)
{
file_sizes[i] = info.fileSize(i);
}
reset({ info.totalSize, info.pieceSize }, std::data(file_sizes), std::size(file_sizes)); reset({ info.totalSize, info.pieceSize }, std::data(file_sizes), std::size(file_sizes));
} }

View File

@ -123,7 +123,7 @@ static int readOrWriteBytes(
if (!tr_sys_file_read_at(fd, buf, buflen, file_offset, nullptr, &error)) if (!tr_sys_file_read_at(fd, buf, buflen, file_offset, nullptr, &error))
{ {
err = error->code; err = error->code;
tr_logAddTorErr(tor, "read failed for \"%s\": %s", tor->fileSubpath(file_index), error->message); tr_logAddTorErr(tor, "read failed for \"%s\": %s", tor->fileSubpath(file_index).c_str(), error->message);
tr_error_free(error); tr_error_free(error);
} }
} }
@ -132,7 +132,7 @@ static int readOrWriteBytes(
if (!tr_sys_file_write_at(fd, buf, buflen, file_offset, nullptr, &error)) if (!tr_sys_file_write_at(fd, buf, buflen, file_offset, nullptr, &error))
{ {
err = error->code; err = error->code;
tr_logAddTorErr(tor, "write failed for \"%s\": %s", tor->fileSubpath(file_index), error->message); tr_logAddTorErr(tor, "write failed for \"%s\": %s", tor->fileSubpath(file_index).c_str(), error->message);
tr_error_free(error); tr_error_free(error);
} }
} }

View File

@ -110,11 +110,11 @@ bool tr_metainfoAppendSanitizedPathComponent(std::string& out, std::string_view
return std::size(out) > original_out_len; return std::size(out) > original_out_len;
} }
static bool getfile(char** setme, std::string_view root, tr_variant* path, std::string& buf) static bool getfile(std::string* setme, std::string_view root, tr_variant* path, std::string& buf)
{ {
bool success = false; bool success = false;
*setme = nullptr; setme->clear();
if (tr_variantIsList(path)) if (tr_variantIsList(path))
{ {
@ -148,7 +148,7 @@ static bool getfile(char** setme, std::string_view root, tr_variant* path, std::
if (success) if (success)
{ {
*setme = tr_utf8clean(buf); *setme = tr_strvUtf8Clean(buf);
} }
return success; return success;
@ -173,10 +173,9 @@ static char const* parseFiles(tr_info* inf, tr_variant* files, tr_variant const*
errstr = nullptr; errstr = nullptr;
inf->isFolder = true; inf->isFolder = true;
inf->fileCount = tr_variantListSize(files); tr_file_index_t const n = tr_variantListSize(files);
inf->files = tr_new0(tr_file, inf->fileCount); inf->files.resize(n);
for (tr_file_index_t i = 0; i < n; ++i)
for (tr_file_index_t i = 0; i < inf->fileCount; i++)
{ {
auto* const file = tr_variantListChild(files, i); auto* const file = tr_variantListChild(files, i);
@ -193,7 +192,7 @@ static char const* parseFiles(tr_info* inf, tr_variant* files, tr_variant const*
break; break;
} }
if (!getfile(&inf->files[i].name, root_name, path, buf)) if (!getfile(&inf->files[i].subpath, root_name, path, buf))
{ {
errstr = "path"; errstr = "path";
break; break;
@ -205,17 +204,16 @@ static char const* parseFiles(tr_info* inf, tr_variant* files, tr_variant const*
break; break;
} }
inf->files[i].length = len; inf->files[i].size = len;
inf->totalSize += len; inf->totalSize += len;
} }
} }
else if (tr_variantGetInt(length, &len)) /* single-file mode */ else if (tr_variantGetInt(length, &len)) /* single-file mode */
{ {
inf->isFolder = false; inf->isFolder = false;
inf->fileCount = 1; inf->files.resize(1);
inf->files = tr_new0(tr_file, 1); inf->files[0].subpath = root_name;
inf->files[0].name = tr_strvDup(root_name); inf->files[0].size = len;
inf->files[0].length = len;
inf->totalSize += len; inf->totalSize += len;
} }
else else
@ -287,7 +285,7 @@ static char* fix_webseed_url(tr_info const* inf, std::string_view url)
return nullptr; return nullptr;
} }
if (inf->fileCount > 1 && !std::empty(url) && url.back() != '/') if (inf->fileCount() > 1 && !std::empty(url) && url.back() != '/')
{ {
return tr_strvDup(tr_strvJoin(url, "/"sv)); return tr_strvDup(tr_strvJoin(url, "/"sv));
} }
@ -500,7 +498,7 @@ static char const* tr_metainfoParseImpl(
return errstr; return errstr;
} }
if (inf->fileCount == 0 || inf->totalSize == 0) if (inf->fileCount() == 0 || inf->totalSize == 0)
{ {
return "files"; return "files";
} }
@ -553,17 +551,8 @@ void tr_metainfoFree(tr_info* inf)
} }
} }
if (inf->files != nullptr)
{
for (tr_file_index_t ff = 0; ff < inf->fileCount; ff++)
{
tr_free(inf->files[ff].name);
}
}
tr_free(inf->comment); tr_free(inf->comment);
tr_free(inf->creator); tr_free(inf->creator);
tr_free(inf->files);
tr_free(inf->name); tr_free(inf->name);
tr_free(inf->source); tr_free(inf->source);
tr_free(inf->torrent); tr_free(inf->torrent);
@ -571,7 +560,6 @@ void tr_metainfoFree(tr_info* inf)
inf->comment = nullptr; inf->comment = nullptr;
inf->creator = nullptr; inf->creator = nullptr;
inf->files = nullptr;
inf->name = nullptr; inf->name = nullptr;
inf->source = nullptr; inf->source = nullptr;
inf->torrent = nullptr; inf->torrent = nullptr;

View File

@ -106,7 +106,7 @@ std::string_view tr_ctorGetContents(tr_ctor const* ctor)
char const* tr_ctorGetSourceFile(tr_ctor const* ctor) char const* tr_ctorGetSourceFile(tr_ctor const* ctor)
{ {
return ctor->metainfo.parsedTorrentFile().c_str(); return ctor->metainfo.torrentFile().c_str();
} }
bool tr_ctorSaveContents(tr_ctor const* ctor, std::string_view filename, tr_error** error) bool tr_ctorSaveContents(tr_ctor const* ctor, std::string_view filename, tr_error** error)
@ -298,7 +298,7 @@ bool tr_ctorGetIncompleteDir(tr_ctor const* ctor, char const** setme)
tr_torrent_metainfo const* tr_ctorGetMetainfo(tr_ctor const* ctor) tr_torrent_metainfo const* tr_ctorGetMetainfo(tr_ctor const* ctor)
{ {
return std::empty(ctor->metainfo.files()) ? nullptr : &ctor->metainfo; return !std::empty(ctor->metainfo) ? &ctor->metainfo : nullptr;
} }
tr_session* tr_ctorGetSession(tr_ctor const* ctor) tr_session* tr_ctorGetSession(tr_ctor const* ctor)

View File

@ -163,46 +163,46 @@ void* tr_torrentGetMetadataPiece(tr_torrent* tor, int piece, size_t* len)
TR_ASSERT(piece >= 0); TR_ASSERT(piece >= 0);
TR_ASSERT(len != nullptr); TR_ASSERT(len != nullptr);
char* ret = nullptr; if (!tor->hasMetadata())
if (tor->hasMetadata())
{ {
ensureInfoDictOffsetIsCached(tor); return nullptr;
}
auto const info_dict_length = tor->infoDictLength(); auto const fd = tr_sys_file_open(tor->torrentFile(), TR_SYS_FILE_READ, 0, nullptr);
TR_ASSERT(info_dict_length > 0); if (fd == TR_BAD_SYS_FILE)
{
return nullptr;
}
auto const fd = tr_sys_file_open(tor->torrentFile(), TR_SYS_FILE_READ, 0, nullptr); ensureInfoDictOffsetIsCached(tor);
if (fd != TR_BAD_SYS_FILE)
auto const info_dict_length = tor->infoDictLength();
TR_ASSERT(info_dict_length > 0);
char* ret = nullptr;
if (size_t o = piece * METADATA_PIECE_SIZE; tr_sys_file_seek(fd, tor->infoDictOffset + o, TR_SEEK_SET, nullptr, nullptr))
{
size_t const l = o + METADATA_PIECE_SIZE <= info_dict_length ? METADATA_PIECE_SIZE : info_dict_length - o;
if (0 < l && l <= METADATA_PIECE_SIZE)
{ {
size_t const o = piece * METADATA_PIECE_SIZE; char* buf = tr_new(char, l);
auto n = uint64_t{};
if (tr_sys_file_seek(fd, tor->infoDictOffset + o, TR_SEEK_SET, nullptr, nullptr)) if (tr_sys_file_read(fd, buf, l, &n, nullptr) && n == l)
{ {
size_t const l = o + METADATA_PIECE_SIZE <= info_dict_length ? METADATA_PIECE_SIZE : info_dict_length - o; *len = l;
ret = buf;
if (0 < l && l <= METADATA_PIECE_SIZE) buf = nullptr;
{
char* buf = tr_new(char, l);
auto n = uint64_t{};
if (tr_sys_file_read(fd, buf, l, &n, nullptr) && n == l)
{
*len = l;
ret = buf;
buf = nullptr;
}
tr_free(buf);
}
} }
tr_sys_file_close(fd, nullptr); tr_free(buf);
} }
} }
TR_ASSERT(ret == nullptr || *len > 0); tr_sys_file_close(fd, nullptr);
TR_ASSERT(ret == nullptr || *len > 0);
return ret; return ret;
} }

View File

@ -24,11 +24,6 @@ struct tr_info;
struct tr_torrent_metainfo : public tr_magnet_metainfo struct tr_torrent_metainfo : public tr_magnet_metainfo
{ {
[[nodiscard]] constexpr auto const& blockInfo() const
{
return block_info_;
}
public: public:
tr_torrent_metainfo() = default; tr_torrent_metainfo() = default;
~tr_torrent_metainfo() override = default; ~tr_torrent_metainfo() override = default;
@ -48,6 +43,11 @@ public:
/// BLOCK INFO /// BLOCK INFO
[[nodiscard]] constexpr auto const& blockInfo() const
{
return block_info_;
}
[[nodiscard]] constexpr auto blockCount() const [[nodiscard]] constexpr auto blockCount() const
{ {
return blockInfo().blockCount(); return blockInfo().blockCount();
@ -114,9 +114,17 @@ public:
return source_; return source_;
} }
auto const& files() const auto fileCount() const
{ {
return files_; return std::size(files_);
}
std::string const& fileSubpath(tr_file_index_t i) const
{
return files_.at(i).path();
}
auto fileSize(tr_file_index_t i) const
{
return files_.at(i).size();
} }
[[nodiscard]] auto const& isPrivate() const [[nodiscard]] auto const& isPrivate() const
@ -124,7 +132,7 @@ public:
return is_private_; return is_private_;
} }
[[nodiscard]] auto const& parsedTorrentFile() const [[nodiscard]] auto const& torrentFile() const
{ {
return torrent_file_; return torrent_file_;
} }
@ -165,20 +173,20 @@ private:
{ {
return path_; return path_;
} }
uint64_t length() const uint64_t size() const
{ {
return length_; return size_;
} }
file_t(std::string_view path, uint64_t length) file_t(std::string_view path, uint64_t size)
: path_{ path } : path_{ path }
, length_{ length } , size_{ size }
{ {
} }
private: private:
std::string path_; std::string path_;
uint64_t length_ = 0; uint64_t size_ = 0;
}; };
tr_block_info block_info_ = tr_block_info{ 0, 0 }; tr_block_info block_info_ = tr_block_info{ 0, 0 };

View File

@ -1109,18 +1109,18 @@ tr_file_view tr_torrentFile(tr_torrent const* tor, tr_file_index_t i)
{ {
TR_ASSERT(tr_isTorrent(tor)); TR_ASSERT(tr_isTorrent(tor));
auto const* subpath = tor->fileSubpath(i); auto const& subpath = tor->fileSubpath(i);
auto const priority = tor->file_priorities_.filePriority(i); auto const priority = tor->file_priorities_.filePriority(i);
auto const wanted = tor->files_wanted_.fileWanted(i); auto const wanted = tor->files_wanted_.fileWanted(i);
auto const length = tor->fileSize(i); auto const length = tor->fileSize(i);
if (tor->completeness == TR_SEED || length == 0) if (tor->completeness == TR_SEED || length == 0)
{ {
return { subpath, length, length, 1.0, priority, wanted }; return { subpath.c_str(), length, length, 1.0, priority, wanted };
} }
auto const have = tor->completion.countHasBytesInSpan(tor->fpm_.byteSpan(i)); auto const have = tor->completion.countHasBytesInSpan(tor->fpm_.byteSpan(i));
return { subpath, have, length, have >= length ? 1.0 : have / double(length), priority, wanted }; return { subpath.c_str(), have, length, have >= length ? 1.0 : have / double(length), priority, wanted };
} }
size_t tr_torrentFileCount(tr_torrent const* torrent) size_t tr_torrentFileCount(tr_torrent const* torrent)
@ -2513,7 +2513,7 @@ static void tr_torrentFileCompleted(tr_torrent* tor, tr_file_index_t i)
char* sub = nullptr; char* sub = nullptr;
if (tr_torrentFindFile2(tor, i, &base, &sub, nullptr)) if (tr_torrentFindFile2(tor, i, &base, &sub, nullptr))
{ {
if (char const* file_subpath = tor->fileSubpath(i); strcmp(sub, file_subpath) != 0) if (auto const& file_subpath = tor->fileSubpath(i); file_subpath != sub)
{ {
auto const oldpath = tr_strvPath(base, sub); auto const oldpath = tr_strvPath(base, sub);
auto const newpath = tr_strvPath(base, file_subpath); auto const newpath = tr_strvPath(base, file_subpath);
@ -2858,26 +2858,21 @@ static bool renameArgsAreValid(char const* oldpath, char const* newname)
strchr(newname, TR_PATH_DELIMITER) == nullptr; strchr(newname, TR_PATH_DELIMITER) == nullptr;
} }
static tr_file_index_t* renameFindAffectedFiles(tr_torrent* tor, char const* oldpath, size_t* setme_n) static auto renameFindAffectedFiles(tr_torrent* tor, std::string_view oldpath)
{ {
auto indices = std::vector<tr_file_index_t>{};
auto oldpath_as_dir = tr_strvJoin(oldpath, "/"sv);
auto const n_files = tor->fileCount(); auto const n_files = tor->fileCount();
auto n_affected_files = size_t{};
auto* const indices = tr_new0(tr_file_index_t, n_files);
auto const oldpath_len = strlen(oldpath);
for (tr_file_index_t i = 0; i < n_files; ++i) for (tr_file_index_t i = 0; i < n_files; ++i)
{ {
char const* name = tor->fileSubpath(i); auto const& name = tor->fileSubpath(i);
size_t const len = strlen(name); if (name == oldpath || tr_strvStartsWith(name, oldpath_as_dir))
if ((len == oldpath_len || (len > oldpath_len && name[oldpath_len] == '/')) && memcmp(oldpath, name, oldpath_len) == 0)
{ {
indices[n_affected_files++] = i; indices.push_back(i);
} }
} }
*setme_n = n_affected_files;
return indices; return indices;
} }
@ -2999,10 +2994,8 @@ static void torrentRenamePath(void* vdata)
} }
else else
{ {
auto n = size_t{}; auto const file_indices = renameFindAffectedFiles(tor, oldpath);
tr_file_index_t* const file_indices = renameFindAffectedFiles(tor, oldpath, &n); if (std::empty(file_indices))
if (n == 0)
{ {
error = EINVAL; error = EINVAL;
} }
@ -3013,13 +3006,13 @@ static void torrentRenamePath(void* vdata)
if (error == 0) if (error == 0)
{ {
/* update tr_info.files */ /* update tr_info.files */
for (size_t i = 0; i < n; ++i) for (auto const& file_index : file_indices)
{ {
renameTorrentFileString(tor, oldpath, newname, file_indices[i]); renameTorrentFileString(tor, oldpath, newname, file_index);
} }
/* update tr_info.name if user changed the toplevel */ /* update tr_info.name if user changed the toplevel */
if (n == tor->fileCount() && strchr(oldpath, '/') == nullptr) if (std::size(file_indices) == tor->fileCount() && strchr(oldpath, '/') == nullptr)
{ {
tor->setName(newname); tor->setName(newname);
} }
@ -3028,8 +3021,6 @@ static void torrentRenamePath(void* vdata)
tor->setDirty(); tor->setDirty();
} }
} }
tr_free(file_indices);
} }
/*** /***
@ -3134,10 +3125,5 @@ void tr_torrent::setName(std::string_view name)
void tr_torrent::setFileSubpath(tr_file_index_t i, std::string_view subpath) void tr_torrent::setFileSubpath(tr_file_index_t i, std::string_view subpath)
{ {
if (fileSubpath(i) != subpath) this->info.files[i].subpath = subpath;
{
auto* old = this->info.files[i].name;
this->info.files[i].name = tr_strvDup(subpath);
tr_free(old);
}
} }

View File

@ -372,21 +372,17 @@ public:
[[nodiscard]] tr_file_index_t fileCount() const [[nodiscard]] tr_file_index_t fileCount() const
{ {
return info.fileCount; return std::size(info.files);
} }
[[nodiscard]] char const* fileSubpath(tr_file_index_t i) const [[nodiscard]] std::string const& fileSubpath(tr_file_index_t i) const
{ {
TR_ASSERT(i < this->fileCount()); return info.fileSubpath(i);
return info.files[i].name ? info.files[i].name : "";
} }
[[nodiscard]] auto fileSize(tr_file_index_t i) const [[nodiscard]] auto fileSize(tr_file_index_t i) const
{ {
TR_ASSERT(i < this->fileCount()); return info.fileSize(i);
return info.files[i].length;
} }
void setFileSubpath(tr_file_index_t i, std::string_view subpath); void setFileSubpath(tr_file_index_t i, std::string_view subpath);

View File

@ -1502,8 +1502,8 @@ void tr_torrentVerify(tr_torrent* torrent, tr_verify_done_func callback_func_or_
struct tr_file struct tr_file
{ {
// public // public
char* name; /* Path to the file */ std::string subpath; /* Path to the file */
uint64_t length; /* Length of the file, in bytes */ uint64_t size; /* Length of the file, in bytes */
}; };
/** @brief information about a torrent that comes from its metainfo file */ /** @brief information about a torrent that comes from its metainfo file */
@ -1528,7 +1528,22 @@ struct tr_info
// Private. // Private.
// Use tr_torrentFile() and tr_torrentFileCount() instead. // Use tr_torrentFile() and tr_torrentFileCount() instead.
tr_file* files; std::vector<tr_file> files;
tr_file_index_t fileCount() const
{
return std::size(files);
}
std::string const& fileSubpath(tr_file_index_t i) const
{
return files[i].subpath;
}
auto fileSize(tr_file_index_t i) const
{
return files[i].size;
}
// TODO(ckerr) aggregate this directly, rather than using a shared_ptr, when tr_info is private // TODO(ckerr) aggregate this directly, rather than using a shared_ptr, when tr_info is private
std::shared_ptr<tr_announce_list> announce_list; std::shared_ptr<tr_announce_list> announce_list;
@ -1537,7 +1552,6 @@ struct tr_info
time_t dateCreated; time_t dateCreated;
unsigned int webseedCount; unsigned int webseedCount;
tr_file_index_t fileCount;
uint32_t pieceSize; uint32_t pieceSize;
tr_piece_index_t pieceCount; tr_piece_index_t pieceCount;

View File

@ -1102,7 +1102,7 @@ static void removeKeRangerRansomware()
} }
//determine to show the options window //determine to show the options window
auto const is_multifile = std::size(metainfo.files()) > 1; auto const is_multifile = metainfo.fileCount() > 1;
BOOL const showWindow = type == ADD_SHOW_OPTIONS || BOOL const showWindow = type == ADD_SHOW_OPTIONS ||
([fDefaults boolForKey:@"DownloadAsk"] && (is_multifile || ![fDefaults boolForKey:@"DownloadAskMulti"]) && ([fDefaults boolForKey:@"DownloadAsk"] && (is_multifile || ![fDefaults boolForKey:@"DownloadAskMulti"]) &&
(type != ADD_AUTO || ![fDefaults boolForKey:@"DownloadAskManual"])); (type != ADD_AUTO || ![fDefaults boolForKey:@"DownloadAskManual"]));

View File

@ -100,7 +100,7 @@
size += metainfo.totalSize(); size += metainfo.totalSize();
auto const n_files = std::size(metainfo.files()); auto const n_files = metainfo.fileCount();
fileCount += n_files; fileCount += n_files;
if (n_files == 1) if (n_files == 1)
{ {

View File

@ -69,7 +69,7 @@ OSStatus GeneratePreviewForURL(void* thisInterface, QLPreviewRequestRef preview,
NSString* name = [NSString stringWithUTF8String:metainfo.name().c_str()]; NSString* name = [NSString stringWithUTF8String:metainfo.name().c_str()];
auto const n_files = std::size(metainfo.files()); auto const n_files = metainfo.fileCount();
auto const is_multifile = n_files > 1; auto const is_multifile = n_files > 1;
NSString* fileTypeString = is_multifile ? NSFileTypeForHFSTypeCode(kGenericFolderIcon) : [name pathExtension]; NSString* fileTypeString = is_multifile ? NSFileTypeForHFSTypeCode(kGenericFolderIcon) : [name pathExtension];
@ -190,9 +190,9 @@ OSStatus GeneratePreviewForURL(void* thisInterface, QLPreviewRequestRef preview,
#warning display size? #warning display size?
#warning display folders? #warning display folders?
for (auto const& file : metainfo.files()) for (tr_file_index_t i = 0; i < n_files; ++i)
{ {
NSString* fullFilePath = [NSString stringWithUTF8String:file.path().c_str()]; NSString* fullFilePath = [NSString stringWithUTF8String:metainfo.fileSubpath(i).c_str()];
NSCAssert([fullFilePath hasPrefix:[name stringByAppendingString:@"/"]], @"Expected file path %@ to begin with %@/", fullFilePath, name); NSCAssert([fullFilePath hasPrefix:[name stringByAppendingString:@"/"]], @"Expected file path %@ to begin with %@/", fullFilePath, name);
NSString* shortenedFilePath = [fullFilePath substringFromIndex:[name length] + 1]; NSString* shortenedFilePath = [fullFilePath substringFromIndex:[name length] + 1];

View File

@ -172,30 +172,27 @@ void OptionsDialog::reload()
metainfo_ = metainfo; metainfo_ = metainfo;
} }
bool const have_files_to_show = metainfo_ && !std::empty(metainfo_->files()); bool const have_files_to_show = metainfo_ && !std::empty(*metainfo_);
ui_.filesView->setVisible(have_files_to_show); ui_.filesView->setVisible(have_files_to_show);
layout()->setSizeConstraint(have_files_to_show ? QLayout::SetDefaultConstraint : QLayout::SetFixedSize); layout()->setSizeConstraint(have_files_to_show ? QLayout::SetDefaultConstraint : QLayout::SetFixedSize);
if (metainfo_) if (metainfo_)
{ {
int i = 0; auto const n_files = metainfo_->fileCount();
auto const n_files = std::size(metainfo_->files());
priorities_.assign(n_files, TR_PRI_NORMAL); priorities_.assign(n_files, TR_PRI_NORMAL);
wanted_.assign(n_files, true); wanted_.assign(n_files, true);
for (auto const& file : metainfo_->files()) for (tr_file_index_t i = 0; i < n_files; ++i)
{ {
auto f = TorrentFile{}; auto f = TorrentFile{};
f.index = i; f.index = i;
f.priority = priorities_[i]; f.priority = priorities_[i];
f.wanted = wanted_[i]; f.wanted = wanted_[i];
f.size = file.length(); f.size = metainfo_->fileSize(i);
f.have = 0; f.have = 0;
f.filename = QString::fromStdString(file.path()); f.filename = QString::fromStdString(metainfo_->fileSubpath(i));
files_.push_back(f); files_.push_back(f);
++i;
} }
} }

View File

@ -388,7 +388,7 @@ TEST_F(AnnounceListTest, save)
// test that non-announce parts of the metainfo are the same // test that non-announce parts of the metainfo are the same
EXPECT_STREQ(original->info.name, saved->info.name); EXPECT_STREQ(original->info.name, saved->info.name);
EXPECT_EQ(original->info.fileCount, saved->info.fileCount); EXPECT_EQ(original->info.fileCount(), saved->info.fileCount());
EXPECT_EQ(original->info.dateCreated, saved->info.dateCreated); EXPECT_EQ(original->info.dateCreated, saved->info.dateCreated);
EXPECT_EQ(original->pieces, saved->pieces); EXPECT_EQ(original->pieces, saved->pieces);

View File

@ -79,7 +79,7 @@ protected:
EXPECT_EQ(payloadSize, metainfo.totalSize()); EXPECT_EQ(payloadSize, metainfo.totalSize());
EXPECT_EQ(makeString(tr_sys_path_basename(input_file.data(), nullptr)), metainfo.name()); EXPECT_EQ(makeString(tr_sys_path_basename(input_file.data(), nullptr)), metainfo.name());
EXPECT_EQ(comment, metainfo.comment()); EXPECT_EQ(comment, metainfo.comment());
EXPECT_EQ(tr_file_index_t{ 1 }, std::size(metainfo.files())); EXPECT_EQ(tr_file_index_t{ 1 }, metainfo.fileCount());
EXPECT_EQ(isPrivate, metainfo.isPrivate()); EXPECT_EQ(isPrivate, metainfo.isPrivate());
EXPECT_EQ(size_t(trackerCount), std::size(metainfo.announceList())); EXPECT_EQ(size_t(trackerCount), std::size(metainfo.announceList()));
@ -160,7 +160,7 @@ protected:
tr_free(tmpstr); tr_free(tmpstr);
EXPECT_EQ(comment, metainfo.comment()); EXPECT_EQ(comment, metainfo.comment());
EXPECT_EQ(source, metainfo.source()); EXPECT_EQ(source, metainfo.source());
EXPECT_EQ(payload_count, std::size(metainfo.files())); EXPECT_EQ(payload_count, metainfo.fileCount());
EXPECT_EQ(is_private, metainfo.isPrivate()); EXPECT_EQ(is_private, metainfo.isPrivate());
EXPECT_EQ(size_t(tracker_count), std::size(metainfo.announceList())); EXPECT_EQ(size_t(tracker_count), std::size(metainfo.announceList()));

View File

@ -22,6 +22,8 @@
#include <cstring> // strcmp() #include <cstring> // strcmp()
#include <string> #include <string>
using namespace std::literals;
namespace libtransmission namespace libtransmission
{ {
@ -262,7 +264,7 @@ TEST_F(RenameTest, multifileTorrent)
"MjpwaWVjZSBsZW5ndGhpMzI3NjhlNjpwaWVjZXMyMDp27buFkmy8ICfNX4nsJmt0Ckm2Ljc6cHJp" "MjpwaWVjZSBsZW5ndGhpMzI3NjhlNjpwaWVjZXMyMDp27buFkmy8ICfNX4nsJmt0Ckm2Ljc6cHJp"
"dmF0ZWkwZWVl"); "dmF0ZWkwZWVl");
EXPECT_TRUE(tr_isTorrent(tor)); EXPECT_TRUE(tr_isTorrent(tor));
auto* files = tor->info.files; auto& files = tor->info.files;
// sanity check the info // sanity check the info
EXPECT_STREQ("Felidae", tr_torrentName(tor)); EXPECT_STREQ("Felidae", tr_torrentName(tor));
@ -318,8 +320,7 @@ TEST_F(RenameTest, multifileTorrent)
// (while the branch is renamed: confirm that the .resume file remembers the changes) // (while the branch is renamed: confirm that the .resume file remembers the changes)
tr_torrentSaveResume(tor); tr_torrentSaveResume(tor);
// this is a bit dodgy code-wise, but let's make sure the .resume file got the name // this is a bit dodgy code-wise, but let's make sure the .resume file got the name
tr_free(files[1].name); files[1].subpath = "gabba gabba hey";
files[1].name = tr_strdup("gabba gabba hey");
auto const loaded = tr_torrentLoadResume(tor, ~0ULL, ctor, nullptr); auto const loaded = tr_torrentLoadResume(tor, ~0ULL, ctor, nullptr);
EXPECT_NE(decltype(loaded){ 0 }, (loaded & TR_FR_FILENAMES)); EXPECT_NE(decltype(loaded){ 0 }, (loaded & TR_FR_FILENAMES));
EXPECT_EQ(expected_files[0], tr_torrentFile(tor, 0).name); EXPECT_EQ(expected_files[0], tr_torrentFile(tor, 0).name);
@ -461,13 +462,12 @@ TEST_F(RenameTest, partialFile)
***/ ***/
auto* tor = zeroTorrentInit(); auto* tor = zeroTorrentInit();
auto const& files = tor->info.files;
EXPECT_EQ(TotalSize, tor->totalSize()); EXPECT_EQ(TotalSize, tor->totalSize());
EXPECT_EQ(PieceSize, tor->pieceSize()); EXPECT_EQ(PieceSize, tor->pieceSize());
EXPECT_EQ(PieceCount, tor->pieceCount()); EXPECT_EQ(PieceCount, tor->pieceCount());
EXPECT_STREQ("files-filled-with-zeroes/1048576", files[0].name); EXPECT_EQ("files-filled-with-zeroes/1048576"sv, tor->fileSubpath(0));
EXPECT_STREQ("files-filled-with-zeroes/4096", files[1].name); EXPECT_EQ("files-filled-with-zeroes/4096"sv, tor->fileSubpath(1));
EXPECT_STREQ("files-filled-with-zeroes/512", files[2].name); EXPECT_EQ("files-filled-with-zeroes/512"sv, tor->fileSubpath(2));
zeroTorrentPopulate(tor, false); zeroTorrentPopulate(tor, false);
EXPECT_EQ(Length[0], tr_torrentFile(tor, 0).have + PieceSize); EXPECT_EQ(Length[0], tr_torrentFile(tor, 0).have + PieceSize);
@ -483,14 +483,14 @@ TEST_F(RenameTest, partialFile)
EXPECT_EQ(0, torrentRenameAndWait(tor, "files-filled-with-zeroes", "foo")); EXPECT_EQ(0, torrentRenameAndWait(tor, "files-filled-with-zeroes", "foo"));
EXPECT_EQ(0, torrentRenameAndWait(tor, "foo/1048576", "bar")); EXPECT_EQ(0, torrentRenameAndWait(tor, "foo/1048576", "bar"));
auto strings = std::array<char const*, 3>{}; auto strings = std::array<std::string_view, 3>{};
strings[0] = "foo/bar"; strings[0] = "foo/bar"sv;
strings[1] = "foo/4096"; strings[1] = "foo/4096"sv;
strings[2] = "foo/512"; strings[2] = "foo/512"sv;
for (tr_file_index_t i = 0; i < 3; ++i) for (tr_file_index_t i = 0; i < 3; ++i)
{ {
EXPECT_STREQ(strings[i], files[i].name); EXPECT_EQ(strings[i], tor->fileSubpath(i));
} }
strings[0] = "foo/bar.part"; strings[0] = "foo/bar.part";

View File

@ -43,7 +43,7 @@ TEST_F(TorrentMetainfoTest, magnetLink)
auto metainfo = tr_torrent_metainfo{}; auto metainfo = tr_torrent_metainfo{};
EXPECT_TRUE(metainfo.parseMagnet(MagnetLink)); EXPECT_TRUE(metainfo.parseMagnet(MagnetLink));
EXPECT_EQ(0, std::size(metainfo.files())); // because it's a magnet link EXPECT_EQ(0, metainfo.fileCount()); // because it's a magnet link
EXPECT_EQ(2, std::size(metainfo.announceList())); EXPECT_EQ(2, std::size(metainfo.announceList()));
EXPECT_EQ(MagnetLink, metainfo.magnet()); EXPECT_EQ(MagnetLink, metainfo.magnet());
} }

View File

@ -177,11 +177,11 @@ void showInfo(app_opts const& opts, tr_torrent_metainfo const& metainfo)
printf("\nFILES\n\n"); printf("\nFILES\n\n");
auto filenames = std::vector<std::string>{}; auto filenames = std::vector<std::string>{};
for (auto const& file : metainfo.files()) for (tr_file_index_t i = 0, n = metainfo.fileCount(); i < n; ++i)
{ {
std::string filename = file.path(); std::string filename = metainfo.fileSubpath(i);
filename += " ("; filename += " (";
filename += tr_formatter_size_B(file.length()); filename += tr_formatter_size_B(metainfo.fileSize(i));
filename += ')'; filename += ')';
filenames.emplace_back(filename); filenames.emplace_back(filename);
} }