mirror of
https://github.com/transmission/transmission
synced 2025-02-22 06:00:41 +00:00
refactor: add tr_interned_string (#2332)
This commit is contained in:
parent
bd68d3a2fd
commit
dd1379b0b6
27 changed files with 343 additions and 226 deletions
|
@ -367,6 +367,7 @@
|
|||
ED8A16422735A8AA000D61F9 /* peer-mgr-wishlist.cc in Sources */ = {isa = PBXBuildFile; fileRef = ED8A163E2735A8AA000D61F9 /* peer-mgr-wishlist.cc */; };
|
||||
EDBDFA9E25AFCCA60093D9C1 /* evutil_time.c in Sources */ = {isa = PBXBuildFile; fileRef = EDBDFA9D25AFCCA60093D9C1 /* evutil_time.c */; };
|
||||
F11545ACA7C4D7A464F703AB /* block-info.h in Headers */ = {isa = PBXBuildFile; fileRef = 6A044CBD8C049AFCBD4DB411 /* block-info.h */; settings = {ATTRIBUTES = (Project, ); }; };
|
||||
E23B55A5FC3B557F7746D510 /* interned-string.h in Headers */ = {isa = PBXBuildFile; fileRef = E23B55A5FC3B557F7746D511 /* interned-string.h */; settings = {ATTRIBUTES = (Project, ); }; };
|
||||
F63480631E1D7274005B9E09 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F63480621E1D7274005B9E09 /* Images.xcassets */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
|
@ -544,6 +545,7 @@
|
|||
4DFBC2DE09C0970D00D5C571 /* Torrent.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = Torrent.mm; sourceTree = "<group>"; };
|
||||
55869925257074EC00F77A43 /* libcurl.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcurl.tbd; path = usr/lib/libcurl.tbd; sourceTree = SDKROOT; };
|
||||
6A044CBD8C049AFCBD4DB411 /* block-info.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "block-info.h"; path = "block-info.h"; sourceTree = SOURCE_ROOT; };
|
||||
E23B55A5FC3B557F7746D511 /* interned-string.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "interned-string.h"; path = "interned-string.h"; sourceTree = SOURCE_ROOT; };
|
||||
8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
8D1107320486CEB800E47090 /* Transmission.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Transmission.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A200B8390A2263BA007BBB1E /* InfoWindowController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InfoWindowController.h; sourceTree = "<group>"; };
|
||||
|
@ -1375,6 +1377,7 @@
|
|||
children = (
|
||||
A54D44C6A7AAF131D9AE29F5 /* block-info.cc */,
|
||||
6A044CBD8C049AFCBD4DB411 /* block-info.h */,
|
||||
E23B55A5FC3B557F7746D511 /* interned-string.h */,
|
||||
C17740D3273A002C00E455D2 /* web-utils.cc */,
|
||||
C17740D4273A002C00E455D2 /* web-utils.h */,
|
||||
CAB35C62252F6F5E00552A55 /* mime-types.h */,
|
||||
|
@ -1897,6 +1900,7 @@
|
|||
A2AF23C916B44FA0003BC59E /* log.h in Headers */,
|
||||
A23FAE55178BC2950053DC5B /* platform-quota.h in Headers */,
|
||||
F11545ACA7C4D7A464F703AB /* block-info.h in Headers */,
|
||||
E23B55A5FC3B557F7746D510 /* interned-string.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
@ -82,20 +82,20 @@ bool tr_announce_list::add(tr_tracker_tier_t tier, std::string_view announce_url
|
|||
}
|
||||
|
||||
auto tracker = tracker_info{};
|
||||
tracker.announce_interned = tr_quark_new(announce_url_sv);
|
||||
tracker.announce = *tr_urlParseTracker(tr_quark_get_string_view(tracker.announce_interned));
|
||||
tracker.announce_str = announce_url_sv;
|
||||
tracker.announce = *tr_urlParseTracker(tracker.announce_str.sv());
|
||||
tracker.tier = getTier(tier, *announce);
|
||||
tracker.id = nextUniqueId();
|
||||
auto host = std::string{ tracker.announce.host };
|
||||
host += ':';
|
||||
host += tracker.announce.portstr;
|
||||
tracker.host = tr_quark_new(host);
|
||||
tracker.host = host;
|
||||
|
||||
auto const scrape_str = announceToScrape(announce_url_sv);
|
||||
if (scrape_str)
|
||||
{
|
||||
tracker.scrape_interned = tr_quark_new(*scrape_str);
|
||||
tracker.scrape = *tr_urlParseTracker(tr_quark_get_string_view(tracker.scrape_interned));
|
||||
tracker.scrape_str = *scrape_str;
|
||||
tracker.scrape = *tr_urlParseTracker(tracker.scrape_str.sv());
|
||||
}
|
||||
|
||||
auto const it = std::lower_bound(std::begin(trackers_), std::end(trackers_), tracker);
|
||||
|
@ -221,7 +221,7 @@ bool tr_announce_list::save(char const* torrent_file, tr_error** error) const
|
|||
// add the new fields
|
||||
if (this->size() == 1)
|
||||
{
|
||||
tr_variantDictAddQuark(&metainfo, TR_KEY_announce, at(0).announce_interned);
|
||||
tr_variantDictAddQuark(&metainfo, TR_KEY_announce, at(0).announce_str.quark());
|
||||
}
|
||||
else if (this->size() > 1)
|
||||
{
|
||||
|
@ -238,7 +238,7 @@ bool tr_announce_list::save(char const* torrent_file, tr_error** error) const
|
|||
current_tier = tracker.tier;
|
||||
}
|
||||
|
||||
tr_variantListAddQuark(tracker_list, tracker.announce_interned);
|
||||
tr_variantListAddQuark(tracker_list, tracker.announce_str.quark());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
#include "transmission.h"
|
||||
|
||||
#include "quark.h"
|
||||
#include "interned-string.h"
|
||||
#include "web-utils.h"
|
||||
|
||||
struct tr_error;
|
||||
|
@ -33,11 +33,11 @@ class tr_announce_list
|
|||
public:
|
||||
struct tracker_info
|
||||
{
|
||||
tr_quark host;
|
||||
tr_url_parsed_t announce;
|
||||
tr_url_parsed_t scrape;
|
||||
tr_quark announce_interned = TR_KEY_NONE;
|
||||
tr_quark scrape_interned = TR_KEY_NONE;
|
||||
tr_interned_string announce_str;
|
||||
tr_interned_string scrape_str;
|
||||
tr_interned_string host;
|
||||
tr_tracker_tier_t tier = 0;
|
||||
tr_tracker_id_t id = 0;
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include "transmission.h"
|
||||
|
||||
#include "quark.h"
|
||||
#include "interned-string.h"
|
||||
#include "web-utils.h"
|
||||
|
||||
/***
|
||||
|
@ -40,7 +40,7 @@ auto inline constexpr TR_MULTISCRAPE_MAX = 60;
|
|||
struct tr_scrape_request
|
||||
{
|
||||
/* the scrape URL */
|
||||
tr_quark scrape_url;
|
||||
tr_interned_string scrape_url;
|
||||
|
||||
/* the name to use when deep logging is enabled */
|
||||
char log_name[128];
|
||||
|
@ -87,7 +87,7 @@ struct tr_scrape_response
|
|||
struct tr_scrape_response_row rows[TR_MULTISCRAPE_MAX];
|
||||
|
||||
/* the raw scrape url */
|
||||
tr_quark scrape_url;
|
||||
tr_interned_string scrape_url;
|
||||
|
||||
/* human-readable error string on failure, or nullptr */
|
||||
std::string errmsg;
|
||||
|
@ -155,7 +155,7 @@ struct tr_announce_request
|
|||
uint64_t leftUntilComplete;
|
||||
|
||||
/* the tracker's announce URL */
|
||||
tr_quark announce_url;
|
||||
tr_interned_string announce_url;
|
||||
|
||||
/* key generated by and returned from an http tracker.
|
||||
* see tr_announce_response.tracker_id_str */
|
||||
|
@ -215,10 +215,10 @@ struct tr_announce_response
|
|||
struct tr_pex* pex6;
|
||||
|
||||
/* human-readable error string on failure, or nullptr */
|
||||
char* errmsg;
|
||||
std::string errmsg;
|
||||
|
||||
/* human-readable warning string or nullptr */
|
||||
char* warning;
|
||||
std::string warning;
|
||||
|
||||
/* key generated by and returned from an http tracker.
|
||||
* if this is provided, subsequent http announces must include this. */
|
||||
|
@ -241,20 +241,4 @@ void tr_tracker_udp_announce(
|
|||
|
||||
void tr_tracker_udp_start_shutdown(tr_session* session);
|
||||
|
||||
tr_quark tr_announcerGetKey(tr_url_parsed_t const& parsed);
|
||||
|
||||
inline tr_quark tr_announcerGetKey(std::string_view url)
|
||||
{
|
||||
auto const parsed = tr_urlParseTracker(url);
|
||||
if (!parsed)
|
||||
{
|
||||
return TR_KEY_NONE;
|
||||
}
|
||||
|
||||
return tr_announcerGetKey(*parsed);
|
||||
}
|
||||
|
||||
inline tr_quark tr_announcerGetKey(tr_quark url)
|
||||
{
|
||||
return tr_announcerGetKey(tr_quark_get_string_view(url));
|
||||
}
|
||||
tr_interned_string tr_announcerGetKey(tr_url_parsed_t const& parsed);
|
||||
|
|
|
@ -43,7 +43,7 @@ static char const* get_event_string(tr_announce_request const* req)
|
|||
|
||||
static char* announce_url_new(tr_session const* session, tr_announce_request const* req)
|
||||
{
|
||||
auto const announce_sv = tr_quark_get_string_view(req->announce_url);
|
||||
auto const announce_sv = req->announce_url.sv();
|
||||
|
||||
char escaped_info_hash[SHA_DIGEST_LENGTH * 3 + 1];
|
||||
tr_http_escape_sha1(escaped_info_hash, req->info_hash);
|
||||
|
@ -190,8 +190,6 @@ static void on_announce_done_eventthread(void* vdata)
|
|||
tr_free(data->response.pex6);
|
||||
tr_free(data->response.pex);
|
||||
tr_free(data->response.tracker_id_str);
|
||||
tr_free(data->response.warning);
|
||||
tr_free(data->response.errmsg);
|
||||
tr_free(data);
|
||||
}
|
||||
|
||||
|
@ -251,12 +249,12 @@ static void on_announce_done(
|
|||
|
||||
if (tr_variantDictFindStrView(&benc, TR_KEY_failure_reason, &sv))
|
||||
{
|
||||
response->errmsg = tr_strvDup(sv);
|
||||
response->errmsg = sv;
|
||||
}
|
||||
|
||||
if (tr_variantDictFindStrView(&benc, TR_KEY_warning_message, &sv))
|
||||
{
|
||||
response->warning = tr_strvDup(sv);
|
||||
response->warning = sv;
|
||||
}
|
||||
|
||||
if (tr_variantDictFindInt(&benc, TR_KEY_interval, &i))
|
||||
|
@ -377,7 +375,7 @@ static void on_scrape_done(
|
|||
response->did_connect = did_connect;
|
||||
response->did_timeout = did_timeout;
|
||||
|
||||
auto const scrape_url_sv = tr_quark_get_string_view(response->scrape_url);
|
||||
auto const scrape_url_sv = response->scrape_url.sv();
|
||||
dbgmsg(data->log_name, "Got scrape response for \"%" TR_PRIsv "\"", TR_PRIsv_ARG(scrape_url_sv));
|
||||
|
||||
if (response_code != HTTP_OK)
|
||||
|
@ -485,12 +483,12 @@ static void on_scrape_done(
|
|||
|
||||
static char* scrape_url_new(tr_scrape_request const* req)
|
||||
{
|
||||
auto const sv = tr_quark_get_string_view(req->scrape_url);
|
||||
auto const sv = req->scrape_url.sv();
|
||||
|
||||
auto* const buf = evbuffer_new();
|
||||
evbuffer_add(buf, std::data(sv), std::size(sv));
|
||||
|
||||
char delimiter = sv.find('?') == sv.npos ? '?' : '&';
|
||||
char delimiter = sv.find('?') == std::string_view::npos ? '?' : '&';
|
||||
for (int i = 0; i < req->info_hash_count; ++i)
|
||||
{
|
||||
char str[SHA_DIGEST_LENGTH * 3 + 1];
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include "tr-udp.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define dbgmsg(key, ...) tr_logAddDeepNamed(tr_quark_get_string(key), __VA_ARGS__)
|
||||
#define dbgmsg(key, ...) tr_logAddDeepNamed(key.c_str(), __VA_ARGS__)
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
|
@ -356,8 +356,6 @@ static struct tau_announce_request* tau_announce_request_new(
|
|||
static void tau_announce_request_free(struct tau_announce_request* req)
|
||||
{
|
||||
tr_free(req->response.tracker_id_str);
|
||||
tr_free(req->response.warning);
|
||||
tr_free(req->response.errmsg);
|
||||
tr_free(req->response.pex6);
|
||||
tr_free(req->response.pex);
|
||||
delete req;
|
||||
|
@ -423,8 +421,8 @@ struct tau_tracker
|
|||
{
|
||||
tr_session* const session;
|
||||
|
||||
tr_quark const key;
|
||||
tr_quark const host;
|
||||
tr_interned_string const key;
|
||||
tr_interned_string const host;
|
||||
int const port;
|
||||
|
||||
struct evdns_getaddrinfo_request* dns_request = nullptr;
|
||||
|
@ -441,7 +439,7 @@ struct tau_tracker
|
|||
tr_ptrArray announces = {};
|
||||
tr_ptrArray scrapes = {};
|
||||
|
||||
tau_tracker(tr_session* session_in, tr_quark key_in, tr_quark host_in, int port_in)
|
||||
tau_tracker(tr_session* session_in, tr_interned_string key_in, tr_interned_string host_in, int port_in)
|
||||
: session{ session_in }
|
||||
, key{ key_in }
|
||||
, host{ host_in }
|
||||
|
@ -687,7 +685,7 @@ static void tau_tracker_upkeep_ex(struct tau_tracker* tracker, bool timeout_reqs
|
|||
dbgmsg(tracker->host, "Trying a new DNS lookup");
|
||||
tracker->dns_request = evdns_getaddrinfo(
|
||||
tracker->session->evdns_base,
|
||||
tr_quark_get_string(tracker->host),
|
||||
tracker->host.c_str(),
|
||||
nullptr,
|
||||
&hints,
|
||||
tau_tracker_on_dns,
|
||||
|
@ -765,10 +763,10 @@ static struct tr_announcer_udp* announcer_udp_get(tr_session* session)
|
|||
|
||||
/* Finds the tau_tracker struct that corresponds to this url.
|
||||
If it doesn't exist yet, create one. */
|
||||
static tau_tracker* tau_session_get_tracker(tr_announcer_udp* tau, tr_quark announce_url)
|
||||
static tau_tracker* tau_session_get_tracker(tr_announcer_udp* tau, tr_interned_string announce_url)
|
||||
{
|
||||
// build a lookup key for this tracker
|
||||
auto const announce_sv = tr_quark_get_string_view(announce_url);
|
||||
auto const announce_sv = announce_url.sv();
|
||||
auto parsed = tr_urlParseTracker(announce_sv);
|
||||
TR_ASSERT(parsed);
|
||||
if (!parsed)
|
||||
|
@ -789,7 +787,7 @@ static tau_tracker* tau_session_get_tracker(tr_announcer_udp* tau, tr_quark anno
|
|||
}
|
||||
|
||||
// we don't have it -- build a new one
|
||||
auto* const tracker = new tau_tracker{ tau->session, key, tr_quark_new(parsed->host), parsed->port };
|
||||
auto* const tracker = new tau_tracker{ tau->session, key, tr_interned_string(parsed->host), parsed->port };
|
||||
tr_ptrArrayAppend(&tau->trackers, tracker);
|
||||
dbgmsg(tracker->key, "New tau_tracker created");
|
||||
return tracker;
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include <event2/buffer.h>
|
||||
|
@ -151,11 +151,11 @@ struct StopsCompare
|
|||
|
||||
struct tr_scrape_info
|
||||
{
|
||||
tr_quark const scrape_url;
|
||||
tr_interned_string scrape_url;
|
||||
|
||||
int multiscrape_max;
|
||||
|
||||
tr_scrape_info(tr_quark scrape_url_in, int const multiscrape_max_in)
|
||||
tr_scrape_info(tr_interned_string scrape_url_in, int const multiscrape_max_in)
|
||||
: scrape_url{ scrape_url_in }
|
||||
, multiscrape_max{ multiscrape_max_in }
|
||||
{
|
||||
|
@ -168,7 +168,7 @@ struct tr_scrape_info
|
|||
struct tr_announcer
|
||||
{
|
||||
std::set<tr_announce_request*, StopsCompare> stops;
|
||||
std::unordered_map<tr_quark, tr_scrape_info> scrape_info;
|
||||
std::map<tr_interned_string, tr_scrape_info> scrape_info;
|
||||
|
||||
tr_session* session;
|
||||
struct event* upkeepTimer;
|
||||
|
@ -176,9 +176,9 @@ struct tr_announcer
|
|||
time_t tauUpkeepAt;
|
||||
};
|
||||
|
||||
static tr_scrape_info* tr_announcerGetScrapeInfo(tr_announcer* announcer, tr_quark url)
|
||||
static tr_scrape_info* tr_announcerGetScrapeInfo(tr_announcer* announcer, tr_interned_string url)
|
||||
{
|
||||
if (url == TR_KEY_NONE)
|
||||
if (std::empty(url))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -227,8 +227,8 @@ void tr_announcerClose(tr_session* session)
|
|||
/* a row in tr_tier's list of trackers */
|
||||
struct tr_tracker
|
||||
{
|
||||
tr_quark key;
|
||||
tr_quark announce_url;
|
||||
tr_interned_string key;
|
||||
tr_interned_string announce_url;
|
||||
struct tr_scrape_info* scrape_info;
|
||||
|
||||
char* tracker_id_str;
|
||||
|
@ -244,20 +244,19 @@ struct tr_tracker
|
|||
};
|
||||
|
||||
// format: `${host}:${port}`
|
||||
tr_quark tr_announcerGetKey(tr_url_parsed_t const& parsed)
|
||||
tr_interned_string tr_announcerGetKey(tr_url_parsed_t const& parsed)
|
||||
{
|
||||
std::string buf;
|
||||
tr_buildBuf(buf, parsed.host, ":"sv, parsed.portstr);
|
||||
return tr_quark_new(buf);
|
||||
return tr_interned_string{ buf };
|
||||
}
|
||||
|
||||
static void trackerConstruct(tr_announcer* announcer, tr_tracker* tracker, tr_announce_list::tracker_info const& info)
|
||||
{
|
||||
memset(tracker, 0, sizeof(tr_tracker));
|
||||
tracker->key = info.host;
|
||||
tracker->announce_url = info.announce_interned;
|
||||
tracker->scrape_info = info.scrape_interned == TR_KEY_NONE ? nullptr :
|
||||
tr_announcerGetScrapeInfo(announcer, info.scrape_interned);
|
||||
tracker->announce_url = info.announce_str;
|
||||
tracker->scrape_info = std::empty(info.scrape_str) ? nullptr : tr_announcerGetScrapeInfo(announcer, info.scrape_str);
|
||||
tracker->id = info.id;
|
||||
tracker->seederCount = -1;
|
||||
tracker->leecherCount = -1;
|
||||
|
@ -369,9 +368,7 @@ static void tierDestruct(tr_tier* tier)
|
|||
static void tier_build_log_name(tr_tier const* tier, char* buf, size_t buflen)
|
||||
{
|
||||
auto const* const name = tier != nullptr && tier->tor != nullptr ? tr_torrentName(tier->tor) : "?";
|
||||
auto const key_sv = tier != nullptr && tier->currentTracker != nullptr ?
|
||||
tr_quark_get_string_view(tier->currentTracker->key) :
|
||||
"?"sv;
|
||||
auto const key_sv = tier != nullptr && tier->currentTracker != nullptr ? tier->currentTracker->key.sv() : "?"sv;
|
||||
tr_snprintf(buf, buflen, "[%s---%" TR_PRIsv "]", name, TR_PRIsv_ARG(key_sv));
|
||||
}
|
||||
|
||||
|
@ -470,7 +467,7 @@ static tr_tier* getTier(tr_announcer* announcer, tr_sha1_digest_t const& info_ha
|
|||
**** PUBLISH
|
||||
***/
|
||||
|
||||
static void publishMessage(tr_tier* tier, char const* msg, TrackerEventType type)
|
||||
static void publishMessage(tr_tier* tier, std::string_view msg, TrackerEventType type)
|
||||
{
|
||||
if (tier != nullptr && tier->tor != nullptr && tier->tor->announcer_tiers != nullptr &&
|
||||
tier->tor->announcer_tiers->callback != nullptr)
|
||||
|
@ -491,15 +488,15 @@ static void publishMessage(tr_tier* tier, char const* msg, TrackerEventType type
|
|||
|
||||
static void publishErrorClear(tr_tier* tier)
|
||||
{
|
||||
publishMessage(tier, nullptr, TR_TRACKER_ERROR_CLEAR);
|
||||
publishMessage(tier, ""sv, TR_TRACKER_ERROR_CLEAR);
|
||||
}
|
||||
|
||||
static void publishWarning(tr_tier* tier, char const* msg)
|
||||
static void publishWarning(tr_tier* tier, std::string_view msg)
|
||||
{
|
||||
publishMessage(tier, msg, TR_TRACKER_WARNING);
|
||||
}
|
||||
|
||||
static void publishError(tr_tier* tier, char const* msg)
|
||||
static void publishError(tr_tier* tier, std::string_view msg)
|
||||
{
|
||||
publishMessage(tier, msg, TR_TRACKER_ERROR);
|
||||
}
|
||||
|
@ -913,7 +910,7 @@ static void on_announce_error(tr_tier* tier, char const* err, tr_announce_event
|
|||
|
||||
/* schedule a reannounce */
|
||||
int const interval = getRetryInterval(tier->currentTracker);
|
||||
auto const* const key_cstr = tr_quark_get_string(tier->currentTracker->key);
|
||||
auto const* const key_cstr = tier->currentTracker->key.c_str();
|
||||
dbgmsg(tier, "Tracker '%s' announce error: %s (Retrying in %d seconds)", key_cstr, err, interval);
|
||||
tr_logAddTorInfo(tier->tor, "Tracker '%s' announce error: %s (Retrying in %d seconds)", key_cstr, err, interval);
|
||||
tier_announce_event_push(tier, e, tr_time() + interval);
|
||||
|
@ -954,8 +951,8 @@ static void on_announce_done(tr_announce_response const* response, void* vdata)
|
|||
response->tracker_id_str != nullptr ? response->tracker_id_str : "none",
|
||||
response->pex_count,
|
||||
response->pex6_count,
|
||||
response->errmsg != nullptr ? response->errmsg : "none",
|
||||
response->warning != nullptr ? response->warning : "none");
|
||||
(!std::empty(response->errmsg) ? response->errmsg.c_str() : "none"),
|
||||
(!std::empty(response->warning) ? response->warning.c_str() : "none"));
|
||||
|
||||
tier->lastAnnounceTime = now;
|
||||
tier->lastAnnounceTimedOut = response->did_timeout;
|
||||
|
@ -971,7 +968,7 @@ static void on_announce_done(tr_announce_response const* response, void* vdata)
|
|||
{
|
||||
on_announce_error(tier, _("Tracker did not respond"), event);
|
||||
}
|
||||
else if (response->errmsg != nullptr)
|
||||
else if (!std::empty(response->errmsg))
|
||||
{
|
||||
/* If the torrent's only tracker returned an error, publish it.
|
||||
Don't bother publishing if there are other trackers -- it's
|
||||
|
@ -982,7 +979,7 @@ static void on_announce_done(tr_announce_response const* response, void* vdata)
|
|||
publishError(tier, response->errmsg);
|
||||
}
|
||||
|
||||
on_announce_error(tier, response->errmsg, event);
|
||||
on_announce_error(tier, response->errmsg.c_str(), event);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1023,12 +1020,12 @@ static void on_announce_done(tr_announce_response const* response, void* vdata)
|
|||
}
|
||||
}
|
||||
|
||||
char const* const str = response->warning;
|
||||
if (str != nullptr)
|
||||
auto const& warning = response->warning;
|
||||
if (!std::empty(warning))
|
||||
{
|
||||
tr_strlcpy(tier->lastAnnounceStr, str, sizeof(tier->lastAnnounceStr));
|
||||
dbgmsg(tier, "tracker gave \"%s\"", str);
|
||||
publishWarning(tier, str);
|
||||
tr_strlcpy(tier->lastAnnounceStr, warning.c_str(), sizeof(tier->lastAnnounceStr));
|
||||
dbgmsg(tier, "tracker gave \"%s\"", warning.c_str());
|
||||
publishWarning(tier, warning);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1127,7 +1124,7 @@ static void announce_request_delegate(
|
|||
|
||||
#endif
|
||||
|
||||
if (auto const announce_sv = tr_quark_get_string_view(request->announce_url);
|
||||
if (auto const announce_sv = request->announce_url.sv();
|
||||
tr_strvStartsWith(announce_sv, "http://"sv) || tr_strvStartsWith(announce_sv, "https://"sv))
|
||||
{
|
||||
tr_tracker_http_announce(session, request, callback, callback_data);
|
||||
|
@ -1211,14 +1208,14 @@ static void on_scrape_error(tr_session const* session, tr_tier* tier, char const
|
|||
|
||||
/* schedule a rescrape */
|
||||
int const interval = getRetryInterval(tier->currentTracker);
|
||||
auto const* const key_cstr = tr_quark_get_string(tier->currentTracker->key);
|
||||
auto const* const key_cstr = tier->currentTracker->key.c_str();
|
||||
dbgmsg(tier, "Tracker '%s' scrape error: %s (Retrying in %zu seconds)", key_cstr, errmsg, (size_t)interval);
|
||||
tr_logAddTorInfo(tier->tor, "Tracker '%s' error: %s (Retrying in %zu seconds)", key_cstr, errmsg, (size_t)interval);
|
||||
tier->lastScrapeSucceeded = false;
|
||||
tier->scrapeAt = get_next_scrape_time(session, tier, interval);
|
||||
}
|
||||
|
||||
static tr_tier* find_tier(tr_torrent* tor, tr_quark scrape_url)
|
||||
static tr_tier* find_tier(tr_torrent* tor, tr_interned_string scrape_url)
|
||||
{
|
||||
struct tr_announcer_tiers* tt = tor->announcer_tiers;
|
||||
|
||||
|
@ -1263,7 +1260,7 @@ static void checkMultiscrapeMax(tr_announcer* announcer, tr_scrape_response cons
|
|||
{
|
||||
// don't log the full URL, since that might have a personal announce id
|
||||
// (note: we know 'parsed' will be successful since this url has a scrape_info)
|
||||
auto const parsed = *tr_urlParse(tr_quark_get_string_view(url));
|
||||
auto const parsed = *tr_urlParse(url.sv());
|
||||
auto clean_url = std::string{};
|
||||
tr_buildBuf(clean_url, parsed.scheme, "://"sv, parsed.host, ":"sv, parsed.portstr);
|
||||
tr_logAddNamedInfo(clean_url.c_str(), "Reducing multiscrape max to %d", n);
|
||||
|
@ -1288,7 +1285,7 @@ static void on_scrape_done(tr_scrape_response const* response, void* vsession)
|
|||
|
||||
if (tier != nullptr)
|
||||
{
|
||||
auto const scrape_url_sv = tr_quark_get_string_view(response->scrape_url);
|
||||
auto const scrape_url_sv = response->scrape_url.sv();
|
||||
|
||||
dbgmsg(
|
||||
tier,
|
||||
|
@ -1378,7 +1375,7 @@ static void scrape_request_delegate(
|
|||
{
|
||||
tr_session* session = announcer->session;
|
||||
|
||||
auto const scrape_sv = tr_quark_get_string_view(request->scrape_url);
|
||||
auto const scrape_sv = request->scrape_url.sv();
|
||||
|
||||
if (tr_strvStartsWith(scrape_sv, "http://"sv) || tr_strvStartsWith(scrape_sv, "https://"sv))
|
||||
{
|
||||
|
@ -1609,9 +1606,9 @@ static tr_tracker_view trackerView(tr_torrent const& tor, int tier_index, tr_tie
|
|||
auto const now = tr_time();
|
||||
auto view = tr_tracker_view{};
|
||||
|
||||
view.host = tr_quark_get_string(tracker.key);
|
||||
view.announce = tr_quark_get_string(tracker.announce_url);
|
||||
view.scrape = tracker.scrape_info == nullptr ? "" : tr_quark_get_string(tracker.scrape_info->scrape_url);
|
||||
view.host = tracker.key.c_str();
|
||||
view.announce = tracker.announce_url.c_str();
|
||||
view.scrape = tracker.scrape_info == nullptr ? "" : tracker.scrape_info->scrape_url.c_str();
|
||||
|
||||
view.id = tracker.id;
|
||||
view.tier = tier_index;
|
||||
|
|
|
@ -43,8 +43,8 @@ struct tr_tracker_event
|
|||
TrackerEventType messageType;
|
||||
|
||||
/* for TR_TRACKER_WARNING and TR_TRACKER_ERROR */
|
||||
char const* text;
|
||||
tr_quark announce_url;
|
||||
std::string_view text;
|
||||
tr_interned_string announce_url;
|
||||
|
||||
/* for TR_TRACKER_PEERS */
|
||||
struct tr_pex const* pex;
|
||||
|
|
1
libtransmission/foo
Normal file
1
libtransmission/foo
Normal file
|
@ -0,0 +1 @@
|
|||
test
|
|
@ -26,6 +26,8 @@
|
|||
#include "tr-assert.h"
|
||||
#include "utils.h"
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
/****
|
||||
***** Low-level IO functions
|
||||
****/
|
||||
|
@ -227,8 +229,8 @@ static int readOrWritePiece(
|
|||
|
||||
if (err != 0 && ioMode == TR_IO_WRITE && tor->error != TR_STAT_LOCAL_ERROR)
|
||||
{
|
||||
auto const path = tr_strvPath(tor->downloadDir, file.name);
|
||||
tr_torrentSetLocalError(tor, "%s (%s)", tr_strerror(err), path.c_str());
|
||||
auto const path = tr_strvPath(tor->downloadDir().sv(), file.name);
|
||||
tor->setLocalError(tr_strvJoin(tr_strerror(err), " ("sv, path, ")"sv));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
142
libtransmission/interned-string.h
Normal file
142
libtransmission/interned-string.h
Normal file
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* This file Copyright (C) Mnemosyne LLC
|
||||
*
|
||||
* It may be used under the GNU GPL versions 2 or 3
|
||||
* or any future license endorsed by Mnemosyne LLC.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
|
||||
#include "transmission.h"
|
||||
|
||||
#include "quark.h"
|
||||
|
||||
/**
|
||||
* Helper functions wrapped around tr_quark
|
||||
*/
|
||||
class tr_interned_string
|
||||
{
|
||||
public:
|
||||
tr_interned_string() = default;
|
||||
|
||||
explicit tr_interned_string(tr_quark quark)
|
||||
: quark_{ quark }
|
||||
{
|
||||
}
|
||||
explicit tr_interned_string(std::string_view sv)
|
||||
: tr_interned_string{ tr_quark_new(sv) }
|
||||
{
|
||||
}
|
||||
explicit tr_interned_string(char const* c_str)
|
||||
: tr_interned_string{ std::string_view{ c_str ? c_str : "" } }
|
||||
{
|
||||
}
|
||||
|
||||
tr_interned_string& operator=(tr_quark quark)
|
||||
{
|
||||
quark_ = quark;
|
||||
return *this;
|
||||
}
|
||||
tr_interned_string& operator=(std::string_view sv)
|
||||
{
|
||||
return *this = tr_quark_new(sv);
|
||||
}
|
||||
tr_interned_string& operator=(char const* c_str)
|
||||
{
|
||||
return *this = std::string_view{ c_str != nullptr ? c_str : "" };
|
||||
}
|
||||
|
||||
[[nodiscard]] tr_quark quark() const
|
||||
{
|
||||
return quark_;
|
||||
}
|
||||
[[nodiscard]] char const* c_str() const
|
||||
{
|
||||
return tr_quark_get_string(quark_);
|
||||
}
|
||||
[[nodiscard]] std::string_view sv() const
|
||||
{
|
||||
return tr_quark_get_string_view(quark_);
|
||||
}
|
||||
|
||||
[[nodiscard]] auto data() const
|
||||
{
|
||||
return std::data(this->sv());
|
||||
}
|
||||
[[nodiscard]] auto empty() const
|
||||
{
|
||||
return quark_ == TR_KEY_NONE;
|
||||
}
|
||||
[[nodiscard]] auto size() const
|
||||
{
|
||||
return std::size(this->sv());
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
*this = TR_KEY_NONE;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto begin() const
|
||||
{
|
||||
return std::begin(this->sv());
|
||||
}
|
||||
[[nodiscard]] auto end() const
|
||||
{
|
||||
return std::end(this->sv());
|
||||
}
|
||||
|
||||
[[nodiscard]] auto rbegin() const
|
||||
{
|
||||
return std::rbegin(this->sv());
|
||||
}
|
||||
[[nodiscard]] auto rend() const
|
||||
{
|
||||
return std::rend(this->sv());
|
||||
}
|
||||
|
||||
[[nodiscard]] int compare(tr_interned_string const& that) const // <=>
|
||||
{
|
||||
return this->quark() - that.quark();
|
||||
}
|
||||
|
||||
[[nodiscard]] bool operator<(tr_interned_string const& that) const
|
||||
{
|
||||
return this->compare(that) < 0;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool operator>(tr_interned_string const& that) const
|
||||
{
|
||||
return this->compare(that) > 0;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool operator==(tr_interned_string const& that) const
|
||||
{
|
||||
return this->compare(that) == 0;
|
||||
}
|
||||
[[nodiscard]] bool operator!=(tr_interned_string const& that) const
|
||||
{
|
||||
return this->compare(that) != 0;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool operator==(std::string_view that) const
|
||||
{
|
||||
return this->sv() == that;
|
||||
}
|
||||
[[nodiscard]] bool operator!=(std::string_view that) const
|
||||
{
|
||||
return this->sv() != that;
|
||||
}
|
||||
[[nodiscard]] bool operator==(char const* that) const
|
||||
{
|
||||
return *this == std::string_view{ that != nullptr ? that : "" };
|
||||
}
|
||||
[[nodiscard]] bool operator!=(char const* that) const
|
||||
{
|
||||
return *this != std::string_view{ that != nullptr ? that : "" };
|
||||
}
|
||||
|
||||
private:
|
||||
tr_quark quark_ = TR_KEY_NONE;
|
||||
};
|
|
@ -208,7 +208,7 @@ void tr_magnet_metainfo::toVariant(tr_variant* top) const
|
|||
auto n = std::size(this->announce_list);
|
||||
if (n == 1)
|
||||
{
|
||||
tr_variantDictAddQuark(top, TR_KEY_announce, this->announce_list.at(0).announce_interned);
|
||||
tr_variantDictAddQuark(top, TR_KEY_announce, this->announce_list.at(0).announce_str.quark());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -224,7 +224,7 @@ void tr_magnet_metainfo::toVariant(tr_variant* top) const
|
|||
current_tier = tracker.tier;
|
||||
}
|
||||
|
||||
tr_variantListAddQuark(tracker_list, tracker.announce_interned);
|
||||
tr_variantListAddQuark(tracker_list, tracker.announce_str.quark());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ public:
|
|||
|
||||
/* the client name.
|
||||
For BitTorrent peers, this is the app name derived from the `v' string in LTEP's handshake dictionary */
|
||||
tr_quark client = TR_KEY_NONE;
|
||||
tr_interned_string client;
|
||||
|
||||
tr_recentHistory blocksSentToClient;
|
||||
tr_recentHistory blocksSentToPeer;
|
||||
|
|
|
@ -1722,7 +1722,7 @@ static auto getPeerStats(tr_peerMsgs const* peer, time_t now, uint64_t now_msec)
|
|||
auto const* const atom = peer->atom;
|
||||
|
||||
tr_address_to_string_with_buf(&atom->addr, stats.addr, sizeof(stats.addr));
|
||||
tr_strlcpy(stats.client, tr_quark_get_string(peer->client), sizeof(stats.client));
|
||||
stats.client = peer->client.c_str();
|
||||
stats.port = ntohs(peer->atom->port);
|
||||
stats.from = atom->fromFirst;
|
||||
stats.progress = peer->progress;
|
||||
|
|
|
@ -676,7 +676,7 @@ static void myDebug(char const* file, int line, tr_peerMsgsImpl const* msgs, cha
|
|||
tr_logGetTimeStr(timestr, sizeof(timestr)),
|
||||
tr_torrentName(msgs->torrent),
|
||||
tr_peerIoGetAddrStr(msgs->io, addrstr, sizeof(addrstr)),
|
||||
tr_quark_get_string(msgs->client));
|
||||
msgs->client.c_str());
|
||||
va_start(args, fmt);
|
||||
evbuffer_add_vprintf(buf, fmt, args);
|
||||
va_end(args);
|
||||
|
@ -2231,10 +2231,11 @@ static size_t fillOutputBuffer(tr_peerMsgsImpl* msgs, time_t now)
|
|||
err = !msgs->torrent->ensurePieceIsChecked(req.index);
|
||||
if (err)
|
||||
{
|
||||
tr_torrentSetLocalError(
|
||||
msgs->torrent,
|
||||
_("Please Verify Local Data! Piece #%zu is corrupt."),
|
||||
(size_t)req.index);
|
||||
auto const errmsg = tr_strvJoin(
|
||||
"Please Verify Local Data! Piece #",
|
||||
std::to_string(req.index),
|
||||
" is corrupt.");
|
||||
msgs->torrent->setLocalError(errmsg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
/*
|
||||
* This file Copyright (C) 2013-2014 Mnemosyne LLC
|
||||
* This file Copyright (C) Mnemosyne LLC
|
||||
*
|
||||
* It may be used under the GNU GPL versions 2 or 3
|
||||
* or any future license endorsed by Mnemosyne LLC.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
|
|
@ -678,11 +678,11 @@ void tr_torrentSaveResume(tr_torrent* tor)
|
|||
tr_variantDictAddInt(&top, TR_KEY_added_date, tor->addedDate);
|
||||
tr_variantDictAddInt(&top, TR_KEY_corrupt, tor->corruptPrev + tor->corruptCur);
|
||||
tr_variantDictAddInt(&top, TR_KEY_done_date, tor->doneDate);
|
||||
tr_variantDictAddStrView(&top, TR_KEY_destination, tor->downloadDir);
|
||||
tr_variantDictAddQuark(&top, TR_KEY_destination, tor->downloadDir().quark());
|
||||
|
||||
if (tor->incompleteDir != nullptr)
|
||||
if (!std::empty(tor->incompleteDir()))
|
||||
{
|
||||
tr_variantDictAddStr(&top, TR_KEY_incomplete_dir, tor->incompleteDir);
|
||||
tr_variantDictAddQuark(&top, TR_KEY_incomplete_dir, tor->incompleteDir().quark());
|
||||
}
|
||||
|
||||
tr_variantDictAddInt(&top, TR_KEY_downloaded, tor->downloadedPrev + tor->downloadedCur);
|
||||
|
@ -710,7 +710,7 @@ void tr_torrentSaveResume(tr_torrent* tor)
|
|||
int const err = tr_variantToFile(&top, TR_VARIANT_FMT_BENC, filename.c_str());
|
||||
if (err != 0)
|
||||
{
|
||||
tr_torrentSetLocalError(tor, "Unable to save resume file: %s", tr_strerror(err));
|
||||
tor->setLocalError(tr_strvJoin("Unable to save resume file: ", tr_strerror(err)));
|
||||
}
|
||||
|
||||
tr_variantFree(&top);
|
||||
|
@ -778,13 +778,11 @@ static uint64_t loadFromFile(tr_torrent* tor, uint64_t fieldsToLoad, bool* didRe
|
|||
if ((fieldsToLoad & (TR_FR_PROGRESS | TR_FR_DOWNLOAD_DIR)) != 0 &&
|
||||
tr_variantDictFindStrView(&top, TR_KEY_destination, &sv) && !std::empty(sv))
|
||||
{
|
||||
bool const is_current_dir = tor->currentDir == tor->downloadDir;
|
||||
tr_free(tor->downloadDir);
|
||||
tor->downloadDir = tr_strvDup(sv);
|
||||
|
||||
bool const is_current_dir = tor->current_dir == tor->download_dir;
|
||||
tor->download_dir = sv;
|
||||
if (is_current_dir)
|
||||
{
|
||||
tor->currentDir = tor->downloadDir;
|
||||
tor->current_dir = sv;
|
||||
}
|
||||
|
||||
fieldsLoaded |= TR_FR_DOWNLOAD_DIR;
|
||||
|
@ -793,13 +791,11 @@ static uint64_t loadFromFile(tr_torrent* tor, uint64_t fieldsToLoad, bool* didRe
|
|||
if ((fieldsToLoad & (TR_FR_PROGRESS | TR_FR_INCOMPLETE_DIR)) != 0 &&
|
||||
tr_variantDictFindStrView(&top, TR_KEY_incomplete_dir, &sv) && !std::empty(sv))
|
||||
{
|
||||
bool const is_current_dir = tor->currentDir == tor->incompleteDir;
|
||||
tr_free(tor->incompleteDir);
|
||||
tor->incompleteDir = tr_strvDup(sv);
|
||||
|
||||
bool const is_current_dir = tor->current_dir == tor->incomplete_dir;
|
||||
tor->incomplete_dir = sv;
|
||||
if (is_current_dir)
|
||||
{
|
||||
tor->currentDir = tor->incompleteDir;
|
||||
tor->current_dir = sv;
|
||||
}
|
||||
|
||||
fieldsLoaded |= TR_FR_INCOMPLETE_DIR;
|
||||
|
@ -953,8 +949,7 @@ static uint64_t setFromCtor(tr_torrent* tor, uint64_t fields, tr_ctor const* cto
|
|||
if (tr_ctorGetDownloadDir(ctor, mode, &path) && !tr_str_is_empty(path))
|
||||
{
|
||||
ret |= TR_FR_DOWNLOAD_DIR;
|
||||
tr_free(tor->downloadDir);
|
||||
tor->downloadDir = tr_strdup(path);
|
||||
tor->download_dir = path;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -414,9 +414,9 @@ static void addTrackers(tr_torrent const* tor, tr_variant* trackers)
|
|||
for (auto const& tracker : tor->announceList())
|
||||
{
|
||||
tr_variant* d = tr_variantListAddDict(trackers, 4);
|
||||
tr_variantDictAddQuark(d, TR_KEY_announce, tracker.announce_interned);
|
||||
tr_variantDictAddQuark(d, TR_KEY_announce, tracker.announce_str.quark());
|
||||
tr_variantDictAddInt(d, TR_KEY_id, tracker.id);
|
||||
tr_variantDictAddQuark(d, TR_KEY_scrape, tracker.scrape_interned);
|
||||
tr_variantDictAddQuark(d, TR_KEY_scrape, tracker.scrape_str.quark());
|
||||
tr_variantDictAddInt(d, TR_KEY_tier, tracker.tier);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -299,7 +299,7 @@ void tr_torrentSetMetadataPiece(tr_torrent* tor, int piece, void const* data, in
|
|||
success = !!info;
|
||||
if (info && tr_block_info::bestBlockSize(info->info.pieceSize) == 0)
|
||||
{
|
||||
tr_torrentSetLocalError(tor, "%s", _("Magnet torrent's metadata is not usable"));
|
||||
tor->setLocalError(_("Magnet torrent's metadata is not usable"));
|
||||
success = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include <climits> /* INT_MAX */
|
||||
#include <cmath>
|
||||
#include <csignal> /* signal() */
|
||||
#include <cstdarg>
|
||||
#include <cstdlib> /* qsort */
|
||||
#include <cstring> /* memcmp */
|
||||
#include <ctime>
|
||||
|
@ -492,31 +491,11 @@ void tr_torrentCheckSeedLimit(tr_torrent* tor)
|
|||
****
|
||||
***/
|
||||
|
||||
void tr_torrentSetLocalError(tr_torrent* tor, char const* fmt, ...)
|
||||
{
|
||||
TR_ASSERT(tr_isTorrent(tor));
|
||||
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
tor->error = TR_STAT_LOCAL_ERROR;
|
||||
tor->error_announce_url = TR_KEY_NONE;
|
||||
evutil_vsnprintf(tor->errorString, sizeof(tor->errorString), fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
tr_logAddTorErr(tor, "%s", tor->errorString);
|
||||
|
||||
if (tor->isRunning)
|
||||
{
|
||||
tor->isStopping = true;
|
||||
}
|
||||
}
|
||||
|
||||
static constexpr void tr_torrentClearError(tr_torrent* tor)
|
||||
static void tr_torrentClearError(tr_torrent* tor)
|
||||
{
|
||||
tor->error = TR_STAT_OK;
|
||||
tor->error_announce_url = TR_KEY_NONE;
|
||||
tor->errorString[0] = '\0';
|
||||
tor->error_announce_url.clear();
|
||||
tor->error_string.clear();
|
||||
}
|
||||
|
||||
static void onTrackerResponse(tr_torrent* tor, tr_tracker_event const* event, void* /*user_data*/)
|
||||
|
@ -537,16 +516,16 @@ static void onTrackerResponse(tr_torrent* tor, tr_tracker_event const* event, vo
|
|||
break;
|
||||
|
||||
case TR_TRACKER_WARNING:
|
||||
tr_logAddTorErr(tor, _("Tracker warning: \"%s\""), event->text);
|
||||
tr_logAddTorErr(tor, _("Tracker warning: \"%" TR_PRIsv "\""), TR_PRIsv_ARG(event->text));
|
||||
tor->error = TR_STAT_TRACKER_WARNING;
|
||||
tor->error_announce_url = event->announce_url;
|
||||
tr_strlcpy(tor->errorString, event->text, sizeof(tor->errorString));
|
||||
tor->error_string = event->text;
|
||||
break;
|
||||
|
||||
case TR_TRACKER_ERROR:
|
||||
tor->error = TR_STAT_TRACKER_ERROR;
|
||||
tor->error_announce_url = event->announce_url;
|
||||
tr_strlcpy(tor->errorString, event->text, sizeof(tor->errorString));
|
||||
tor->error_string = event->text;
|
||||
break;
|
||||
|
||||
case TR_TRACKER_ERROR_CLEAR:
|
||||
|
@ -630,11 +609,8 @@ static bool setLocalErrorIfFilesDisappeared(tr_torrent* tor)
|
|||
if (disappeared)
|
||||
{
|
||||
tr_deeplog_tor(tor, "%s", "[LAZY] uh oh, the files disappeared");
|
||||
tr_torrentSetLocalError(
|
||||
tor,
|
||||
"%s",
|
||||
_("No data found! Ensure your drives are connected or use \"Set Location\". "
|
||||
"To re-download, remove the torrent and re-add it."));
|
||||
tor->setLocalError(_(
|
||||
"No data found! Ensure your drives are connected or use \"Set Location\". To re-download, remove the torrent and re-add it."));
|
||||
}
|
||||
|
||||
return disappeared;
|
||||
|
@ -671,7 +647,7 @@ static void torrentInit(tr_torrent* tor, tr_ctor const* ctor)
|
|||
char const* dir = nullptr;
|
||||
if (tr_ctorGetDownloadDir(ctor, TR_FORCE, &dir) || tr_ctorGetDownloadDir(ctor, TR_FALLBACK, &dir))
|
||||
{
|
||||
tor->downloadDir = tr_strdup(dir);
|
||||
tor->download_dir = dir;
|
||||
}
|
||||
|
||||
if (!tr_ctorGetIncompleteDir(ctor, &dir))
|
||||
|
@ -681,7 +657,7 @@ static void torrentInit(tr_torrent* tor, tr_ctor const* ctor)
|
|||
|
||||
if (tr_sessionIsIncompleteDirEnabled(session))
|
||||
{
|
||||
tor->incompleteDir = tr_strdup(dir);
|
||||
tor->incomplete_dir = dir;
|
||||
}
|
||||
|
||||
tor->bandwidth = new Bandwidth(session->bandwidth);
|
||||
|
@ -757,7 +733,8 @@ static void torrentInit(tr_torrent* tor, tr_ctor const* ctor)
|
|||
tr_error* error = nullptr;
|
||||
if (!tr_ctorSaveContents(ctor, tor->torrentFile(), &error))
|
||||
{
|
||||
tr_torrentSetLocalError(tor, "Unable to save torrent file: %s (%d)", error->message, error->code);
|
||||
tor->setLocalError(
|
||||
tr_strvJoin("Unable to save torrent file: ", error->message, " ("sv, std::to_string(error->code), ")"sv));
|
||||
}
|
||||
tr_error_clear(&error);
|
||||
}
|
||||
|
@ -860,11 +837,9 @@ void tr_torrentSetDownloadDir(tr_torrent* tor, char const* path)
|
|||
{
|
||||
TR_ASSERT(tr_isTorrent(tor));
|
||||
|
||||
if (path == nullptr || tor->downloadDir == nullptr || strcmp(path, tor->downloadDir) != 0)
|
||||
if (tor->download_dir != path)
|
||||
{
|
||||
tr_free(tor->downloadDir);
|
||||
tor->downloadDir = tr_strdup(path);
|
||||
|
||||
tor->download_dir = path;
|
||||
tor->markEdited();
|
||||
tor->setDirty();
|
||||
}
|
||||
|
@ -876,14 +851,14 @@ char const* tr_torrentGetDownloadDir(tr_torrent const* tor)
|
|||
{
|
||||
TR_ASSERT(tr_isTorrent(tor));
|
||||
|
||||
return tor->downloadDir;
|
||||
return tor->downloadDir().c_str();
|
||||
}
|
||||
|
||||
char const* tr_torrentGetCurrentDir(tr_torrent const* tor)
|
||||
{
|
||||
TR_ASSERT(tr_isTorrent(tor));
|
||||
|
||||
return tor->currentDir;
|
||||
return tor->currentDir().c_str();
|
||||
}
|
||||
|
||||
void tr_torrentChangeMyPort(tr_torrent* tor)
|
||||
|
@ -1007,7 +982,7 @@ tr_stat const* tr_torrentStat(tr_torrent* tor)
|
|||
s->queuePosition = tor->queuePosition;
|
||||
s->idleSecs = torrentGetIdleSecs(tor, s->activity);
|
||||
s->isStalled = tr_torrentIsStalled(tor, s->idleSecs);
|
||||
s->errorString = tor->errorString;
|
||||
s->errorString = tor->error_string.c_str();
|
||||
|
||||
s->manualAnnounceTime = tr_announcerNextManualAnnounce(tor);
|
||||
s->peersConnected = swarm_stats.peerCount;
|
||||
|
@ -1336,9 +1311,6 @@ static void freeTorrent(tr_torrent* tor)
|
|||
|
||||
tr_announcerRemoveTorrent(session->announcer, tor);
|
||||
|
||||
tr_free(tor->downloadDir);
|
||||
tr_free(tor->incompleteDir);
|
||||
|
||||
tr_sessionRemoveTorrent(session, tor);
|
||||
|
||||
if (!session->isClosing())
|
||||
|
@ -1830,7 +1802,8 @@ static void torrentCallScript(tr_torrent const* tor, char const* script)
|
|||
tr_localtime_r(&now, &tm);
|
||||
strftime(ctime_str, sizeof(ctime_str), "%a %b %d %T %Y%n", &tm); /* ctime equiv */
|
||||
|
||||
char* const torrent_dir = tr_sys_path_native_separators(tr_strdup(tor->currentDir));
|
||||
auto torrent_dir = std::string{ tor->currentDir().sv() };
|
||||
tr_sys_path_native_separators(std::data(torrent_dir));
|
||||
|
||||
auto const cmd = std::array<char const*, 2>{
|
||||
script,
|
||||
|
@ -1844,7 +1817,7 @@ static void torrentCallScript(tr_torrent const* tor, char const* script)
|
|||
auto const env = std::map<std::string_view, std::string_view>{
|
||||
{ "TR_APP_VERSION"sv, SHORT_VERSION_STRING },
|
||||
{ "TR_TIME_LOCALTIME"sv, ctime_str },
|
||||
{ "TR_TORRENT_DIR"sv, torrent_dir },
|
||||
{ "TR_TORRENT_DIR"sv, torrent_dir.c_str() },
|
||||
{ "TR_TORRENT_HASH"sv, tor->hashString() },
|
||||
{ "TR_TORRENT_ID"sv, id_str },
|
||||
{ "TR_TORRENT_LABELS"sv, labels_str },
|
||||
|
@ -1861,8 +1834,6 @@ static void torrentCallScript(tr_torrent const* tor, char const* script)
|
|||
tr_logAddTorErr(tor, "Error executing script \"%s\" (%d): %s", script, error->code, error->message);
|
||||
tr_error_free(error);
|
||||
}
|
||||
|
||||
tr_free(torrent_dir);
|
||||
}
|
||||
|
||||
void tr_torrent::recheckCompleteness()
|
||||
|
@ -1904,9 +1875,9 @@ void tr_torrent::recheckCompleteness()
|
|||
tr_peerMgrClearInterest(this);
|
||||
}
|
||||
|
||||
if (this->currentDir == this->incompleteDir)
|
||||
if (this->currentDir() == this->incompleteDir())
|
||||
{
|
||||
this->setLocation(this->downloadDir, true, nullptr, nullptr);
|
||||
this->setLocation(this->downloadDir().sv(), true, nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2153,7 +2124,7 @@ bool tr_torrentSetAnnounceList(tr_torrent* tor, char const* const* announce_urls
|
|||
if (std::any_of(
|
||||
std::begin(tor->announceList()),
|
||||
std::end(tor->announceList()),
|
||||
[error_url](auto const& tracker) { return tracker.announce_interned == error_url; }))
|
||||
[error_url](auto const& tracker) { return tracker.announce_str == error_url; }))
|
||||
{
|
||||
tr_torrentClearError(tor);
|
||||
}
|
||||
|
@ -2276,7 +2247,7 @@ static void deleteLocalData(tr_torrent* tor, tr_fileFunc func)
|
|||
{
|
||||
auto files = std::vector<std::string>{};
|
||||
auto folders = std::set<std::string>{};
|
||||
char const* const top = tor->currentDir;
|
||||
char const* const top = tor->currentDir().c_str();
|
||||
|
||||
/* don't try to delete local data if the directory's gone missing */
|
||||
if (!tr_sys_path_exists(top, nullptr))
|
||||
|
@ -2457,12 +2428,12 @@ static void setLocationImpl(void* vdata)
|
|||
tr_logAddDebug(
|
||||
"Moving \"%s\" location from currentDir \"%s\" to \"%s\"",
|
||||
tr_torrentName(tor),
|
||||
tor->currentDir,
|
||||
tor->currentDir().c_str(),
|
||||
location.c_str());
|
||||
|
||||
tr_sys_dir_create(location.c_str(), TR_SYS_DIR_CREATE_PARENTS, 0777, nullptr);
|
||||
|
||||
if (!tr_sys_path_is_same(location.c_str(), tor->currentDir, nullptr))
|
||||
if (!tr_sys_path_is_same(location.c_str(), tor->currentDir().c_str(), nullptr))
|
||||
{
|
||||
/* bad idea to move files while they're being verified... */
|
||||
tr_verifyRemove(tor);
|
||||
|
@ -2526,9 +2497,8 @@ static void setLocationImpl(void* vdata)
|
|||
|
||||
if (do_move)
|
||||
{
|
||||
tr_free(tor->incompleteDir);
|
||||
tor->incompleteDir = nullptr;
|
||||
tor->currentDir = tor->downloadDir;
|
||||
tor->incomplete_dir.clear();
|
||||
tor->current_dir = tor->downloadDir();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2710,9 +2680,9 @@ std::optional<tr_torrent::tr_found_file_t> tr_torrent::findFile(std::string& fil
|
|||
tr_file const& file = this->file(i);
|
||||
auto file_info = tr_sys_path_info{};
|
||||
|
||||
if (this->downloadDir != nullptr)
|
||||
if (!std::empty(this->downloadDir()))
|
||||
{
|
||||
auto base = std::string_view{ this->downloadDir };
|
||||
auto const base = this->downloadDir().sv();
|
||||
|
||||
tr_buildBuf(filename, base, "/"sv, file.name);
|
||||
if (tr_sys_path_get_info(filename.c_str(), 0, &file_info, nullptr))
|
||||
|
@ -2727,9 +2697,9 @@ std::optional<tr_torrent::tr_found_file_t> tr_torrent::findFile(std::string& fil
|
|||
}
|
||||
}
|
||||
|
||||
if (this->incompleteDir != nullptr)
|
||||
if (!std::empty(this->incompleteDir()))
|
||||
{
|
||||
auto const base = std::string_view{ this->incompleteDir };
|
||||
auto const base = this->incompleteDir().sv();
|
||||
|
||||
tr_buildBuf(filename, base, "/"sv, file.name);
|
||||
if (tr_sys_path_get_info(filename.c_str(), 0, &file_info, nullptr))
|
||||
|
@ -2787,25 +2757,27 @@ char* tr_torrentFindFile(tr_torrent const* tor, tr_file_index_t fileNum)
|
|||
/* Decide whether we should be looking for files in downloadDir or incompleteDir. */
|
||||
static void refreshCurrentDir(tr_torrent* tor)
|
||||
{
|
||||
char const* dir = nullptr;
|
||||
tr_interned_string dir;
|
||||
|
||||
if (tor->incompleteDir == nullptr)
|
||||
if (std::empty(tor->incompleteDir()))
|
||||
{
|
||||
dir = tor->downloadDir;
|
||||
dir = tor->downloadDir();
|
||||
}
|
||||
else if (!tor->hasMetadata()) /* no files to find */
|
||||
{
|
||||
dir = tor->incompleteDir;
|
||||
dir = tor->incompleteDir();
|
||||
}
|
||||
else if (!tr_torrentFindFile2(tor, 0, &dir, nullptr, nullptr))
|
||||
else
|
||||
{
|
||||
dir = tor->incompleteDir;
|
||||
auto filename = std::string{};
|
||||
auto const found = tor->findFile(filename, 0);
|
||||
dir = found ? tr_interned_string{ found->base } : tor->incompleteDir();
|
||||
}
|
||||
|
||||
TR_ASSERT(dir != nullptr);
|
||||
TR_ASSERT(dir == tor->downloadDir || dir == tor->incompleteDir);
|
||||
TR_ASSERT(!std::empty(dir));
|
||||
TR_ASSERT(dir == tor->downloadDir() || dir == tor->incompleteDir());
|
||||
|
||||
tor->currentDir = dir;
|
||||
tor->current_dir = dir;
|
||||
}
|
||||
|
||||
char* tr_torrentBuildPartial(tr_torrent const* tor, tr_file_index_t i)
|
||||
|
@ -3001,7 +2973,7 @@ static int renamePath(tr_torrent* tor, char const* oldpath, char const* newname)
|
|||
{
|
||||
int err = 0;
|
||||
|
||||
char const* const base = !tor->isDone() && tor->incompleteDir != nullptr ? tor->incompleteDir : tor->downloadDir;
|
||||
auto const base = tor->isDone() || std::empty(tor->incompleteDir()) ? tor->downloadDir().sv() : tor->incompleteDir().sv();
|
||||
|
||||
auto src = tr_strvPath(base, oldpath);
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "completion.h"
|
||||
#include "file.h"
|
||||
#include "file-piece-map.h"
|
||||
#include "interned-string.h"
|
||||
#include "quark.h"
|
||||
#include "session.h"
|
||||
#include "tr-assert.h"
|
||||
|
@ -94,8 +95,6 @@ void tr_torrentCheckSeedLimit(tr_torrent* tor);
|
|||
/** save a torrent's .resume file if it's changed since the last time it was saved */
|
||||
void tr_torrentSave(tr_torrent* tor);
|
||||
|
||||
void tr_torrentSetLocalError(tr_torrent* tor, char const* fmt, ...) TR_GNUC_PRINTF(2, 3);
|
||||
|
||||
enum tr_verify_state
|
||||
{
|
||||
TR_VERIFY_NONE,
|
||||
|
@ -286,6 +285,23 @@ public:
|
|||
setDirty();
|
||||
}
|
||||
|
||||
/// LOCATION
|
||||
|
||||
[[nodiscard]] tr_interned_string currentDir() const
|
||||
{
|
||||
return this->current_dir;
|
||||
}
|
||||
|
||||
[[nodiscard]] tr_interned_string downloadDir() const
|
||||
{
|
||||
return this->download_dir;
|
||||
}
|
||||
|
||||
[[nodiscard]] tr_interned_string incompleteDir() const
|
||||
{
|
||||
return this->incomplete_dir;
|
||||
}
|
||||
|
||||
/// METAINFO - FILES
|
||||
|
||||
[[nodiscard]] tr_file_index_t fileCount() const
|
||||
|
@ -504,6 +520,13 @@ public:
|
|||
return this->isPieceTransferAllowed(TR_CLIENT_TO_PEER);
|
||||
}
|
||||
|
||||
void setLocalError(std::string_view errmsg)
|
||||
{
|
||||
this->error = TR_STAT_LOCAL_ERROR;
|
||||
this->error_announce_url = TR_KEY_NONE;
|
||||
this->error_string = errmsg;
|
||||
}
|
||||
|
||||
void setVerifyState(tr_verify_state state);
|
||||
|
||||
void setDateActive(time_t t);
|
||||
|
@ -535,8 +558,8 @@ public:
|
|||
std::optional<double> verify_progress;
|
||||
|
||||
tr_stat_errtype error = TR_STAT_OK;
|
||||
char errorString[128] = {};
|
||||
tr_quark error_announce_url = TR_KEY_NONE;
|
||||
tr_interned_string error_announce_url;
|
||||
std::string error_string;
|
||||
|
||||
bool checkPiece(tr_piece_index_t piece);
|
||||
|
||||
|
@ -558,15 +581,16 @@ public:
|
|||
|
||||
time_t peer_id_creation_time = 0;
|
||||
|
||||
/* Where the files will be when it's complete */
|
||||
char* downloadDir = nullptr;
|
||||
// Where the files are when the torrent is complete.
|
||||
tr_interned_string download_dir;
|
||||
|
||||
/* Where the files are when the torrent is incomplete */
|
||||
char* incompleteDir = nullptr;
|
||||
// Where the files are when the torrent is incomplete.
|
||||
// a value of TR_KEY_NONE indicates the 'incomplete_dir' feature is unused
|
||||
tr_interned_string incomplete_dir;
|
||||
|
||||
/* Where the files are now.
|
||||
* This pointer will be equal to downloadDir or incompleteDir */
|
||||
char const* currentDir = nullptr;
|
||||
// Where the files are now.
|
||||
// Will equal either download_dir or incomplete_dir
|
||||
tr_interned_string current_dir;
|
||||
|
||||
/* Length, in bytes, of the "info" dict in the .torrent file. */
|
||||
uint64_t infoDictLength = 0;
|
||||
|
|
|
@ -1343,8 +1343,8 @@ struct tr_peer_stat
|
|||
tr_port port;
|
||||
|
||||
char addr[TR_INET6_ADDRSTRLEN];
|
||||
char client[80];
|
||||
char flagStr[32];
|
||||
char const* client;
|
||||
|
||||
float progress;
|
||||
double rateToPeer_KBps;
|
||||
|
|
|
@ -171,7 +171,7 @@ OSStatus GeneratePreviewForURL(void* thisInterface, QLPreviewRequestRef preview,
|
|||
#warning handle tiers?
|
||||
for (auto const tracker : *inf.announce_list)
|
||||
{
|
||||
[listSection appendFormat:@"<tr><td>%s<td></tr>", tr_quark_get_string(tracker.announce_interned)];
|
||||
[listSection appendFormat:@"<tr><td>%s<td></tr>", tracker.announce_str.c_str()];
|
||||
}
|
||||
|
||||
[listSection appendString:@"</table>"];
|
||||
|
|
|
@ -36,7 +36,7 @@ TEST_F(AnnounceListTest, canAdd)
|
|||
EXPECT_EQ(Announce, tracker.announce.full);
|
||||
EXPECT_EQ("https://example.org/scrape"sv, tracker.scrape.full);
|
||||
EXPECT_EQ(Tier, tracker.tier);
|
||||
EXPECT_EQ("example.org:443"sv, tr_quark_get_string_view(tracker.host));
|
||||
EXPECT_EQ("example.org:443"sv, tracker.host.sv());
|
||||
}
|
||||
|
||||
TEST_F(AnnounceListTest, groupsSiblingsIntoSameTier)
|
||||
|
@ -60,9 +60,9 @@ TEST_F(AnnounceListTest, groupsSiblingsIntoSameTier)
|
|||
EXPECT_EQ(Announce1, announce_list.at(1).announce.full);
|
||||
EXPECT_EQ(Announce2, announce_list.at(0).announce.full);
|
||||
EXPECT_EQ(Announce3, announce_list.at(2).announce.full);
|
||||
EXPECT_EQ("example.org:443"sv, tr_quark_get_string_view(announce_list.at(1).host));
|
||||
EXPECT_EQ("example.org:80"sv, tr_quark_get_string_view(announce_list.at(0).host));
|
||||
EXPECT_EQ("example.org:999"sv, tr_quark_get_string_view(announce_list.at(2).host));
|
||||
EXPECT_EQ("example.org:443"sv, announce_list.at(1).host.sv());
|
||||
EXPECT_EQ("example.org:80"sv, announce_list.at(0).host.sv());
|
||||
EXPECT_EQ("example.org:999"sv, announce_list.at(2).host.sv());
|
||||
}
|
||||
|
||||
TEST_F(AnnounceListTest, canAddWithoutScrape)
|
||||
|
@ -74,7 +74,7 @@ TEST_F(AnnounceListTest, canAddWithoutScrape)
|
|||
EXPECT_TRUE(announce_list.add(Tier, Announce));
|
||||
auto const tracker = announce_list.at(0);
|
||||
EXPECT_EQ(Announce, tracker.announce.full);
|
||||
EXPECT_EQ(TR_KEY_NONE, tracker.scrape_interned);
|
||||
EXPECT_TRUE(std::empty(tracker.scrape_str));
|
||||
EXPECT_EQ(Tier, tracker.tier);
|
||||
}
|
||||
|
||||
|
|
|
@ -43,13 +43,13 @@ protected:
|
|||
EXPECT_TRUE(waitFor(test, MaxWaitMsec));
|
||||
}
|
||||
|
||||
void createSingleFileTorrentContents(char const* top)
|
||||
void createSingleFileTorrentContents(std::string_view top)
|
||||
{
|
||||
auto const path = tr_strvPath(top, "hello-world.txt");
|
||||
createFileWithContents(path, "hello, world!\n");
|
||||
}
|
||||
|
||||
void createMultifileTorrentContents(char const* top)
|
||||
void createMultifileTorrentContents(std::string_view top)
|
||||
{
|
||||
auto path = tr_strvPath(top, "Felidae", "Felinae", "Acinonyx", "Cheetah", "Chester");
|
||||
createFileWithContents(path, "It ain't easy bein' cheesy.\n");
|
||||
|
@ -163,7 +163,7 @@ TEST_F(RenameTest, singleFilenameTorrent)
|
|||
blockingTorrentVerify(tor);
|
||||
expectHaveNone(tor, TotalSize);
|
||||
|
||||
createSingleFileTorrentContents(tor->currentDir);
|
||||
createSingleFileTorrentContents(tor->currentDir().sv());
|
||||
|
||||
// sanity check the stats again, now that we've added the file
|
||||
blockingTorrentVerify(tor);
|
||||
|
@ -197,7 +197,7 @@ TEST_F(RenameTest, singleFilenameTorrent)
|
|||
**** Now try a rename that should succeed
|
||||
***/
|
||||
|
||||
auto tmpstr = tr_strvPath(tor->currentDir, "hello-world.txt");
|
||||
auto tmpstr = tr_strvPath(tor->currentDir().sv(), "hello-world.txt");
|
||||
EXPECT_TRUE(tr_sys_path_exists(tmpstr.c_str(), nullptr));
|
||||
EXPECT_STREQ("hello-world.txt", tr_torrentName(tor));
|
||||
EXPECT_EQ(0, torrentRenameAndWait(tor, tr_torrentName(tor), "foobar"));
|
||||
|
@ -206,7 +206,7 @@ TEST_F(RenameTest, singleFilenameTorrent)
|
|||
EXPECT_STREQ("foobar", tr_torrentName(tor)); // confirm the torrent's name is now 'foobar'
|
||||
EXPECT_STREQ("foobar", files[0].name); // confirm the file's name is now 'foobar' in our struct
|
||||
EXPECT_STREQ(nullptr, strstr(tr_torrentView(tor).torrent_filename, "foobar")); // confirm .torrent file hasn't changed
|
||||
tmpstr = tr_strvPath(tor->currentDir, "foobar");
|
||||
tmpstr = tr_strvPath(tor->currentDir().sv(), "foobar");
|
||||
EXPECT_TRUE(tr_sys_path_exists(tmpstr.c_str(), nullptr)); // confirm the file's name is now 'foobar' on the disk
|
||||
EXPECT_TRUE(testFileExistsAndConsistsOfThisString(tor, 0, "hello, world!\n")); // confirm the contents are right
|
||||
|
||||
|
@ -221,7 +221,7 @@ TEST_F(RenameTest, singleFilenameTorrent)
|
|||
**** ...and rename it back again
|
||||
***/
|
||||
|
||||
tmpstr = tr_strvPath(tor->currentDir, "foobar");
|
||||
tmpstr = tr_strvPath(tor->currentDir().sv(), "foobar");
|
||||
EXPECT_TRUE(tr_sys_path_exists(tmpstr.c_str(), nullptr));
|
||||
EXPECT_EQ(0, torrentRenameAndWait(tor, "foobar", "hello-world.txt"));
|
||||
EXPECT_FALSE(tr_sys_path_exists(tmpstr.c_str(), nullptr));
|
||||
|
@ -287,7 +287,7 @@ TEST_F(RenameTest, multifileTorrent)
|
|||
expectHaveNone(tor, TotalSize);
|
||||
|
||||
// build the local data
|
||||
createMultifileTorrentContents(tor->currentDir);
|
||||
createMultifileTorrentContents(tor->currentDir().sv());
|
||||
|
||||
// sanity check the (full) stats
|
||||
blockingTorrentVerify(tor);
|
||||
|
@ -523,7 +523,7 @@ TEST_F(RenameTest, partialFile)
|
|||
|
||||
for (tr_file_index_t i = 0; i < 3; ++i)
|
||||
{
|
||||
auto const expected = tr_strvPath(tor->currentDir, strings[i]);
|
||||
auto const expected = tr_strvPath(tor->currentDir().sv(), strings[i]);
|
||||
char* path = tr_torrentFindFile(tor, i);
|
||||
EXPECT_EQ(expected, path);
|
||||
tr_free(path);
|
||||
|
|
|
@ -399,8 +399,8 @@ protected:
|
|||
{
|
||||
auto const file = tr_torrentFile(tor, i);
|
||||
|
||||
auto path = (!complete && i == 0) ? tr_strvJoin(tor->currentDir, TR_PATH_DELIMITER_STR, file.name, ".part") :
|
||||
tr_strvJoin(tor->currentDir, TR_PATH_DELIMITER_STR, file.name);
|
||||
auto path = (!complete && i == 0) ? tr_strvJoin(tor->currentDir().sv(), TR_PATH_DELIMITER_STR, file.name, ".part") :
|
||||
tr_strvJoin(tor->currentDir().sv(), TR_PATH_DELIMITER_STR, file.name);
|
||||
|
||||
auto const dirname = makeString(tr_sys_path_dirname(path.c_str(), nullptr));
|
||||
tr_sys_dir_create(dirname.data(), TR_SYS_DIR_CREATE_PARENTS, 0700, nullptr);
|
||||
|
|
|
@ -218,7 +218,7 @@ static void doScrape(tr_info const* inf)
|
|||
{
|
||||
for (auto const& tracker : *inf->announce_list)
|
||||
{
|
||||
if (tracker.scrape_interned == TR_KEY_NONE)
|
||||
if (std::empty(tracker.scrape_str))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue