refactor: use std::vector in tr_info (#2386)

This commit is contained in:
Charles Kerr 2022-01-09 10:55:09 -06:00 committed by GitHub
parent 7068eb66c1
commit dfc06fe918
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 109 additions and 111 deletions

View File

@ -16,7 +16,7 @@
#include "transmission.h"
#include "quark.h"
#include "interned-string.h"
struct tr_announcer;
struct tr_announcer_tiers;

View File

@ -59,7 +59,7 @@ void tr_file_piece_map::reset(tr_info const& info)
{
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));
}
tr_file_piece_map::piece_span_t tr_file_piece_map::pieceSpan(tr_file_index_t file) const

View File

@ -239,14 +239,14 @@ void tr_magnet_metainfo::toVariant(tr_variant* top) const
}
// webseeds
n = std::size(this->webseeds());
n = this->webseedCount();
if (n != 0)
{
tr_variant* list = tr_variantDictAddList(top, TR_KEY_url_list, n);
for (auto& url : this->webseeds())
for (size_t i = 0; i < n; ++i)
{
tr_variantListAddStr(list, url);
tr_variantListAddStr(list, this->webseed(i));
}
}

View File

@ -34,9 +34,15 @@ public:
{
return name_;
}
auto const& webseeds() const
auto webseedCount() const
{
return webseed_urls_;
return std::size(webseed_urls_);
}
auto const& webseed(size_t i) const
{
return webseed_urls_[i];
}
auto& announceList()

View File

@ -151,7 +151,7 @@ static bool getfile(std::string* setme, std::string_view root, tr_variant* path,
static char const* parseFiles(tr_info* inf, tr_variant* files, tr_variant const* length)
{
int64_t len = 0;
inf->totalSize = 0;
inf->total_size_ = 0;
auto root_name = std::string{};
if (!tr_metainfoAppendSanitizedPathComponent(root_name, inf->name()))
@ -166,7 +166,6 @@ static char const* parseFiles(tr_info* inf, tr_variant* files, tr_variant const*
auto buf = std::string{};
errstr = nullptr;
inf->isFolder = true;
tr_file_index_t const n = tr_variantListSize(files);
inf->files.resize(n);
for (tr_file_index_t i = 0; i < n; ++i)
@ -199,16 +198,15 @@ static char const* parseFiles(tr_info* inf, tr_variant* files, tr_variant const*
}
inf->files[i].size_ = len;
inf->totalSize += len;
inf->total_size_ += len;
}
}
else if (tr_variantGetInt(length, &len)) /* single-file mode */
{
inf->isFolder = false;
inf->files.resize(1);
inf->files[0].subpath_ = root_name;
inf->files[0].size_ = len;
inf->totalSize += len;
inf->total_size_ += len;
}
else
{
@ -289,24 +287,22 @@ static char* fix_webseed_url(tr_info const* inf, std::string_view url)
static void geturllist(tr_info* inf, tr_variant* meta)
{
tr_variant* urls = nullptr;
auto url = std::string_view{};
inf->webseeds_.clear();
auto url = std::string_view{};
tr_variant* urls = nullptr;
if (tr_variantDictFindList(meta, TR_KEY_url_list, &urls))
{
int const n = tr_variantListSize(urls);
inf->webseedCount = 0;
inf->webseeds = tr_new0(char*, n);
for (int i = 0; i < n; i++)
for (int i = 0; i < n; ++i)
{
if (tr_variantGetStrView(tr_variantListChild(urls, i), &url))
{
char* const fixed_url = fix_webseed_url(inf, url);
if (fixed_url != nullptr)
{
inf->webseeds[inf->webseedCount++] = fixed_url;
inf->webseeds_.emplace_back(fixed_url);
}
}
}
@ -316,9 +312,7 @@ static void geturllist(tr_info* inf, tr_variant* meta)
char* const fixed_url = fix_webseed_url(inf, url);
if (fixed_url != nullptr)
{
inf->webseedCount = 1;
inf->webseeds = tr_new0(char*, 1);
inf->webseeds[0] = fixed_url;
inf->webseeds_.emplace_back(fixed_url);
}
}
}
@ -432,7 +426,7 @@ static char const* tr_metainfoParseImpl(
i = 0;
}
inf->isPrivate = i != 0;
inf->is_private_ = i != 0;
/* source */
if (!tr_variantDictFindStrView(infoDict, TR_KEY_source, &sv) && !tr_variantDictFindStrView(meta, TR_KEY_source, &sv))
@ -450,7 +444,7 @@ static char const* tr_metainfoParseImpl(
return "piece length";
}
inf->pieceSize = i;
inf->piece_size_ = i;
}
/* pieces and files */
@ -467,7 +461,7 @@ static char const* tr_metainfoParseImpl(
}
auto const n_pieces = std::size(sv) / std::size(tr_sha1_digest_t{});
inf->pieceCount = n_pieces;
inf->piece_count_ = n_pieces;
pieces->resize(n_pieces);
std::copy_n(std::data(sv), std::size(sv), reinterpret_cast<uint8_t*>(std::data(*pieces)));
@ -480,12 +474,12 @@ static char const* tr_metainfoParseImpl(
return errstr;
}
if (inf->fileCount() == 0 || inf->totalSize == 0)
if (inf->fileCount() == 0 || inf->total_size_ == 0)
{
return "files";
}
if ((uint64_t)inf->pieceCount != (inf->totalSize + inf->pieceSize - 1) / inf->pieceSize)
if ((uint64_t)inf->piece_count_ != (inf->total_size_ + inf->piece_size_ - 1) / inf->piece_size_)
{
return "files";
}
@ -524,17 +518,6 @@ std::optional<tr_metainfo_parsed> tr_metainfoParse(tr_session const* session, tr
void tr_metainfoFree(tr_info* inf)
{
if (inf->webseeds != nullptr)
{
for (unsigned int i = 0; i < inf->webseedCount; i++)
{
tr_free(inf->webseeds[i]);
}
}
tr_free(inf->webseeds);
inf->webseeds = nullptr;
inf->webseeds_.clear();
inf->announce_list.reset();
}

View File

@ -13,9 +13,10 @@
#endif
#include "transmission.h"
#include "bitfield.h"
#include "history.h"
#include "quark.h"
#include "interned-string.h"
/**
* @addtogroup peers Peers

View File

@ -302,7 +302,7 @@ void tr_torrentSetMetadataPiece(tr_torrent* tor, int piece, void const* data, in
auto info = tr_metainfoParse(tor->session, &newMetainfo, nullptr);
success = !!info;
if (info && tr_block_info::bestBlockSize(info->info.pieceSize) == 0)
if (info && tr_block_info::bestBlockSize(info->info.pieceSize()) == 0)
{
tor->setLocalError(_("Magnet torrent's metadata is not usable"));
success = false;
@ -409,10 +409,10 @@ char* tr_torrentInfoGetMagnetLink(tr_info const* inf)
tr_http_escape(buf, inf->announce_list->at(i).announce.full, true);
}
for (unsigned int i = 0; i < inf->webseedCount; i++)
for (size_t i = 0, n = inf->webseedCount(); i < n; ++i)
{
buf += "&ws="sv;
tr_http_escape(buf, inf->webseeds[i], true);
tr_http_escape(buf, inf->webseed(i), true);
}
return tr_strvDup(buf);

View File

@ -561,7 +561,7 @@ static void tr_torrentFireMetadataCompleted(tr_torrent* tor);
static void torrentInitFromInfoDict(tr_torrent* tor)
{
tor->block_info.initSizes(tor->info.totalSize, tor->info.pieceSize);
tor->block_info.initSizes(tor->info.totalSize(), tor->info.pieceSize());
tor->completion = tr_completion{ tor, &tor->block_info };
auto const obfuscated = tr_sha1("req2"sv, tor->infoHash());
if (obfuscated)

View File

@ -109,7 +109,7 @@ struct tr_torrent : public tr_completion::torrent_view
{
public:
explicit tr_torrent(tr_info const& inf)
: block_info{ inf.totalSize, inf.pieceSize }
: block_info{ inf.totalSize(), inf.pieceSize() }
, completion{ this, &this->block_info }
{
}
@ -435,14 +435,12 @@ public:
[[nodiscard]] auto webseedCount() const
{
return info.webseedCount;
return info.webseedCount();
}
[[nodiscard]] auto const& webseed(size_t i) const
{
TR_ASSERT(i < webseedCount());
return info.webseeds[i];
return info.webseed(i);
}
/// METAINFO - OTHER
@ -461,7 +459,7 @@ public:
[[nodiscard]] auto isPrivate() const
{
return this->info.isPrivate;
return this->info.isPrivate();
}
[[nodiscard]] auto isPublic() const

View File

@ -21,7 +21,9 @@
***/
#include <memory>
#include <string>
#include <string_view>
#include <vector>
#include <stdbool.h> /* bool */
#include <stddef.h> /* size_t */
@ -40,8 +42,6 @@ using tr_tracker_tier_t = uint32_t;
using tr_tracker_id_t = uint32_t;
using tr_byte_index_t = uint64_t;
#include "announce-list.h"
struct tr_block_span_t
{
tr_block_index_t begin;
@ -54,6 +54,8 @@ struct tr_byte_span_t
uint64_t end;
};
class tr_announce_list;
struct tr_ctor;
struct tr_error;
struct tr_info;
@ -1511,26 +1513,34 @@ struct tr_file
/** @brief information about a torrent that comes from its metainfo file */
struct tr_info
{
/* total size of the torrent, in bytes */
uint64_t totalSize;
/* The torrent's name. */
std::string name_;
/* Path to torrent Transmission's internal copy of the .torrent file. */
std::string torrent_file_;
char** webseeds;
std::string comment_;
std::string creator_;
/* torrent's source. empty if not set. */
std::string source_;
auto const& torrentFile() const
auto totalSize() const
{
return torrent_file_;
return total_size_;
}
auto pieceSize() const
{
return piece_size_;
}
auto pieceCount() const
{
return piece_count_;
}
auto dateCreated() const
{
return date_created_;
}
auto const& infoHash() const
{
return hash_;
}
auto const& infoHashString() const
{
return info_hash_string_;
}
auto const& name() const
@ -1538,6 +1548,11 @@ struct tr_info
return name_;
}
void setName(std::string_view name)
{
name_ = name;
}
auto const& creator() const
{
return creator_;
@ -1553,25 +1568,21 @@ struct tr_info
return source_;
}
auto const& infoHash() const
auto const& torrentFile() const
{
return hash_;
return torrent_file_;
}
void setName(std::string_view name)
{
name_ = name;
}
// Private.
// Use tr_torrentFile() and tr_torrentFileCount() instead.
std::vector<tr_file> files;
tr_file_index_t fileCount() const
{
return std::size(files);
}
auto fileSize(tr_file_index_t i) const
{
return files[i].size_;
}
std::string const& fileSubpath(tr_file_index_t i) const
{
return files[i].subpath_;
@ -1582,38 +1593,36 @@ struct tr_info
files[i].subpath_ = subpath;
}
auto fileSize(tr_file_index_t i) const
auto webseedCount() const
{
return files[i].size_;
return std::size(webseeds_);
}
auto const& infoHashString() const
auto const& webseed(size_t i) const
{
return info_hash_string_;
return webseeds_[i];
}
auto dateCreated() const
auto isPrivate() const
{
return date_created_;
return 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;
/* Torrent info */
time_t date_created_;
unsigned int webseedCount;
uint32_t pieceSize;
tr_piece_index_t pieceCount;
/* General info */
tr_sha1_digest_t hash_;
std::shared_ptr<tr_announce_list> announce_list;
std::vector<tr_file> files;
std::vector<std::string> webseeds_;
std::string comment_;
std::string creator_;
std::string info_hash_string_;
/* Flags */
bool isPrivate;
bool isFolder;
std::string name_;
std::string source_;
std::string torrent_file_;
uint64_t total_size_ = 0;
tr_piece_index_t piece_count_ = 0;
time_t date_created_ = 0;
uint32_t piece_size_ = 0;
bool is_private_ = false;
};
bool tr_torrentHasMetadata(tr_torrent const* tor);

View File

@ -133,7 +133,7 @@ OSStatus GeneratePreviewForURL(void* thisInterface, QLPreviewRequestRef preview,
NSMutableArray* lists = [NSMutableArray array];
auto const n_webseeds = std::size(metainfo.webseeds());
auto const n_webseeds = metainfo.webseedCount();
if (n_webseeds > 0)
{
NSMutableString* listSection = [NSMutableString string];
@ -145,9 +145,9 @@ OSStatus GeneratePreviewForURL(void* thisInterface, QLPreviewRequestRef preview,
[NSString formattedUInteger:n_webseeds]];
[listSection appendFormat:@"<tr><th>%@</th></tr>", headerTitleString];
for (auto const& url : metainfo.webseeds())
for (size_t i = 0; i < n_webseeds; ++i)
{
[listSection appendFormat:@"<tr><td>%s<td></tr>", url.c_str()];
[listSection appendFormat:@"<tr><td>%s<td></tr>", metainfo.webseed(i).c_str()];
}
[listSection appendString:@"</table>"];

View File

@ -55,8 +55,8 @@ TEST(MagnetMetainfo, magnetParse)
EXPECT_EQ(1, it->tier);
EXPECT_EQ("http://tracker.opentracker.org/announce", it->announce.full);
EXPECT_EQ("http://tracker.opentracker.org/scrape", it->scrape.full);
EXPECT_EQ(1, std::size(mm.webseeds()));
EXPECT_EQ("http://server.webseed.org/path/to/file"sv, mm.webseeds().front());
EXPECT_EQ(1, mm.webseedCount());
EXPECT_EQ("http://server.webseed.org/path/to/file"sv, mm.webseed(0));
EXPECT_EQ("Display Name"sv, mm.name());
EXPECT_EQ(ExpectedHash, mm.infoHash());
}

View File

@ -160,13 +160,14 @@ void showInfo(app_opts const& opts, tr_torrent_metainfo const& metainfo)
***
**/
if (auto const& webseeds = metainfo.webseeds(); !std::empty(webseeds))
auto const n_webseeds = metainfo.webseedCount();
if (n_webseeds > 0)
{
printf("\nWEBSEEDS\n\n");
for (auto const& webseed : webseeds)
for (size_t i = 0; i < n_webseeds; ++i)
{
printf(" %s\n", webseed.c_str());
printf(" %s\n", metainfo.webseed(i).c_str());
}
}